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 ;; Y -- print condition for XOP pcom* instruction.
62 ;; + -- print a branch hint as 'cs' or 'ds' prefix
63 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
65 ;; @ -- print a segment register of thread base pointer load
66 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
80 UNSPEC_MACHOPIC_OFFSET
90 UNSPEC_MEMORY_BLOCKAGE
100 ;; Other random patterns
109 UNSPEC_LD_MPIC ; load_macho_picbase
111 UNSPEC_DIV_ALREADY_SPLIT
112 UNSPEC_MS_TO_SYSV_CALL
113 UNSPEC_CALL_NEEDS_VZEROUPPER
118 ;; For SSE/MMX support:
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
178 ;; For RDRAND support
189 (define_c_enum "unspecv" [
192 UNSPECV_PROBE_STACK_RANGE
195 UNSPECV_SPLIT_STACK_RETURN
201 UNSPECV_LLWP_INTRINSIC
202 UNSPECV_SLWP_INTRINSIC
203 UNSPECV_LWPVAL_INTRINSIC
204 UNSPECV_LWPINS_INTRINSIC
217 ;; Constants to represent rounding modes in the ROUND instruction
226 ;; Constants to represent pcomtrue/pcomfalse variants
236 ;; Constants used in the XOP pperm instruction
238 [(PPERM_SRC 0x00) /* copy source */
239 (PPERM_INVERT 0x20) /* invert source */
240 (PPERM_REVERSE 0x40) /* bit reverse source */
241 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
242 (PPERM_ZERO 0x80) /* all 0's */
243 (PPERM_ONES 0xa0) /* all 1's */
244 (PPERM_SIGN 0xc0) /* propagate sign bit */
245 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
246 (PPERM_SRC1 0x00) /* use first source byte */
247 (PPERM_SRC2 0x10) /* use second source byte */
250 ;; Registers by name.
303 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
306 ;; In C guard expressions, put expressions which may be compile-time
307 ;; constants first. This allows for better optimization. For
308 ;; example, write "TARGET_64BIT && reload_completed", not
309 ;; "reload_completed && TARGET_64BIT".
313 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
314 atom,generic64,amdfam10,bdver1,bdver2,btver1"
315 (const (symbol_ref "ix86_schedule")))
317 ;; A basic instruction type. Refinements due to arguments to be
318 ;; provided in other attributes.
321 alu,alu1,negnot,imov,imovx,lea,
322 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
323 icmp,test,ibr,setcc,icmov,
324 push,pop,call,callv,leave,
326 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
327 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
328 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
329 ssemuladd,sse4arg,lwp,
330 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
331 (const_string "other"))
333 ;; Main data type used by the insn
335 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
336 (const_string "unknown"))
338 ;; The CPU unit operations uses.
339 (define_attr "unit" "integer,i387,sse,mmx,unknown"
340 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
341 (const_string "i387")
342 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
343 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
344 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
346 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
348 (eq_attr "type" "other")
349 (const_string "unknown")]
350 (const_string "integer")))
352 ;; The (bounding maximum) length of an instruction immediate.
353 (define_attr "length_immediate" ""
354 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
357 (eq_attr "unit" "i387,sse,mmx")
359 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
360 rotate,rotatex,rotate1,imul,icmp,push,pop")
361 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
362 (eq_attr "type" "imov,test")
363 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
364 (eq_attr "type" "call")
365 (if_then_else (match_operand 0 "constant_call_address_operand")
368 (eq_attr "type" "callv")
369 (if_then_else (match_operand 1 "constant_call_address_operand")
372 ;; We don't know the size before shorten_branches. Expect
373 ;; the instruction to fit for better scheduling.
374 (eq_attr "type" "ibr")
377 (symbol_ref "/* Update immediate_length and other attributes! */
378 gcc_unreachable (),1")))
380 ;; The (bounding maximum) length of an instruction address.
381 (define_attr "length_address" ""
382 (cond [(eq_attr "type" "str,other,multi,fxch")
384 (and (eq_attr "type" "call")
385 (match_operand 0 "constant_call_address_operand"))
387 (and (eq_attr "type" "callv")
388 (match_operand 1 "constant_call_address_operand"))
391 (symbol_ref "ix86_attr_length_address_default (insn)")))
393 ;; Set when length prefix is used.
394 (define_attr "prefix_data16" ""
395 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
397 (eq_attr "mode" "HI")
399 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
404 ;; Set when string REP prefix is used.
405 (define_attr "prefix_rep" ""
406 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
408 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
413 ;; Set when 0f opcode prefix is used.
414 (define_attr "prefix_0f" ""
416 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
417 (eq_attr "unit" "sse,mmx"))
421 ;; Set when REX opcode prefix is used.
422 (define_attr "prefix_rex" ""
423 (cond [(not (match_test "TARGET_64BIT"))
425 (and (eq_attr "mode" "DI")
426 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
427 (eq_attr "unit" "!mmx")))
429 (and (eq_attr "mode" "QI")
430 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
432 (match_test "x86_extended_reg_mentioned_p (insn)")
434 (and (eq_attr "type" "imovx")
435 (match_operand:QI 1 "ext_QIreg_operand"))
440 ;; There are also additional prefixes in 3DNOW, SSSE3.
441 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
442 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
443 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
444 (define_attr "prefix_extra" ""
445 (cond [(eq_attr "type" "ssemuladd,sse4arg")
447 (eq_attr "type" "sseiadd1,ssecvt1")
452 ;; Prefix used: original, VEX or maybe VEX.
453 (define_attr "prefix" "orig,vex,maybe_vex"
454 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
456 (const_string "orig")))
458 ;; VEX W bit is used.
459 (define_attr "prefix_vex_w" "" (const_int 0))
461 ;; The length of VEX prefix
462 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
463 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
464 ;; still prefix_0f 1, with prefix_extra 1.
465 (define_attr "length_vex" ""
466 (if_then_else (and (eq_attr "prefix_0f" "1")
467 (eq_attr "prefix_extra" "0"))
468 (if_then_else (eq_attr "prefix_vex_w" "1")
469 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
470 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
471 (if_then_else (eq_attr "prefix_vex_w" "1")
472 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
473 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
475 ;; Set when modrm byte is used.
476 (define_attr "modrm" ""
477 (cond [(eq_attr "type" "str,leave")
479 (eq_attr "unit" "i387")
481 (and (eq_attr "type" "incdec")
482 (and (not (match_test "TARGET_64BIT"))
483 (ior (match_operand:SI 1 "register_operand")
484 (match_operand:HI 1 "register_operand"))))
486 (and (eq_attr "type" "push")
487 (not (match_operand 1 "memory_operand")))
489 (and (eq_attr "type" "pop")
490 (not (match_operand 0 "memory_operand")))
492 (and (eq_attr "type" "imov")
493 (and (not (eq_attr "mode" "DI"))
494 (ior (and (match_operand 0 "register_operand")
495 (match_operand 1 "immediate_operand"))
496 (ior (and (match_operand 0 "ax_reg_operand")
497 (match_operand 1 "memory_displacement_only_operand"))
498 (and (match_operand 0 "memory_displacement_only_operand")
499 (match_operand 1 "ax_reg_operand"))))))
501 (and (eq_attr "type" "call")
502 (match_operand 0 "constant_call_address_operand"))
504 (and (eq_attr "type" "callv")
505 (match_operand 1 "constant_call_address_operand"))
507 (and (eq_attr "type" "alu,alu1,icmp,test")
508 (match_operand 0 "ax_reg_operand"))
509 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
513 ;; The (bounding maximum) length of an instruction in bytes.
514 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
515 ;; Later we may want to split them and compute proper length as for
517 (define_attr "length" ""
518 (cond [(eq_attr "type" "other,multi,fistp,frndint")
520 (eq_attr "type" "fcmp")
522 (eq_attr "unit" "i387")
524 (plus (attr "prefix_data16")
525 (attr "length_address")))
526 (ior (eq_attr "prefix" "vex")
527 (and (eq_attr "prefix" "maybe_vex")
528 (match_test "TARGET_AVX")))
529 (plus (attr "length_vex")
530 (plus (attr "length_immediate")
532 (attr "length_address"))))]
533 (plus (plus (attr "modrm")
534 (plus (attr "prefix_0f")
535 (plus (attr "prefix_rex")
536 (plus (attr "prefix_extra")
538 (plus (attr "prefix_rep")
539 (plus (attr "prefix_data16")
540 (plus (attr "length_immediate")
541 (attr "length_address")))))))
543 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
544 ;; `store' if there is a simple memory reference therein, or `unknown'
545 ;; if the instruction is complex.
547 (define_attr "memory" "none,load,store,both,unknown"
548 (cond [(eq_attr "type" "other,multi,str,lwp")
549 (const_string "unknown")
550 (eq_attr "type" "lea,fcmov,fpspc")
551 (const_string "none")
552 (eq_attr "type" "fistp,leave")
553 (const_string "both")
554 (eq_attr "type" "frndint")
555 (const_string "load")
556 (eq_attr "type" "push")
557 (if_then_else (match_operand 1 "memory_operand")
558 (const_string "both")
559 (const_string "store"))
560 (eq_attr "type" "pop")
561 (if_then_else (match_operand 0 "memory_operand")
562 (const_string "both")
563 (const_string "load"))
564 (eq_attr "type" "setcc")
565 (if_then_else (match_operand 0 "memory_operand")
566 (const_string "store")
567 (const_string "none"))
568 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
569 (if_then_else (ior (match_operand 0 "memory_operand")
570 (match_operand 1 "memory_operand"))
571 (const_string "load")
572 (const_string "none"))
573 (eq_attr "type" "ibr")
574 (if_then_else (match_operand 0 "memory_operand")
575 (const_string "load")
576 (const_string "none"))
577 (eq_attr "type" "call")
578 (if_then_else (match_operand 0 "constant_call_address_operand")
579 (const_string "none")
580 (const_string "load"))
581 (eq_attr "type" "callv")
582 (if_then_else (match_operand 1 "constant_call_address_operand")
583 (const_string "none")
584 (const_string "load"))
585 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
586 (match_operand 1 "memory_operand"))
587 (const_string "both")
588 (and (match_operand 0 "memory_operand")
589 (match_operand 1 "memory_operand"))
590 (const_string "both")
591 (match_operand 0 "memory_operand")
592 (const_string "store")
593 (match_operand 1 "memory_operand")
594 (const_string "load")
596 "!alu1,negnot,ishift1,
597 imov,imovx,icmp,test,bitmanip,
599 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
600 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
601 (match_operand 2 "memory_operand"))
602 (const_string "load")
603 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
604 (match_operand 3 "memory_operand"))
605 (const_string "load")
607 (const_string "none")))
609 ;; Indicates if an instruction has both an immediate and a displacement.
611 (define_attr "imm_disp" "false,true,unknown"
612 (cond [(eq_attr "type" "other,multi")
613 (const_string "unknown")
614 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
615 (and (match_operand 0 "memory_displacement_operand")
616 (match_operand 1 "immediate_operand")))
617 (const_string "true")
618 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
619 (and (match_operand 0 "memory_displacement_operand")
620 (match_operand 2 "immediate_operand")))
621 (const_string "true")
623 (const_string "false")))
625 ;; Indicates if an FP operation has an integer source.
627 (define_attr "fp_int_src" "false,true"
628 (const_string "false"))
630 ;; Defines rounding mode of an FP operation.
632 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
633 (const_string "any"))
635 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
636 (define_attr "use_carry" "0,1" (const_string "0"))
638 ;; Define attribute to indicate unaligned ssemov insns
639 (define_attr "movu" "0,1" (const_string "0"))
641 ;; Used to control the "enabled" attribute on a per-instruction basis.
642 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
643 (const_string "base"))
645 (define_attr "enabled" ""
646 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
647 (eq_attr "isa" "sse2_noavx")
648 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
649 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
650 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
651 (eq_attr "isa" "sse4_noavx")
652 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
653 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
654 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
655 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
659 ;; Describe a user's asm statement.
660 (define_asm_attributes
661 [(set_attr "length" "128")
662 (set_attr "type" "multi")])
664 (define_code_iterator plusminus [plus minus])
666 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
668 ;; Base name for define_insn
669 (define_code_attr plusminus_insn
670 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
671 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
673 ;; Base name for insn mnemonic.
674 (define_code_attr plusminus_mnemonic
675 [(plus "add") (ss_plus "adds") (us_plus "addus")
676 (minus "sub") (ss_minus "subs") (us_minus "subus")])
677 (define_code_attr plusminus_carry_mnemonic
678 [(plus "adc") (minus "sbb")])
680 ;; Mark commutative operators as such in constraints.
681 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
682 (minus "") (ss_minus "") (us_minus "")])
684 ;; Mapping of max and min
685 (define_code_iterator maxmin [smax smin umax umin])
687 ;; Mapping of signed max and min
688 (define_code_iterator smaxmin [smax smin])
690 ;; Mapping of unsigned max and min
691 (define_code_iterator umaxmin [umax umin])
693 ;; Base name for integer and FP insn mnemonic
694 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
695 (umax "maxu") (umin "minu")])
696 (define_code_attr maxmin_float [(smax "max") (smin "min")])
698 ;; Mapping of logic operators
699 (define_code_iterator any_logic [and ior xor])
700 (define_code_iterator any_or [ior xor])
702 ;; Base name for insn mnemonic.
703 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
705 ;; Mapping of logic-shift operators
706 (define_code_iterator any_lshift [ashift lshiftrt])
708 ;; Mapping of shift-right operators
709 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
711 ;; Base name for define_insn
712 (define_code_attr shift_insn
713 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
715 ;; Base name for insn mnemonic.
716 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
717 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
719 ;; Mapping of rotate operators
720 (define_code_iterator any_rotate [rotate rotatert])
722 ;; Base name for define_insn
723 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
725 ;; Base name for insn mnemonic.
726 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
728 ;; Mapping of abs neg operators
729 (define_code_iterator absneg [abs neg])
731 ;; Base name for x87 insn mnemonic.
732 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
734 ;; Used in signed and unsigned widening multiplications.
735 (define_code_iterator any_extend [sign_extend zero_extend])
737 ;; Prefix for insn menmonic.
738 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
740 ;; Prefix for define_insn
741 (define_code_attr u [(sign_extend "") (zero_extend "u")])
742 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
744 ;; All integer modes.
745 (define_mode_iterator SWI1248x [QI HI SI DI])
747 ;; All integer modes without QImode.
748 (define_mode_iterator SWI248x [HI SI DI])
750 ;; All integer modes without QImode and HImode.
751 (define_mode_iterator SWI48x [SI DI])
753 ;; All integer modes without SImode and DImode.
754 (define_mode_iterator SWI12 [QI HI])
756 ;; All integer modes without DImode.
757 (define_mode_iterator SWI124 [QI HI SI])
759 ;; All integer modes without QImode and DImode.
760 (define_mode_iterator SWI24 [HI SI])
762 ;; Single word integer modes.
763 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
765 ;; Single word integer modes without QImode.
766 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
768 ;; Single word integer modes without QImode and HImode.
769 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
771 ;; All math-dependant single and double word integer modes.
772 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
773 (HI "TARGET_HIMODE_MATH")
774 SI DI (TI "TARGET_64BIT")])
776 ;; Math-dependant single word integer modes.
777 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
778 (HI "TARGET_HIMODE_MATH")
779 SI (DI "TARGET_64BIT")])
781 ;; Math-dependant integer modes without DImode.
782 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
783 (HI "TARGET_HIMODE_MATH")
786 ;; Math-dependant single word integer modes without QImode.
787 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
788 SI (DI "TARGET_64BIT")])
790 ;; Double word integer modes.
791 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
792 (TI "TARGET_64BIT")])
794 ;; Double word integer modes as mode attribute.
795 (define_mode_attr DWI [(SI "DI") (DI "TI")])
796 (define_mode_attr dwi [(SI "di") (DI "ti")])
798 ;; Half mode for double word integer modes.
799 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
800 (DI "TARGET_64BIT")])
802 ;; Instruction suffix for integer modes.
803 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
805 ;; Pointer size prefix for integer modes (Intel asm dialect)
806 (define_mode_attr iptrsize [(QI "BYTE")
811 ;; Register class for integer modes.
812 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
814 ;; Immediate operand constraint for integer modes.
815 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
817 ;; General operand constraint for word modes.
818 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
820 ;; Immediate operand constraint for double integer modes.
821 (define_mode_attr di [(SI "nF") (DI "e")])
823 ;; Immediate operand constraint for shifts.
824 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
826 ;; General operand predicate for integer modes.
827 (define_mode_attr general_operand
828 [(QI "general_operand")
829 (HI "general_operand")
830 (SI "x86_64_general_operand")
831 (DI "x86_64_general_operand")
832 (TI "x86_64_general_operand")])
834 ;; General sign/zero extend operand predicate for integer modes.
835 (define_mode_attr general_szext_operand
836 [(QI "general_operand")
837 (HI "general_operand")
838 (SI "x86_64_szext_general_operand")
839 (DI "x86_64_szext_general_operand")])
841 ;; Immediate operand predicate for integer modes.
842 (define_mode_attr immediate_operand
843 [(QI "immediate_operand")
844 (HI "immediate_operand")
845 (SI "x86_64_immediate_operand")
846 (DI "x86_64_immediate_operand")])
848 ;; Nonmemory operand predicate for integer modes.
849 (define_mode_attr nonmemory_operand
850 [(QI "nonmemory_operand")
851 (HI "nonmemory_operand")
852 (SI "x86_64_nonmemory_operand")
853 (DI "x86_64_nonmemory_operand")])
855 ;; Operand predicate for shifts.
856 (define_mode_attr shift_operand
857 [(QI "nonimmediate_operand")
858 (HI "nonimmediate_operand")
859 (SI "nonimmediate_operand")
860 (DI "shiftdi_operand")
861 (TI "register_operand")])
863 ;; Operand predicate for shift argument.
864 (define_mode_attr shift_immediate_operand
865 [(QI "const_1_to_31_operand")
866 (HI "const_1_to_31_operand")
867 (SI "const_1_to_31_operand")
868 (DI "const_1_to_63_operand")])
870 ;; Input operand predicate for arithmetic left shifts.
871 (define_mode_attr ashl_input_operand
872 [(QI "nonimmediate_operand")
873 (HI "nonimmediate_operand")
874 (SI "nonimmediate_operand")
875 (DI "ashldi_input_operand")
876 (TI "reg_or_pm1_operand")])
878 ;; SSE and x87 SFmode and DFmode floating point modes
879 (define_mode_iterator MODEF [SF DF])
881 ;; All x87 floating point modes
882 (define_mode_iterator X87MODEF [SF DF XF])
884 ;; SSE instruction suffix for various modes
885 (define_mode_attr ssemodesuffix
887 (V8SF "ps") (V4DF "pd")
888 (V4SF "ps") (V2DF "pd")
889 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
890 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
892 ;; SSE vector suffix for floating point modes
893 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
895 ;; SSE vector mode corresponding to a scalar mode
896 (define_mode_attr ssevecmode
897 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
899 ;; Instruction suffix for REX 64bit operators.
900 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
902 ;; This mode iterator allows :P to be used for patterns that operate on
903 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
904 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
906 ;; This mode iterator allows :W to be used for patterns that operate on
907 ;; word_mode sized quantities.
908 (define_mode_iterator W
909 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
911 ;; This mode iterator allows :PTR to be used for patterns that operate on
912 ;; ptr_mode sized quantities.
913 (define_mode_iterator PTR
914 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
916 ;; Scheduling descriptions
918 (include "pentium.md")
921 (include "athlon.md")
922 (include "bdver1.md")
928 ;; Operand and operator predicates and constraints
930 (include "predicates.md")
931 (include "constraints.md")
934 ;; Compare and branch/compare and store instructions.
936 (define_expand "cbranch<mode>4"
937 [(set (reg:CC FLAGS_REG)
938 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand")
939 (match_operand:SDWIM 2 "<general_operand>")))
940 (set (pc) (if_then_else
941 (match_operator 0 "ordered_comparison_operator"
942 [(reg:CC FLAGS_REG) (const_int 0)])
943 (label_ref (match_operand 3))
947 if (MEM_P (operands[1]) && MEM_P (operands[2]))
948 operands[1] = force_reg (<MODE>mode, operands[1]);
949 ix86_expand_branch (GET_CODE (operands[0]),
950 operands[1], operands[2], operands[3]);
954 (define_expand "cstore<mode>4"
955 [(set (reg:CC FLAGS_REG)
956 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand")
957 (match_operand:SWIM 3 "<general_operand>")))
958 (set (match_operand:QI 0 "register_operand")
959 (match_operator 1 "ordered_comparison_operator"
960 [(reg:CC FLAGS_REG) (const_int 0)]))]
963 if (MEM_P (operands[2]) && MEM_P (operands[3]))
964 operands[2] = force_reg (<MODE>mode, operands[2]);
965 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
966 operands[2], operands[3]);
970 (define_expand "cmp<mode>_1"
971 [(set (reg:CC FLAGS_REG)
972 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand")
973 (match_operand:SWI48 1 "<general_operand>")))])
975 (define_insn "*cmp<mode>_ccno_1"
976 [(set (reg FLAGS_REG)
977 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
978 (match_operand:SWI 1 "const0_operand")))]
979 "ix86_match_ccmode (insn, CCNOmode)"
981 test{<imodesuffix>}\t%0, %0
982 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
983 [(set_attr "type" "test,icmp")
984 (set_attr "length_immediate" "0,1")
985 (set_attr "mode" "<MODE>")])
987 (define_insn "*cmp<mode>_1"
988 [(set (reg FLAGS_REG)
989 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
990 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
991 "ix86_match_ccmode (insn, CCmode)"
992 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
993 [(set_attr "type" "icmp")
994 (set_attr "mode" "<MODE>")])
996 (define_insn "*cmp<mode>_minus_1"
997 [(set (reg FLAGS_REG)
999 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
1000 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
1002 "ix86_match_ccmode (insn, CCGOCmode)"
1003 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
1004 [(set_attr "type" "icmp")
1005 (set_attr "mode" "<MODE>")])
1007 (define_insn "*cmpqi_ext_1"
1008 [(set (reg FLAGS_REG)
1010 (match_operand:QI 0 "general_operand" "Qm")
1013 (match_operand 1 "ext_register_operand" "Q")
1015 (const_int 8)) 0)))]
1016 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1017 "cmp{b}\t{%h1, %0|%0, %h1}"
1018 [(set_attr "type" "icmp")
1019 (set_attr "mode" "QI")])
1021 (define_insn "*cmpqi_ext_1_rex64"
1022 [(set (reg FLAGS_REG)
1024 (match_operand:QI 0 "register_operand" "Q")
1027 (match_operand 1 "ext_register_operand" "Q")
1029 (const_int 8)) 0)))]
1030 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1031 "cmp{b}\t{%h1, %0|%0, %h1}"
1032 [(set_attr "type" "icmp")
1033 (set_attr "mode" "QI")])
1035 (define_insn "*cmpqi_ext_2"
1036 [(set (reg FLAGS_REG)
1040 (match_operand 0 "ext_register_operand" "Q")
1043 (match_operand:QI 1 "const0_operand")))]
1044 "ix86_match_ccmode (insn, CCNOmode)"
1046 [(set_attr "type" "test")
1047 (set_attr "length_immediate" "0")
1048 (set_attr "mode" "QI")])
1050 (define_expand "cmpqi_ext_3"
1051 [(set (reg:CC FLAGS_REG)
1055 (match_operand 0 "ext_register_operand")
1058 (match_operand:QI 1 "immediate_operand")))])
1060 (define_insn "*cmpqi_ext_3_insn"
1061 [(set (reg FLAGS_REG)
1065 (match_operand 0 "ext_register_operand" "Q")
1068 (match_operand:QI 1 "general_operand" "Qmn")))]
1069 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1070 "cmp{b}\t{%1, %h0|%h0, %1}"
1071 [(set_attr "type" "icmp")
1072 (set_attr "modrm" "1")
1073 (set_attr "mode" "QI")])
1075 (define_insn "*cmpqi_ext_3_insn_rex64"
1076 [(set (reg FLAGS_REG)
1080 (match_operand 0 "ext_register_operand" "Q")
1083 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1084 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1085 "cmp{b}\t{%1, %h0|%h0, %1}"
1086 [(set_attr "type" "icmp")
1087 (set_attr "modrm" "1")
1088 (set_attr "mode" "QI")])
1090 (define_insn "*cmpqi_ext_4"
1091 [(set (reg FLAGS_REG)
1095 (match_operand 0 "ext_register_operand" "Q")
1100 (match_operand 1 "ext_register_operand" "Q")
1102 (const_int 8)) 0)))]
1103 "ix86_match_ccmode (insn, CCmode)"
1104 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1105 [(set_attr "type" "icmp")
1106 (set_attr "mode" "QI")])
1108 ;; These implement float point compares.
1109 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1110 ;; which would allow mix and match FP modes on the compares. Which is what
1111 ;; the old patterns did, but with many more of them.
1113 (define_expand "cbranchxf4"
1114 [(set (reg:CC FLAGS_REG)
1115 (compare:CC (match_operand:XF 1 "nonmemory_operand")
1116 (match_operand:XF 2 "nonmemory_operand")))
1117 (set (pc) (if_then_else
1118 (match_operator 0 "ix86_fp_comparison_operator"
1121 (label_ref (match_operand 3))
1125 ix86_expand_branch (GET_CODE (operands[0]),
1126 operands[1], operands[2], operands[3]);
1130 (define_expand "cstorexf4"
1131 [(set (reg:CC FLAGS_REG)
1132 (compare:CC (match_operand:XF 2 "nonmemory_operand")
1133 (match_operand:XF 3 "nonmemory_operand")))
1134 (set (match_operand:QI 0 "register_operand")
1135 (match_operator 1 "ix86_fp_comparison_operator"
1140 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1141 operands[2], operands[3]);
1145 (define_expand "cbranch<mode>4"
1146 [(set (reg:CC FLAGS_REG)
1147 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand")
1148 (match_operand:MODEF 2 "cmp_fp_expander_operand")))
1149 (set (pc) (if_then_else
1150 (match_operator 0 "ix86_fp_comparison_operator"
1153 (label_ref (match_operand 3))
1155 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1157 ix86_expand_branch (GET_CODE (operands[0]),
1158 operands[1], operands[2], operands[3]);
1162 (define_expand "cstore<mode>4"
1163 [(set (reg:CC FLAGS_REG)
1164 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand")
1165 (match_operand:MODEF 3 "cmp_fp_expander_operand")))
1166 (set (match_operand:QI 0 "register_operand")
1167 (match_operator 1 "ix86_fp_comparison_operator"
1170 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1172 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1173 operands[2], operands[3]);
1177 (define_expand "cbranchcc4"
1178 [(set (pc) (if_then_else
1179 (match_operator 0 "comparison_operator"
1180 [(match_operand 1 "flags_reg_operand")
1181 (match_operand 2 "const0_operand")])
1182 (label_ref (match_operand 3))
1186 ix86_expand_branch (GET_CODE (operands[0]),
1187 operands[1], operands[2], operands[3]);
1191 (define_expand "cstorecc4"
1192 [(set (match_operand:QI 0 "register_operand")
1193 (match_operator 1 "comparison_operator"
1194 [(match_operand 2 "flags_reg_operand")
1195 (match_operand 3 "const0_operand")]))]
1198 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1199 operands[2], operands[3]);
1204 ;; FP compares, step 1:
1205 ;; Set the FP condition codes.
1207 ;; CCFPmode compare with exceptions
1208 ;; CCFPUmode compare with no exceptions
1210 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1211 ;; used to manage the reg stack popping would not be preserved.
1213 (define_insn "*cmpfp_0"
1214 [(set (match_operand:HI 0 "register_operand" "=a")
1217 (match_operand 1 "register_operand" "f")
1218 (match_operand 2 "const0_operand"))]
1220 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1221 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1222 "* return output_fp_compare (insn, operands, false, false);"
1223 [(set_attr "type" "multi")
1224 (set_attr "unit" "i387")
1226 (cond [(match_operand:SF 1)
1228 (match_operand:DF 1)
1231 (const_string "XF")))])
1233 (define_insn_and_split "*cmpfp_0_cc"
1234 [(set (reg:CCFP FLAGS_REG)
1236 (match_operand 1 "register_operand" "f")
1237 (match_operand 2 "const0_operand")))
1238 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1239 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1240 && TARGET_SAHF && !TARGET_CMOVE
1241 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1243 "&& reload_completed"
1246 [(compare:CCFP (match_dup 1)(match_dup 2))]
1248 (set (reg:CC FLAGS_REG)
1249 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1251 [(set_attr "type" "multi")
1252 (set_attr "unit" "i387")
1254 (cond [(match_operand:SF 1)
1256 (match_operand:DF 1)
1259 (const_string "XF")))])
1261 (define_insn "*cmpfp_xf"
1262 [(set (match_operand:HI 0 "register_operand" "=a")
1265 (match_operand:XF 1 "register_operand" "f")
1266 (match_operand:XF 2 "register_operand" "f"))]
1269 "* return output_fp_compare (insn, operands, false, false);"
1270 [(set_attr "type" "multi")
1271 (set_attr "unit" "i387")
1272 (set_attr "mode" "XF")])
1274 (define_insn_and_split "*cmpfp_xf_cc"
1275 [(set (reg:CCFP FLAGS_REG)
1277 (match_operand:XF 1 "register_operand" "f")
1278 (match_operand:XF 2 "register_operand" "f")))
1279 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1281 && TARGET_SAHF && !TARGET_CMOVE"
1283 "&& reload_completed"
1286 [(compare:CCFP (match_dup 1)(match_dup 2))]
1288 (set (reg:CC FLAGS_REG)
1289 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1291 [(set_attr "type" "multi")
1292 (set_attr "unit" "i387")
1293 (set_attr "mode" "XF")])
1295 (define_insn "*cmpfp_<mode>"
1296 [(set (match_operand:HI 0 "register_operand" "=a")
1299 (match_operand:MODEF 1 "register_operand" "f")
1300 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1303 "* return output_fp_compare (insn, operands, false, false);"
1304 [(set_attr "type" "multi")
1305 (set_attr "unit" "i387")
1306 (set_attr "mode" "<MODE>")])
1308 (define_insn_and_split "*cmpfp_<mode>_cc"
1309 [(set (reg:CCFP FLAGS_REG)
1311 (match_operand:MODEF 1 "register_operand" "f")
1312 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1313 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1315 && TARGET_SAHF && !TARGET_CMOVE"
1317 "&& reload_completed"
1320 [(compare:CCFP (match_dup 1)(match_dup 2))]
1322 (set (reg:CC FLAGS_REG)
1323 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1325 [(set_attr "type" "multi")
1326 (set_attr "unit" "i387")
1327 (set_attr "mode" "<MODE>")])
1329 (define_insn "*cmpfp_u"
1330 [(set (match_operand:HI 0 "register_operand" "=a")
1333 (match_operand 1 "register_operand" "f")
1334 (match_operand 2 "register_operand" "f"))]
1336 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1337 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1338 "* return output_fp_compare (insn, operands, false, true);"
1339 [(set_attr "type" "multi")
1340 (set_attr "unit" "i387")
1342 (cond [(match_operand:SF 1)
1344 (match_operand:DF 1)
1347 (const_string "XF")))])
1349 (define_insn_and_split "*cmpfp_u_cc"
1350 [(set (reg:CCFPU FLAGS_REG)
1352 (match_operand 1 "register_operand" "f")
1353 (match_operand 2 "register_operand" "f")))
1354 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1355 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1356 && TARGET_SAHF && !TARGET_CMOVE
1357 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1359 "&& reload_completed"
1362 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1364 (set (reg:CC FLAGS_REG)
1365 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1367 [(set_attr "type" "multi")
1368 (set_attr "unit" "i387")
1370 (cond [(match_operand:SF 1)
1372 (match_operand:DF 1)
1375 (const_string "XF")))])
1377 (define_insn "*cmpfp_<mode>"
1378 [(set (match_operand:HI 0 "register_operand" "=a")
1381 (match_operand 1 "register_operand" "f")
1382 (match_operator 3 "float_operator"
1383 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1385 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1386 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1387 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1388 "* return output_fp_compare (insn, operands, false, false);"
1389 [(set_attr "type" "multi")
1390 (set_attr "unit" "i387")
1391 (set_attr "fp_int_src" "true")
1392 (set_attr "mode" "<MODE>")])
1394 (define_insn_and_split "*cmpfp_<mode>_cc"
1395 [(set (reg:CCFP FLAGS_REG)
1397 (match_operand 1 "register_operand" "f")
1398 (match_operator 3 "float_operator"
1399 [(match_operand:SWI24 2 "memory_operand" "m")])))
1400 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1401 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1402 && TARGET_SAHF && !TARGET_CMOVE
1403 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1404 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1406 "&& reload_completed"
1411 (match_op_dup 3 [(match_dup 2)]))]
1413 (set (reg:CC FLAGS_REG)
1414 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1416 [(set_attr "type" "multi")
1417 (set_attr "unit" "i387")
1418 (set_attr "fp_int_src" "true")
1419 (set_attr "mode" "<MODE>")])
1421 ;; FP compares, step 2
1422 ;; Move the fpsw to ax.
1424 (define_insn "x86_fnstsw_1"
1425 [(set (match_operand:HI 0 "register_operand" "=a")
1426 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1429 [(set (attr "length")
1430 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1431 (set_attr "mode" "SI")
1432 (set_attr "unit" "i387")])
1434 ;; FP compares, step 3
1435 ;; Get ax into flags, general case.
1437 (define_insn "x86_sahf_1"
1438 [(set (reg:CC FLAGS_REG)
1439 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1443 #ifndef HAVE_AS_IX86_SAHF
1445 return ASM_BYTE "0x9e";
1450 [(set_attr "length" "1")
1451 (set_attr "athlon_decode" "vector")
1452 (set_attr "amdfam10_decode" "direct")
1453 (set_attr "bdver1_decode" "direct")
1454 (set_attr "mode" "SI")])
1456 ;; Pentium Pro can do steps 1 through 3 in one go.
1457 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1458 ;; (these i387 instructions set flags directly)
1459 (define_insn "*cmpfp_i_mixed"
1460 [(set (reg:CCFP FLAGS_REG)
1461 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1462 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1463 "TARGET_MIX_SSE_I387
1464 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1465 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1466 "* return output_fp_compare (insn, operands, true, false);"
1467 [(set_attr "type" "fcmp,ssecomi")
1468 (set_attr "prefix" "orig,maybe_vex")
1470 (if_then_else (match_operand:SF 1)
1472 (const_string "DF")))
1473 (set (attr "prefix_rep")
1474 (if_then_else (eq_attr "type" "ssecomi")
1476 (const_string "*")))
1477 (set (attr "prefix_data16")
1478 (cond [(eq_attr "type" "fcmp")
1480 (eq_attr "mode" "DF")
1483 (const_string "0")))
1484 (set_attr "athlon_decode" "vector")
1485 (set_attr "amdfam10_decode" "direct")
1486 (set_attr "bdver1_decode" "double")])
1488 (define_insn "*cmpfp_i_sse"
1489 [(set (reg:CCFP FLAGS_REG)
1490 (compare:CCFP (match_operand 0 "register_operand" "x")
1491 (match_operand 1 "nonimmediate_operand" "xm")))]
1493 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1494 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1495 "* return output_fp_compare (insn, operands, true, false);"
1496 [(set_attr "type" "ssecomi")
1497 (set_attr "prefix" "maybe_vex")
1499 (if_then_else (match_operand:SF 1)
1501 (const_string "DF")))
1502 (set_attr "prefix_rep" "0")
1503 (set (attr "prefix_data16")
1504 (if_then_else (eq_attr "mode" "DF")
1506 (const_string "0")))
1507 (set_attr "athlon_decode" "vector")
1508 (set_attr "amdfam10_decode" "direct")
1509 (set_attr "bdver1_decode" "double")])
1511 (define_insn "*cmpfp_i_i387"
1512 [(set (reg:CCFP FLAGS_REG)
1513 (compare:CCFP (match_operand 0 "register_operand" "f")
1514 (match_operand 1 "register_operand" "f")))]
1515 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1517 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1518 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1519 "* return output_fp_compare (insn, operands, true, false);"
1520 [(set_attr "type" "fcmp")
1522 (cond [(match_operand:SF 1)
1524 (match_operand:DF 1)
1527 (const_string "XF")))
1528 (set_attr "athlon_decode" "vector")
1529 (set_attr "amdfam10_decode" "direct")
1530 (set_attr "bdver1_decode" "double")])
1532 (define_insn "*cmpfp_iu_mixed"
1533 [(set (reg:CCFPU FLAGS_REG)
1534 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1535 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1536 "TARGET_MIX_SSE_I387
1537 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1538 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1539 "* return output_fp_compare (insn, operands, true, true);"
1540 [(set_attr "type" "fcmp,ssecomi")
1541 (set_attr "prefix" "orig,maybe_vex")
1543 (if_then_else (match_operand:SF 1)
1545 (const_string "DF")))
1546 (set (attr "prefix_rep")
1547 (if_then_else (eq_attr "type" "ssecomi")
1549 (const_string "*")))
1550 (set (attr "prefix_data16")
1551 (cond [(eq_attr "type" "fcmp")
1553 (eq_attr "mode" "DF")
1556 (const_string "0")))
1557 (set_attr "athlon_decode" "vector")
1558 (set_attr "amdfam10_decode" "direct")
1559 (set_attr "bdver1_decode" "double")])
1561 (define_insn "*cmpfp_iu_sse"
1562 [(set (reg:CCFPU FLAGS_REG)
1563 (compare:CCFPU (match_operand 0 "register_operand" "x")
1564 (match_operand 1 "nonimmediate_operand" "xm")))]
1566 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1567 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1568 "* return output_fp_compare (insn, operands, true, true);"
1569 [(set_attr "type" "ssecomi")
1570 (set_attr "prefix" "maybe_vex")
1572 (if_then_else (match_operand:SF 1)
1574 (const_string "DF")))
1575 (set_attr "prefix_rep" "0")
1576 (set (attr "prefix_data16")
1577 (if_then_else (eq_attr "mode" "DF")
1579 (const_string "0")))
1580 (set_attr "athlon_decode" "vector")
1581 (set_attr "amdfam10_decode" "direct")
1582 (set_attr "bdver1_decode" "double")])
1584 (define_insn "*cmpfp_iu_387"
1585 [(set (reg:CCFPU FLAGS_REG)
1586 (compare:CCFPU (match_operand 0 "register_operand" "f")
1587 (match_operand 1 "register_operand" "f")))]
1588 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1590 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1591 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1592 "* return output_fp_compare (insn, operands, true, true);"
1593 [(set_attr "type" "fcmp")
1595 (cond [(match_operand:SF 1)
1597 (match_operand:DF 1)
1600 (const_string "XF")))
1601 (set_attr "athlon_decode" "vector")
1602 (set_attr "amdfam10_decode" "direct")
1603 (set_attr "bdver1_decode" "direct")])
1605 ;; Push/pop instructions.
1607 (define_insn "*push<mode>2"
1608 [(set (match_operand:DWI 0 "push_operand" "=<")
1609 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1612 [(set_attr "type" "multi")
1613 (set_attr "mode" "<MODE>")])
1616 [(set (match_operand:TI 0 "push_operand")
1617 (match_operand:TI 1 "general_operand"))]
1618 "TARGET_64BIT && reload_completed
1619 && !SSE_REG_P (operands[1])"
1621 "ix86_split_long_move (operands); DONE;")
1623 (define_insn "*pushdi2_rex64"
1624 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1625 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1630 [(set_attr "type" "push,multi")
1631 (set_attr "mode" "DI")])
1633 ;; Convert impossible pushes of immediate to existing instructions.
1634 ;; First try to get scratch register and go through it. In case this
1635 ;; fails, push sign extended lower part first and then overwrite
1636 ;; upper part by 32bit move.
1638 [(match_scratch:DI 2 "r")
1639 (set (match_operand:DI 0 "push_operand")
1640 (match_operand:DI 1 "immediate_operand"))]
1641 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1642 && !x86_64_immediate_operand (operands[1], DImode)"
1643 [(set (match_dup 2) (match_dup 1))
1644 (set (match_dup 0) (match_dup 2))])
1646 ;; We need to define this as both peepholer and splitter for case
1647 ;; peephole2 pass is not run.
1648 ;; "&& 1" is needed to keep it from matching the previous pattern.
1650 [(set (match_operand:DI 0 "push_operand")
1651 (match_operand:DI 1 "immediate_operand"))]
1652 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1653 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1654 [(set (match_dup 0) (match_dup 1))
1655 (set (match_dup 2) (match_dup 3))]
1657 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1659 operands[1] = gen_lowpart (DImode, operands[2]);
1660 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1665 [(set (match_operand:DI 0 "push_operand")
1666 (match_operand:DI 1 "immediate_operand"))]
1667 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1668 ? epilogue_completed : reload_completed)
1669 && !symbolic_operand (operands[1], DImode)
1670 && !x86_64_immediate_operand (operands[1], DImode)"
1671 [(set (match_dup 0) (match_dup 1))
1672 (set (match_dup 2) (match_dup 3))]
1674 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1676 operands[1] = gen_lowpart (DImode, operands[2]);
1677 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1682 [(set (match_operand:DI 0 "push_operand")
1683 (match_operand:DI 1 "general_operand"))]
1684 "!TARGET_64BIT && reload_completed
1685 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1687 "ix86_split_long_move (operands); DONE;")
1689 (define_insn "*pushsi2"
1690 [(set (match_operand:SI 0 "push_operand" "=<")
1691 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1694 [(set_attr "type" "push")
1695 (set_attr "mode" "SI")])
1697 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1698 ;; "push a byte/word". But actually we use pushl, which has the effect
1699 ;; of rounding the amount pushed up to a word.
1701 ;; For TARGET_64BIT we always round up to 8 bytes.
1702 (define_insn "*push<mode>2_rex64"
1703 [(set (match_operand:SWI124 0 "push_operand" "=X")
1704 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1707 [(set_attr "type" "push")
1708 (set_attr "mode" "DI")])
1710 (define_insn "*push<mode>2"
1711 [(set (match_operand:SWI12 0 "push_operand" "=X")
1712 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1715 [(set_attr "type" "push")
1716 (set_attr "mode" "SI")])
1718 (define_insn "*push<mode>2_prologue"
1719 [(set (match_operand:W 0 "push_operand" "=<")
1720 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1721 (clobber (mem:BLK (scratch)))]
1723 "push{<imodesuffix>}\t%1"
1724 [(set_attr "type" "push")
1725 (set_attr "mode" "<MODE>")])
1727 (define_insn "*pop<mode>1"
1728 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1729 (match_operand:W 1 "pop_operand" ">"))]
1731 "pop{<imodesuffix>}\t%0"
1732 [(set_attr "type" "pop")
1733 (set_attr "mode" "<MODE>")])
1735 (define_insn "*pop<mode>1_epilogue"
1736 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1737 (match_operand:W 1 "pop_operand" ">"))
1738 (clobber (mem:BLK (scratch)))]
1740 "pop{<imodesuffix>}\t%0"
1741 [(set_attr "type" "pop")
1742 (set_attr "mode" "<MODE>")])
1744 ;; Move instructions.
1746 (define_expand "movoi"
1747 [(set (match_operand:OI 0 "nonimmediate_operand")
1748 (match_operand:OI 1 "general_operand"))]
1750 "ix86_expand_move (OImode, operands); DONE;")
1752 (define_expand "movti"
1753 [(set (match_operand:TI 0 "nonimmediate_operand")
1754 (match_operand:TI 1 "nonimmediate_operand"))]
1755 "TARGET_64BIT || TARGET_SSE"
1758 ix86_expand_move (TImode, operands);
1759 else if (push_operand (operands[0], TImode))
1760 ix86_expand_push (TImode, operands[1]);
1762 ix86_expand_vector_move (TImode, operands);
1766 ;; This expands to what emit_move_complex would generate if we didn't
1767 ;; have a movti pattern. Having this avoids problems with reload on
1768 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1769 ;; to have around all the time.
1770 (define_expand "movcdi"
1771 [(set (match_operand:CDI 0 "nonimmediate_operand")
1772 (match_operand:CDI 1 "general_operand"))]
1775 if (push_operand (operands[0], CDImode))
1776 emit_move_complex_push (CDImode, operands[0], operands[1]);
1778 emit_move_complex_parts (operands[0], operands[1]);
1782 (define_expand "mov<mode>"
1783 [(set (match_operand:SWI1248x 0 "nonimmediate_operand")
1784 (match_operand:SWI1248x 1 "general_operand"))]
1786 "ix86_expand_move (<MODE>mode, operands); DONE;")
1788 (define_insn "*mov<mode>_xor"
1789 [(set (match_operand:SWI48 0 "register_operand" "=r")
1790 (match_operand:SWI48 1 "const0_operand"))
1791 (clobber (reg:CC FLAGS_REG))]
1794 [(set_attr "type" "alu1")
1795 (set_attr "mode" "SI")
1796 (set_attr "length_immediate" "0")])
1798 (define_insn "*mov<mode>_or"
1799 [(set (match_operand:SWI48 0 "register_operand" "=r")
1800 (match_operand:SWI48 1 "const_int_operand"))
1801 (clobber (reg:CC FLAGS_REG))]
1803 && operands[1] == constm1_rtx"
1804 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1805 [(set_attr "type" "alu1")
1806 (set_attr "mode" "<MODE>")
1807 (set_attr "length_immediate" "1")])
1809 (define_insn "*movoi_internal_avx"
1810 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1811 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1812 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1814 switch (which_alternative)
1817 return standard_sse_constant_opcode (insn, operands[1]);
1820 if (misaligned_operand (operands[0], OImode)
1821 || misaligned_operand (operands[1], OImode))
1822 return "vmovdqu\t{%1, %0|%0, %1}";
1824 return "vmovdqa\t{%1, %0|%0, %1}";
1829 [(set_attr "type" "sselog1,ssemov,ssemov")
1830 (set_attr "prefix" "vex")
1831 (set_attr "mode" "OI")])
1833 (define_insn "*movti_internal_rex64"
1834 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1835 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1836 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1838 switch (which_alternative)
1844 return standard_sse_constant_opcode (insn, operands[1]);
1847 /* TDmode values are passed as TImode on the stack. Moving them
1848 to stack may result in unaligned memory access. */
1849 if (misaligned_operand (operands[0], TImode)
1850 || misaligned_operand (operands[1], TImode))
1852 if (get_attr_mode (insn) == MODE_V4SF)
1853 return "%vmovups\t{%1, %0|%0, %1}";
1855 return "%vmovdqu\t{%1, %0|%0, %1}";
1859 if (get_attr_mode (insn) == MODE_V4SF)
1860 return "%vmovaps\t{%1, %0|%0, %1}";
1862 return "%vmovdqa\t{%1, %0|%0, %1}";
1868 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1869 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1871 (cond [(eq_attr "alternative" "2,3")
1873 (match_test "optimize_function_for_size_p (cfun)")
1874 (const_string "V4SF")
1875 (const_string "TI"))
1876 (eq_attr "alternative" "4")
1878 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1879 (match_test "optimize_function_for_size_p (cfun)"))
1880 (const_string "V4SF")
1881 (const_string "TI"))]
1882 (const_string "DI")))])
1885 [(set (match_operand:TI 0 "nonimmediate_operand")
1886 (match_operand:TI 1 "general_operand"))]
1888 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1890 "ix86_split_long_move (operands); DONE;")
1892 (define_insn "*movti_internal_sse"
1893 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1894 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1895 "TARGET_SSE && !TARGET_64BIT
1896 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1898 switch (which_alternative)
1901 return standard_sse_constant_opcode (insn, operands[1]);
1904 /* TDmode values are passed as TImode on the stack. Moving them
1905 to stack may result in unaligned memory access. */
1906 if (misaligned_operand (operands[0], TImode)
1907 || misaligned_operand (operands[1], TImode))
1909 if (get_attr_mode (insn) == MODE_V4SF)
1910 return "%vmovups\t{%1, %0|%0, %1}";
1912 return "%vmovdqu\t{%1, %0|%0, %1}";
1916 if (get_attr_mode (insn) == MODE_V4SF)
1917 return "%vmovaps\t{%1, %0|%0, %1}";
1919 return "%vmovdqa\t{%1, %0|%0, %1}";
1925 [(set_attr "type" "sselog1,ssemov,ssemov")
1926 (set_attr "prefix" "maybe_vex")
1928 (cond [(ior (not (match_test "TARGET_SSE2"))
1929 (match_test "optimize_function_for_size_p (cfun)"))
1930 (const_string "V4SF")
1931 (and (eq_attr "alternative" "2")
1932 (match_test "TARGET_SSE_TYPELESS_STORES"))
1933 (const_string "V4SF")]
1934 (const_string "TI")))])
1936 (define_insn "*movdi_internal_rex64"
1937 [(set (match_operand:DI 0 "nonimmediate_operand"
1938 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1939 (match_operand:DI 1 "general_operand"
1940 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1941 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1943 switch (get_attr_type (insn))
1946 if (SSE_REG_P (operands[0]))
1947 return "movq2dq\t{%1, %0|%0, %1}";
1949 return "movdq2q\t{%1, %0|%0, %1}";
1952 if (get_attr_mode (insn) == MODE_TI)
1953 return "%vmovdqa\t{%1, %0|%0, %1}";
1954 /* Handle broken assemblers that require movd instead of movq. */
1955 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1956 return "%vmovd\t{%1, %0|%0, %1}";
1958 return "%vmovq\t{%1, %0|%0, %1}";
1961 /* Handle broken assemblers that require movd instead of movq. */
1962 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1963 return "movd\t{%1, %0|%0, %1}";
1965 return "movq\t{%1, %0|%0, %1}";
1968 return standard_sse_constant_opcode (insn, operands[1]);
1971 return "pxor\t%0, %0";
1977 return "lea{q}\t{%E1, %0|%0, %E1}";
1980 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1981 if (get_attr_mode (insn) == MODE_SI)
1982 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1983 else if (which_alternative == 2)
1984 return "movabs{q}\t{%1, %0|%0, %1}";
1985 else if (ix86_use_lea_for_mov (insn, operands))
1986 return "lea{q}\t{%E1, %0|%0, %E1}";
1988 return "mov{q}\t{%1, %0|%0, %1}";
1992 (cond [(eq_attr "alternative" "4")
1993 (const_string "multi")
1994 (eq_attr "alternative" "5")
1995 (const_string "mmx")
1996 (eq_attr "alternative" "6,7,8,9")
1997 (const_string "mmxmov")
1998 (eq_attr "alternative" "10")
1999 (const_string "sselog1")
2000 (eq_attr "alternative" "11,12,13,14,15")
2001 (const_string "ssemov")
2002 (eq_attr "alternative" "16,17")
2003 (const_string "ssecvt")
2004 (match_operand 1 "pic_32bit_operand")
2005 (const_string "lea")
2007 (const_string "imov")))
2010 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2012 (const_string "*")))
2013 (set (attr "length_immediate")
2015 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2017 (const_string "*")))
2018 (set (attr "prefix_rex")
2019 (if_then_else (eq_attr "alternative" "8,9")
2021 (const_string "*")))
2022 (set (attr "prefix_data16")
2023 (if_then_else (eq_attr "alternative" "11")
2025 (const_string "*")))
2026 (set (attr "prefix")
2027 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2028 (const_string "maybe_vex")
2029 (const_string "orig")))
2030 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2032 ;; Reload patterns to support multi-word load/store
2033 ;; with non-offsetable address.
2034 (define_expand "reload_noff_store"
2035 [(parallel [(match_operand 0 "memory_operand" "=m")
2036 (match_operand 1 "register_operand" "r")
2037 (match_operand:DI 2 "register_operand" "=&r")])]
2040 rtx mem = operands[0];
2041 rtx addr = XEXP (mem, 0);
2043 emit_move_insn (operands[2], addr);
2044 mem = replace_equiv_address_nv (mem, operands[2]);
2046 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2050 (define_expand "reload_noff_load"
2051 [(parallel [(match_operand 0 "register_operand" "=r")
2052 (match_operand 1 "memory_operand" "m")
2053 (match_operand:DI 2 "register_operand" "=r")])]
2056 rtx mem = operands[1];
2057 rtx addr = XEXP (mem, 0);
2059 emit_move_insn (operands[2], addr);
2060 mem = replace_equiv_address_nv (mem, operands[2]);
2062 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2066 ;; Convert impossible stores of immediate to existing instructions.
2067 ;; First try to get scratch register and go through it. In case this
2068 ;; fails, move by 32bit parts.
2070 [(match_scratch:DI 2 "r")
2071 (set (match_operand:DI 0 "memory_operand")
2072 (match_operand:DI 1 "immediate_operand"))]
2073 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2074 && !x86_64_immediate_operand (operands[1], DImode)"
2075 [(set (match_dup 2) (match_dup 1))
2076 (set (match_dup 0) (match_dup 2))])
2078 ;; We need to define this as both peepholer and splitter for case
2079 ;; peephole2 pass is not run.
2080 ;; "&& 1" is needed to keep it from matching the previous pattern.
2082 [(set (match_operand:DI 0 "memory_operand")
2083 (match_operand:DI 1 "immediate_operand"))]
2084 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2085 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2086 [(set (match_dup 2) (match_dup 3))
2087 (set (match_dup 4) (match_dup 5))]
2088 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2091 [(set (match_operand:DI 0 "memory_operand")
2092 (match_operand:DI 1 "immediate_operand"))]
2093 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2094 ? epilogue_completed : reload_completed)
2095 && !symbolic_operand (operands[1], DImode)
2096 && !x86_64_immediate_operand (operands[1], DImode)"
2097 [(set (match_dup 2) (match_dup 3))
2098 (set (match_dup 4) (match_dup 5))]
2099 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2101 (define_insn "*movdi_internal"
2102 [(set (match_operand:DI 0 "nonimmediate_operand"
2103 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2104 (match_operand:DI 1 "general_operand"
2105 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2106 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2108 switch (get_attr_type (insn))
2111 if (SSE_REG_P (operands[0]))
2112 return "movq2dq\t{%1, %0|%0, %1}";
2114 return "movdq2q\t{%1, %0|%0, %1}";
2117 switch (get_attr_mode (insn))
2120 return "%vmovdqa\t{%1, %0|%0, %1}";
2122 return "%vmovq\t{%1, %0|%0, %1}";
2124 return "movaps\t{%1, %0|%0, %1}";
2126 return "movlps\t{%1, %0|%0, %1}";
2132 return "movq\t{%1, %0|%0, %1}";
2135 return standard_sse_constant_opcode (insn, operands[1]);
2138 return "pxor\t%0, %0";
2148 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2149 (const_string "sse2")
2150 (eq_attr "alternative" "9,10,11,12")
2151 (const_string "noavx")
2153 (const_string "*")))
2155 (cond [(eq_attr "alternative" "0,1")
2156 (const_string "multi")
2157 (eq_attr "alternative" "2")
2158 (const_string "mmx")
2159 (eq_attr "alternative" "3,4")
2160 (const_string "mmxmov")
2161 (eq_attr "alternative" "5,9")
2162 (const_string "sselog1")
2163 (eq_attr "alternative" "13,14")
2164 (const_string "ssecvt")
2166 (const_string "ssemov")))
2167 (set (attr "prefix")
2168 (if_then_else (eq_attr "alternative" "5,6,7,8")
2169 (const_string "maybe_vex")
2170 (const_string "orig")))
2171 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2174 [(set (match_operand:DI 0 "nonimmediate_operand")
2175 (match_operand:DI 1 "general_operand"))]
2176 "!TARGET_64BIT && reload_completed
2177 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2178 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2180 "ix86_split_long_move (operands); DONE;")
2182 (define_insn "*movsi_internal"
2183 [(set (match_operand:SI 0 "nonimmediate_operand"
2184 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2185 (match_operand:SI 1 "general_operand"
2186 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2187 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2189 switch (get_attr_type (insn))
2192 return standard_sse_constant_opcode (insn, operands[1]);
2195 switch (get_attr_mode (insn))
2198 return "%vmovdqa\t{%1, %0|%0, %1}";
2200 return "%vmovaps\t{%1, %0|%0, %1}";
2202 return "%vmovd\t{%1, %0|%0, %1}";
2204 return "%vmovss\t{%1, %0|%0, %1}";
2210 return "pxor\t%0, %0";
2213 if (get_attr_mode (insn) == MODE_DI)
2214 return "movq\t{%1, %0|%0, %1}";
2215 return "movd\t{%1, %0|%0, %1}";
2218 return "lea{l}\t{%E1, %0|%0, %E1}";
2221 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2222 if (ix86_use_lea_for_mov (insn, operands))
2223 return "lea{l}\t{%E1, %0|%0, %E1}";
2225 return "mov{l}\t{%1, %0|%0, %1}";
2229 (cond [(eq_attr "alternative" "2")
2230 (const_string "mmx")
2231 (eq_attr "alternative" "3,4,5")
2232 (const_string "mmxmov")
2233 (eq_attr "alternative" "6")
2234 (const_string "sselog1")
2235 (eq_attr "alternative" "7,8,9,10,11")
2236 (const_string "ssemov")
2237 (match_operand 1 "pic_32bit_operand")
2238 (const_string "lea")
2240 (const_string "imov")))
2241 (set (attr "prefix")
2242 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2243 (const_string "orig")
2244 (const_string "maybe_vex")))
2245 (set (attr "prefix_data16")
2246 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2248 (const_string "*")))
2250 (cond [(eq_attr "alternative" "2,3")
2252 (eq_attr "alternative" "6,7")
2254 (not (match_test "TARGET_SSE2"))
2255 (const_string "V4SF")
2256 (const_string "TI"))
2257 (and (eq_attr "alternative" "8,9,10,11")
2258 (not (match_test "TARGET_SSE2")))
2261 (const_string "SI")))])
2263 (define_insn "*movhi_internal"
2264 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2265 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2266 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2268 switch (get_attr_type (insn))
2271 /* movzwl is faster than movw on p2 due to partial word stalls,
2272 though not as fast as an aligned movl. */
2273 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2275 if (get_attr_mode (insn) == MODE_SI)
2276 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2278 return "mov{w}\t{%1, %0|%0, %1}";
2282 (cond [(match_test "optimize_function_for_size_p (cfun)")
2283 (const_string "imov")
2284 (and (eq_attr "alternative" "0")
2285 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2286 (not (match_test "TARGET_HIMODE_MATH"))))
2287 (const_string "imov")
2288 (and (eq_attr "alternative" "1,2")
2289 (match_operand:HI 1 "aligned_operand"))
2290 (const_string "imov")
2291 (and (match_test "TARGET_MOVX")
2292 (eq_attr "alternative" "0,2"))
2293 (const_string "imovx")
2295 (const_string "imov")))
2297 (cond [(eq_attr "type" "imovx")
2299 (and (eq_attr "alternative" "1,2")
2300 (match_operand:HI 1 "aligned_operand"))
2302 (and (eq_attr "alternative" "0")
2303 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2304 (not (match_test "TARGET_HIMODE_MATH"))))
2307 (const_string "HI")))])
2309 ;; Situation is quite tricky about when to choose full sized (SImode) move
2310 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2311 ;; partial register dependency machines (such as AMD Athlon), where QImode
2312 ;; moves issue extra dependency and for partial register stalls machines
2313 ;; that don't use QImode patterns (and QImode move cause stall on the next
2316 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2317 ;; register stall machines with, where we use QImode instructions, since
2318 ;; partial register stall can be caused there. Then we use movzx.
2319 (define_insn "*movqi_internal"
2320 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2321 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2322 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2324 switch (get_attr_type (insn))
2327 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2328 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2330 if (get_attr_mode (insn) == MODE_SI)
2331 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2333 return "mov{b}\t{%1, %0|%0, %1}";
2337 (cond [(and (eq_attr "alternative" "5")
2338 (not (match_operand:QI 1 "aligned_operand")))
2339 (const_string "imovx")
2340 (match_test "optimize_function_for_size_p (cfun)")
2341 (const_string "imov")
2342 (and (eq_attr "alternative" "3")
2343 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2344 (not (match_test "TARGET_QIMODE_MATH"))))
2345 (const_string "imov")
2346 (eq_attr "alternative" "3,5")
2347 (const_string "imovx")
2348 (and (match_test "TARGET_MOVX")
2349 (eq_attr "alternative" "2"))
2350 (const_string "imovx")
2352 (const_string "imov")))
2354 (cond [(eq_attr "alternative" "3,4,5")
2356 (eq_attr "alternative" "6")
2358 (eq_attr "type" "imovx")
2360 (and (eq_attr "type" "imov")
2361 (and (eq_attr "alternative" "0,1")
2362 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2363 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2364 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2366 ;; Avoid partial register stalls when not using QImode arithmetic
2367 (and (eq_attr "type" "imov")
2368 (and (eq_attr "alternative" "0,1")
2369 (and (match_test "TARGET_PARTIAL_REG_STALL")
2370 (not (match_test "TARGET_QIMODE_MATH")))))
2373 (const_string "QI")))])
2375 ;; Stores and loads of ax to arbitrary constant address.
2376 ;; We fake an second form of instruction to force reload to load address
2377 ;; into register when rax is not available
2378 (define_insn "*movabs<mode>_1"
2379 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2380 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2381 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2383 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2384 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2385 [(set_attr "type" "imov")
2386 (set_attr "modrm" "0,*")
2387 (set_attr "length_address" "8,0")
2388 (set_attr "length_immediate" "0,*")
2389 (set_attr "memory" "store")
2390 (set_attr "mode" "<MODE>")])
2392 (define_insn "*movabs<mode>_2"
2393 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2394 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2395 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2397 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2398 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2399 [(set_attr "type" "imov")
2400 (set_attr "modrm" "0,*")
2401 (set_attr "length_address" "8,0")
2402 (set_attr "length_immediate" "0")
2403 (set_attr "memory" "load")
2404 (set_attr "mode" "<MODE>")])
2406 (define_insn "*swap<mode>"
2407 [(set (match_operand:SWI48 0 "register_operand" "+r")
2408 (match_operand:SWI48 1 "register_operand" "+r"))
2412 "xchg{<imodesuffix>}\t%1, %0"
2413 [(set_attr "type" "imov")
2414 (set_attr "mode" "<MODE>")
2415 (set_attr "pent_pair" "np")
2416 (set_attr "athlon_decode" "vector")
2417 (set_attr "amdfam10_decode" "double")
2418 (set_attr "bdver1_decode" "double")])
2420 (define_insn "*swap<mode>_1"
2421 [(set (match_operand:SWI12 0 "register_operand" "+r")
2422 (match_operand:SWI12 1 "register_operand" "+r"))
2425 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2427 [(set_attr "type" "imov")
2428 (set_attr "mode" "SI")
2429 (set_attr "pent_pair" "np")
2430 (set_attr "athlon_decode" "vector")
2431 (set_attr "amdfam10_decode" "double")
2432 (set_attr "bdver1_decode" "double")])
2434 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2435 ;; is disabled for AMDFAM10
2436 (define_insn "*swap<mode>_2"
2437 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2438 (match_operand:SWI12 1 "register_operand" "+<r>"))
2441 "TARGET_PARTIAL_REG_STALL"
2442 "xchg{<imodesuffix>}\t%1, %0"
2443 [(set_attr "type" "imov")
2444 (set_attr "mode" "<MODE>")
2445 (set_attr "pent_pair" "np")
2446 (set_attr "athlon_decode" "vector")])
2448 (define_expand "movstrict<mode>"
2449 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand"))
2450 (match_operand:SWI12 1 "general_operand"))]
2453 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2455 if (GET_CODE (operands[0]) == SUBREG
2456 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2458 /* Don't generate memory->memory moves, go through a register */
2459 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2460 operands[1] = force_reg (<MODE>mode, operands[1]);
2463 (define_insn "*movstrict<mode>_1"
2464 [(set (strict_low_part
2465 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2466 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2467 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2468 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2469 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2470 [(set_attr "type" "imov")
2471 (set_attr "mode" "<MODE>")])
2473 (define_insn "*movstrict<mode>_xor"
2474 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2475 (match_operand:SWI12 1 "const0_operand"))
2476 (clobber (reg:CC FLAGS_REG))]
2478 "xor{<imodesuffix>}\t%0, %0"
2479 [(set_attr "type" "alu1")
2480 (set_attr "mode" "<MODE>")
2481 (set_attr "length_immediate" "0")])
2483 (define_insn "*mov<mode>_extv_1"
2484 [(set (match_operand:SWI24 0 "register_operand" "=R")
2485 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2489 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2490 [(set_attr "type" "imovx")
2491 (set_attr "mode" "SI")])
2493 (define_insn "*movqi_extv_1_rex64"
2494 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2495 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2500 switch (get_attr_type (insn))
2503 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2505 return "mov{b}\t{%h1, %0|%0, %h1}";
2509 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2510 (match_test "TARGET_MOVX"))
2511 (const_string "imovx")
2512 (const_string "imov")))
2514 (if_then_else (eq_attr "type" "imovx")
2516 (const_string "QI")))])
2518 (define_insn "*movqi_extv_1"
2519 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2520 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2525 switch (get_attr_type (insn))
2528 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2530 return "mov{b}\t{%h1, %0|%0, %h1}";
2534 (if_then_else (and (match_operand:QI 0 "register_operand")
2535 (ior (not (match_operand:QI 0 "QIreg_operand"))
2536 (match_test "TARGET_MOVX")))
2537 (const_string "imovx")
2538 (const_string "imov")))
2540 (if_then_else (eq_attr "type" "imovx")
2542 (const_string "QI")))])
2544 (define_insn "*mov<mode>_extzv_1"
2545 [(set (match_operand:SWI48 0 "register_operand" "=R")
2546 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2550 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2551 [(set_attr "type" "imovx")
2552 (set_attr "mode" "SI")])
2554 (define_insn "*movqi_extzv_2_rex64"
2555 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2557 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2562 switch (get_attr_type (insn))
2565 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2567 return "mov{b}\t{%h1, %0|%0, %h1}";
2571 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand"))
2572 (match_test "TARGET_MOVX"))
2573 (const_string "imovx")
2574 (const_string "imov")))
2576 (if_then_else (eq_attr "type" "imovx")
2578 (const_string "QI")))])
2580 (define_insn "*movqi_extzv_2"
2581 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2583 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2588 switch (get_attr_type (insn))
2591 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2593 return "mov{b}\t{%h1, %0|%0, %h1}";
2597 (if_then_else (and (match_operand:QI 0 "register_operand")
2598 (ior (not (match_operand:QI 0 "QIreg_operand"))
2599 (match_test "TARGET_MOVX")))
2600 (const_string "imovx")
2601 (const_string "imov")))
2603 (if_then_else (eq_attr "type" "imovx")
2605 (const_string "QI")))])
2607 (define_expand "mov<mode>_insv_1"
2608 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand")
2611 (match_operand:SWI48 1 "nonmemory_operand"))])
2613 (define_insn "*mov<mode>_insv_1_rex64"
2614 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2617 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2619 "mov{b}\t{%b1, %h0|%h0, %b1}"
2620 [(set_attr "type" "imov")
2621 (set_attr "mode" "QI")])
2623 (define_insn "*movsi_insv_1"
2624 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2627 (match_operand:SI 1 "general_operand" "Qmn"))]
2629 "mov{b}\t{%b1, %h0|%h0, %b1}"
2630 [(set_attr "type" "imov")
2631 (set_attr "mode" "QI")])
2633 (define_insn "*movqi_insv_2"
2634 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2637 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2640 "mov{b}\t{%h1, %h0|%h0, %h1}"
2641 [(set_attr "type" "imov")
2642 (set_attr "mode" "QI")])
2644 ;; Floating point push instructions.
2646 (define_insn "*pushtf"
2647 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2648 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2651 /* This insn should be already split before reg-stack. */
2654 [(set_attr "type" "multi")
2655 (set_attr "unit" "sse,*,*")
2656 (set_attr "mode" "TF,SI,SI")])
2658 ;; %%% Kill this when call knows how to work this out.
2660 [(set (match_operand:TF 0 "push_operand")
2661 (match_operand:TF 1 "sse_reg_operand"))]
2662 "TARGET_SSE2 && reload_completed"
2663 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2664 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2666 (define_insn "*pushxf"
2667 [(set (match_operand:XF 0 "push_operand" "=<,<")
2668 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2669 "optimize_function_for_speed_p (cfun)"
2671 /* This insn should be already split before reg-stack. */
2674 [(set_attr "type" "multi")
2675 (set_attr "unit" "i387,*")
2676 (set_attr "mode" "XF,SI")])
2678 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2679 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2680 ;; Pushing using integer instructions is longer except for constants
2681 ;; and direct memory references (assuming that any given constant is pushed
2682 ;; only once, but this ought to be handled elsewhere).
2684 (define_insn "*pushxf_nointeger"
2685 [(set (match_operand:XF 0 "push_operand" "=<,<")
2686 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2687 "optimize_function_for_size_p (cfun)"
2689 /* This insn should be already split before reg-stack. */
2692 [(set_attr "type" "multi")
2693 (set_attr "unit" "i387,*")
2694 (set_attr "mode" "XF,SI")])
2696 ;; %%% Kill this when call knows how to work this out.
2698 [(set (match_operand:XF 0 "push_operand")
2699 (match_operand:XF 1 "fp_register_operand"))]
2701 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2702 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2703 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2705 (define_insn "*pushdf_rex64"
2706 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2707 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2710 /* This insn should be already split before reg-stack. */
2713 [(set_attr "type" "multi")
2714 (set_attr "unit" "i387,*,*")
2715 (set_attr "mode" "DF,DI,DF")])
2717 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2718 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2719 ;; On the average, pushdf using integers can be still shorter.
2721 (define_insn "*pushdf"
2722 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2723 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2726 /* This insn should be already split before reg-stack. */
2729 [(set_attr "isa" "*,*,sse2")
2730 (set_attr "type" "multi")
2731 (set_attr "unit" "i387,*,*")
2732 (set_attr "mode" "DF,DI,DF")])
2734 ;; %%% Kill this when call knows how to work this out.
2736 [(set (match_operand:DF 0 "push_operand")
2737 (match_operand:DF 1 "any_fp_register_operand"))]
2739 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2740 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2742 (define_insn "*pushsf_rex64"
2743 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2744 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2747 /* Anything else should be already split before reg-stack. */
2748 gcc_assert (which_alternative == 1);
2749 return "push{q}\t%q1";
2751 [(set_attr "type" "multi,push,multi")
2752 (set_attr "unit" "i387,*,*")
2753 (set_attr "mode" "SF,DI,SF")])
2755 (define_insn "*pushsf"
2756 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2757 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2760 /* Anything else should be already split before reg-stack. */
2761 gcc_assert (which_alternative == 1);
2762 return "push{l}\t%1";
2764 [(set_attr "type" "multi,push,multi")
2765 (set_attr "unit" "i387,*,*")
2766 (set_attr "mode" "SF,SI,SF")])
2768 ;; %%% Kill this when call knows how to work this out.
2770 [(set (match_operand:SF 0 "push_operand")
2771 (match_operand:SF 1 "any_fp_register_operand"))]
2773 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2774 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2775 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2778 [(set (match_operand:SF 0 "push_operand")
2779 (match_operand:SF 1 "memory_operand"))]
2781 && (operands[2] = find_constant_src (insn))"
2782 [(set (match_dup 0) (match_dup 2))])
2785 [(set (match_operand 0 "push_operand")
2786 (match_operand 1 "general_operand"))]
2788 && (GET_MODE (operands[0]) == TFmode
2789 || GET_MODE (operands[0]) == XFmode
2790 || GET_MODE (operands[0]) == DFmode)
2791 && !ANY_FP_REG_P (operands[1])"
2793 "ix86_split_long_move (operands); DONE;")
2795 ;; Floating point move instructions.
2797 (define_expand "movtf"
2798 [(set (match_operand:TF 0 "nonimmediate_operand")
2799 (match_operand:TF 1 "nonimmediate_operand"))]
2802 ix86_expand_move (TFmode, operands);
2806 (define_expand "mov<mode>"
2807 [(set (match_operand:X87MODEF 0 "nonimmediate_operand")
2808 (match_operand:X87MODEF 1 "general_operand"))]
2810 "ix86_expand_move (<MODE>mode, operands); DONE;")
2812 (define_insn "*movtf_internal"
2813 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2814 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2816 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2817 && (!can_create_pseudo_p ()
2818 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2819 || GET_CODE (operands[1]) != CONST_DOUBLE
2820 || (optimize_function_for_size_p (cfun)
2821 && standard_sse_constant_p (operands[1])
2822 && !memory_operand (operands[0], TFmode))
2823 || (!TARGET_MEMORY_MISMATCH_STALL
2824 && memory_operand (operands[0], TFmode)))"
2826 switch (which_alternative)
2830 /* Handle misaligned load/store since we
2831 don't have movmisaligntf pattern. */
2832 if (misaligned_operand (operands[0], TFmode)
2833 || misaligned_operand (operands[1], TFmode))
2835 if (get_attr_mode (insn) == MODE_V4SF)
2836 return "%vmovups\t{%1, %0|%0, %1}";
2838 return "%vmovdqu\t{%1, %0|%0, %1}";
2842 if (get_attr_mode (insn) == MODE_V4SF)
2843 return "%vmovaps\t{%1, %0|%0, %1}";
2845 return "%vmovdqa\t{%1, %0|%0, %1}";
2849 return standard_sse_constant_opcode (insn, operands[1]);
2859 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2860 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2862 (cond [(eq_attr "alternative" "0,2")
2864 (match_test "optimize_function_for_size_p (cfun)")
2865 (const_string "V4SF")
2866 (const_string "TI"))
2867 (eq_attr "alternative" "1")
2869 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2870 (match_test "optimize_function_for_size_p (cfun)"))
2871 (const_string "V4SF")
2872 (const_string "TI"))]
2873 (const_string "DI")))])
2875 ;; Possible store forwarding (partial memory) stall in alternative 4.
2876 (define_insn "*movxf_internal"
2877 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2878 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2879 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2880 && (!can_create_pseudo_p ()
2881 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2882 || GET_CODE (operands[1]) != CONST_DOUBLE
2883 || (optimize_function_for_size_p (cfun)
2884 && standard_80387_constant_p (operands[1]) > 0
2885 && !memory_operand (operands[0], XFmode))
2886 || (!TARGET_MEMORY_MISMATCH_STALL
2887 && memory_operand (operands[0], XFmode)))"
2889 switch (which_alternative)
2893 return output_387_reg_move (insn, operands);
2896 return standard_80387_constant_opcode (operands[1]);
2906 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2907 (set_attr "mode" "XF,XF,XF,SI,SI")])
2909 (define_insn "*movdf_internal_rex64"
2910 [(set (match_operand:DF 0 "nonimmediate_operand"
2911 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2912 (match_operand:DF 1 "general_operand"
2913 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2914 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2915 && (!can_create_pseudo_p ()
2916 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2917 || GET_CODE (operands[1]) != CONST_DOUBLE
2918 || (optimize_function_for_size_p (cfun)
2919 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2920 && standard_80387_constant_p (operands[1]) > 0)
2921 || (TARGET_SSE2 && TARGET_SSE_MATH
2922 && standard_sse_constant_p (operands[1]))))
2923 || memory_operand (operands[0], DFmode))"
2925 switch (which_alternative)
2929 return output_387_reg_move (insn, operands);
2932 return standard_80387_constant_opcode (operands[1]);
2936 return "mov{q}\t{%1, %0|%0, %1}";
2939 return "movabs{q}\t{%1, %0|%0, %1}";
2945 return standard_sse_constant_opcode (insn, operands[1]);
2950 switch (get_attr_mode (insn))
2953 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2954 return "%vmovapd\t{%1, %0|%0, %1}";
2956 return "%vmovaps\t{%1, %0|%0, %1}";
2959 return "%vmovq\t{%1, %0|%0, %1}";
2961 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2962 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2963 return "%vmovsd\t{%1, %0|%0, %1}";
2965 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2967 return "%vmovlps\t{%1, %d0|%d0, %1}";
2974 /* Handle broken assemblers that require movd instead of movq. */
2975 return "%vmovd\t{%1, %0|%0, %1}";
2982 (cond [(eq_attr "alternative" "0,1,2")
2983 (const_string "fmov")
2984 (eq_attr "alternative" "3,4,5")
2985 (const_string "imov")
2986 (eq_attr "alternative" "6")
2987 (const_string "multi")
2988 (eq_attr "alternative" "7")
2989 (const_string "sselog1")
2991 (const_string "ssemov")))
2994 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2996 (const_string "*")))
2997 (set (attr "length_immediate")
2999 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
3001 (const_string "*")))
3002 (set (attr "prefix")
3003 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3004 (const_string "orig")
3005 (const_string "maybe_vex")))
3006 (set (attr "prefix_data16")
3007 (if_then_else (eq_attr "mode" "V1DF")
3009 (const_string "*")))
3011 (cond [(eq_attr "alternative" "0,1,2")
3013 (eq_attr "alternative" "3,4,5,6,11,12")
3016 /* xorps is one byte shorter. */
3017 (eq_attr "alternative" "7")
3018 (cond [(match_test "optimize_function_for_size_p (cfun)")
3019 (const_string "V4SF")
3020 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3023 (const_string "V2DF"))
3025 /* For architectures resolving dependencies on
3026 whole SSE registers use APD move to break dependency
3027 chains, otherwise use short move to avoid extra work.
3029 movaps encodes one byte shorter. */
3030 (eq_attr "alternative" "8")
3032 [(match_test "optimize_function_for_size_p (cfun)")
3033 (const_string "V4SF")
3034 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3035 (const_string "V2DF")
3037 (const_string "DF"))
3038 /* For architectures resolving dependencies on register
3039 parts we may avoid extra work to zero out upper part
3041 (eq_attr "alternative" "9")
3043 (match_test "TARGET_SSE_SPLIT_REGS")
3044 (const_string "V1DF")
3045 (const_string "DF"))
3047 (const_string "DF")))])
3049 ;; Possible store forwarding (partial memory) stall in alternative 4.
3050 (define_insn "*movdf_internal"
3051 [(set (match_operand:DF 0 "nonimmediate_operand"
3052 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3053 (match_operand:DF 1 "general_operand"
3054 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3055 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3056 && (!can_create_pseudo_p ()
3057 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3058 || GET_CODE (operands[1]) != CONST_DOUBLE
3059 || (optimize_function_for_size_p (cfun)
3060 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3061 && standard_80387_constant_p (operands[1]) > 0)
3062 || (TARGET_SSE2 && TARGET_SSE_MATH
3063 && standard_sse_constant_p (operands[1])))
3064 && !memory_operand (operands[0], DFmode))
3065 || (!TARGET_MEMORY_MISMATCH_STALL
3066 && memory_operand (operands[0], DFmode)))"
3068 switch (which_alternative)
3072 return output_387_reg_move (insn, operands);
3075 return standard_80387_constant_opcode (operands[1]);
3083 return standard_sse_constant_opcode (insn, operands[1]);
3091 switch (get_attr_mode (insn))
3094 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3095 return "%vmovapd\t{%1, %0|%0, %1}";
3097 return "%vmovaps\t{%1, %0|%0, %1}";
3100 return "%vmovq\t{%1, %0|%0, %1}";
3102 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3103 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3104 return "%vmovsd\t{%1, %0|%0, %1}";
3106 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3108 return "%vmovlps\t{%1, %d0|%d0, %1}";
3118 (if_then_else (eq_attr "alternative" "5,6,7,8")
3119 (const_string "sse2")
3120 (const_string "*")))
3122 (cond [(eq_attr "alternative" "0,1,2")
3123 (const_string "fmov")
3124 (eq_attr "alternative" "3,4")
3125 (const_string "multi")
3126 (eq_attr "alternative" "5,9")
3127 (const_string "sselog1")
3129 (const_string "ssemov")))
3130 (set (attr "prefix")
3131 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3132 (const_string "orig")
3133 (const_string "maybe_vex")))
3134 (set (attr "prefix_data16")
3135 (if_then_else (eq_attr "mode" "V1DF")
3137 (const_string "*")))
3139 (cond [(eq_attr "alternative" "0,1,2")
3141 (eq_attr "alternative" "3,4")
3144 /* For SSE1, we have many fewer alternatives. */
3145 (not (match_test "TARGET_SSE2"))
3147 (eq_attr "alternative" "5,6,9,10")
3148 (const_string "V4SF")
3149 (const_string "V2SF"))
3151 /* xorps is one byte shorter. */
3152 (eq_attr "alternative" "5,9")
3153 (cond [(match_test "optimize_function_for_size_p (cfun)")
3154 (const_string "V4SF")
3155 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3158 (const_string "V2DF"))
3160 /* For architectures resolving dependencies on
3161 whole SSE registers use APD move to break dependency
3162 chains, otherwise use short move to avoid extra work.
3164 movaps encodes one byte shorter. */
3165 (eq_attr "alternative" "6,10")
3167 [(match_test "optimize_function_for_size_p (cfun)")
3168 (const_string "V4SF")
3169 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3170 (const_string "V2DF")
3172 (const_string "DF"))
3173 /* For architectures resolving dependencies on register
3174 parts we may avoid extra work to zero out upper part
3176 (eq_attr "alternative" "7,11")
3178 (match_test "TARGET_SSE_SPLIT_REGS")
3179 (const_string "V1DF")
3180 (const_string "DF"))
3182 (const_string "DF")))])
3184 (define_insn "*movsf_internal"
3185 [(set (match_operand:SF 0 "nonimmediate_operand"
3186 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3187 (match_operand:SF 1 "general_operand"
3188 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3189 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3190 && (!can_create_pseudo_p ()
3191 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3192 || GET_CODE (operands[1]) != CONST_DOUBLE
3193 || (optimize_function_for_size_p (cfun)
3194 && ((!TARGET_SSE_MATH
3195 && standard_80387_constant_p (operands[1]) > 0)
3197 && standard_sse_constant_p (operands[1]))))
3198 || memory_operand (operands[0], SFmode))"
3200 switch (which_alternative)
3204 return output_387_reg_move (insn, operands);
3207 return standard_80387_constant_opcode (operands[1]);
3211 return "mov{l}\t{%1, %0|%0, %1}";
3214 return standard_sse_constant_opcode (insn, operands[1]);
3217 if (get_attr_mode (insn) == MODE_V4SF)
3218 return "%vmovaps\t{%1, %0|%0, %1}";
3220 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3224 return "%vmovss\t{%1, %0|%0, %1}";
3230 return "movd\t{%1, %0|%0, %1}";
3233 return "movq\t{%1, %0|%0, %1}";
3237 return "%vmovd\t{%1, %0|%0, %1}";
3244 (cond [(eq_attr "alternative" "0,1,2")
3245 (const_string "fmov")
3246 (eq_attr "alternative" "3,4")
3247 (const_string "multi")
3248 (eq_attr "alternative" "5")
3249 (const_string "sselog1")
3250 (eq_attr "alternative" "9,10,11,14,15")
3251 (const_string "mmxmov")
3253 (const_string "ssemov")))
3254 (set (attr "prefix")
3255 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3256 (const_string "maybe_vex")
3257 (const_string "orig")))
3259 (cond [(eq_attr "alternative" "3,4,9,10")
3261 (eq_attr "alternative" "5")
3263 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3264 (match_test "TARGET_SSE2"))
3265 (not (match_test "optimize_function_for_size_p (cfun)")))
3267 (const_string "V4SF"))
3268 /* For architectures resolving dependencies on
3269 whole SSE registers use APS move to break dependency
3270 chains, otherwise use short move to avoid extra work.
3272 Do the same for architectures resolving dependencies on
3273 the parts. While in DF mode it is better to always handle
3274 just register parts, the SF mode is different due to lack
3275 of instructions to load just part of the register. It is
3276 better to maintain the whole registers in single format
3277 to avoid problems on using packed logical operations. */
3278 (eq_attr "alternative" "6")
3280 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3281 (match_test "TARGET_SSE_SPLIT_REGS"))
3282 (const_string "V4SF")
3283 (const_string "SF"))
3284 (eq_attr "alternative" "11")
3285 (const_string "DI")]
3286 (const_string "SF")))])
3289 [(set (match_operand 0 "any_fp_register_operand")
3290 (match_operand 1 "memory_operand"))]
3292 && (GET_MODE (operands[0]) == TFmode
3293 || GET_MODE (operands[0]) == XFmode
3294 || GET_MODE (operands[0]) == DFmode
3295 || GET_MODE (operands[0]) == SFmode)
3296 && (operands[2] = find_constant_src (insn))"
3297 [(set (match_dup 0) (match_dup 2))]
3299 rtx c = operands[2];
3300 int r = REGNO (operands[0]);
3302 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3303 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3308 [(set (match_operand 0 "any_fp_register_operand")
3309 (float_extend (match_operand 1 "memory_operand")))]
3311 && (GET_MODE (operands[0]) == TFmode
3312 || GET_MODE (operands[0]) == XFmode
3313 || GET_MODE (operands[0]) == DFmode)
3314 && (operands[2] = find_constant_src (insn))"
3315 [(set (match_dup 0) (match_dup 2))]
3317 rtx c = operands[2];
3318 int r = REGNO (operands[0]);
3320 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3321 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3325 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3327 [(set (match_operand:X87MODEF 0 "fp_register_operand")
3328 (match_operand:X87MODEF 1 "immediate_operand"))]
3330 && (standard_80387_constant_p (operands[1]) == 8
3331 || standard_80387_constant_p (operands[1]) == 9)"
3332 [(set (match_dup 0)(match_dup 1))
3334 (neg:X87MODEF (match_dup 0)))]
3338 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3339 if (real_isnegzero (&r))
3340 operands[1] = CONST0_RTX (<MODE>mode);
3342 operands[1] = CONST1_RTX (<MODE>mode);
3346 [(set (match_operand 0 "nonimmediate_operand")
3347 (match_operand 1 "general_operand"))]
3349 && (GET_MODE (operands[0]) == TFmode
3350 || GET_MODE (operands[0]) == XFmode
3351 || GET_MODE (operands[0]) == DFmode)
3352 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3354 "ix86_split_long_move (operands); DONE;")
3356 (define_insn "swapxf"
3357 [(set (match_operand:XF 0 "register_operand" "+f")
3358 (match_operand:XF 1 "register_operand" "+f"))
3363 if (STACK_TOP_P (operands[0]))
3368 [(set_attr "type" "fxch")
3369 (set_attr "mode" "XF")])
3371 (define_insn "*swap<mode>"
3372 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3373 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3376 "TARGET_80387 || reload_completed"
3378 if (STACK_TOP_P (operands[0]))
3383 [(set_attr "type" "fxch")
3384 (set_attr "mode" "<MODE>")])
3386 ;; Zero extension instructions
3388 (define_expand "zero_extendsidi2"
3389 [(set (match_operand:DI 0 "nonimmediate_operand")
3390 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))])
3392 (define_insn "*zero_extendsidi2_rex64"
3393 [(set (match_operand:DI 0 "nonimmediate_operand"
3394 "=r ,o,?*Ym,?*y,?*Yi,!*x")
3396 (match_operand:SI 1 "x86_64_zext_general_operand"
3397 "rmZ,0,r ,m ,r ,m*x")))]
3400 mov{l}\t{%1, %k0|%k0, %1}
3402 movd\t{%1, %0|%0, %1}
3403 movd\t{%1, %0|%0, %1}
3404 %vmovd\t{%1, %0|%0, %1}
3405 %vmovd\t{%1, %0|%0, %1}"
3406 [(set_attr "isa" "*,*,*,*,*,sse2")
3407 (set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3408 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3409 (set_attr "prefix_0f" "0,*,*,*,*,*")
3410 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3412 (define_insn "*zero_extendsidi2"
3413 [(set (match_operand:DI 0 "nonimmediate_operand"
3414 "=ro,?r,?o,?*Ym,?*y,?*Yi,!*x")
3415 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3416 "0 ,rm,r ,r ,m ,r ,m*x")))]
3422 movd\t{%1, %0|%0, %1}
3423 movd\t{%1, %0|%0, %1}
3424 %vmovd\t{%1, %0|%0, %1}
3425 %vmovd\t{%1, %0|%0, %1}"
3426 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3427 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3428 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3429 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3432 [(set (match_operand:DI 0 "memory_operand")
3433 (zero_extend:DI (match_operand:SI 1 "memory_operand")))]
3435 [(set (match_dup 4) (const_int 0))]
3436 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3439 [(set (match_operand:DI 0 "register_operand")
3440 (zero_extend:DI (match_operand:SI 1 "register_operand")))]
3441 "!TARGET_64BIT && reload_completed
3442 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3443 && true_regnum (operands[0]) == true_regnum (operands[1])"
3444 [(set (match_dup 4) (const_int 0))]
3445 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3448 [(set (match_operand:DI 0 "nonimmediate_operand")
3449 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand")))]
3450 "!TARGET_64BIT && reload_completed
3451 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3452 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3453 [(set (match_dup 3) (match_dup 1))
3454 (set (match_dup 4) (const_int 0))]
3455 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3457 (define_insn "zero_extend<mode>di2"
3458 [(set (match_operand:DI 0 "register_operand" "=r")
3460 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3462 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3463 [(set_attr "type" "imovx")
3464 (set_attr "mode" "SI")])
3466 (define_expand "zero_extend<mode>si2"
3467 [(set (match_operand:SI 0 "register_operand")
3468 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand")))]
3471 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3473 operands[1] = force_reg (<MODE>mode, operands[1]);
3474 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3479 (define_insn_and_split "zero_extend<mode>si2_and"
3480 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3482 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3483 (clobber (reg:CC FLAGS_REG))]
3484 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3486 "&& reload_completed"
3487 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3488 (clobber (reg:CC FLAGS_REG))])]
3490 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3492 ix86_expand_clear (operands[0]);
3494 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3495 emit_insn (gen_movstrict<mode>
3496 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3500 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3502 [(set_attr "type" "alu1")
3503 (set_attr "mode" "SI")])
3505 (define_insn "*zero_extend<mode>si2"
3506 [(set (match_operand:SI 0 "register_operand" "=r")
3508 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3509 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3510 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3511 [(set_attr "type" "imovx")
3512 (set_attr "mode" "SI")])
3514 (define_expand "zero_extendqihi2"
3515 [(set (match_operand:HI 0 "register_operand")
3516 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand")))]
3519 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3521 operands[1] = force_reg (QImode, operands[1]);
3522 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3527 (define_insn_and_split "zero_extendqihi2_and"
3528 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3529 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3530 (clobber (reg:CC FLAGS_REG))]
3531 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3533 "&& reload_completed"
3534 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3535 (clobber (reg:CC FLAGS_REG))])]
3537 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3539 ix86_expand_clear (operands[0]);
3541 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3542 emit_insn (gen_movstrictqi
3543 (gen_lowpart (QImode, operands[0]), operands[1]));
3547 operands[0] = gen_lowpart (SImode, operands[0]);
3549 [(set_attr "type" "alu1")
3550 (set_attr "mode" "SI")])
3552 ; zero extend to SImode to avoid partial register stalls
3553 (define_insn "*zero_extendqihi2"
3554 [(set (match_operand:HI 0 "register_operand" "=r")
3555 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3556 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3557 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3558 [(set_attr "type" "imovx")
3559 (set_attr "mode" "SI")])
3561 ;; Sign extension instructions
3563 (define_expand "extendsidi2"
3564 [(set (match_operand:DI 0 "register_operand")
3565 (sign_extend:DI (match_operand:SI 1 "register_operand")))]
3570 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3575 (define_insn "*extendsidi2_rex64"
3576 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3577 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3581 movs{lq|x}\t{%1, %0|%0, %1}"
3582 [(set_attr "type" "imovx")
3583 (set_attr "mode" "DI")
3584 (set_attr "prefix_0f" "0")
3585 (set_attr "modrm" "0,1")])
3587 (define_insn "extendsidi2_1"
3588 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3589 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3590 (clobber (reg:CC FLAGS_REG))
3591 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3595 ;; Extend to memory case when source register does die.
3597 [(set (match_operand:DI 0 "memory_operand")
3598 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3599 (clobber (reg:CC FLAGS_REG))
3600 (clobber (match_operand:SI 2 "register_operand"))]
3602 && dead_or_set_p (insn, operands[1])
3603 && !reg_mentioned_p (operands[1], operands[0]))"
3604 [(set (match_dup 3) (match_dup 1))
3605 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3606 (clobber (reg:CC FLAGS_REG))])
3607 (set (match_dup 4) (match_dup 1))]
3608 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3610 ;; Extend to memory case when source register does not die.
3612 [(set (match_operand:DI 0 "memory_operand")
3613 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3614 (clobber (reg:CC FLAGS_REG))
3615 (clobber (match_operand:SI 2 "register_operand"))]
3619 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3621 emit_move_insn (operands[3], operands[1]);
3623 /* Generate a cltd if possible and doing so it profitable. */
3624 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3625 && true_regnum (operands[1]) == AX_REG
3626 && true_regnum (operands[2]) == DX_REG)
3628 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3632 emit_move_insn (operands[2], operands[1]);
3633 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3635 emit_move_insn (operands[4], operands[2]);
3639 ;; Extend to register case. Optimize case where source and destination
3640 ;; registers match and cases where we can use cltd.
3642 [(set (match_operand:DI 0 "register_operand")
3643 (sign_extend:DI (match_operand:SI 1 "register_operand")))
3644 (clobber (reg:CC FLAGS_REG))
3645 (clobber (match_scratch:SI 2))]
3649 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3651 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3652 emit_move_insn (operands[3], operands[1]);
3654 /* Generate a cltd if possible and doing so it profitable. */
3655 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3656 && true_regnum (operands[3]) == AX_REG
3657 && true_regnum (operands[4]) == DX_REG)
3659 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3663 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3664 emit_move_insn (operands[4], operands[1]);
3666 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3670 (define_insn "extend<mode>di2"
3671 [(set (match_operand:DI 0 "register_operand" "=r")
3673 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3675 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3676 [(set_attr "type" "imovx")
3677 (set_attr "mode" "DI")])
3679 (define_insn "extendhisi2"
3680 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3681 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3684 switch (get_attr_prefix_0f (insn))
3687 return "{cwtl|cwde}";
3689 return "movs{wl|x}\t{%1, %0|%0, %1}";
3692 [(set_attr "type" "imovx")
3693 (set_attr "mode" "SI")
3694 (set (attr "prefix_0f")
3695 ;; movsx is short decodable while cwtl is vector decoded.
3696 (if_then_else (and (eq_attr "cpu" "!k6")
3697 (eq_attr "alternative" "0"))
3699 (const_string "1")))
3701 (if_then_else (eq_attr "prefix_0f" "0")
3703 (const_string "1")))])
3705 (define_insn "*extendhisi2_zext"
3706 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3709 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3712 switch (get_attr_prefix_0f (insn))
3715 return "{cwtl|cwde}";
3717 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3720 [(set_attr "type" "imovx")
3721 (set_attr "mode" "SI")
3722 (set (attr "prefix_0f")
3723 ;; movsx is short decodable while cwtl is vector decoded.
3724 (if_then_else (and (eq_attr "cpu" "!k6")
3725 (eq_attr "alternative" "0"))
3727 (const_string "1")))
3729 (if_then_else (eq_attr "prefix_0f" "0")
3731 (const_string "1")))])
3733 (define_insn "extendqisi2"
3734 [(set (match_operand:SI 0 "register_operand" "=r")
3735 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3737 "movs{bl|x}\t{%1, %0|%0, %1}"
3738 [(set_attr "type" "imovx")
3739 (set_attr "mode" "SI")])
3741 (define_insn "*extendqisi2_zext"
3742 [(set (match_operand:DI 0 "register_operand" "=r")
3744 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3746 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3747 [(set_attr "type" "imovx")
3748 (set_attr "mode" "SI")])
3750 (define_insn "extendqihi2"
3751 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3752 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3755 switch (get_attr_prefix_0f (insn))
3758 return "{cbtw|cbw}";
3760 return "movs{bw|x}\t{%1, %0|%0, %1}";
3763 [(set_attr "type" "imovx")
3764 (set_attr "mode" "HI")
3765 (set (attr "prefix_0f")
3766 ;; movsx is short decodable while cwtl is vector decoded.
3767 (if_then_else (and (eq_attr "cpu" "!k6")
3768 (eq_attr "alternative" "0"))
3770 (const_string "1")))
3772 (if_then_else (eq_attr "prefix_0f" "0")
3774 (const_string "1")))])
3776 ;; Conversions between float and double.
3778 ;; These are all no-ops in the model used for the 80387.
3779 ;; So just emit moves.
3781 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3783 [(set (match_operand:DF 0 "push_operand")
3784 (float_extend:DF (match_operand:SF 1 "fp_register_operand")))]
3786 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3787 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3790 [(set (match_operand:XF 0 "push_operand")
3791 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand")))]
3793 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3794 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3795 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3797 (define_expand "extendsfdf2"
3798 [(set (match_operand:DF 0 "nonimmediate_operand")
3799 (float_extend:DF (match_operand:SF 1 "general_operand")))]
3800 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3802 /* ??? Needed for compress_float_constant since all fp constants
3803 are TARGET_LEGITIMATE_CONSTANT_P. */
3804 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3806 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3807 && standard_80387_constant_p (operands[1]) > 0)
3809 operands[1] = simplify_const_unary_operation
3810 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3811 emit_move_insn_1 (operands[0], operands[1]);
3814 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3818 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3820 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3822 We do the conversion post reload to avoid producing of 128bit spills
3823 that might lead to ICE on 32bit target. The sequence unlikely combine
3826 [(set (match_operand:DF 0 "register_operand")
3828 (match_operand:SF 1 "nonimmediate_operand")))]
3829 "TARGET_USE_VECTOR_FP_CONVERTS
3830 && optimize_insn_for_speed_p ()
3831 && reload_completed && SSE_REG_P (operands[0])"
3836 (parallel [(const_int 0) (const_int 1)]))))]
3838 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3839 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3840 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3841 Try to avoid move when unpacking can be done in source. */
3842 if (REG_P (operands[1]))
3844 /* If it is unsafe to overwrite upper half of source, we need
3845 to move to destination and unpack there. */
3846 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3847 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3848 && true_regnum (operands[0]) != true_regnum (operands[1]))
3850 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3851 emit_move_insn (tmp, operands[1]);
3854 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3855 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3859 emit_insn (gen_vec_setv4sf_0 (operands[3],
3860 CONST0_RTX (V4SFmode), operands[1]));
3863 (define_insn "*extendsfdf2_mixed"
3864 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3866 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3867 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3869 switch (which_alternative)
3873 return output_387_reg_move (insn, operands);
3876 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3882 [(set_attr "type" "fmov,fmov,ssecvt")
3883 (set_attr "prefix" "orig,orig,maybe_vex")
3884 (set_attr "mode" "SF,XF,DF")])
3886 (define_insn "*extendsfdf2_sse"
3887 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3888 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3889 "TARGET_SSE2 && TARGET_SSE_MATH"
3890 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3891 [(set_attr "type" "ssecvt")
3892 (set_attr "prefix" "maybe_vex")
3893 (set_attr "mode" "DF")])
3895 (define_insn "*extendsfdf2_i387"
3896 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3897 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3899 "* return output_387_reg_move (insn, operands);"
3900 [(set_attr "type" "fmov")
3901 (set_attr "mode" "SF,XF")])
3903 (define_expand "extend<mode>xf2"
3904 [(set (match_operand:XF 0 "nonimmediate_operand")
3905 (float_extend:XF (match_operand:MODEF 1 "general_operand")))]
3908 /* ??? Needed for compress_float_constant since all fp constants
3909 are TARGET_LEGITIMATE_CONSTANT_P. */
3910 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3912 if (standard_80387_constant_p (operands[1]) > 0)
3914 operands[1] = simplify_const_unary_operation
3915 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3916 emit_move_insn_1 (operands[0], operands[1]);
3919 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3923 (define_insn "*extend<mode>xf2_i387"
3924 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3926 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3928 "* return output_387_reg_move (insn, operands);"
3929 [(set_attr "type" "fmov")
3930 (set_attr "mode" "<MODE>,XF")])
3932 ;; %%% This seems bad bad news.
3933 ;; This cannot output into an f-reg because there is no way to be sure
3934 ;; of truncating in that case. Otherwise this is just like a simple move
3935 ;; insn. So we pretend we can output to a reg in order to get better
3936 ;; register preferencing, but we really use a stack slot.
3938 ;; Conversion from DFmode to SFmode.
3940 (define_expand "truncdfsf2"
3941 [(set (match_operand:SF 0 "nonimmediate_operand")
3943 (match_operand:DF 1 "nonimmediate_operand")))]
3944 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3946 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3948 else if (flag_unsafe_math_optimizations)
3952 enum ix86_stack_slot slot = (virtuals_instantiated
3955 rtx temp = assign_386_stack_local (SFmode, slot);
3956 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3961 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3963 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3965 We do the conversion post reload to avoid producing of 128bit spills
3966 that might lead to ICE on 32bit target. The sequence unlikely combine
3969 [(set (match_operand:SF 0 "register_operand")
3971 (match_operand:DF 1 "nonimmediate_operand")))]
3972 "TARGET_USE_VECTOR_FP_CONVERTS
3973 && optimize_insn_for_speed_p ()
3974 && reload_completed && SSE_REG_P (operands[0])"
3977 (float_truncate:V2SF
3981 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3982 operands[3] = CONST0_RTX (V2SFmode);
3983 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3984 /* Use movsd for loading from memory, unpcklpd for registers.
3985 Try to avoid move when unpacking can be done in source, or SSE3
3986 movddup is available. */
3987 if (REG_P (operands[1]))
3990 && true_regnum (operands[0]) != true_regnum (operands[1])
3991 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3992 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3994 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3995 emit_move_insn (tmp, operands[1]);
3998 else if (!TARGET_SSE3)
3999 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4000 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4003 emit_insn (gen_sse2_loadlpd (operands[4],
4004 CONST0_RTX (V2DFmode), operands[1]));
4007 (define_expand "truncdfsf2_with_temp"
4008 [(parallel [(set (match_operand:SF 0)
4009 (float_truncate:SF (match_operand:DF 1)))
4010 (clobber (match_operand:SF 2))])])
4012 (define_insn "*truncdfsf_fast_mixed"
4013 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4015 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4016 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4018 switch (which_alternative)
4021 return output_387_reg_move (insn, operands);
4023 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4028 [(set_attr "type" "fmov,ssecvt")
4029 (set_attr "prefix" "orig,maybe_vex")
4030 (set_attr "mode" "SF")])
4032 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4033 ;; because nothing we do here is unsafe.
4034 (define_insn "*truncdfsf_fast_sse"
4035 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4037 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4038 "TARGET_SSE2 && TARGET_SSE_MATH"
4039 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4040 [(set_attr "type" "ssecvt")
4041 (set_attr "prefix" "maybe_vex")
4042 (set_attr "mode" "SF")])
4044 (define_insn "*truncdfsf_fast_i387"
4045 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4047 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4048 "TARGET_80387 && flag_unsafe_math_optimizations"
4049 "* return output_387_reg_move (insn, operands);"
4050 [(set_attr "type" "fmov")
4051 (set_attr "mode" "SF")])
4053 (define_insn "*truncdfsf_mixed"
4054 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4056 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4057 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4058 "TARGET_MIX_SSE_I387"
4060 switch (which_alternative)
4063 return output_387_reg_move (insn, operands);
4065 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4071 [(set_attr "isa" "*,sse2,*,*,*")
4072 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4073 (set_attr "unit" "*,*,i387,i387,i387")
4074 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4075 (set_attr "mode" "SF")])
4077 (define_insn "*truncdfsf_i387"
4078 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4080 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4081 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4084 switch (which_alternative)
4087 return output_387_reg_move (insn, operands);
4093 [(set_attr "type" "fmov,multi,multi,multi")
4094 (set_attr "unit" "*,i387,i387,i387")
4095 (set_attr "mode" "SF")])
4097 (define_insn "*truncdfsf2_i387_1"
4098 [(set (match_operand:SF 0 "memory_operand" "=m")
4100 (match_operand:DF 1 "register_operand" "f")))]
4102 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4103 && !TARGET_MIX_SSE_I387"
4104 "* return output_387_reg_move (insn, operands);"
4105 [(set_attr "type" "fmov")
4106 (set_attr "mode" "SF")])
4109 [(set (match_operand:SF 0 "register_operand")
4111 (match_operand:DF 1 "fp_register_operand")))
4112 (clobber (match_operand 2))]
4114 [(set (match_dup 2) (match_dup 1))
4115 (set (match_dup 0) (match_dup 2))]
4116 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4118 ;; Conversion from XFmode to {SF,DF}mode
4120 (define_expand "truncxf<mode>2"
4121 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand")
4122 (float_truncate:MODEF
4123 (match_operand:XF 1 "register_operand")))
4124 (clobber (match_dup 2))])]
4127 if (flag_unsafe_math_optimizations)
4129 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4130 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4131 if (reg != operands[0])
4132 emit_move_insn (operands[0], reg);
4137 enum ix86_stack_slot slot = (virtuals_instantiated
4140 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4144 (define_insn "*truncxfsf2_mixed"
4145 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4147 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4148 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4151 gcc_assert (!which_alternative);
4152 return output_387_reg_move (insn, operands);
4154 [(set_attr "type" "fmov,multi,multi,multi")
4155 (set_attr "unit" "*,i387,i387,i387")
4156 (set_attr "mode" "SF")])
4158 (define_insn "*truncxfdf2_mixed"
4159 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4161 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4162 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4165 gcc_assert (!which_alternative);
4166 return output_387_reg_move (insn, operands);
4168 [(set_attr "isa" "*,*,sse2,*")
4169 (set_attr "type" "fmov,multi,multi,multi")
4170 (set_attr "unit" "*,i387,i387,i387")
4171 (set_attr "mode" "DF")])
4173 (define_insn "truncxf<mode>2_i387_noop"
4174 [(set (match_operand:MODEF 0 "register_operand" "=f")
4175 (float_truncate:MODEF
4176 (match_operand:XF 1 "register_operand" "f")))]
4177 "TARGET_80387 && flag_unsafe_math_optimizations"
4178 "* return output_387_reg_move (insn, operands);"
4179 [(set_attr "type" "fmov")
4180 (set_attr "mode" "<MODE>")])
4182 (define_insn "*truncxf<mode>2_i387"
4183 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4184 (float_truncate:MODEF
4185 (match_operand:XF 1 "register_operand" "f")))]
4187 "* return output_387_reg_move (insn, operands);"
4188 [(set_attr "type" "fmov")
4189 (set_attr "mode" "<MODE>")])
4192 [(set (match_operand:MODEF 0 "register_operand")
4193 (float_truncate:MODEF
4194 (match_operand:XF 1 "register_operand")))
4195 (clobber (match_operand:MODEF 2 "memory_operand"))]
4196 "TARGET_80387 && reload_completed"
4197 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4198 (set (match_dup 0) (match_dup 2))])
4201 [(set (match_operand:MODEF 0 "memory_operand")
4202 (float_truncate:MODEF
4203 (match_operand:XF 1 "register_operand")))
4204 (clobber (match_operand:MODEF 2 "memory_operand"))]
4206 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4208 ;; Signed conversion to DImode.
4210 (define_expand "fix_truncxfdi2"
4211 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4212 (fix:DI (match_operand:XF 1 "register_operand")))
4213 (clobber (reg:CC FLAGS_REG))])]
4218 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4223 (define_expand "fix_trunc<mode>di2"
4224 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand")
4225 (fix:DI (match_operand:MODEF 1 "register_operand")))
4226 (clobber (reg:CC FLAGS_REG))])]
4227 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4230 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4232 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4235 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4237 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4238 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4239 if (out != operands[0])
4240 emit_move_insn (operands[0], out);
4245 ;; Signed conversion to SImode.
4247 (define_expand "fix_truncxfsi2"
4248 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4249 (fix:SI (match_operand:XF 1 "register_operand")))
4250 (clobber (reg:CC FLAGS_REG))])]
4255 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4260 (define_expand "fix_trunc<mode>si2"
4261 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand")
4262 (fix:SI (match_operand:MODEF 1 "register_operand")))
4263 (clobber (reg:CC FLAGS_REG))])]
4264 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4267 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4269 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4272 if (SSE_FLOAT_MODE_P (<MODE>mode))
4274 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4275 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4276 if (out != operands[0])
4277 emit_move_insn (operands[0], out);
4282 ;; Signed conversion to HImode.
4284 (define_expand "fix_trunc<mode>hi2"
4285 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand")
4286 (fix:HI (match_operand:X87MODEF 1 "register_operand")))
4287 (clobber (reg:CC FLAGS_REG))])]
4289 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4293 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4298 ;; Unsigned conversion to SImode.
4300 (define_expand "fixuns_trunc<mode>si2"
4302 [(set (match_operand:SI 0 "register_operand")
4304 (match_operand:MODEF 1 "nonimmediate_operand")))
4306 (clobber (match_scratch:<ssevecmode> 3))
4307 (clobber (match_scratch:<ssevecmode> 4))])]
4308 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4310 enum machine_mode mode = <MODE>mode;
4311 enum machine_mode vecmode = <ssevecmode>mode;
4312 REAL_VALUE_TYPE TWO31r;
4315 if (optimize_insn_for_size_p ())
4318 real_ldexp (&TWO31r, &dconst1, 31);
4319 two31 = const_double_from_real_value (TWO31r, mode);
4320 two31 = ix86_build_const_vector (vecmode, true, two31);
4321 operands[2] = force_reg (vecmode, two31);
4324 (define_insn_and_split "*fixuns_trunc<mode>_1"
4325 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4327 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4328 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4329 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4330 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4331 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4332 && optimize_function_for_speed_p (cfun)"
4334 "&& reload_completed"
4337 ix86_split_convert_uns_si_sse (operands);
4341 ;; Unsigned conversion to HImode.
4342 ;; Without these patterns, we'll try the unsigned SI conversion which
4343 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4345 (define_expand "fixuns_trunc<mode>hi2"
4347 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand")))
4348 (set (match_operand:HI 0 "nonimmediate_operand")
4349 (subreg:HI (match_dup 2) 0))]
4350 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4351 "operands[2] = gen_reg_rtx (SImode);")
4353 ;; When SSE is available, it is always faster to use it!
4354 (define_insn "fix_trunc<mode>di_sse"
4355 [(set (match_operand:DI 0 "register_operand" "=r,r")
4356 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4357 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4358 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4359 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4360 [(set_attr "type" "sseicvt")
4361 (set_attr "prefix" "maybe_vex")
4362 (set_attr "prefix_rex" "1")
4363 (set_attr "mode" "<MODE>")
4364 (set_attr "athlon_decode" "double,vector")
4365 (set_attr "amdfam10_decode" "double,double")
4366 (set_attr "bdver1_decode" "double,double")])
4368 (define_insn "fix_trunc<mode>si_sse"
4369 [(set (match_operand:SI 0 "register_operand" "=r,r")
4370 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4371 "SSE_FLOAT_MODE_P (<MODE>mode)
4372 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4373 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4374 [(set_attr "type" "sseicvt")
4375 (set_attr "prefix" "maybe_vex")
4376 (set_attr "mode" "<MODE>")
4377 (set_attr "athlon_decode" "double,vector")
4378 (set_attr "amdfam10_decode" "double,double")
4379 (set_attr "bdver1_decode" "double,double")])
4381 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4383 [(set (match_operand:MODEF 0 "register_operand")
4384 (match_operand:MODEF 1 "memory_operand"))
4385 (set (match_operand:SWI48x 2 "register_operand")
4386 (fix:SWI48x (match_dup 0)))]
4387 "TARGET_SHORTEN_X87_SSE
4388 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4389 && peep2_reg_dead_p (2, operands[0])"
4390 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4392 ;; Avoid vector decoded forms of the instruction.
4394 [(match_scratch:DF 2 "x")
4395 (set (match_operand:SWI48x 0 "register_operand")
4396 (fix:SWI48x (match_operand:DF 1 "memory_operand")))]
4397 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4398 [(set (match_dup 2) (match_dup 1))
4399 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4402 [(match_scratch:SF 2 "x")
4403 (set (match_operand:SWI48x 0 "register_operand")
4404 (fix:SWI48x (match_operand:SF 1 "memory_operand")))]
4405 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4406 [(set (match_dup 2) (match_dup 1))
4407 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4409 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4410 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4411 (fix:SWI248x (match_operand 1 "register_operand")))]
4412 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4414 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4415 && (TARGET_64BIT || <MODE>mode != DImode))
4417 && can_create_pseudo_p ()"
4422 if (memory_operand (operands[0], VOIDmode))
4423 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4426 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4427 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4433 [(set_attr "type" "fisttp")
4434 (set_attr "mode" "<MODE>")])
4436 (define_insn "fix_trunc<mode>_i387_fisttp"
4437 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4438 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4439 (clobber (match_scratch:XF 2 "=&1f"))]
4440 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4442 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4443 && (TARGET_64BIT || <MODE>mode != DImode))
4444 && TARGET_SSE_MATH)"
4445 "* return output_fix_trunc (insn, operands, true);"
4446 [(set_attr "type" "fisttp")
4447 (set_attr "mode" "<MODE>")])
4449 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4450 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4451 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4452 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4453 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4454 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4456 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4457 && (TARGET_64BIT || <MODE>mode != DImode))
4458 && TARGET_SSE_MATH)"
4460 [(set_attr "type" "fisttp")
4461 (set_attr "mode" "<MODE>")])
4464 [(set (match_operand:SWI248x 0 "register_operand")
4465 (fix:SWI248x (match_operand 1 "register_operand")))
4466 (clobber (match_operand:SWI248x 2 "memory_operand"))
4467 (clobber (match_scratch 3))]
4469 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4470 (clobber (match_dup 3))])
4471 (set (match_dup 0) (match_dup 2))])
4474 [(set (match_operand:SWI248x 0 "memory_operand")
4475 (fix:SWI248x (match_operand 1 "register_operand")))
4476 (clobber (match_operand:SWI248x 2 "memory_operand"))
4477 (clobber (match_scratch 3))]
4479 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4480 (clobber (match_dup 3))])])
4482 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4483 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4484 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4485 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4486 ;; function in i386.c.
4487 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4488 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
4489 (fix:SWI248x (match_operand 1 "register_operand")))
4490 (clobber (reg:CC FLAGS_REG))]
4491 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4493 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4494 && (TARGET_64BIT || <MODE>mode != DImode))
4495 && can_create_pseudo_p ()"
4500 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4502 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4503 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4504 if (memory_operand (operands[0], VOIDmode))
4505 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4506 operands[2], operands[3]));
4509 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4510 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4511 operands[2], operands[3],
4516 [(set_attr "type" "fistp")
4517 (set_attr "i387_cw" "trunc")
4518 (set_attr "mode" "<MODE>")])
4520 (define_insn "fix_truncdi_i387"
4521 [(set (match_operand:DI 0 "memory_operand" "=m")
4522 (fix:DI (match_operand 1 "register_operand" "f")))
4523 (use (match_operand:HI 2 "memory_operand" "m"))
4524 (use (match_operand:HI 3 "memory_operand" "m"))
4525 (clobber (match_scratch:XF 4 "=&1f"))]
4526 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4528 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4529 "* return output_fix_trunc (insn, operands, false);"
4530 [(set_attr "type" "fistp")
4531 (set_attr "i387_cw" "trunc")
4532 (set_attr "mode" "DI")])
4534 (define_insn "fix_truncdi_i387_with_temp"
4535 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4536 (fix:DI (match_operand 1 "register_operand" "f,f")))
4537 (use (match_operand:HI 2 "memory_operand" "m,m"))
4538 (use (match_operand:HI 3 "memory_operand" "m,m"))
4539 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4540 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4541 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4543 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4545 [(set_attr "type" "fistp")
4546 (set_attr "i387_cw" "trunc")
4547 (set_attr "mode" "DI")])
4550 [(set (match_operand:DI 0 "register_operand")
4551 (fix:DI (match_operand 1 "register_operand")))
4552 (use (match_operand:HI 2 "memory_operand"))
4553 (use (match_operand:HI 3 "memory_operand"))
4554 (clobber (match_operand:DI 4 "memory_operand"))
4555 (clobber (match_scratch 5))]
4557 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4560 (clobber (match_dup 5))])
4561 (set (match_dup 0) (match_dup 4))])
4564 [(set (match_operand:DI 0 "memory_operand")
4565 (fix:DI (match_operand 1 "register_operand")))
4566 (use (match_operand:HI 2 "memory_operand"))
4567 (use (match_operand:HI 3 "memory_operand"))
4568 (clobber (match_operand:DI 4 "memory_operand"))
4569 (clobber (match_scratch 5))]
4571 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4574 (clobber (match_dup 5))])])
4576 (define_insn "fix_trunc<mode>_i387"
4577 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4578 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4579 (use (match_operand:HI 2 "memory_operand" "m"))
4580 (use (match_operand:HI 3 "memory_operand" "m"))]
4581 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4584 "* return output_fix_trunc (insn, operands, false);"
4585 [(set_attr "type" "fistp")
4586 (set_attr "i387_cw" "trunc")
4587 (set_attr "mode" "<MODE>")])
4589 (define_insn "fix_trunc<mode>_i387_with_temp"
4590 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4591 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4592 (use (match_operand:HI 2 "memory_operand" "m,m"))
4593 (use (match_operand:HI 3 "memory_operand" "m,m"))
4594 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4595 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4597 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4599 [(set_attr "type" "fistp")
4600 (set_attr "i387_cw" "trunc")
4601 (set_attr "mode" "<MODE>")])
4604 [(set (match_operand:SWI24 0 "register_operand")
4605 (fix:SWI24 (match_operand 1 "register_operand")))
4606 (use (match_operand:HI 2 "memory_operand"))
4607 (use (match_operand:HI 3 "memory_operand"))
4608 (clobber (match_operand:SWI24 4 "memory_operand"))]
4610 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4612 (use (match_dup 3))])
4613 (set (match_dup 0) (match_dup 4))])
4616 [(set (match_operand:SWI24 0 "memory_operand")
4617 (fix:SWI24 (match_operand 1 "register_operand")))
4618 (use (match_operand:HI 2 "memory_operand"))
4619 (use (match_operand:HI 3 "memory_operand"))
4620 (clobber (match_operand:SWI24 4 "memory_operand"))]
4622 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4624 (use (match_dup 3))])])
4626 (define_insn "x86_fnstcw_1"
4627 [(set (match_operand:HI 0 "memory_operand" "=m")
4628 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4631 [(set (attr "length")
4632 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4633 (set_attr "mode" "HI")
4634 (set_attr "unit" "i387")
4635 (set_attr "bdver1_decode" "vector")])
4637 (define_insn "x86_fldcw_1"
4638 [(set (reg:HI FPCR_REG)
4639 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4642 [(set (attr "length")
4643 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4644 (set_attr "mode" "HI")
4645 (set_attr "unit" "i387")
4646 (set_attr "athlon_decode" "vector")
4647 (set_attr "amdfam10_decode" "vector")
4648 (set_attr "bdver1_decode" "vector")])
4650 ;; Conversion between fixed point and floating point.
4652 ;; Even though we only accept memory inputs, the backend _really_
4653 ;; wants to be able to do this between registers.
4655 (define_expand "floathi<mode>2"
4656 [(set (match_operand:X87MODEF 0 "register_operand")
4657 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand")))]
4659 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4660 || TARGET_MIX_SSE_I387)")
4662 ;; Pre-reload splitter to add memory clobber to the pattern.
4663 (define_insn_and_split "*floathi<mode>2_1"
4664 [(set (match_operand:X87MODEF 0 "register_operand")
4665 (float:X87MODEF (match_operand:HI 1 "register_operand")))]
4667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4668 || TARGET_MIX_SSE_I387)
4669 && can_create_pseudo_p ()"
4672 [(parallel [(set (match_dup 0)
4673 (float:X87MODEF (match_dup 1)))
4674 (clobber (match_dup 2))])]
4675 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4677 (define_insn "*floathi<mode>2_i387_with_temp"
4678 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4679 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4680 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4682 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4683 || TARGET_MIX_SSE_I387)"
4685 [(set_attr "type" "fmov,multi")
4686 (set_attr "mode" "<MODE>")
4687 (set_attr "unit" "*,i387")
4688 (set_attr "fp_int_src" "true")])
4690 (define_insn "*floathi<mode>2_i387"
4691 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4692 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4694 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4695 || TARGET_MIX_SSE_I387)"
4697 [(set_attr "type" "fmov")
4698 (set_attr "mode" "<MODE>")
4699 (set_attr "fp_int_src" "true")])
4702 [(set (match_operand:X87MODEF 0 "register_operand")
4703 (float:X87MODEF (match_operand:HI 1 "register_operand")))
4704 (clobber (match_operand:HI 2 "memory_operand"))]
4706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4707 || TARGET_MIX_SSE_I387)
4708 && reload_completed"
4709 [(set (match_dup 2) (match_dup 1))
4710 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4713 [(set (match_operand:X87MODEF 0 "register_operand")
4714 (float:X87MODEF (match_operand:HI 1 "memory_operand")))
4715 (clobber (match_operand:HI 2 "memory_operand"))]
4717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4718 || TARGET_MIX_SSE_I387)
4719 && reload_completed"
4720 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4722 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4723 [(set (match_operand:X87MODEF 0 "register_operand")
4725 (match_operand:SWI48x 1 "nonimmediate_operand")))]
4727 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4728 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4730 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4731 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4732 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4734 rtx reg = gen_reg_rtx (XFmode);
4735 rtx (*insn)(rtx, rtx);
4737 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4739 if (<X87MODEF:MODE>mode == SFmode)
4740 insn = gen_truncxfsf2;
4741 else if (<X87MODEF:MODE>mode == DFmode)
4742 insn = gen_truncxfdf2;
4746 emit_insn (insn (operands[0], reg));
4751 ;; Pre-reload splitter to add memory clobber to the pattern.
4752 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4753 [(set (match_operand:X87MODEF 0 "register_operand")
4754 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))]
4756 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4757 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4758 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4759 || TARGET_MIX_SSE_I387))
4760 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4761 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4762 && ((<SWI48x:MODE>mode == SImode
4763 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4764 && optimize_function_for_speed_p (cfun)
4765 && flag_trapping_math)
4766 || !(TARGET_INTER_UNIT_CONVERSIONS
4767 || optimize_function_for_size_p (cfun)))))
4768 && can_create_pseudo_p ()"
4771 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4772 (clobber (match_dup 2))])]
4774 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4776 /* Avoid store forwarding (partial memory) stall penalty
4777 by passing DImode value through XMM registers. */
4778 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4779 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4780 && optimize_function_for_speed_p (cfun))
4782 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4789 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4790 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4792 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4793 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4794 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4795 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4797 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4798 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4799 (set_attr "unit" "*,i387,*,*,*")
4800 (set_attr "athlon_decode" "*,*,double,direct,double")
4801 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4802 (set_attr "bdver1_decode" "*,*,double,direct,double")
4803 (set_attr "fp_int_src" "true")])
4805 (define_insn "*floatsi<mode>2_vector_mixed"
4806 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4807 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4808 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4809 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4813 [(set_attr "type" "fmov,sseicvt")
4814 (set_attr "mode" "<MODE>,<ssevecmode>")
4815 (set_attr "unit" "i387,*")
4816 (set_attr "athlon_decode" "*,direct")
4817 (set_attr "amdfam10_decode" "*,double")
4818 (set_attr "bdver1_decode" "*,direct")
4819 (set_attr "fp_int_src" "true")])
4821 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4822 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4824 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4825 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4826 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4827 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4829 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4830 (set_attr "mode" "<MODEF:MODE>")
4831 (set_attr "unit" "*,i387,*,*")
4832 (set_attr "athlon_decode" "*,*,double,direct")
4833 (set_attr "amdfam10_decode" "*,*,vector,double")
4834 (set_attr "bdver1_decode" "*,*,double,direct")
4835 (set_attr "fp_int_src" "true")])
4838 [(set (match_operand:MODEF 0 "register_operand")
4839 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4840 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4841 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4842 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4843 && TARGET_INTER_UNIT_CONVERSIONS
4845 && (SSE_REG_P (operands[0])
4846 || (GET_CODE (operands[0]) == SUBREG
4847 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4848 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4851 [(set (match_operand:MODEF 0 "register_operand")
4852 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
4853 (clobber (match_operand:SWI48x 2 "memory_operand"))]
4854 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4855 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4856 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4858 && (SSE_REG_P (operands[0])
4859 || (GET_CODE (operands[0]) == SUBREG
4860 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4861 [(set (match_dup 2) (match_dup 1))
4862 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4864 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4865 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4867 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4868 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4869 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4870 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4873 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4874 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4875 [(set_attr "type" "fmov,sseicvt,sseicvt")
4876 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4877 (set_attr "mode" "<MODEF:MODE>")
4878 (set (attr "prefix_rex")
4880 (and (eq_attr "prefix" "maybe_vex")
4881 (match_test "<SWI48x:MODE>mode == DImode"))
4883 (const_string "*")))
4884 (set_attr "unit" "i387,*,*")
4885 (set_attr "athlon_decode" "*,double,direct")
4886 (set_attr "amdfam10_decode" "*,vector,double")
4887 (set_attr "bdver1_decode" "*,double,direct")
4888 (set_attr "fp_int_src" "true")])
4890 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4891 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4893 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4894 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4895 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4896 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4899 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4900 [(set_attr "type" "fmov,sseicvt")
4901 (set_attr "prefix" "orig,maybe_vex")
4902 (set_attr "mode" "<MODEF:MODE>")
4903 (set (attr "prefix_rex")
4905 (and (eq_attr "prefix" "maybe_vex")
4906 (match_test "<SWI48x:MODE>mode == DImode"))
4908 (const_string "*")))
4909 (set_attr "athlon_decode" "*,direct")
4910 (set_attr "amdfam10_decode" "*,double")
4911 (set_attr "bdver1_decode" "*,direct")
4912 (set_attr "fp_int_src" "true")])
4914 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4915 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4917 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4918 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4919 "TARGET_SSE2 && TARGET_SSE_MATH
4920 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4922 [(set_attr "type" "sseicvt")
4923 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4924 (set_attr "athlon_decode" "double,direct,double")
4925 (set_attr "amdfam10_decode" "vector,double,double")
4926 (set_attr "bdver1_decode" "double,direct,double")
4927 (set_attr "fp_int_src" "true")])
4929 (define_insn "*floatsi<mode>2_vector_sse"
4930 [(set (match_operand:MODEF 0 "register_operand" "=x")
4931 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4932 "TARGET_SSE2 && TARGET_SSE_MATH
4933 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4935 [(set_attr "type" "sseicvt")
4936 (set_attr "mode" "<MODE>")
4937 (set_attr "athlon_decode" "direct")
4938 (set_attr "amdfam10_decode" "double")
4939 (set_attr "bdver1_decode" "direct")
4940 (set_attr "fp_int_src" "true")])
4943 [(set (match_operand:MODEF 0 "register_operand")
4944 (float:MODEF (match_operand:SI 1 "register_operand")))
4945 (clobber (match_operand:SI 2 "memory_operand"))]
4946 "TARGET_SSE2 && TARGET_SSE_MATH
4947 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4949 && (SSE_REG_P (operands[0])
4950 || (GET_CODE (operands[0]) == SUBREG
4951 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4954 rtx op1 = operands[1];
4956 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4958 if (GET_CODE (op1) == SUBREG)
4959 op1 = SUBREG_REG (op1);
4961 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4963 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4964 emit_insn (gen_sse2_loadld (operands[4],
4965 CONST0_RTX (V4SImode), operands[1]));
4967 /* We can ignore possible trapping value in the
4968 high part of SSE register for non-trapping math. */
4969 else if (SSE_REG_P (op1) && !flag_trapping_math)
4970 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4973 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4974 emit_move_insn (operands[2], operands[1]);
4975 emit_insn (gen_sse2_loadld (operands[4],
4976 CONST0_RTX (V4SImode), operands[2]));
4978 if (<ssevecmode>mode == V4SFmode)
4979 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4981 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4986 [(set (match_operand:MODEF 0 "register_operand")
4987 (float:MODEF (match_operand:SI 1 "memory_operand")))
4988 (clobber (match_operand:SI 2 "memory_operand"))]
4989 "TARGET_SSE2 && TARGET_SSE_MATH
4990 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4992 && (SSE_REG_P (operands[0])
4993 || (GET_CODE (operands[0]) == SUBREG
4994 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4997 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4999 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5001 emit_insn (gen_sse2_loadld (operands[4],
5002 CONST0_RTX (V4SImode), operands[1]));
5003 if (<ssevecmode>mode == V4SFmode)
5004 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5006 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5011 [(set (match_operand:MODEF 0 "register_operand")
5012 (float:MODEF (match_operand:SI 1 "register_operand")))]
5013 "TARGET_SSE2 && TARGET_SSE_MATH
5014 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5016 && (SSE_REG_P (operands[0])
5017 || (GET_CODE (operands[0]) == SUBREG
5018 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5021 rtx op1 = operands[1];
5023 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5025 if (GET_CODE (op1) == SUBREG)
5026 op1 = SUBREG_REG (op1);
5028 if (GENERAL_REG_P (op1))
5030 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5031 if (TARGET_INTER_UNIT_MOVES)
5032 emit_insn (gen_sse2_loadld (operands[4],
5033 CONST0_RTX (V4SImode), operands[1]));
5036 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5038 emit_insn (gen_sse2_loadld (operands[4],
5039 CONST0_RTX (V4SImode), operands[5]));
5040 ix86_free_from_memory (GET_MODE (operands[1]));
5043 /* We can ignore possible trapping value in the
5044 high part of SSE register for non-trapping math. */
5045 else if (SSE_REG_P (op1) && !flag_trapping_math)
5046 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5049 if (<ssevecmode>mode == V4SFmode)
5050 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5052 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5057 [(set (match_operand:MODEF 0 "register_operand")
5058 (float:MODEF (match_operand:SI 1 "memory_operand")))]
5059 "TARGET_SSE2 && TARGET_SSE_MATH
5060 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5062 && (SSE_REG_P (operands[0])
5063 || (GET_CODE (operands[0]) == SUBREG
5064 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5067 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5069 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5071 emit_insn (gen_sse2_loadld (operands[4],
5072 CONST0_RTX (V4SImode), operands[1]));
5073 if (<ssevecmode>mode == V4SFmode)
5074 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5076 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5080 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5081 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5083 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5084 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5085 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5086 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5088 [(set_attr "type" "sseicvt")
5089 (set_attr "mode" "<MODEF:MODE>")
5090 (set_attr "athlon_decode" "double,direct")
5091 (set_attr "amdfam10_decode" "vector,double")
5092 (set_attr "bdver1_decode" "double,direct")
5093 (set_attr "fp_int_src" "true")])
5095 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5096 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5098 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5099 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5100 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5101 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5102 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5103 [(set_attr "type" "sseicvt")
5104 (set_attr "prefix" "maybe_vex")
5105 (set_attr "mode" "<MODEF:MODE>")
5106 (set (attr "prefix_rex")
5108 (and (eq_attr "prefix" "maybe_vex")
5109 (match_test "<SWI48x:MODE>mode == DImode"))
5111 (const_string "*")))
5112 (set_attr "athlon_decode" "double,direct")
5113 (set_attr "amdfam10_decode" "vector,double")
5114 (set_attr "bdver1_decode" "double,direct")
5115 (set_attr "fp_int_src" "true")])
5118 [(set (match_operand:MODEF 0 "register_operand")
5119 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand")))
5120 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5121 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5122 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5123 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5125 && (SSE_REG_P (operands[0])
5126 || (GET_CODE (operands[0]) == SUBREG
5127 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5128 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5130 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5131 [(set (match_operand:MODEF 0 "register_operand" "=x")
5133 (match_operand:SWI48x 1 "memory_operand" "m")))]
5134 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5135 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5136 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5137 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5138 [(set_attr "type" "sseicvt")
5139 (set_attr "prefix" "maybe_vex")
5140 (set_attr "mode" "<MODEF:MODE>")
5141 (set (attr "prefix_rex")
5143 (and (eq_attr "prefix" "maybe_vex")
5144 (match_test "<SWI48x:MODE>mode == DImode"))
5146 (const_string "*")))
5147 (set_attr "athlon_decode" "direct")
5148 (set_attr "amdfam10_decode" "double")
5149 (set_attr "bdver1_decode" "direct")
5150 (set_attr "fp_int_src" "true")])
5153 [(set (match_operand:MODEF 0 "register_operand")
5154 (float:MODEF (match_operand:SWI48x 1 "register_operand")))
5155 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5156 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5157 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5158 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5160 && (SSE_REG_P (operands[0])
5161 || (GET_CODE (operands[0]) == SUBREG
5162 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5163 [(set (match_dup 2) (match_dup 1))
5164 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5167 [(set (match_operand:MODEF 0 "register_operand")
5168 (float:MODEF (match_operand:SWI48x 1 "memory_operand")))
5169 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5170 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5171 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5173 && (SSE_REG_P (operands[0])
5174 || (GET_CODE (operands[0]) == SUBREG
5175 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5176 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5178 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5179 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5181 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5182 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5184 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5188 [(set_attr "type" "fmov,multi")
5189 (set_attr "mode" "<X87MODEF:MODE>")
5190 (set_attr "unit" "*,i387")
5191 (set_attr "fp_int_src" "true")])
5193 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5194 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5196 (match_operand:SWI48x 1 "memory_operand" "m")))]
5198 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5200 [(set_attr "type" "fmov")
5201 (set_attr "mode" "<X87MODEF:MODE>")
5202 (set_attr "fp_int_src" "true")])
5205 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5206 (float:X87MODEF (match_operand:SWI48x 1 "register_operand")))
5207 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5209 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5210 && reload_completed"
5211 [(set (match_dup 2) (match_dup 1))
5212 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5215 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5216 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand")))
5217 (clobber (match_operand:SWI48x 2 "memory_operand"))]
5219 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5220 && reload_completed"
5221 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5223 ;; Avoid store forwarding (partial memory) stall penalty
5224 ;; by passing DImode value through XMM registers. */
5226 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5227 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5229 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5230 (clobber (match_scratch:V4SI 3 "=X,x"))
5231 (clobber (match_scratch:V4SI 4 "=X,x"))
5232 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5233 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5234 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5235 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5237 [(set_attr "type" "multi")
5238 (set_attr "mode" "<X87MODEF:MODE>")
5239 (set_attr "unit" "i387")
5240 (set_attr "fp_int_src" "true")])
5243 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5244 (float:X87MODEF (match_operand:DI 1 "register_operand")))
5245 (clobber (match_scratch:V4SI 3))
5246 (clobber (match_scratch:V4SI 4))
5247 (clobber (match_operand:DI 2 "memory_operand"))]
5248 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5249 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5250 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5251 && reload_completed"
5252 [(set (match_dup 2) (match_dup 3))
5253 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5255 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5256 Assemble the 64-bit DImode value in an xmm register. */
5257 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5258 gen_rtx_SUBREG (SImode, operands[1], 0)));
5259 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5260 gen_rtx_SUBREG (SImode, operands[1], 4)));
5261 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5264 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5268 [(set (match_operand:X87MODEF 0 "fp_register_operand")
5269 (float:X87MODEF (match_operand:DI 1 "memory_operand")))
5270 (clobber (match_scratch:V4SI 3))
5271 (clobber (match_scratch:V4SI 4))
5272 (clobber (match_operand:DI 2 "memory_operand"))]
5273 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5274 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5275 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5276 && reload_completed"
5277 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5279 ;; Avoid store forwarding (partial memory) stall penalty by extending
5280 ;; SImode value to DImode through XMM register instead of pushing two
5281 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5282 ;; targets benefit from this optimization. Also note that fild
5283 ;; loads from memory only.
5285 (define_insn "*floatunssi<mode>2_1"
5286 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5287 (unsigned_float:X87MODEF
5288 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5289 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5290 (clobber (match_scratch:SI 3 "=X,x"))]
5292 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5295 [(set_attr "type" "multi")
5296 (set_attr "mode" "<MODE>")])
5299 [(set (match_operand:X87MODEF 0 "register_operand")
5300 (unsigned_float:X87MODEF
5301 (match_operand:SI 1 "register_operand")))
5302 (clobber (match_operand:DI 2 "memory_operand"))
5303 (clobber (match_scratch:SI 3))]
5305 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307 && reload_completed"
5308 [(set (match_dup 2) (match_dup 1))
5310 (float:X87MODEF (match_dup 2)))]
5311 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5314 [(set (match_operand:X87MODEF 0 "register_operand")
5315 (unsigned_float:X87MODEF
5316 (match_operand:SI 1 "memory_operand")))
5317 (clobber (match_operand:DI 2 "memory_operand"))
5318 (clobber (match_scratch:SI 3))]
5320 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5322 && reload_completed"
5323 [(set (match_dup 2) (match_dup 3))
5325 (float:X87MODEF (match_dup 2)))]
5327 emit_move_insn (operands[3], operands[1]);
5328 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5331 (define_expand "floatunssi<mode>2"
5333 [(set (match_operand:X87MODEF 0 "register_operand")
5334 (unsigned_float:X87MODEF
5335 (match_operand:SI 1 "nonimmediate_operand")))
5336 (clobber (match_dup 2))
5337 (clobber (match_scratch:SI 3))])]
5339 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5341 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5343 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5345 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5350 enum ix86_stack_slot slot = (virtuals_instantiated
5353 operands[2] = assign_386_stack_local (DImode, slot);
5357 (define_expand "floatunsdisf2"
5358 [(use (match_operand:SF 0 "register_operand"))
5359 (use (match_operand:DI 1 "nonimmediate_operand"))]
5360 "TARGET_64BIT && TARGET_SSE_MATH"
5361 "x86_emit_floatuns (operands); DONE;")
5363 (define_expand "floatunsdidf2"
5364 [(use (match_operand:DF 0 "register_operand"))
5365 (use (match_operand:DI 1 "nonimmediate_operand"))]
5366 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5367 && TARGET_SSE2 && TARGET_SSE_MATH"
5370 x86_emit_floatuns (operands);
5372 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5378 (define_expand "add<mode>3"
5379 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
5380 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
5381 (match_operand:SDWIM 2 "<general_operand>")))]
5383 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5385 (define_insn_and_split "*add<dwi>3_doubleword"
5386 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5388 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5389 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5390 (clobber (reg:CC FLAGS_REG))]
5391 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5394 [(parallel [(set (reg:CC FLAGS_REG)
5395 (unspec:CC [(match_dup 1) (match_dup 2)]
5398 (plus:DWIH (match_dup 1) (match_dup 2)))])
5399 (parallel [(set (match_dup 3)
5403 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5405 (clobber (reg:CC FLAGS_REG))])]
5406 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5408 (define_insn "*add<mode>3_cc"
5409 [(set (reg:CC FLAGS_REG)
5411 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5412 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5414 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5415 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5416 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5417 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5418 [(set_attr "type" "alu")
5419 (set_attr "mode" "<MODE>")])
5421 (define_insn "addqi3_cc"
5422 [(set (reg:CC FLAGS_REG)
5424 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5425 (match_operand:QI 2 "general_operand" "qn,qm")]
5427 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5428 (plus:QI (match_dup 1) (match_dup 2)))]
5429 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5430 "add{b}\t{%2, %0|%0, %2}"
5431 [(set_attr "type" "alu")
5432 (set_attr "mode" "QI")])
5434 (define_insn_and_split "*lea_1"
5435 [(set (match_operand:SI 0 "register_operand" "=r")
5436 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5438 "lea{l}\t{%E1, %0|%0, %E1}"
5439 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5442 ix86_split_lea_for_addr (operands, SImode);
5445 [(set_attr "type" "lea")
5446 (set_attr "mode" "SI")])
5448 (define_insn_and_split "*lea<mode>_2"
5449 [(set (match_operand:SWI48 0 "register_operand" "=r")
5450 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5452 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5453 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5456 ix86_split_lea_for_addr (operands, <MODE>mode);
5459 [(set_attr "type" "lea")
5460 (set_attr "mode" "<MODE>")])
5462 (define_insn "*lea_3_zext"
5463 [(set (match_operand:DI 0 "register_operand" "=r")
5465 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5467 "lea{l}\t{%E1, %k0|%k0, %E1}"
5468 [(set_attr "type" "lea")
5469 (set_attr "mode" "SI")])
5471 (define_insn "*lea_4_zext"
5472 [(set (match_operand:DI 0 "register_operand" "=r")
5474 (match_operand:SI 1 "lea_address_operand" "j")))]
5476 "lea{l}\t{%E1, %k0|%k0, %E1}"
5477 [(set_attr "type" "lea")
5478 (set_attr "mode" "SI")])
5480 (define_insn "*lea_5_zext"
5481 [(set (match_operand:DI 0 "register_operand" "=r")
5483 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5484 (match_operand:DI 2 "const_32bit_mask" "n")))]
5486 "lea{l}\t{%E1, %k0|%k0, %E1}"
5487 [(set_attr "type" "lea")
5488 (set_attr "mode" "SI")])
5490 (define_insn "*lea_6_zext"
5491 [(set (match_operand:DI 0 "register_operand" "=r")
5493 (match_operand:DI 1 "lea_address_operand" "p")
5494 (match_operand:DI 2 "const_32bit_mask" "n")))]
5496 "lea{l}\t{%E1, %k0|%k0, %E1}"
5497 [(set_attr "type" "lea")
5498 (set_attr "mode" "SI")])
5500 (define_insn "*add<mode>_1"
5501 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5503 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5504 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5505 (clobber (reg:CC FLAGS_REG))]
5506 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5508 switch (get_attr_type (insn))
5514 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5515 if (operands[2] == const1_rtx)
5516 return "inc{<imodesuffix>}\t%0";
5519 gcc_assert (operands[2] == constm1_rtx);
5520 return "dec{<imodesuffix>}\t%0";
5524 /* For most processors, ADD is faster than LEA. This alternative
5525 was added to use ADD as much as possible. */
5526 if (which_alternative == 2)
5529 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5532 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5533 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5534 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5536 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5540 (cond [(eq_attr "alternative" "3")
5541 (const_string "lea")
5542 (match_operand:SWI48 2 "incdec_operand")
5543 (const_string "incdec")
5545 (const_string "alu")))
5546 (set (attr "length_immediate")
5548 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5550 (const_string "*")))
5551 (set_attr "mode" "<MODE>")])
5553 ;; It may seem that nonimmediate operand is proper one for operand 1.
5554 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5555 ;; we take care in ix86_binary_operator_ok to not allow two memory
5556 ;; operands so proper swapping will be done in reload. This allow
5557 ;; patterns constructed from addsi_1 to match.
5559 (define_insn "addsi_1_zext"
5560 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5562 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5563 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5564 (clobber (reg:CC FLAGS_REG))]
5565 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5567 switch (get_attr_type (insn))
5573 if (operands[2] == const1_rtx)
5574 return "inc{l}\t%k0";
5577 gcc_assert (operands[2] == constm1_rtx);
5578 return "dec{l}\t%k0";
5582 /* For most processors, ADD is faster than LEA. This alternative
5583 was added to use ADD as much as possible. */
5584 if (which_alternative == 1)
5587 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5590 if (x86_maybe_negate_const_int (&operands[2], SImode))
5591 return "sub{l}\t{%2, %k0|%k0, %2}";
5593 return "add{l}\t{%2, %k0|%k0, %2}";
5597 (cond [(eq_attr "alternative" "2")
5598 (const_string "lea")
5599 (match_operand:SI 2 "incdec_operand")
5600 (const_string "incdec")
5602 (const_string "alu")))
5603 (set (attr "length_immediate")
5605 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5607 (const_string "*")))
5608 (set_attr "mode" "SI")])
5610 (define_insn "*addhi_1"
5611 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5612 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5613 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5614 (clobber (reg:CC FLAGS_REG))]
5615 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5617 switch (get_attr_type (insn))
5623 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5624 if (operands[2] == const1_rtx)
5625 return "inc{w}\t%0";
5628 gcc_assert (operands[2] == constm1_rtx);
5629 return "dec{w}\t%0";
5633 /* For most processors, ADD is faster than LEA. This alternative
5634 was added to use ADD as much as possible. */
5635 if (which_alternative == 2)
5638 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5642 if (x86_maybe_negate_const_int (&operands[2], HImode))
5643 return "sub{w}\t{%2, %0|%0, %2}";
5645 return "add{w}\t{%2, %0|%0, %2}";
5649 (cond [(eq_attr "alternative" "3")
5650 (const_string "lea")
5651 (match_operand:HI 2 "incdec_operand")
5652 (const_string "incdec")
5654 (const_string "alu")))
5655 (set (attr "length_immediate")
5657 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5659 (const_string "*")))
5660 (set_attr "mode" "HI,HI,HI,SI")])
5662 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5663 (define_insn "*addqi_1"
5664 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5665 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5666 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5667 (clobber (reg:CC FLAGS_REG))]
5668 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5670 bool widen = (which_alternative == 3 || which_alternative == 4);
5672 switch (get_attr_type (insn))
5678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5679 if (operands[2] == const1_rtx)
5680 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5683 gcc_assert (operands[2] == constm1_rtx);
5684 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5688 /* For most processors, ADD is faster than LEA. These alternatives
5689 were added to use ADD as much as possible. */
5690 if (which_alternative == 2 || which_alternative == 4)
5693 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5696 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5697 if (x86_maybe_negate_const_int (&operands[2], QImode))
5700 return "sub{l}\t{%2, %k0|%k0, %2}";
5702 return "sub{b}\t{%2, %0|%0, %2}";
5705 return "add{l}\t{%k2, %k0|%k0, %k2}";
5707 return "add{b}\t{%2, %0|%0, %2}";
5711 (cond [(eq_attr "alternative" "5")
5712 (const_string "lea")
5713 (match_operand:QI 2 "incdec_operand")
5714 (const_string "incdec")
5716 (const_string "alu")))
5717 (set (attr "length_immediate")
5719 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5721 (const_string "*")))
5722 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5724 (define_insn "*addqi_1_slp"
5725 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5726 (plus:QI (match_dup 0)
5727 (match_operand:QI 1 "general_operand" "qn,qm")))
5728 (clobber (reg:CC FLAGS_REG))]
5729 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5730 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5732 switch (get_attr_type (insn))
5735 if (operands[1] == const1_rtx)
5736 return "inc{b}\t%0";
5739 gcc_assert (operands[1] == constm1_rtx);
5740 return "dec{b}\t%0";
5744 if (x86_maybe_negate_const_int (&operands[1], QImode))
5745 return "sub{b}\t{%1, %0|%0, %1}";
5747 return "add{b}\t{%1, %0|%0, %1}";
5751 (if_then_else (match_operand:QI 1 "incdec_operand")
5752 (const_string "incdec")
5753 (const_string "alu1")))
5754 (set (attr "memory")
5755 (if_then_else (match_operand 1 "memory_operand")
5756 (const_string "load")
5757 (const_string "none")))
5758 (set_attr "mode" "QI")])
5760 ;; Split non destructive adds if we cannot use lea.
5762 [(set (match_operand:SWI48 0 "register_operand")
5763 (plus:SWI48 (match_operand:SWI48 1 "register_operand")
5764 (match_operand:SWI48 2 "nonmemory_operand")))
5765 (clobber (reg:CC FLAGS_REG))]
5766 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5767 [(set (match_dup 0) (match_dup 1))
5768 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5769 (clobber (reg:CC FLAGS_REG))])])
5771 ;; Convert add to the lea pattern to avoid flags dependency.
5773 [(set (match_operand:SWI 0 "register_operand")
5774 (plus:SWI (match_operand:SWI 1 "register_operand")
5775 (match_operand:SWI 2 "<nonmemory_operand>")))
5776 (clobber (reg:CC FLAGS_REG))]
5777 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5780 enum machine_mode mode = <MODE>mode;
5783 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5786 operands[0] = gen_lowpart (mode, operands[0]);
5787 operands[1] = gen_lowpart (mode, operands[1]);
5788 operands[2] = gen_lowpart (mode, operands[2]);
5791 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5793 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5797 ;; Convert add to the lea pattern to avoid flags dependency.
5799 [(set (match_operand:DI 0 "register_operand")
5801 (plus:SI (match_operand:SI 1 "register_operand")
5802 (match_operand:SI 2 "x86_64_nonmemory_operand"))))
5803 (clobber (reg:CC FLAGS_REG))]
5804 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5806 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5808 (define_insn "*add<mode>_2"
5809 [(set (reg FLAGS_REG)
5812 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5813 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5815 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5816 (plus:SWI (match_dup 1) (match_dup 2)))]
5817 "ix86_match_ccmode (insn, CCGOCmode)
5818 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5820 switch (get_attr_type (insn))
5823 if (operands[2] == const1_rtx)
5824 return "inc{<imodesuffix>}\t%0";
5827 gcc_assert (operands[2] == constm1_rtx);
5828 return "dec{<imodesuffix>}\t%0";
5832 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5833 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5835 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5839 (if_then_else (match_operand:SWI 2 "incdec_operand")
5840 (const_string "incdec")
5841 (const_string "alu")))
5842 (set (attr "length_immediate")
5844 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5846 (const_string "*")))
5847 (set_attr "mode" "<MODE>")])
5849 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5850 (define_insn "*addsi_2_zext"
5851 [(set (reg FLAGS_REG)
5853 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5854 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5856 (set (match_operand:DI 0 "register_operand" "=r")
5857 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5858 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5859 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5861 switch (get_attr_type (insn))
5864 if (operands[2] == const1_rtx)
5865 return "inc{l}\t%k0";
5868 gcc_assert (operands[2] == constm1_rtx);
5869 return "dec{l}\t%k0";
5873 if (x86_maybe_negate_const_int (&operands[2], SImode))
5874 return "sub{l}\t{%2, %k0|%k0, %2}";
5876 return "add{l}\t{%2, %k0|%k0, %2}";
5880 (if_then_else (match_operand:SI 2 "incdec_operand")
5881 (const_string "incdec")
5882 (const_string "alu")))
5883 (set (attr "length_immediate")
5885 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5887 (const_string "*")))
5888 (set_attr "mode" "SI")])
5890 (define_insn "*add<mode>_3"
5891 [(set (reg FLAGS_REG)
5893 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5894 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5895 (clobber (match_scratch:SWI 0 "=<r>"))]
5896 "ix86_match_ccmode (insn, CCZmode)
5897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5899 switch (get_attr_type (insn))
5902 if (operands[2] == const1_rtx)
5903 return "inc{<imodesuffix>}\t%0";
5906 gcc_assert (operands[2] == constm1_rtx);
5907 return "dec{<imodesuffix>}\t%0";
5911 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5912 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5914 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5918 (if_then_else (match_operand:SWI 2 "incdec_operand")
5919 (const_string "incdec")
5920 (const_string "alu")))
5921 (set (attr "length_immediate")
5923 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5925 (const_string "*")))
5926 (set_attr "mode" "<MODE>")])
5928 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5929 (define_insn "*addsi_3_zext"
5930 [(set (reg FLAGS_REG)
5932 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5933 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5934 (set (match_operand:DI 0 "register_operand" "=r")
5935 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5936 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5937 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5939 switch (get_attr_type (insn))
5942 if (operands[2] == const1_rtx)
5943 return "inc{l}\t%k0";
5946 gcc_assert (operands[2] == constm1_rtx);
5947 return "dec{l}\t%k0";
5951 if (x86_maybe_negate_const_int (&operands[2], SImode))
5952 return "sub{l}\t{%2, %k0|%k0, %2}";
5954 return "add{l}\t{%2, %k0|%k0, %2}";
5958 (if_then_else (match_operand:SI 2 "incdec_operand")
5959 (const_string "incdec")
5960 (const_string "alu")))
5961 (set (attr "length_immediate")
5963 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
5965 (const_string "*")))
5966 (set_attr "mode" "SI")])
5968 ; For comparisons against 1, -1 and 128, we may generate better code
5969 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5970 ; is matched then. We can't accept general immediate, because for
5971 ; case of overflows, the result is messed up.
5972 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5973 ; only for comparisons not depending on it.
5975 (define_insn "*adddi_4"
5976 [(set (reg FLAGS_REG)
5978 (match_operand:DI 1 "nonimmediate_operand" "0")
5979 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5980 (clobber (match_scratch:DI 0 "=rm"))]
5982 && ix86_match_ccmode (insn, CCGCmode)"
5984 switch (get_attr_type (insn))
5987 if (operands[2] == constm1_rtx)
5988 return "inc{q}\t%0";
5991 gcc_assert (operands[2] == const1_rtx);
5992 return "dec{q}\t%0";
5996 if (x86_maybe_negate_const_int (&operands[2], DImode))
5997 return "add{q}\t{%2, %0|%0, %2}";
5999 return "sub{q}\t{%2, %0|%0, %2}";
6003 (if_then_else (match_operand:DI 2 "incdec_operand")
6004 (const_string "incdec")
6005 (const_string "alu")))
6006 (set (attr "length_immediate")
6008 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6010 (const_string "*")))
6011 (set_attr "mode" "DI")])
6013 ; For comparisons against 1, -1 and 128, we may generate better code
6014 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6015 ; is matched then. We can't accept general immediate, because for
6016 ; case of overflows, the result is messed up.
6017 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6018 ; only for comparisons not depending on it.
6020 (define_insn "*add<mode>_4"
6021 [(set (reg FLAGS_REG)
6023 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6024 (match_operand:SWI124 2 "const_int_operand" "n")))
6025 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6026 "ix86_match_ccmode (insn, CCGCmode)"
6028 switch (get_attr_type (insn))
6031 if (operands[2] == constm1_rtx)
6032 return "inc{<imodesuffix>}\t%0";
6035 gcc_assert (operands[2] == const1_rtx);
6036 return "dec{<imodesuffix>}\t%0";
6040 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6041 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6043 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6047 (if_then_else (match_operand:<MODE> 2 "incdec_operand")
6048 (const_string "incdec")
6049 (const_string "alu")))
6050 (set (attr "length_immediate")
6052 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6054 (const_string "*")))
6055 (set_attr "mode" "<MODE>")])
6057 (define_insn "*add<mode>_5"
6058 [(set (reg FLAGS_REG)
6061 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6062 (match_operand:SWI 2 "<general_operand>" "<g>"))
6064 (clobber (match_scratch:SWI 0 "=<r>"))]
6065 "ix86_match_ccmode (insn, CCGOCmode)
6066 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6068 switch (get_attr_type (insn))
6071 if (operands[2] == const1_rtx)
6072 return "inc{<imodesuffix>}\t%0";
6075 gcc_assert (operands[2] == constm1_rtx);
6076 return "dec{<imodesuffix>}\t%0";
6080 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6081 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6083 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6087 (if_then_else (match_operand:SWI 2 "incdec_operand")
6088 (const_string "incdec")
6089 (const_string "alu")))
6090 (set (attr "length_immediate")
6092 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand"))
6094 (const_string "*")))
6095 (set_attr "mode" "<MODE>")])
6097 (define_insn "*addqi_ext_1_rex64"
6098 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6103 (match_operand 1 "ext_register_operand" "0")
6106 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6107 (clobber (reg:CC FLAGS_REG))]
6110 switch (get_attr_type (insn))
6113 if (operands[2] == const1_rtx)
6114 return "inc{b}\t%h0";
6117 gcc_assert (operands[2] == constm1_rtx);
6118 return "dec{b}\t%h0";
6122 return "add{b}\t{%2, %h0|%h0, %2}";
6126 (if_then_else (match_operand:QI 2 "incdec_operand")
6127 (const_string "incdec")
6128 (const_string "alu")))
6129 (set_attr "modrm" "1")
6130 (set_attr "mode" "QI")])
6132 (define_insn "addqi_ext_1"
6133 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6138 (match_operand 1 "ext_register_operand" "0")
6141 (match_operand:QI 2 "general_operand" "Qmn")))
6142 (clobber (reg:CC FLAGS_REG))]
6145 switch (get_attr_type (insn))
6148 if (operands[2] == const1_rtx)
6149 return "inc{b}\t%h0";
6152 gcc_assert (operands[2] == constm1_rtx);
6153 return "dec{b}\t%h0";
6157 return "add{b}\t{%2, %h0|%h0, %2}";
6161 (if_then_else (match_operand:QI 2 "incdec_operand")
6162 (const_string "incdec")
6163 (const_string "alu")))
6164 (set_attr "modrm" "1")
6165 (set_attr "mode" "QI")])
6167 (define_insn "*addqi_ext_2"
6168 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6173 (match_operand 1 "ext_register_operand" "%0")
6177 (match_operand 2 "ext_register_operand" "Q")
6180 (clobber (reg:CC FLAGS_REG))]
6182 "add{b}\t{%h2, %h0|%h0, %h2}"
6183 [(set_attr "type" "alu")
6184 (set_attr "mode" "QI")])
6186 ;; The lea patterns for modes less than 32 bits need to be matched by
6187 ;; several insns converted to real lea by splitters.
6189 (define_insn_and_split "*lea_general_1"
6190 [(set (match_operand 0 "register_operand" "=r")
6191 (plus (plus (match_operand 1 "index_register_operand" "l")
6192 (match_operand 2 "register_operand" "r"))
6193 (match_operand 3 "immediate_operand" "i")))]
6194 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6195 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6196 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6197 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6198 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6199 || GET_MODE (operands[3]) == VOIDmode)"
6201 "&& reload_completed"
6204 enum machine_mode mode = SImode;
6207 operands[0] = gen_lowpart (mode, operands[0]);
6208 operands[1] = gen_lowpart (mode, operands[1]);
6209 operands[2] = gen_lowpart (mode, operands[2]);
6210 operands[3] = gen_lowpart (mode, operands[3]);
6212 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6215 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6218 [(set_attr "type" "lea")
6219 (set_attr "mode" "SI")])
6221 (define_insn_and_split "*lea_general_2"
6222 [(set (match_operand 0 "register_operand" "=r")
6223 (plus (mult (match_operand 1 "index_register_operand" "l")
6224 (match_operand 2 "const248_operand" "n"))
6225 (match_operand 3 "nonmemory_operand" "ri")))]
6226 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6227 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6228 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6229 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6230 || GET_MODE (operands[3]) == VOIDmode)"
6232 "&& reload_completed"
6235 enum machine_mode mode = SImode;
6238 operands[0] = gen_lowpart (mode, operands[0]);
6239 operands[1] = gen_lowpart (mode, operands[1]);
6240 operands[3] = gen_lowpart (mode, operands[3]);
6242 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6245 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6248 [(set_attr "type" "lea")
6249 (set_attr "mode" "SI")])
6251 (define_insn_and_split "*lea_general_3"
6252 [(set (match_operand 0 "register_operand" "=r")
6253 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6254 (match_operand 2 "const248_operand" "n"))
6255 (match_operand 3 "register_operand" "r"))
6256 (match_operand 4 "immediate_operand" "i")))]
6257 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6258 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6259 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6260 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6262 "&& reload_completed"
6265 enum machine_mode mode = SImode;
6268 operands[0] = gen_lowpart (mode, operands[0]);
6269 operands[1] = gen_lowpart (mode, operands[1]);
6270 operands[3] = gen_lowpart (mode, operands[3]);
6271 operands[4] = gen_lowpart (mode, operands[4]);
6273 pat = gen_rtx_PLUS (mode,
6275 gen_rtx_MULT (mode, operands[1],
6280 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6283 [(set_attr "type" "lea")
6284 (set_attr "mode" "SI")])
6286 (define_insn_and_split "*lea_general_4"
6287 [(set (match_operand 0 "register_operand" "=r")
6289 (match_operand 1 "index_register_operand" "l")
6290 (match_operand 2 "const_int_operand" "n"))
6291 (match_operand 3 "const_int_operand" "n")))]
6292 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6293 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6294 || GET_MODE (operands[0]) == SImode
6295 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6296 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6297 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6298 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6299 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6301 "&& reload_completed"
6304 enum machine_mode mode = GET_MODE (operands[0]);
6307 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6310 operands[0] = gen_lowpart (mode, operands[0]);
6311 operands[1] = gen_lowpart (mode, operands[1]);
6314 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6316 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6317 INTVAL (operands[3]));
6319 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6322 [(set_attr "type" "lea")
6324 (if_then_else (match_operand:DI 0)
6326 (const_string "SI")))])
6328 ;; Subtract instructions
6330 (define_expand "sub<mode>3"
6331 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
6332 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")
6333 (match_operand:SDWIM 2 "<general_operand>")))]
6335 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6337 (define_insn_and_split "*sub<dwi>3_doubleword"
6338 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6340 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6341 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6342 (clobber (reg:CC FLAGS_REG))]
6343 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6346 [(parallel [(set (reg:CC FLAGS_REG)
6347 (compare:CC (match_dup 1) (match_dup 2)))
6349 (minus:DWIH (match_dup 1) (match_dup 2)))])
6350 (parallel [(set (match_dup 3)
6354 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6356 (clobber (reg:CC FLAGS_REG))])]
6357 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6359 (define_insn "*sub<mode>_1"
6360 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6362 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6363 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6364 (clobber (reg:CC FLAGS_REG))]
6365 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6366 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6367 [(set_attr "type" "alu")
6368 (set_attr "mode" "<MODE>")])
6370 (define_insn "*subsi_1_zext"
6371 [(set (match_operand:DI 0 "register_operand" "=r")
6373 (minus:SI (match_operand:SI 1 "register_operand" "0")
6374 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6375 (clobber (reg:CC FLAGS_REG))]
6376 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6377 "sub{l}\t{%2, %k0|%k0, %2}"
6378 [(set_attr "type" "alu")
6379 (set_attr "mode" "SI")])
6381 (define_insn "*subqi_1_slp"
6382 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6383 (minus:QI (match_dup 0)
6384 (match_operand:QI 1 "general_operand" "qn,qm")))
6385 (clobber (reg:CC FLAGS_REG))]
6386 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6387 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6388 "sub{b}\t{%1, %0|%0, %1}"
6389 [(set_attr "type" "alu1")
6390 (set_attr "mode" "QI")])
6392 (define_insn "*sub<mode>_2"
6393 [(set (reg FLAGS_REG)
6396 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6397 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6399 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6400 (minus:SWI (match_dup 1) (match_dup 2)))]
6401 "ix86_match_ccmode (insn, CCGOCmode)
6402 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6403 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6404 [(set_attr "type" "alu")
6405 (set_attr "mode" "<MODE>")])
6407 (define_insn "*subsi_2_zext"
6408 [(set (reg FLAGS_REG)
6410 (minus:SI (match_operand:SI 1 "register_operand" "0")
6411 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6413 (set (match_operand:DI 0 "register_operand" "=r")
6415 (minus:SI (match_dup 1)
6417 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6418 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6419 "sub{l}\t{%2, %k0|%k0, %2}"
6420 [(set_attr "type" "alu")
6421 (set_attr "mode" "SI")])
6423 (define_insn "*sub<mode>_3"
6424 [(set (reg FLAGS_REG)
6425 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6426 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6427 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6428 (minus:SWI (match_dup 1) (match_dup 2)))]
6429 "ix86_match_ccmode (insn, CCmode)
6430 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6431 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6432 [(set_attr "type" "alu")
6433 (set_attr "mode" "<MODE>")])
6435 (define_insn "*subsi_3_zext"
6436 [(set (reg FLAGS_REG)
6437 (compare (match_operand:SI 1 "register_operand" "0")
6438 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6439 (set (match_operand:DI 0 "register_operand" "=r")
6441 (minus:SI (match_dup 1)
6443 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6444 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6445 "sub{l}\t{%2, %1|%1, %2}"
6446 [(set_attr "type" "alu")
6447 (set_attr "mode" "SI")])
6449 ;; Add with carry and subtract with borrow
6451 (define_expand "<plusminus_insn><mode>3_carry"
6453 [(set (match_operand:SWI 0 "nonimmediate_operand")
6455 (match_operand:SWI 1 "nonimmediate_operand")
6456 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6457 [(match_operand 3 "flags_reg_operand")
6459 (match_operand:SWI 2 "<general_operand>"))))
6460 (clobber (reg:CC FLAGS_REG))])]
6461 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6463 (define_insn "*<plusminus_insn><mode>3_carry"
6464 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6466 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6468 (match_operator 3 "ix86_carry_flag_operator"
6469 [(reg FLAGS_REG) (const_int 0)])
6470 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6471 (clobber (reg:CC FLAGS_REG))]
6472 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6473 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6474 [(set_attr "type" "alu")
6475 (set_attr "use_carry" "1")
6476 (set_attr "pent_pair" "pu")
6477 (set_attr "mode" "<MODE>")])
6479 (define_insn "*addsi3_carry_zext"
6480 [(set (match_operand:DI 0 "register_operand" "=r")
6482 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6483 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6484 [(reg FLAGS_REG) (const_int 0)])
6485 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6486 (clobber (reg:CC FLAGS_REG))]
6487 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6488 "adc{l}\t{%2, %k0|%k0, %2}"
6489 [(set_attr "type" "alu")
6490 (set_attr "use_carry" "1")
6491 (set_attr "pent_pair" "pu")
6492 (set_attr "mode" "SI")])
6494 (define_insn "*subsi3_carry_zext"
6495 [(set (match_operand:DI 0 "register_operand" "=r")
6497 (minus:SI (match_operand:SI 1 "register_operand" "0")
6498 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6499 [(reg FLAGS_REG) (const_int 0)])
6500 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6501 (clobber (reg:CC FLAGS_REG))]
6502 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6503 "sbb{l}\t{%2, %k0|%k0, %2}"
6504 [(set_attr "type" "alu")
6505 (set_attr "pent_pair" "pu")
6506 (set_attr "mode" "SI")])
6508 ;; Overflow setting add and subtract instructions
6510 (define_insn "*add<mode>3_cconly_overflow"
6511 [(set (reg:CCC FLAGS_REG)
6514 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6515 (match_operand:SWI 2 "<general_operand>" "<g>"))
6517 (clobber (match_scratch:SWI 0 "=<r>"))]
6518 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6519 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6520 [(set_attr "type" "alu")
6521 (set_attr "mode" "<MODE>")])
6523 (define_insn "*sub<mode>3_cconly_overflow"
6524 [(set (reg:CCC FLAGS_REG)
6527 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6528 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6531 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6532 [(set_attr "type" "icmp")
6533 (set_attr "mode" "<MODE>")])
6535 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6536 [(set (reg:CCC FLAGS_REG)
6539 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6540 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6542 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6543 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6544 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6545 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6546 [(set_attr "type" "alu")
6547 (set_attr "mode" "<MODE>")])
6549 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6550 [(set (reg:CCC FLAGS_REG)
6553 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6554 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6556 (set (match_operand:DI 0 "register_operand" "=r")
6557 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6558 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6559 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6560 [(set_attr "type" "alu")
6561 (set_attr "mode" "SI")])
6563 ;; The patterns that match these are at the end of this file.
6565 (define_expand "<plusminus_insn>xf3"
6566 [(set (match_operand:XF 0 "register_operand")
6568 (match_operand:XF 1 "register_operand")
6569 (match_operand:XF 2 "register_operand")))]
6572 (define_expand "<plusminus_insn><mode>3"
6573 [(set (match_operand:MODEF 0 "register_operand")
6575 (match_operand:MODEF 1 "register_operand")
6576 (match_operand:MODEF 2 "nonimmediate_operand")))]
6577 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6578 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6580 ;; Multiply instructions
6582 (define_expand "mul<mode>3"
6583 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
6585 (match_operand:SWIM248 1 "register_operand")
6586 (match_operand:SWIM248 2 "<general_operand>")))
6587 (clobber (reg:CC FLAGS_REG))])])
6589 (define_expand "mulqi3"
6590 [(parallel [(set (match_operand:QI 0 "register_operand")
6592 (match_operand:QI 1 "register_operand")
6593 (match_operand:QI 2 "nonimmediate_operand")))
6594 (clobber (reg:CC FLAGS_REG))])]
6595 "TARGET_QIMODE_MATH")
6598 ;; IMUL reg32/64, reg32/64, imm8 Direct
6599 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6600 ;; IMUL reg32/64, reg32/64, imm32 Direct
6601 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6602 ;; IMUL reg32/64, reg32/64 Direct
6603 ;; IMUL reg32/64, mem32/64 Direct
6605 ;; On BDVER1, all above IMULs use DirectPath
6607 (define_insn "*mul<mode>3_1"
6608 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6610 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6611 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6612 (clobber (reg:CC FLAGS_REG))]
6613 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6615 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6616 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6617 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6618 [(set_attr "type" "imul")
6619 (set_attr "prefix_0f" "0,0,1")
6620 (set (attr "athlon_decode")
6621 (cond [(eq_attr "cpu" "athlon")
6622 (const_string "vector")
6623 (eq_attr "alternative" "1")
6624 (const_string "vector")
6625 (and (eq_attr "alternative" "2")
6626 (match_operand 1 "memory_operand"))
6627 (const_string "vector")]
6628 (const_string "direct")))
6629 (set (attr "amdfam10_decode")
6630 (cond [(and (eq_attr "alternative" "0,1")
6631 (match_operand 1 "memory_operand"))
6632 (const_string "vector")]
6633 (const_string "direct")))
6634 (set_attr "bdver1_decode" "direct")
6635 (set_attr "mode" "<MODE>")])
6637 (define_insn "*mulsi3_1_zext"
6638 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6640 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6641 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6642 (clobber (reg:CC FLAGS_REG))]
6644 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6646 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6647 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6648 imul{l}\t{%2, %k0|%k0, %2}"
6649 [(set_attr "type" "imul")
6650 (set_attr "prefix_0f" "0,0,1")
6651 (set (attr "athlon_decode")
6652 (cond [(eq_attr "cpu" "athlon")
6653 (const_string "vector")
6654 (eq_attr "alternative" "1")
6655 (const_string "vector")
6656 (and (eq_attr "alternative" "2")
6657 (match_operand 1 "memory_operand"))
6658 (const_string "vector")]
6659 (const_string "direct")))
6660 (set (attr "amdfam10_decode")
6661 (cond [(and (eq_attr "alternative" "0,1")
6662 (match_operand 1 "memory_operand"))
6663 (const_string "vector")]
6664 (const_string "direct")))
6665 (set_attr "bdver1_decode" "direct")
6666 (set_attr "mode" "SI")])
6669 ;; IMUL reg16, reg16, imm8 VectorPath
6670 ;; IMUL reg16, mem16, imm8 VectorPath
6671 ;; IMUL reg16, reg16, imm16 VectorPath
6672 ;; IMUL reg16, mem16, imm16 VectorPath
6673 ;; IMUL reg16, reg16 Direct
6674 ;; IMUL reg16, mem16 Direct
6676 ;; On BDVER1, all HI MULs use DoublePath
6678 (define_insn "*mulhi3_1"
6679 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6680 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6681 (match_operand:HI 2 "general_operand" "K,n,mr")))
6682 (clobber (reg:CC FLAGS_REG))]
6684 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6686 imul{w}\t{%2, %1, %0|%0, %1, %2}
6687 imul{w}\t{%2, %1, %0|%0, %1, %2}
6688 imul{w}\t{%2, %0|%0, %2}"
6689 [(set_attr "type" "imul")
6690 (set_attr "prefix_0f" "0,0,1")
6691 (set (attr "athlon_decode")
6692 (cond [(eq_attr "cpu" "athlon")
6693 (const_string "vector")
6694 (eq_attr "alternative" "1,2")
6695 (const_string "vector")]
6696 (const_string "direct")))
6697 (set (attr "amdfam10_decode")
6698 (cond [(eq_attr "alternative" "0,1")
6699 (const_string "vector")]
6700 (const_string "direct")))
6701 (set_attr "bdver1_decode" "double")
6702 (set_attr "mode" "HI")])
6704 ;;On AMDFAM10 and BDVER1
6708 (define_insn "*mulqi3_1"
6709 [(set (match_operand:QI 0 "register_operand" "=a")
6710 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6711 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6712 (clobber (reg:CC FLAGS_REG))]
6714 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6716 [(set_attr "type" "imul")
6717 (set_attr "length_immediate" "0")
6718 (set (attr "athlon_decode")
6719 (if_then_else (eq_attr "cpu" "athlon")
6720 (const_string "vector")
6721 (const_string "direct")))
6722 (set_attr "amdfam10_decode" "direct")
6723 (set_attr "bdver1_decode" "direct")
6724 (set_attr "mode" "QI")])
6726 (define_expand "<u>mul<mode><dwi>3"
6727 [(parallel [(set (match_operand:<DWI> 0 "register_operand")
6730 (match_operand:DWIH 1 "nonimmediate_operand"))
6732 (match_operand:DWIH 2 "register_operand"))))
6733 (clobber (reg:CC FLAGS_REG))])])
6735 (define_expand "<u>mulqihi3"
6736 [(parallel [(set (match_operand:HI 0 "register_operand")
6739 (match_operand:QI 1 "nonimmediate_operand"))
6741 (match_operand:QI 2 "register_operand"))))
6742 (clobber (reg:CC FLAGS_REG))])]
6743 "TARGET_QIMODE_MATH")
6745 (define_insn "*bmi2_umulditi3_1"
6746 [(set (match_operand:DI 0 "register_operand" "=r")
6748 (match_operand:DI 2 "nonimmediate_operand" "%d")
6749 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6750 (set (match_operand:DI 1 "register_operand" "=r")
6753 (mult:TI (zero_extend:TI (match_dup 2))
6754 (zero_extend:TI (match_dup 3)))
6756 "TARGET_64BIT && TARGET_BMI2
6757 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6758 "mulx\t{%3, %0, %1|%1, %0, %3}"
6759 [(set_attr "type" "imulx")
6760 (set_attr "prefix" "vex")
6761 (set_attr "mode" "DI")])
6763 (define_insn "*bmi2_umulsidi3_1"
6764 [(set (match_operand:SI 0 "register_operand" "=r")
6766 (match_operand:SI 2 "nonimmediate_operand" "%d")
6767 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6768 (set (match_operand:SI 1 "register_operand" "=r")
6771 (mult:DI (zero_extend:DI (match_dup 2))
6772 (zero_extend:DI (match_dup 3)))
6774 "!TARGET_64BIT && TARGET_BMI2
6775 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6776 "mulx\t{%3, %0, %1|%1, %0, %3}"
6777 [(set_attr "type" "imulx")
6778 (set_attr "prefix" "vex")
6779 (set_attr "mode" "SI")])
6781 (define_insn "*umul<mode><dwi>3_1"
6782 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6785 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6787 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6788 (clobber (reg:CC FLAGS_REG))]
6789 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6791 mul{<imodesuffix>}\t%2
6793 [(set_attr "isa" "*,bmi2")
6794 (set_attr "type" "imul,imulx")
6795 (set_attr "length_immediate" "0,*")
6796 (set (attr "athlon_decode")
6797 (cond [(eq_attr "alternative" "0")
6798 (if_then_else (eq_attr "cpu" "athlon")
6799 (const_string "vector")
6800 (const_string "double"))]
6801 (const_string "*")))
6802 (set_attr "amdfam10_decode" "double,*")
6803 (set_attr "bdver1_decode" "direct,*")
6804 (set_attr "prefix" "orig,vex")
6805 (set_attr "mode" "<MODE>")])
6807 ;; Convert mul to the mulx pattern to avoid flags dependency.
6809 [(set (match_operand:<DWI> 0 "register_operand")
6812 (match_operand:DWIH 1 "register_operand"))
6814 (match_operand:DWIH 2 "nonimmediate_operand"))))
6815 (clobber (reg:CC FLAGS_REG))]
6816 "TARGET_BMI2 && reload_completed
6817 && true_regnum (operands[1]) == DX_REG"
6818 [(parallel [(set (match_dup 3)
6819 (mult:DWIH (match_dup 1) (match_dup 2)))
6823 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6824 (zero_extend:<DWI> (match_dup 2)))
6827 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6829 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6832 (define_insn "*mul<mode><dwi>3_1"
6833 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6836 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6838 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6839 (clobber (reg:CC FLAGS_REG))]
6840 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6841 "imul{<imodesuffix>}\t%2"
6842 [(set_attr "type" "imul")
6843 (set_attr "length_immediate" "0")
6844 (set (attr "athlon_decode")
6845 (if_then_else (eq_attr "cpu" "athlon")
6846 (const_string "vector")
6847 (const_string "double")))
6848 (set_attr "amdfam10_decode" "double")
6849 (set_attr "bdver1_decode" "direct")
6850 (set_attr "mode" "<MODE>")])
6852 (define_insn "*<u>mulqihi3_1"
6853 [(set (match_operand:HI 0 "register_operand" "=a")
6856 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6858 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6859 (clobber (reg:CC FLAGS_REG))]
6861 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6862 "<sgnprefix>mul{b}\t%2"
6863 [(set_attr "type" "imul")
6864 (set_attr "length_immediate" "0")
6865 (set (attr "athlon_decode")
6866 (if_then_else (eq_attr "cpu" "athlon")
6867 (const_string "vector")
6868 (const_string "direct")))
6869 (set_attr "amdfam10_decode" "direct")
6870 (set_attr "bdver1_decode" "direct")
6871 (set_attr "mode" "QI")])
6873 (define_expand "<s>mul<mode>3_highpart"
6874 [(parallel [(set (match_operand:SWI48 0 "register_operand")
6879 (match_operand:SWI48 1 "nonimmediate_operand"))
6881 (match_operand:SWI48 2 "register_operand")))
6883 (clobber (match_scratch:SWI48 3))
6884 (clobber (reg:CC FLAGS_REG))])]
6886 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6888 (define_insn "*<s>muldi3_highpart_1"
6889 [(set (match_operand:DI 0 "register_operand" "=d")
6894 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6896 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6898 (clobber (match_scratch:DI 3 "=1"))
6899 (clobber (reg:CC FLAGS_REG))]
6901 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6902 "<sgnprefix>mul{q}\t%2"
6903 [(set_attr "type" "imul")
6904 (set_attr "length_immediate" "0")
6905 (set (attr "athlon_decode")
6906 (if_then_else (eq_attr "cpu" "athlon")
6907 (const_string "vector")
6908 (const_string "double")))
6909 (set_attr "amdfam10_decode" "double")
6910 (set_attr "bdver1_decode" "direct")
6911 (set_attr "mode" "DI")])
6913 (define_insn "*<s>mulsi3_highpart_1"
6914 [(set (match_operand:SI 0 "register_operand" "=d")
6919 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6921 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6923 (clobber (match_scratch:SI 3 "=1"))
6924 (clobber (reg:CC FLAGS_REG))]
6925 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6926 "<sgnprefix>mul{l}\t%2"
6927 [(set_attr "type" "imul")
6928 (set_attr "length_immediate" "0")
6929 (set (attr "athlon_decode")
6930 (if_then_else (eq_attr "cpu" "athlon")
6931 (const_string "vector")
6932 (const_string "double")))
6933 (set_attr "amdfam10_decode" "double")
6934 (set_attr "bdver1_decode" "direct")
6935 (set_attr "mode" "SI")])
6937 (define_insn "*<s>mulsi3_highpart_zext"
6938 [(set (match_operand:DI 0 "register_operand" "=d")
6939 (zero_extend:DI (truncate:SI
6941 (mult:DI (any_extend:DI
6942 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6944 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6946 (clobber (match_scratch:SI 3 "=1"))
6947 (clobber (reg:CC FLAGS_REG))]
6949 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6950 "<sgnprefix>mul{l}\t%2"
6951 [(set_attr "type" "imul")
6952 (set_attr "length_immediate" "0")
6953 (set (attr "athlon_decode")
6954 (if_then_else (eq_attr "cpu" "athlon")
6955 (const_string "vector")
6956 (const_string "double")))
6957 (set_attr "amdfam10_decode" "double")
6958 (set_attr "bdver1_decode" "direct")
6959 (set_attr "mode" "SI")])
6961 ;; The patterns that match these are at the end of this file.
6963 (define_expand "mulxf3"
6964 [(set (match_operand:XF 0 "register_operand")
6965 (mult:XF (match_operand:XF 1 "register_operand")
6966 (match_operand:XF 2 "register_operand")))]
6969 (define_expand "mul<mode>3"
6970 [(set (match_operand:MODEF 0 "register_operand")
6971 (mult:MODEF (match_operand:MODEF 1 "register_operand")
6972 (match_operand:MODEF 2 "nonimmediate_operand")))]
6973 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6974 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6976 ;; Divide instructions
6978 ;; The patterns that match these are at the end of this file.
6980 (define_expand "divxf3"
6981 [(set (match_operand:XF 0 "register_operand")
6982 (div:XF (match_operand:XF 1 "register_operand")
6983 (match_operand:XF 2 "register_operand")))]
6986 (define_expand "divdf3"
6987 [(set (match_operand:DF 0 "register_operand")
6988 (div:DF (match_operand:DF 1 "register_operand")
6989 (match_operand:DF 2 "nonimmediate_operand")))]
6990 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6991 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6993 (define_expand "divsf3"
6994 [(set (match_operand:SF 0 "register_operand")
6995 (div:SF (match_operand:SF 1 "register_operand")
6996 (match_operand:SF 2 "nonimmediate_operand")))]
6997 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7002 && optimize_insn_for_speed_p ()
7003 && flag_finite_math_only && !flag_trapping_math
7004 && flag_unsafe_math_optimizations)
7006 ix86_emit_swdivsf (operands[0], operands[1],
7007 operands[2], SFmode);
7012 ;; Divmod instructions.
7014 (define_expand "divmod<mode>4"
7015 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7017 (match_operand:SWIM248 1 "register_operand")
7018 (match_operand:SWIM248 2 "nonimmediate_operand")))
7019 (set (match_operand:SWIM248 3 "register_operand")
7020 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7021 (clobber (reg:CC FLAGS_REG))])])
7023 ;; Split with 8bit unsigned divide:
7024 ;; if (dividend an divisor are in [0-255])
7025 ;; use 8bit unsigned integer divide
7027 ;; use original integer divide
7029 [(set (match_operand:SWI48 0 "register_operand")
7030 (div:SWI48 (match_operand:SWI48 2 "register_operand")
7031 (match_operand:SWI48 3 "nonimmediate_operand")))
7032 (set (match_operand:SWI48 1 "register_operand")
7033 (mod:SWI48 (match_dup 2) (match_dup 3)))
7034 (clobber (reg:CC FLAGS_REG))]
7035 "TARGET_USE_8BIT_IDIV
7036 && TARGET_QIMODE_MATH
7037 && can_create_pseudo_p ()
7038 && !optimize_insn_for_size_p ()"
7040 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7042 (define_insn_and_split "divmod<mode>4_1"
7043 [(set (match_operand:SWI48 0 "register_operand" "=a")
7044 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7045 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7046 (set (match_operand:SWI48 1 "register_operand" "=&d")
7047 (mod:SWI48 (match_dup 2) (match_dup 3)))
7048 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7049 (clobber (reg:CC FLAGS_REG))]
7053 [(parallel [(set (match_dup 1)
7054 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7055 (clobber (reg:CC FLAGS_REG))])
7056 (parallel [(set (match_dup 0)
7057 (div:SWI48 (match_dup 2) (match_dup 3)))
7059 (mod:SWI48 (match_dup 2) (match_dup 3)))
7061 (clobber (reg:CC FLAGS_REG))])]
7063 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7065 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7066 operands[4] = operands[2];
7069 /* Avoid use of cltd in favor of a mov+shift. */
7070 emit_move_insn (operands[1], operands[2]);
7071 operands[4] = operands[1];
7074 [(set_attr "type" "multi")
7075 (set_attr "mode" "<MODE>")])
7077 (define_insn_and_split "*divmod<mode>4"
7078 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7079 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7080 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7081 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7082 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7083 (clobber (reg:CC FLAGS_REG))]
7087 [(parallel [(set (match_dup 1)
7088 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7089 (clobber (reg:CC FLAGS_REG))])
7090 (parallel [(set (match_dup 0)
7091 (div:SWIM248 (match_dup 2) (match_dup 3)))
7093 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7095 (clobber (reg:CC FLAGS_REG))])]
7097 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7099 if (<MODE>mode != HImode
7100 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7101 operands[4] = operands[2];
7104 /* Avoid use of cltd in favor of a mov+shift. */
7105 emit_move_insn (operands[1], operands[2]);
7106 operands[4] = operands[1];
7109 [(set_attr "type" "multi")
7110 (set_attr "mode" "<MODE>")])
7112 (define_insn "*divmod<mode>4_noext"
7113 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7114 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7115 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7116 (set (match_operand:SWIM248 1 "register_operand" "=d")
7117 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7118 (use (match_operand:SWIM248 4 "register_operand" "1"))
7119 (clobber (reg:CC FLAGS_REG))]
7121 "idiv{<imodesuffix>}\t%3"
7122 [(set_attr "type" "idiv")
7123 (set_attr "mode" "<MODE>")])
7125 (define_expand "divmodqi4"
7126 [(parallel [(set (match_operand:QI 0 "register_operand")
7128 (match_operand:QI 1 "register_operand")
7129 (match_operand:QI 2 "nonimmediate_operand")))
7130 (set (match_operand:QI 3 "register_operand")
7131 (mod:QI (match_dup 1) (match_dup 2)))
7132 (clobber (reg:CC FLAGS_REG))])]
7133 "TARGET_QIMODE_MATH"
7138 tmp0 = gen_reg_rtx (HImode);
7139 tmp1 = gen_reg_rtx (HImode);
7141 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7143 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7144 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7146 /* Extract remainder from AH. */
7147 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7148 insn = emit_move_insn (operands[3], tmp1);
7150 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7151 set_unique_reg_note (insn, REG_EQUAL, mod);
7153 /* Extract quotient from AL. */
7154 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7156 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7157 set_unique_reg_note (insn, REG_EQUAL, div);
7162 ;; Divide AX by r/m8, with result stored in
7165 ;; Change div/mod to HImode and extend the second argument to HImode
7166 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7167 ;; combine may fail.
7168 (define_insn "divmodhiqi3"
7169 [(set (match_operand:HI 0 "register_operand" "=a")
7174 (mod:HI (match_operand:HI 1 "register_operand" "0")
7176 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7180 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7181 (clobber (reg:CC FLAGS_REG))]
7182 "TARGET_QIMODE_MATH"
7184 [(set_attr "type" "idiv")
7185 (set_attr "mode" "QI")])
7187 (define_expand "udivmod<mode>4"
7188 [(parallel [(set (match_operand:SWIM248 0 "register_operand")
7190 (match_operand:SWIM248 1 "register_operand")
7191 (match_operand:SWIM248 2 "nonimmediate_operand")))
7192 (set (match_operand:SWIM248 3 "register_operand")
7193 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7194 (clobber (reg:CC FLAGS_REG))])])
7196 ;; Split with 8bit unsigned divide:
7197 ;; if (dividend an divisor are in [0-255])
7198 ;; use 8bit unsigned integer divide
7200 ;; use original integer divide
7202 [(set (match_operand:SWI48 0 "register_operand")
7203 (udiv:SWI48 (match_operand:SWI48 2 "register_operand")
7204 (match_operand:SWI48 3 "nonimmediate_operand")))
7205 (set (match_operand:SWI48 1 "register_operand")
7206 (umod:SWI48 (match_dup 2) (match_dup 3)))
7207 (clobber (reg:CC FLAGS_REG))]
7208 "TARGET_USE_8BIT_IDIV
7209 && TARGET_QIMODE_MATH
7210 && can_create_pseudo_p ()
7211 && !optimize_insn_for_size_p ()"
7213 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7215 (define_insn_and_split "udivmod<mode>4_1"
7216 [(set (match_operand:SWI48 0 "register_operand" "=a")
7217 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7218 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7219 (set (match_operand:SWI48 1 "register_operand" "=&d")
7220 (umod:SWI48 (match_dup 2) (match_dup 3)))
7221 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7222 (clobber (reg:CC FLAGS_REG))]
7226 [(set (match_dup 1) (const_int 0))
7227 (parallel [(set (match_dup 0)
7228 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7230 (umod:SWI48 (match_dup 2) (match_dup 3)))
7232 (clobber (reg:CC FLAGS_REG))])]
7234 [(set_attr "type" "multi")
7235 (set_attr "mode" "<MODE>")])
7237 (define_insn_and_split "*udivmod<mode>4"
7238 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7239 (udiv: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 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7243 (clobber (reg:CC FLAGS_REG))]
7247 [(set (match_dup 1) (const_int 0))
7248 (parallel [(set (match_dup 0)
7249 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7251 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7253 (clobber (reg:CC FLAGS_REG))])]
7255 [(set_attr "type" "multi")
7256 (set_attr "mode" "<MODE>")])
7258 (define_insn "*udivmod<mode>4_noext"
7259 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7260 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7261 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7262 (set (match_operand:SWIM248 1 "register_operand" "=d")
7263 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7264 (use (match_operand:SWIM248 4 "register_operand" "1"))
7265 (clobber (reg:CC FLAGS_REG))]
7267 "div{<imodesuffix>}\t%3"
7268 [(set_attr "type" "idiv")
7269 (set_attr "mode" "<MODE>")])
7271 (define_expand "udivmodqi4"
7272 [(parallel [(set (match_operand:QI 0 "register_operand")
7274 (match_operand:QI 1 "register_operand")
7275 (match_operand:QI 2 "nonimmediate_operand")))
7276 (set (match_operand:QI 3 "register_operand")
7277 (umod:QI (match_dup 1) (match_dup 2)))
7278 (clobber (reg:CC FLAGS_REG))])]
7279 "TARGET_QIMODE_MATH"
7284 tmp0 = gen_reg_rtx (HImode);
7285 tmp1 = gen_reg_rtx (HImode);
7287 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7289 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7290 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7292 /* Extract remainder from AH. */
7293 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7294 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7295 insn = emit_move_insn (operands[3], tmp1);
7297 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7298 set_unique_reg_note (insn, REG_EQUAL, mod);
7300 /* Extract quotient from AL. */
7301 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7303 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7304 set_unique_reg_note (insn, REG_EQUAL, div);
7309 (define_insn "udivmodhiqi3"
7310 [(set (match_operand:HI 0 "register_operand" "=a")
7315 (mod:HI (match_operand:HI 1 "register_operand" "0")
7317 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7321 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7322 (clobber (reg:CC FLAGS_REG))]
7323 "TARGET_QIMODE_MATH"
7325 [(set_attr "type" "idiv")
7326 (set_attr "mode" "QI")])
7328 ;; We cannot use div/idiv for double division, because it causes
7329 ;; "division by zero" on the overflow and that's not what we expect
7330 ;; from truncate. Because true (non truncating) double division is
7331 ;; never generated, we can't create this insn anyway.
7334 ; [(set (match_operand:SI 0 "register_operand" "=a")
7336 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7338 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7339 ; (set (match_operand:SI 3 "register_operand" "=d")
7341 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7342 ; (clobber (reg:CC FLAGS_REG))]
7344 ; "div{l}\t{%2, %0|%0, %2}"
7345 ; [(set_attr "type" "idiv")])
7347 ;;- Logical AND instructions
7349 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7350 ;; Note that this excludes ah.
7352 (define_expand "testsi_ccno_1"
7353 [(set (reg:CCNO FLAGS_REG)
7355 (and:SI (match_operand:SI 0 "nonimmediate_operand")
7356 (match_operand:SI 1 "x86_64_nonmemory_operand"))
7359 (define_expand "testqi_ccz_1"
7360 [(set (reg:CCZ FLAGS_REG)
7361 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand")
7362 (match_operand:QI 1 "nonmemory_operand"))
7365 (define_expand "testdi_ccno_1"
7366 [(set (reg:CCNO FLAGS_REG)
7368 (and:DI (match_operand:DI 0 "nonimmediate_operand")
7369 (match_operand:DI 1 "x86_64_szext_general_operand"))
7371 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7373 (define_insn "*testdi_1"
7374 [(set (reg FLAGS_REG)
7377 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7378 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7380 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7381 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7383 test{l}\t{%k1, %k0|%k0, %k1}
7384 test{l}\t{%k1, %k0|%k0, %k1}
7385 test{q}\t{%1, %0|%0, %1}
7386 test{q}\t{%1, %0|%0, %1}
7387 test{q}\t{%1, %0|%0, %1}"
7388 [(set_attr "type" "test")
7389 (set_attr "modrm" "0,1,0,1,1")
7390 (set_attr "mode" "SI,SI,DI,DI,DI")])
7392 (define_insn "*testqi_1_maybe_si"
7393 [(set (reg FLAGS_REG)
7396 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7397 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7399 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7400 && ix86_match_ccmode (insn,
7401 CONST_INT_P (operands[1])
7402 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7404 if (which_alternative == 3)
7406 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7407 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7408 return "test{l}\t{%1, %k0|%k0, %1}";
7410 return "test{b}\t{%1, %0|%0, %1}";
7412 [(set_attr "type" "test")
7413 (set_attr "modrm" "0,1,1,1")
7414 (set_attr "mode" "QI,QI,QI,SI")
7415 (set_attr "pent_pair" "uv,np,uv,np")])
7417 (define_insn "*test<mode>_1"
7418 [(set (reg FLAGS_REG)
7421 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7422 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7424 "ix86_match_ccmode (insn, CCNOmode)
7425 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7426 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7427 [(set_attr "type" "test")
7428 (set_attr "modrm" "0,1,1")
7429 (set_attr "mode" "<MODE>")
7430 (set_attr "pent_pair" "uv,np,uv")])
7432 (define_expand "testqi_ext_ccno_0"
7433 [(set (reg:CCNO FLAGS_REG)
7437 (match_operand 0 "ext_register_operand")
7440 (match_operand 1 "const_int_operand"))
7443 (define_insn "*testqi_ext_0"
7444 [(set (reg FLAGS_REG)
7448 (match_operand 0 "ext_register_operand" "Q")
7451 (match_operand 1 "const_int_operand" "n"))
7453 "ix86_match_ccmode (insn, CCNOmode)"
7454 "test{b}\t{%1, %h0|%h0, %1}"
7455 [(set_attr "type" "test")
7456 (set_attr "mode" "QI")
7457 (set_attr "length_immediate" "1")
7458 (set_attr "modrm" "1")
7459 (set_attr "pent_pair" "np")])
7461 (define_insn "*testqi_ext_1_rex64"
7462 [(set (reg FLAGS_REG)
7466 (match_operand 0 "ext_register_operand" "Q")
7470 (match_operand:QI 1 "register_operand" "Q")))
7472 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7473 "test{b}\t{%1, %h0|%h0, %1}"
7474 [(set_attr "type" "test")
7475 (set_attr "mode" "QI")])
7477 (define_insn "*testqi_ext_1"
7478 [(set (reg FLAGS_REG)
7482 (match_operand 0 "ext_register_operand" "Q")
7486 (match_operand:QI 1 "general_operand" "Qm")))
7488 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7489 "test{b}\t{%1, %h0|%h0, %1}"
7490 [(set_attr "type" "test")
7491 (set_attr "mode" "QI")])
7493 (define_insn "*testqi_ext_2"
7494 [(set (reg FLAGS_REG)
7498 (match_operand 0 "ext_register_operand" "Q")
7502 (match_operand 1 "ext_register_operand" "Q")
7506 "ix86_match_ccmode (insn, CCNOmode)"
7507 "test{b}\t{%h1, %h0|%h0, %h1}"
7508 [(set_attr "type" "test")
7509 (set_attr "mode" "QI")])
7511 (define_insn "*testqi_ext_3_rex64"
7512 [(set (reg FLAGS_REG)
7513 (compare (zero_extract:DI
7514 (match_operand 0 "nonimmediate_operand" "rm")
7515 (match_operand:DI 1 "const_int_operand")
7516 (match_operand:DI 2 "const_int_operand"))
7519 && ix86_match_ccmode (insn, CCNOmode)
7520 && INTVAL (operands[1]) > 0
7521 && INTVAL (operands[2]) >= 0
7522 /* Ensure that resulting mask is zero or sign extended operand. */
7523 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7524 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7525 && INTVAL (operands[1]) > 32))
7526 && (GET_MODE (operands[0]) == SImode
7527 || GET_MODE (operands[0]) == DImode
7528 || GET_MODE (operands[0]) == HImode
7529 || GET_MODE (operands[0]) == QImode)"
7532 ;; Combine likes to form bit extractions for some tests. Humor it.
7533 (define_insn "*testqi_ext_3"
7534 [(set (reg FLAGS_REG)
7535 (compare (zero_extract:SI
7536 (match_operand 0 "nonimmediate_operand" "rm")
7537 (match_operand:SI 1 "const_int_operand")
7538 (match_operand:SI 2 "const_int_operand"))
7540 "ix86_match_ccmode (insn, CCNOmode)
7541 && INTVAL (operands[1]) > 0
7542 && INTVAL (operands[2]) >= 0
7543 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7544 && (GET_MODE (operands[0]) == SImode
7545 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7546 || GET_MODE (operands[0]) == HImode
7547 || GET_MODE (operands[0]) == QImode)"
7551 [(set (match_operand 0 "flags_reg_operand")
7552 (match_operator 1 "compare_operator"
7554 (match_operand 2 "nonimmediate_operand")
7555 (match_operand 3 "const_int_operand")
7556 (match_operand 4 "const_int_operand"))
7558 "ix86_match_ccmode (insn, CCNOmode)"
7559 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7561 rtx val = operands[2];
7562 HOST_WIDE_INT len = INTVAL (operands[3]);
7563 HOST_WIDE_INT pos = INTVAL (operands[4]);
7565 enum machine_mode mode, submode;
7567 mode = GET_MODE (val);
7570 /* ??? Combine likes to put non-volatile mem extractions in QImode
7571 no matter the size of the test. So find a mode that works. */
7572 if (! MEM_VOLATILE_P (val))
7574 mode = smallest_mode_for_size (pos + len, MODE_INT);
7575 val = adjust_address (val, mode, 0);
7578 else if (GET_CODE (val) == SUBREG
7579 && (submode = GET_MODE (SUBREG_REG (val)),
7580 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7581 && pos + len <= GET_MODE_BITSIZE (submode)
7582 && GET_MODE_CLASS (submode) == MODE_INT)
7584 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7586 val = SUBREG_REG (val);
7588 else if (mode == HImode && pos + len <= 8)
7590 /* Small HImode tests can be converted to QImode. */
7592 val = gen_lowpart (QImode, val);
7595 if (len == HOST_BITS_PER_WIDE_INT)
7598 mask = ((HOST_WIDE_INT)1 << len) - 1;
7601 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7604 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7605 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7606 ;; this is relatively important trick.
7607 ;; Do the conversion only post-reload to avoid limiting of the register class
7610 [(set (match_operand 0 "flags_reg_operand")
7611 (match_operator 1 "compare_operator"
7612 [(and (match_operand 2 "register_operand")
7613 (match_operand 3 "const_int_operand"))
7616 && QI_REG_P (operands[2])
7617 && GET_MODE (operands[2]) != QImode
7618 && ((ix86_match_ccmode (insn, CCZmode)
7619 && !(INTVAL (operands[3]) & ~(255 << 8)))
7620 || (ix86_match_ccmode (insn, CCNOmode)
7621 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7624 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7628 operands[2] = gen_lowpart (SImode, operands[2]);
7629 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7633 [(set (match_operand 0 "flags_reg_operand")
7634 (match_operator 1 "compare_operator"
7635 [(and (match_operand 2 "nonimmediate_operand")
7636 (match_operand 3 "const_int_operand"))
7639 && GET_MODE (operands[2]) != QImode
7640 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7641 && ((ix86_match_ccmode (insn, CCZmode)
7642 && !(INTVAL (operands[3]) & ~255))
7643 || (ix86_match_ccmode (insn, CCNOmode)
7644 && !(INTVAL (operands[3]) & ~127)))"
7646 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7649 operands[2] = gen_lowpart (QImode, operands[2]);
7650 operands[3] = gen_lowpart (QImode, operands[3]);
7653 ;; %%% This used to optimize known byte-wide and operations to memory,
7654 ;; and sometimes to QImode registers. If this is considered useful,
7655 ;; it should be done with splitters.
7657 (define_expand "and<mode>3"
7658 [(set (match_operand:SWIM 0 "nonimmediate_operand")
7659 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
7660 (match_operand:SWIM 2 "<general_szext_operand>")))]
7662 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7664 (define_insn "*anddi_1"
7665 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7667 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7668 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7669 (clobber (reg:CC FLAGS_REG))]
7670 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7672 switch (get_attr_type (insn))
7678 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7679 if (get_attr_mode (insn) == MODE_SI)
7680 return "and{l}\t{%k2, %k0|%k0, %k2}";
7682 return "and{q}\t{%2, %0|%0, %2}";
7685 [(set_attr "type" "alu,alu,alu,imovx")
7686 (set_attr "length_immediate" "*,*,*,0")
7687 (set (attr "prefix_rex")
7689 (and (eq_attr "type" "imovx")
7690 (and (match_test "INTVAL (operands[2]) == 0xff")
7691 (match_operand 1 "ext_QIreg_operand")))
7693 (const_string "*")))
7694 (set_attr "mode" "SI,DI,DI,SI")])
7696 (define_insn "*andsi_1"
7697 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7698 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7699 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7700 (clobber (reg:CC FLAGS_REG))]
7701 "ix86_binary_operator_ok (AND, SImode, operands)"
7703 switch (get_attr_type (insn))
7709 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7710 return "and{l}\t{%2, %0|%0, %2}";
7713 [(set_attr "type" "alu,alu,imovx")
7714 (set (attr "prefix_rex")
7716 (and (eq_attr "type" "imovx")
7717 (and (match_test "INTVAL (operands[2]) == 0xff")
7718 (match_operand 1 "ext_QIreg_operand")))
7720 (const_string "*")))
7721 (set_attr "length_immediate" "*,*,0")
7722 (set_attr "mode" "SI")])
7724 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7725 (define_insn "*andsi_1_zext"
7726 [(set (match_operand:DI 0 "register_operand" "=r")
7728 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7729 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7730 (clobber (reg:CC FLAGS_REG))]
7731 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7732 "and{l}\t{%2, %k0|%k0, %2}"
7733 [(set_attr "type" "alu")
7734 (set_attr "mode" "SI")])
7736 (define_insn "*andhi_1"
7737 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7738 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7739 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7740 (clobber (reg:CC FLAGS_REG))]
7741 "ix86_binary_operator_ok (AND, HImode, operands)"
7743 switch (get_attr_type (insn))
7749 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7750 return "and{w}\t{%2, %0|%0, %2}";
7753 [(set_attr "type" "alu,alu,imovx")
7754 (set_attr "length_immediate" "*,*,0")
7755 (set (attr "prefix_rex")
7757 (and (eq_attr "type" "imovx")
7758 (match_operand 1 "ext_QIreg_operand"))
7760 (const_string "*")))
7761 (set_attr "mode" "HI,HI,SI")])
7763 ;; %%% Potential partial reg stall on alternative 2. What to do?
7764 (define_insn "*andqi_1"
7765 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7766 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7767 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7768 (clobber (reg:CC FLAGS_REG))]
7769 "ix86_binary_operator_ok (AND, QImode, operands)"
7771 and{b}\t{%2, %0|%0, %2}
7772 and{b}\t{%2, %0|%0, %2}
7773 and{l}\t{%k2, %k0|%k0, %k2}"
7774 [(set_attr "type" "alu")
7775 (set_attr "mode" "QI,QI,SI")])
7777 (define_insn "*andqi_1_slp"
7778 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7779 (and:QI (match_dup 0)
7780 (match_operand:QI 1 "general_operand" "qn,qmn")))
7781 (clobber (reg:CC FLAGS_REG))]
7782 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7783 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7784 "and{b}\t{%1, %0|%0, %1}"
7785 [(set_attr "type" "alu1")
7786 (set_attr "mode" "QI")])
7789 [(set (match_operand:SWI248 0 "register_operand")
7790 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand")
7791 (match_operand:SWI248 2 "const_int_operand")))
7792 (clobber (reg:CC FLAGS_REG))]
7794 && true_regnum (operands[0]) != true_regnum (operands[1])"
7797 enum machine_mode mode;
7799 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7801 else if (INTVAL (operands[2]) == 0xffff)
7805 gcc_assert (INTVAL (operands[2]) == 0xff);
7809 operands[1] = gen_lowpart (mode, operands[1]);
7812 emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
7815 rtx (*insn) (rtx, rtx);
7817 /* Zero extend to SImode to avoid partial register stalls. */
7818 operands[0] = gen_lowpart (SImode, operands[0]);
7820 insn = (mode == HImode) ? gen_zero_extendhisi2 : gen_zero_extendqisi2;
7821 emit_insn (insn (operands[0], operands[1]));
7827 [(set (match_operand 0 "register_operand")
7829 (const_int -65536)))
7830 (clobber (reg:CC FLAGS_REG))]
7831 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7832 || optimize_function_for_size_p (cfun)"
7833 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7834 "operands[1] = gen_lowpart (HImode, operands[0]);")
7837 [(set (match_operand 0 "ext_register_operand")
7840 (clobber (reg:CC FLAGS_REG))]
7841 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7842 && reload_completed"
7843 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7844 "operands[1] = gen_lowpart (QImode, operands[0]);")
7847 [(set (match_operand 0 "ext_register_operand")
7849 (const_int -65281)))
7850 (clobber (reg:CC FLAGS_REG))]
7851 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7852 && reload_completed"
7853 [(parallel [(set (zero_extract:SI (match_dup 0)
7857 (zero_extract:SI (match_dup 0)
7860 (zero_extract:SI (match_dup 0)
7863 (clobber (reg:CC FLAGS_REG))])]
7864 "operands[0] = gen_lowpart (SImode, operands[0]);")
7866 (define_insn "*anddi_2"
7867 [(set (reg FLAGS_REG)
7870 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7871 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7873 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7874 (and:DI (match_dup 1) (match_dup 2)))]
7875 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7876 && ix86_binary_operator_ok (AND, DImode, operands)"
7878 and{l}\t{%k2, %k0|%k0, %k2}
7879 and{q}\t{%2, %0|%0, %2}
7880 and{q}\t{%2, %0|%0, %2}"
7881 [(set_attr "type" "alu")
7882 (set_attr "mode" "SI,DI,DI")])
7884 (define_insn "*andqi_2_maybe_si"
7885 [(set (reg FLAGS_REG)
7887 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7888 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7890 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7891 (and:QI (match_dup 1) (match_dup 2)))]
7892 "ix86_binary_operator_ok (AND, QImode, operands)
7893 && ix86_match_ccmode (insn,
7894 CONST_INT_P (operands[2])
7895 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7897 if (which_alternative == 2)
7899 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7900 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7901 return "and{l}\t{%2, %k0|%k0, %2}";
7903 return "and{b}\t{%2, %0|%0, %2}";
7905 [(set_attr "type" "alu")
7906 (set_attr "mode" "QI,QI,SI")])
7908 (define_insn "*and<mode>_2"
7909 [(set (reg FLAGS_REG)
7910 (compare (and:SWI124
7911 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7912 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7914 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7915 (and:SWI124 (match_dup 1) (match_dup 2)))]
7916 "ix86_match_ccmode (insn, CCNOmode)
7917 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7918 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7919 [(set_attr "type" "alu")
7920 (set_attr "mode" "<MODE>")])
7922 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7923 (define_insn "*andsi_2_zext"
7924 [(set (reg FLAGS_REG)
7926 (match_operand:SI 1 "nonimmediate_operand" "%0")
7927 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7929 (set (match_operand:DI 0 "register_operand" "=r")
7930 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7931 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7932 && ix86_binary_operator_ok (AND, SImode, operands)"
7933 "and{l}\t{%2, %k0|%k0, %2}"
7934 [(set_attr "type" "alu")
7935 (set_attr "mode" "SI")])
7937 (define_insn "*andqi_2_slp"
7938 [(set (reg FLAGS_REG)
7940 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7941 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7943 (set (strict_low_part (match_dup 0))
7944 (and:QI (match_dup 0) (match_dup 1)))]
7945 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7946 && ix86_match_ccmode (insn, CCNOmode)
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 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7953 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7954 ;; for a QImode operand, which of course failed.
7955 (define_insn "andqi_ext_0"
7956 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7961 (match_operand 1 "ext_register_operand" "0")
7964 (match_operand 2 "const_int_operand" "n")))
7965 (clobber (reg:CC FLAGS_REG))]
7967 "and{b}\t{%2, %h0|%h0, %2}"
7968 [(set_attr "type" "alu")
7969 (set_attr "length_immediate" "1")
7970 (set_attr "modrm" "1")
7971 (set_attr "mode" "QI")])
7973 ;; Generated by peephole translating test to and. This shows up
7974 ;; often in fp comparisons.
7975 (define_insn "*andqi_ext_0_cc"
7976 [(set (reg FLAGS_REG)
7980 (match_operand 1 "ext_register_operand" "0")
7983 (match_operand 2 "const_int_operand" "n"))
7985 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7994 "ix86_match_ccmode (insn, CCNOmode)"
7995 "and{b}\t{%2, %h0|%h0, %2}"
7996 [(set_attr "type" "alu")
7997 (set_attr "length_immediate" "1")
7998 (set_attr "modrm" "1")
7999 (set_attr "mode" "QI")])
8001 (define_insn "*andqi_ext_1_rex64"
8002 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8007 (match_operand 1 "ext_register_operand" "0")
8011 (match_operand 2 "ext_register_operand" "Q"))))
8012 (clobber (reg:CC FLAGS_REG))]
8014 "and{b}\t{%2, %h0|%h0, %2}"
8015 [(set_attr "type" "alu")
8016 (set_attr "length_immediate" "0")
8017 (set_attr "mode" "QI")])
8019 (define_insn "*andqi_ext_1"
8020 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8025 (match_operand 1 "ext_register_operand" "0")
8029 (match_operand:QI 2 "general_operand" "Qm"))))
8030 (clobber (reg:CC FLAGS_REG))]
8032 "and{b}\t{%2, %h0|%h0, %2}"
8033 [(set_attr "type" "alu")
8034 (set_attr "length_immediate" "0")
8035 (set_attr "mode" "QI")])
8037 (define_insn "*andqi_ext_2"
8038 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8043 (match_operand 1 "ext_register_operand" "%0")
8047 (match_operand 2 "ext_register_operand" "Q")
8050 (clobber (reg:CC FLAGS_REG))]
8052 "and{b}\t{%h2, %h0|%h0, %h2}"
8053 [(set_attr "type" "alu")
8054 (set_attr "length_immediate" "0")
8055 (set_attr "mode" "QI")])
8057 ;; Convert wide AND instructions with immediate operand to shorter QImode
8058 ;; equivalents when possible.
8059 ;; Don't do the splitting with memory operands, since it introduces risk
8060 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8061 ;; for size, but that can (should?) be handled by generic code instead.
8063 [(set (match_operand 0 "register_operand")
8064 (and (match_operand 1 "register_operand")
8065 (match_operand 2 "const_int_operand")))
8066 (clobber (reg:CC FLAGS_REG))]
8068 && QI_REG_P (operands[0])
8069 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8070 && !(~INTVAL (operands[2]) & ~(255 << 8))
8071 && GET_MODE (operands[0]) != QImode"
8072 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8073 (and:SI (zero_extract:SI (match_dup 1)
8074 (const_int 8) (const_int 8))
8076 (clobber (reg:CC FLAGS_REG))])]
8078 operands[0] = gen_lowpart (SImode, operands[0]);
8079 operands[1] = gen_lowpart (SImode, operands[1]);
8080 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8083 ;; Since AND can be encoded with sign extended immediate, this is only
8084 ;; profitable when 7th bit is not set.
8086 [(set (match_operand 0 "register_operand")
8087 (and (match_operand 1 "general_operand")
8088 (match_operand 2 "const_int_operand")))
8089 (clobber (reg:CC FLAGS_REG))]
8091 && ANY_QI_REG_P (operands[0])
8092 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8093 && !(~INTVAL (operands[2]) & ~255)
8094 && !(INTVAL (operands[2]) & 128)
8095 && GET_MODE (operands[0]) != QImode"
8096 [(parallel [(set (strict_low_part (match_dup 0))
8097 (and:QI (match_dup 1)
8099 (clobber (reg:CC FLAGS_REG))])]
8101 operands[0] = gen_lowpart (QImode, operands[0]);
8102 operands[1] = gen_lowpart (QImode, operands[1]);
8103 operands[2] = gen_lowpart (QImode, operands[2]);
8106 ;; Logical inclusive and exclusive OR instructions
8108 ;; %%% This used to optimize known byte-wide and operations to memory.
8109 ;; If this is considered useful, it should be done with splitters.
8111 (define_expand "<code><mode>3"
8112 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8113 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand")
8114 (match_operand:SWIM 2 "<general_operand>")))]
8116 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8118 (define_insn "*<code><mode>_1"
8119 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8121 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8122 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8123 (clobber (reg:CC FLAGS_REG))]
8124 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8125 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8126 [(set_attr "type" "alu")
8127 (set_attr "mode" "<MODE>")])
8129 ;; %%% Potential partial reg stall on alternative 2. What to do?
8130 (define_insn "*<code>qi_1"
8131 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8132 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8133 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8134 (clobber (reg:CC FLAGS_REG))]
8135 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8137 <logic>{b}\t{%2, %0|%0, %2}
8138 <logic>{b}\t{%2, %0|%0, %2}
8139 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8140 [(set_attr "type" "alu")
8141 (set_attr "mode" "QI,QI,SI")])
8143 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8144 (define_insn "*<code>si_1_zext"
8145 [(set (match_operand:DI 0 "register_operand" "=r")
8147 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8148 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8149 (clobber (reg:CC FLAGS_REG))]
8150 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8151 "<logic>{l}\t{%2, %k0|%k0, %2}"
8152 [(set_attr "type" "alu")
8153 (set_attr "mode" "SI")])
8155 (define_insn "*<code>si_1_zext_imm"
8156 [(set (match_operand:DI 0 "register_operand" "=r")
8158 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8159 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8160 (clobber (reg:CC FLAGS_REG))]
8161 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8162 "<logic>{l}\t{%2, %k0|%k0, %2}"
8163 [(set_attr "type" "alu")
8164 (set_attr "mode" "SI")])
8166 (define_insn "*<code>qi_1_slp"
8167 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8168 (any_or:QI (match_dup 0)
8169 (match_operand:QI 1 "general_operand" "qmn,qn")))
8170 (clobber (reg:CC FLAGS_REG))]
8171 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8172 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8173 "<logic>{b}\t{%1, %0|%0, %1}"
8174 [(set_attr "type" "alu1")
8175 (set_attr "mode" "QI")])
8177 (define_insn "*<code><mode>_2"
8178 [(set (reg FLAGS_REG)
8179 (compare (any_or:SWI
8180 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8181 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8183 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8184 (any_or:SWI (match_dup 1) (match_dup 2)))]
8185 "ix86_match_ccmode (insn, CCNOmode)
8186 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8187 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8188 [(set_attr "type" "alu")
8189 (set_attr "mode" "<MODE>")])
8191 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8192 ;; ??? Special case for immediate operand is missing - it is tricky.
8193 (define_insn "*<code>si_2_zext"
8194 [(set (reg FLAGS_REG)
8195 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8196 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8198 (set (match_operand:DI 0 "register_operand" "=r")
8199 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8200 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8201 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8202 "<logic>{l}\t{%2, %k0|%k0, %2}"
8203 [(set_attr "type" "alu")
8204 (set_attr "mode" "SI")])
8206 (define_insn "*<code>si_2_zext_imm"
8207 [(set (reg FLAGS_REG)
8209 (match_operand:SI 1 "nonimmediate_operand" "%0")
8210 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8212 (set (match_operand:DI 0 "register_operand" "=r")
8213 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8214 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8215 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8216 "<logic>{l}\t{%2, %k0|%k0, %2}"
8217 [(set_attr "type" "alu")
8218 (set_attr "mode" "SI")])
8220 (define_insn "*<code>qi_2_slp"
8221 [(set (reg FLAGS_REG)
8222 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8223 (match_operand:QI 1 "general_operand" "qmn,qn"))
8225 (set (strict_low_part (match_dup 0))
8226 (any_or:QI (match_dup 0) (match_dup 1)))]
8227 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8228 && ix86_match_ccmode (insn, CCNOmode)
8229 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8230 "<logic>{b}\t{%1, %0|%0, %1}"
8231 [(set_attr "type" "alu1")
8232 (set_attr "mode" "QI")])
8234 (define_insn "*<code><mode>_3"
8235 [(set (reg FLAGS_REG)
8236 (compare (any_or:SWI
8237 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8238 (match_operand:SWI 2 "<general_operand>" "<g>"))
8240 (clobber (match_scratch:SWI 0 "=<r>"))]
8241 "ix86_match_ccmode (insn, CCNOmode)
8242 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8243 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8244 [(set_attr "type" "alu")
8245 (set_attr "mode" "<MODE>")])
8247 (define_insn "*<code>qi_ext_0"
8248 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8253 (match_operand 1 "ext_register_operand" "0")
8256 (match_operand 2 "const_int_operand" "n")))
8257 (clobber (reg:CC FLAGS_REG))]
8258 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8259 "<logic>{b}\t{%2, %h0|%h0, %2}"
8260 [(set_attr "type" "alu")
8261 (set_attr "length_immediate" "1")
8262 (set_attr "modrm" "1")
8263 (set_attr "mode" "QI")])
8265 (define_insn "*<code>qi_ext_1_rex64"
8266 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8271 (match_operand 1 "ext_register_operand" "0")
8275 (match_operand 2 "ext_register_operand" "Q"))))
8276 (clobber (reg:CC FLAGS_REG))]
8278 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8279 "<logic>{b}\t{%2, %h0|%h0, %2}"
8280 [(set_attr "type" "alu")
8281 (set_attr "length_immediate" "0")
8282 (set_attr "mode" "QI")])
8284 (define_insn "*<code>qi_ext_1"
8285 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8290 (match_operand 1 "ext_register_operand" "0")
8294 (match_operand:QI 2 "general_operand" "Qm"))))
8295 (clobber (reg:CC FLAGS_REG))]
8297 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8298 "<logic>{b}\t{%2, %h0|%h0, %2}"
8299 [(set_attr "type" "alu")
8300 (set_attr "length_immediate" "0")
8301 (set_attr "mode" "QI")])
8303 (define_insn "*<code>qi_ext_2"
8304 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8308 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8311 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8314 (clobber (reg:CC FLAGS_REG))]
8315 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8316 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8317 [(set_attr "type" "alu")
8318 (set_attr "length_immediate" "0")
8319 (set_attr "mode" "QI")])
8322 [(set (match_operand 0 "register_operand")
8323 (any_or (match_operand 1 "register_operand")
8324 (match_operand 2 "const_int_operand")))
8325 (clobber (reg:CC FLAGS_REG))]
8327 && QI_REG_P (operands[0])
8328 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8329 && !(INTVAL (operands[2]) & ~(255 << 8))
8330 && GET_MODE (operands[0]) != QImode"
8331 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8332 (any_or:SI (zero_extract:SI (match_dup 1)
8333 (const_int 8) (const_int 8))
8335 (clobber (reg:CC FLAGS_REG))])]
8337 operands[0] = gen_lowpart (SImode, operands[0]);
8338 operands[1] = gen_lowpart (SImode, operands[1]);
8339 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8342 ;; Since OR can be encoded with sign extended immediate, this is only
8343 ;; profitable when 7th bit is set.
8345 [(set (match_operand 0 "register_operand")
8346 (any_or (match_operand 1 "general_operand")
8347 (match_operand 2 "const_int_operand")))
8348 (clobber (reg:CC FLAGS_REG))]
8350 && ANY_QI_REG_P (operands[0])
8351 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8352 && !(INTVAL (operands[2]) & ~255)
8353 && (INTVAL (operands[2]) & 128)
8354 && GET_MODE (operands[0]) != QImode"
8355 [(parallel [(set (strict_low_part (match_dup 0))
8356 (any_or:QI (match_dup 1)
8358 (clobber (reg:CC FLAGS_REG))])]
8360 operands[0] = gen_lowpart (QImode, operands[0]);
8361 operands[1] = gen_lowpart (QImode, operands[1]);
8362 operands[2] = gen_lowpart (QImode, operands[2]);
8365 (define_expand "xorqi_cc_ext_1"
8367 (set (reg:CCNO FLAGS_REG)
8371 (match_operand 1 "ext_register_operand")
8374 (match_operand:QI 2 "general_operand"))
8376 (set (zero_extract:SI (match_operand 0 "ext_register_operand")
8386 (define_insn "*xorqi_cc_ext_1_rex64"
8387 [(set (reg FLAGS_REG)
8391 (match_operand 1 "ext_register_operand" "0")
8394 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8396 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8405 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8406 "xor{b}\t{%2, %h0|%h0, %2}"
8407 [(set_attr "type" "alu")
8408 (set_attr "modrm" "1")
8409 (set_attr "mode" "QI")])
8411 (define_insn "*xorqi_cc_ext_1"
8412 [(set (reg FLAGS_REG)
8416 (match_operand 1 "ext_register_operand" "0")
8419 (match_operand:QI 2 "general_operand" "qmn"))
8421 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8430 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8431 "xor{b}\t{%2, %h0|%h0, %2}"
8432 [(set_attr "type" "alu")
8433 (set_attr "modrm" "1")
8434 (set_attr "mode" "QI")])
8436 ;; Negation instructions
8438 (define_expand "neg<mode>2"
8439 [(set (match_operand:SDWIM 0 "nonimmediate_operand")
8440 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand")))]
8442 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8444 (define_insn_and_split "*neg<dwi>2_doubleword"
8445 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8446 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8447 (clobber (reg:CC FLAGS_REG))]
8448 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8452 [(set (reg:CCZ FLAGS_REG)
8453 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8454 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8457 (plus:DWIH (match_dup 3)
8458 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8460 (clobber (reg:CC FLAGS_REG))])
8463 (neg:DWIH (match_dup 2)))
8464 (clobber (reg:CC FLAGS_REG))])]
8465 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8467 (define_insn "*neg<mode>2_1"
8468 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8469 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8470 (clobber (reg:CC FLAGS_REG))]
8471 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8472 "neg{<imodesuffix>}\t%0"
8473 [(set_attr "type" "negnot")
8474 (set_attr "mode" "<MODE>")])
8476 ;; Combine is quite creative about this pattern.
8477 (define_insn "*negsi2_1_zext"
8478 [(set (match_operand:DI 0 "register_operand" "=r")
8480 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8483 (clobber (reg:CC FLAGS_REG))]
8484 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8486 [(set_attr "type" "negnot")
8487 (set_attr "mode" "SI")])
8489 ;; The problem with neg is that it does not perform (compare x 0),
8490 ;; it really performs (compare 0 x), which leaves us with the zero
8491 ;; flag being the only useful item.
8493 (define_insn "*neg<mode>2_cmpz"
8494 [(set (reg:CCZ FLAGS_REG)
8496 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8498 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8499 (neg:SWI (match_dup 1)))]
8500 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8501 "neg{<imodesuffix>}\t%0"
8502 [(set_attr "type" "negnot")
8503 (set_attr "mode" "<MODE>")])
8505 (define_insn "*negsi2_cmpz_zext"
8506 [(set (reg:CCZ FLAGS_REG)
8510 (match_operand:DI 1 "register_operand" "0")
8514 (set (match_operand:DI 0 "register_operand" "=r")
8515 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8518 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8520 [(set_attr "type" "negnot")
8521 (set_attr "mode" "SI")])
8523 ;; Changing of sign for FP values is doable using integer unit too.
8525 (define_expand "<code><mode>2"
8526 [(set (match_operand:X87MODEF 0 "register_operand")
8527 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand")))]
8528 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8529 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8531 (define_insn "*absneg<mode>2_mixed"
8532 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8533 (match_operator:MODEF 3 "absneg_operator"
8534 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8535 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8536 (clobber (reg:CC FLAGS_REG))]
8537 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8540 (define_insn "*absneg<mode>2_sse"
8541 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8542 (match_operator:MODEF 3 "absneg_operator"
8543 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8544 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8545 (clobber (reg:CC FLAGS_REG))]
8546 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8549 (define_insn "*absneg<mode>2_i387"
8550 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8551 (match_operator:X87MODEF 3 "absneg_operator"
8552 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8553 (use (match_operand 2))
8554 (clobber (reg:CC FLAGS_REG))]
8555 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8558 (define_expand "<code>tf2"
8559 [(set (match_operand:TF 0 "register_operand")
8560 (absneg:TF (match_operand:TF 1 "register_operand")))]
8562 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8564 (define_insn "*absnegtf2_sse"
8565 [(set (match_operand:TF 0 "register_operand" "=x,x")
8566 (match_operator:TF 3 "absneg_operator"
8567 [(match_operand:TF 1 "register_operand" "0,x")]))
8568 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8569 (clobber (reg:CC FLAGS_REG))]
8573 ;; Splitters for fp abs and neg.
8576 [(set (match_operand 0 "fp_register_operand")
8577 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8578 (use (match_operand 2))
8579 (clobber (reg:CC FLAGS_REG))]
8581 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8584 [(set (match_operand 0 "register_operand")
8585 (match_operator 3 "absneg_operator"
8586 [(match_operand 1 "register_operand")]))
8587 (use (match_operand 2 "nonimmediate_operand"))
8588 (clobber (reg:CC FLAGS_REG))]
8589 "reload_completed && SSE_REG_P (operands[0])"
8590 [(set (match_dup 0) (match_dup 3))]
8592 enum machine_mode mode = GET_MODE (operands[0]);
8593 enum machine_mode vmode = GET_MODE (operands[2]);
8596 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8597 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8598 if (operands_match_p (operands[0], operands[2]))
8601 operands[1] = operands[2];
8604 if (GET_CODE (operands[3]) == ABS)
8605 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8607 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8612 [(set (match_operand:SF 0 "register_operand")
8613 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8614 (use (match_operand:V4SF 2))
8615 (clobber (reg:CC FLAGS_REG))]
8617 [(parallel [(set (match_dup 0) (match_dup 1))
8618 (clobber (reg:CC FLAGS_REG))])]
8621 operands[0] = gen_lowpart (SImode, operands[0]);
8622 if (GET_CODE (operands[1]) == ABS)
8624 tmp = gen_int_mode (0x7fffffff, SImode);
8625 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8629 tmp = gen_int_mode (0x80000000, SImode);
8630 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8636 [(set (match_operand:DF 0 "register_operand")
8637 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8638 (use (match_operand 2))
8639 (clobber (reg:CC FLAGS_REG))]
8641 [(parallel [(set (match_dup 0) (match_dup 1))
8642 (clobber (reg:CC FLAGS_REG))])]
8647 tmp = gen_lowpart (DImode, operands[0]);
8648 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8651 if (GET_CODE (operands[1]) == ABS)
8654 tmp = gen_rtx_NOT (DImode, tmp);
8658 operands[0] = gen_highpart (SImode, operands[0]);
8659 if (GET_CODE (operands[1]) == ABS)
8661 tmp = gen_int_mode (0x7fffffff, SImode);
8662 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8666 tmp = gen_int_mode (0x80000000, SImode);
8667 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8674 [(set (match_operand:XF 0 "register_operand")
8675 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8676 (use (match_operand 2))
8677 (clobber (reg:CC FLAGS_REG))]
8679 [(parallel [(set (match_dup 0) (match_dup 1))
8680 (clobber (reg:CC FLAGS_REG))])]
8683 operands[0] = gen_rtx_REG (SImode,
8684 true_regnum (operands[0])
8685 + (TARGET_64BIT ? 1 : 2));
8686 if (GET_CODE (operands[1]) == ABS)
8688 tmp = GEN_INT (0x7fff);
8689 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8693 tmp = GEN_INT (0x8000);
8694 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8699 ;; Conditionalize these after reload. If they match before reload, we
8700 ;; lose the clobber and ability to use integer instructions.
8702 (define_insn "*<code><mode>2_1"
8703 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8704 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8706 && (reload_completed
8707 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8708 "f<absneg_mnemonic>"
8709 [(set_attr "type" "fsgn")
8710 (set_attr "mode" "<MODE>")])
8712 (define_insn "*<code>extendsfdf2"
8713 [(set (match_operand:DF 0 "register_operand" "=f")
8714 (absneg:DF (float_extend:DF
8715 (match_operand:SF 1 "register_operand" "0"))))]
8716 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8717 "f<absneg_mnemonic>"
8718 [(set_attr "type" "fsgn")
8719 (set_attr "mode" "DF")])
8721 (define_insn "*<code>extendsfxf2"
8722 [(set (match_operand:XF 0 "register_operand" "=f")
8723 (absneg:XF (float_extend:XF
8724 (match_operand:SF 1 "register_operand" "0"))))]
8726 "f<absneg_mnemonic>"
8727 [(set_attr "type" "fsgn")
8728 (set_attr "mode" "XF")])
8730 (define_insn "*<code>extenddfxf2"
8731 [(set (match_operand:XF 0 "register_operand" "=f")
8732 (absneg:XF (float_extend:XF
8733 (match_operand:DF 1 "register_operand" "0"))))]
8735 "f<absneg_mnemonic>"
8736 [(set_attr "type" "fsgn")
8737 (set_attr "mode" "XF")])
8739 ;; Copysign instructions
8741 (define_mode_iterator CSGNMODE [SF DF TF])
8742 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8744 (define_expand "copysign<mode>3"
8745 [(match_operand:CSGNMODE 0 "register_operand")
8746 (match_operand:CSGNMODE 1 "nonmemory_operand")
8747 (match_operand:CSGNMODE 2 "register_operand")]
8748 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8749 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8750 "ix86_expand_copysign (operands); DONE;")
8752 (define_insn_and_split "copysign<mode>3_const"
8753 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8755 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8756 (match_operand:CSGNMODE 2 "register_operand" "0")
8757 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8759 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8760 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8762 "&& reload_completed"
8764 "ix86_split_copysign_const (operands); DONE;")
8766 (define_insn "copysign<mode>3_var"
8767 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8769 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8770 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8771 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8772 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8774 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8775 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8776 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8780 [(set (match_operand:CSGNMODE 0 "register_operand")
8782 [(match_operand:CSGNMODE 2 "register_operand")
8783 (match_operand:CSGNMODE 3 "register_operand")
8784 (match_operand:<CSGNVMODE> 4)
8785 (match_operand:<CSGNVMODE> 5)]
8787 (clobber (match_scratch:<CSGNVMODE> 1))]
8788 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8789 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8790 && reload_completed"
8792 "ix86_split_copysign_var (operands); DONE;")
8794 ;; One complement instructions
8796 (define_expand "one_cmpl<mode>2"
8797 [(set (match_operand:SWIM 0 "nonimmediate_operand")
8798 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand")))]
8800 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8802 (define_insn "*one_cmpl<mode>2_1"
8803 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8804 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8805 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8806 "not{<imodesuffix>}\t%0"
8807 [(set_attr "type" "negnot")
8808 (set_attr "mode" "<MODE>")])
8810 ;; %%% Potential partial reg stall on alternative 1. What to do?
8811 (define_insn "*one_cmplqi2_1"
8812 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8813 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8814 "ix86_unary_operator_ok (NOT, QImode, operands)"
8818 [(set_attr "type" "negnot")
8819 (set_attr "mode" "QI,SI")])
8821 ;; ??? Currently never generated - xor is used instead.
8822 (define_insn "*one_cmplsi2_1_zext"
8823 [(set (match_operand:DI 0 "register_operand" "=r")
8825 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8826 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8828 [(set_attr "type" "negnot")
8829 (set_attr "mode" "SI")])
8831 (define_insn "*one_cmpl<mode>2_2"
8832 [(set (reg FLAGS_REG)
8833 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8835 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8836 (not:SWI (match_dup 1)))]
8837 "ix86_match_ccmode (insn, CCNOmode)
8838 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8840 [(set_attr "type" "alu1")
8841 (set_attr "mode" "<MODE>")])
8844 [(set (match_operand 0 "flags_reg_operand")
8845 (match_operator 2 "compare_operator"
8846 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand"))
8848 (set (match_operand:SWI 1 "nonimmediate_operand")
8849 (not:SWI (match_dup 3)))]
8850 "ix86_match_ccmode (insn, CCNOmode)"
8851 [(parallel [(set (match_dup 0)
8852 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8855 (xor:SWI (match_dup 3) (const_int -1)))])])
8857 ;; ??? Currently never generated - xor is used instead.
8858 (define_insn "*one_cmplsi2_2_zext"
8859 [(set (reg FLAGS_REG)
8860 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8862 (set (match_operand:DI 0 "register_operand" "=r")
8863 (zero_extend:DI (not:SI (match_dup 1))))]
8864 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8865 && ix86_unary_operator_ok (NOT, SImode, operands)"
8867 [(set_attr "type" "alu1")
8868 (set_attr "mode" "SI")])
8871 [(set (match_operand 0 "flags_reg_operand")
8872 (match_operator 2 "compare_operator"
8873 [(not:SI (match_operand:SI 3 "register_operand"))
8875 (set (match_operand:DI 1 "register_operand")
8876 (zero_extend:DI (not:SI (match_dup 3))))]
8877 "ix86_match_ccmode (insn, CCNOmode)"
8878 [(parallel [(set (match_dup 0)
8879 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8882 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8884 ;; Shift instructions
8886 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8887 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8888 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8889 ;; from the assembler input.
8891 ;; This instruction shifts the target reg/mem as usual, but instead of
8892 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8893 ;; is a left shift double, bits are taken from the high order bits of
8894 ;; reg, else if the insn is a shift right double, bits are taken from the
8895 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8896 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8898 ;; Since sh[lr]d does not change the `reg' operand, that is done
8899 ;; separately, making all shifts emit pairs of shift double and normal
8900 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8901 ;; support a 63 bit shift, each shift where the count is in a reg expands
8902 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8904 ;; If the shift count is a constant, we need never emit more than one
8905 ;; shift pair, instead using moves and sign extension for counts greater
8908 (define_expand "ashl<mode>3"
8909 [(set (match_operand:SDWIM 0 "<shift_operand>")
8910 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>")
8911 (match_operand:QI 2 "nonmemory_operand")))]
8913 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8915 (define_insn "*ashl<mode>3_doubleword"
8916 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8917 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8918 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8919 (clobber (reg:CC FLAGS_REG))]
8922 [(set_attr "type" "multi")])
8925 [(set (match_operand:DWI 0 "register_operand")
8926 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand")
8927 (match_operand:QI 2 "nonmemory_operand")))
8928 (clobber (reg:CC FLAGS_REG))]
8929 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8931 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8933 ;; By default we don't ask for a scratch register, because when DWImode
8934 ;; values are manipulated, registers are already at a premium. But if
8935 ;; we have one handy, we won't turn it away.
8938 [(match_scratch:DWIH 3 "r")
8939 (parallel [(set (match_operand:<DWI> 0 "register_operand")
8941 (match_operand:<DWI> 1 "nonmemory_operand")
8942 (match_operand:QI 2 "nonmemory_operand")))
8943 (clobber (reg:CC FLAGS_REG))])
8947 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8949 (define_insn "x86_64_shld"
8950 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8951 (ior:DI (ashift:DI (match_dup 0)
8952 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8953 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8954 (minus:QI (const_int 64) (match_dup 2)))))
8955 (clobber (reg:CC FLAGS_REG))]
8957 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8958 [(set_attr "type" "ishift")
8959 (set_attr "prefix_0f" "1")
8960 (set_attr "mode" "DI")
8961 (set_attr "athlon_decode" "vector")
8962 (set_attr "amdfam10_decode" "vector")
8963 (set_attr "bdver1_decode" "vector")])
8965 (define_insn "x86_shld"
8966 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8967 (ior:SI (ashift:SI (match_dup 0)
8968 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8969 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8970 (minus:QI (const_int 32) (match_dup 2)))))
8971 (clobber (reg:CC FLAGS_REG))]
8973 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8974 [(set_attr "type" "ishift")
8975 (set_attr "prefix_0f" "1")
8976 (set_attr "mode" "SI")
8977 (set_attr "pent_pair" "np")
8978 (set_attr "athlon_decode" "vector")
8979 (set_attr "amdfam10_decode" "vector")
8980 (set_attr "bdver1_decode" "vector")])
8982 (define_expand "x86_shift<mode>_adj_1"
8983 [(set (reg:CCZ FLAGS_REG)
8984 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand")
8987 (set (match_operand:SWI48 0 "register_operand")
8988 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8989 (match_operand:SWI48 1 "register_operand")
8992 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8993 (match_operand:SWI48 3 "register_operand")
8996 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8998 (define_expand "x86_shift<mode>_adj_2"
8999 [(use (match_operand:SWI48 0 "register_operand"))
9000 (use (match_operand:SWI48 1 "register_operand"))
9001 (use (match_operand:QI 2 "register_operand"))]
9004 rtx label = gen_label_rtx ();
9007 emit_insn (gen_testqi_ccz_1 (operands[2],
9008 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9010 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9011 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9012 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9013 gen_rtx_LABEL_REF (VOIDmode, label),
9015 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9016 JUMP_LABEL (tmp) = label;
9018 emit_move_insn (operands[0], operands[1]);
9019 ix86_expand_clear (operands[1]);
9022 LABEL_NUSES (label) = 1;
9027 ;; Avoid useless masking of count operand.
9028 (define_insn_and_split "*ashl<mode>3_mask"
9029 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9031 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9034 (match_operand:SI 2 "nonimmediate_operand" "c")
9035 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9036 (clobber (reg:CC FLAGS_REG))]
9037 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9038 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9039 == GET_MODE_BITSIZE (<MODE>mode)-1"
9042 [(parallel [(set (match_dup 0)
9043 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9044 (clobber (reg:CC FLAGS_REG))])]
9046 if (can_create_pseudo_p ())
9047 operands [2] = force_reg (SImode, operands[2]);
9049 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9051 [(set_attr "type" "ishift")
9052 (set_attr "mode" "<MODE>")])
9054 (define_insn "*bmi2_ashl<mode>3_1"
9055 [(set (match_operand:SWI48 0 "register_operand" "=r")
9056 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9057 (match_operand:SWI48 2 "register_operand" "r")))]
9059 "shlx\t{%2, %1, %0|%0, %1, %2}"
9060 [(set_attr "type" "ishiftx")
9061 (set_attr "mode" "<MODE>")])
9063 (define_insn "*ashl<mode>3_1"
9064 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9065 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9066 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9067 (clobber (reg:CC FLAGS_REG))]
9068 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9070 switch (get_attr_type (insn))
9077 gcc_assert (operands[2] == const1_rtx);
9078 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9079 return "add{<imodesuffix>}\t%0, %0";
9082 if (operands[2] == const1_rtx
9083 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9084 return "sal{<imodesuffix>}\t%0";
9086 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9089 [(set_attr "isa" "*,*,bmi2")
9091 (cond [(eq_attr "alternative" "1")
9092 (const_string "lea")
9093 (eq_attr "alternative" "2")
9094 (const_string "ishiftx")
9095 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9096 (match_operand 0 "register_operand"))
9097 (match_operand 2 "const1_operand"))
9098 (const_string "alu")
9100 (const_string "ishift")))
9101 (set (attr "length_immediate")
9103 (ior (eq_attr "type" "alu")
9104 (and (eq_attr "type" "ishift")
9105 (and (match_operand 2 "const1_operand")
9106 (ior (match_test "TARGET_SHIFT1")
9107 (match_test "optimize_function_for_size_p (cfun)")))))
9109 (const_string "*")))
9110 (set_attr "mode" "<MODE>")])
9112 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9114 [(set (match_operand:SWI48 0 "register_operand")
9115 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9116 (match_operand:QI 2 "register_operand")))
9117 (clobber (reg:CC FLAGS_REG))]
9118 "TARGET_BMI2 && reload_completed"
9120 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9121 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9123 (define_insn "*bmi2_ashlsi3_1_zext"
9124 [(set (match_operand:DI 0 "register_operand" "=r")
9126 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9127 (match_operand:SI 2 "register_operand" "r"))))]
9128 "TARGET_64BIT && TARGET_BMI2"
9129 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9130 [(set_attr "type" "ishiftx")
9131 (set_attr "mode" "SI")])
9133 (define_insn "*ashlsi3_1_zext"
9134 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9136 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9137 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9138 (clobber (reg:CC FLAGS_REG))]
9139 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9141 switch (get_attr_type (insn))
9148 gcc_assert (operands[2] == const1_rtx);
9149 return "add{l}\t%k0, %k0";
9152 if (operands[2] == const1_rtx
9153 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9154 return "sal{l}\t%k0";
9156 return "sal{l}\t{%2, %k0|%k0, %2}";
9159 [(set_attr "isa" "*,*,bmi2")
9161 (cond [(eq_attr "alternative" "1")
9162 (const_string "lea")
9163 (eq_attr "alternative" "2")
9164 (const_string "ishiftx")
9165 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9166 (match_operand 2 "const1_operand"))
9167 (const_string "alu")
9169 (const_string "ishift")))
9170 (set (attr "length_immediate")
9172 (ior (eq_attr "type" "alu")
9173 (and (eq_attr "type" "ishift")
9174 (and (match_operand 2 "const1_operand")
9175 (ior (match_test "TARGET_SHIFT1")
9176 (match_test "optimize_function_for_size_p (cfun)")))))
9178 (const_string "*")))
9179 (set_attr "mode" "SI")])
9181 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9183 [(set (match_operand:DI 0 "register_operand")
9185 (ashift:SI (match_operand:SI 1 "nonimmediate_operand")
9186 (match_operand:QI 2 "register_operand"))))
9187 (clobber (reg:CC FLAGS_REG))]
9188 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9190 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9191 "operands[2] = gen_lowpart (SImode, operands[2]);")
9193 (define_insn "*ashlhi3_1"
9194 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9195 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9196 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9197 (clobber (reg:CC FLAGS_REG))]
9198 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9200 switch (get_attr_type (insn))
9206 gcc_assert (operands[2] == const1_rtx);
9207 return "add{w}\t%0, %0";
9210 if (operands[2] == const1_rtx
9211 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9212 return "sal{w}\t%0";
9214 return "sal{w}\t{%2, %0|%0, %2}";
9218 (cond [(eq_attr "alternative" "1")
9219 (const_string "lea")
9220 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9221 (match_operand 0 "register_operand"))
9222 (match_operand 2 "const1_operand"))
9223 (const_string "alu")
9225 (const_string "ishift")))
9226 (set (attr "length_immediate")
9228 (ior (eq_attr "type" "alu")
9229 (and (eq_attr "type" "ishift")
9230 (and (match_operand 2 "const1_operand")
9231 (ior (match_test "TARGET_SHIFT1")
9232 (match_test "optimize_function_for_size_p (cfun)")))))
9234 (const_string "*")))
9235 (set_attr "mode" "HI,SI")])
9237 ;; %%% Potential partial reg stall on alternative 1. What to do?
9238 (define_insn "*ashlqi3_1"
9239 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9240 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9241 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9242 (clobber (reg:CC FLAGS_REG))]
9243 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9245 switch (get_attr_type (insn))
9251 gcc_assert (operands[2] == const1_rtx);
9252 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9253 return "add{l}\t%k0, %k0";
9255 return "add{b}\t%0, %0";
9258 if (operands[2] == const1_rtx
9259 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9261 if (get_attr_mode (insn) == MODE_SI)
9262 return "sal{l}\t%k0";
9264 return "sal{b}\t%0";
9268 if (get_attr_mode (insn) == MODE_SI)
9269 return "sal{l}\t{%2, %k0|%k0, %2}";
9271 return "sal{b}\t{%2, %0|%0, %2}";
9276 (cond [(eq_attr "alternative" "2")
9277 (const_string "lea")
9278 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9279 (match_operand 0 "register_operand"))
9280 (match_operand 2 "const1_operand"))
9281 (const_string "alu")
9283 (const_string "ishift")))
9284 (set (attr "length_immediate")
9286 (ior (eq_attr "type" "alu")
9287 (and (eq_attr "type" "ishift")
9288 (and (match_operand 2 "const1_operand")
9289 (ior (match_test "TARGET_SHIFT1")
9290 (match_test "optimize_function_for_size_p (cfun)")))))
9292 (const_string "*")))
9293 (set_attr "mode" "QI,SI,SI")])
9295 (define_insn "*ashlqi3_1_slp"
9296 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9297 (ashift:QI (match_dup 0)
9298 (match_operand:QI 1 "nonmemory_operand" "cI")))
9299 (clobber (reg:CC FLAGS_REG))]
9300 "(optimize_function_for_size_p (cfun)
9301 || !TARGET_PARTIAL_FLAG_REG_STALL
9302 || (operands[1] == const1_rtx
9304 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9306 switch (get_attr_type (insn))
9309 gcc_assert (operands[1] == const1_rtx);
9310 return "add{b}\t%0, %0";
9313 if (operands[1] == const1_rtx
9314 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9315 return "sal{b}\t%0";
9317 return "sal{b}\t{%1, %0|%0, %1}";
9321 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9322 (match_operand 0 "register_operand"))
9323 (match_operand 1 "const1_operand"))
9324 (const_string "alu")
9326 (const_string "ishift1")))
9327 (set (attr "length_immediate")
9329 (ior (eq_attr "type" "alu")
9330 (and (eq_attr "type" "ishift1")
9331 (and (match_operand 1 "const1_operand")
9332 (ior (match_test "TARGET_SHIFT1")
9333 (match_test "optimize_function_for_size_p (cfun)")))))
9335 (const_string "*")))
9336 (set_attr "mode" "QI")])
9338 ;; Convert ashift to the lea pattern to avoid flags dependency.
9340 [(set (match_operand 0 "register_operand")
9341 (ashift (match_operand 1 "index_register_operand")
9342 (match_operand:QI 2 "const_int_operand")))
9343 (clobber (reg:CC FLAGS_REG))]
9344 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9346 && true_regnum (operands[0]) != true_regnum (operands[1])"
9349 enum machine_mode mode = GET_MODE (operands[0]);
9352 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9355 operands[0] = gen_lowpart (mode, operands[0]);
9356 operands[1] = gen_lowpart (mode, operands[1]);
9359 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9361 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9363 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9367 ;; Convert ashift to the lea pattern to avoid flags dependency.
9369 [(set (match_operand:DI 0 "register_operand")
9371 (ashift:SI (match_operand:SI 1 "index_register_operand")
9372 (match_operand:QI 2 "const_int_operand"))))
9373 (clobber (reg:CC FLAGS_REG))]
9374 "TARGET_64BIT && reload_completed
9375 && true_regnum (operands[0]) != true_regnum (operands[1])"
9377 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9379 operands[1] = gen_lowpart (DImode, operands[1]);
9380 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9383 ;; This pattern can't accept a variable shift count, since shifts by
9384 ;; zero don't affect the flags. We assume that shifts by constant
9385 ;; zero are optimized away.
9386 (define_insn "*ashl<mode>3_cmp"
9387 [(set (reg FLAGS_REG)
9389 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9390 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9392 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9393 (ashift:SWI (match_dup 1) (match_dup 2)))]
9394 "(optimize_function_for_size_p (cfun)
9395 || !TARGET_PARTIAL_FLAG_REG_STALL
9396 || (operands[2] == const1_rtx
9398 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9399 && ix86_match_ccmode (insn, CCGOCmode)
9400 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9402 switch (get_attr_type (insn))
9405 gcc_assert (operands[2] == const1_rtx);
9406 return "add{<imodesuffix>}\t%0, %0";
9409 if (operands[2] == const1_rtx
9410 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9411 return "sal{<imodesuffix>}\t%0";
9413 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9417 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9418 (match_operand 0 "register_operand"))
9419 (match_operand 2 "const1_operand"))
9420 (const_string "alu")
9422 (const_string "ishift")))
9423 (set (attr "length_immediate")
9425 (ior (eq_attr "type" "alu")
9426 (and (eq_attr "type" "ishift")
9427 (and (match_operand 2 "const1_operand")
9428 (ior (match_test "TARGET_SHIFT1")
9429 (match_test "optimize_function_for_size_p (cfun)")))))
9431 (const_string "*")))
9432 (set_attr "mode" "<MODE>")])
9434 (define_insn "*ashlsi3_cmp_zext"
9435 [(set (reg FLAGS_REG)
9437 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9438 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9440 (set (match_operand:DI 0 "register_operand" "=r")
9441 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9443 && (optimize_function_for_size_p (cfun)
9444 || !TARGET_PARTIAL_FLAG_REG_STALL
9445 || (operands[2] == const1_rtx
9447 || TARGET_DOUBLE_WITH_ADD)))
9448 && ix86_match_ccmode (insn, CCGOCmode)
9449 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9451 switch (get_attr_type (insn))
9454 gcc_assert (operands[2] == const1_rtx);
9455 return "add{l}\t%k0, %k0";
9458 if (operands[2] == const1_rtx
9459 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9460 return "sal{l}\t%k0";
9462 return "sal{l}\t{%2, %k0|%k0, %2}";
9466 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9467 (match_operand 2 "const1_operand"))
9468 (const_string "alu")
9470 (const_string "ishift")))
9471 (set (attr "length_immediate")
9473 (ior (eq_attr "type" "alu")
9474 (and (eq_attr "type" "ishift")
9475 (and (match_operand 2 "const1_operand")
9476 (ior (match_test "TARGET_SHIFT1")
9477 (match_test "optimize_function_for_size_p (cfun)")))))
9479 (const_string "*")))
9480 (set_attr "mode" "SI")])
9482 (define_insn "*ashl<mode>3_cconly"
9483 [(set (reg FLAGS_REG)
9485 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9486 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9488 (clobber (match_scratch:SWI 0 "=<r>"))]
9489 "(optimize_function_for_size_p (cfun)
9490 || !TARGET_PARTIAL_FLAG_REG_STALL
9491 || (operands[2] == const1_rtx
9493 || TARGET_DOUBLE_WITH_ADD)))
9494 && ix86_match_ccmode (insn, CCGOCmode)"
9496 switch (get_attr_type (insn))
9499 gcc_assert (operands[2] == const1_rtx);
9500 return "add{<imodesuffix>}\t%0, %0";
9503 if (operands[2] == const1_rtx
9504 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9505 return "sal{<imodesuffix>}\t%0";
9507 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9511 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9512 (match_operand 0 "register_operand"))
9513 (match_operand 2 "const1_operand"))
9514 (const_string "alu")
9516 (const_string "ishift")))
9517 (set (attr "length_immediate")
9519 (ior (eq_attr "type" "alu")
9520 (and (eq_attr "type" "ishift")
9521 (and (match_operand 2 "const1_operand")
9522 (ior (match_test "TARGET_SHIFT1")
9523 (match_test "optimize_function_for_size_p (cfun)")))))
9525 (const_string "*")))
9526 (set_attr "mode" "<MODE>")])
9528 ;; See comment above `ashl<mode>3' about how this works.
9530 (define_expand "<shift_insn><mode>3"
9531 [(set (match_operand:SDWIM 0 "<shift_operand>")
9532 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>")
9533 (match_operand:QI 2 "nonmemory_operand")))]
9535 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9537 ;; Avoid useless masking of count operand.
9538 (define_insn_and_split "*<shift_insn><mode>3_mask"
9539 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9541 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9544 (match_operand:SI 2 "nonimmediate_operand" "c")
9545 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9546 (clobber (reg:CC FLAGS_REG))]
9547 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9548 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9549 == GET_MODE_BITSIZE (<MODE>mode)-1"
9552 [(parallel [(set (match_dup 0)
9553 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9554 (clobber (reg:CC FLAGS_REG))])]
9556 if (can_create_pseudo_p ())
9557 operands [2] = force_reg (SImode, operands[2]);
9559 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9561 [(set_attr "type" "ishift")
9562 (set_attr "mode" "<MODE>")])
9564 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9565 [(set (match_operand:DWI 0 "register_operand" "=r")
9566 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9567 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9568 (clobber (reg:CC FLAGS_REG))]
9571 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9573 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9574 [(set_attr "type" "multi")])
9576 ;; By default we don't ask for a scratch register, because when DWImode
9577 ;; values are manipulated, registers are already at a premium. But if
9578 ;; we have one handy, we won't turn it away.
9581 [(match_scratch:DWIH 3 "r")
9582 (parallel [(set (match_operand:<DWI> 0 "register_operand")
9584 (match_operand:<DWI> 1 "register_operand")
9585 (match_operand:QI 2 "nonmemory_operand")))
9586 (clobber (reg:CC FLAGS_REG))])
9590 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9592 (define_insn "x86_64_shrd"
9593 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9594 (ior:DI (ashiftrt:DI (match_dup 0)
9595 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9596 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9597 (minus:QI (const_int 64) (match_dup 2)))))
9598 (clobber (reg:CC FLAGS_REG))]
9600 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9601 [(set_attr "type" "ishift")
9602 (set_attr "prefix_0f" "1")
9603 (set_attr "mode" "DI")
9604 (set_attr "athlon_decode" "vector")
9605 (set_attr "amdfam10_decode" "vector")
9606 (set_attr "bdver1_decode" "vector")])
9608 (define_insn "x86_shrd"
9609 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9610 (ior:SI (ashiftrt:SI (match_dup 0)
9611 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9612 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9613 (minus:QI (const_int 32) (match_dup 2)))))
9614 (clobber (reg:CC FLAGS_REG))]
9616 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9617 [(set_attr "type" "ishift")
9618 (set_attr "prefix_0f" "1")
9619 (set_attr "mode" "SI")
9620 (set_attr "pent_pair" "np")
9621 (set_attr "athlon_decode" "vector")
9622 (set_attr "amdfam10_decode" "vector")
9623 (set_attr "bdver1_decode" "vector")])
9625 (define_insn "ashrdi3_cvt"
9626 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9627 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9628 (match_operand:QI 2 "const_int_operand")))
9629 (clobber (reg:CC FLAGS_REG))]
9630 "TARGET_64BIT && INTVAL (operands[2]) == 63
9631 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9632 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9635 sar{q}\t{%2, %0|%0, %2}"
9636 [(set_attr "type" "imovx,ishift")
9637 (set_attr "prefix_0f" "0,*")
9638 (set_attr "length_immediate" "0,*")
9639 (set_attr "modrm" "0,1")
9640 (set_attr "mode" "DI")])
9642 (define_insn "ashrsi3_cvt"
9643 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9644 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9645 (match_operand:QI 2 "const_int_operand")))
9646 (clobber (reg:CC FLAGS_REG))]
9647 "INTVAL (operands[2]) == 31
9648 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9649 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9652 sar{l}\t{%2, %0|%0, %2}"
9653 [(set_attr "type" "imovx,ishift")
9654 (set_attr "prefix_0f" "0,*")
9655 (set_attr "length_immediate" "0,*")
9656 (set_attr "modrm" "0,1")
9657 (set_attr "mode" "SI")])
9659 (define_insn "*ashrsi3_cvt_zext"
9660 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9662 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9663 (match_operand:QI 2 "const_int_operand"))))
9664 (clobber (reg:CC FLAGS_REG))]
9665 "TARGET_64BIT && INTVAL (operands[2]) == 31
9666 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9667 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9670 sar{l}\t{%2, %k0|%k0, %2}"
9671 [(set_attr "type" "imovx,ishift")
9672 (set_attr "prefix_0f" "0,*")
9673 (set_attr "length_immediate" "0,*")
9674 (set_attr "modrm" "0,1")
9675 (set_attr "mode" "SI")])
9677 (define_expand "x86_shift<mode>_adj_3"
9678 [(use (match_operand:SWI48 0 "register_operand"))
9679 (use (match_operand:SWI48 1 "register_operand"))
9680 (use (match_operand:QI 2 "register_operand"))]
9683 rtx label = gen_label_rtx ();
9686 emit_insn (gen_testqi_ccz_1 (operands[2],
9687 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9689 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9690 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9691 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9692 gen_rtx_LABEL_REF (VOIDmode, label),
9694 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9695 JUMP_LABEL (tmp) = label;
9697 emit_move_insn (operands[0], operands[1]);
9698 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9699 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9701 LABEL_NUSES (label) = 1;
9706 (define_insn "*bmi2_<shift_insn><mode>3_1"
9707 [(set (match_operand:SWI48 0 "register_operand" "=r")
9708 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9709 (match_operand:SWI48 2 "register_operand" "r")))]
9711 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9712 [(set_attr "type" "ishiftx")
9713 (set_attr "mode" "<MODE>")])
9715 (define_insn "*<shift_insn><mode>3_1"
9716 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9718 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9719 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9720 (clobber (reg:CC FLAGS_REG))]
9721 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9723 switch (get_attr_type (insn))
9729 if (operands[2] == const1_rtx
9730 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9731 return "<shift>{<imodesuffix>}\t%0";
9733 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9736 [(set_attr "isa" "*,bmi2")
9737 (set_attr "type" "ishift,ishiftx")
9738 (set (attr "length_immediate")
9740 (and (match_operand 2 "const1_operand")
9741 (ior (match_test "TARGET_SHIFT1")
9742 (match_test "optimize_function_for_size_p (cfun)")))
9744 (const_string "*")))
9745 (set_attr "mode" "<MODE>")])
9747 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9749 [(set (match_operand:SWI48 0 "register_operand")
9750 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
9751 (match_operand:QI 2 "register_operand")))
9752 (clobber (reg:CC FLAGS_REG))]
9753 "TARGET_BMI2 && reload_completed"
9755 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9756 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9758 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9759 [(set (match_operand:DI 0 "register_operand" "=r")
9761 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9762 (match_operand:SI 2 "register_operand" "r"))))]
9763 "TARGET_64BIT && TARGET_BMI2"
9764 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9765 [(set_attr "type" "ishiftx")
9766 (set_attr "mode" "SI")])
9768 (define_insn "*<shift_insn>si3_1_zext"
9769 [(set (match_operand:DI 0 "register_operand" "=r,r")
9771 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9772 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9773 (clobber (reg:CC FLAGS_REG))]
9774 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9776 switch (get_attr_type (insn))
9782 if (operands[2] == const1_rtx
9783 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9784 return "<shift>{l}\t%k0";
9786 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9789 [(set_attr "isa" "*,bmi2")
9790 (set_attr "type" "ishift,ishiftx")
9791 (set (attr "length_immediate")
9793 (and (match_operand 2 "const1_operand")
9794 (ior (match_test "TARGET_SHIFT1")
9795 (match_test "optimize_function_for_size_p (cfun)")))
9797 (const_string "*")))
9798 (set_attr "mode" "SI")])
9800 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9802 [(set (match_operand:DI 0 "register_operand")
9804 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand")
9805 (match_operand:QI 2 "register_operand"))))
9806 (clobber (reg:CC FLAGS_REG))]
9807 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9809 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9810 "operands[2] = gen_lowpart (SImode, operands[2]);")
9812 (define_insn "*<shift_insn><mode>3_1"
9813 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9815 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9816 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9817 (clobber (reg:CC FLAGS_REG))]
9818 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9820 if (operands[2] == const1_rtx
9821 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9822 return "<shift>{<imodesuffix>}\t%0";
9824 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9826 [(set_attr "type" "ishift")
9827 (set (attr "length_immediate")
9829 (and (match_operand 2 "const1_operand")
9830 (ior (match_test "TARGET_SHIFT1")
9831 (match_test "optimize_function_for_size_p (cfun)")))
9833 (const_string "*")))
9834 (set_attr "mode" "<MODE>")])
9836 (define_insn "*<shift_insn>qi3_1_slp"
9837 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9838 (any_shiftrt:QI (match_dup 0)
9839 (match_operand:QI 1 "nonmemory_operand" "cI")))
9840 (clobber (reg:CC FLAGS_REG))]
9841 "(optimize_function_for_size_p (cfun)
9842 || !TARGET_PARTIAL_REG_STALL
9843 || (operands[1] == const1_rtx
9846 if (operands[1] == const1_rtx
9847 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9848 return "<shift>{b}\t%0";
9850 return "<shift>{b}\t{%1, %0|%0, %1}";
9852 [(set_attr "type" "ishift1")
9853 (set (attr "length_immediate")
9855 (and (match_operand 1 "const1_operand")
9856 (ior (match_test "TARGET_SHIFT1")
9857 (match_test "optimize_function_for_size_p (cfun)")))
9859 (const_string "*")))
9860 (set_attr "mode" "QI")])
9862 ;; This pattern can't accept a variable shift count, since shifts by
9863 ;; zero don't affect the flags. We assume that shifts by constant
9864 ;; zero are optimized away.
9865 (define_insn "*<shift_insn><mode>3_cmp"
9866 [(set (reg FLAGS_REG)
9869 (match_operand:SWI 1 "nonimmediate_operand" "0")
9870 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9872 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9873 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9874 "(optimize_function_for_size_p (cfun)
9875 || !TARGET_PARTIAL_FLAG_REG_STALL
9876 || (operands[2] == const1_rtx
9878 && ix86_match_ccmode (insn, CCGOCmode)
9879 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9881 if (operands[2] == const1_rtx
9882 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9883 return "<shift>{<imodesuffix>}\t%0";
9885 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9887 [(set_attr "type" "ishift")
9888 (set (attr "length_immediate")
9890 (and (match_operand 2 "const1_operand")
9891 (ior (match_test "TARGET_SHIFT1")
9892 (match_test "optimize_function_for_size_p (cfun)")))
9894 (const_string "*")))
9895 (set_attr "mode" "<MODE>")])
9897 (define_insn "*<shift_insn>si3_cmp_zext"
9898 [(set (reg FLAGS_REG)
9900 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9901 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9903 (set (match_operand:DI 0 "register_operand" "=r")
9904 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9906 && (optimize_function_for_size_p (cfun)
9907 || !TARGET_PARTIAL_FLAG_REG_STALL
9908 || (operands[2] == const1_rtx
9910 && ix86_match_ccmode (insn, CCGOCmode)
9911 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9913 if (operands[2] == const1_rtx
9914 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9915 return "<shift>{l}\t%k0";
9917 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9919 [(set_attr "type" "ishift")
9920 (set (attr "length_immediate")
9922 (and (match_operand 2 "const1_operand")
9923 (ior (match_test "TARGET_SHIFT1")
9924 (match_test "optimize_function_for_size_p (cfun)")))
9926 (const_string "*")))
9927 (set_attr "mode" "SI")])
9929 (define_insn "*<shift_insn><mode>3_cconly"
9930 [(set (reg FLAGS_REG)
9933 (match_operand:SWI 1 "register_operand" "0")
9934 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9936 (clobber (match_scratch:SWI 0 "=<r>"))]
9937 "(optimize_function_for_size_p (cfun)
9938 || !TARGET_PARTIAL_FLAG_REG_STALL
9939 || (operands[2] == const1_rtx
9941 && ix86_match_ccmode (insn, CCGOCmode)"
9943 if (operands[2] == const1_rtx
9944 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9945 return "<shift>{<imodesuffix>}\t%0";
9947 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9949 [(set_attr "type" "ishift")
9950 (set (attr "length_immediate")
9952 (and (match_operand 2 "const1_operand")
9953 (ior (match_test "TARGET_SHIFT1")
9954 (match_test "optimize_function_for_size_p (cfun)")))
9956 (const_string "*")))
9957 (set_attr "mode" "<MODE>")])
9959 ;; Rotate instructions
9961 (define_expand "<rotate_insn>ti3"
9962 [(set (match_operand:TI 0 "register_operand")
9963 (any_rotate:TI (match_operand:TI 1 "register_operand")
9964 (match_operand:QI 2 "nonmemory_operand")))]
9967 if (const_1_to_63_operand (operands[2], VOIDmode))
9968 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9969 (operands[0], operands[1], operands[2]));
9976 (define_expand "<rotate_insn>di3"
9977 [(set (match_operand:DI 0 "shiftdi_operand")
9978 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand")
9979 (match_operand:QI 2 "nonmemory_operand")))]
9983 ix86_expand_binary_operator (<CODE>, DImode, operands);
9984 else if (const_1_to_31_operand (operands[2], VOIDmode))
9985 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9986 (operands[0], operands[1], operands[2]));
9993 (define_expand "<rotate_insn><mode>3"
9994 [(set (match_operand:SWIM124 0 "nonimmediate_operand")
9995 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand")
9996 (match_operand:QI 2 "nonmemory_operand")))]
9998 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10000 ;; Avoid useless masking of count operand.
10001 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10002 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10004 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10007 (match_operand:SI 2 "nonimmediate_operand" "c")
10008 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10009 (clobber (reg:CC FLAGS_REG))]
10010 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10011 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10012 == GET_MODE_BITSIZE (<MODE>mode)-1"
10015 [(parallel [(set (match_dup 0)
10016 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10017 (clobber (reg:CC FLAGS_REG))])]
10019 if (can_create_pseudo_p ())
10020 operands [2] = force_reg (SImode, operands[2]);
10022 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10024 [(set_attr "type" "rotate")
10025 (set_attr "mode" "<MODE>")])
10027 ;; Implement rotation using two double-precision
10028 ;; shift instructions and a scratch register.
10030 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10031 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10032 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10033 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10034 (clobber (reg:CC FLAGS_REG))
10035 (clobber (match_scratch:DWIH 3 "=&r"))]
10039 [(set (match_dup 3) (match_dup 4))
10041 [(set (match_dup 4)
10042 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10043 (lshiftrt:DWIH (match_dup 5)
10044 (minus:QI (match_dup 6) (match_dup 2)))))
10045 (clobber (reg:CC FLAGS_REG))])
10047 [(set (match_dup 5)
10048 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10049 (lshiftrt:DWIH (match_dup 3)
10050 (minus:QI (match_dup 6) (match_dup 2)))))
10051 (clobber (reg:CC FLAGS_REG))])]
10053 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10055 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10058 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10059 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10060 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10061 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10062 (clobber (reg:CC FLAGS_REG))
10063 (clobber (match_scratch:DWIH 3 "=&r"))]
10067 [(set (match_dup 3) (match_dup 4))
10069 [(set (match_dup 4)
10070 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10071 (ashift:DWIH (match_dup 5)
10072 (minus:QI (match_dup 6) (match_dup 2)))))
10073 (clobber (reg:CC FLAGS_REG))])
10075 [(set (match_dup 5)
10076 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10077 (ashift:DWIH (match_dup 3)
10078 (minus:QI (match_dup 6) (match_dup 2)))))
10079 (clobber (reg:CC FLAGS_REG))])]
10081 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10083 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10086 (define_insn "*bmi2_rorx<mode>3_1"
10087 [(set (match_operand:SWI48 0 "register_operand" "=r")
10088 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10089 (match_operand:QI 2 "immediate_operand" "<S>")))]
10091 "rorx\t{%2, %1, %0|%0, %1, %2}"
10092 [(set_attr "type" "rotatex")
10093 (set_attr "mode" "<MODE>")])
10095 (define_insn "*<rotate_insn><mode>3_1"
10096 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10098 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10099 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10100 (clobber (reg:CC FLAGS_REG))]
10101 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10103 switch (get_attr_type (insn))
10109 if (operands[2] == const1_rtx
10110 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10111 return "<rotate>{<imodesuffix>}\t%0";
10113 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10116 [(set_attr "isa" "*,bmi2")
10117 (set_attr "type" "rotate,rotatex")
10118 (set (attr "length_immediate")
10120 (and (eq_attr "type" "rotate")
10121 (and (match_operand 2 "const1_operand")
10122 (ior (match_test "TARGET_SHIFT1")
10123 (match_test "optimize_function_for_size_p (cfun)"))))
10125 (const_string "*")))
10126 (set_attr "mode" "<MODE>")])
10128 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10130 [(set (match_operand:SWI48 0 "register_operand")
10131 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10132 (match_operand:QI 2 "immediate_operand")))
10133 (clobber (reg:CC FLAGS_REG))]
10134 "TARGET_BMI2 && reload_completed"
10135 [(set (match_dup 0)
10136 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10139 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10143 [(set (match_operand:SWI48 0 "register_operand")
10144 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
10145 (match_operand:QI 2 "immediate_operand")))
10146 (clobber (reg:CC FLAGS_REG))]
10147 "TARGET_BMI2 && reload_completed"
10148 [(set (match_dup 0)
10149 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10151 (define_insn "*bmi2_rorxsi3_1_zext"
10152 [(set (match_operand:DI 0 "register_operand" "=r")
10154 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10155 (match_operand:QI 2 "immediate_operand" "I"))))]
10156 "TARGET_64BIT && TARGET_BMI2"
10157 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10158 [(set_attr "type" "rotatex")
10159 (set_attr "mode" "SI")])
10161 (define_insn "*<rotate_insn>si3_1_zext"
10162 [(set (match_operand:DI 0 "register_operand" "=r,r")
10164 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10165 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10166 (clobber (reg:CC FLAGS_REG))]
10167 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10169 switch (get_attr_type (insn))
10175 if (operands[2] == const1_rtx
10176 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10177 return "<rotate>{l}\t%k0";
10179 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10182 [(set_attr "isa" "*,bmi2")
10183 (set_attr "type" "rotate,rotatex")
10184 (set (attr "length_immediate")
10186 (and (eq_attr "type" "rotate")
10187 (and (match_operand 2 "const1_operand")
10188 (ior (match_test "TARGET_SHIFT1")
10189 (match_test "optimize_function_for_size_p (cfun)"))))
10191 (const_string "*")))
10192 (set_attr "mode" "SI")])
10194 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10196 [(set (match_operand:DI 0 "register_operand")
10198 (rotate:SI (match_operand:SI 1 "nonimmediate_operand")
10199 (match_operand:QI 2 "immediate_operand"))))
10200 (clobber (reg:CC FLAGS_REG))]
10201 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10202 [(set (match_dup 0)
10203 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10206 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10210 [(set (match_operand:DI 0 "register_operand")
10212 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand")
10213 (match_operand:QI 2 "immediate_operand"))))
10214 (clobber (reg:CC FLAGS_REG))]
10215 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10216 [(set (match_dup 0)
10217 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10219 (define_insn "*<rotate_insn><mode>3_1"
10220 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10221 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10222 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10226 if (operands[2] == const1_rtx
10227 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10228 return "<rotate>{<imodesuffix>}\t%0";
10230 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10232 [(set_attr "type" "rotate")
10233 (set (attr "length_immediate")
10235 (and (match_operand 2 "const1_operand")
10236 (ior (match_test "TARGET_SHIFT1")
10237 (match_test "optimize_function_for_size_p (cfun)")))
10239 (const_string "*")))
10240 (set_attr "mode" "<MODE>")])
10242 (define_insn "*<rotate_insn>qi3_1_slp"
10243 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10244 (any_rotate:QI (match_dup 0)
10245 (match_operand:QI 1 "nonmemory_operand" "cI")))
10246 (clobber (reg:CC FLAGS_REG))]
10247 "(optimize_function_for_size_p (cfun)
10248 || !TARGET_PARTIAL_REG_STALL
10249 || (operands[1] == const1_rtx
10250 && TARGET_SHIFT1))"
10252 if (operands[1] == const1_rtx
10253 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10254 return "<rotate>{b}\t%0";
10256 return "<rotate>{b}\t{%1, %0|%0, %1}";
10258 [(set_attr "type" "rotate1")
10259 (set (attr "length_immediate")
10261 (and (match_operand 1 "const1_operand")
10262 (ior (match_test "TARGET_SHIFT1")
10263 (match_test "optimize_function_for_size_p (cfun)")))
10265 (const_string "*")))
10266 (set_attr "mode" "QI")])
10269 [(set (match_operand:HI 0 "register_operand")
10270 (any_rotate:HI (match_dup 0) (const_int 8)))
10271 (clobber (reg:CC FLAGS_REG))]
10273 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10274 [(parallel [(set (strict_low_part (match_dup 0))
10275 (bswap:HI (match_dup 0)))
10276 (clobber (reg:CC FLAGS_REG))])])
10278 ;; Bit set / bit test instructions
10280 (define_expand "extv"
10281 [(set (match_operand:SI 0 "register_operand")
10282 (sign_extract:SI (match_operand:SI 1 "register_operand")
10283 (match_operand:SI 2 "const8_operand")
10284 (match_operand:SI 3 "const8_operand")))]
10287 /* Handle extractions from %ah et al. */
10288 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10291 /* From mips.md: extract_bit_field doesn't verify that our source
10292 matches the predicate, so check it again here. */
10293 if (! ext_register_operand (operands[1], VOIDmode))
10297 (define_expand "extzv"
10298 [(set (match_operand:SI 0 "register_operand")
10299 (zero_extract:SI (match_operand 1 "ext_register_operand")
10300 (match_operand:SI 2 "const8_operand")
10301 (match_operand:SI 3 "const8_operand")))]
10304 /* Handle extractions from %ah et al. */
10305 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10308 /* From mips.md: extract_bit_field doesn't verify that our source
10309 matches the predicate, so check it again here. */
10310 if (! ext_register_operand (operands[1], VOIDmode))
10314 (define_expand "insv"
10315 [(set (zero_extract (match_operand 0 "register_operand")
10316 (match_operand 1 "const_int_operand")
10317 (match_operand 2 "const_int_operand"))
10318 (match_operand 3 "register_operand"))]
10321 rtx (*gen_mov_insv_1) (rtx, rtx);
10323 if (ix86_expand_pinsr (operands))
10326 /* Handle insertions to %ah et al. */
10327 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10330 /* From mips.md: insert_bit_field doesn't verify that our source
10331 matches the predicate, so check it again here. */
10332 if (! ext_register_operand (operands[0], VOIDmode))
10335 gen_mov_insv_1 = (TARGET_64BIT
10336 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10338 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10342 ;; %%% bts, btr, btc, bt.
10343 ;; In general these instructions are *slow* when applied to memory,
10344 ;; since they enforce atomic operation. When applied to registers,
10345 ;; it depends on the cpu implementation. They're never faster than
10346 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10347 ;; no point. But in 64-bit, we can't hold the relevant immediates
10348 ;; within the instruction itself, so operating on bits in the high
10349 ;; 32-bits of a register becomes easier.
10351 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10352 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10353 ;; negdf respectively, so they can never be disabled entirely.
10355 (define_insn "*btsq"
10356 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10358 (match_operand:DI 1 "const_0_to_63_operand"))
10360 (clobber (reg:CC FLAGS_REG))]
10361 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10362 "bts{q}\t{%1, %0|%0, %1}"
10363 [(set_attr "type" "alu1")
10364 (set_attr "prefix_0f" "1")
10365 (set_attr "mode" "DI")])
10367 (define_insn "*btrq"
10368 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10370 (match_operand:DI 1 "const_0_to_63_operand"))
10372 (clobber (reg:CC FLAGS_REG))]
10373 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10374 "btr{q}\t{%1, %0|%0, %1}"
10375 [(set_attr "type" "alu1")
10376 (set_attr "prefix_0f" "1")
10377 (set_attr "mode" "DI")])
10379 (define_insn "*btcq"
10380 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10382 (match_operand:DI 1 "const_0_to_63_operand"))
10383 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10384 (clobber (reg:CC FLAGS_REG))]
10385 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10386 "btc{q}\t{%1, %0|%0, %1}"
10387 [(set_attr "type" "alu1")
10388 (set_attr "prefix_0f" "1")
10389 (set_attr "mode" "DI")])
10391 ;; Allow Nocona to avoid these instructions if a register is available.
10394 [(match_scratch:DI 2 "r")
10395 (parallel [(set (zero_extract:DI
10396 (match_operand:DI 0 "register_operand")
10398 (match_operand:DI 1 "const_0_to_63_operand"))
10400 (clobber (reg:CC FLAGS_REG))])]
10401 "TARGET_64BIT && !TARGET_USE_BT"
10404 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10407 if (HOST_BITS_PER_WIDE_INT >= 64)
10408 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10409 else if (i < HOST_BITS_PER_WIDE_INT)
10410 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10412 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10414 op1 = immed_double_const (lo, hi, DImode);
10417 emit_move_insn (operands[2], op1);
10421 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10426 [(match_scratch:DI 2 "r")
10427 (parallel [(set (zero_extract:DI
10428 (match_operand:DI 0 "register_operand")
10430 (match_operand:DI 1 "const_0_to_63_operand"))
10432 (clobber (reg:CC FLAGS_REG))])]
10433 "TARGET_64BIT && !TARGET_USE_BT"
10436 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10439 if (HOST_BITS_PER_WIDE_INT >= 64)
10440 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10441 else if (i < HOST_BITS_PER_WIDE_INT)
10442 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10444 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10446 op1 = immed_double_const (~lo, ~hi, DImode);
10449 emit_move_insn (operands[2], op1);
10453 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10458 [(match_scratch:DI 2 "r")
10459 (parallel [(set (zero_extract:DI
10460 (match_operand:DI 0 "register_operand")
10462 (match_operand:DI 1 "const_0_to_63_operand"))
10463 (not:DI (zero_extract:DI
10464 (match_dup 0) (const_int 1) (match_dup 1))))
10465 (clobber (reg:CC FLAGS_REG))])]
10466 "TARGET_64BIT && !TARGET_USE_BT"
10469 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10472 if (HOST_BITS_PER_WIDE_INT >= 64)
10473 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10474 else if (i < HOST_BITS_PER_WIDE_INT)
10475 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10477 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10479 op1 = immed_double_const (lo, hi, DImode);
10482 emit_move_insn (operands[2], op1);
10486 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10490 (define_insn "*bt<mode>"
10491 [(set (reg:CCC FLAGS_REG)
10493 (zero_extract:SWI48
10494 (match_operand:SWI48 0 "register_operand" "r")
10496 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10498 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10499 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10500 [(set_attr "type" "alu1")
10501 (set_attr "prefix_0f" "1")
10502 (set_attr "mode" "<MODE>")])
10504 ;; Store-flag instructions.
10506 ;; For all sCOND expanders, also expand the compare or test insn that
10507 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10509 (define_insn_and_split "*setcc_di_1"
10510 [(set (match_operand:DI 0 "register_operand" "=q")
10511 (match_operator:DI 1 "ix86_comparison_operator"
10512 [(reg FLAGS_REG) (const_int 0)]))]
10513 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10515 "&& reload_completed"
10516 [(set (match_dup 2) (match_dup 1))
10517 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10519 PUT_MODE (operands[1], QImode);
10520 operands[2] = gen_lowpart (QImode, operands[0]);
10523 (define_insn_and_split "*setcc_si_1_and"
10524 [(set (match_operand:SI 0 "register_operand" "=q")
10525 (match_operator:SI 1 "ix86_comparison_operator"
10526 [(reg FLAGS_REG) (const_int 0)]))
10527 (clobber (reg:CC FLAGS_REG))]
10528 "!TARGET_PARTIAL_REG_STALL
10529 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10531 "&& reload_completed"
10532 [(set (match_dup 2) (match_dup 1))
10533 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10534 (clobber (reg:CC FLAGS_REG))])]
10536 PUT_MODE (operands[1], QImode);
10537 operands[2] = gen_lowpart (QImode, operands[0]);
10540 (define_insn_and_split "*setcc_si_1_movzbl"
10541 [(set (match_operand:SI 0 "register_operand" "=q")
10542 (match_operator:SI 1 "ix86_comparison_operator"
10543 [(reg FLAGS_REG) (const_int 0)]))]
10544 "!TARGET_PARTIAL_REG_STALL
10545 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10547 "&& reload_completed"
10548 [(set (match_dup 2) (match_dup 1))
10549 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10551 PUT_MODE (operands[1], QImode);
10552 operands[2] = gen_lowpart (QImode, operands[0]);
10555 (define_insn "*setcc_qi"
10556 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10557 (match_operator:QI 1 "ix86_comparison_operator"
10558 [(reg FLAGS_REG) (const_int 0)]))]
10561 [(set_attr "type" "setcc")
10562 (set_attr "mode" "QI")])
10564 (define_insn "*setcc_qi_slp"
10565 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10566 (match_operator:QI 1 "ix86_comparison_operator"
10567 [(reg FLAGS_REG) (const_int 0)]))]
10570 [(set_attr "type" "setcc")
10571 (set_attr "mode" "QI")])
10573 ;; In general it is not safe to assume too much about CCmode registers,
10574 ;; so simplify-rtx stops when it sees a second one. Under certain
10575 ;; conditions this is safe on x86, so help combine not create
10582 [(set (match_operand:QI 0 "nonimmediate_operand")
10583 (ne:QI (match_operator 1 "ix86_comparison_operator"
10584 [(reg FLAGS_REG) (const_int 0)])
10587 [(set (match_dup 0) (match_dup 1))]
10588 "PUT_MODE (operands[1], QImode);")
10591 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10592 (ne:QI (match_operator 1 "ix86_comparison_operator"
10593 [(reg FLAGS_REG) (const_int 0)])
10596 [(set (match_dup 0) (match_dup 1))]
10597 "PUT_MODE (operands[1], QImode);")
10600 [(set (match_operand:QI 0 "nonimmediate_operand")
10601 (eq:QI (match_operator 1 "ix86_comparison_operator"
10602 [(reg FLAGS_REG) (const_int 0)])
10605 [(set (match_dup 0) (match_dup 1))]
10607 rtx new_op1 = copy_rtx (operands[1]);
10608 operands[1] = new_op1;
10609 PUT_MODE (new_op1, QImode);
10610 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10611 GET_MODE (XEXP (new_op1, 0))));
10613 /* Make sure that (a) the CCmode we have for the flags is strong
10614 enough for the reversed compare or (b) we have a valid FP compare. */
10615 if (! ix86_comparison_operator (new_op1, VOIDmode))
10620 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand"))
10621 (eq:QI (match_operator 1 "ix86_comparison_operator"
10622 [(reg FLAGS_REG) (const_int 0)])
10625 [(set (match_dup 0) (match_dup 1))]
10627 rtx new_op1 = copy_rtx (operands[1]);
10628 operands[1] = new_op1;
10629 PUT_MODE (new_op1, QImode);
10630 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10631 GET_MODE (XEXP (new_op1, 0))));
10633 /* Make sure that (a) the CCmode we have for the flags is strong
10634 enough for the reversed compare or (b) we have a valid FP compare. */
10635 if (! ix86_comparison_operator (new_op1, VOIDmode))
10639 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10640 ;; subsequent logical operations are used to imitate conditional moves.
10641 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10644 (define_insn "setcc_<mode>_sse"
10645 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10646 (match_operator:MODEF 3 "sse_comparison_operator"
10647 [(match_operand:MODEF 1 "register_operand" "0,x")
10648 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10649 "SSE_FLOAT_MODE_P (<MODE>mode)"
10651 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10652 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10653 [(set_attr "isa" "noavx,avx")
10654 (set_attr "type" "ssecmp")
10655 (set_attr "length_immediate" "1")
10656 (set_attr "prefix" "orig,vex")
10657 (set_attr "mode" "<MODE>")])
10659 ;; Basic conditional jump instructions.
10660 ;; We ignore the overflow flag for signed branch instructions.
10662 (define_insn "*jcc_1"
10664 (if_then_else (match_operator 1 "ix86_comparison_operator"
10665 [(reg FLAGS_REG) (const_int 0)])
10666 (label_ref (match_operand 0))
10670 [(set_attr "type" "ibr")
10671 (set_attr "modrm" "0")
10672 (set (attr "length")
10673 (if_then_else (and (ge (minus (match_dup 0) (pc))
10675 (lt (minus (match_dup 0) (pc))
10680 (define_insn "*jcc_2"
10682 (if_then_else (match_operator 1 "ix86_comparison_operator"
10683 [(reg FLAGS_REG) (const_int 0)])
10685 (label_ref (match_operand 0))))]
10688 [(set_attr "type" "ibr")
10689 (set_attr "modrm" "0")
10690 (set (attr "length")
10691 (if_then_else (and (ge (minus (match_dup 0) (pc))
10693 (lt (minus (match_dup 0) (pc))
10698 ;; In general it is not safe to assume too much about CCmode registers,
10699 ;; so simplify-rtx stops when it sees a second one. Under certain
10700 ;; conditions this is safe on x86, so help combine not create
10708 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10709 [(reg FLAGS_REG) (const_int 0)])
10711 (label_ref (match_operand 1))
10715 (if_then_else (match_dup 0)
10716 (label_ref (match_dup 1))
10718 "PUT_MODE (operands[0], VOIDmode);")
10722 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10723 [(reg FLAGS_REG) (const_int 0)])
10725 (label_ref (match_operand 1))
10729 (if_then_else (match_dup 0)
10730 (label_ref (match_dup 1))
10733 rtx new_op0 = copy_rtx (operands[0]);
10734 operands[0] = new_op0;
10735 PUT_MODE (new_op0, VOIDmode);
10736 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10737 GET_MODE (XEXP (new_op0, 0))));
10739 /* Make sure that (a) the CCmode we have for the flags is strong
10740 enough for the reversed compare or (b) we have a valid FP compare. */
10741 if (! ix86_comparison_operator (new_op0, VOIDmode))
10745 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10746 ;; pass generates from shift insn with QImode operand. Actually, the mode
10747 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10748 ;; appropriate modulo of the bit offset value.
10750 (define_insn_and_split "*jcc_bt<mode>"
10752 (if_then_else (match_operator 0 "bt_comparison_operator"
10753 [(zero_extract:SWI48
10754 (match_operand:SWI48 1 "register_operand" "r")
10757 (match_operand:QI 2 "register_operand" "r")))
10759 (label_ref (match_operand 3))
10761 (clobber (reg:CC FLAGS_REG))]
10762 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10765 [(set (reg:CCC FLAGS_REG)
10767 (zero_extract:SWI48
10773 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10774 (label_ref (match_dup 3))
10777 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10779 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10782 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10783 ;; also for DImode, this is what combine produces.
10784 (define_insn_and_split "*jcc_bt<mode>_mask"
10786 (if_then_else (match_operator 0 "bt_comparison_operator"
10787 [(zero_extract:SWI48
10788 (match_operand:SWI48 1 "register_operand" "r")
10791 (match_operand:SI 2 "register_operand" "r")
10792 (match_operand:SI 3 "const_int_operand" "n")))])
10793 (label_ref (match_operand 4))
10795 (clobber (reg:CC FLAGS_REG))]
10796 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10797 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10798 == GET_MODE_BITSIZE (<MODE>mode)-1"
10801 [(set (reg:CCC FLAGS_REG)
10803 (zero_extract:SWI48
10809 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10810 (label_ref (match_dup 4))
10813 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10815 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10818 (define_insn_and_split "*jcc_btsi_1"
10820 (if_then_else (match_operator 0 "bt_comparison_operator"
10823 (match_operand:SI 1 "register_operand" "r")
10824 (match_operand:QI 2 "register_operand" "r"))
10827 (label_ref (match_operand 3))
10829 (clobber (reg:CC FLAGS_REG))]
10830 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10833 [(set (reg:CCC FLAGS_REG)
10841 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10842 (label_ref (match_dup 3))
10845 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10847 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10850 ;; avoid useless masking of bit offset operand
10851 (define_insn_and_split "*jcc_btsi_mask_1"
10854 (match_operator 0 "bt_comparison_operator"
10857 (match_operand:SI 1 "register_operand" "r")
10860 (match_operand:SI 2 "register_operand" "r")
10861 (match_operand:SI 3 "const_int_operand" "n")) 0))
10864 (label_ref (match_operand 4))
10866 (clobber (reg:CC FLAGS_REG))]
10867 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10868 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10871 [(set (reg:CCC FLAGS_REG)
10879 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10880 (label_ref (match_dup 4))
10882 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10884 ;; Define combination compare-and-branch fp compare instructions to help
10887 (define_insn "*fp_jcc_1_387"
10889 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10890 [(match_operand 1 "register_operand" "f")
10891 (match_operand 2 "nonimmediate_operand" "fm")])
10892 (label_ref (match_operand 3))
10894 (clobber (reg:CCFP FPSR_REG))
10895 (clobber (reg:CCFP FLAGS_REG))
10896 (clobber (match_scratch:HI 4 "=a"))]
10898 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10899 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10900 && SELECT_CC_MODE (GET_CODE (operands[0]),
10901 operands[1], operands[2]) == CCFPmode
10905 (define_insn "*fp_jcc_1r_387"
10907 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10908 [(match_operand 1 "register_operand" "f")
10909 (match_operand 2 "nonimmediate_operand" "fm")])
10911 (label_ref (match_operand 3))))
10912 (clobber (reg:CCFP FPSR_REG))
10913 (clobber (reg:CCFP FLAGS_REG))
10914 (clobber (match_scratch:HI 4 "=a"))]
10916 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10917 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10918 && SELECT_CC_MODE (GET_CODE (operands[0]),
10919 operands[1], operands[2]) == CCFPmode
10923 (define_insn "*fp_jcc_2_387"
10925 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10926 [(match_operand 1 "register_operand" "f")
10927 (match_operand 2 "register_operand" "f")])
10928 (label_ref (match_operand 3))
10930 (clobber (reg:CCFP FPSR_REG))
10931 (clobber (reg:CCFP FLAGS_REG))
10932 (clobber (match_scratch:HI 4 "=a"))]
10933 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10934 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10938 (define_insn "*fp_jcc_2r_387"
10940 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10941 [(match_operand 1 "register_operand" "f")
10942 (match_operand 2 "register_operand" "f")])
10944 (label_ref (match_operand 3))))
10945 (clobber (reg:CCFP FPSR_REG))
10946 (clobber (reg:CCFP FLAGS_REG))
10947 (clobber (match_scratch:HI 4 "=a"))]
10948 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10949 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10953 (define_insn "*fp_jcc_3_387"
10955 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10956 [(match_operand 1 "register_operand" "f")
10957 (match_operand 2 "const0_operand")])
10958 (label_ref (match_operand 3))
10960 (clobber (reg:CCFP FPSR_REG))
10961 (clobber (reg:CCFP FLAGS_REG))
10962 (clobber (match_scratch:HI 4 "=a"))]
10963 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10964 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10965 && SELECT_CC_MODE (GET_CODE (operands[0]),
10966 operands[1], operands[2]) == CCFPmode
10972 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10973 [(match_operand 1 "register_operand")
10974 (match_operand 2 "nonimmediate_operand")])
10976 (match_operand 4)))
10977 (clobber (reg:CCFP FPSR_REG))
10978 (clobber (reg:CCFP FLAGS_REG))]
10982 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10983 operands[3], operands[4], NULL_RTX, NULL_RTX);
10989 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990 [(match_operand 1 "register_operand")
10991 (match_operand 2 "general_operand")])
10993 (match_operand 4)))
10994 (clobber (reg:CCFP FPSR_REG))
10995 (clobber (reg:CCFP FLAGS_REG))
10996 (clobber (match_scratch:HI 5 "=a"))]
11000 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11001 operands[3], operands[4], operands[5], NULL_RTX);
11005 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11006 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11007 ;; with a precedence over other operators and is always put in the first
11008 ;; place. Swap condition and operands to match ficom instruction.
11010 (define_insn "*fp_jcc_4_<mode>_387"
11013 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11014 [(match_operator 1 "float_operator"
11015 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11016 (match_operand 3 "register_operand" "f,f")])
11017 (label_ref (match_operand 4))
11019 (clobber (reg:CCFP FPSR_REG))
11020 (clobber (reg:CCFP FLAGS_REG))
11021 (clobber (match_scratch:HI 5 "=a,a"))]
11022 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11023 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11024 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11025 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11032 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11033 [(match_operator 1 "float_operator"
11034 [(match_operand:SWI24 2 "memory_operand")])
11035 (match_operand 3 "register_operand")])
11037 (match_operand 5)))
11038 (clobber (reg:CCFP FPSR_REG))
11039 (clobber (reg:CCFP FLAGS_REG))
11040 (clobber (match_scratch:HI 6 "=a"))]
11044 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11046 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11047 operands[3], operands[7],
11048 operands[4], operands[5], operands[6], NULL_RTX);
11052 ;; %%% Kill this when reload knows how to do it.
11056 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11057 [(match_operator 1 "float_operator"
11058 [(match_operand:SWI24 2 "register_operand")])
11059 (match_operand 3 "register_operand")])
11061 (match_operand 5)))
11062 (clobber (reg:CCFP FPSR_REG))
11063 (clobber (reg:CCFP FLAGS_REG))
11064 (clobber (match_scratch:HI 6 "=a"))]
11068 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11069 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11071 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11072 operands[3], operands[7],
11073 operands[4], operands[5], operands[6], operands[2]);
11077 ;; Unconditional and other jump instructions
11079 (define_insn "jump"
11081 (label_ref (match_operand 0)))]
11084 [(set_attr "type" "ibr")
11085 (set (attr "length")
11086 (if_then_else (and (ge (minus (match_dup 0) (pc))
11088 (lt (minus (match_dup 0) (pc))
11092 (set_attr "modrm" "0")])
11094 (define_expand "indirect_jump"
11095 [(set (pc) (match_operand 0 "indirect_branch_operand"))]
11099 operands[0] = convert_memory_address (word_mode, operands[0]);
11102 (define_insn "*indirect_jump"
11103 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11106 [(set_attr "type" "ibr")
11107 (set_attr "length_immediate" "0")])
11109 (define_expand "tablejump"
11110 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand"))
11111 (use (label_ref (match_operand 1)))])]
11114 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11115 relative. Convert the relative address to an absolute address. */
11119 enum rtx_code code;
11121 /* We can't use @GOTOFF for text labels on VxWorks;
11122 see gotoff_operand. */
11123 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11127 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11129 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11133 op1 = pic_offset_table_rtx;
11138 op0 = pic_offset_table_rtx;
11142 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11147 operands[0] = convert_memory_address (word_mode, operands[0]);
11150 (define_insn "*tablejump_1"
11151 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11152 (use (label_ref (match_operand 1)))]
11155 [(set_attr "type" "ibr")
11156 (set_attr "length_immediate" "0")])
11158 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11161 [(set (reg FLAGS_REG) (match_operand 0))
11162 (set (match_operand:QI 1 "register_operand")
11163 (match_operator:QI 2 "ix86_comparison_operator"
11164 [(reg FLAGS_REG) (const_int 0)]))
11165 (set (match_operand 3 "q_regs_operand")
11166 (zero_extend (match_dup 1)))]
11167 "(peep2_reg_dead_p (3, operands[1])
11168 || operands_match_p (operands[1], operands[3]))
11169 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11170 [(set (match_dup 4) (match_dup 0))
11171 (set (strict_low_part (match_dup 5))
11174 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11175 operands[5] = gen_lowpart (QImode, operands[3]);
11176 ix86_expand_clear (operands[3]);
11180 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11181 (match_operand 4)])
11182 (set (match_operand:QI 1 "register_operand")
11183 (match_operator:QI 2 "ix86_comparison_operator"
11184 [(reg FLAGS_REG) (const_int 0)]))
11185 (set (match_operand 3 "q_regs_operand")
11186 (zero_extend (match_dup 1)))]
11187 "(peep2_reg_dead_p (3, operands[1])
11188 || operands_match_p (operands[1], operands[3]))
11189 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11190 [(parallel [(set (match_dup 5) (match_dup 0))
11192 (set (strict_low_part (match_dup 6))
11195 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11196 operands[6] = gen_lowpart (QImode, operands[3]);
11197 ix86_expand_clear (operands[3]);
11200 ;; Similar, but match zero extend with andsi3.
11203 [(set (reg FLAGS_REG) (match_operand 0))
11204 (set (match_operand:QI 1 "register_operand")
11205 (match_operator:QI 2 "ix86_comparison_operator"
11206 [(reg FLAGS_REG) (const_int 0)]))
11207 (parallel [(set (match_operand:SI 3 "q_regs_operand")
11208 (and:SI (match_dup 3) (const_int 255)))
11209 (clobber (reg:CC FLAGS_REG))])]
11210 "REGNO (operands[1]) == REGNO (operands[3])
11211 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11212 [(set (match_dup 4) (match_dup 0))
11213 (set (strict_low_part (match_dup 5))
11216 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11217 operands[5] = gen_lowpart (QImode, operands[3]);
11218 ix86_expand_clear (operands[3]);
11222 [(parallel [(set (reg FLAGS_REG) (match_operand 0))
11223 (match_operand 4)])
11224 (set (match_operand:QI 1 "register_operand")
11225 (match_operator:QI 2 "ix86_comparison_operator"
11226 [(reg FLAGS_REG) (const_int 0)]))
11227 (parallel [(set (match_operand 3 "q_regs_operand")
11228 (zero_extend (match_dup 1)))
11229 (clobber (reg:CC FLAGS_REG))])]
11230 "(peep2_reg_dead_p (3, operands[1])
11231 || operands_match_p (operands[1], operands[3]))
11232 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11233 [(parallel [(set (match_dup 5) (match_dup 0))
11235 (set (strict_low_part (match_dup 6))
11238 operands[5] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11239 operands[6] = gen_lowpart (QImode, operands[3]);
11240 ix86_expand_clear (operands[3]);
11243 ;; Call instructions.
11245 ;; The predicates normally associated with named expanders are not properly
11246 ;; checked for calls. This is a bug in the generic code, but it isn't that
11247 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11249 ;; P6 processors will jump to the address after the decrement when %esp
11250 ;; is used as a call operand, so they will execute return address as a code.
11251 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11253 ;; Register constraint for call instruction.
11254 (define_mode_attr c [(SI "l") (DI "r")])
11256 ;; Call subroutine returning no value.
11258 (define_expand "call"
11259 [(call (match_operand:QI 0)
11261 (use (match_operand 2))]
11264 ix86_expand_call (NULL, operands[0], operands[1],
11265 operands[2], NULL, false);
11269 (define_expand "sibcall"
11270 [(call (match_operand:QI 0)
11272 (use (match_operand 2))]
11275 ix86_expand_call (NULL, operands[0], operands[1],
11276 operands[2], NULL, true);
11280 (define_insn_and_split "*call_vzeroupper"
11281 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11283 (unspec [(match_operand 2 "const_int_operand")]
11284 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11285 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11287 "&& reload_completed"
11289 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11290 [(set_attr "type" "call")])
11292 (define_insn "*call"
11293 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11294 (match_operand 1))]
11295 "!SIBLING_CALL_P (insn)"
11296 "* return ix86_output_call_insn (insn, operands[0]);"
11297 [(set_attr "type" "call")])
11299 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11300 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11302 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11303 (clobber (reg:TI XMM6_REG))
11304 (clobber (reg:TI XMM7_REG))
11305 (clobber (reg:TI XMM8_REG))
11306 (clobber (reg:TI XMM9_REG))
11307 (clobber (reg:TI XMM10_REG))
11308 (clobber (reg:TI XMM11_REG))
11309 (clobber (reg:TI XMM12_REG))
11310 (clobber (reg:TI XMM13_REG))
11311 (clobber (reg:TI XMM14_REG))
11312 (clobber (reg:TI XMM15_REG))
11313 (clobber (reg:DI SI_REG))
11314 (clobber (reg:DI DI_REG))
11315 (unspec [(match_operand 2 "const_int_operand")]
11316 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11317 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11319 "&& reload_completed"
11321 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11322 [(set_attr "type" "call")])
11324 (define_insn "*call_rex64_ms_sysv"
11325 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11327 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11328 (clobber (reg:TI XMM6_REG))
11329 (clobber (reg:TI XMM7_REG))
11330 (clobber (reg:TI XMM8_REG))
11331 (clobber (reg:TI XMM9_REG))
11332 (clobber (reg:TI XMM10_REG))
11333 (clobber (reg:TI XMM11_REG))
11334 (clobber (reg:TI XMM12_REG))
11335 (clobber (reg:TI XMM13_REG))
11336 (clobber (reg:TI XMM14_REG))
11337 (clobber (reg:TI XMM15_REG))
11338 (clobber (reg:DI SI_REG))
11339 (clobber (reg:DI DI_REG))]
11340 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11341 "* return ix86_output_call_insn (insn, operands[0]);"
11342 [(set_attr "type" "call")])
11344 (define_insn_and_split "*sibcall_vzeroupper"
11345 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11347 (unspec [(match_operand 2 "const_int_operand")]
11348 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11349 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11351 "&& reload_completed"
11353 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11354 [(set_attr "type" "call")])
11356 (define_insn "*sibcall"
11357 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11358 (match_operand 1))]
11359 "SIBLING_CALL_P (insn)"
11360 "* return ix86_output_call_insn (insn, operands[0]);"
11361 [(set_attr "type" "call")])
11363 (define_expand "call_pop"
11364 [(parallel [(call (match_operand:QI 0)
11365 (match_operand:SI 1))
11366 (set (reg:SI SP_REG)
11367 (plus:SI (reg:SI SP_REG)
11368 (match_operand:SI 3)))])]
11371 ix86_expand_call (NULL, operands[0], operands[1],
11372 operands[2], operands[3], false);
11376 (define_insn_and_split "*call_pop_vzeroupper"
11377 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11379 (set (reg:SI SP_REG)
11380 (plus:SI (reg:SI SP_REG)
11381 (match_operand:SI 2 "immediate_operand" "i")))
11382 (unspec [(match_operand 3 "const_int_operand")]
11383 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11384 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11386 "&& reload_completed"
11388 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11389 [(set_attr "type" "call")])
11391 (define_insn "*call_pop"
11392 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11394 (set (reg:SI SP_REG)
11395 (plus:SI (reg:SI SP_REG)
11396 (match_operand:SI 2 "immediate_operand" "i")))]
11397 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11398 "* return ix86_output_call_insn (insn, operands[0]);"
11399 [(set_attr "type" "call")])
11401 (define_insn_and_split "*sibcall_pop_vzeroupper"
11402 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11404 (set (reg:SI SP_REG)
11405 (plus:SI (reg:SI SP_REG)
11406 (match_operand:SI 2 "immediate_operand" "i")))
11407 (unspec [(match_operand 3 "const_int_operand")]
11408 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11409 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11411 "&& reload_completed"
11413 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11414 [(set_attr "type" "call")])
11416 (define_insn "*sibcall_pop"
11417 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11419 (set (reg:SI SP_REG)
11420 (plus:SI (reg:SI SP_REG)
11421 (match_operand:SI 2 "immediate_operand" "i")))]
11422 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11423 "* return ix86_output_call_insn (insn, operands[0]);"
11424 [(set_attr "type" "call")])
11426 ;; Call subroutine, returning value in operand 0
11428 (define_expand "call_value"
11429 [(set (match_operand 0)
11430 (call (match_operand:QI 1)
11431 (match_operand 2)))
11432 (use (match_operand 3))]
11435 ix86_expand_call (operands[0], operands[1], operands[2],
11436 operands[3], NULL, false);
11440 (define_expand "sibcall_value"
11441 [(set (match_operand 0)
11442 (call (match_operand:QI 1)
11443 (match_operand 2)))
11444 (use (match_operand 3))]
11447 ix86_expand_call (operands[0], operands[1], operands[2],
11448 operands[3], NULL, true);
11452 (define_insn_and_split "*call_value_vzeroupper"
11453 [(set (match_operand 0)
11454 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11455 (match_operand 2)))
11456 (unspec [(match_operand 3 "const_int_operand")]
11457 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11458 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11460 "&& reload_completed"
11462 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11463 [(set_attr "type" "callv")])
11465 (define_insn "*call_value"
11466 [(set (match_operand 0)
11467 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11468 (match_operand 2)))]
11469 "!SIBLING_CALL_P (insn)"
11470 "* return ix86_output_call_insn (insn, operands[1]);"
11471 [(set_attr "type" "callv")])
11473 (define_insn_and_split "*sibcall_value_vzeroupper"
11474 [(set (match_operand 0)
11475 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11476 (match_operand 2)))
11477 (unspec [(match_operand 3 "const_int_operand")]
11478 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11479 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11481 "&& reload_completed"
11483 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11484 [(set_attr "type" "callv")])
11486 (define_insn "*sibcall_value"
11487 [(set (match_operand 0)
11488 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11489 (match_operand 2)))]
11490 "SIBLING_CALL_P (insn)"
11491 "* return ix86_output_call_insn (insn, operands[1]);"
11492 [(set_attr "type" "callv")])
11494 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11495 [(set (match_operand 0)
11496 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11497 (match_operand 2)))
11498 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11499 (clobber (reg:TI XMM6_REG))
11500 (clobber (reg:TI XMM7_REG))
11501 (clobber (reg:TI XMM8_REG))
11502 (clobber (reg:TI XMM9_REG))
11503 (clobber (reg:TI XMM10_REG))
11504 (clobber (reg:TI XMM11_REG))
11505 (clobber (reg:TI XMM12_REG))
11506 (clobber (reg:TI XMM13_REG))
11507 (clobber (reg:TI XMM14_REG))
11508 (clobber (reg:TI XMM15_REG))
11509 (clobber (reg:DI SI_REG))
11510 (clobber (reg:DI DI_REG))
11511 (unspec [(match_operand 3 "const_int_operand")]
11512 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11513 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11515 "&& reload_completed"
11517 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11518 [(set_attr "type" "callv")])
11520 (define_insn "*call_value_rex64_ms_sysv"
11521 [(set (match_operand 0)
11522 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11523 (match_operand 2)))
11524 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11525 (clobber (reg:TI XMM6_REG))
11526 (clobber (reg:TI XMM7_REG))
11527 (clobber (reg:TI XMM8_REG))
11528 (clobber (reg:TI XMM9_REG))
11529 (clobber (reg:TI XMM10_REG))
11530 (clobber (reg:TI XMM11_REG))
11531 (clobber (reg:TI XMM12_REG))
11532 (clobber (reg:TI XMM13_REG))
11533 (clobber (reg:TI XMM14_REG))
11534 (clobber (reg:TI XMM15_REG))
11535 (clobber (reg:DI SI_REG))
11536 (clobber (reg:DI DI_REG))]
11537 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11538 "* return ix86_output_call_insn (insn, operands[1]);"
11539 [(set_attr "type" "callv")])
11541 (define_expand "call_value_pop"
11542 [(parallel [(set (match_operand 0)
11543 (call (match_operand:QI 1)
11544 (match_operand:SI 2)))
11545 (set (reg:SI SP_REG)
11546 (plus:SI (reg:SI SP_REG)
11547 (match_operand:SI 4)))])]
11550 ix86_expand_call (operands[0], operands[1], operands[2],
11551 operands[3], operands[4], false);
11555 (define_insn_and_split "*call_value_pop_vzeroupper"
11556 [(set (match_operand 0)
11557 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11558 (match_operand 2)))
11559 (set (reg:SI SP_REG)
11560 (plus:SI (reg:SI SP_REG)
11561 (match_operand:SI 3 "immediate_operand" "i")))
11562 (unspec [(match_operand 4 "const_int_operand")]
11563 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11564 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11566 "&& reload_completed"
11568 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11569 [(set_attr "type" "callv")])
11571 (define_insn "*call_value_pop"
11572 [(set (match_operand 0)
11573 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11574 (match_operand 2)))
11575 (set (reg:SI SP_REG)
11576 (plus:SI (reg:SI SP_REG)
11577 (match_operand:SI 3 "immediate_operand" "i")))]
11578 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11579 "* return ix86_output_call_insn (insn, operands[1]);"
11580 [(set_attr "type" "callv")])
11582 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11583 [(set (match_operand 0)
11584 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11585 (match_operand 2)))
11586 (set (reg:SI SP_REG)
11587 (plus:SI (reg:SI SP_REG)
11588 (match_operand:SI 3 "immediate_operand" "i")))
11589 (unspec [(match_operand 4 "const_int_operand")]
11590 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11591 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11593 "&& reload_completed"
11595 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11596 [(set_attr "type" "callv")])
11598 (define_insn "*sibcall_value_pop"
11599 [(set (match_operand 0)
11600 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11601 (match_operand 2)))
11602 (set (reg:SI SP_REG)
11603 (plus:SI (reg:SI SP_REG)
11604 (match_operand:SI 3 "immediate_operand" "i")))]
11605 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11606 "* return ix86_output_call_insn (insn, operands[1]);"
11607 [(set_attr "type" "callv")])
11609 ;; Call subroutine returning any type.
11611 (define_expand "untyped_call"
11612 [(parallel [(call (match_operand 0)
11615 (match_operand 2)])]
11620 /* In order to give reg-stack an easier job in validating two
11621 coprocessor registers as containing a possible return value,
11622 simply pretend the untyped call returns a complex long double
11625 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11626 and should have the default ABI. */
11628 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11629 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11630 operands[0], const0_rtx,
11631 GEN_INT ((TARGET_64BIT
11632 ? (ix86_abi == SYSV_ABI
11633 ? X86_64_SSE_REGPARM_MAX
11634 : X86_64_MS_SSE_REGPARM_MAX)
11635 : X86_32_SSE_REGPARM_MAX)
11639 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11641 rtx set = XVECEXP (operands[2], 0, i);
11642 emit_move_insn (SET_DEST (set), SET_SRC (set));
11645 /* The optimizer does not know that the call sets the function value
11646 registers we stored in the result block. We avoid problems by
11647 claiming that all hard registers are used and clobbered at this
11649 emit_insn (gen_blockage ());
11654 ;; Prologue and epilogue instructions
11656 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11657 ;; all of memory. This blocks insns from being moved across this point.
11659 (define_insn "blockage"
11660 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11663 [(set_attr "length" "0")])
11665 ;; Do not schedule instructions accessing memory across this point.
11667 (define_expand "memory_blockage"
11668 [(set (match_dup 0)
11669 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11672 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11673 MEM_VOLATILE_P (operands[0]) = 1;
11676 (define_insn "*memory_blockage"
11677 [(set (match_operand:BLK 0)
11678 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11681 [(set_attr "length" "0")])
11683 ;; As USE insns aren't meaningful after reload, this is used instead
11684 ;; to prevent deleting instructions setting registers for PIC code
11685 (define_insn "prologue_use"
11686 [(unspec_volatile [(match_operand 0)] UNSPECV_PROLOGUE_USE)]
11689 [(set_attr "length" "0")])
11691 ;; Insn emitted into the body of a function to return from a function.
11692 ;; This is only done if the function's epilogue is known to be simple.
11693 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11695 (define_expand "return"
11697 "ix86_can_use_return_insn_p ()"
11699 ix86_maybe_emit_epilogue_vzeroupper ();
11700 if (crtl->args.pops_args)
11702 rtx popc = GEN_INT (crtl->args.pops_args);
11703 emit_jump_insn (gen_simple_return_pop_internal (popc));
11708 ;; We need to disable this for TARGET_SEH, as otherwise
11709 ;; shrink-wrapped prologue gets enabled too. This might exceed
11710 ;; the maximum size of prologue in unwind information.
11712 (define_expand "simple_return"
11716 ix86_maybe_emit_epilogue_vzeroupper ();
11717 if (crtl->args.pops_args)
11719 rtx popc = GEN_INT (crtl->args.pops_args);
11720 emit_jump_insn (gen_simple_return_pop_internal (popc));
11725 (define_insn "simple_return_internal"
11729 [(set_attr "length" "1")
11730 (set_attr "atom_unit" "jeu")
11731 (set_attr "length_immediate" "0")
11732 (set_attr "modrm" "0")])
11734 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11735 ;; instruction Athlon and K8 have.
11737 (define_insn "simple_return_internal_long"
11739 (unspec [(const_int 0)] UNSPEC_REP)]
11742 [(set_attr "length" "2")
11743 (set_attr "atom_unit" "jeu")
11744 (set_attr "length_immediate" "0")
11745 (set_attr "prefix_rep" "1")
11746 (set_attr "modrm" "0")])
11748 (define_insn "simple_return_pop_internal"
11750 (use (match_operand:SI 0 "const_int_operand"))]
11753 [(set_attr "length" "3")
11754 (set_attr "atom_unit" "jeu")
11755 (set_attr "length_immediate" "2")
11756 (set_attr "modrm" "0")])
11758 (define_insn "simple_return_indirect_internal"
11760 (use (match_operand:SI 0 "register_operand" "r"))]
11763 [(set_attr "type" "ibr")
11764 (set_attr "length_immediate" "0")])
11770 [(set_attr "length" "1")
11771 (set_attr "length_immediate" "0")
11772 (set_attr "modrm" "0")])
11774 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11775 (define_insn "nops"
11776 [(unspec_volatile [(match_operand 0 "const_int_operand")]
11780 int num = INTVAL (operands[0]);
11782 gcc_assert (num >= 1 && num <= 8);
11785 fputs ("\tnop\n", asm_out_file);
11789 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11790 (set_attr "length_immediate" "0")
11791 (set_attr "modrm" "0")])
11793 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11794 ;; branch prediction penalty for the third jump in a 16-byte
11798 [(unspec_volatile [(match_operand 0)] UNSPECV_ALIGN)]
11801 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11802 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11804 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11805 The align insn is used to avoid 3 jump instructions in the row to improve
11806 branch prediction and the benefits hardly outweigh the cost of extra 8
11807 nops on the average inserted by full alignment pseudo operation. */
11811 [(set_attr "length" "16")])
11813 (define_expand "prologue"
11816 "ix86_expand_prologue (); DONE;")
11818 (define_insn "set_got"
11819 [(set (match_operand:SI 0 "register_operand" "=r")
11820 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11821 (clobber (reg:CC FLAGS_REG))]
11823 "* return output_set_got (operands[0], NULL_RTX);"
11824 [(set_attr "type" "multi")
11825 (set_attr "length" "12")])
11827 (define_insn "set_got_labelled"
11828 [(set (match_operand:SI 0 "register_operand" "=r")
11829 (unspec:SI [(label_ref (match_operand 1))]
11831 (clobber (reg:CC FLAGS_REG))]
11833 "* return output_set_got (operands[0], operands[1]);"
11834 [(set_attr "type" "multi")
11835 (set_attr "length" "12")])
11837 (define_insn "set_got_rex64"
11838 [(set (match_operand:DI 0 "register_operand" "=r")
11839 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11841 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11842 [(set_attr "type" "lea")
11843 (set_attr "length_address" "4")
11844 (set_attr "mode" "DI")])
11846 (define_insn "set_rip_rex64"
11847 [(set (match_operand:DI 0 "register_operand" "=r")
11848 (unspec:DI [(label_ref (match_operand 1))] UNSPEC_SET_RIP))]
11850 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11851 [(set_attr "type" "lea")
11852 (set_attr "length_address" "4")
11853 (set_attr "mode" "DI")])
11855 (define_insn "set_got_offset_rex64"
11856 [(set (match_operand:DI 0 "register_operand" "=r")
11858 [(label_ref (match_operand 1))]
11859 UNSPEC_SET_GOT_OFFSET))]
11861 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11862 [(set_attr "type" "imov")
11863 (set_attr "length_immediate" "0")
11864 (set_attr "length_address" "8")
11865 (set_attr "mode" "DI")])
11867 (define_expand "epilogue"
11870 "ix86_expand_epilogue (1); DONE;")
11872 (define_expand "sibcall_epilogue"
11875 "ix86_expand_epilogue (0); DONE;")
11877 (define_expand "eh_return"
11878 [(use (match_operand 0 "register_operand"))]
11881 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11883 /* Tricky bit: we write the address of the handler to which we will
11884 be returning into someone else's stack frame, one word below the
11885 stack address we wish to restore. */
11886 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11887 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11888 tmp = gen_rtx_MEM (Pmode, tmp);
11889 emit_move_insn (tmp, ra);
11891 emit_jump_insn (gen_eh_return_internal ());
11896 (define_insn_and_split "eh_return_internal"
11900 "epilogue_completed"
11902 "ix86_expand_epilogue (2); DONE;")
11904 (define_insn "leave"
11905 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11906 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11907 (clobber (mem:BLK (scratch)))]
11910 [(set_attr "type" "leave")])
11912 (define_insn "leave_rex64"
11913 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11914 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11915 (clobber (mem:BLK (scratch)))]
11918 [(set_attr "type" "leave")])
11920 ;; Handle -fsplit-stack.
11922 (define_expand "split_stack_prologue"
11926 ix86_expand_split_stack_prologue ();
11930 ;; In order to support the call/return predictor, we use a return
11931 ;; instruction which the middle-end doesn't see.
11932 (define_insn "split_stack_return"
11933 [(unspec_volatile [(match_operand:SI 0 "const_int_operand")]
11934 UNSPECV_SPLIT_STACK_RETURN)]
11937 if (operands[0] == const0_rtx)
11942 [(set_attr "atom_unit" "jeu")
11943 (set_attr "modrm" "0")
11944 (set (attr "length")
11945 (if_then_else (match_operand:SI 0 "const0_operand")
11948 (set (attr "length_immediate")
11949 (if_then_else (match_operand:SI 0 "const0_operand")
11953 ;; If there are operand 0 bytes available on the stack, jump to
11956 (define_expand "split_stack_space_check"
11957 [(set (pc) (if_then_else
11958 (ltu (minus (reg SP_REG)
11959 (match_operand 0 "register_operand"))
11960 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11961 (label_ref (match_operand 1))
11965 rtx reg, size, limit;
11967 reg = gen_reg_rtx (Pmode);
11968 size = force_reg (Pmode, operands[0]);
11969 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11970 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11971 UNSPEC_STACK_CHECK);
11972 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11973 ix86_expand_branch (GEU, reg, limit, operands[1]);
11978 ;; Bit manipulation instructions.
11980 (define_expand "ffs<mode>2"
11981 [(set (match_dup 2) (const_int -1))
11982 (parallel [(set (reg:CCZ FLAGS_REG)
11984 (match_operand:SWI48 1 "nonimmediate_operand")
11986 (set (match_operand:SWI48 0 "register_operand")
11987 (ctz:SWI48 (match_dup 1)))])
11988 (set (match_dup 0) (if_then_else:SWI48
11989 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11992 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11993 (clobber (reg:CC FLAGS_REG))])]
11996 if (<MODE>mode == SImode && !TARGET_CMOVE)
11998 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12001 operands[2] = gen_reg_rtx (<MODE>mode);
12004 (define_insn_and_split "ffssi2_no_cmove"
12005 [(set (match_operand:SI 0 "register_operand" "=r")
12006 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12007 (clobber (match_scratch:SI 2 "=&q"))
12008 (clobber (reg:CC FLAGS_REG))]
12011 "&& reload_completed"
12012 [(parallel [(set (reg:CCZ FLAGS_REG)
12013 (compare:CCZ (match_dup 1) (const_int 0)))
12014 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12015 (set (strict_low_part (match_dup 3))
12016 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12017 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12018 (clobber (reg:CC FLAGS_REG))])
12019 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12020 (clobber (reg:CC FLAGS_REG))])
12021 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12022 (clobber (reg:CC FLAGS_REG))])]
12024 operands[3] = gen_lowpart (QImode, operands[2]);
12025 ix86_expand_clear (operands[2]);
12028 (define_insn "*ffs<mode>_1"
12029 [(set (reg:CCZ FLAGS_REG)
12030 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12032 (set (match_operand:SWI48 0 "register_operand" "=r")
12033 (ctz:SWI48 (match_dup 1)))]
12035 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12036 [(set_attr "type" "alu1")
12037 (set_attr "prefix_0f" "1")
12038 (set_attr "mode" "<MODE>")])
12040 (define_insn "ctz<mode>2"
12041 [(set (match_operand:SWI248 0 "register_operand" "=r")
12042 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12043 (clobber (reg:CC FLAGS_REG))]
12047 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12049 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12051 [(set_attr "type" "alu1")
12052 (set_attr "prefix_0f" "1")
12053 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12054 (set_attr "mode" "<MODE>")])
12056 (define_expand "clz<mode>2"
12058 [(set (match_operand:SWI248 0 "register_operand")
12061 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand"))))
12062 (clobber (reg:CC FLAGS_REG))])
12064 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12065 (clobber (reg:CC FLAGS_REG))])]
12070 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12073 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12076 (define_insn "clz<mode>2_lzcnt"
12077 [(set (match_operand:SWI248 0 "register_operand" "=r")
12078 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12079 (clobber (reg:CC FLAGS_REG))]
12081 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12082 [(set_attr "prefix_rep" "1")
12083 (set_attr "type" "bitmanip")
12084 (set_attr "mode" "<MODE>")])
12086 ;; BMI instructions.
12087 (define_insn "*bmi_andn_<mode>"
12088 [(set (match_operand:SWI48 0 "register_operand" "=r")
12091 (match_operand:SWI48 1 "register_operand" "r"))
12092 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12093 (clobber (reg:CC FLAGS_REG))]
12095 "andn\t{%2, %1, %0|%0, %1, %2}"
12096 [(set_attr "type" "bitmanip")
12097 (set_attr "mode" "<MODE>")])
12099 (define_insn "bmi_bextr_<mode>"
12100 [(set (match_operand:SWI48 0 "register_operand" "=r")
12101 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12102 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12104 (clobber (reg:CC FLAGS_REG))]
12106 "bextr\t{%2, %1, %0|%0, %1, %2}"
12107 [(set_attr "type" "bitmanip")
12108 (set_attr "mode" "<MODE>")])
12110 (define_insn "*bmi_blsi_<mode>"
12111 [(set (match_operand:SWI48 0 "register_operand" "=r")
12114 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12116 (clobber (reg:CC FLAGS_REG))]
12118 "blsi\t{%1, %0|%0, %1}"
12119 [(set_attr "type" "bitmanip")
12120 (set_attr "mode" "<MODE>")])
12122 (define_insn "*bmi_blsmsk_<mode>"
12123 [(set (match_operand:SWI48 0 "register_operand" "=r")
12126 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12129 (clobber (reg:CC FLAGS_REG))]
12131 "blsmsk\t{%1, %0|%0, %1}"
12132 [(set_attr "type" "bitmanip")
12133 (set_attr "mode" "<MODE>")])
12135 (define_insn "*bmi_blsr_<mode>"
12136 [(set (match_operand:SWI48 0 "register_operand" "=r")
12139 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12142 (clobber (reg:CC FLAGS_REG))]
12144 "blsr\t{%1, %0|%0, %1}"
12145 [(set_attr "type" "bitmanip")
12146 (set_attr "mode" "<MODE>")])
12148 ;; BMI2 instructions.
12149 (define_insn "bmi2_bzhi_<mode>3"
12150 [(set (match_operand:SWI48 0 "register_operand" "=r")
12151 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12152 (lshiftrt:SWI48 (const_int -1)
12153 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12154 (clobber (reg:CC FLAGS_REG))]
12156 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12157 [(set_attr "type" "bitmanip")
12158 (set_attr "prefix" "vex")
12159 (set_attr "mode" "<MODE>")])
12161 (define_insn "bmi2_pdep_<mode>3"
12162 [(set (match_operand:SWI48 0 "register_operand" "=r")
12163 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12164 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12167 "pdep\t{%2, %1, %0|%0, %1, %2}"
12168 [(set_attr "type" "bitmanip")
12169 (set_attr "prefix" "vex")
12170 (set_attr "mode" "<MODE>")])
12172 (define_insn "bmi2_pext_<mode>3"
12173 [(set (match_operand:SWI48 0 "register_operand" "=r")
12174 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12175 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12178 "pext\t{%2, %1, %0|%0, %1, %2}"
12179 [(set_attr "type" "bitmanip")
12180 (set_attr "prefix" "vex")
12181 (set_attr "mode" "<MODE>")])
12183 ;; TBM instructions.
12184 (define_insn "tbm_bextri_<mode>"
12185 [(set (match_operand:SWI48 0 "register_operand" "=r")
12186 (zero_extract:SWI48
12187 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12188 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12189 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12190 (clobber (reg:CC FLAGS_REG))]
12193 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12194 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12196 [(set_attr "type" "bitmanip")
12197 (set_attr "mode" "<MODE>")])
12199 (define_insn "*tbm_blcfill_<mode>"
12200 [(set (match_operand:SWI48 0 "register_operand" "=r")
12203 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12206 (clobber (reg:CC FLAGS_REG))]
12208 "blcfill\t{%1, %0|%0, %1}"
12209 [(set_attr "type" "bitmanip")
12210 (set_attr "mode" "<MODE>")])
12212 (define_insn "*tbm_blci_<mode>"
12213 [(set (match_operand:SWI48 0 "register_operand" "=r")
12217 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12220 (clobber (reg:CC FLAGS_REG))]
12222 "blci\t{%1, %0|%0, %1}"
12223 [(set_attr "type" "bitmanip")
12224 (set_attr "mode" "<MODE>")])
12226 (define_insn "*tbm_blcic_<mode>"
12227 [(set (match_operand:SWI48 0 "register_operand" "=r")
12230 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12234 (clobber (reg:CC FLAGS_REG))]
12236 "blcic\t{%1, %0|%0, %1}"
12237 [(set_attr "type" "bitmanip")
12238 (set_attr "mode" "<MODE>")])
12240 (define_insn "*tbm_blcmsk_<mode>"
12241 [(set (match_operand:SWI48 0 "register_operand" "=r")
12244 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12247 (clobber (reg:CC FLAGS_REG))]
12249 "blcmsk\t{%1, %0|%0, %1}"
12250 [(set_attr "type" "bitmanip")
12251 (set_attr "mode" "<MODE>")])
12253 (define_insn "*tbm_blcs_<mode>"
12254 [(set (match_operand:SWI48 0 "register_operand" "=r")
12257 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12260 (clobber (reg:CC FLAGS_REG))]
12262 "blcs\t{%1, %0|%0, %1}"
12263 [(set_attr "type" "bitmanip")
12264 (set_attr "mode" "<MODE>")])
12266 (define_insn "*tbm_blsfill_<mode>"
12267 [(set (match_operand:SWI48 0 "register_operand" "=r")
12270 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12273 (clobber (reg:CC FLAGS_REG))]
12275 "blsfill\t{%1, %0|%0, %1}"
12276 [(set_attr "type" "bitmanip")
12277 (set_attr "mode" "<MODE>")])
12279 (define_insn "*tbm_blsic_<mode>"
12280 [(set (match_operand:SWI48 0 "register_operand" "=r")
12283 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12287 (clobber (reg:CC FLAGS_REG))]
12289 "blsic\t{%1, %0|%0, %1}"
12290 [(set_attr "type" "bitmanip")
12291 (set_attr "mode" "<MODE>")])
12293 (define_insn "*tbm_t1mskc_<mode>"
12294 [(set (match_operand:SWI48 0 "register_operand" "=r")
12297 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12301 (clobber (reg:CC FLAGS_REG))]
12303 "t1mskc\t{%1, %0|%0, %1}"
12304 [(set_attr "type" "bitmanip")
12305 (set_attr "mode" "<MODE>")])
12307 (define_insn "*tbm_tzmsk_<mode>"
12308 [(set (match_operand:SWI48 0 "register_operand" "=r")
12311 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12315 (clobber (reg:CC FLAGS_REG))]
12317 "tzmsk\t{%1, %0|%0, %1}"
12318 [(set_attr "type" "bitmanip")
12319 (set_attr "mode" "<MODE>")])
12321 (define_insn "bsr_rex64"
12322 [(set (match_operand:DI 0 "register_operand" "=r")
12323 (minus:DI (const_int 63)
12324 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12325 (clobber (reg:CC FLAGS_REG))]
12327 "bsr{q}\t{%1, %0|%0, %1}"
12328 [(set_attr "type" "alu1")
12329 (set_attr "prefix_0f" "1")
12330 (set_attr "mode" "DI")])
12333 [(set (match_operand:SI 0 "register_operand" "=r")
12334 (minus:SI (const_int 31)
12335 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12336 (clobber (reg:CC FLAGS_REG))]
12338 "bsr{l}\t{%1, %0|%0, %1}"
12339 [(set_attr "type" "alu1")
12340 (set_attr "prefix_0f" "1")
12341 (set_attr "mode" "SI")])
12343 (define_insn "*bsrhi"
12344 [(set (match_operand:HI 0 "register_operand" "=r")
12345 (minus:HI (const_int 15)
12346 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12347 (clobber (reg:CC FLAGS_REG))]
12349 "bsr{w}\t{%1, %0|%0, %1}"
12350 [(set_attr "type" "alu1")
12351 (set_attr "prefix_0f" "1")
12352 (set_attr "mode" "HI")])
12354 (define_insn "popcount<mode>2"
12355 [(set (match_operand:SWI248 0 "register_operand" "=r")
12357 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12358 (clobber (reg:CC FLAGS_REG))]
12362 return "popcnt\t{%1, %0|%0, %1}";
12364 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12367 [(set_attr "prefix_rep" "1")
12368 (set_attr "type" "bitmanip")
12369 (set_attr "mode" "<MODE>")])
12371 (define_insn "*popcount<mode>2_cmp"
12372 [(set (reg FLAGS_REG)
12375 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12377 (set (match_operand:SWI248 0 "register_operand" "=r")
12378 (popcount:SWI248 (match_dup 1)))]
12379 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12382 return "popcnt\t{%1, %0|%0, %1}";
12384 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12387 [(set_attr "prefix_rep" "1")
12388 (set_attr "type" "bitmanip")
12389 (set_attr "mode" "<MODE>")])
12391 (define_insn "*popcountsi2_cmp_zext"
12392 [(set (reg FLAGS_REG)
12394 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12396 (set (match_operand:DI 0 "register_operand" "=r")
12397 (zero_extend:DI(popcount:SI (match_dup 1))))]
12398 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12401 return "popcnt\t{%1, %0|%0, %1}";
12403 return "popcnt{l}\t{%1, %0|%0, %1}";
12406 [(set_attr "prefix_rep" "1")
12407 (set_attr "type" "bitmanip")
12408 (set_attr "mode" "SI")])
12410 (define_expand "bswap<mode>2"
12411 [(set (match_operand:SWI48 0 "register_operand")
12412 (bswap:SWI48 (match_operand:SWI48 1 "register_operand")))]
12415 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12417 rtx x = operands[0];
12419 emit_move_insn (x, operands[1]);
12420 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12421 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12422 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12427 (define_insn "*bswap<mode>2_movbe"
12428 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12429 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12431 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12434 movbe\t{%1, %0|%0, %1}
12435 movbe\t{%1, %0|%0, %1}"
12436 [(set_attr "type" "bitmanip,imov,imov")
12437 (set_attr "modrm" "0,1,1")
12438 (set_attr "prefix_0f" "*,1,1")
12439 (set_attr "prefix_extra" "*,1,1")
12440 (set_attr "mode" "<MODE>")])
12442 (define_insn "*bswap<mode>2_1"
12443 [(set (match_operand:SWI48 0 "register_operand" "=r")
12444 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12447 [(set_attr "type" "bitmanip")
12448 (set_attr "modrm" "0")
12449 (set_attr "mode" "<MODE>")])
12451 (define_insn "*bswaphi_lowpart_1"
12452 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12453 (bswap:HI (match_dup 0)))
12454 (clobber (reg:CC FLAGS_REG))]
12455 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12457 xchg{b}\t{%h0, %b0|%b0, %h0}
12458 rol{w}\t{$8, %0|%0, 8}"
12459 [(set_attr "length" "2,4")
12460 (set_attr "mode" "QI,HI")])
12462 (define_insn "bswaphi_lowpart"
12463 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12464 (bswap:HI (match_dup 0)))
12465 (clobber (reg:CC FLAGS_REG))]
12467 "rol{w}\t{$8, %0|%0, 8}"
12468 [(set_attr "length" "4")
12469 (set_attr "mode" "HI")])
12471 (define_expand "paritydi2"
12472 [(set (match_operand:DI 0 "register_operand")
12473 (parity:DI (match_operand:DI 1 "register_operand")))]
12476 rtx scratch = gen_reg_rtx (QImode);
12479 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12480 NULL_RTX, operands[1]));
12482 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12483 gen_rtx_REG (CCmode, FLAGS_REG),
12485 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12488 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12491 rtx tmp = gen_reg_rtx (SImode);
12493 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12494 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12499 (define_expand "paritysi2"
12500 [(set (match_operand:SI 0 "register_operand")
12501 (parity:SI (match_operand:SI 1 "register_operand")))]
12504 rtx scratch = gen_reg_rtx (QImode);
12507 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12509 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12510 gen_rtx_REG (CCmode, FLAGS_REG),
12512 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12514 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12518 (define_insn_and_split "paritydi2_cmp"
12519 [(set (reg:CC FLAGS_REG)
12520 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12522 (clobber (match_scratch:DI 0 "=r"))
12523 (clobber (match_scratch:SI 1 "=&r"))
12524 (clobber (match_scratch:HI 2 "=Q"))]
12527 "&& reload_completed"
12529 [(set (match_dup 1)
12530 (xor:SI (match_dup 1) (match_dup 4)))
12531 (clobber (reg:CC FLAGS_REG))])
12533 [(set (reg:CC FLAGS_REG)
12534 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12535 (clobber (match_dup 1))
12536 (clobber (match_dup 2))])]
12538 operands[4] = gen_lowpart (SImode, operands[3]);
12542 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12543 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12546 operands[1] = gen_highpart (SImode, operands[3]);
12549 (define_insn_and_split "paritysi2_cmp"
12550 [(set (reg:CC FLAGS_REG)
12551 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12553 (clobber (match_scratch:SI 0 "=r"))
12554 (clobber (match_scratch:HI 1 "=&Q"))]
12557 "&& reload_completed"
12559 [(set (match_dup 1)
12560 (xor:HI (match_dup 1) (match_dup 3)))
12561 (clobber (reg:CC FLAGS_REG))])
12563 [(set (reg:CC FLAGS_REG)
12564 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12565 (clobber (match_dup 1))])]
12567 operands[3] = gen_lowpart (HImode, operands[2]);
12569 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12570 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12573 (define_insn "*parityhi2_cmp"
12574 [(set (reg:CC FLAGS_REG)
12575 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12577 (clobber (match_scratch:HI 0 "=Q"))]
12579 "xor{b}\t{%h0, %b0|%b0, %h0}"
12580 [(set_attr "length" "2")
12581 (set_attr "mode" "HI")])
12584 ;; Thread-local storage patterns for ELF.
12586 ;; Note that these code sequences must appear exactly as shown
12587 ;; in order to allow linker relaxation.
12589 (define_insn "*tls_global_dynamic_32_gnu"
12590 [(set (match_operand:SI 0 "register_operand" "=a")
12592 [(match_operand:SI 1 "register_operand" "b")
12593 (match_operand 2 "tls_symbolic_operand")
12594 (match_operand 3 "constant_call_address_operand" "z")]
12596 (clobber (match_scratch:SI 4 "=d"))
12597 (clobber (match_scratch:SI 5 "=c"))
12598 (clobber (reg:CC FLAGS_REG))]
12599 "!TARGET_64BIT && TARGET_GNU_TLS"
12602 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12603 if (TARGET_SUN_TLS)
12604 #ifdef HAVE_AS_IX86_TLSGDPLT
12605 return "call\t%a2@tlsgdplt";
12607 return "call\t%p3@plt";
12609 return "call\t%P3";
12611 [(set_attr "type" "multi")
12612 (set_attr "length" "12")])
12614 (define_expand "tls_global_dynamic_32"
12616 [(set (match_operand:SI 0 "register_operand")
12617 (unspec:SI [(match_operand:SI 2 "register_operand")
12618 (match_operand 1 "tls_symbolic_operand")
12619 (match_operand 3 "constant_call_address_operand")]
12621 (clobber (match_scratch:SI 4))
12622 (clobber (match_scratch:SI 5))
12623 (clobber (reg:CC FLAGS_REG))])])
12625 (define_insn "*tls_global_dynamic_64_<mode>"
12626 [(set (match_operand:P 0 "register_operand" "=a")
12628 (mem:QI (match_operand 2 "constant_call_address_operand" "z"))
12629 (match_operand 3)))
12630 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12635 fputs (ASM_BYTE "0x66\n", asm_out_file);
12637 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12638 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12639 fputs ("\trex64\n", asm_out_file);
12640 if (TARGET_SUN_TLS)
12641 return "call\t%p2@plt";
12642 return "call\t%P2";
12644 [(set_attr "type" "multi")
12645 (set (attr "length")
12646 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12648 (define_expand "tls_global_dynamic_64_<mode>"
12650 [(set (match_operand:P 0 "register_operand")
12652 (mem:QI (match_operand 2 "constant_call_address_operand"))
12654 (unspec:P [(match_operand 1 "tls_symbolic_operand")]
12658 (define_insn "*tls_local_dynamic_base_32_gnu"
12659 [(set (match_operand:SI 0 "register_operand" "=a")
12661 [(match_operand:SI 1 "register_operand" "b")
12662 (match_operand 2 "constant_call_address_operand" "z")]
12663 UNSPEC_TLS_LD_BASE))
12664 (clobber (match_scratch:SI 3 "=d"))
12665 (clobber (match_scratch:SI 4 "=c"))
12666 (clobber (reg:CC FLAGS_REG))]
12667 "!TARGET_64BIT && TARGET_GNU_TLS"
12670 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12671 if (TARGET_SUN_TLS)
12672 #ifdef HAVE_AS_IX86_TLSLDMPLT
12673 return "call\t%&@tlsldmplt";
12675 return "call\t%p2@plt";
12677 return "call\t%P2";
12679 [(set_attr "type" "multi")
12680 (set_attr "length" "11")])
12682 (define_expand "tls_local_dynamic_base_32"
12684 [(set (match_operand:SI 0 "register_operand")
12686 [(match_operand:SI 1 "register_operand")
12687 (match_operand 2 "constant_call_address_operand")]
12688 UNSPEC_TLS_LD_BASE))
12689 (clobber (match_scratch:SI 3))
12690 (clobber (match_scratch:SI 4))
12691 (clobber (reg:CC FLAGS_REG))])])
12693 (define_insn "*tls_local_dynamic_base_64_<mode>"
12694 [(set (match_operand:P 0 "register_operand" "=a")
12696 (mem:QI (match_operand 1 "constant_call_address_operand" "z"))
12697 (match_operand 2)))
12698 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12702 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12703 if (TARGET_SUN_TLS)
12704 return "call\t%p1@plt";
12705 return "call\t%P1";
12707 [(set_attr "type" "multi")
12708 (set_attr "length" "12")])
12710 (define_expand "tls_local_dynamic_base_64_<mode>"
12712 [(set (match_operand:P 0 "register_operand")
12714 (mem:QI (match_operand 1 "constant_call_address_operand"))
12716 (unspec:P [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
12719 ;; Local dynamic of a single variable is a lose. Show combine how
12720 ;; to convert that back to global dynamic.
12722 (define_insn_and_split "*tls_local_dynamic_32_once"
12723 [(set (match_operand:SI 0 "register_operand" "=a")
12725 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12726 (match_operand 2 "constant_call_address_operand" "z")]
12727 UNSPEC_TLS_LD_BASE)
12728 (const:SI (unspec:SI
12729 [(match_operand 3 "tls_symbolic_operand")]
12731 (clobber (match_scratch:SI 4 "=d"))
12732 (clobber (match_scratch:SI 5 "=c"))
12733 (clobber (reg:CC FLAGS_REG))]
12738 [(set (match_dup 0)
12739 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12741 (clobber (match_dup 4))
12742 (clobber (match_dup 5))
12743 (clobber (reg:CC FLAGS_REG))])])
12745 ;; Segment register for the thread base ptr load
12746 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12748 ;; Load and add the thread base pointer from %<tp_seg>:0.
12749 (define_insn "*load_tp_x32"
12750 [(set (match_operand:SI 0 "register_operand" "=r")
12751 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12753 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12754 [(set_attr "type" "imov")
12755 (set_attr "modrm" "0")
12756 (set_attr "length" "7")
12757 (set_attr "memory" "load")
12758 (set_attr "imm_disp" "false")])
12760 (define_insn "*load_tp_x32_zext"
12761 [(set (match_operand:DI 0 "register_operand" "=r")
12762 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12764 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12765 [(set_attr "type" "imov")
12766 (set_attr "modrm" "0")
12767 (set_attr "length" "7")
12768 (set_attr "memory" "load")
12769 (set_attr "imm_disp" "false")])
12771 (define_insn "*load_tp_<mode>"
12772 [(set (match_operand:P 0 "register_operand" "=r")
12773 (unspec:P [(const_int 0)] UNSPEC_TP))]
12775 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12776 [(set_attr "type" "imov")
12777 (set_attr "modrm" "0")
12778 (set_attr "length" "7")
12779 (set_attr "memory" "load")
12780 (set_attr "imm_disp" "false")])
12782 (define_insn "*add_tp_x32"
12783 [(set (match_operand:SI 0 "register_operand" "=r")
12784 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12785 (match_operand:SI 1 "register_operand" "0")))
12786 (clobber (reg:CC FLAGS_REG))]
12788 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12789 [(set_attr "type" "alu")
12790 (set_attr "modrm" "0")
12791 (set_attr "length" "7")
12792 (set_attr "memory" "load")
12793 (set_attr "imm_disp" "false")])
12795 (define_insn "*add_tp_x32_zext"
12796 [(set (match_operand:DI 0 "register_operand" "=r")
12798 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12799 (match_operand:SI 1 "register_operand" "0"))))
12800 (clobber (reg:CC FLAGS_REG))]
12802 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12803 [(set_attr "type" "alu")
12804 (set_attr "modrm" "0")
12805 (set_attr "length" "7")
12806 (set_attr "memory" "load")
12807 (set_attr "imm_disp" "false")])
12809 (define_insn "*add_tp_<mode>"
12810 [(set (match_operand:P 0 "register_operand" "=r")
12811 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12812 (match_operand:P 1 "register_operand" "0")))
12813 (clobber (reg:CC FLAGS_REG))]
12815 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12816 [(set_attr "type" "alu")
12817 (set_attr "modrm" "0")
12818 (set_attr "length" "7")
12819 (set_attr "memory" "load")
12820 (set_attr "imm_disp" "false")])
12822 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12823 ;; %rax as destination of the initial executable code sequence.
12824 (define_insn "tls_initial_exec_64_sun"
12825 [(set (match_operand:DI 0 "register_operand" "=a")
12827 [(match_operand 1 "tls_symbolic_operand")]
12828 UNSPEC_TLS_IE_SUN))
12829 (clobber (reg:CC FLAGS_REG))]
12830 "TARGET_64BIT && TARGET_SUN_TLS"
12833 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12834 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12836 [(set_attr "type" "multi")])
12838 ;; GNU2 TLS patterns can be split.
12840 (define_expand "tls_dynamic_gnu2_32"
12841 [(set (match_dup 3)
12842 (plus:SI (match_operand:SI 2 "register_operand")
12844 (unspec:SI [(match_operand 1 "tls_symbolic_operand")]
12847 [(set (match_operand:SI 0 "register_operand")
12848 (unspec:SI [(match_dup 1) (match_dup 3)
12849 (match_dup 2) (reg:SI SP_REG)]
12851 (clobber (reg:CC FLAGS_REG))])]
12852 "!TARGET_64BIT && TARGET_GNU2_TLS"
12854 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12855 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12858 (define_insn "*tls_dynamic_gnu2_lea_32"
12859 [(set (match_operand:SI 0 "register_operand" "=r")
12860 (plus:SI (match_operand:SI 1 "register_operand" "b")
12862 (unspec:SI [(match_operand 2 "tls_symbolic_operand")]
12863 UNSPEC_TLSDESC))))]
12864 "!TARGET_64BIT && TARGET_GNU2_TLS"
12865 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12866 [(set_attr "type" "lea")
12867 (set_attr "mode" "SI")
12868 (set_attr "length" "6")
12869 (set_attr "length_address" "4")])
12871 (define_insn "*tls_dynamic_gnu2_call_32"
12872 [(set (match_operand:SI 0 "register_operand" "=a")
12873 (unspec:SI [(match_operand 1 "tls_symbolic_operand")
12874 (match_operand:SI 2 "register_operand" "0")
12875 ;; we have to make sure %ebx still points to the GOT
12876 (match_operand:SI 3 "register_operand" "b")
12879 (clobber (reg:CC FLAGS_REG))]
12880 "!TARGET_64BIT && TARGET_GNU2_TLS"
12881 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12882 [(set_attr "type" "call")
12883 (set_attr "length" "2")
12884 (set_attr "length_address" "0")])
12886 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12887 [(set (match_operand:SI 0 "register_operand" "=&a")
12889 (unspec:SI [(match_operand 3 "tls_modbase_operand")
12890 (match_operand:SI 4)
12891 (match_operand:SI 2 "register_operand" "b")
12894 (const:SI (unspec:SI
12895 [(match_operand 1 "tls_symbolic_operand")]
12897 (clobber (reg:CC FLAGS_REG))]
12898 "!TARGET_64BIT && TARGET_GNU2_TLS"
12901 [(set (match_dup 0) (match_dup 5))]
12903 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12904 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12907 (define_expand "tls_dynamic_gnu2_64"
12908 [(set (match_dup 2)
12909 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12912 [(set (match_operand:DI 0 "register_operand")
12913 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12915 (clobber (reg:CC FLAGS_REG))])]
12916 "TARGET_64BIT && TARGET_GNU2_TLS"
12918 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12919 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12922 (define_insn "*tls_dynamic_gnu2_lea_64"
12923 [(set (match_operand:DI 0 "register_operand" "=r")
12924 (unspec:DI [(match_operand 1 "tls_symbolic_operand")]
12926 "TARGET_64BIT && TARGET_GNU2_TLS"
12927 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12928 [(set_attr "type" "lea")
12929 (set_attr "mode" "DI")
12930 (set_attr "length" "7")
12931 (set_attr "length_address" "4")])
12933 (define_insn "*tls_dynamic_gnu2_call_64"
12934 [(set (match_operand:DI 0 "register_operand" "=a")
12935 (unspec:DI [(match_operand 1 "tls_symbolic_operand")
12936 (match_operand:DI 2 "register_operand" "0")
12939 (clobber (reg:CC FLAGS_REG))]
12940 "TARGET_64BIT && TARGET_GNU2_TLS"
12941 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12942 [(set_attr "type" "call")
12943 (set_attr "length" "2")
12944 (set_attr "length_address" "0")])
12946 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12947 [(set (match_operand:DI 0 "register_operand" "=&a")
12949 (unspec:DI [(match_operand 2 "tls_modbase_operand")
12950 (match_operand:DI 3)
12953 (const:DI (unspec:DI
12954 [(match_operand 1 "tls_symbolic_operand")]
12956 (clobber (reg:CC FLAGS_REG))]
12957 "TARGET_64BIT && TARGET_GNU2_TLS"
12960 [(set (match_dup 0) (match_dup 4))]
12962 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12963 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12966 ;; These patterns match the binary 387 instructions for addM3, subM3,
12967 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12968 ;; SFmode. The first is the normal insn, the second the same insn but
12969 ;; with one operand a conversion, and the third the same insn but with
12970 ;; the other operand a conversion. The conversion may be SFmode or
12971 ;; SImode if the target mode DFmode, but only SImode if the target mode
12974 ;; Gcc is slightly more smart about handling normal two address instructions
12975 ;; so use special patterns for add and mull.
12977 (define_insn "*fop_<mode>_comm_mixed"
12978 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12979 (match_operator:MODEF 3 "binary_fp_operator"
12980 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12981 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12982 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12983 && COMMUTATIVE_ARITH_P (operands[3])
12984 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12985 "* return output_387_binary_op (insn, operands);"
12986 [(set (attr "type")
12987 (if_then_else (eq_attr "alternative" "1,2")
12988 (if_then_else (match_operand:MODEF 3 "mult_operator")
12989 (const_string "ssemul")
12990 (const_string "sseadd"))
12991 (if_then_else (match_operand:MODEF 3 "mult_operator")
12992 (const_string "fmul")
12993 (const_string "fop"))))
12994 (set_attr "isa" "*,noavx,avx")
12995 (set_attr "prefix" "orig,orig,vex")
12996 (set_attr "mode" "<MODE>")])
12998 (define_insn "*fop_<mode>_comm_sse"
12999 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13000 (match_operator:MODEF 3 "binary_fp_operator"
13001 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13002 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13003 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13004 && COMMUTATIVE_ARITH_P (operands[3])
13005 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13006 "* return output_387_binary_op (insn, operands);"
13007 [(set (attr "type")
13008 (if_then_else (match_operand:MODEF 3 "mult_operator")
13009 (const_string "ssemul")
13010 (const_string "sseadd")))
13011 (set_attr "isa" "noavx,avx")
13012 (set_attr "prefix" "orig,vex")
13013 (set_attr "mode" "<MODE>")])
13015 (define_insn "*fop_<mode>_comm_i387"
13016 [(set (match_operand:MODEF 0 "register_operand" "=f")
13017 (match_operator:MODEF 3 "binary_fp_operator"
13018 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13019 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13020 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13021 && COMMUTATIVE_ARITH_P (operands[3])
13022 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13023 "* return output_387_binary_op (insn, operands);"
13024 [(set (attr "type")
13025 (if_then_else (match_operand:MODEF 3 "mult_operator")
13026 (const_string "fmul")
13027 (const_string "fop")))
13028 (set_attr "mode" "<MODE>")])
13030 (define_insn "*fop_<mode>_1_mixed"
13031 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13032 (match_operator:MODEF 3 "binary_fp_operator"
13033 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13034 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13035 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13036 && !COMMUTATIVE_ARITH_P (operands[3])
13037 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13038 "* return output_387_binary_op (insn, operands);"
13039 [(set (attr "type")
13040 (cond [(and (eq_attr "alternative" "2,3")
13041 (match_operand:MODEF 3 "mult_operator"))
13042 (const_string "ssemul")
13043 (and (eq_attr "alternative" "2,3")
13044 (match_operand:MODEF 3 "div_operator"))
13045 (const_string "ssediv")
13046 (eq_attr "alternative" "2,3")
13047 (const_string "sseadd")
13048 (match_operand:MODEF 3 "mult_operator")
13049 (const_string "fmul")
13050 (match_operand:MODEF 3 "div_operator")
13051 (const_string "fdiv")
13053 (const_string "fop")))
13054 (set_attr "isa" "*,*,noavx,avx")
13055 (set_attr "prefix" "orig,orig,orig,vex")
13056 (set_attr "mode" "<MODE>")])
13058 (define_insn "*rcpsf2_sse"
13059 [(set (match_operand:SF 0 "register_operand" "=x")
13060 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13063 "%vrcpss\t{%1, %d0|%d0, %1}"
13064 [(set_attr "type" "sse")
13065 (set_attr "atom_sse_attr" "rcp")
13066 (set_attr "prefix" "maybe_vex")
13067 (set_attr "mode" "SF")])
13069 (define_insn "*fop_<mode>_1_sse"
13070 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13071 (match_operator:MODEF 3 "binary_fp_operator"
13072 [(match_operand:MODEF 1 "register_operand" "0,x")
13073 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13074 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13075 && !COMMUTATIVE_ARITH_P (operands[3])"
13076 "* return output_387_binary_op (insn, operands);"
13077 [(set (attr "type")
13078 (cond [(match_operand:MODEF 3 "mult_operator")
13079 (const_string "ssemul")
13080 (match_operand:MODEF 3 "div_operator")
13081 (const_string "ssediv")
13083 (const_string "sseadd")))
13084 (set_attr "isa" "noavx,avx")
13085 (set_attr "prefix" "orig,vex")
13086 (set_attr "mode" "<MODE>")])
13088 ;; This pattern is not fully shadowed by the pattern above.
13089 (define_insn "*fop_<mode>_1_i387"
13090 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13091 (match_operator:MODEF 3 "binary_fp_operator"
13092 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13093 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13094 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13095 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13096 && !COMMUTATIVE_ARITH_P (operands[3])
13097 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13098 "* return output_387_binary_op (insn, operands);"
13099 [(set (attr "type")
13100 (cond [(match_operand:MODEF 3 "mult_operator")
13101 (const_string "fmul")
13102 (match_operand:MODEF 3 "div_operator")
13103 (const_string "fdiv")
13105 (const_string "fop")))
13106 (set_attr "mode" "<MODE>")])
13108 ;; ??? Add SSE splitters for these!
13109 (define_insn "*fop_<MODEF:mode>_2_i387"
13110 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13111 (match_operator:MODEF 3 "binary_fp_operator"
13113 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13114 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13115 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13116 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13117 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13118 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13119 [(set (attr "type")
13120 (cond [(match_operand:MODEF 3 "mult_operator")
13121 (const_string "fmul")
13122 (match_operand:MODEF 3 "div_operator")
13123 (const_string "fdiv")
13125 (const_string "fop")))
13126 (set_attr "fp_int_src" "true")
13127 (set_attr "mode" "<SWI24:MODE>")])
13129 (define_insn "*fop_<MODEF:mode>_3_i387"
13130 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13131 (match_operator:MODEF 3 "binary_fp_operator"
13132 [(match_operand:MODEF 1 "register_operand" "0,0")
13134 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13135 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13136 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13137 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13138 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13139 [(set (attr "type")
13140 (cond [(match_operand:MODEF 3 "mult_operator")
13141 (const_string "fmul")
13142 (match_operand:MODEF 3 "div_operator")
13143 (const_string "fdiv")
13145 (const_string "fop")))
13146 (set_attr "fp_int_src" "true")
13147 (set_attr "mode" "<MODE>")])
13149 (define_insn "*fop_df_4_i387"
13150 [(set (match_operand:DF 0 "register_operand" "=f,f")
13151 (match_operator:DF 3 "binary_fp_operator"
13153 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13154 (match_operand:DF 2 "register_operand" "0,f")]))]
13155 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13156 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13157 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13158 "* return output_387_binary_op (insn, operands);"
13159 [(set (attr "type")
13160 (cond [(match_operand:DF 3 "mult_operator")
13161 (const_string "fmul")
13162 (match_operand:DF 3 "div_operator")
13163 (const_string "fdiv")
13165 (const_string "fop")))
13166 (set_attr "mode" "SF")])
13168 (define_insn "*fop_df_5_i387"
13169 [(set (match_operand:DF 0 "register_operand" "=f,f")
13170 (match_operator:DF 3 "binary_fp_operator"
13171 [(match_operand:DF 1 "register_operand" "0,f")
13173 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13174 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13175 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13176 "* return output_387_binary_op (insn, operands);"
13177 [(set (attr "type")
13178 (cond [(match_operand:DF 3 "mult_operator")
13179 (const_string "fmul")
13180 (match_operand:DF 3 "div_operator")
13181 (const_string "fdiv")
13183 (const_string "fop")))
13184 (set_attr "mode" "SF")])
13186 (define_insn "*fop_df_6_i387"
13187 [(set (match_operand:DF 0 "register_operand" "=f,f")
13188 (match_operator:DF 3 "binary_fp_operator"
13190 (match_operand:SF 1 "register_operand" "0,f"))
13192 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13193 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13194 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13195 "* return output_387_binary_op (insn, operands);"
13196 [(set (attr "type")
13197 (cond [(match_operand:DF 3 "mult_operator")
13198 (const_string "fmul")
13199 (match_operand:DF 3 "div_operator")
13200 (const_string "fdiv")
13202 (const_string "fop")))
13203 (set_attr "mode" "SF")])
13205 (define_insn "*fop_xf_comm_i387"
13206 [(set (match_operand:XF 0 "register_operand" "=f")
13207 (match_operator:XF 3 "binary_fp_operator"
13208 [(match_operand:XF 1 "register_operand" "%0")
13209 (match_operand:XF 2 "register_operand" "f")]))]
13211 && COMMUTATIVE_ARITH_P (operands[3])"
13212 "* return output_387_binary_op (insn, operands);"
13213 [(set (attr "type")
13214 (if_then_else (match_operand:XF 3 "mult_operator")
13215 (const_string "fmul")
13216 (const_string "fop")))
13217 (set_attr "mode" "XF")])
13219 (define_insn "*fop_xf_1_i387"
13220 [(set (match_operand:XF 0 "register_operand" "=f,f")
13221 (match_operator:XF 3 "binary_fp_operator"
13222 [(match_operand:XF 1 "register_operand" "0,f")
13223 (match_operand:XF 2 "register_operand" "f,0")]))]
13225 && !COMMUTATIVE_ARITH_P (operands[3])"
13226 "* return output_387_binary_op (insn, operands);"
13227 [(set (attr "type")
13228 (cond [(match_operand:XF 3 "mult_operator")
13229 (const_string "fmul")
13230 (match_operand:XF 3 "div_operator")
13231 (const_string "fdiv")
13233 (const_string "fop")))
13234 (set_attr "mode" "XF")])
13236 (define_insn "*fop_xf_2_i387"
13237 [(set (match_operand:XF 0 "register_operand" "=f,f")
13238 (match_operator:XF 3 "binary_fp_operator"
13240 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13241 (match_operand:XF 2 "register_operand" "0,0")]))]
13242 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13243 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13244 [(set (attr "type")
13245 (cond [(match_operand:XF 3 "mult_operator")
13246 (const_string "fmul")
13247 (match_operand:XF 3 "div_operator")
13248 (const_string "fdiv")
13250 (const_string "fop")))
13251 (set_attr "fp_int_src" "true")
13252 (set_attr "mode" "<MODE>")])
13254 (define_insn "*fop_xf_3_i387"
13255 [(set (match_operand:XF 0 "register_operand" "=f,f")
13256 (match_operator:XF 3 "binary_fp_operator"
13257 [(match_operand:XF 1 "register_operand" "0,0")
13259 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13260 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13261 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13262 [(set (attr "type")
13263 (cond [(match_operand:XF 3 "mult_operator")
13264 (const_string "fmul")
13265 (match_operand:XF 3 "div_operator")
13266 (const_string "fdiv")
13268 (const_string "fop")))
13269 (set_attr "fp_int_src" "true")
13270 (set_attr "mode" "<MODE>")])
13272 (define_insn "*fop_xf_4_i387"
13273 [(set (match_operand:XF 0 "register_operand" "=f,f")
13274 (match_operator:XF 3 "binary_fp_operator"
13276 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13277 (match_operand:XF 2 "register_operand" "0,f")]))]
13279 "* return output_387_binary_op (insn, operands);"
13280 [(set (attr "type")
13281 (cond [(match_operand:XF 3 "mult_operator")
13282 (const_string "fmul")
13283 (match_operand:XF 3 "div_operator")
13284 (const_string "fdiv")
13286 (const_string "fop")))
13287 (set_attr "mode" "<MODE>")])
13289 (define_insn "*fop_xf_5_i387"
13290 [(set (match_operand:XF 0 "register_operand" "=f,f")
13291 (match_operator:XF 3 "binary_fp_operator"
13292 [(match_operand:XF 1 "register_operand" "0,f")
13294 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13296 "* return output_387_binary_op (insn, operands);"
13297 [(set (attr "type")
13298 (cond [(match_operand:XF 3 "mult_operator")
13299 (const_string "fmul")
13300 (match_operand:XF 3 "div_operator")
13301 (const_string "fdiv")
13303 (const_string "fop")))
13304 (set_attr "mode" "<MODE>")])
13306 (define_insn "*fop_xf_6_i387"
13307 [(set (match_operand:XF 0 "register_operand" "=f,f")
13308 (match_operator:XF 3 "binary_fp_operator"
13310 (match_operand:MODEF 1 "register_operand" "0,f"))
13312 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13314 "* return output_387_binary_op (insn, operands);"
13315 [(set (attr "type")
13316 (cond [(match_operand:XF 3 "mult_operator")
13317 (const_string "fmul")
13318 (match_operand:XF 3 "div_operator")
13319 (const_string "fdiv")
13321 (const_string "fop")))
13322 (set_attr "mode" "<MODE>")])
13325 [(set (match_operand 0 "register_operand")
13326 (match_operator 3 "binary_fp_operator"
13327 [(float (match_operand:SWI24 1 "register_operand"))
13328 (match_operand 2 "register_operand")]))]
13330 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13331 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13334 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13335 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13336 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13337 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13338 GET_MODE (operands[3]),
13341 ix86_free_from_memory (GET_MODE (operands[1]));
13346 [(set (match_operand 0 "register_operand")
13347 (match_operator 3 "binary_fp_operator"
13348 [(match_operand 1 "register_operand")
13349 (float (match_operand:SWI24 2 "register_operand"))]))]
13351 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13352 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13355 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13356 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13357 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13358 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13359 GET_MODE (operands[3]),
13362 ix86_free_from_memory (GET_MODE (operands[2]));
13366 ;; FPU special functions.
13368 ;; This pattern implements a no-op XFmode truncation for
13369 ;; all fancy i386 XFmode math functions.
13371 (define_insn "truncxf<mode>2_i387_noop_unspec"
13372 [(set (match_operand:MODEF 0 "register_operand" "=f")
13373 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13374 UNSPEC_TRUNC_NOOP))]
13375 "TARGET_USE_FANCY_MATH_387"
13376 "* return output_387_reg_move (insn, operands);"
13377 [(set_attr "type" "fmov")
13378 (set_attr "mode" "<MODE>")])
13380 (define_insn "sqrtxf2"
13381 [(set (match_operand:XF 0 "register_operand" "=f")
13382 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13383 "TARGET_USE_FANCY_MATH_387"
13385 [(set_attr "type" "fpspc")
13386 (set_attr "mode" "XF")
13387 (set_attr "athlon_decode" "direct")
13388 (set_attr "amdfam10_decode" "direct")
13389 (set_attr "bdver1_decode" "direct")])
13391 (define_insn "sqrt_extend<mode>xf2_i387"
13392 [(set (match_operand:XF 0 "register_operand" "=f")
13395 (match_operand:MODEF 1 "register_operand" "0"))))]
13396 "TARGET_USE_FANCY_MATH_387"
13398 [(set_attr "type" "fpspc")
13399 (set_attr "mode" "XF")
13400 (set_attr "athlon_decode" "direct")
13401 (set_attr "amdfam10_decode" "direct")
13402 (set_attr "bdver1_decode" "direct")])
13404 (define_insn "*rsqrtsf2_sse"
13405 [(set (match_operand:SF 0 "register_operand" "=x")
13406 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13409 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13410 [(set_attr "type" "sse")
13411 (set_attr "atom_sse_attr" "rcp")
13412 (set_attr "prefix" "maybe_vex")
13413 (set_attr "mode" "SF")])
13415 (define_expand "rsqrtsf2"
13416 [(set (match_operand:SF 0 "register_operand")
13417 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand")]
13421 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13425 (define_insn "*sqrt<mode>2_sse"
13426 [(set (match_operand:MODEF 0 "register_operand" "=x")
13428 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13429 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13430 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13431 [(set_attr "type" "sse")
13432 (set_attr "atom_sse_attr" "sqrt")
13433 (set_attr "prefix" "maybe_vex")
13434 (set_attr "mode" "<MODE>")
13435 (set_attr "athlon_decode" "*")
13436 (set_attr "amdfam10_decode" "*")
13437 (set_attr "bdver1_decode" "*")])
13439 (define_expand "sqrt<mode>2"
13440 [(set (match_operand:MODEF 0 "register_operand")
13442 (match_operand:MODEF 1 "nonimmediate_operand")))]
13443 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13444 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13446 if (<MODE>mode == SFmode
13448 && TARGET_RECIP_SQRT
13449 && !optimize_function_for_size_p (cfun)
13450 && flag_finite_math_only && !flag_trapping_math
13451 && flag_unsafe_math_optimizations)
13453 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13457 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13459 rtx op0 = gen_reg_rtx (XFmode);
13460 rtx op1 = force_reg (<MODE>mode, operands[1]);
13462 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13463 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13468 (define_insn "fpremxf4_i387"
13469 [(set (match_operand:XF 0 "register_operand" "=f")
13470 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13471 (match_operand:XF 3 "register_operand" "1")]
13473 (set (match_operand:XF 1 "register_operand" "=u")
13474 (unspec:XF [(match_dup 2) (match_dup 3)]
13476 (set (reg:CCFP FPSR_REG)
13477 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13479 "TARGET_USE_FANCY_MATH_387"
13481 [(set_attr "type" "fpspc")
13482 (set_attr "mode" "XF")])
13484 (define_expand "fmodxf3"
13485 [(use (match_operand:XF 0 "register_operand"))
13486 (use (match_operand:XF 1 "general_operand"))
13487 (use (match_operand:XF 2 "general_operand"))]
13488 "TARGET_USE_FANCY_MATH_387"
13490 rtx label = gen_label_rtx ();
13492 rtx op1 = gen_reg_rtx (XFmode);
13493 rtx op2 = gen_reg_rtx (XFmode);
13495 emit_move_insn (op2, operands[2]);
13496 emit_move_insn (op1, operands[1]);
13498 emit_label (label);
13499 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13500 ix86_emit_fp_unordered_jump (label);
13501 LABEL_NUSES (label) = 1;
13503 emit_move_insn (operands[0], op1);
13507 (define_expand "fmod<mode>3"
13508 [(use (match_operand:MODEF 0 "register_operand"))
13509 (use (match_operand:MODEF 1 "general_operand"))
13510 (use (match_operand:MODEF 2 "general_operand"))]
13511 "TARGET_USE_FANCY_MATH_387"
13513 rtx (*gen_truncxf) (rtx, rtx);
13515 rtx label = gen_label_rtx ();
13517 rtx op1 = gen_reg_rtx (XFmode);
13518 rtx op2 = gen_reg_rtx (XFmode);
13520 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13521 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13523 emit_label (label);
13524 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13525 ix86_emit_fp_unordered_jump (label);
13526 LABEL_NUSES (label) = 1;
13528 /* Truncate the result properly for strict SSE math. */
13529 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13530 && !TARGET_MIX_SSE_I387)
13531 gen_truncxf = gen_truncxf<mode>2;
13533 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13535 emit_insn (gen_truncxf (operands[0], op1));
13539 (define_insn "fprem1xf4_i387"
13540 [(set (match_operand:XF 0 "register_operand" "=f")
13541 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13542 (match_operand:XF 3 "register_operand" "1")]
13544 (set (match_operand:XF 1 "register_operand" "=u")
13545 (unspec:XF [(match_dup 2) (match_dup 3)]
13547 (set (reg:CCFP FPSR_REG)
13548 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13550 "TARGET_USE_FANCY_MATH_387"
13552 [(set_attr "type" "fpspc")
13553 (set_attr "mode" "XF")])
13555 (define_expand "remainderxf3"
13556 [(use (match_operand:XF 0 "register_operand"))
13557 (use (match_operand:XF 1 "general_operand"))
13558 (use (match_operand:XF 2 "general_operand"))]
13559 "TARGET_USE_FANCY_MATH_387"
13561 rtx label = gen_label_rtx ();
13563 rtx op1 = gen_reg_rtx (XFmode);
13564 rtx op2 = gen_reg_rtx (XFmode);
13566 emit_move_insn (op2, operands[2]);
13567 emit_move_insn (op1, operands[1]);
13569 emit_label (label);
13570 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13571 ix86_emit_fp_unordered_jump (label);
13572 LABEL_NUSES (label) = 1;
13574 emit_move_insn (operands[0], op1);
13578 (define_expand "remainder<mode>3"
13579 [(use (match_operand:MODEF 0 "register_operand"))
13580 (use (match_operand:MODEF 1 "general_operand"))
13581 (use (match_operand:MODEF 2 "general_operand"))]
13582 "TARGET_USE_FANCY_MATH_387"
13584 rtx (*gen_truncxf) (rtx, rtx);
13586 rtx label = gen_label_rtx ();
13588 rtx op1 = gen_reg_rtx (XFmode);
13589 rtx op2 = gen_reg_rtx (XFmode);
13591 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13592 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13594 emit_label (label);
13596 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13597 ix86_emit_fp_unordered_jump (label);
13598 LABEL_NUSES (label) = 1;
13600 /* Truncate the result properly for strict SSE math. */
13601 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13602 && !TARGET_MIX_SSE_I387)
13603 gen_truncxf = gen_truncxf<mode>2;
13605 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13607 emit_insn (gen_truncxf (operands[0], op1));
13611 (define_insn "*sinxf2_i387"
13612 [(set (match_operand:XF 0 "register_operand" "=f")
13613 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13614 "TARGET_USE_FANCY_MATH_387
13615 && flag_unsafe_math_optimizations"
13617 [(set_attr "type" "fpspc")
13618 (set_attr "mode" "XF")])
13620 (define_insn "*sin_extend<mode>xf2_i387"
13621 [(set (match_operand:XF 0 "register_operand" "=f")
13622 (unspec:XF [(float_extend:XF
13623 (match_operand:MODEF 1 "register_operand" "0"))]
13625 "TARGET_USE_FANCY_MATH_387
13626 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13627 || TARGET_MIX_SSE_I387)
13628 && flag_unsafe_math_optimizations"
13630 [(set_attr "type" "fpspc")
13631 (set_attr "mode" "XF")])
13633 (define_insn "*cosxf2_i387"
13634 [(set (match_operand:XF 0 "register_operand" "=f")
13635 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13636 "TARGET_USE_FANCY_MATH_387
13637 && flag_unsafe_math_optimizations"
13639 [(set_attr "type" "fpspc")
13640 (set_attr "mode" "XF")])
13642 (define_insn "*cos_extend<mode>xf2_i387"
13643 [(set (match_operand:XF 0 "register_operand" "=f")
13644 (unspec:XF [(float_extend:XF
13645 (match_operand:MODEF 1 "register_operand" "0"))]
13647 "TARGET_USE_FANCY_MATH_387
13648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13649 || TARGET_MIX_SSE_I387)
13650 && flag_unsafe_math_optimizations"
13652 [(set_attr "type" "fpspc")
13653 (set_attr "mode" "XF")])
13655 ;; When sincos pattern is defined, sin and cos builtin functions will be
13656 ;; expanded to sincos pattern with one of its outputs left unused.
13657 ;; CSE pass will figure out if two sincos patterns can be combined,
13658 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13659 ;; depending on the unused output.
13661 (define_insn "sincosxf3"
13662 [(set (match_operand:XF 0 "register_operand" "=f")
13663 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13664 UNSPEC_SINCOS_COS))
13665 (set (match_operand:XF 1 "register_operand" "=u")
13666 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13667 "TARGET_USE_FANCY_MATH_387
13668 && flag_unsafe_math_optimizations"
13670 [(set_attr "type" "fpspc")
13671 (set_attr "mode" "XF")])
13674 [(set (match_operand:XF 0 "register_operand")
13675 (unspec:XF [(match_operand:XF 2 "register_operand")]
13676 UNSPEC_SINCOS_COS))
13677 (set (match_operand:XF 1 "register_operand")
13678 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13679 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13680 && can_create_pseudo_p ()"
13681 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13684 [(set (match_operand:XF 0 "register_operand")
13685 (unspec:XF [(match_operand:XF 2 "register_operand")]
13686 UNSPEC_SINCOS_COS))
13687 (set (match_operand:XF 1 "register_operand")
13688 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13689 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13690 && can_create_pseudo_p ()"
13691 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13693 (define_insn "sincos_extend<mode>xf3_i387"
13694 [(set (match_operand:XF 0 "register_operand" "=f")
13695 (unspec:XF [(float_extend:XF
13696 (match_operand:MODEF 2 "register_operand" "0"))]
13697 UNSPEC_SINCOS_COS))
13698 (set (match_operand:XF 1 "register_operand" "=u")
13699 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13700 "TARGET_USE_FANCY_MATH_387
13701 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13702 || TARGET_MIX_SSE_I387)
13703 && flag_unsafe_math_optimizations"
13705 [(set_attr "type" "fpspc")
13706 (set_attr "mode" "XF")])
13709 [(set (match_operand:XF 0 "register_operand")
13710 (unspec:XF [(float_extend:XF
13711 (match_operand:MODEF 2 "register_operand"))]
13712 UNSPEC_SINCOS_COS))
13713 (set (match_operand:XF 1 "register_operand")
13714 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13715 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13716 && can_create_pseudo_p ()"
13717 [(set (match_dup 1)
13718 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13721 [(set (match_operand:XF 0 "register_operand")
13722 (unspec:XF [(float_extend:XF
13723 (match_operand:MODEF 2 "register_operand"))]
13724 UNSPEC_SINCOS_COS))
13725 (set (match_operand:XF 1 "register_operand")
13726 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13727 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13728 && can_create_pseudo_p ()"
13729 [(set (match_dup 0)
13730 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13732 (define_expand "sincos<mode>3"
13733 [(use (match_operand:MODEF 0 "register_operand"))
13734 (use (match_operand:MODEF 1 "register_operand"))
13735 (use (match_operand:MODEF 2 "register_operand"))]
13736 "TARGET_USE_FANCY_MATH_387
13737 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13738 || TARGET_MIX_SSE_I387)
13739 && flag_unsafe_math_optimizations"
13741 rtx op0 = gen_reg_rtx (XFmode);
13742 rtx op1 = gen_reg_rtx (XFmode);
13744 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13745 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13746 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13750 (define_insn "fptanxf4_i387"
13751 [(set (match_operand:XF 0 "register_operand" "=f")
13752 (match_operand:XF 3 "const_double_operand" "F"))
13753 (set (match_operand:XF 1 "register_operand" "=u")
13754 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13756 "TARGET_USE_FANCY_MATH_387
13757 && flag_unsafe_math_optimizations
13758 && standard_80387_constant_p (operands[3]) == 2"
13760 [(set_attr "type" "fpspc")
13761 (set_attr "mode" "XF")])
13763 (define_insn "fptan_extend<mode>xf4_i387"
13764 [(set (match_operand:MODEF 0 "register_operand" "=f")
13765 (match_operand:MODEF 3 "const_double_operand" "F"))
13766 (set (match_operand:XF 1 "register_operand" "=u")
13767 (unspec:XF [(float_extend:XF
13768 (match_operand:MODEF 2 "register_operand" "0"))]
13770 "TARGET_USE_FANCY_MATH_387
13771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13772 || TARGET_MIX_SSE_I387)
13773 && flag_unsafe_math_optimizations
13774 && standard_80387_constant_p (operands[3]) == 2"
13776 [(set_attr "type" "fpspc")
13777 (set_attr "mode" "XF")])
13779 (define_expand "tanxf2"
13780 [(use (match_operand:XF 0 "register_operand"))
13781 (use (match_operand:XF 1 "register_operand"))]
13782 "TARGET_USE_FANCY_MATH_387
13783 && flag_unsafe_math_optimizations"
13785 rtx one = gen_reg_rtx (XFmode);
13786 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13788 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13792 (define_expand "tan<mode>2"
13793 [(use (match_operand:MODEF 0 "register_operand"))
13794 (use (match_operand:MODEF 1 "register_operand"))]
13795 "TARGET_USE_FANCY_MATH_387
13796 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13797 || TARGET_MIX_SSE_I387)
13798 && flag_unsafe_math_optimizations"
13800 rtx op0 = gen_reg_rtx (XFmode);
13802 rtx one = gen_reg_rtx (<MODE>mode);
13803 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13805 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13806 operands[1], op2));
13807 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13811 (define_insn "*fpatanxf3_i387"
13812 [(set (match_operand:XF 0 "register_operand" "=f")
13813 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13814 (match_operand:XF 2 "register_operand" "u")]
13816 (clobber (match_scratch:XF 3 "=2"))]
13817 "TARGET_USE_FANCY_MATH_387
13818 && flag_unsafe_math_optimizations"
13820 [(set_attr "type" "fpspc")
13821 (set_attr "mode" "XF")])
13823 (define_insn "fpatan_extend<mode>xf3_i387"
13824 [(set (match_operand:XF 0 "register_operand" "=f")
13825 (unspec:XF [(float_extend:XF
13826 (match_operand:MODEF 1 "register_operand" "0"))
13828 (match_operand:MODEF 2 "register_operand" "u"))]
13830 (clobber (match_scratch:XF 3 "=2"))]
13831 "TARGET_USE_FANCY_MATH_387
13832 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13833 || TARGET_MIX_SSE_I387)
13834 && flag_unsafe_math_optimizations"
13836 [(set_attr "type" "fpspc")
13837 (set_attr "mode" "XF")])
13839 (define_expand "atan2xf3"
13840 [(parallel [(set (match_operand:XF 0 "register_operand")
13841 (unspec:XF [(match_operand:XF 2 "register_operand")
13842 (match_operand:XF 1 "register_operand")]
13844 (clobber (match_scratch:XF 3))])]
13845 "TARGET_USE_FANCY_MATH_387
13846 && flag_unsafe_math_optimizations")
13848 (define_expand "atan2<mode>3"
13849 [(use (match_operand:MODEF 0 "register_operand"))
13850 (use (match_operand:MODEF 1 "register_operand"))
13851 (use (match_operand:MODEF 2 "register_operand"))]
13852 "TARGET_USE_FANCY_MATH_387
13853 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13854 || TARGET_MIX_SSE_I387)
13855 && flag_unsafe_math_optimizations"
13857 rtx op0 = gen_reg_rtx (XFmode);
13859 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13860 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13864 (define_expand "atanxf2"
13865 [(parallel [(set (match_operand:XF 0 "register_operand")
13866 (unspec:XF [(match_dup 2)
13867 (match_operand:XF 1 "register_operand")]
13869 (clobber (match_scratch:XF 3))])]
13870 "TARGET_USE_FANCY_MATH_387
13871 && flag_unsafe_math_optimizations"
13873 operands[2] = gen_reg_rtx (XFmode);
13874 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13877 (define_expand "atan<mode>2"
13878 [(use (match_operand:MODEF 0 "register_operand"))
13879 (use (match_operand:MODEF 1 "register_operand"))]
13880 "TARGET_USE_FANCY_MATH_387
13881 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13882 || TARGET_MIX_SSE_I387)
13883 && flag_unsafe_math_optimizations"
13885 rtx op0 = gen_reg_rtx (XFmode);
13887 rtx op2 = gen_reg_rtx (<MODE>mode);
13888 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13890 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13891 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13895 (define_expand "asinxf2"
13896 [(set (match_dup 2)
13897 (mult:XF (match_operand:XF 1 "register_operand")
13899 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13900 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13901 (parallel [(set (match_operand:XF 0 "register_operand")
13902 (unspec:XF [(match_dup 5) (match_dup 1)]
13904 (clobber (match_scratch:XF 6))])]
13905 "TARGET_USE_FANCY_MATH_387
13906 && flag_unsafe_math_optimizations"
13910 if (optimize_insn_for_size_p ())
13913 for (i = 2; i < 6; i++)
13914 operands[i] = gen_reg_rtx (XFmode);
13916 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13919 (define_expand "asin<mode>2"
13920 [(use (match_operand:MODEF 0 "register_operand"))
13921 (use (match_operand:MODEF 1 "general_operand"))]
13922 "TARGET_USE_FANCY_MATH_387
13923 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13924 || TARGET_MIX_SSE_I387)
13925 && flag_unsafe_math_optimizations"
13927 rtx op0 = gen_reg_rtx (XFmode);
13928 rtx op1 = gen_reg_rtx (XFmode);
13930 if (optimize_insn_for_size_p ())
13933 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13934 emit_insn (gen_asinxf2 (op0, op1));
13935 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13939 (define_expand "acosxf2"
13940 [(set (match_dup 2)
13941 (mult:XF (match_operand:XF 1 "register_operand")
13943 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13944 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13945 (parallel [(set (match_operand:XF 0 "register_operand")
13946 (unspec:XF [(match_dup 1) (match_dup 5)]
13948 (clobber (match_scratch:XF 6))])]
13949 "TARGET_USE_FANCY_MATH_387
13950 && flag_unsafe_math_optimizations"
13954 if (optimize_insn_for_size_p ())
13957 for (i = 2; i < 6; i++)
13958 operands[i] = gen_reg_rtx (XFmode);
13960 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13963 (define_expand "acos<mode>2"
13964 [(use (match_operand:MODEF 0 "register_operand"))
13965 (use (match_operand:MODEF 1 "general_operand"))]
13966 "TARGET_USE_FANCY_MATH_387
13967 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13968 || TARGET_MIX_SSE_I387)
13969 && flag_unsafe_math_optimizations"
13971 rtx op0 = gen_reg_rtx (XFmode);
13972 rtx op1 = gen_reg_rtx (XFmode);
13974 if (optimize_insn_for_size_p ())
13977 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13978 emit_insn (gen_acosxf2 (op0, op1));
13979 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13983 (define_insn "fyl2xxf3_i387"
13984 [(set (match_operand:XF 0 "register_operand" "=f")
13985 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13986 (match_operand:XF 2 "register_operand" "u")]
13988 (clobber (match_scratch:XF 3 "=2"))]
13989 "TARGET_USE_FANCY_MATH_387
13990 && flag_unsafe_math_optimizations"
13992 [(set_attr "type" "fpspc")
13993 (set_attr "mode" "XF")])
13995 (define_insn "fyl2x_extend<mode>xf3_i387"
13996 [(set (match_operand:XF 0 "register_operand" "=f")
13997 (unspec:XF [(float_extend:XF
13998 (match_operand:MODEF 1 "register_operand" "0"))
13999 (match_operand:XF 2 "register_operand" "u")]
14001 (clobber (match_scratch:XF 3 "=2"))]
14002 "TARGET_USE_FANCY_MATH_387
14003 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14004 || TARGET_MIX_SSE_I387)
14005 && flag_unsafe_math_optimizations"
14007 [(set_attr "type" "fpspc")
14008 (set_attr "mode" "XF")])
14010 (define_expand "logxf2"
14011 [(parallel [(set (match_operand:XF 0 "register_operand")
14012 (unspec:XF [(match_operand:XF 1 "register_operand")
14013 (match_dup 2)] UNSPEC_FYL2X))
14014 (clobber (match_scratch:XF 3))])]
14015 "TARGET_USE_FANCY_MATH_387
14016 && flag_unsafe_math_optimizations"
14018 operands[2] = gen_reg_rtx (XFmode);
14019 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14022 (define_expand "log<mode>2"
14023 [(use (match_operand:MODEF 0 "register_operand"))
14024 (use (match_operand:MODEF 1 "register_operand"))]
14025 "TARGET_USE_FANCY_MATH_387
14026 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14027 || TARGET_MIX_SSE_I387)
14028 && flag_unsafe_math_optimizations"
14030 rtx op0 = gen_reg_rtx (XFmode);
14032 rtx op2 = gen_reg_rtx (XFmode);
14033 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14035 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14036 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14040 (define_expand "log10xf2"
14041 [(parallel [(set (match_operand:XF 0 "register_operand")
14042 (unspec:XF [(match_operand:XF 1 "register_operand")
14043 (match_dup 2)] UNSPEC_FYL2X))
14044 (clobber (match_scratch:XF 3))])]
14045 "TARGET_USE_FANCY_MATH_387
14046 && flag_unsafe_math_optimizations"
14048 operands[2] = gen_reg_rtx (XFmode);
14049 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14052 (define_expand "log10<mode>2"
14053 [(use (match_operand:MODEF 0 "register_operand"))
14054 (use (match_operand:MODEF 1 "register_operand"))]
14055 "TARGET_USE_FANCY_MATH_387
14056 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14057 || TARGET_MIX_SSE_I387)
14058 && flag_unsafe_math_optimizations"
14060 rtx op0 = gen_reg_rtx (XFmode);
14062 rtx op2 = gen_reg_rtx (XFmode);
14063 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14065 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14066 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14070 (define_expand "log2xf2"
14071 [(parallel [(set (match_operand:XF 0 "register_operand")
14072 (unspec:XF [(match_operand:XF 1 "register_operand")
14073 (match_dup 2)] UNSPEC_FYL2X))
14074 (clobber (match_scratch:XF 3))])]
14075 "TARGET_USE_FANCY_MATH_387
14076 && flag_unsafe_math_optimizations"
14078 operands[2] = gen_reg_rtx (XFmode);
14079 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14082 (define_expand "log2<mode>2"
14083 [(use (match_operand:MODEF 0 "register_operand"))
14084 (use (match_operand:MODEF 1 "register_operand"))]
14085 "TARGET_USE_FANCY_MATH_387
14086 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14087 || TARGET_MIX_SSE_I387)
14088 && flag_unsafe_math_optimizations"
14090 rtx op0 = gen_reg_rtx (XFmode);
14092 rtx op2 = gen_reg_rtx (XFmode);
14093 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14095 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14096 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14100 (define_insn "fyl2xp1xf3_i387"
14101 [(set (match_operand:XF 0 "register_operand" "=f")
14102 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14103 (match_operand:XF 2 "register_operand" "u")]
14105 (clobber (match_scratch:XF 3 "=2"))]
14106 "TARGET_USE_FANCY_MATH_387
14107 && flag_unsafe_math_optimizations"
14109 [(set_attr "type" "fpspc")
14110 (set_attr "mode" "XF")])
14112 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14113 [(set (match_operand:XF 0 "register_operand" "=f")
14114 (unspec:XF [(float_extend:XF
14115 (match_operand:MODEF 1 "register_operand" "0"))
14116 (match_operand:XF 2 "register_operand" "u")]
14118 (clobber (match_scratch:XF 3 "=2"))]
14119 "TARGET_USE_FANCY_MATH_387
14120 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14121 || TARGET_MIX_SSE_I387)
14122 && flag_unsafe_math_optimizations"
14124 [(set_attr "type" "fpspc")
14125 (set_attr "mode" "XF")])
14127 (define_expand "log1pxf2"
14128 [(use (match_operand:XF 0 "register_operand"))
14129 (use (match_operand:XF 1 "register_operand"))]
14130 "TARGET_USE_FANCY_MATH_387
14131 && flag_unsafe_math_optimizations"
14133 if (optimize_insn_for_size_p ())
14136 ix86_emit_i387_log1p (operands[0], operands[1]);
14140 (define_expand "log1p<mode>2"
14141 [(use (match_operand:MODEF 0 "register_operand"))
14142 (use (match_operand:MODEF 1 "register_operand"))]
14143 "TARGET_USE_FANCY_MATH_387
14144 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14145 || TARGET_MIX_SSE_I387)
14146 && flag_unsafe_math_optimizations"
14150 if (optimize_insn_for_size_p ())
14153 op0 = gen_reg_rtx (XFmode);
14155 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14157 ix86_emit_i387_log1p (op0, operands[1]);
14158 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14162 (define_insn "fxtractxf3_i387"
14163 [(set (match_operand:XF 0 "register_operand" "=f")
14164 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14165 UNSPEC_XTRACT_FRACT))
14166 (set (match_operand:XF 1 "register_operand" "=u")
14167 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14168 "TARGET_USE_FANCY_MATH_387
14169 && flag_unsafe_math_optimizations"
14171 [(set_attr "type" "fpspc")
14172 (set_attr "mode" "XF")])
14174 (define_insn "fxtract_extend<mode>xf3_i387"
14175 [(set (match_operand:XF 0 "register_operand" "=f")
14176 (unspec:XF [(float_extend:XF
14177 (match_operand:MODEF 2 "register_operand" "0"))]
14178 UNSPEC_XTRACT_FRACT))
14179 (set (match_operand:XF 1 "register_operand" "=u")
14180 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
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 [(set_attr "type" "fpspc")
14187 (set_attr "mode" "XF")])
14189 (define_expand "logbxf2"
14190 [(parallel [(set (match_dup 2)
14191 (unspec:XF [(match_operand:XF 1 "register_operand")]
14192 UNSPEC_XTRACT_FRACT))
14193 (set (match_operand:XF 0 "register_operand")
14194 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14195 "TARGET_USE_FANCY_MATH_387
14196 && flag_unsafe_math_optimizations"
14197 "operands[2] = gen_reg_rtx (XFmode);")
14199 (define_expand "logb<mode>2"
14200 [(use (match_operand:MODEF 0 "register_operand"))
14201 (use (match_operand:MODEF 1 "register_operand"))]
14202 "TARGET_USE_FANCY_MATH_387
14203 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14204 || TARGET_MIX_SSE_I387)
14205 && flag_unsafe_math_optimizations"
14207 rtx op0 = gen_reg_rtx (XFmode);
14208 rtx op1 = gen_reg_rtx (XFmode);
14210 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14211 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14215 (define_expand "ilogbxf2"
14216 [(use (match_operand:SI 0 "register_operand"))
14217 (use (match_operand:XF 1 "register_operand"))]
14218 "TARGET_USE_FANCY_MATH_387
14219 && flag_unsafe_math_optimizations"
14223 if (optimize_insn_for_size_p ())
14226 op0 = gen_reg_rtx (XFmode);
14227 op1 = gen_reg_rtx (XFmode);
14229 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14230 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14234 (define_expand "ilogb<mode>2"
14235 [(use (match_operand:SI 0 "register_operand"))
14236 (use (match_operand:MODEF 1 "register_operand"))]
14237 "TARGET_USE_FANCY_MATH_387
14238 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14239 || TARGET_MIX_SSE_I387)
14240 && flag_unsafe_math_optimizations"
14244 if (optimize_insn_for_size_p ())
14247 op0 = gen_reg_rtx (XFmode);
14248 op1 = gen_reg_rtx (XFmode);
14250 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14251 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14255 (define_insn "*f2xm1xf2_i387"
14256 [(set (match_operand:XF 0 "register_operand" "=f")
14257 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14259 "TARGET_USE_FANCY_MATH_387
14260 && flag_unsafe_math_optimizations"
14262 [(set_attr "type" "fpspc")
14263 (set_attr "mode" "XF")])
14265 (define_insn "*fscalexf4_i387"
14266 [(set (match_operand:XF 0 "register_operand" "=f")
14267 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14268 (match_operand:XF 3 "register_operand" "1")]
14269 UNSPEC_FSCALE_FRACT))
14270 (set (match_operand:XF 1 "register_operand" "=u")
14271 (unspec:XF [(match_dup 2) (match_dup 3)]
14272 UNSPEC_FSCALE_EXP))]
14273 "TARGET_USE_FANCY_MATH_387
14274 && flag_unsafe_math_optimizations"
14276 [(set_attr "type" "fpspc")
14277 (set_attr "mode" "XF")])
14279 (define_expand "expNcorexf3"
14280 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14281 (match_operand:XF 2 "register_operand")))
14282 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14283 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14284 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14285 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14286 (parallel [(set (match_operand:XF 0 "register_operand")
14287 (unspec:XF [(match_dup 8) (match_dup 4)]
14288 UNSPEC_FSCALE_FRACT))
14290 (unspec:XF [(match_dup 8) (match_dup 4)]
14291 UNSPEC_FSCALE_EXP))])]
14292 "TARGET_USE_FANCY_MATH_387
14293 && flag_unsafe_math_optimizations"
14297 if (optimize_insn_for_size_p ())
14300 for (i = 3; i < 10; i++)
14301 operands[i] = gen_reg_rtx (XFmode);
14303 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14306 (define_expand "expxf2"
14307 [(use (match_operand:XF 0 "register_operand"))
14308 (use (match_operand:XF 1 "register_operand"))]
14309 "TARGET_USE_FANCY_MATH_387
14310 && flag_unsafe_math_optimizations"
14314 if (optimize_insn_for_size_p ())
14317 op2 = gen_reg_rtx (XFmode);
14318 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14320 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14324 (define_expand "exp<mode>2"
14325 [(use (match_operand:MODEF 0 "register_operand"))
14326 (use (match_operand:MODEF 1 "general_operand"))]
14327 "TARGET_USE_FANCY_MATH_387
14328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14329 || TARGET_MIX_SSE_I387)
14330 && flag_unsafe_math_optimizations"
14334 if (optimize_insn_for_size_p ())
14337 op0 = gen_reg_rtx (XFmode);
14338 op1 = gen_reg_rtx (XFmode);
14340 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14341 emit_insn (gen_expxf2 (op0, op1));
14342 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14346 (define_expand "exp10xf2"
14347 [(use (match_operand:XF 0 "register_operand"))
14348 (use (match_operand:XF 1 "register_operand"))]
14349 "TARGET_USE_FANCY_MATH_387
14350 && flag_unsafe_math_optimizations"
14354 if (optimize_insn_for_size_p ())
14357 op2 = gen_reg_rtx (XFmode);
14358 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14360 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14364 (define_expand "exp10<mode>2"
14365 [(use (match_operand:MODEF 0 "register_operand"))
14366 (use (match_operand:MODEF 1 "general_operand"))]
14367 "TARGET_USE_FANCY_MATH_387
14368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14369 || TARGET_MIX_SSE_I387)
14370 && flag_unsafe_math_optimizations"
14374 if (optimize_insn_for_size_p ())
14377 op0 = gen_reg_rtx (XFmode);
14378 op1 = gen_reg_rtx (XFmode);
14380 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14381 emit_insn (gen_exp10xf2 (op0, op1));
14382 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14386 (define_expand "exp2xf2"
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"
14394 if (optimize_insn_for_size_p ())
14397 op2 = gen_reg_rtx (XFmode);
14398 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14400 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14404 (define_expand "exp2<mode>2"
14405 [(use (match_operand:MODEF 0 "register_operand"))
14406 (use (match_operand:MODEF 1 "general_operand"))]
14407 "TARGET_USE_FANCY_MATH_387
14408 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14409 || TARGET_MIX_SSE_I387)
14410 && flag_unsafe_math_optimizations"
14414 if (optimize_insn_for_size_p ())
14417 op0 = gen_reg_rtx (XFmode);
14418 op1 = gen_reg_rtx (XFmode);
14420 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14421 emit_insn (gen_exp2xf2 (op0, op1));
14422 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14426 (define_expand "expm1xf2"
14427 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand")
14429 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14430 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14431 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14432 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14433 (parallel [(set (match_dup 7)
14434 (unspec:XF [(match_dup 6) (match_dup 4)]
14435 UNSPEC_FSCALE_FRACT))
14437 (unspec:XF [(match_dup 6) (match_dup 4)]
14438 UNSPEC_FSCALE_EXP))])
14439 (parallel [(set (match_dup 10)
14440 (unspec:XF [(match_dup 9) (match_dup 8)]
14441 UNSPEC_FSCALE_FRACT))
14442 (set (match_dup 11)
14443 (unspec:XF [(match_dup 9) (match_dup 8)]
14444 UNSPEC_FSCALE_EXP))])
14445 (set (match_dup 12) (minus:XF (match_dup 10)
14446 (float_extend:XF (match_dup 13))))
14447 (set (match_operand:XF 0 "register_operand")
14448 (plus:XF (match_dup 12) (match_dup 7)))]
14449 "TARGET_USE_FANCY_MATH_387
14450 && flag_unsafe_math_optimizations"
14454 if (optimize_insn_for_size_p ())
14457 for (i = 2; i < 13; i++)
14458 operands[i] = gen_reg_rtx (XFmode);
14461 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14463 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14466 (define_expand "expm1<mode>2"
14467 [(use (match_operand:MODEF 0 "register_operand"))
14468 (use (match_operand:MODEF 1 "general_operand"))]
14469 "TARGET_USE_FANCY_MATH_387
14470 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14471 || TARGET_MIX_SSE_I387)
14472 && flag_unsafe_math_optimizations"
14476 if (optimize_insn_for_size_p ())
14479 op0 = gen_reg_rtx (XFmode);
14480 op1 = gen_reg_rtx (XFmode);
14482 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14483 emit_insn (gen_expm1xf2 (op0, op1));
14484 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14488 (define_expand "ldexpxf3"
14489 [(set (match_dup 3)
14490 (float:XF (match_operand:SI 2 "register_operand")))
14491 (parallel [(set (match_operand:XF 0 " register_operand")
14492 (unspec:XF [(match_operand:XF 1 "register_operand")
14494 UNSPEC_FSCALE_FRACT))
14496 (unspec:XF [(match_dup 1) (match_dup 3)]
14497 UNSPEC_FSCALE_EXP))])]
14498 "TARGET_USE_FANCY_MATH_387
14499 && flag_unsafe_math_optimizations"
14501 if (optimize_insn_for_size_p ())
14504 operands[3] = gen_reg_rtx (XFmode);
14505 operands[4] = gen_reg_rtx (XFmode);
14508 (define_expand "ldexp<mode>3"
14509 [(use (match_operand:MODEF 0 "register_operand"))
14510 (use (match_operand:MODEF 1 "general_operand"))
14511 (use (match_operand:SI 2 "register_operand"))]
14512 "TARGET_USE_FANCY_MATH_387
14513 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14514 || TARGET_MIX_SSE_I387)
14515 && flag_unsafe_math_optimizations"
14519 if (optimize_insn_for_size_p ())
14522 op0 = gen_reg_rtx (XFmode);
14523 op1 = gen_reg_rtx (XFmode);
14525 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14526 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14527 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14531 (define_expand "scalbxf3"
14532 [(parallel [(set (match_operand:XF 0 " register_operand")
14533 (unspec:XF [(match_operand:XF 1 "register_operand")
14534 (match_operand:XF 2 "register_operand")]
14535 UNSPEC_FSCALE_FRACT))
14537 (unspec:XF [(match_dup 1) (match_dup 2)]
14538 UNSPEC_FSCALE_EXP))])]
14539 "TARGET_USE_FANCY_MATH_387
14540 && flag_unsafe_math_optimizations"
14542 if (optimize_insn_for_size_p ())
14545 operands[3] = gen_reg_rtx (XFmode);
14548 (define_expand "scalb<mode>3"
14549 [(use (match_operand:MODEF 0 "register_operand"))
14550 (use (match_operand:MODEF 1 "general_operand"))
14551 (use (match_operand:MODEF 2 "general_operand"))]
14552 "TARGET_USE_FANCY_MATH_387
14553 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14554 || TARGET_MIX_SSE_I387)
14555 && flag_unsafe_math_optimizations"
14559 if (optimize_insn_for_size_p ())
14562 op0 = gen_reg_rtx (XFmode);
14563 op1 = gen_reg_rtx (XFmode);
14564 op2 = gen_reg_rtx (XFmode);
14566 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14567 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14568 emit_insn (gen_scalbxf3 (op0, op1, op2));
14569 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14573 (define_expand "significandxf2"
14574 [(parallel [(set (match_operand:XF 0 "register_operand")
14575 (unspec:XF [(match_operand:XF 1 "register_operand")]
14576 UNSPEC_XTRACT_FRACT))
14578 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14579 "TARGET_USE_FANCY_MATH_387
14580 && flag_unsafe_math_optimizations"
14581 "operands[2] = gen_reg_rtx (XFmode);")
14583 (define_expand "significand<mode>2"
14584 [(use (match_operand:MODEF 0 "register_operand"))
14585 (use (match_operand:MODEF 1 "register_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"
14591 rtx op0 = gen_reg_rtx (XFmode);
14592 rtx op1 = gen_reg_rtx (XFmode);
14594 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14595 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14600 (define_insn "sse4_1_round<mode>2"
14601 [(set (match_operand:MODEF 0 "register_operand" "=x")
14602 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14603 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14606 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14607 [(set_attr "type" "ssecvt")
14608 (set_attr "prefix_extra" "1")
14609 (set_attr "prefix" "maybe_vex")
14610 (set_attr "mode" "<MODE>")])
14612 (define_insn "rintxf2"
14613 [(set (match_operand:XF 0 "register_operand" "=f")
14614 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14616 "TARGET_USE_FANCY_MATH_387
14617 && flag_unsafe_math_optimizations"
14619 [(set_attr "type" "fpspc")
14620 (set_attr "mode" "XF")])
14622 (define_expand "rint<mode>2"
14623 [(use (match_operand:MODEF 0 "register_operand"))
14624 (use (match_operand:MODEF 1 "register_operand"))]
14625 "(TARGET_USE_FANCY_MATH_387
14626 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14627 || TARGET_MIX_SSE_I387)
14628 && flag_unsafe_math_optimizations)
14629 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14630 && !flag_trapping_math)"
14632 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14633 && !flag_trapping_math)
14636 emit_insn (gen_sse4_1_round<mode>2
14637 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14638 else if (optimize_insn_for_size_p ())
14641 ix86_expand_rint (operands[0], operands[1]);
14645 rtx op0 = gen_reg_rtx (XFmode);
14646 rtx op1 = gen_reg_rtx (XFmode);
14648 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14649 emit_insn (gen_rintxf2 (op0, op1));
14651 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14656 (define_expand "round<mode>2"
14657 [(match_operand:X87MODEF 0 "register_operand")
14658 (match_operand:X87MODEF 1 "nonimmediate_operand")]
14659 "(TARGET_USE_FANCY_MATH_387
14660 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14661 || TARGET_MIX_SSE_I387)
14662 && flag_unsafe_math_optimizations)
14663 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14664 && !flag_trapping_math && !flag_rounding_math)"
14666 if (optimize_insn_for_size_p ())
14669 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14670 && !flag_trapping_math && !flag_rounding_math)
14674 operands[1] = force_reg (<MODE>mode, operands[1]);
14675 ix86_expand_round_sse4 (operands[0], operands[1]);
14677 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14678 ix86_expand_round (operands[0], operands[1]);
14680 ix86_expand_rounddf_32 (operands[0], operands[1]);
14684 operands[1] = force_reg (<MODE>mode, operands[1]);
14685 ix86_emit_i387_round (operands[0], operands[1]);
14690 (define_insn_and_split "*fistdi2_1"
14691 [(set (match_operand:DI 0 "nonimmediate_operand")
14692 (unspec:DI [(match_operand:XF 1 "register_operand")]
14694 "TARGET_USE_FANCY_MATH_387
14695 && can_create_pseudo_p ()"
14700 if (memory_operand (operands[0], VOIDmode))
14701 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14704 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14705 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14710 [(set_attr "type" "fpspc")
14711 (set_attr "mode" "DI")])
14713 (define_insn "fistdi2"
14714 [(set (match_operand:DI 0 "memory_operand" "=m")
14715 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14717 (clobber (match_scratch:XF 2 "=&1f"))]
14718 "TARGET_USE_FANCY_MATH_387"
14719 "* return output_fix_trunc (insn, operands, false);"
14720 [(set_attr "type" "fpspc")
14721 (set_attr "mode" "DI")])
14723 (define_insn "fistdi2_with_temp"
14724 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14725 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14727 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14728 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14729 "TARGET_USE_FANCY_MATH_387"
14731 [(set_attr "type" "fpspc")
14732 (set_attr "mode" "DI")])
14735 [(set (match_operand:DI 0 "register_operand")
14736 (unspec:DI [(match_operand:XF 1 "register_operand")]
14738 (clobber (match_operand:DI 2 "memory_operand"))
14739 (clobber (match_scratch 3))]
14741 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14742 (clobber (match_dup 3))])
14743 (set (match_dup 0) (match_dup 2))])
14746 [(set (match_operand:DI 0 "memory_operand")
14747 (unspec:DI [(match_operand:XF 1 "register_operand")]
14749 (clobber (match_operand:DI 2 "memory_operand"))
14750 (clobber (match_scratch 3))]
14752 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14753 (clobber (match_dup 3))])])
14755 (define_insn_and_split "*fist<mode>2_1"
14756 [(set (match_operand:SWI24 0 "register_operand")
14757 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14759 "TARGET_USE_FANCY_MATH_387
14760 && can_create_pseudo_p ()"
14765 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14766 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14770 [(set_attr "type" "fpspc")
14771 (set_attr "mode" "<MODE>")])
14773 (define_insn "fist<mode>2"
14774 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14775 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14777 "TARGET_USE_FANCY_MATH_387"
14778 "* return output_fix_trunc (insn, operands, false);"
14779 [(set_attr "type" "fpspc")
14780 (set_attr "mode" "<MODE>")])
14782 (define_insn "fist<mode>2_with_temp"
14783 [(set (match_operand:SWI24 0 "register_operand" "=r")
14784 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14786 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14787 "TARGET_USE_FANCY_MATH_387"
14789 [(set_attr "type" "fpspc")
14790 (set_attr "mode" "<MODE>")])
14793 [(set (match_operand:SWI24 0 "register_operand")
14794 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14796 (clobber (match_operand:SWI24 2 "memory_operand"))]
14798 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14799 (set (match_dup 0) (match_dup 2))])
14802 [(set (match_operand:SWI24 0 "memory_operand")
14803 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
14805 (clobber (match_operand:SWI24 2 "memory_operand"))]
14807 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14809 (define_expand "lrintxf<mode>2"
14810 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14811 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14813 "TARGET_USE_FANCY_MATH_387")
14815 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14816 [(set (match_operand:SWI48x 0 "nonimmediate_operand")
14817 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand")]
14818 UNSPEC_FIX_NOTRUNC))]
14819 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14820 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14822 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14823 [(match_operand:SWI248x 0 "nonimmediate_operand")
14824 (match_operand:X87MODEF 1 "register_operand")]
14825 "(TARGET_USE_FANCY_MATH_387
14826 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14827 || TARGET_MIX_SSE_I387)
14828 && flag_unsafe_math_optimizations)
14829 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14830 && <SWI248x:MODE>mode != HImode
14831 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14832 && !flag_trapping_math && !flag_rounding_math)"
14834 if (optimize_insn_for_size_p ())
14837 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14838 && <SWI248x:MODE>mode != HImode
14839 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14840 && !flag_trapping_math && !flag_rounding_math)
14841 ix86_expand_lround (operands[0], operands[1]);
14843 ix86_emit_i387_round (operands[0], operands[1]);
14847 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14848 (define_insn_and_split "frndintxf2_floor"
14849 [(set (match_operand:XF 0 "register_operand")
14850 (unspec:XF [(match_operand:XF 1 "register_operand")]
14851 UNSPEC_FRNDINT_FLOOR))
14852 (clobber (reg:CC FLAGS_REG))]
14853 "TARGET_USE_FANCY_MATH_387
14854 && flag_unsafe_math_optimizations
14855 && can_create_pseudo_p ()"
14860 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14862 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14863 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14865 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14866 operands[2], operands[3]));
14869 [(set_attr "type" "frndint")
14870 (set_attr "i387_cw" "floor")
14871 (set_attr "mode" "XF")])
14873 (define_insn "frndintxf2_floor_i387"
14874 [(set (match_operand:XF 0 "register_operand" "=f")
14875 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14876 UNSPEC_FRNDINT_FLOOR))
14877 (use (match_operand:HI 2 "memory_operand" "m"))
14878 (use (match_operand:HI 3 "memory_operand" "m"))]
14879 "TARGET_USE_FANCY_MATH_387
14880 && flag_unsafe_math_optimizations"
14881 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14882 [(set_attr "type" "frndint")
14883 (set_attr "i387_cw" "floor")
14884 (set_attr "mode" "XF")])
14886 (define_expand "floorxf2"
14887 [(use (match_operand:XF 0 "register_operand"))
14888 (use (match_operand:XF 1 "register_operand"))]
14889 "TARGET_USE_FANCY_MATH_387
14890 && flag_unsafe_math_optimizations"
14892 if (optimize_insn_for_size_p ())
14894 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14898 (define_expand "floor<mode>2"
14899 [(use (match_operand:MODEF 0 "register_operand"))
14900 (use (match_operand:MODEF 1 "register_operand"))]
14901 "(TARGET_USE_FANCY_MATH_387
14902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14903 || TARGET_MIX_SSE_I387)
14904 && flag_unsafe_math_optimizations)
14905 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14906 && !flag_trapping_math)"
14908 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14909 && !flag_trapping_math)
14912 emit_insn (gen_sse4_1_round<mode>2
14913 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14914 else if (optimize_insn_for_size_p ())
14916 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14917 ix86_expand_floorceil (operands[0], operands[1], true);
14919 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14925 if (optimize_insn_for_size_p ())
14928 op0 = gen_reg_rtx (XFmode);
14929 op1 = gen_reg_rtx (XFmode);
14930 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14931 emit_insn (gen_frndintxf2_floor (op0, op1));
14933 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14938 (define_insn_and_split "*fist<mode>2_floor_1"
14939 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
14940 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
14941 UNSPEC_FIST_FLOOR))
14942 (clobber (reg:CC FLAGS_REG))]
14943 "TARGET_USE_FANCY_MATH_387
14944 && flag_unsafe_math_optimizations
14945 && can_create_pseudo_p ()"
14950 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14952 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14953 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14954 if (memory_operand (operands[0], VOIDmode))
14955 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14956 operands[2], operands[3]));
14959 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14960 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14961 operands[2], operands[3],
14966 [(set_attr "type" "fistp")
14967 (set_attr "i387_cw" "floor")
14968 (set_attr "mode" "<MODE>")])
14970 (define_insn "fistdi2_floor"
14971 [(set (match_operand:DI 0 "memory_operand" "=m")
14972 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14973 UNSPEC_FIST_FLOOR))
14974 (use (match_operand:HI 2 "memory_operand" "m"))
14975 (use (match_operand:HI 3 "memory_operand" "m"))
14976 (clobber (match_scratch:XF 4 "=&1f"))]
14977 "TARGET_USE_FANCY_MATH_387
14978 && flag_unsafe_math_optimizations"
14979 "* return output_fix_trunc (insn, operands, false);"
14980 [(set_attr "type" "fistp")
14981 (set_attr "i387_cw" "floor")
14982 (set_attr "mode" "DI")])
14984 (define_insn "fistdi2_floor_with_temp"
14985 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14986 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14987 UNSPEC_FIST_FLOOR))
14988 (use (match_operand:HI 2 "memory_operand" "m,m"))
14989 (use (match_operand:HI 3 "memory_operand" "m,m"))
14990 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14991 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14992 "TARGET_USE_FANCY_MATH_387
14993 && flag_unsafe_math_optimizations"
14995 [(set_attr "type" "fistp")
14996 (set_attr "i387_cw" "floor")
14997 (set_attr "mode" "DI")])
15000 [(set (match_operand:DI 0 "register_operand")
15001 (unspec:DI [(match_operand:XF 1 "register_operand")]
15002 UNSPEC_FIST_FLOOR))
15003 (use (match_operand:HI 2 "memory_operand"))
15004 (use (match_operand:HI 3 "memory_operand"))
15005 (clobber (match_operand:DI 4 "memory_operand"))
15006 (clobber (match_scratch 5))]
15008 [(parallel [(set (match_dup 4)
15009 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15010 (use (match_dup 2))
15011 (use (match_dup 3))
15012 (clobber (match_dup 5))])
15013 (set (match_dup 0) (match_dup 4))])
15016 [(set (match_operand:DI 0 "memory_operand")
15017 (unspec:DI [(match_operand:XF 1 "register_operand")]
15018 UNSPEC_FIST_FLOOR))
15019 (use (match_operand:HI 2 "memory_operand"))
15020 (use (match_operand:HI 3 "memory_operand"))
15021 (clobber (match_operand:DI 4 "memory_operand"))
15022 (clobber (match_scratch 5))]
15024 [(parallel [(set (match_dup 0)
15025 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15026 (use (match_dup 2))
15027 (use (match_dup 3))
15028 (clobber (match_dup 5))])])
15030 (define_insn "fist<mode>2_floor"
15031 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15032 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15033 UNSPEC_FIST_FLOOR))
15034 (use (match_operand:HI 2 "memory_operand" "m"))
15035 (use (match_operand:HI 3 "memory_operand" "m"))]
15036 "TARGET_USE_FANCY_MATH_387
15037 && flag_unsafe_math_optimizations"
15038 "* return output_fix_trunc (insn, operands, false);"
15039 [(set_attr "type" "fistp")
15040 (set_attr "i387_cw" "floor")
15041 (set_attr "mode" "<MODE>")])
15043 (define_insn "fist<mode>2_floor_with_temp"
15044 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15045 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15046 UNSPEC_FIST_FLOOR))
15047 (use (match_operand:HI 2 "memory_operand" "m,m"))
15048 (use (match_operand:HI 3 "memory_operand" "m,m"))
15049 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15050 "TARGET_USE_FANCY_MATH_387
15051 && flag_unsafe_math_optimizations"
15053 [(set_attr "type" "fistp")
15054 (set_attr "i387_cw" "floor")
15055 (set_attr "mode" "<MODE>")])
15058 [(set (match_operand:SWI24 0 "register_operand")
15059 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15060 UNSPEC_FIST_FLOOR))
15061 (use (match_operand:HI 2 "memory_operand"))
15062 (use (match_operand:HI 3 "memory_operand"))
15063 (clobber (match_operand:SWI24 4 "memory_operand"))]
15065 [(parallel [(set (match_dup 4)
15066 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15067 (use (match_dup 2))
15068 (use (match_dup 3))])
15069 (set (match_dup 0) (match_dup 4))])
15072 [(set (match_operand:SWI24 0 "memory_operand")
15073 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15074 UNSPEC_FIST_FLOOR))
15075 (use (match_operand:HI 2 "memory_operand"))
15076 (use (match_operand:HI 3 "memory_operand"))
15077 (clobber (match_operand:SWI24 4 "memory_operand"))]
15079 [(parallel [(set (match_dup 0)
15080 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15081 (use (match_dup 2))
15082 (use (match_dup 3))])])
15084 (define_expand "lfloorxf<mode>2"
15085 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15086 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15087 UNSPEC_FIST_FLOOR))
15088 (clobber (reg:CC FLAGS_REG))])]
15089 "TARGET_USE_FANCY_MATH_387
15090 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15091 && flag_unsafe_math_optimizations")
15093 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15094 [(match_operand:SWI48 0 "nonimmediate_operand")
15095 (match_operand:MODEF 1 "register_operand")]
15096 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15097 && !flag_trapping_math"
15099 if (TARGET_64BIT && optimize_insn_for_size_p ())
15101 ix86_expand_lfloorceil (operands[0], operands[1], true);
15105 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15106 (define_insn_and_split "frndintxf2_ceil"
15107 [(set (match_operand:XF 0 "register_operand")
15108 (unspec:XF [(match_operand:XF 1 "register_operand")]
15109 UNSPEC_FRNDINT_CEIL))
15110 (clobber (reg:CC FLAGS_REG))]
15111 "TARGET_USE_FANCY_MATH_387
15112 && flag_unsafe_math_optimizations
15113 && can_create_pseudo_p ()"
15118 ix86_optimize_mode_switching[I387_CEIL] = 1;
15120 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15121 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15123 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15124 operands[2], operands[3]));
15127 [(set_attr "type" "frndint")
15128 (set_attr "i387_cw" "ceil")
15129 (set_attr "mode" "XF")])
15131 (define_insn "frndintxf2_ceil_i387"
15132 [(set (match_operand:XF 0 "register_operand" "=f")
15133 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15134 UNSPEC_FRNDINT_CEIL))
15135 (use (match_operand:HI 2 "memory_operand" "m"))
15136 (use (match_operand:HI 3 "memory_operand" "m"))]
15137 "TARGET_USE_FANCY_MATH_387
15138 && flag_unsafe_math_optimizations"
15139 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15140 [(set_attr "type" "frndint")
15141 (set_attr "i387_cw" "ceil")
15142 (set_attr "mode" "XF")])
15144 (define_expand "ceilxf2"
15145 [(use (match_operand:XF 0 "register_operand"))
15146 (use (match_operand:XF 1 "register_operand"))]
15147 "TARGET_USE_FANCY_MATH_387
15148 && flag_unsafe_math_optimizations"
15150 if (optimize_insn_for_size_p ())
15152 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15156 (define_expand "ceil<mode>2"
15157 [(use (match_operand:MODEF 0 "register_operand"))
15158 (use (match_operand:MODEF 1 "register_operand"))]
15159 "(TARGET_USE_FANCY_MATH_387
15160 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15161 || TARGET_MIX_SSE_I387)
15162 && flag_unsafe_math_optimizations)
15163 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15164 && !flag_trapping_math)"
15166 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15167 && !flag_trapping_math)
15170 emit_insn (gen_sse4_1_round<mode>2
15171 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15172 else if (optimize_insn_for_size_p ())
15174 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15175 ix86_expand_floorceil (operands[0], operands[1], false);
15177 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15183 if (optimize_insn_for_size_p ())
15186 op0 = gen_reg_rtx (XFmode);
15187 op1 = gen_reg_rtx (XFmode);
15188 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15189 emit_insn (gen_frndintxf2_ceil (op0, op1));
15191 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15196 (define_insn_and_split "*fist<mode>2_ceil_1"
15197 [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15198 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15200 (clobber (reg:CC FLAGS_REG))]
15201 "TARGET_USE_FANCY_MATH_387
15202 && flag_unsafe_math_optimizations
15203 && can_create_pseudo_p ()"
15208 ix86_optimize_mode_switching[I387_CEIL] = 1;
15210 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15211 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15212 if (memory_operand (operands[0], VOIDmode))
15213 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15214 operands[2], operands[3]));
15217 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15218 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15219 operands[2], operands[3],
15224 [(set_attr "type" "fistp")
15225 (set_attr "i387_cw" "ceil")
15226 (set_attr "mode" "<MODE>")])
15228 (define_insn "fistdi2_ceil"
15229 [(set (match_operand:DI 0 "memory_operand" "=m")
15230 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15232 (use (match_operand:HI 2 "memory_operand" "m"))
15233 (use (match_operand:HI 3 "memory_operand" "m"))
15234 (clobber (match_scratch:XF 4 "=&1f"))]
15235 "TARGET_USE_FANCY_MATH_387
15236 && flag_unsafe_math_optimizations"
15237 "* return output_fix_trunc (insn, operands, false);"
15238 [(set_attr "type" "fistp")
15239 (set_attr "i387_cw" "ceil")
15240 (set_attr "mode" "DI")])
15242 (define_insn "fistdi2_ceil_with_temp"
15243 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15244 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15246 (use (match_operand:HI 2 "memory_operand" "m,m"))
15247 (use (match_operand:HI 3 "memory_operand" "m,m"))
15248 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15249 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15250 "TARGET_USE_FANCY_MATH_387
15251 && flag_unsafe_math_optimizations"
15253 [(set_attr "type" "fistp")
15254 (set_attr "i387_cw" "ceil")
15255 (set_attr "mode" "DI")])
15258 [(set (match_operand:DI 0 "register_operand")
15259 (unspec:DI [(match_operand:XF 1 "register_operand")]
15261 (use (match_operand:HI 2 "memory_operand"))
15262 (use (match_operand:HI 3 "memory_operand"))
15263 (clobber (match_operand:DI 4 "memory_operand"))
15264 (clobber (match_scratch 5))]
15266 [(parallel [(set (match_dup 4)
15267 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15268 (use (match_dup 2))
15269 (use (match_dup 3))
15270 (clobber (match_dup 5))])
15271 (set (match_dup 0) (match_dup 4))])
15274 [(set (match_operand:DI 0 "memory_operand")
15275 (unspec:DI [(match_operand:XF 1 "register_operand")]
15277 (use (match_operand:HI 2 "memory_operand"))
15278 (use (match_operand:HI 3 "memory_operand"))
15279 (clobber (match_operand:DI 4 "memory_operand"))
15280 (clobber (match_scratch 5))]
15282 [(parallel [(set (match_dup 0)
15283 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15284 (use (match_dup 2))
15285 (use (match_dup 3))
15286 (clobber (match_dup 5))])])
15288 (define_insn "fist<mode>2_ceil"
15289 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15290 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15292 (use (match_operand:HI 2 "memory_operand" "m"))
15293 (use (match_operand:HI 3 "memory_operand" "m"))]
15294 "TARGET_USE_FANCY_MATH_387
15295 && flag_unsafe_math_optimizations"
15296 "* return output_fix_trunc (insn, operands, false);"
15297 [(set_attr "type" "fistp")
15298 (set_attr "i387_cw" "ceil")
15299 (set_attr "mode" "<MODE>")])
15301 (define_insn "fist<mode>2_ceil_with_temp"
15302 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15303 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15305 (use (match_operand:HI 2 "memory_operand" "m,m"))
15306 (use (match_operand:HI 3 "memory_operand" "m,m"))
15307 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15308 "TARGET_USE_FANCY_MATH_387
15309 && flag_unsafe_math_optimizations"
15311 [(set_attr "type" "fistp")
15312 (set_attr "i387_cw" "ceil")
15313 (set_attr "mode" "<MODE>")])
15316 [(set (match_operand:SWI24 0 "register_operand")
15317 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15319 (use (match_operand:HI 2 "memory_operand"))
15320 (use (match_operand:HI 3 "memory_operand"))
15321 (clobber (match_operand:SWI24 4 "memory_operand"))]
15323 [(parallel [(set (match_dup 4)
15324 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15325 (use (match_dup 2))
15326 (use (match_dup 3))])
15327 (set (match_dup 0) (match_dup 4))])
15330 [(set (match_operand:SWI24 0 "memory_operand")
15331 (unspec:SWI24 [(match_operand:XF 1 "register_operand")]
15333 (use (match_operand:HI 2 "memory_operand"))
15334 (use (match_operand:HI 3 "memory_operand"))
15335 (clobber (match_operand:SWI24 4 "memory_operand"))]
15337 [(parallel [(set (match_dup 0)
15338 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15339 (use (match_dup 2))
15340 (use (match_dup 3))])])
15342 (define_expand "lceilxf<mode>2"
15343 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand")
15344 (unspec:SWI248x [(match_operand:XF 1 "register_operand")]
15346 (clobber (reg:CC FLAGS_REG))])]
15347 "TARGET_USE_FANCY_MATH_387
15348 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15349 && flag_unsafe_math_optimizations")
15351 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15352 [(match_operand:SWI48 0 "nonimmediate_operand")
15353 (match_operand:MODEF 1 "register_operand")]
15354 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15355 && !flag_trapping_math"
15357 ix86_expand_lfloorceil (operands[0], operands[1], false);
15361 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15362 (define_insn_and_split "frndintxf2_trunc"
15363 [(set (match_operand:XF 0 "register_operand")
15364 (unspec:XF [(match_operand:XF 1 "register_operand")]
15365 UNSPEC_FRNDINT_TRUNC))
15366 (clobber (reg:CC FLAGS_REG))]
15367 "TARGET_USE_FANCY_MATH_387
15368 && flag_unsafe_math_optimizations
15369 && can_create_pseudo_p ()"
15374 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15376 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15377 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15379 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15380 operands[2], operands[3]));
15383 [(set_attr "type" "frndint")
15384 (set_attr "i387_cw" "trunc")
15385 (set_attr "mode" "XF")])
15387 (define_insn "frndintxf2_trunc_i387"
15388 [(set (match_operand:XF 0 "register_operand" "=f")
15389 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15390 UNSPEC_FRNDINT_TRUNC))
15391 (use (match_operand:HI 2 "memory_operand" "m"))
15392 (use (match_operand:HI 3 "memory_operand" "m"))]
15393 "TARGET_USE_FANCY_MATH_387
15394 && flag_unsafe_math_optimizations"
15395 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15396 [(set_attr "type" "frndint")
15397 (set_attr "i387_cw" "trunc")
15398 (set_attr "mode" "XF")])
15400 (define_expand "btruncxf2"
15401 [(use (match_operand:XF 0 "register_operand"))
15402 (use (match_operand:XF 1 "register_operand"))]
15403 "TARGET_USE_FANCY_MATH_387
15404 && flag_unsafe_math_optimizations"
15406 if (optimize_insn_for_size_p ())
15408 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15412 (define_expand "btrunc<mode>2"
15413 [(use (match_operand:MODEF 0 "register_operand"))
15414 (use (match_operand:MODEF 1 "register_operand"))]
15415 "(TARGET_USE_FANCY_MATH_387
15416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15417 || TARGET_MIX_SSE_I387)
15418 && flag_unsafe_math_optimizations)
15419 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15420 && !flag_trapping_math)"
15422 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15423 && !flag_trapping_math)
15426 emit_insn (gen_sse4_1_round<mode>2
15427 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15428 else if (optimize_insn_for_size_p ())
15430 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15431 ix86_expand_trunc (operands[0], operands[1]);
15433 ix86_expand_truncdf_32 (operands[0], operands[1]);
15439 if (optimize_insn_for_size_p ())
15442 op0 = gen_reg_rtx (XFmode);
15443 op1 = gen_reg_rtx (XFmode);
15444 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15445 emit_insn (gen_frndintxf2_trunc (op0, op1));
15447 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15452 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15453 (define_insn_and_split "frndintxf2_mask_pm"
15454 [(set (match_operand:XF 0 "register_operand")
15455 (unspec:XF [(match_operand:XF 1 "register_operand")]
15456 UNSPEC_FRNDINT_MASK_PM))
15457 (clobber (reg:CC FLAGS_REG))]
15458 "TARGET_USE_FANCY_MATH_387
15459 && flag_unsafe_math_optimizations
15460 && can_create_pseudo_p ()"
15465 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15467 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15468 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15470 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15471 operands[2], operands[3]));
15474 [(set_attr "type" "frndint")
15475 (set_attr "i387_cw" "mask_pm")
15476 (set_attr "mode" "XF")])
15478 (define_insn "frndintxf2_mask_pm_i387"
15479 [(set (match_operand:XF 0 "register_operand" "=f")
15480 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15481 UNSPEC_FRNDINT_MASK_PM))
15482 (use (match_operand:HI 2 "memory_operand" "m"))
15483 (use (match_operand:HI 3 "memory_operand" "m"))]
15484 "TARGET_USE_FANCY_MATH_387
15485 && flag_unsafe_math_optimizations"
15486 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15487 [(set_attr "type" "frndint")
15488 (set_attr "i387_cw" "mask_pm")
15489 (set_attr "mode" "XF")])
15491 (define_expand "nearbyintxf2"
15492 [(use (match_operand:XF 0 "register_operand"))
15493 (use (match_operand:XF 1 "register_operand"))]
15494 "TARGET_USE_FANCY_MATH_387
15495 && flag_unsafe_math_optimizations"
15497 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15501 (define_expand "nearbyint<mode>2"
15502 [(use (match_operand:MODEF 0 "register_operand"))
15503 (use (match_operand:MODEF 1 "register_operand"))]
15504 "TARGET_USE_FANCY_MATH_387
15505 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15506 || TARGET_MIX_SSE_I387)
15507 && flag_unsafe_math_optimizations"
15509 rtx op0 = gen_reg_rtx (XFmode);
15510 rtx op1 = gen_reg_rtx (XFmode);
15512 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15513 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15519 (define_insn "fxam<mode>2_i387"
15520 [(set (match_operand:HI 0 "register_operand" "=a")
15522 [(match_operand:X87MODEF 1 "register_operand" "f")]
15524 "TARGET_USE_FANCY_MATH_387"
15525 "fxam\n\tfnstsw\t%0"
15526 [(set_attr "type" "multi")
15527 (set_attr "length" "4")
15528 (set_attr "unit" "i387")
15529 (set_attr "mode" "<MODE>")])
15531 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15532 [(set (match_operand:HI 0 "register_operand")
15534 [(match_operand:MODEF 1 "memory_operand")]
15536 "TARGET_USE_FANCY_MATH_387
15537 && can_create_pseudo_p ()"
15540 [(set (match_dup 2)(match_dup 1))
15542 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15544 operands[2] = gen_reg_rtx (<MODE>mode);
15546 MEM_VOLATILE_P (operands[1]) = 1;
15548 [(set_attr "type" "multi")
15549 (set_attr "unit" "i387")
15550 (set_attr "mode" "<MODE>")])
15552 (define_expand "isinfxf2"
15553 [(use (match_operand:SI 0 "register_operand"))
15554 (use (match_operand:XF 1 "register_operand"))]
15555 "TARGET_USE_FANCY_MATH_387
15556 && TARGET_C99_FUNCTIONS"
15558 rtx mask = GEN_INT (0x45);
15559 rtx val = GEN_INT (0x05);
15563 rtx scratch = gen_reg_rtx (HImode);
15564 rtx res = gen_reg_rtx (QImode);
15566 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15568 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15569 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15570 cond = gen_rtx_fmt_ee (EQ, QImode,
15571 gen_rtx_REG (CCmode, FLAGS_REG),
15573 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15574 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15578 (define_expand "isinf<mode>2"
15579 [(use (match_operand:SI 0 "register_operand"))
15580 (use (match_operand:MODEF 1 "nonimmediate_operand"))]
15581 "TARGET_USE_FANCY_MATH_387
15582 && TARGET_C99_FUNCTIONS
15583 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15585 rtx mask = GEN_INT (0x45);
15586 rtx val = GEN_INT (0x05);
15590 rtx scratch = gen_reg_rtx (HImode);
15591 rtx res = gen_reg_rtx (QImode);
15593 /* Remove excess precision by forcing value through memory. */
15594 if (memory_operand (operands[1], VOIDmode))
15595 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15598 enum ix86_stack_slot slot = (virtuals_instantiated
15601 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15603 emit_move_insn (temp, operands[1]);
15604 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15607 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15608 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15609 cond = gen_rtx_fmt_ee (EQ, QImode,
15610 gen_rtx_REG (CCmode, FLAGS_REG),
15612 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15613 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15617 (define_expand "signbitxf2"
15618 [(use (match_operand:SI 0 "register_operand"))
15619 (use (match_operand:XF 1 "register_operand"))]
15620 "TARGET_USE_FANCY_MATH_387"
15622 rtx scratch = gen_reg_rtx (HImode);
15624 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15625 emit_insn (gen_andsi3 (operands[0],
15626 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15630 (define_insn "movmsk_df"
15631 [(set (match_operand:SI 0 "register_operand" "=r")
15633 [(match_operand:DF 1 "register_operand" "x")]
15635 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15636 "%vmovmskpd\t{%1, %0|%0, %1}"
15637 [(set_attr "type" "ssemov")
15638 (set_attr "prefix" "maybe_vex")
15639 (set_attr "mode" "DF")])
15641 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15642 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15643 (define_expand "signbitdf2"
15644 [(use (match_operand:SI 0 "register_operand"))
15645 (use (match_operand:DF 1 "register_operand"))]
15646 "TARGET_USE_FANCY_MATH_387
15647 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15649 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15651 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15652 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15656 rtx scratch = gen_reg_rtx (HImode);
15658 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15659 emit_insn (gen_andsi3 (operands[0],
15660 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15665 (define_expand "signbitsf2"
15666 [(use (match_operand:SI 0 "register_operand"))
15667 (use (match_operand:SF 1 "register_operand"))]
15668 "TARGET_USE_FANCY_MATH_387
15669 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15671 rtx scratch = gen_reg_rtx (HImode);
15673 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15674 emit_insn (gen_andsi3 (operands[0],
15675 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15679 ;; Block operation instructions
15682 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15685 [(set_attr "length" "1")
15686 (set_attr "length_immediate" "0")
15687 (set_attr "modrm" "0")])
15689 (define_expand "movmem<mode>"
15690 [(use (match_operand:BLK 0 "memory_operand"))
15691 (use (match_operand:BLK 1 "memory_operand"))
15692 (use (match_operand:SWI48 2 "nonmemory_operand"))
15693 (use (match_operand:SWI48 3 "const_int_operand"))
15694 (use (match_operand:SI 4 "const_int_operand"))
15695 (use (match_operand:SI 5 "const_int_operand"))]
15698 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15699 operands[4], operands[5]))
15705 ;; Most CPUs don't like single string operations
15706 ;; Handle this case here to simplify previous expander.
15708 (define_expand "strmov"
15709 [(set (match_dup 4) (match_operand 3 "memory_operand"))
15710 (set (match_operand 1 "memory_operand") (match_dup 4))
15711 (parallel [(set (match_operand 0 "register_operand") (match_dup 5))
15712 (clobber (reg:CC FLAGS_REG))])
15713 (parallel [(set (match_operand 2 "register_operand") (match_dup 6))
15714 (clobber (reg:CC FLAGS_REG))])]
15717 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15719 /* If .md ever supports :P for Pmode, these can be directly
15720 in the pattern above. */
15721 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15722 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15724 /* Can't use this if the user has appropriated esi or edi. */
15725 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15726 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15728 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15729 operands[2], operands[3],
15730 operands[5], operands[6]));
15734 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15737 (define_expand "strmov_singleop"
15738 [(parallel [(set (match_operand 1 "memory_operand")
15739 (match_operand 3 "memory_operand"))
15740 (set (match_operand 0 "register_operand")
15742 (set (match_operand 2 "register_operand")
15743 (match_operand 5))])]
15745 "ix86_current_function_needs_cld = 1;")
15747 (define_insn "*strmovdi_rex_1"
15748 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15749 (mem:DI (match_operand:P 3 "register_operand" "1")))
15750 (set (match_operand:P 0 "register_operand" "=D")
15751 (plus:P (match_dup 2)
15753 (set (match_operand:P 1 "register_operand" "=S")
15754 (plus:P (match_dup 3)
15757 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15759 [(set_attr "type" "str")
15760 (set_attr "memory" "both")
15761 (set_attr "mode" "DI")])
15763 (define_insn "*strmovsi_1"
15764 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15765 (mem:SI (match_operand:P 3 "register_operand" "1")))
15766 (set (match_operand:P 0 "register_operand" "=D")
15767 (plus:P (match_dup 2)
15769 (set (match_operand:P 1 "register_operand" "=S")
15770 (plus:P (match_dup 3)
15772 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15774 [(set_attr "type" "str")
15775 (set_attr "memory" "both")
15776 (set_attr "mode" "SI")])
15778 (define_insn "*strmovhi_1"
15779 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15780 (mem:HI (match_operand:P 3 "register_operand" "1")))
15781 (set (match_operand:P 0 "register_operand" "=D")
15782 (plus:P (match_dup 2)
15784 (set (match_operand:P 1 "register_operand" "=S")
15785 (plus:P (match_dup 3)
15787 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15789 [(set_attr "type" "str")
15790 (set_attr "memory" "both")
15791 (set_attr "mode" "HI")])
15793 (define_insn "*strmovqi_1"
15794 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15795 (mem:QI (match_operand:P 3 "register_operand" "1")))
15796 (set (match_operand:P 0 "register_operand" "=D")
15797 (plus:P (match_dup 2)
15799 (set (match_operand:P 1 "register_operand" "=S")
15800 (plus:P (match_dup 3)
15802 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15804 [(set_attr "type" "str")
15805 (set_attr "memory" "both")
15806 (set (attr "prefix_rex")
15808 (match_test "<P:MODE>mode == DImode")
15810 (const_string "*")))
15811 (set_attr "mode" "QI")])
15813 (define_expand "rep_mov"
15814 [(parallel [(set (match_operand 4 "register_operand") (const_int 0))
15815 (set (match_operand 0 "register_operand")
15817 (set (match_operand 2 "register_operand")
15819 (set (match_operand 1 "memory_operand")
15820 (match_operand 3 "memory_operand"))
15821 (use (match_dup 4))])]
15823 "ix86_current_function_needs_cld = 1;")
15825 (define_insn "*rep_movdi_rex64"
15826 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15827 (set (match_operand:P 0 "register_operand" "=D")
15828 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15830 (match_operand:P 3 "register_operand" "0")))
15831 (set (match_operand:P 1 "register_operand" "=S")
15832 (plus:P (ashift:P (match_dup 5) (const_int 3))
15833 (match_operand:P 4 "register_operand" "1")))
15834 (set (mem:BLK (match_dup 3))
15835 (mem:BLK (match_dup 4)))
15836 (use (match_dup 5))]
15838 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15840 [(set_attr "type" "str")
15841 (set_attr "prefix_rep" "1")
15842 (set_attr "memory" "both")
15843 (set_attr "mode" "DI")])
15845 (define_insn "*rep_movsi"
15846 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15847 (set (match_operand:P 0 "register_operand" "=D")
15848 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15850 (match_operand:P 3 "register_operand" "0")))
15851 (set (match_operand:P 1 "register_operand" "=S")
15852 (plus:P (ashift:P (match_dup 5) (const_int 2))
15853 (match_operand:P 4 "register_operand" "1")))
15854 (set (mem:BLK (match_dup 3))
15855 (mem:BLK (match_dup 4)))
15856 (use (match_dup 5))]
15857 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15858 "%^rep{%;} movs{l|d}"
15859 [(set_attr "type" "str")
15860 (set_attr "prefix_rep" "1")
15861 (set_attr "memory" "both")
15862 (set_attr "mode" "SI")])
15864 (define_insn "*rep_movqi"
15865 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15866 (set (match_operand:P 0 "register_operand" "=D")
15867 (plus:P (match_operand:P 3 "register_operand" "0")
15868 (match_operand:P 5 "register_operand" "2")))
15869 (set (match_operand:P 1 "register_operand" "=S")
15870 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15871 (set (mem:BLK (match_dup 3))
15872 (mem:BLK (match_dup 4)))
15873 (use (match_dup 5))]
15874 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15876 [(set_attr "type" "str")
15877 (set_attr "prefix_rep" "1")
15878 (set_attr "memory" "both")
15879 (set_attr "mode" "QI")])
15881 (define_expand "setmem<mode>"
15882 [(use (match_operand:BLK 0 "memory_operand"))
15883 (use (match_operand:SWI48 1 "nonmemory_operand"))
15884 (use (match_operand:QI 2 "nonmemory_operand"))
15885 (use (match_operand 3 "const_int_operand"))
15886 (use (match_operand:SI 4 "const_int_operand"))
15887 (use (match_operand:SI 5 "const_int_operand"))]
15890 if (ix86_expand_setmem (operands[0], operands[1],
15891 operands[2], operands[3],
15892 operands[4], operands[5]))
15898 ;; Most CPUs don't like single string operations
15899 ;; Handle this case here to simplify previous expander.
15901 (define_expand "strset"
15902 [(set (match_operand 1 "memory_operand")
15903 (match_operand 2 "register_operand"))
15904 (parallel [(set (match_operand 0 "register_operand")
15906 (clobber (reg:CC FLAGS_REG))])]
15909 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15910 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15912 /* If .md ever supports :P for Pmode, this can be directly
15913 in the pattern above. */
15914 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15915 GEN_INT (GET_MODE_SIZE (GET_MODE
15917 /* Can't use this if the user has appropriated eax or edi. */
15918 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15919 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15921 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15927 (define_expand "strset_singleop"
15928 [(parallel [(set (match_operand 1 "memory_operand")
15929 (match_operand 2 "register_operand"))
15930 (set (match_operand 0 "register_operand")
15931 (match_operand 3))])]
15933 "ix86_current_function_needs_cld = 1;")
15935 (define_insn "*strsetdi_rex_1"
15936 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15937 (match_operand:DI 2 "register_operand" "a"))
15938 (set (match_operand:P 0 "register_operand" "=D")
15939 (plus:P (match_dup 1)
15942 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15944 [(set_attr "type" "str")
15945 (set_attr "memory" "store")
15946 (set_attr "mode" "DI")])
15948 (define_insn "*strsetsi_1"
15949 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15950 (match_operand:SI 2 "register_operand" "a"))
15951 (set (match_operand:P 0 "register_operand" "=D")
15952 (plus:P (match_dup 1)
15954 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15956 [(set_attr "type" "str")
15957 (set_attr "memory" "store")
15958 (set_attr "mode" "SI")])
15960 (define_insn "*strsethi_1"
15961 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15962 (match_operand:HI 2 "register_operand" "a"))
15963 (set (match_operand:P 0 "register_operand" "=D")
15964 (plus:P (match_dup 1)
15966 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15968 [(set_attr "type" "str")
15969 (set_attr "memory" "store")
15970 (set_attr "mode" "HI")])
15972 (define_insn "*strsetqi_1"
15973 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15974 (match_operand:QI 2 "register_operand" "a"))
15975 (set (match_operand:P 0 "register_operand" "=D")
15976 (plus:P (match_dup 1)
15978 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15980 [(set_attr "type" "str")
15981 (set_attr "memory" "store")
15982 (set (attr "prefix_rex")
15984 (match_test "<P:MODE>mode == DImode")
15986 (const_string "*")))
15987 (set_attr "mode" "QI")])
15989 (define_expand "rep_stos"
15990 [(parallel [(set (match_operand 1 "register_operand") (const_int 0))
15991 (set (match_operand 0 "register_operand")
15993 (set (match_operand 2 "memory_operand") (const_int 0))
15994 (use (match_operand 3 "register_operand"))
15995 (use (match_dup 1))])]
15997 "ix86_current_function_needs_cld = 1;")
15999 (define_insn "*rep_stosdi_rex64"
16000 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16001 (set (match_operand:P 0 "register_operand" "=D")
16002 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16004 (match_operand:P 3 "register_operand" "0")))
16005 (set (mem:BLK (match_dup 3))
16007 (use (match_operand:DI 2 "register_operand" "a"))
16008 (use (match_dup 4))]
16010 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16012 [(set_attr "type" "str")
16013 (set_attr "prefix_rep" "1")
16014 (set_attr "memory" "store")
16015 (set_attr "mode" "DI")])
16017 (define_insn "*rep_stossi"
16018 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16019 (set (match_operand:P 0 "register_operand" "=D")
16020 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16022 (match_operand:P 3 "register_operand" "0")))
16023 (set (mem:BLK (match_dup 3))
16025 (use (match_operand:SI 2 "register_operand" "a"))
16026 (use (match_dup 4))]
16027 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16028 "%^rep{%;} stos{l|d}"
16029 [(set_attr "type" "str")
16030 (set_attr "prefix_rep" "1")
16031 (set_attr "memory" "store")
16032 (set_attr "mode" "SI")])
16034 (define_insn "*rep_stosqi"
16035 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16036 (set (match_operand:P 0 "register_operand" "=D")
16037 (plus:P (match_operand:P 3 "register_operand" "0")
16038 (match_operand:P 4 "register_operand" "1")))
16039 (set (mem:BLK (match_dup 3))
16041 (use (match_operand:QI 2 "register_operand" "a"))
16042 (use (match_dup 4))]
16043 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16045 [(set_attr "type" "str")
16046 (set_attr "prefix_rep" "1")
16047 (set_attr "memory" "store")
16048 (set (attr "prefix_rex")
16050 (match_test "<P:MODE>mode == DImode")
16052 (const_string "*")))
16053 (set_attr "mode" "QI")])
16055 (define_expand "cmpstrnsi"
16056 [(set (match_operand:SI 0 "register_operand")
16057 (compare:SI (match_operand:BLK 1 "general_operand")
16058 (match_operand:BLK 2 "general_operand")))
16059 (use (match_operand 3 "general_operand"))
16060 (use (match_operand 4 "immediate_operand"))]
16063 rtx addr1, addr2, out, outlow, count, countreg, align;
16065 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16068 /* Can't use this if the user has appropriated ecx, esi or edi. */
16069 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16074 out = gen_reg_rtx (SImode);
16076 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16077 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16078 if (addr1 != XEXP (operands[1], 0))
16079 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16080 if (addr2 != XEXP (operands[2], 0))
16081 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16083 count = operands[3];
16084 countreg = ix86_zero_extend_to_Pmode (count);
16086 /* %%% Iff we are testing strict equality, we can use known alignment
16087 to good advantage. This may be possible with combine, particularly
16088 once cc0 is dead. */
16089 align = operands[4];
16091 if (CONST_INT_P (count))
16093 if (INTVAL (count) == 0)
16095 emit_move_insn (operands[0], const0_rtx);
16098 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16099 operands[1], operands[2]));
16103 rtx (*gen_cmp) (rtx, rtx);
16105 gen_cmp = (TARGET_64BIT
16106 ? gen_cmpdi_1 : gen_cmpsi_1);
16108 emit_insn (gen_cmp (countreg, countreg));
16109 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16110 operands[1], operands[2]));
16113 outlow = gen_lowpart (QImode, out);
16114 emit_insn (gen_cmpintqi (outlow));
16115 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16117 if (operands[0] != out)
16118 emit_move_insn (operands[0], out);
16123 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16125 (define_expand "cmpintqi"
16126 [(set (match_dup 1)
16127 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16129 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16130 (parallel [(set (match_operand:QI 0 "register_operand")
16131 (minus:QI (match_dup 1)
16133 (clobber (reg:CC FLAGS_REG))])]
16136 operands[1] = gen_reg_rtx (QImode);
16137 operands[2] = gen_reg_rtx (QImode);
16140 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16141 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16143 (define_expand "cmpstrnqi_nz_1"
16144 [(parallel [(set (reg:CC FLAGS_REG)
16145 (compare:CC (match_operand 4 "memory_operand")
16146 (match_operand 5 "memory_operand")))
16147 (use (match_operand 2 "register_operand"))
16148 (use (match_operand:SI 3 "immediate_operand"))
16149 (clobber (match_operand 0 "register_operand"))
16150 (clobber (match_operand 1 "register_operand"))
16151 (clobber (match_dup 2))])]
16153 "ix86_current_function_needs_cld = 1;")
16155 (define_insn "*cmpstrnqi_nz_1"
16156 [(set (reg:CC FLAGS_REG)
16157 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16158 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16159 (use (match_operand:P 6 "register_operand" "2"))
16160 (use (match_operand:SI 3 "immediate_operand" "i"))
16161 (clobber (match_operand:P 0 "register_operand" "=S"))
16162 (clobber (match_operand:P 1 "register_operand" "=D"))
16163 (clobber (match_operand:P 2 "register_operand" "=c"))]
16164 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16166 [(set_attr "type" "str")
16167 (set_attr "mode" "QI")
16168 (set (attr "prefix_rex")
16170 (match_test "<P:MODE>mode == DImode")
16172 (const_string "*")))
16173 (set_attr "prefix_rep" "1")])
16175 ;; The same, but the count is not known to not be zero.
16177 (define_expand "cmpstrnqi_1"
16178 [(parallel [(set (reg:CC FLAGS_REG)
16179 (if_then_else:CC (ne (match_operand 2 "register_operand")
16181 (compare:CC (match_operand 4 "memory_operand")
16182 (match_operand 5 "memory_operand"))
16184 (use (match_operand:SI 3 "immediate_operand"))
16185 (use (reg:CC FLAGS_REG))
16186 (clobber (match_operand 0 "register_operand"))
16187 (clobber (match_operand 1 "register_operand"))
16188 (clobber (match_dup 2))])]
16190 "ix86_current_function_needs_cld = 1;")
16192 (define_insn "*cmpstrnqi_1"
16193 [(set (reg:CC FLAGS_REG)
16194 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16196 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16197 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16199 (use (match_operand:SI 3 "immediate_operand" "i"))
16200 (use (reg:CC FLAGS_REG))
16201 (clobber (match_operand:P 0 "register_operand" "=S"))
16202 (clobber (match_operand:P 1 "register_operand" "=D"))
16203 (clobber (match_operand:P 2 "register_operand" "=c"))]
16204 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16206 [(set_attr "type" "str")
16207 (set_attr "mode" "QI")
16208 (set (attr "prefix_rex")
16210 (match_test "<P:MODE>mode == DImode")
16212 (const_string "*")))
16213 (set_attr "prefix_rep" "1")])
16215 (define_expand "strlen<mode>"
16216 [(set (match_operand:P 0 "register_operand")
16217 (unspec:P [(match_operand:BLK 1 "general_operand")
16218 (match_operand:QI 2 "immediate_operand")
16219 (match_operand 3 "immediate_operand")]
16223 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16229 (define_expand "strlenqi_1"
16230 [(parallel [(set (match_operand 0 "register_operand")
16232 (clobber (match_operand 1 "register_operand"))
16233 (clobber (reg:CC FLAGS_REG))])]
16235 "ix86_current_function_needs_cld = 1;")
16237 (define_insn "*strlenqi_1"
16238 [(set (match_operand:P 0 "register_operand" "=&c")
16239 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16240 (match_operand:QI 2 "register_operand" "a")
16241 (match_operand:P 3 "immediate_operand" "i")
16242 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16243 (clobber (match_operand:P 1 "register_operand" "=D"))
16244 (clobber (reg:CC FLAGS_REG))]
16245 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16246 "%^repnz{%;} scasb"
16247 [(set_attr "type" "str")
16248 (set_attr "mode" "QI")
16249 (set (attr "prefix_rex")
16251 (match_test "<P:MODE>mode == DImode")
16253 (const_string "*")))
16254 (set_attr "prefix_rep" "1")])
16256 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16257 ;; handled in combine, but it is not currently up to the task.
16258 ;; When used for their truth value, the cmpstrn* expanders generate
16267 ;; The intermediate three instructions are unnecessary.
16269 ;; This one handles cmpstrn*_nz_1...
16272 (set (reg:CC FLAGS_REG)
16273 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16274 (mem:BLK (match_operand 5 "register_operand"))))
16275 (use (match_operand 6 "register_operand"))
16276 (use (match_operand:SI 3 "immediate_operand"))
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 (compare:CC (mem:BLK (match_dup 4))
16291 (mem:BLK (match_dup 5))))
16292 (use (match_dup 6))
16293 (use (match_dup 3))
16294 (clobber (match_dup 0))
16295 (clobber (match_dup 1))
16296 (clobber (match_dup 2))])])
16298 ;; ...and this one handles cmpstrn*_1.
16301 (set (reg:CC FLAGS_REG)
16302 (if_then_else:CC (ne (match_operand 6 "register_operand")
16304 (compare:CC (mem:BLK (match_operand 4 "register_operand"))
16305 (mem:BLK (match_operand 5 "register_operand")))
16307 (use (match_operand:SI 3 "immediate_operand"))
16308 (use (reg:CC FLAGS_REG))
16309 (clobber (match_operand 0 "register_operand"))
16310 (clobber (match_operand 1 "register_operand"))
16311 (clobber (match_operand 2 "register_operand"))])
16312 (set (match_operand:QI 7 "register_operand")
16313 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16314 (set (match_operand:QI 8 "register_operand")
16315 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16316 (set (reg FLAGS_REG)
16317 (compare (match_dup 7) (match_dup 8)))
16319 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16321 (set (reg:CC FLAGS_REG)
16322 (if_then_else:CC (ne (match_dup 6)
16324 (compare:CC (mem:BLK (match_dup 4))
16325 (mem:BLK (match_dup 5)))
16327 (use (match_dup 3))
16328 (use (reg:CC FLAGS_REG))
16329 (clobber (match_dup 0))
16330 (clobber (match_dup 1))
16331 (clobber (match_dup 2))])])
16333 ;; Conditional move instructions.
16335 (define_expand "mov<mode>cc"
16336 [(set (match_operand:SWIM 0 "register_operand")
16337 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator")
16338 (match_operand:SWIM 2 "<general_operand>")
16339 (match_operand:SWIM 3 "<general_operand>")))]
16341 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16343 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16344 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16345 ;; So just document what we're doing explicitly.
16347 (define_expand "x86_mov<mode>cc_0_m1"
16349 [(set (match_operand:SWI48 0 "register_operand")
16350 (if_then_else:SWI48
16351 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16352 [(match_operand 1 "flags_reg_operand")
16356 (clobber (reg:CC FLAGS_REG))])])
16358 (define_insn "*x86_mov<mode>cc_0_m1"
16359 [(set (match_operand:SWI48 0 "register_operand" "=r")
16360 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16361 [(reg FLAGS_REG) (const_int 0)])
16364 (clobber (reg:CC FLAGS_REG))]
16366 "sbb{<imodesuffix>}\t%0, %0"
16367 ; Since we don't have the proper number of operands for an alu insn,
16368 ; fill in all the blanks.
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 "*x86_mov<mode>cc_0_m1_se"
16378 [(set (match_operand:SWI48 0 "register_operand" "=r")
16379 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16380 [(reg FLAGS_REG) (const_int 0)])
16383 (clobber (reg:CC FLAGS_REG))]
16385 "sbb{<imodesuffix>}\t%0, %0"
16386 [(set_attr "type" "alu")
16387 (set_attr "use_carry" "1")
16388 (set_attr "pent_pair" "pu")
16389 (set_attr "memory" "none")
16390 (set_attr "imm_disp" "false")
16391 (set_attr "mode" "<MODE>")
16392 (set_attr "length_immediate" "0")])
16394 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16395 [(set (match_operand:SWI48 0 "register_operand" "=r")
16396 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16397 [(reg FLAGS_REG) (const_int 0)])))]
16399 "sbb{<imodesuffix>}\t%0, %0"
16400 [(set_attr "type" "alu")
16401 (set_attr "use_carry" "1")
16402 (set_attr "pent_pair" "pu")
16403 (set_attr "memory" "none")
16404 (set_attr "imm_disp" "false")
16405 (set_attr "mode" "<MODE>")
16406 (set_attr "length_immediate" "0")])
16408 (define_insn "*mov<mode>cc_noc"
16409 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16410 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16411 [(reg FLAGS_REG) (const_int 0)])
16412 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16413 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16414 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16416 cmov%O2%C1\t{%2, %0|%0, %2}
16417 cmov%O2%c1\t{%3, %0|%0, %3}"
16418 [(set_attr "type" "icmov")
16419 (set_attr "mode" "<MODE>")])
16421 (define_insn_and_split "*movqicc_noc"
16422 [(set (match_operand:QI 0 "register_operand" "=r,r")
16423 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16424 [(match_operand 4 "flags_reg_operand")
16426 (match_operand:QI 2 "register_operand" "r,0")
16427 (match_operand:QI 3 "register_operand" "0,r")))]
16428 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16430 "&& reload_completed"
16431 [(set (match_dup 0)
16432 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16435 "operands[0] = gen_lowpart (SImode, operands[0]);
16436 operands[2] = gen_lowpart (SImode, operands[2]);
16437 operands[3] = gen_lowpart (SImode, operands[3]);"
16438 [(set_attr "type" "icmov")
16439 (set_attr "mode" "SI")])
16441 (define_expand "mov<mode>cc"
16442 [(set (match_operand:X87MODEF 0 "register_operand")
16443 (if_then_else:X87MODEF
16444 (match_operand 1 "ix86_fp_comparison_operator")
16445 (match_operand:X87MODEF 2 "register_operand")
16446 (match_operand:X87MODEF 3 "register_operand")))]
16447 "(TARGET_80387 && TARGET_CMOVE)
16448 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16449 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16451 (define_insn "*movxfcc_1"
16452 [(set (match_operand:XF 0 "register_operand" "=f,f")
16453 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16454 [(reg FLAGS_REG) (const_int 0)])
16455 (match_operand:XF 2 "register_operand" "f,0")
16456 (match_operand:XF 3 "register_operand" "0,f")))]
16457 "TARGET_80387 && TARGET_CMOVE"
16459 fcmov%F1\t{%2, %0|%0, %2}
16460 fcmov%f1\t{%3, %0|%0, %3}"
16461 [(set_attr "type" "fcmov")
16462 (set_attr "mode" "XF")])
16464 (define_insn "*movdfcc_1_rex64"
16465 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16466 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16467 [(reg FLAGS_REG) (const_int 0)])
16468 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16469 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16470 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16471 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16473 fcmov%F1\t{%2, %0|%0, %2}
16474 fcmov%f1\t{%3, %0|%0, %3}
16475 cmov%O2%C1\t{%2, %0|%0, %2}
16476 cmov%O2%c1\t{%3, %0|%0, %3}"
16477 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16478 (set_attr "mode" "DF,DF,DI,DI")])
16480 (define_insn "*movdfcc_1"
16481 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16482 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16483 [(reg FLAGS_REG) (const_int 0)])
16484 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16485 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16486 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16487 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16489 fcmov%F1\t{%2, %0|%0, %2}
16490 fcmov%f1\t{%3, %0|%0, %3}
16493 [(set_attr "type" "fcmov,fcmov,multi,multi")
16494 (set_attr "mode" "DF,DF,DI,DI")])
16497 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16498 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16499 [(match_operand 4 "flags_reg_operand")
16501 (match_operand:DF 2 "nonimmediate_operand")
16502 (match_operand:DF 3 "nonimmediate_operand")))]
16503 "!TARGET_64BIT && reload_completed"
16504 [(set (match_dup 2)
16505 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16509 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16513 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16514 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16517 (define_insn "*movsfcc_1_387"
16518 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16519 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16520 [(reg FLAGS_REG) (const_int 0)])
16521 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16522 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16523 "TARGET_80387 && TARGET_CMOVE
16524 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16526 fcmov%F1\t{%2, %0|%0, %2}
16527 fcmov%f1\t{%3, %0|%0, %3}
16528 cmov%O2%C1\t{%2, %0|%0, %2}
16529 cmov%O2%c1\t{%3, %0|%0, %3}"
16530 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16531 (set_attr "mode" "SF,SF,SI,SI")])
16533 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16534 ;; the scalar versions to have only XMM registers as operands.
16536 ;; XOP conditional move
16537 (define_insn "*xop_pcmov_<mode>"
16538 [(set (match_operand:MODEF 0 "register_operand" "=x")
16539 (if_then_else:MODEF
16540 (match_operand:MODEF 1 "register_operand" "x")
16541 (match_operand:MODEF 2 "register_operand" "x")
16542 (match_operand:MODEF 3 "register_operand" "x")))]
16544 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16545 [(set_attr "type" "sse4arg")])
16547 ;; These versions of the min/max patterns are intentionally ignorant of
16548 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16549 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16550 ;; are undefined in this condition, we're certain this is correct.
16552 (define_insn "<code><mode>3"
16553 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16555 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16556 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16557 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16559 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16560 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16561 [(set_attr "isa" "noavx,avx")
16562 (set_attr "prefix" "orig,vex")
16563 (set_attr "type" "sseadd")
16564 (set_attr "mode" "<MODE>")])
16566 ;; These versions of the min/max patterns implement exactly the operations
16567 ;; min = (op1 < op2 ? op1 : op2)
16568 ;; max = (!(op1 < op2) ? op1 : op2)
16569 ;; Their operands are not commutative, and thus they may be used in the
16570 ;; presence of -0.0 and NaN.
16572 (define_insn "*ieee_smin<mode>3"
16573 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16575 [(match_operand:MODEF 1 "register_operand" "0,x")
16576 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16578 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16580 min<ssemodesuffix>\t{%2, %0|%0, %2}
16581 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16582 [(set_attr "isa" "noavx,avx")
16583 (set_attr "prefix" "orig,vex")
16584 (set_attr "type" "sseadd")
16585 (set_attr "mode" "<MODE>")])
16587 (define_insn "*ieee_smax<mode>3"
16588 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16590 [(match_operand:MODEF 1 "register_operand" "0,x")
16591 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16593 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16595 max<ssemodesuffix>\t{%2, %0|%0, %2}
16596 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16597 [(set_attr "isa" "noavx,avx")
16598 (set_attr "prefix" "orig,vex")
16599 (set_attr "type" "sseadd")
16600 (set_attr "mode" "<MODE>")])
16602 ;; Make two stack loads independent:
16604 ;; fld %st(0) -> fld bb
16605 ;; fmul bb fmul %st(1), %st
16607 ;; Actually we only match the last two instructions for simplicity.
16609 [(set (match_operand 0 "fp_register_operand")
16610 (match_operand 1 "fp_register_operand"))
16612 (match_operator 2 "binary_fp_operator"
16614 (match_operand 3 "memory_operand")]))]
16615 "REGNO (operands[0]) != REGNO (operands[1])"
16616 [(set (match_dup 0) (match_dup 3))
16617 (set (match_dup 0) (match_dup 4))]
16619 ;; The % modifier is not operational anymore in peephole2's, so we have to
16620 ;; swap the operands manually in the case of addition and multiplication.
16624 if (COMMUTATIVE_ARITH_P (operands[2]))
16625 op0 = operands[0], op1 = operands[1];
16627 op0 = operands[1], op1 = operands[0];
16629 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16630 GET_MODE (operands[2]),
16634 ;; Conditional addition patterns
16635 (define_expand "add<mode>cc"
16636 [(match_operand:SWI 0 "register_operand")
16637 (match_operand 1 "ordered_comparison_operator")
16638 (match_operand:SWI 2 "register_operand")
16639 (match_operand:SWI 3 "const_int_operand")]
16641 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16643 ;; Misc patterns (?)
16645 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16646 ;; Otherwise there will be nothing to keep
16648 ;; [(set (reg ebp) (reg esp))]
16649 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16650 ;; (clobber (eflags)]
16651 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16653 ;; in proper program order.
16655 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16656 [(set (match_operand:P 0 "register_operand" "=r,r")
16657 (plus:P (match_operand:P 1 "register_operand" "0,r")
16658 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16659 (clobber (reg:CC FLAGS_REG))
16660 (clobber (mem:BLK (scratch)))]
16663 switch (get_attr_type (insn))
16666 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16669 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16670 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16671 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16673 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16676 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16677 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16680 [(set (attr "type")
16681 (cond [(and (eq_attr "alternative" "0")
16682 (not (match_test "TARGET_OPT_AGU")))
16683 (const_string "alu")
16684 (match_operand:<MODE> 2 "const0_operand")
16685 (const_string "imov")
16687 (const_string "lea")))
16688 (set (attr "length_immediate")
16689 (cond [(eq_attr "type" "imov")
16691 (and (eq_attr "type" "alu")
16692 (match_operand 2 "const128_operand"))
16695 (const_string "*")))
16696 (set_attr "mode" "<MODE>")])
16698 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16699 [(set (match_operand:P 0 "register_operand" "=r")
16700 (minus:P (match_operand:P 1 "register_operand" "0")
16701 (match_operand:P 2 "register_operand" "r")))
16702 (clobber (reg:CC FLAGS_REG))
16703 (clobber (mem:BLK (scratch)))]
16705 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16706 [(set_attr "type" "alu")
16707 (set_attr "mode" "<MODE>")])
16709 (define_insn "allocate_stack_worker_probe_<mode>"
16710 [(set (match_operand:P 0 "register_operand" "=a")
16711 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16712 UNSPECV_STACK_PROBE))
16713 (clobber (reg:CC FLAGS_REG))]
16714 "ix86_target_stack_probe ()"
16715 "call\t___chkstk_ms"
16716 [(set_attr "type" "multi")
16717 (set_attr "length" "5")])
16719 (define_expand "allocate_stack"
16720 [(match_operand 0 "register_operand")
16721 (match_operand 1 "general_operand")]
16722 "ix86_target_stack_probe ()"
16726 #ifndef CHECK_STACK_LIMIT
16727 #define CHECK_STACK_LIMIT 0
16730 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16731 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16733 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16734 stack_pointer_rtx, 0, OPTAB_DIRECT);
16735 if (x != stack_pointer_rtx)
16736 emit_move_insn (stack_pointer_rtx, x);
16740 x = copy_to_mode_reg (Pmode, operands[1]);
16742 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16744 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16745 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16746 stack_pointer_rtx, 0, OPTAB_DIRECT);
16747 if (x != stack_pointer_rtx)
16748 emit_move_insn (stack_pointer_rtx, x);
16751 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16755 ;; Use IOR for stack probes, this is shorter.
16756 (define_expand "probe_stack"
16757 [(match_operand 0 "memory_operand")]
16760 rtx (*gen_ior3) (rtx, rtx, rtx);
16762 gen_ior3 = (GET_MODE (operands[0]) == DImode
16763 ? gen_iordi3 : gen_iorsi3);
16765 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16769 (define_insn "adjust_stack_and_probe<mode>"
16770 [(set (match_operand:P 0 "register_operand" "=r")
16771 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16772 UNSPECV_PROBE_STACK_RANGE))
16773 (set (reg:P SP_REG)
16774 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16775 (clobber (reg:CC FLAGS_REG))
16776 (clobber (mem:BLK (scratch)))]
16778 "* return output_adjust_stack_and_probe (operands[0]);"
16779 [(set_attr "type" "multi")])
16781 (define_insn "probe_stack_range<mode>"
16782 [(set (match_operand:P 0 "register_operand" "=r")
16783 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16784 (match_operand:P 2 "const_int_operand" "n")]
16785 UNSPECV_PROBE_STACK_RANGE))
16786 (clobber (reg:CC FLAGS_REG))]
16788 "* return output_probe_stack_range (operands[0], operands[2]);"
16789 [(set_attr "type" "multi")])
16791 (define_expand "builtin_setjmp_receiver"
16792 [(label_ref (match_operand 0))]
16793 "!TARGET_64BIT && flag_pic"
16799 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16800 rtx label_rtx = gen_label_rtx ();
16801 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16802 xops[0] = xops[1] = picreg;
16803 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16804 ix86_expand_binary_operator (MINUS, SImode, xops);
16808 emit_insn (gen_set_got (pic_offset_table_rtx));
16812 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16815 [(set (match_operand 0 "register_operand")
16816 (match_operator 3 "promotable_binary_operator"
16817 [(match_operand 1 "register_operand")
16818 (match_operand 2 "aligned_operand")]))
16819 (clobber (reg:CC FLAGS_REG))]
16820 "! TARGET_PARTIAL_REG_STALL && reload_completed
16821 && ((GET_MODE (operands[0]) == HImode
16822 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16823 /* ??? next two lines just !satisfies_constraint_K (...) */
16824 || !CONST_INT_P (operands[2])
16825 || satisfies_constraint_K (operands[2])))
16826 || (GET_MODE (operands[0]) == QImode
16827 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16828 [(parallel [(set (match_dup 0)
16829 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16830 (clobber (reg:CC FLAGS_REG))])]
16832 operands[0] = gen_lowpart (SImode, operands[0]);
16833 operands[1] = gen_lowpart (SImode, operands[1]);
16834 if (GET_CODE (operands[3]) != ASHIFT)
16835 operands[2] = gen_lowpart (SImode, operands[2]);
16836 PUT_MODE (operands[3], SImode);
16839 ; Promote the QImode tests, as i386 has encoding of the AND
16840 ; instruction with 32-bit sign-extended immediate and thus the
16841 ; instruction size is unchanged, except in the %eax case for
16842 ; which it is increased by one byte, hence the ! optimize_size.
16844 [(set (match_operand 0 "flags_reg_operand")
16845 (match_operator 2 "compare_operator"
16846 [(and (match_operand 3 "aligned_operand")
16847 (match_operand 4 "const_int_operand"))
16849 (set (match_operand 1 "register_operand")
16850 (and (match_dup 3) (match_dup 4)))]
16851 "! TARGET_PARTIAL_REG_STALL && reload_completed
16852 && optimize_insn_for_speed_p ()
16853 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16854 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16855 /* Ensure that the operand will remain sign-extended immediate. */
16856 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16857 [(parallel [(set (match_dup 0)
16858 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16861 (and:SI (match_dup 3) (match_dup 4)))])]
16864 = gen_int_mode (INTVAL (operands[4])
16865 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16866 operands[1] = gen_lowpart (SImode, operands[1]);
16867 operands[3] = gen_lowpart (SImode, operands[3]);
16870 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16871 ; the TEST instruction with 32-bit sign-extended immediate and thus
16872 ; the instruction size would at least double, which is not what we
16873 ; want even with ! optimize_size.
16875 [(set (match_operand 0 "flags_reg_operand")
16876 (match_operator 1 "compare_operator"
16877 [(and (match_operand:HI 2 "aligned_operand")
16878 (match_operand:HI 3 "const_int_operand"))
16880 "! TARGET_PARTIAL_REG_STALL && reload_completed
16881 && ! TARGET_FAST_PREFIX
16882 && optimize_insn_for_speed_p ()
16883 /* Ensure that the operand will remain sign-extended immediate. */
16884 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16885 [(set (match_dup 0)
16886 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16890 = gen_int_mode (INTVAL (operands[3])
16891 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16892 operands[2] = gen_lowpart (SImode, operands[2]);
16896 [(set (match_operand 0 "register_operand")
16897 (neg (match_operand 1 "register_operand")))
16898 (clobber (reg:CC FLAGS_REG))]
16899 "! TARGET_PARTIAL_REG_STALL && reload_completed
16900 && (GET_MODE (operands[0]) == HImode
16901 || (GET_MODE (operands[0]) == QImode
16902 && (TARGET_PROMOTE_QImode
16903 || optimize_insn_for_size_p ())))"
16904 [(parallel [(set (match_dup 0)
16905 (neg:SI (match_dup 1)))
16906 (clobber (reg:CC FLAGS_REG))])]
16908 operands[0] = gen_lowpart (SImode, operands[0]);
16909 operands[1] = gen_lowpart (SImode, operands[1]);
16913 [(set (match_operand 0 "register_operand")
16914 (not (match_operand 1 "register_operand")))]
16915 "! TARGET_PARTIAL_REG_STALL && reload_completed
16916 && (GET_MODE (operands[0]) == HImode
16917 || (GET_MODE (operands[0]) == QImode
16918 && (TARGET_PROMOTE_QImode
16919 || optimize_insn_for_size_p ())))"
16920 [(set (match_dup 0)
16921 (not:SI (match_dup 1)))]
16923 operands[0] = gen_lowpart (SImode, operands[0]);
16924 operands[1] = gen_lowpart (SImode, operands[1]);
16928 [(set (match_operand 0 "register_operand")
16929 (if_then_else (match_operator 1 "ordered_comparison_operator"
16930 [(reg FLAGS_REG) (const_int 0)])
16931 (match_operand 2 "register_operand")
16932 (match_operand 3 "register_operand")))]
16933 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16934 && (GET_MODE (operands[0]) == HImode
16935 || (GET_MODE (operands[0]) == QImode
16936 && (TARGET_PROMOTE_QImode
16937 || optimize_insn_for_size_p ())))"
16938 [(set (match_dup 0)
16939 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16941 operands[0] = gen_lowpart (SImode, operands[0]);
16942 operands[2] = gen_lowpart (SImode, operands[2]);
16943 operands[3] = gen_lowpart (SImode, operands[3]);
16946 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16947 ;; transform a complex memory operation into two memory to register operations.
16949 ;; Don't push memory operands
16951 [(set (match_operand:SWI 0 "push_operand")
16952 (match_operand:SWI 1 "memory_operand"))
16953 (match_scratch:SWI 2 "<r>")]
16954 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16955 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16956 [(set (match_dup 2) (match_dup 1))
16957 (set (match_dup 0) (match_dup 2))])
16959 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16962 [(set (match_operand:SF 0 "push_operand")
16963 (match_operand:SF 1 "memory_operand"))
16964 (match_scratch:SF 2 "r")]
16965 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16966 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16967 [(set (match_dup 2) (match_dup 1))
16968 (set (match_dup 0) (match_dup 2))])
16970 ;; Don't move an immediate directly to memory when the instruction
16973 [(match_scratch:SWI124 1 "<r>")
16974 (set (match_operand:SWI124 0 "memory_operand")
16976 "optimize_insn_for_speed_p ()
16977 && !TARGET_USE_MOV0
16978 && TARGET_SPLIT_LONG_MOVES
16979 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16980 && peep2_regno_dead_p (0, FLAGS_REG)"
16981 [(parallel [(set (match_dup 2) (const_int 0))
16982 (clobber (reg:CC FLAGS_REG))])
16983 (set (match_dup 0) (match_dup 1))]
16984 "operands[2] = gen_lowpart (SImode, operands[1]);")
16987 [(match_scratch:SWI124 2 "<r>")
16988 (set (match_operand:SWI124 0 "memory_operand")
16989 (match_operand:SWI124 1 "immediate_operand"))]
16990 "optimize_insn_for_speed_p ()
16991 && TARGET_SPLIT_LONG_MOVES
16992 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16993 [(set (match_dup 2) (match_dup 1))
16994 (set (match_dup 0) (match_dup 2))])
16996 ;; Don't compare memory with zero, load and use a test instead.
16998 [(set (match_operand 0 "flags_reg_operand")
16999 (match_operator 1 "compare_operator"
17000 [(match_operand:SI 2 "memory_operand")
17002 (match_scratch:SI 3 "r")]
17003 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17004 [(set (match_dup 3) (match_dup 2))
17005 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17007 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17008 ;; Don't split NOTs with a displacement operand, because resulting XOR
17009 ;; will not be pairable anyway.
17011 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17012 ;; represented using a modRM byte. The XOR replacement is long decoded,
17013 ;; so this split helps here as well.
17015 ;; Note: Can't do this as a regular split because we can't get proper
17016 ;; lifetime information then.
17019 [(set (match_operand:SWI124 0 "nonimmediate_operand")
17020 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand")))]
17021 "optimize_insn_for_speed_p ()
17022 && ((TARGET_NOT_UNPAIRABLE
17023 && (!MEM_P (operands[0])
17024 || !memory_displacement_operand (operands[0], <MODE>mode)))
17025 || (TARGET_NOT_VECTORMODE
17026 && long_memory_operand (operands[0], <MODE>mode)))
17027 && peep2_regno_dead_p (0, FLAGS_REG)"
17028 [(parallel [(set (match_dup 0)
17029 (xor:SWI124 (match_dup 1) (const_int -1)))
17030 (clobber (reg:CC FLAGS_REG))])])
17032 ;; Non pairable "test imm, reg" instructions can be translated to
17033 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17034 ;; byte opcode instead of two, have a short form for byte operands),
17035 ;; so do it for other CPUs as well. Given that the value was dead,
17036 ;; this should not create any new dependencies. Pass on the sub-word
17037 ;; versions if we're concerned about partial register stalls.
17040 [(set (match_operand 0 "flags_reg_operand")
17041 (match_operator 1 "compare_operator"
17042 [(and:SI (match_operand:SI 2 "register_operand")
17043 (match_operand:SI 3 "immediate_operand"))
17045 "ix86_match_ccmode (insn, CCNOmode)
17046 && (true_regnum (operands[2]) != AX_REG
17047 || satisfies_constraint_K (operands[3]))
17048 && peep2_reg_dead_p (1, operands[2])"
17050 [(set (match_dup 0)
17051 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17054 (and:SI (match_dup 2) (match_dup 3)))])])
17056 ;; We don't need to handle HImode case, because it will be promoted to SImode
17057 ;; on ! TARGET_PARTIAL_REG_STALL
17060 [(set (match_operand 0 "flags_reg_operand")
17061 (match_operator 1 "compare_operator"
17062 [(and:QI (match_operand:QI 2 "register_operand")
17063 (match_operand:QI 3 "immediate_operand"))
17065 "! TARGET_PARTIAL_REG_STALL
17066 && ix86_match_ccmode (insn, CCNOmode)
17067 && true_regnum (operands[2]) != AX_REG
17068 && peep2_reg_dead_p (1, operands[2])"
17070 [(set (match_dup 0)
17071 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17074 (and:QI (match_dup 2) (match_dup 3)))])])
17077 [(set (match_operand 0 "flags_reg_operand")
17078 (match_operator 1 "compare_operator"
17081 (match_operand 2 "ext_register_operand")
17084 (match_operand 3 "const_int_operand"))
17086 "! TARGET_PARTIAL_REG_STALL
17087 && ix86_match_ccmode (insn, CCNOmode)
17088 && true_regnum (operands[2]) != AX_REG
17089 && peep2_reg_dead_p (1, operands[2])"
17090 [(parallel [(set (match_dup 0)
17099 (set (zero_extract:SI (match_dup 2)
17107 (match_dup 3)))])])
17109 ;; Don't do logical operations with memory inputs.
17111 [(match_scratch:SI 2 "r")
17112 (parallel [(set (match_operand:SI 0 "register_operand")
17113 (match_operator:SI 3 "arith_or_logical_operator"
17115 (match_operand:SI 1 "memory_operand")]))
17116 (clobber (reg:CC FLAGS_REG))])]
17117 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17118 [(set (match_dup 2) (match_dup 1))
17119 (parallel [(set (match_dup 0)
17120 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17121 (clobber (reg:CC FLAGS_REG))])])
17124 [(match_scratch:SI 2 "r")
17125 (parallel [(set (match_operand:SI 0 "register_operand")
17126 (match_operator:SI 3 "arith_or_logical_operator"
17127 [(match_operand:SI 1 "memory_operand")
17129 (clobber (reg:CC FLAGS_REG))])]
17130 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17131 [(set (match_dup 2) (match_dup 1))
17132 (parallel [(set (match_dup 0)
17133 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17134 (clobber (reg:CC FLAGS_REG))])])
17136 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17137 ;; refers to the destination of the load!
17140 [(set (match_operand:SI 0 "register_operand")
17141 (match_operand:SI 1 "register_operand"))
17142 (parallel [(set (match_dup 0)
17143 (match_operator:SI 3 "commutative_operator"
17145 (match_operand:SI 2 "memory_operand")]))
17146 (clobber (reg:CC FLAGS_REG))])]
17147 "REGNO (operands[0]) != REGNO (operands[1])
17148 && GENERAL_REGNO_P (REGNO (operands[0]))
17149 && GENERAL_REGNO_P (REGNO (operands[1]))"
17150 [(set (match_dup 0) (match_dup 4))
17151 (parallel [(set (match_dup 0)
17152 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17153 (clobber (reg:CC FLAGS_REG))])]
17154 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17157 [(set (match_operand 0 "register_operand")
17158 (match_operand 1 "register_operand"))
17160 (match_operator 3 "commutative_operator"
17162 (match_operand 2 "memory_operand")]))]
17163 "REGNO (operands[0]) != REGNO (operands[1])
17164 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17165 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17166 [(set (match_dup 0) (match_dup 2))
17168 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17170 ; Don't do logical operations with memory outputs
17172 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17173 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17174 ; the same decoder scheduling characteristics as the original.
17177 [(match_scratch:SI 2 "r")
17178 (parallel [(set (match_operand:SI 0 "memory_operand")
17179 (match_operator:SI 3 "arith_or_logical_operator"
17181 (match_operand:SI 1 "nonmemory_operand")]))
17182 (clobber (reg:CC FLAGS_REG))])]
17183 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17184 /* Do not split stack checking probes. */
17185 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17186 [(set (match_dup 2) (match_dup 0))
17187 (parallel [(set (match_dup 2)
17188 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17189 (clobber (reg:CC FLAGS_REG))])
17190 (set (match_dup 0) (match_dup 2))])
17193 [(match_scratch:SI 2 "r")
17194 (parallel [(set (match_operand:SI 0 "memory_operand")
17195 (match_operator:SI 3 "arith_or_logical_operator"
17196 [(match_operand:SI 1 "nonmemory_operand")
17198 (clobber (reg:CC FLAGS_REG))])]
17199 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17200 /* Do not split stack checking probes. */
17201 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17202 [(set (match_dup 2) (match_dup 0))
17203 (parallel [(set (match_dup 2)
17204 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17205 (clobber (reg:CC FLAGS_REG))])
17206 (set (match_dup 0) (match_dup 2))])
17208 ;; Attempt to use arith or logical operations with memory outputs with
17209 ;; setting of flags.
17211 [(set (match_operand:SWI 0 "register_operand")
17212 (match_operand:SWI 1 "memory_operand"))
17213 (parallel [(set (match_dup 0)
17214 (match_operator:SWI 3 "plusminuslogic_operator"
17216 (match_operand:SWI 2 "<nonmemory_operand>")]))
17217 (clobber (reg:CC FLAGS_REG))])
17218 (set (match_dup 1) (match_dup 0))
17219 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17220 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17221 && peep2_reg_dead_p (4, operands[0])
17222 && !reg_overlap_mentioned_p (operands[0], operands[1])
17223 && ix86_match_ccmode (peep2_next_insn (3),
17224 (GET_CODE (operands[3]) == PLUS
17225 || GET_CODE (operands[3]) == MINUS)
17226 ? CCGOCmode : CCNOmode)"
17227 [(parallel [(set (match_dup 4) (match_dup 5))
17228 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17229 (match_dup 2)]))])]
17231 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17232 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17233 copy_rtx (operands[1]),
17234 copy_rtx (operands[2]));
17235 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17236 operands[5], const0_rtx);
17240 [(parallel [(set (match_operand:SWI 0 "register_operand")
17241 (match_operator:SWI 2 "plusminuslogic_operator"
17243 (match_operand:SWI 1 "memory_operand")]))
17244 (clobber (reg:CC FLAGS_REG))])
17245 (set (match_dup 1) (match_dup 0))
17246 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17247 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17248 && GET_CODE (operands[2]) != MINUS
17249 && peep2_reg_dead_p (3, operands[0])
17250 && !reg_overlap_mentioned_p (operands[0], operands[1])
17251 && ix86_match_ccmode (peep2_next_insn (2),
17252 GET_CODE (operands[2]) == PLUS
17253 ? CCGOCmode : CCNOmode)"
17254 [(parallel [(set (match_dup 3) (match_dup 4))
17255 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17256 (match_dup 0)]))])]
17258 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17259 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17260 copy_rtx (operands[1]),
17261 copy_rtx (operands[0]));
17262 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17263 operands[4], const0_rtx);
17267 [(set (match_operand:SWI12 0 "register_operand")
17268 (match_operand:SWI12 1 "memory_operand"))
17269 (parallel [(set (match_operand:SI 4 "register_operand")
17270 (match_operator:SI 3 "plusminuslogic_operator"
17272 (match_operand:SI 2 "nonmemory_operand")]))
17273 (clobber (reg:CC FLAGS_REG))])
17274 (set (match_dup 1) (match_dup 0))
17275 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17276 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17277 && REG_P (operands[0]) && REG_P (operands[4])
17278 && REGNO (operands[0]) == REGNO (operands[4])
17279 && peep2_reg_dead_p (4, operands[0])
17280 && (<MODE>mode != QImode
17281 || immediate_operand (operands[2], SImode)
17282 || q_regs_operand (operands[2], SImode))
17283 && !reg_overlap_mentioned_p (operands[0], operands[1])
17284 && ix86_match_ccmode (peep2_next_insn (3),
17285 (GET_CODE (operands[3]) == PLUS
17286 || GET_CODE (operands[3]) == MINUS)
17287 ? CCGOCmode : CCNOmode)"
17288 [(parallel [(set (match_dup 4) (match_dup 5))
17289 (set (match_dup 1) (match_dup 6))])]
17291 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17292 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17293 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17294 copy_rtx (operands[1]), operands[2]);
17295 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17296 operands[5], const0_rtx);
17297 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17298 copy_rtx (operands[1]),
17299 copy_rtx (operands[2]));
17302 ;; Attempt to always use XOR for zeroing registers.
17304 [(set (match_operand 0 "register_operand")
17305 (match_operand 1 "const0_operand"))]
17306 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17307 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17308 && GENERAL_REG_P (operands[0])
17309 && peep2_regno_dead_p (0, FLAGS_REG)"
17310 [(parallel [(set (match_dup 0) (const_int 0))
17311 (clobber (reg:CC FLAGS_REG))])]
17312 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17315 [(set (strict_low_part (match_operand 0 "register_operand"))
17317 "(GET_MODE (operands[0]) == QImode
17318 || GET_MODE (operands[0]) == HImode)
17319 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17320 && peep2_regno_dead_p (0, FLAGS_REG)"
17321 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17322 (clobber (reg:CC FLAGS_REG))])])
17324 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17326 [(set (match_operand:SWI248 0 "register_operand")
17328 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17329 && peep2_regno_dead_p (0, FLAGS_REG)"
17330 [(parallel [(set (match_dup 0) (const_int -1))
17331 (clobber (reg:CC FLAGS_REG))])]
17333 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17334 operands[0] = gen_lowpart (SImode, operands[0]);
17337 ;; Attempt to convert simple lea to add/shift.
17338 ;; These can be created by move expanders.
17341 [(set (match_operand:SWI48 0 "register_operand")
17342 (plus:SWI48 (match_dup 0)
17343 (match_operand:SWI48 1 "<nonmemory_operand>")))]
17344 "peep2_regno_dead_p (0, FLAGS_REG)"
17345 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17346 (clobber (reg:CC FLAGS_REG))])])
17349 [(set (match_operand:SI 0 "register_operand")
17350 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand")
17351 (match_operand:DI 2 "nonmemory_operand")) 0))]
17353 && peep2_regno_dead_p (0, FLAGS_REG)
17354 && REGNO (operands[0]) == REGNO (operands[1])"
17355 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17356 (clobber (reg:CC FLAGS_REG))])]
17357 "operands[2] = gen_lowpart (SImode, operands[2]);")
17360 [(set (match_operand:SWI48 0 "register_operand")
17361 (mult:SWI48 (match_dup 0)
17362 (match_operand:SWI48 1 "const_int_operand")))]
17363 "exact_log2 (INTVAL (operands[1])) >= 0
17364 && peep2_regno_dead_p (0, FLAGS_REG)"
17365 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17366 (clobber (reg:CC FLAGS_REG))])]
17367 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17370 [(set (match_operand:SI 0 "register_operand")
17371 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand")
17372 (match_operand:DI 2 "const_int_operand")) 0))]
17374 && exact_log2 (INTVAL (operands[2])) >= 0
17375 && REGNO (operands[0]) == REGNO (operands[1])
17376 && peep2_regno_dead_p (0, FLAGS_REG)"
17377 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17378 (clobber (reg:CC FLAGS_REG))])]
17379 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17381 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17382 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17383 ;; On many CPUs it is also faster, since special hardware to avoid esp
17384 ;; dependencies is present.
17386 ;; While some of these conversions may be done using splitters, we use
17387 ;; peepholes in order to allow combine_stack_adjustments pass to see
17388 ;; nonobfuscated RTL.
17390 ;; Convert prologue esp subtractions to push.
17391 ;; We need register to push. In order to keep verify_flow_info happy we have
17393 ;; - use scratch and clobber it in order to avoid dependencies
17394 ;; - use already live register
17395 ;; We can't use the second way right now, since there is no reliable way how to
17396 ;; verify that given register is live. First choice will also most likely in
17397 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17398 ;; call clobbered registers are dead. We may want to use base pointer as an
17399 ;; alternative when no register is available later.
17402 [(match_scratch:W 1 "r")
17403 (parallel [(set (reg:P SP_REG)
17404 (plus:P (reg:P SP_REG)
17405 (match_operand:P 0 "const_int_operand")))
17406 (clobber (reg:CC FLAGS_REG))
17407 (clobber (mem:BLK (scratch)))])]
17408 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17409 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17410 [(clobber (match_dup 1))
17411 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17412 (clobber (mem:BLK (scratch)))])])
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 (clobber (mem:BLK (scratch)))])]
17421 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17422 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17423 [(clobber (match_dup 1))
17424 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17425 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17426 (clobber (mem:BLK (scratch)))])])
17428 ;; Convert esp subtractions to push.
17430 [(match_scratch:W 1 "r")
17431 (parallel [(set (reg:P SP_REG)
17432 (plus:P (reg:P SP_REG)
17433 (match_operand:P 0 "const_int_operand")))
17434 (clobber (reg:CC FLAGS_REG))])]
17435 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17436 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17437 [(clobber (match_dup 1))
17438 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17441 [(match_scratch:W 1 "r")
17442 (parallel [(set (reg:P SP_REG)
17443 (plus:P (reg:P SP_REG)
17444 (match_operand:P 0 "const_int_operand")))
17445 (clobber (reg:CC FLAGS_REG))])]
17446 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17447 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17448 [(clobber (match_dup 1))
17449 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17450 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17452 ;; Convert epilogue deallocator to pop.
17454 [(match_scratch:W 1 "r")
17455 (parallel [(set (reg:P SP_REG)
17456 (plus:P (reg:P SP_REG)
17457 (match_operand:P 0 "const_int_operand")))
17458 (clobber (reg:CC FLAGS_REG))
17459 (clobber (mem:BLK (scratch)))])]
17460 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17461 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17462 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17463 (clobber (mem:BLK (scratch)))])])
17465 ;; Two pops case is tricky, since pop causes dependency
17466 ;; on destination register. We use two registers if available.
17468 [(match_scratch:W 1 "r")
17469 (match_scratch:W 2 "r")
17470 (parallel [(set (reg:P SP_REG)
17471 (plus:P (reg:P SP_REG)
17472 (match_operand:P 0 "const_int_operand")))
17473 (clobber (reg:CC FLAGS_REG))
17474 (clobber (mem:BLK (scratch)))])]
17475 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17476 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17477 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17478 (clobber (mem:BLK (scratch)))])
17479 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17482 [(match_scratch:W 1 "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 (clobber (mem:BLK (scratch)))])]
17488 "optimize_insn_for_size_p ()
17489 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17490 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17491 (clobber (mem:BLK (scratch)))])
17492 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17494 ;; Convert esp additions to pop.
17496 [(match_scratch:W 1 "r")
17497 (parallel [(set (reg:P SP_REG)
17498 (plus:P (reg:P SP_REG)
17499 (match_operand:P 0 "const_int_operand")))
17500 (clobber (reg:CC FLAGS_REG))])]
17501 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17502 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17504 ;; Two pops case is tricky, since pop causes dependency
17505 ;; on destination register. We use two registers if available.
17507 [(match_scratch:W 1 "r")
17508 (match_scratch:W 2 "r")
17509 (parallel [(set (reg:P SP_REG)
17510 (plus:P (reg:P SP_REG)
17511 (match_operand:P 0 "const_int_operand")))
17512 (clobber (reg:CC FLAGS_REG))])]
17513 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17514 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17515 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17518 [(match_scratch:W 1 "r")
17519 (parallel [(set (reg:P SP_REG)
17520 (plus:P (reg:P SP_REG)
17521 (match_operand:P 0 "const_int_operand")))
17522 (clobber (reg:CC FLAGS_REG))])]
17523 "optimize_insn_for_size_p ()
17524 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17525 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17526 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17528 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17529 ;; required and register dies. Similarly for 128 to -128.
17531 [(set (match_operand 0 "flags_reg_operand")
17532 (match_operator 1 "compare_operator"
17533 [(match_operand 2 "register_operand")
17534 (match_operand 3 "const_int_operand")]))]
17535 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17536 && incdec_operand (operands[3], GET_MODE (operands[3])))
17537 || (!TARGET_FUSE_CMP_AND_BRANCH
17538 && INTVAL (operands[3]) == 128))
17539 && ix86_match_ccmode (insn, CCGCmode)
17540 && peep2_reg_dead_p (1, operands[2])"
17541 [(parallel [(set (match_dup 0)
17542 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17543 (clobber (match_dup 2))])])
17545 ;; Convert imul by three, five and nine into lea
17548 [(set (match_operand:SWI48 0 "register_operand")
17549 (mult:SWI48 (match_operand:SWI48 1 "register_operand")
17550 (match_operand:SWI48 2 "const359_operand")))
17551 (clobber (reg:CC FLAGS_REG))])]
17552 "!TARGET_PARTIAL_REG_STALL
17553 || <MODE>mode == SImode
17554 || optimize_function_for_size_p (cfun)"
17555 [(set (match_dup 0)
17556 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17558 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17562 [(set (match_operand:SWI48 0 "register_operand")
17563 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand")
17564 (match_operand:SWI48 2 "const359_operand")))
17565 (clobber (reg:CC FLAGS_REG))])]
17566 "optimize_insn_for_speed_p ()
17567 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17568 [(set (match_dup 0) (match_dup 1))
17570 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17572 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17574 ;; imul $32bit_imm, mem, reg is vector decoded, while
17575 ;; imul $32bit_imm, reg, reg is direct decoded.
17577 [(match_scratch:SWI48 3 "r")
17578 (parallel [(set (match_operand:SWI48 0 "register_operand")
17579 (mult:SWI48 (match_operand:SWI48 1 "memory_operand")
17580 (match_operand:SWI48 2 "immediate_operand")))
17581 (clobber (reg:CC FLAGS_REG))])]
17582 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17583 && !satisfies_constraint_K (operands[2])"
17584 [(set (match_dup 3) (match_dup 1))
17585 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17586 (clobber (reg:CC FLAGS_REG))])])
17589 [(match_scratch:SI 3 "r")
17590 (parallel [(set (match_operand:DI 0 "register_operand")
17592 (mult:SI (match_operand:SI 1 "memory_operand")
17593 (match_operand:SI 2 "immediate_operand"))))
17594 (clobber (reg:CC FLAGS_REG))])]
17596 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17597 && !satisfies_constraint_K (operands[2])"
17598 [(set (match_dup 3) (match_dup 1))
17599 (parallel [(set (match_dup 0)
17600 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17601 (clobber (reg:CC FLAGS_REG))])])
17603 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17604 ;; Convert it into imul reg, reg
17605 ;; It would be better to force assembler to encode instruction using long
17606 ;; immediate, but there is apparently no way to do so.
17608 [(parallel [(set (match_operand:SWI248 0 "register_operand")
17610 (match_operand:SWI248 1 "nonimmediate_operand")
17611 (match_operand:SWI248 2 "const_int_operand")))
17612 (clobber (reg:CC FLAGS_REG))])
17613 (match_scratch:SWI248 3 "r")]
17614 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17615 && satisfies_constraint_K (operands[2])"
17616 [(set (match_dup 3) (match_dup 2))
17617 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17618 (clobber (reg:CC FLAGS_REG))])]
17620 if (!rtx_equal_p (operands[0], operands[1]))
17621 emit_move_insn (operands[0], operands[1]);
17624 ;; After splitting up read-modify operations, array accesses with memory
17625 ;; operands might end up in form:
17627 ;; movl 4(%esp), %edx
17629 ;; instead of pre-splitting:
17631 ;; addl 4(%esp), %eax
17633 ;; movl 4(%esp), %edx
17634 ;; leal (%edx,%eax,4), %eax
17637 [(match_scratch:W 5 "r")
17638 (parallel [(set (match_operand 0 "register_operand")
17639 (ashift (match_operand 1 "register_operand")
17640 (match_operand 2 "const_int_operand")))
17641 (clobber (reg:CC FLAGS_REG))])
17642 (parallel [(set (match_operand 3 "register_operand")
17643 (plus (match_dup 0)
17644 (match_operand 4 "x86_64_general_operand")))
17645 (clobber (reg:CC FLAGS_REG))])]
17646 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17647 /* Validate MODE for lea. */
17648 && ((!TARGET_PARTIAL_REG_STALL
17649 && (GET_MODE (operands[0]) == QImode
17650 || GET_MODE (operands[0]) == HImode))
17651 || GET_MODE (operands[0]) == SImode
17652 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17653 && (rtx_equal_p (operands[0], operands[3])
17654 || peep2_reg_dead_p (2, operands[0]))
17655 /* We reorder load and the shift. */
17656 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17657 [(set (match_dup 5) (match_dup 4))
17658 (set (match_dup 0) (match_dup 1))]
17660 enum machine_mode op1mode = GET_MODE (operands[1]);
17661 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17662 int scale = 1 << INTVAL (operands[2]);
17663 rtx index = gen_lowpart (word_mode, operands[1]);
17664 rtx base = gen_lowpart (word_mode, operands[5]);
17665 rtx dest = gen_lowpart (mode, operands[3]);
17667 operands[1] = gen_rtx_PLUS (word_mode, base,
17668 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17669 operands[5] = base;
17670 if (mode != word_mode)
17671 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17672 if (op1mode != word_mode)
17673 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17674 operands[0] = dest;
17677 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17678 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17679 ;; caught for use by garbage collectors and the like. Using an insn that
17680 ;; maps to SIGILL makes it more likely the program will rightfully die.
17681 ;; Keeping with tradition, "6" is in honor of #UD.
17682 (define_insn "trap"
17683 [(trap_if (const_int 1) (const_int 6))]
17685 { return ASM_SHORT "0x0b0f"; }
17686 [(set_attr "length" "2")])
17688 (define_expand "prefetch"
17689 [(prefetch (match_operand 0 "address_operand")
17690 (match_operand:SI 1 "const_int_operand")
17691 (match_operand:SI 2 "const_int_operand"))]
17692 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17694 int rw = INTVAL (operands[1]);
17695 int locality = INTVAL (operands[2]);
17697 gcc_assert (rw == 0 || rw == 1);
17698 gcc_assert (locality >= 0 && locality <= 3);
17699 gcc_assert (GET_MODE (operands[0]) == Pmode
17700 || GET_MODE (operands[0]) == VOIDmode);
17702 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17703 supported by SSE counterpart or the SSE prefetch is not available
17704 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17706 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17707 operands[2] = GEN_INT (3);
17709 operands[1] = const0_rtx;
17712 (define_insn "*prefetch_sse_<mode>"
17713 [(prefetch (match_operand:P 0 "address_operand" "p")
17715 (match_operand:SI 1 "const_int_operand"))]
17716 "TARGET_PREFETCH_SSE"
17718 static const char * const patterns[4] = {
17719 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17722 int locality = INTVAL (operands[1]);
17723 gcc_assert (locality >= 0 && locality <= 3);
17725 return patterns[locality];
17727 [(set_attr "type" "sse")
17728 (set_attr "atom_sse_attr" "prefetch")
17729 (set (attr "length_address")
17730 (symbol_ref "memory_address_length (operands[0])"))
17731 (set_attr "memory" "none")])
17733 (define_insn "*prefetch_3dnow_<mode>"
17734 [(prefetch (match_operand:P 0 "address_operand" "p")
17735 (match_operand:SI 1 "const_int_operand" "n")
17739 if (INTVAL (operands[1]) == 0)
17740 return "prefetch\t%a0";
17742 return "prefetchw\t%a0";
17744 [(set_attr "type" "mmx")
17745 (set (attr "length_address")
17746 (symbol_ref "memory_address_length (operands[0])"))
17747 (set_attr "memory" "none")])
17749 (define_expand "stack_protect_set"
17750 [(match_operand 0 "memory_operand")
17751 (match_operand 1 "memory_operand")]
17754 rtx (*insn)(rtx, rtx);
17756 #ifdef TARGET_THREAD_SSP_OFFSET
17757 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17758 insn = (TARGET_LP64
17759 ? gen_stack_tls_protect_set_di
17760 : gen_stack_tls_protect_set_si);
17762 insn = (TARGET_LP64
17763 ? gen_stack_protect_set_di
17764 : gen_stack_protect_set_si);
17767 emit_insn (insn (operands[0], operands[1]));
17771 (define_insn "stack_protect_set_<mode>"
17772 [(set (match_operand:PTR 0 "memory_operand" "=m")
17773 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17775 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17776 (clobber (reg:CC FLAGS_REG))]
17778 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17779 [(set_attr "type" "multi")])
17781 (define_insn "stack_tls_protect_set_<mode>"
17782 [(set (match_operand:PTR 0 "memory_operand" "=m")
17783 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17784 UNSPEC_SP_TLS_SET))
17785 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17786 (clobber (reg:CC FLAGS_REG))]
17788 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17789 [(set_attr "type" "multi")])
17791 (define_expand "stack_protect_test"
17792 [(match_operand 0 "memory_operand")
17793 (match_operand 1 "memory_operand")
17797 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17799 rtx (*insn)(rtx, rtx, rtx);
17801 #ifdef TARGET_THREAD_SSP_OFFSET
17802 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17803 insn = (TARGET_LP64
17804 ? gen_stack_tls_protect_test_di
17805 : gen_stack_tls_protect_test_si);
17807 insn = (TARGET_LP64
17808 ? gen_stack_protect_test_di
17809 : gen_stack_protect_test_si);
17812 emit_insn (insn (flags, operands[0], operands[1]));
17814 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17815 flags, const0_rtx, operands[2]));
17819 (define_insn "stack_protect_test_<mode>"
17820 [(set (match_operand:CCZ 0 "flags_reg_operand")
17821 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17822 (match_operand:PTR 2 "memory_operand" "m")]
17824 (clobber (match_scratch:PTR 3 "=&r"))]
17826 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17827 [(set_attr "type" "multi")])
17829 (define_insn "stack_tls_protect_test_<mode>"
17830 [(set (match_operand:CCZ 0 "flags_reg_operand")
17831 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17832 (match_operand:PTR 2 "const_int_operand" "i")]
17833 UNSPEC_SP_TLS_TEST))
17834 (clobber (match_scratch:PTR 3 "=r"))]
17836 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17837 [(set_attr "type" "multi")])
17839 (define_insn "sse4_2_crc32<mode>"
17840 [(set (match_operand:SI 0 "register_operand" "=r")
17842 [(match_operand:SI 1 "register_operand" "0")
17843 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17845 "TARGET_SSE4_2 || TARGET_CRC32"
17846 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17847 [(set_attr "type" "sselog1")
17848 (set_attr "prefix_rep" "1")
17849 (set_attr "prefix_extra" "1")
17850 (set (attr "prefix_data16")
17851 (if_then_else (match_operand:HI 2)
17853 (const_string "*")))
17854 (set (attr "prefix_rex")
17855 (if_then_else (match_operand:QI 2 "ext_QIreg_operand")
17857 (const_string "*")))
17858 (set_attr "mode" "SI")])
17860 (define_insn "sse4_2_crc32di"
17861 [(set (match_operand:DI 0 "register_operand" "=r")
17863 [(match_operand:DI 1 "register_operand" "0")
17864 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17866 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17867 "crc32{q}\t{%2, %0|%0, %2}"
17868 [(set_attr "type" "sselog1")
17869 (set_attr "prefix_rep" "1")
17870 (set_attr "prefix_extra" "1")
17871 (set_attr "mode" "DI")])
17873 (define_expand "rdpmc"
17874 [(match_operand:DI 0 "register_operand")
17875 (match_operand:SI 1 "register_operand")]
17878 rtx reg = gen_reg_rtx (DImode);
17881 /* Force operand 1 into ECX. */
17882 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17883 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17884 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17889 rtvec vec = rtvec_alloc (2);
17890 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17891 rtx upper = gen_reg_rtx (DImode);
17892 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17893 gen_rtvec (1, const0_rtx),
17895 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17896 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17898 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17899 NULL, 1, OPTAB_DIRECT);
17900 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17904 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17905 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17909 (define_insn "*rdpmc"
17910 [(set (match_operand:DI 0 "register_operand" "=A")
17911 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17915 [(set_attr "type" "other")
17916 (set_attr "length" "2")])
17918 (define_insn "*rdpmc_rex64"
17919 [(set (match_operand:DI 0 "register_operand" "=a")
17920 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17922 (set (match_operand:DI 1 "register_operand" "=d")
17923 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17926 [(set_attr "type" "other")
17927 (set_attr "length" "2")])
17929 (define_expand "rdtsc"
17930 [(set (match_operand:DI 0 "register_operand")
17931 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17936 rtvec vec = rtvec_alloc (2);
17937 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17938 rtx upper = gen_reg_rtx (DImode);
17939 rtx lower = gen_reg_rtx (DImode);
17940 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17941 gen_rtvec (1, const0_rtx),
17943 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17944 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17946 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17947 NULL, 1, OPTAB_DIRECT);
17948 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17950 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17955 (define_insn "*rdtsc"
17956 [(set (match_operand:DI 0 "register_operand" "=A")
17957 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17960 [(set_attr "type" "other")
17961 (set_attr "length" "2")])
17963 (define_insn "*rdtsc_rex64"
17964 [(set (match_operand:DI 0 "register_operand" "=a")
17965 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17966 (set (match_operand:DI 1 "register_operand" "=d")
17967 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17970 [(set_attr "type" "other")
17971 (set_attr "length" "2")])
17973 (define_expand "rdtscp"
17974 [(match_operand:DI 0 "register_operand")
17975 (match_operand:SI 1 "memory_operand")]
17978 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17979 gen_rtvec (1, const0_rtx),
17981 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17982 gen_rtvec (1, const0_rtx),
17984 rtx reg = gen_reg_rtx (DImode);
17985 rtx tmp = gen_reg_rtx (SImode);
17989 rtvec vec = rtvec_alloc (3);
17990 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17991 rtx upper = gen_reg_rtx (DImode);
17992 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17993 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17994 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17996 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17997 NULL, 1, OPTAB_DIRECT);
17998 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18003 rtvec vec = rtvec_alloc (2);
18004 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18005 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18006 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18009 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18010 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18014 (define_insn "*rdtscp"
18015 [(set (match_operand:DI 0 "register_operand" "=A")
18016 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18017 (set (match_operand:SI 1 "register_operand" "=c")
18018 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18021 [(set_attr "type" "other")
18022 (set_attr "length" "3")])
18024 (define_insn "*rdtscp_rex64"
18025 [(set (match_operand:DI 0 "register_operand" "=a")
18026 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18027 (set (match_operand:DI 1 "register_operand" "=d")
18028 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18029 (set (match_operand:SI 2 "register_operand" "=c")
18030 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18033 [(set_attr "type" "other")
18034 (set_attr "length" "3")])
18036 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18038 ;; LWP instructions
18040 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18042 (define_expand "lwp_llwpcb"
18043 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18044 UNSPECV_LLWP_INTRINSIC)]
18047 (define_insn "*lwp_llwpcb<mode>1"
18048 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18049 UNSPECV_LLWP_INTRINSIC)]
18052 [(set_attr "type" "lwp")
18053 (set_attr "mode" "<MODE>")
18054 (set_attr "length" "5")])
18056 (define_expand "lwp_slwpcb"
18057 [(set (match_operand 0 "register_operand" "=r")
18058 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18063 insn = (Pmode == DImode
18065 : gen_lwp_slwpcbsi);
18067 emit_insn (insn (operands[0]));
18071 (define_insn "lwp_slwpcb<mode>"
18072 [(set (match_operand:P 0 "register_operand" "=r")
18073 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18076 [(set_attr "type" "lwp")
18077 (set_attr "mode" "<MODE>")
18078 (set_attr "length" "5")])
18080 (define_expand "lwp_lwpval<mode>3"
18081 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18082 (match_operand:SI 2 "nonimmediate_operand" "rm")
18083 (match_operand:SI 3 "const_int_operand" "i")]
18084 UNSPECV_LWPVAL_INTRINSIC)]
18086 ;; Avoid unused variable warning.
18087 "(void) operands[0];")
18089 (define_insn "*lwp_lwpval<mode>3_1"
18090 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18091 (match_operand:SI 1 "nonimmediate_operand" "rm")
18092 (match_operand:SI 2 "const_int_operand" "i")]
18093 UNSPECV_LWPVAL_INTRINSIC)]
18095 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18096 [(set_attr "type" "lwp")
18097 (set_attr "mode" "<MODE>")
18098 (set (attr "length")
18099 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18101 (define_expand "lwp_lwpins<mode>3"
18102 [(set (reg:CCC FLAGS_REG)
18103 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18104 (match_operand:SI 2 "nonimmediate_operand" "rm")
18105 (match_operand:SI 3 "const_int_operand" "i")]
18106 UNSPECV_LWPINS_INTRINSIC))
18107 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18108 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18111 (define_insn "*lwp_lwpins<mode>3_1"
18112 [(set (reg:CCC FLAGS_REG)
18113 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18114 (match_operand:SI 1 "nonimmediate_operand" "rm")
18115 (match_operand:SI 2 "const_int_operand" "i")]
18116 UNSPECV_LWPINS_INTRINSIC))]
18118 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18119 [(set_attr "type" "lwp")
18120 (set_attr "mode" "<MODE>")
18121 (set (attr "length")
18122 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18124 (define_insn "rdfsbase<mode>"
18125 [(set (match_operand:SWI48 0 "register_operand" "=r")
18126 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18127 "TARGET_64BIT && TARGET_FSGSBASE"
18129 [(set_attr "type" "other")
18130 (set_attr "prefix_extra" "2")])
18132 (define_insn "rdgsbase<mode>"
18133 [(set (match_operand:SWI48 0 "register_operand" "=r")
18134 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18135 "TARGET_64BIT && TARGET_FSGSBASE"
18137 [(set_attr "type" "other")
18138 (set_attr "prefix_extra" "2")])
18140 (define_insn "wrfsbase<mode>"
18141 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18143 "TARGET_64BIT && TARGET_FSGSBASE"
18145 [(set_attr "type" "other")
18146 (set_attr "prefix_extra" "2")])
18148 (define_insn "wrgsbase<mode>"
18149 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18151 "TARGET_64BIT && TARGET_FSGSBASE"
18153 [(set_attr "type" "other")
18154 (set_attr "prefix_extra" "2")])
18156 (define_insn "rdrand<mode>_1"
18157 [(set (match_operand:SWI248 0 "register_operand" "=r")
18158 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18159 (set (reg:CCC FLAGS_REG)
18160 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18163 [(set_attr "type" "other")
18164 (set_attr "prefix_extra" "1")])
18166 (define_expand "pause"
18167 [(set (match_dup 0)
18168 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18171 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18172 MEM_VOLATILE_P (operands[0]) = 1;
18175 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18176 ;; They have the same encoding.
18177 (define_insn "*pause"
18178 [(set (match_operand:BLK 0)
18179 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18182 [(set_attr "length" "2")
18183 (set_attr "memory" "unknown")])
18185 (define_expand "xbegin"
18186 [(set (match_operand:SI 0 "register_operand")
18187 (unspec_volatile:SI [(match_dup 1)] UNSPECV_XBEGIN))]
18190 rtx label = gen_label_rtx ();
18192 operands[1] = force_reg (SImode, constm1_rtx);
18194 emit_jump_insn (gen_xbegin_1 (operands[0], operands[1], label));
18196 emit_label (label);
18197 LABEL_NUSES (label) = 1;
18202 (define_insn "xbegin_1"
18204 (if_then_else (ne (unspec [(const_int 0)] UNSPEC_XBEGIN_ABORT)
18206 (label_ref (match_operand 2))
18208 (set (match_operand:SI 0 "register_operand" "=a")
18209 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18213 [(set_attr "type" "other")
18214 (set_attr "length" "6")])
18216 (define_insn "xend"
18217 [(unspec_volatile [(const_int 0)] UNSPECV_XEND)]
18220 [(set_attr "type" "other")
18221 (set_attr "length" "3")])
18223 (define_insn "xabort"
18224 [(unspec_volatile [(match_operand:SI 0 "const_0_to_255_operand" "n")]
18228 [(set_attr "type" "other")
18229 (set_attr "length" "3")])
18231 (define_expand "xtest"
18232 [(set (match_operand:QI 0 "register_operand")
18233 (unspec_volatile:QI [(const_int 0)] UNSPECV_XTEST))]
18236 emit_insn (gen_xtest_1 ());
18238 ix86_expand_setcc (operands[0], EQ,
18239 gen_rtx_REG (CCZmode, FLAGS_REG), const0_rtx);
18243 (define_insn "xtest_1"
18244 [(set (reg:CCZ FLAGS_REG)
18245 (unspec_volatile:CCZ [(const_int 0)] UNSPECV_XTEST))]
18248 [(set_attr "type" "other")
18249 (set_attr "length" "3")])
18253 (include "sync.md")