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 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; p -- print raw symbol name.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
63 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
64 ;; @ -- print a segment register of thread base pointer load
65 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
67 (define_c_enum "unspec" [
68 ;; Relocation specifiers
79 UNSPEC_MACHOPIC_OFFSET
89 UNSPEC_MEMORY_BLOCKAGE
99 ;; Other random patterns
108 UNSPEC_LD_MPIC ; load_macho_picbase
110 UNSPEC_DIV_ALREADY_SPLIT
111 UNSPEC_MS_TO_SYSV_CALL
112 UNSPEC_CALL_NEEDS_VZEROUPPER
115 ;; For SSE/MMX support:
123 ;; Generic math support
125 UNSPEC_IEEE_MIN ; not commutative
126 UNSPEC_IEEE_MAX ; not commutative
128 ;; x87 Floating point
144 UNSPEC_FRNDINT_MASK_PM
148 ;; x87 Double output FP
175 ;; For RDRAND support
186 (define_c_enum "unspecv" [
189 UNSPECV_PROBE_STACK_RANGE
192 UNSPECV_SPLIT_STACK_RETURN
198 UNSPECV_LLWP_INTRINSIC
199 UNSPECV_SLWP_INTRINSIC
200 UNSPECV_LWPVAL_INTRINSIC
201 UNSPECV_LWPINS_INTRINSIC
208 ;; Constants to represent rounding modes in the ROUND instruction
217 ;; Constants to represent pcomtrue/pcomfalse variants
227 ;; Constants used in the XOP pperm instruction
229 [(PPERM_SRC 0x00) /* copy source */
230 (PPERM_INVERT 0x20) /* invert source */
231 (PPERM_REVERSE 0x40) /* bit reverse source */
232 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
233 (PPERM_ZERO 0x80) /* all 0's */
234 (PPERM_ONES 0xa0) /* all 1's */
235 (PPERM_SIGN 0xc0) /* propagate sign bit */
236 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
237 (PPERM_SRC1 0x00) /* use first source byte */
238 (PPERM_SRC2 0x10) /* use second source byte */
241 ;; Registers by name.
294 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
297 ;; In C guard expressions, put expressions which may be compile-time
298 ;; constants first. This allows for better optimization. For
299 ;; example, write "TARGET_64BIT && reload_completed", not
300 ;; "reload_completed && TARGET_64BIT".
304 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
305 atom,generic64,amdfam10,bdver1,bdver2,btver1"
306 (const (symbol_ref "ix86_schedule")))
308 ;; A basic instruction type. Refinements due to arguments to be
309 ;; provided in other attributes.
312 alu,alu1,negnot,imov,imovx,lea,
313 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
314 icmp,test,ibr,setcc,icmov,
315 push,pop,call,callv,leave,
317 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
318 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
319 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
320 ssemuladd,sse4arg,lwp,
321 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
322 (const_string "other"))
324 ;; Main data type used by the insn
326 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
327 (const_string "unknown"))
329 ;; The CPU unit operations uses.
330 (define_attr "unit" "integer,i387,sse,mmx,unknown"
331 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
332 (const_string "i387")
333 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
334 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
335 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
337 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
339 (eq_attr "type" "other")
340 (const_string "unknown")]
341 (const_string "integer")))
343 ;; The (bounding maximum) length of an instruction immediate.
344 (define_attr "length_immediate" ""
345 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
348 (eq_attr "unit" "i387,sse,mmx")
350 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
351 rotate,rotatex,rotate1,imul,icmp,push,pop")
352 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
353 (eq_attr "type" "imov,test")
354 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
355 (eq_attr "type" "call")
356 (if_then_else (match_operand 0 "constant_call_address_operand" "")
359 (eq_attr "type" "callv")
360 (if_then_else (match_operand 1 "constant_call_address_operand" "")
363 ;; We don't know the size before shorten_branches. Expect
364 ;; the instruction to fit for better scheduling.
365 (eq_attr "type" "ibr")
368 (symbol_ref "/* Update immediate_length and other attributes! */
369 gcc_unreachable (),1")))
371 ;; The (bounding maximum) length of an instruction address.
372 (define_attr "length_address" ""
373 (cond [(eq_attr "type" "str,other,multi,fxch")
375 (and (eq_attr "type" "call")
376 (match_operand 0 "constant_call_address_operand" ""))
378 (and (eq_attr "type" "callv")
379 (match_operand 1 "constant_call_address_operand" ""))
382 (symbol_ref "ix86_attr_length_address_default (insn)")))
384 ;; Set when length prefix is used.
385 (define_attr "prefix_data16" ""
386 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
388 (eq_attr "mode" "HI")
390 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
395 ;; Set when string REP prefix is used.
396 (define_attr "prefix_rep" ""
397 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
399 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
404 ;; Set when 0f opcode prefix is used.
405 (define_attr "prefix_0f" ""
407 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
408 (eq_attr "unit" "sse,mmx"))
412 ;; Set when REX opcode prefix is used.
413 (define_attr "prefix_rex" ""
414 (cond [(not (match_test "TARGET_64BIT"))
416 (and (eq_attr "mode" "DI")
417 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
418 (eq_attr "unit" "!mmx")))
420 (and (eq_attr "mode" "QI")
421 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
423 (match_test "x86_extended_reg_mentioned_p (insn)")
425 (and (eq_attr "type" "imovx")
426 (match_operand:QI 1 "ext_QIreg_operand" ""))
431 ;; There are also additional prefixes in 3DNOW, SSSE3.
432 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
433 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
434 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
435 (define_attr "prefix_extra" ""
436 (cond [(eq_attr "type" "ssemuladd,sse4arg")
438 (eq_attr "type" "sseiadd1,ssecvt1")
443 ;; Prefix used: original, VEX or maybe VEX.
444 (define_attr "prefix" "orig,vex,maybe_vex"
445 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
447 (const_string "orig")))
449 ;; VEX W bit is used.
450 (define_attr "prefix_vex_w" "" (const_int 0))
452 ;; The length of VEX prefix
453 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
454 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
455 ;; still prefix_0f 1, with prefix_extra 1.
456 (define_attr "length_vex" ""
457 (if_then_else (and (eq_attr "prefix_0f" "1")
458 (eq_attr "prefix_extra" "0"))
459 (if_then_else (eq_attr "prefix_vex_w" "1")
460 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
461 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
462 (if_then_else (eq_attr "prefix_vex_w" "1")
463 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
464 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
466 ;; Set when modrm byte is used.
467 (define_attr "modrm" ""
468 (cond [(eq_attr "type" "str,leave")
470 (eq_attr "unit" "i387")
472 (and (eq_attr "type" "incdec")
473 (and (not (match_test "TARGET_64BIT"))
474 (ior (match_operand:SI 1 "register_operand" "")
475 (match_operand:HI 1 "register_operand" ""))))
477 (and (eq_attr "type" "push")
478 (not (match_operand 1 "memory_operand" "")))
480 (and (eq_attr "type" "pop")
481 (not (match_operand 0 "memory_operand" "")))
483 (and (eq_attr "type" "imov")
484 (and (not (eq_attr "mode" "DI"))
485 (ior (and (match_operand 0 "register_operand" "")
486 (match_operand 1 "immediate_operand" ""))
487 (ior (and (match_operand 0 "ax_reg_operand" "")
488 (match_operand 1 "memory_displacement_only_operand" ""))
489 (and (match_operand 0 "memory_displacement_only_operand" "")
490 (match_operand 1 "ax_reg_operand" ""))))))
492 (and (eq_attr "type" "call")
493 (match_operand 0 "constant_call_address_operand" ""))
495 (and (eq_attr "type" "callv")
496 (match_operand 1 "constant_call_address_operand" ""))
498 (and (eq_attr "type" "alu,alu1,icmp,test")
499 (match_operand 0 "ax_reg_operand" ""))
500 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
504 ;; The (bounding maximum) length of an instruction in bytes.
505 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
506 ;; Later we may want to split them and compute proper length as for
508 (define_attr "length" ""
509 (cond [(eq_attr "type" "other,multi,fistp,frndint")
511 (eq_attr "type" "fcmp")
513 (eq_attr "unit" "i387")
515 (plus (attr "prefix_data16")
516 (attr "length_address")))
517 (ior (eq_attr "prefix" "vex")
518 (and (eq_attr "prefix" "maybe_vex")
519 (match_test "TARGET_AVX")))
520 (plus (attr "length_vex")
521 (plus (attr "length_immediate")
523 (attr "length_address"))))]
524 (plus (plus (attr "modrm")
525 (plus (attr "prefix_0f")
526 (plus (attr "prefix_rex")
527 (plus (attr "prefix_extra")
529 (plus (attr "prefix_rep")
530 (plus (attr "prefix_data16")
531 (plus (attr "length_immediate")
532 (attr "length_address")))))))
534 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
535 ;; `store' if there is a simple memory reference therein, or `unknown'
536 ;; if the instruction is complex.
538 (define_attr "memory" "none,load,store,both,unknown"
539 (cond [(eq_attr "type" "other,multi,str,lwp")
540 (const_string "unknown")
541 (eq_attr "type" "lea,fcmov,fpspc")
542 (const_string "none")
543 (eq_attr "type" "fistp,leave")
544 (const_string "both")
545 (eq_attr "type" "frndint")
546 (const_string "load")
547 (eq_attr "type" "push")
548 (if_then_else (match_operand 1 "memory_operand" "")
549 (const_string "both")
550 (const_string "store"))
551 (eq_attr "type" "pop")
552 (if_then_else (match_operand 0 "memory_operand" "")
553 (const_string "both")
554 (const_string "load"))
555 (eq_attr "type" "setcc")
556 (if_then_else (match_operand 0 "memory_operand" "")
557 (const_string "store")
558 (const_string "none"))
559 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
560 (if_then_else (ior (match_operand 0 "memory_operand" "")
561 (match_operand 1 "memory_operand" ""))
562 (const_string "load")
563 (const_string "none"))
564 (eq_attr "type" "ibr")
565 (if_then_else (match_operand 0 "memory_operand" "")
566 (const_string "load")
567 (const_string "none"))
568 (eq_attr "type" "call")
569 (if_then_else (match_operand 0 "constant_call_address_operand" "")
570 (const_string "none")
571 (const_string "load"))
572 (eq_attr "type" "callv")
573 (if_then_else (match_operand 1 "constant_call_address_operand" "")
574 (const_string "none")
575 (const_string "load"))
576 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
577 (match_operand 1 "memory_operand" ""))
578 (const_string "both")
579 (and (match_operand 0 "memory_operand" "")
580 (match_operand 1 "memory_operand" ""))
581 (const_string "both")
582 (match_operand 0 "memory_operand" "")
583 (const_string "store")
584 (match_operand 1 "memory_operand" "")
585 (const_string "load")
587 "!alu1,negnot,ishift1,
588 imov,imovx,icmp,test,bitmanip,
590 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
591 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
592 (match_operand 2 "memory_operand" ""))
593 (const_string "load")
594 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
595 (match_operand 3 "memory_operand" ""))
596 (const_string "load")
598 (const_string "none")))
600 ;; Indicates if an instruction has both an immediate and a displacement.
602 (define_attr "imm_disp" "false,true,unknown"
603 (cond [(eq_attr "type" "other,multi")
604 (const_string "unknown")
605 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
606 (and (match_operand 0 "memory_displacement_operand" "")
607 (match_operand 1 "immediate_operand" "")))
608 (const_string "true")
609 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
610 (and (match_operand 0 "memory_displacement_operand" "")
611 (match_operand 2 "immediate_operand" "")))
612 (const_string "true")
614 (const_string "false")))
616 ;; Indicates if an FP operation has an integer source.
618 (define_attr "fp_int_src" "false,true"
619 (const_string "false"))
621 ;; Defines rounding mode of an FP operation.
623 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
624 (const_string "any"))
626 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
627 (define_attr "use_carry" "0,1" (const_string "0"))
629 ;; Define attribute to indicate unaligned ssemov insns
630 (define_attr "movu" "0,1" (const_string "0"))
632 ;; Used to control the "enabled" attribute on a per-instruction basis.
633 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
634 (const_string "base"))
636 (define_attr "enabled" ""
637 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
638 (eq_attr "isa" "sse2_noavx")
639 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
640 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
641 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
642 (eq_attr "isa" "sse4_noavx")
643 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
644 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
645 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
646 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
650 ;; Describe a user's asm statement.
651 (define_asm_attributes
652 [(set_attr "length" "128")
653 (set_attr "type" "multi")])
655 (define_code_iterator plusminus [plus minus])
657 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
659 ;; Base name for define_insn
660 (define_code_attr plusminus_insn
661 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
662 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
664 ;; Base name for insn mnemonic.
665 (define_code_attr plusminus_mnemonic
666 [(plus "add") (ss_plus "adds") (us_plus "addus")
667 (minus "sub") (ss_minus "subs") (us_minus "subus")])
668 (define_code_attr plusminus_carry_mnemonic
669 [(plus "adc") (minus "sbb")])
671 ;; Mark commutative operators as such in constraints.
672 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
673 (minus "") (ss_minus "") (us_minus "")])
675 ;; Mapping of max and min
676 (define_code_iterator maxmin [smax smin umax umin])
678 ;; Mapping of signed max and min
679 (define_code_iterator smaxmin [smax smin])
681 ;; Mapping of unsigned max and min
682 (define_code_iterator umaxmin [umax umin])
684 ;; Base name for integer and FP insn mnemonic
685 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
686 (umax "maxu") (umin "minu")])
687 (define_code_attr maxmin_float [(smax "max") (smin "min")])
689 ;; Mapping of logic operators
690 (define_code_iterator any_logic [and ior xor])
691 (define_code_iterator any_or [ior xor])
693 ;; Base name for insn mnemonic.
694 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
696 ;; Mapping of logic-shift operators
697 (define_code_iterator any_lshift [ashift lshiftrt])
699 ;; Mapping of shift-right operators
700 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
702 ;; Base name for define_insn
703 (define_code_attr shift_insn
704 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
706 ;; Base name for insn mnemonic.
707 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
708 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
710 ;; Mapping of rotate operators
711 (define_code_iterator any_rotate [rotate rotatert])
713 ;; Base name for define_insn
714 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
716 ;; Base name for insn mnemonic.
717 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
719 ;; Mapping of abs neg operators
720 (define_code_iterator absneg [abs neg])
722 ;; Base name for x87 insn mnemonic.
723 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
725 ;; Used in signed and unsigned widening multiplications.
726 (define_code_iterator any_extend [sign_extend zero_extend])
728 ;; Prefix for insn menmonic.
729 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
731 ;; Prefix for define_insn
732 (define_code_attr u [(sign_extend "") (zero_extend "u")])
733 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
735 ;; All integer modes.
736 (define_mode_iterator SWI1248x [QI HI SI DI])
738 ;; All integer modes without QImode.
739 (define_mode_iterator SWI248x [HI SI DI])
741 ;; All integer modes without QImode and HImode.
742 (define_mode_iterator SWI48x [SI DI])
744 ;; All integer modes without SImode and DImode.
745 (define_mode_iterator SWI12 [QI HI])
747 ;; All integer modes without DImode.
748 (define_mode_iterator SWI124 [QI HI SI])
750 ;; All integer modes without QImode and DImode.
751 (define_mode_iterator SWI24 [HI SI])
753 ;; Single word integer modes.
754 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
756 ;; Single word integer modes without QImode.
757 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
759 ;; Single word integer modes without QImode and HImode.
760 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
762 ;; All math-dependant single and double word integer modes.
763 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
764 (HI "TARGET_HIMODE_MATH")
765 SI DI (TI "TARGET_64BIT")])
767 ;; Math-dependant single word integer modes.
768 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
769 (HI "TARGET_HIMODE_MATH")
770 SI (DI "TARGET_64BIT")])
772 ;; Math-dependant integer modes without DImode.
773 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
774 (HI "TARGET_HIMODE_MATH")
777 ;; Math-dependant single word integer modes without QImode.
778 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
779 SI (DI "TARGET_64BIT")])
781 ;; Double word integer modes.
782 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
783 (TI "TARGET_64BIT")])
785 ;; Double word integer modes as mode attribute.
786 (define_mode_attr DWI [(SI "DI") (DI "TI")])
787 (define_mode_attr dwi [(SI "di") (DI "ti")])
789 ;; Half mode for double word integer modes.
790 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
791 (DI "TARGET_64BIT")])
793 ;; Instruction suffix for integer modes.
794 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
796 ;; Pointer size prefix for integer modes (Intel asm dialect)
797 (define_mode_attr iptrsize [(QI "BYTE")
802 ;; Register class for integer modes.
803 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
805 ;; Immediate operand constraint for integer modes.
806 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
808 ;; General operand constraint for word modes.
809 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
811 ;; Immediate operand constraint for double integer modes.
812 (define_mode_attr di [(SI "nF") (DI "e")])
814 ;; Immediate operand constraint for shifts.
815 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
817 ;; General operand predicate for integer modes.
818 (define_mode_attr general_operand
819 [(QI "general_operand")
820 (HI "general_operand")
821 (SI "x86_64_general_operand")
822 (DI "x86_64_general_operand")
823 (TI "x86_64_general_operand")])
825 ;; General sign/zero extend operand predicate for integer modes.
826 (define_mode_attr general_szext_operand
827 [(QI "general_operand")
828 (HI "general_operand")
829 (SI "x86_64_szext_general_operand")
830 (DI "x86_64_szext_general_operand")])
832 ;; Immediate operand predicate for integer modes.
833 (define_mode_attr immediate_operand
834 [(QI "immediate_operand")
835 (HI "immediate_operand")
836 (SI "x86_64_immediate_operand")
837 (DI "x86_64_immediate_operand")])
839 ;; Nonmemory operand predicate for integer modes.
840 (define_mode_attr nonmemory_operand
841 [(QI "nonmemory_operand")
842 (HI "nonmemory_operand")
843 (SI "x86_64_nonmemory_operand")
844 (DI "x86_64_nonmemory_operand")])
846 ;; Operand predicate for shifts.
847 (define_mode_attr shift_operand
848 [(QI "nonimmediate_operand")
849 (HI "nonimmediate_operand")
850 (SI "nonimmediate_operand")
851 (DI "shiftdi_operand")
852 (TI "register_operand")])
854 ;; Operand predicate for shift argument.
855 (define_mode_attr shift_immediate_operand
856 [(QI "const_1_to_31_operand")
857 (HI "const_1_to_31_operand")
858 (SI "const_1_to_31_operand")
859 (DI "const_1_to_63_operand")])
861 ;; Input operand predicate for arithmetic left shifts.
862 (define_mode_attr ashl_input_operand
863 [(QI "nonimmediate_operand")
864 (HI "nonimmediate_operand")
865 (SI "nonimmediate_operand")
866 (DI "ashldi_input_operand")
867 (TI "reg_or_pm1_operand")])
869 ;; SSE and x87 SFmode and DFmode floating point modes
870 (define_mode_iterator MODEF [SF DF])
872 ;; All x87 floating point modes
873 (define_mode_iterator X87MODEF [SF DF XF])
875 ;; SSE instruction suffix for various modes
876 (define_mode_attr ssemodesuffix
878 (V8SF "ps") (V4DF "pd")
879 (V4SF "ps") (V2DF "pd")
880 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
881 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
883 ;; SSE vector suffix for floating point modes
884 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
886 ;; SSE vector mode corresponding to a scalar mode
887 (define_mode_attr ssevecmode
888 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
890 ;; Instruction suffix for REX 64bit operators.
891 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
893 ;; This mode iterator allows :P to be used for patterns that operate on
894 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
895 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
897 ;; This mode iterator allows :PTR to be used for patterns that operate on
898 ;; ptr_mode sized quantities.
899 (define_mode_iterator PTR
900 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
902 ;; Scheduling descriptions
904 (include "pentium.md")
907 (include "athlon.md")
908 (include "bdver1.md")
914 ;; Operand and operator predicates and constraints
916 (include "predicates.md")
917 (include "constraints.md")
920 ;; Compare and branch/compare and store instructions.
922 (define_expand "cbranch<mode>4"
923 [(set (reg:CC FLAGS_REG)
924 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
925 (match_operand:SDWIM 2 "<general_operand>" "")))
926 (set (pc) (if_then_else
927 (match_operator 0 "ordered_comparison_operator"
928 [(reg:CC FLAGS_REG) (const_int 0)])
929 (label_ref (match_operand 3 "" ""))
933 if (MEM_P (operands[1]) && MEM_P (operands[2]))
934 operands[1] = force_reg (<MODE>mode, operands[1]);
935 ix86_expand_branch (GET_CODE (operands[0]),
936 operands[1], operands[2], operands[3]);
940 (define_expand "cstore<mode>4"
941 [(set (reg:CC FLAGS_REG)
942 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
943 (match_operand:SWIM 3 "<general_operand>" "")))
944 (set (match_operand:QI 0 "register_operand" "")
945 (match_operator 1 "ordered_comparison_operator"
946 [(reg:CC FLAGS_REG) (const_int 0)]))]
949 if (MEM_P (operands[2]) && MEM_P (operands[3]))
950 operands[2] = force_reg (<MODE>mode, operands[2]);
951 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
952 operands[2], operands[3]);
956 (define_expand "cmp<mode>_1"
957 [(set (reg:CC FLAGS_REG)
958 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
959 (match_operand:SWI48 1 "<general_operand>" "")))])
961 (define_insn "*cmp<mode>_ccno_1"
962 [(set (reg FLAGS_REG)
963 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
964 (match_operand:SWI 1 "const0_operand" "")))]
965 "ix86_match_ccmode (insn, CCNOmode)"
967 test{<imodesuffix>}\t%0, %0
968 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
969 [(set_attr "type" "test,icmp")
970 (set_attr "length_immediate" "0,1")
971 (set_attr "mode" "<MODE>")])
973 (define_insn "*cmp<mode>_1"
974 [(set (reg FLAGS_REG)
975 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
976 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
977 "ix86_match_ccmode (insn, CCmode)"
978 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
979 [(set_attr "type" "icmp")
980 (set_attr "mode" "<MODE>")])
982 (define_insn "*cmp<mode>_minus_1"
983 [(set (reg FLAGS_REG)
985 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
986 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
988 "ix86_match_ccmode (insn, CCGOCmode)"
989 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
990 [(set_attr "type" "icmp")
991 (set_attr "mode" "<MODE>")])
993 (define_insn "*cmpqi_ext_1"
994 [(set (reg FLAGS_REG)
996 (match_operand:QI 0 "general_operand" "Qm")
999 (match_operand 1 "ext_register_operand" "Q")
1001 (const_int 8)) 0)))]
1002 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1003 "cmp{b}\t{%h1, %0|%0, %h1}"
1004 [(set_attr "type" "icmp")
1005 (set_attr "mode" "QI")])
1007 (define_insn "*cmpqi_ext_1_rex64"
1008 [(set (reg FLAGS_REG)
1010 (match_operand:QI 0 "register_operand" "Q")
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_2"
1022 [(set (reg FLAGS_REG)
1026 (match_operand 0 "ext_register_operand" "Q")
1029 (match_operand:QI 1 "const0_operand" "")))]
1030 "ix86_match_ccmode (insn, CCNOmode)"
1032 [(set_attr "type" "test")
1033 (set_attr "length_immediate" "0")
1034 (set_attr "mode" "QI")])
1036 (define_expand "cmpqi_ext_3"
1037 [(set (reg:CC FLAGS_REG)
1041 (match_operand 0 "ext_register_operand" "")
1044 (match_operand:QI 1 "immediate_operand" "")))])
1046 (define_insn "*cmpqi_ext_3_insn"
1047 [(set (reg FLAGS_REG)
1051 (match_operand 0 "ext_register_operand" "Q")
1054 (match_operand:QI 1 "general_operand" "Qmn")))]
1055 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1056 "cmp{b}\t{%1, %h0|%h0, %1}"
1057 [(set_attr "type" "icmp")
1058 (set_attr "modrm" "1")
1059 (set_attr "mode" "QI")])
1061 (define_insn "*cmpqi_ext_3_insn_rex64"
1062 [(set (reg FLAGS_REG)
1066 (match_operand 0 "ext_register_operand" "Q")
1069 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1070 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1071 "cmp{b}\t{%1, %h0|%h0, %1}"
1072 [(set_attr "type" "icmp")
1073 (set_attr "modrm" "1")
1074 (set_attr "mode" "QI")])
1076 (define_insn "*cmpqi_ext_4"
1077 [(set (reg FLAGS_REG)
1081 (match_operand 0 "ext_register_operand" "Q")
1086 (match_operand 1 "ext_register_operand" "Q")
1088 (const_int 8)) 0)))]
1089 "ix86_match_ccmode (insn, CCmode)"
1090 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1091 [(set_attr "type" "icmp")
1092 (set_attr "mode" "QI")])
1094 ;; These implement float point compares.
1095 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1096 ;; which would allow mix and match FP modes on the compares. Which is what
1097 ;; the old patterns did, but with many more of them.
1099 (define_expand "cbranchxf4"
1100 [(set (reg:CC FLAGS_REG)
1101 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1102 (match_operand:XF 2 "nonmemory_operand" "")))
1103 (set (pc) (if_then_else
1104 (match_operator 0 "ix86_fp_comparison_operator"
1107 (label_ref (match_operand 3 "" ""))
1111 ix86_expand_branch (GET_CODE (operands[0]),
1112 operands[1], operands[2], operands[3]);
1116 (define_expand "cstorexf4"
1117 [(set (reg:CC FLAGS_REG)
1118 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1119 (match_operand:XF 3 "nonmemory_operand" "")))
1120 (set (match_operand:QI 0 "register_operand" "")
1121 (match_operator 1 "ix86_fp_comparison_operator"
1126 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1127 operands[2], operands[3]);
1131 (define_expand "cbranch<mode>4"
1132 [(set (reg:CC FLAGS_REG)
1133 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1134 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1135 (set (pc) (if_then_else
1136 (match_operator 0 "ix86_fp_comparison_operator"
1139 (label_ref (match_operand 3 "" ""))
1141 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1143 ix86_expand_branch (GET_CODE (operands[0]),
1144 operands[1], operands[2], operands[3]);
1148 (define_expand "cstore<mode>4"
1149 [(set (reg:CC FLAGS_REG)
1150 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1151 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1152 (set (match_operand:QI 0 "register_operand" "")
1153 (match_operator 1 "ix86_fp_comparison_operator"
1156 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1158 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1159 operands[2], operands[3]);
1163 (define_expand "cbranchcc4"
1164 [(set (pc) (if_then_else
1165 (match_operator 0 "comparison_operator"
1166 [(match_operand 1 "flags_reg_operand" "")
1167 (match_operand 2 "const0_operand" "")])
1168 (label_ref (match_operand 3 "" ""))
1172 ix86_expand_branch (GET_CODE (operands[0]),
1173 operands[1], operands[2], operands[3]);
1177 (define_expand "cstorecc4"
1178 [(set (match_operand:QI 0 "register_operand" "")
1179 (match_operator 1 "comparison_operator"
1180 [(match_operand 2 "flags_reg_operand" "")
1181 (match_operand 3 "const0_operand" "")]))]
1184 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1185 operands[2], operands[3]);
1190 ;; FP compares, step 1:
1191 ;; Set the FP condition codes.
1193 ;; CCFPmode compare with exceptions
1194 ;; CCFPUmode compare with no exceptions
1196 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1197 ;; used to manage the reg stack popping would not be preserved.
1199 (define_insn "*cmpfp_0"
1200 [(set (match_operand:HI 0 "register_operand" "=a")
1203 (match_operand 1 "register_operand" "f")
1204 (match_operand 2 "const0_operand" ""))]
1206 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1207 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1208 "* return output_fp_compare (insn, operands, false, false);"
1209 [(set_attr "type" "multi")
1210 (set_attr "unit" "i387")
1212 (cond [(match_operand:SF 1 "" "")
1214 (match_operand:DF 1 "" "")
1217 (const_string "XF")))])
1219 (define_insn_and_split "*cmpfp_0_cc"
1220 [(set (reg:CCFP FLAGS_REG)
1222 (match_operand 1 "register_operand" "f")
1223 (match_operand 2 "const0_operand" "")))
1224 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1225 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1226 && TARGET_SAHF && !TARGET_CMOVE
1227 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1229 "&& reload_completed"
1232 [(compare:CCFP (match_dup 1)(match_dup 2))]
1234 (set (reg:CC FLAGS_REG)
1235 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1237 [(set_attr "type" "multi")
1238 (set_attr "unit" "i387")
1240 (cond [(match_operand:SF 1 "" "")
1242 (match_operand:DF 1 "" "")
1245 (const_string "XF")))])
1247 (define_insn "*cmpfp_xf"
1248 [(set (match_operand:HI 0 "register_operand" "=a")
1251 (match_operand:XF 1 "register_operand" "f")
1252 (match_operand:XF 2 "register_operand" "f"))]
1255 "* return output_fp_compare (insn, operands, false, false);"
1256 [(set_attr "type" "multi")
1257 (set_attr "unit" "i387")
1258 (set_attr "mode" "XF")])
1260 (define_insn_and_split "*cmpfp_xf_cc"
1261 [(set (reg:CCFP FLAGS_REG)
1263 (match_operand:XF 1 "register_operand" "f")
1264 (match_operand:XF 2 "register_operand" "f")))
1265 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1267 && TARGET_SAHF && !TARGET_CMOVE"
1269 "&& reload_completed"
1272 [(compare:CCFP (match_dup 1)(match_dup 2))]
1274 (set (reg:CC FLAGS_REG)
1275 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1277 [(set_attr "type" "multi")
1278 (set_attr "unit" "i387")
1279 (set_attr "mode" "XF")])
1281 (define_insn "*cmpfp_<mode>"
1282 [(set (match_operand:HI 0 "register_operand" "=a")
1285 (match_operand:MODEF 1 "register_operand" "f")
1286 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1289 "* return output_fp_compare (insn, operands, false, false);"
1290 [(set_attr "type" "multi")
1291 (set_attr "unit" "i387")
1292 (set_attr "mode" "<MODE>")])
1294 (define_insn_and_split "*cmpfp_<mode>_cc"
1295 [(set (reg:CCFP FLAGS_REG)
1297 (match_operand:MODEF 1 "register_operand" "f")
1298 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1299 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1301 && TARGET_SAHF && !TARGET_CMOVE"
1303 "&& reload_completed"
1306 [(compare:CCFP (match_dup 1)(match_dup 2))]
1308 (set (reg:CC FLAGS_REG)
1309 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1311 [(set_attr "type" "multi")
1312 (set_attr "unit" "i387")
1313 (set_attr "mode" "<MODE>")])
1315 (define_insn "*cmpfp_u"
1316 [(set (match_operand:HI 0 "register_operand" "=a")
1319 (match_operand 1 "register_operand" "f")
1320 (match_operand 2 "register_operand" "f"))]
1322 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1323 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1324 "* return output_fp_compare (insn, operands, false, true);"
1325 [(set_attr "type" "multi")
1326 (set_attr "unit" "i387")
1328 (cond [(match_operand:SF 1 "" "")
1330 (match_operand:DF 1 "" "")
1333 (const_string "XF")))])
1335 (define_insn_and_split "*cmpfp_u_cc"
1336 [(set (reg:CCFPU FLAGS_REG)
1338 (match_operand 1 "register_operand" "f")
1339 (match_operand 2 "register_operand" "f")))
1340 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1341 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1342 && TARGET_SAHF && !TARGET_CMOVE
1343 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1345 "&& reload_completed"
1348 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1350 (set (reg:CC FLAGS_REG)
1351 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1353 [(set_attr "type" "multi")
1354 (set_attr "unit" "i387")
1356 (cond [(match_operand:SF 1 "" "")
1358 (match_operand:DF 1 "" "")
1361 (const_string "XF")))])
1363 (define_insn "*cmpfp_<mode>"
1364 [(set (match_operand:HI 0 "register_operand" "=a")
1367 (match_operand 1 "register_operand" "f")
1368 (match_operator 3 "float_operator"
1369 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1371 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1372 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1373 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1374 "* return output_fp_compare (insn, operands, false, false);"
1375 [(set_attr "type" "multi")
1376 (set_attr "unit" "i387")
1377 (set_attr "fp_int_src" "true")
1378 (set_attr "mode" "<MODE>")])
1380 (define_insn_and_split "*cmpfp_<mode>_cc"
1381 [(set (reg:CCFP FLAGS_REG)
1383 (match_operand 1 "register_operand" "f")
1384 (match_operator 3 "float_operator"
1385 [(match_operand:SWI24 2 "memory_operand" "m")])))
1386 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1387 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1388 && TARGET_SAHF && !TARGET_CMOVE
1389 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1390 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1392 "&& reload_completed"
1397 (match_op_dup 3 [(match_dup 2)]))]
1399 (set (reg:CC FLAGS_REG)
1400 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1402 [(set_attr "type" "multi")
1403 (set_attr "unit" "i387")
1404 (set_attr "fp_int_src" "true")
1405 (set_attr "mode" "<MODE>")])
1407 ;; FP compares, step 2
1408 ;; Move the fpsw to ax.
1410 (define_insn "x86_fnstsw_1"
1411 [(set (match_operand:HI 0 "register_operand" "=a")
1412 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1415 [(set (attr "length")
1416 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1417 (set_attr "mode" "SI")
1418 (set_attr "unit" "i387")])
1420 ;; FP compares, step 3
1421 ;; Get ax into flags, general case.
1423 (define_insn "x86_sahf_1"
1424 [(set (reg:CC FLAGS_REG)
1425 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1429 #ifndef HAVE_AS_IX86_SAHF
1431 return ASM_BYTE "0x9e";
1436 [(set_attr "length" "1")
1437 (set_attr "athlon_decode" "vector")
1438 (set_attr "amdfam10_decode" "direct")
1439 (set_attr "bdver1_decode" "direct")
1440 (set_attr "mode" "SI")])
1442 ;; Pentium Pro can do steps 1 through 3 in one go.
1443 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1444 ;; (these i387 instructions set flags directly)
1445 (define_insn "*cmpfp_i_mixed"
1446 [(set (reg:CCFP FLAGS_REG)
1447 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1448 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1449 "TARGET_MIX_SSE_I387
1450 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1451 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1452 "* return output_fp_compare (insn, operands, true, false);"
1453 [(set_attr "type" "fcmp,ssecomi")
1454 (set_attr "prefix" "orig,maybe_vex")
1456 (if_then_else (match_operand:SF 1 "" "")
1458 (const_string "DF")))
1459 (set (attr "prefix_rep")
1460 (if_then_else (eq_attr "type" "ssecomi")
1462 (const_string "*")))
1463 (set (attr "prefix_data16")
1464 (cond [(eq_attr "type" "fcmp")
1466 (eq_attr "mode" "DF")
1469 (const_string "0")))
1470 (set_attr "athlon_decode" "vector")
1471 (set_attr "amdfam10_decode" "direct")
1472 (set_attr "bdver1_decode" "double")])
1474 (define_insn "*cmpfp_i_sse"
1475 [(set (reg:CCFP FLAGS_REG)
1476 (compare:CCFP (match_operand 0 "register_operand" "x")
1477 (match_operand 1 "nonimmediate_operand" "xm")))]
1479 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1480 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1481 "* return output_fp_compare (insn, operands, true, false);"
1482 [(set_attr "type" "ssecomi")
1483 (set_attr "prefix" "maybe_vex")
1485 (if_then_else (match_operand:SF 1 "" "")
1487 (const_string "DF")))
1488 (set_attr "prefix_rep" "0")
1489 (set (attr "prefix_data16")
1490 (if_then_else (eq_attr "mode" "DF")
1492 (const_string "0")))
1493 (set_attr "athlon_decode" "vector")
1494 (set_attr "amdfam10_decode" "direct")
1495 (set_attr "bdver1_decode" "double")])
1497 (define_insn "*cmpfp_i_i387"
1498 [(set (reg:CCFP FLAGS_REG)
1499 (compare:CCFP (match_operand 0 "register_operand" "f")
1500 (match_operand 1 "register_operand" "f")))]
1501 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1503 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1504 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1505 "* return output_fp_compare (insn, operands, true, false);"
1506 [(set_attr "type" "fcmp")
1508 (cond [(match_operand:SF 1 "" "")
1510 (match_operand:DF 1 "" "")
1513 (const_string "XF")))
1514 (set_attr "athlon_decode" "vector")
1515 (set_attr "amdfam10_decode" "direct")
1516 (set_attr "bdver1_decode" "double")])
1518 (define_insn "*cmpfp_iu_mixed"
1519 [(set (reg:CCFPU FLAGS_REG)
1520 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1521 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1522 "TARGET_MIX_SSE_I387
1523 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1524 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1525 "* return output_fp_compare (insn, operands, true, true);"
1526 [(set_attr "type" "fcmp,ssecomi")
1527 (set_attr "prefix" "orig,maybe_vex")
1529 (if_then_else (match_operand:SF 1 "" "")
1531 (const_string "DF")))
1532 (set (attr "prefix_rep")
1533 (if_then_else (eq_attr "type" "ssecomi")
1535 (const_string "*")))
1536 (set (attr "prefix_data16")
1537 (cond [(eq_attr "type" "fcmp")
1539 (eq_attr "mode" "DF")
1542 (const_string "0")))
1543 (set_attr "athlon_decode" "vector")
1544 (set_attr "amdfam10_decode" "direct")
1545 (set_attr "bdver1_decode" "double")])
1547 (define_insn "*cmpfp_iu_sse"
1548 [(set (reg:CCFPU FLAGS_REG)
1549 (compare:CCFPU (match_operand 0 "register_operand" "x")
1550 (match_operand 1 "nonimmediate_operand" "xm")))]
1552 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1553 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1554 "* return output_fp_compare (insn, operands, true, true);"
1555 [(set_attr "type" "ssecomi")
1556 (set_attr "prefix" "maybe_vex")
1558 (if_then_else (match_operand:SF 1 "" "")
1560 (const_string "DF")))
1561 (set_attr "prefix_rep" "0")
1562 (set (attr "prefix_data16")
1563 (if_then_else (eq_attr "mode" "DF")
1565 (const_string "0")))
1566 (set_attr "athlon_decode" "vector")
1567 (set_attr "amdfam10_decode" "direct")
1568 (set_attr "bdver1_decode" "double")])
1570 (define_insn "*cmpfp_iu_387"
1571 [(set (reg:CCFPU FLAGS_REG)
1572 (compare:CCFPU (match_operand 0 "register_operand" "f")
1573 (match_operand 1 "register_operand" "f")))]
1574 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1576 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1577 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1578 "* return output_fp_compare (insn, operands, true, true);"
1579 [(set_attr "type" "fcmp")
1581 (cond [(match_operand:SF 1 "" "")
1583 (match_operand:DF 1 "" "")
1586 (const_string "XF")))
1587 (set_attr "athlon_decode" "vector")
1588 (set_attr "amdfam10_decode" "direct")
1589 (set_attr "bdver1_decode" "direct")])
1591 ;; Push/pop instructions.
1593 (define_insn "*push<mode>2"
1594 [(set (match_operand:DWI 0 "push_operand" "=<")
1595 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1598 [(set_attr "type" "multi")
1599 (set_attr "mode" "<MODE>")])
1602 [(set (match_operand:TI 0 "push_operand" "")
1603 (match_operand:TI 1 "general_operand" ""))]
1604 "TARGET_64BIT && reload_completed
1605 && !SSE_REG_P (operands[1])"
1607 "ix86_split_long_move (operands); DONE;")
1609 (define_insn "*pushdi2_rex64"
1610 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1611 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1616 [(set_attr "type" "push,multi")
1617 (set_attr "mode" "DI")])
1619 ;; Convert impossible pushes of immediate to existing instructions.
1620 ;; First try to get scratch register and go through it. In case this
1621 ;; fails, push sign extended lower part first and then overwrite
1622 ;; upper part by 32bit move.
1624 [(match_scratch:DI 2 "r")
1625 (set (match_operand:DI 0 "push_operand" "")
1626 (match_operand:DI 1 "immediate_operand" ""))]
1627 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1628 && !x86_64_immediate_operand (operands[1], DImode)"
1629 [(set (match_dup 2) (match_dup 1))
1630 (set (match_dup 0) (match_dup 2))])
1632 ;; We need to define this as both peepholer and splitter for case
1633 ;; peephole2 pass is not run.
1634 ;; "&& 1" is needed to keep it from matching the previous pattern.
1636 [(set (match_operand:DI 0 "push_operand" "")
1637 (match_operand:DI 1 "immediate_operand" ""))]
1638 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1639 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1640 [(set (match_dup 0) (match_dup 1))
1641 (set (match_dup 2) (match_dup 3))]
1643 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1645 operands[1] = gen_lowpart (DImode, operands[2]);
1646 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1651 [(set (match_operand:DI 0 "push_operand" "")
1652 (match_operand:DI 1 "immediate_operand" ""))]
1653 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1654 ? epilogue_completed : reload_completed)
1655 && !symbolic_operand (operands[1], DImode)
1656 && !x86_64_immediate_operand (operands[1], DImode)"
1657 [(set (match_dup 0) (match_dup 1))
1658 (set (match_dup 2) (match_dup 3))]
1660 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1662 operands[1] = gen_lowpart (DImode, operands[2]);
1663 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1668 [(set (match_operand:DI 0 "push_operand" "")
1669 (match_operand:DI 1 "general_operand" ""))]
1670 "!TARGET_64BIT && reload_completed
1671 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1673 "ix86_split_long_move (operands); DONE;")
1675 (define_insn "*pushsi2"
1676 [(set (match_operand:SI 0 "push_operand" "=<")
1677 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1680 [(set_attr "type" "push")
1681 (set_attr "mode" "SI")])
1683 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1684 ;; "push a byte/word". But actually we use pushl, which has the effect
1685 ;; of rounding the amount pushed up to a word.
1687 ;; For TARGET_64BIT we always round up to 8 bytes.
1688 (define_insn "*push<mode>2_rex64"
1689 [(set (match_operand:SWI124 0 "push_operand" "=X")
1690 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1693 [(set_attr "type" "push")
1694 (set_attr "mode" "DI")])
1696 (define_insn "*push<mode>2"
1697 [(set (match_operand:SWI12 0 "push_operand" "=X")
1698 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1701 [(set_attr "type" "push")
1702 (set_attr "mode" "SI")])
1704 (define_insn "*push<mode>2_prologue"
1705 [(set (match_operand:P 0 "push_operand" "=<")
1706 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1707 (clobber (mem:BLK (scratch)))]
1709 "push{<imodesuffix>}\t%1"
1710 [(set_attr "type" "push")
1711 (set_attr "mode" "<MODE>")])
1713 (define_insn "*pop<mode>1"
1714 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1715 (match_operand:P 1 "pop_operand" ">"))]
1717 "pop{<imodesuffix>}\t%0"
1718 [(set_attr "type" "pop")
1719 (set_attr "mode" "<MODE>")])
1721 (define_insn "*pop<mode>1_epilogue"
1722 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1723 (match_operand:P 1 "pop_operand" ">"))
1724 (clobber (mem:BLK (scratch)))]
1726 "pop{<imodesuffix>}\t%0"
1727 [(set_attr "type" "pop")
1728 (set_attr "mode" "<MODE>")])
1730 ;; Move instructions.
1732 (define_expand "movoi"
1733 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1734 (match_operand:OI 1 "general_operand" ""))]
1736 "ix86_expand_move (OImode, operands); DONE;")
1738 (define_expand "movti"
1739 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1740 (match_operand:TI 1 "nonimmediate_operand" ""))]
1741 "TARGET_64BIT || TARGET_SSE"
1744 ix86_expand_move (TImode, operands);
1745 else if (push_operand (operands[0], TImode))
1746 ix86_expand_push (TImode, operands[1]);
1748 ix86_expand_vector_move (TImode, operands);
1752 ;; This expands to what emit_move_complex would generate if we didn't
1753 ;; have a movti pattern. Having this avoids problems with reload on
1754 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1755 ;; to have around all the time.
1756 (define_expand "movcdi"
1757 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1758 (match_operand:CDI 1 "general_operand" ""))]
1761 if (push_operand (operands[0], CDImode))
1762 emit_move_complex_push (CDImode, operands[0], operands[1]);
1764 emit_move_complex_parts (operands[0], operands[1]);
1768 (define_expand "mov<mode>"
1769 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1770 (match_operand:SWI1248x 1 "general_operand" ""))]
1772 "ix86_expand_move (<MODE>mode, operands); DONE;")
1774 (define_insn "*mov<mode>_xor"
1775 [(set (match_operand:SWI48 0 "register_operand" "=r")
1776 (match_operand:SWI48 1 "const0_operand" ""))
1777 (clobber (reg:CC FLAGS_REG))]
1780 [(set_attr "type" "alu1")
1781 (set_attr "mode" "SI")
1782 (set_attr "length_immediate" "0")])
1784 (define_insn "*mov<mode>_or"
1785 [(set (match_operand:SWI48 0 "register_operand" "=r")
1786 (match_operand:SWI48 1 "const_int_operand" ""))
1787 (clobber (reg:CC FLAGS_REG))]
1789 && operands[1] == constm1_rtx"
1790 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1791 [(set_attr "type" "alu1")
1792 (set_attr "mode" "<MODE>")
1793 (set_attr "length_immediate" "1")])
1795 (define_insn "*movoi_internal_avx"
1796 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1797 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1798 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1800 switch (which_alternative)
1803 return standard_sse_constant_opcode (insn, operands[1]);
1806 if (misaligned_operand (operands[0], OImode)
1807 || misaligned_operand (operands[1], OImode))
1808 return "vmovdqu\t{%1, %0|%0, %1}";
1810 return "vmovdqa\t{%1, %0|%0, %1}";
1815 [(set_attr "type" "sselog1,ssemov,ssemov")
1816 (set_attr "prefix" "vex")
1817 (set_attr "mode" "OI")])
1819 (define_insn "*movti_internal_rex64"
1820 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1821 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1822 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1824 switch (which_alternative)
1830 return standard_sse_constant_opcode (insn, operands[1]);
1833 /* TDmode values are passed as TImode on the stack. Moving them
1834 to stack may result in unaligned memory access. */
1835 if (misaligned_operand (operands[0], TImode)
1836 || misaligned_operand (operands[1], TImode))
1838 if (get_attr_mode (insn) == MODE_V4SF)
1839 return "%vmovups\t{%1, %0|%0, %1}";
1841 return "%vmovdqu\t{%1, %0|%0, %1}";
1845 if (get_attr_mode (insn) == MODE_V4SF)
1846 return "%vmovaps\t{%1, %0|%0, %1}";
1848 return "%vmovdqa\t{%1, %0|%0, %1}";
1854 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1855 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1857 (cond [(eq_attr "alternative" "2,3")
1859 (match_test "optimize_function_for_size_p (cfun)")
1860 (const_string "V4SF")
1861 (const_string "TI"))
1862 (eq_attr "alternative" "4")
1864 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1865 (match_test "optimize_function_for_size_p (cfun)"))
1866 (const_string "V4SF")
1867 (const_string "TI"))]
1868 (const_string "DI")))])
1871 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1872 (match_operand:TI 1 "general_operand" ""))]
1874 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1876 "ix86_split_long_move (operands); DONE;")
1878 (define_insn "*movti_internal_sse"
1879 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1880 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1881 "TARGET_SSE && !TARGET_64BIT
1882 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1884 switch (which_alternative)
1887 return standard_sse_constant_opcode (insn, operands[1]);
1890 /* TDmode values are passed as TImode on the stack. Moving them
1891 to stack may result in unaligned memory access. */
1892 if (misaligned_operand (operands[0], TImode)
1893 || misaligned_operand (operands[1], TImode))
1895 if (get_attr_mode (insn) == MODE_V4SF)
1896 return "%vmovups\t{%1, %0|%0, %1}";
1898 return "%vmovdqu\t{%1, %0|%0, %1}";
1902 if (get_attr_mode (insn) == MODE_V4SF)
1903 return "%vmovaps\t{%1, %0|%0, %1}";
1905 return "%vmovdqa\t{%1, %0|%0, %1}";
1911 [(set_attr "type" "sselog1,ssemov,ssemov")
1912 (set_attr "prefix" "maybe_vex")
1914 (cond [(ior (not (match_test "TARGET_SSE2"))
1915 (match_test "optimize_function_for_size_p (cfun)"))
1916 (const_string "V4SF")
1917 (and (eq_attr "alternative" "2")
1918 (match_test "TARGET_SSE_TYPELESS_STORES"))
1919 (const_string "V4SF")]
1920 (const_string "TI")))])
1922 (define_insn "*movdi_internal_rex64"
1923 [(set (match_operand:DI 0 "nonimmediate_operand"
1924 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1925 (match_operand:DI 1 "general_operand"
1926 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1927 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1929 switch (get_attr_type (insn))
1932 if (SSE_REG_P (operands[0]))
1933 return "movq2dq\t{%1, %0|%0, %1}";
1935 return "movdq2q\t{%1, %0|%0, %1}";
1938 if (get_attr_mode (insn) == MODE_TI)
1939 return "%vmovdqa\t{%1, %0|%0, %1}";
1940 /* Handle broken assemblers that require movd instead of movq. */
1941 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942 return "%vmovd\t{%1, %0|%0, %1}";
1944 return "%vmovq\t{%1, %0|%0, %1}";
1947 /* Handle broken assemblers that require movd instead of movq. */
1948 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1949 return "movd\t{%1, %0|%0, %1}";
1951 return "movq\t{%1, %0|%0, %1}";
1954 return standard_sse_constant_opcode (insn, operands[1]);
1957 return "pxor\t%0, %0";
1963 return "lea{q}\t{%a1, %0|%0, %a1}";
1966 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1967 if (get_attr_mode (insn) == MODE_SI)
1968 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1969 else if (which_alternative == 2)
1970 return "movabs{q}\t{%1, %0|%0, %1}";
1971 else if (ix86_use_lea_for_mov (insn, operands))
1972 return "lea{q}\t{%a1, %0|%0, %a1}";
1974 return "mov{q}\t{%1, %0|%0, %1}";
1978 (cond [(eq_attr "alternative" "4")
1979 (const_string "multi")
1980 (eq_attr "alternative" "5")
1981 (const_string "mmx")
1982 (eq_attr "alternative" "6,7,8,9")
1983 (const_string "mmxmov")
1984 (eq_attr "alternative" "10")
1985 (const_string "sselog1")
1986 (eq_attr "alternative" "11,12,13,14,15")
1987 (const_string "ssemov")
1988 (eq_attr "alternative" "16,17")
1989 (const_string "ssecvt")
1990 (match_operand 1 "pic_32bit_operand" "")
1991 (const_string "lea")
1993 (const_string "imov")))
1996 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1998 (const_string "*")))
1999 (set (attr "length_immediate")
2001 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2003 (const_string "*")))
2004 (set (attr "prefix_rex")
2005 (if_then_else (eq_attr "alternative" "8,9")
2007 (const_string "*")))
2008 (set (attr "prefix_data16")
2009 (if_then_else (eq_attr "alternative" "11")
2011 (const_string "*")))
2012 (set (attr "prefix")
2013 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2014 (const_string "maybe_vex")
2015 (const_string "orig")))
2016 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2018 ;; Reload patterns to support multi-word load/store
2019 ;; with non-offsetable address.
2020 (define_expand "reload_noff_store"
2021 [(parallel [(match_operand 0 "memory_operand" "=m")
2022 (match_operand 1 "register_operand" "r")
2023 (match_operand:DI 2 "register_operand" "=&r")])]
2026 rtx mem = operands[0];
2027 rtx addr = XEXP (mem, 0);
2029 emit_move_insn (operands[2], addr);
2030 mem = replace_equiv_address_nv (mem, operands[2]);
2032 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2036 (define_expand "reload_noff_load"
2037 [(parallel [(match_operand 0 "register_operand" "=r")
2038 (match_operand 1 "memory_operand" "m")
2039 (match_operand:DI 2 "register_operand" "=r")])]
2042 rtx mem = operands[1];
2043 rtx addr = XEXP (mem, 0);
2045 emit_move_insn (operands[2], addr);
2046 mem = replace_equiv_address_nv (mem, operands[2]);
2048 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2052 ;; Convert impossible stores of immediate to existing instructions.
2053 ;; First try to get scratch register and go through it. In case this
2054 ;; fails, move by 32bit parts.
2056 [(match_scratch:DI 2 "r")
2057 (set (match_operand:DI 0 "memory_operand" "")
2058 (match_operand:DI 1 "immediate_operand" ""))]
2059 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2060 && !x86_64_immediate_operand (operands[1], DImode)"
2061 [(set (match_dup 2) (match_dup 1))
2062 (set (match_dup 0) (match_dup 2))])
2064 ;; We need to define this as both peepholer and splitter for case
2065 ;; peephole2 pass is not run.
2066 ;; "&& 1" is needed to keep it from matching the previous pattern.
2068 [(set (match_operand:DI 0 "memory_operand" "")
2069 (match_operand:DI 1 "immediate_operand" ""))]
2070 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2071 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2072 [(set (match_dup 2) (match_dup 3))
2073 (set (match_dup 4) (match_dup 5))]
2074 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2077 [(set (match_operand:DI 0 "memory_operand" "")
2078 (match_operand:DI 1 "immediate_operand" ""))]
2079 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2080 ? epilogue_completed : reload_completed)
2081 && !symbolic_operand (operands[1], DImode)
2082 && !x86_64_immediate_operand (operands[1], DImode)"
2083 [(set (match_dup 2) (match_dup 3))
2084 (set (match_dup 4) (match_dup 5))]
2085 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2087 (define_insn "*movdi_internal"
2088 [(set (match_operand:DI 0 "nonimmediate_operand"
2089 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2090 (match_operand:DI 1 "general_operand"
2091 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2092 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2094 switch (get_attr_type (insn))
2097 if (SSE_REG_P (operands[0]))
2098 return "movq2dq\t{%1, %0|%0, %1}";
2100 return "movdq2q\t{%1, %0|%0, %1}";
2103 switch (get_attr_mode (insn))
2106 return "%vmovdqa\t{%1, %0|%0, %1}";
2108 return "%vmovq\t{%1, %0|%0, %1}";
2110 return "movaps\t{%1, %0|%0, %1}";
2112 return "movlps\t{%1, %0|%0, %1}";
2118 return "movq\t{%1, %0|%0, %1}";
2121 return standard_sse_constant_opcode (insn, operands[1]);
2124 return "pxor\t%0, %0";
2134 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2135 (const_string "sse2")
2136 (eq_attr "alternative" "9,10,11,12")
2137 (const_string "noavx")
2139 (const_string "*")))
2141 (cond [(eq_attr "alternative" "0,1")
2142 (const_string "multi")
2143 (eq_attr "alternative" "2")
2144 (const_string "mmx")
2145 (eq_attr "alternative" "3,4")
2146 (const_string "mmxmov")
2147 (eq_attr "alternative" "5,9")
2148 (const_string "sselog1")
2149 (eq_attr "alternative" "13,14")
2150 (const_string "ssecvt")
2152 (const_string "ssemov")))
2153 (set (attr "prefix")
2154 (if_then_else (eq_attr "alternative" "5,6,7,8")
2155 (const_string "maybe_vex")
2156 (const_string "orig")))
2157 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2160 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2161 (match_operand:DI 1 "general_operand" ""))]
2162 "!TARGET_64BIT && reload_completed
2163 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2164 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2166 "ix86_split_long_move (operands); DONE;")
2168 (define_insn "*movsi_internal"
2169 [(set (match_operand:SI 0 "nonimmediate_operand"
2170 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2171 (match_operand:SI 1 "general_operand"
2172 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2173 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2175 switch (get_attr_type (insn))
2178 return standard_sse_constant_opcode (insn, operands[1]);
2181 switch (get_attr_mode (insn))
2184 return "%vmovdqa\t{%1, %0|%0, %1}";
2186 return "%vmovaps\t{%1, %0|%0, %1}";
2188 return "%vmovd\t{%1, %0|%0, %1}";
2190 return "%vmovss\t{%1, %0|%0, %1}";
2196 return "pxor\t%0, %0";
2199 if (get_attr_mode (insn) == MODE_DI)
2200 return "movq\t{%1, %0|%0, %1}";
2201 return "movd\t{%1, %0|%0, %1}";
2204 return "lea{l}\t{%a1, %0|%0, %a1}";
2207 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2208 if (ix86_use_lea_for_mov (insn, operands))
2209 return "lea{l}\t{%a1, %0|%0, %a1}";
2211 return "mov{l}\t{%1, %0|%0, %1}";
2215 (cond [(eq_attr "alternative" "2")
2216 (const_string "mmx")
2217 (eq_attr "alternative" "3,4,5")
2218 (const_string "mmxmov")
2219 (eq_attr "alternative" "6")
2220 (const_string "sselog1")
2221 (eq_attr "alternative" "7,8,9,10,11")
2222 (const_string "ssemov")
2223 (match_operand 1 "pic_32bit_operand" "")
2224 (const_string "lea")
2226 (const_string "imov")))
2227 (set (attr "prefix")
2228 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2229 (const_string "orig")
2230 (const_string "maybe_vex")))
2231 (set (attr "prefix_data16")
2232 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2234 (const_string "*")))
2236 (cond [(eq_attr "alternative" "2,3")
2238 (eq_attr "alternative" "6,7")
2240 (not (match_test "TARGET_SSE2"))
2241 (const_string "V4SF")
2242 (const_string "TI"))
2243 (and (eq_attr "alternative" "8,9,10,11")
2244 (not (match_test "TARGET_SSE2")))
2247 (const_string "SI")))])
2249 (define_insn "*movhi_internal"
2250 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2251 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2252 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2254 switch (get_attr_type (insn))
2257 /* movzwl is faster than movw on p2 due to partial word stalls,
2258 though not as fast as an aligned movl. */
2259 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2261 if (get_attr_mode (insn) == MODE_SI)
2262 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2264 return "mov{w}\t{%1, %0|%0, %1}";
2268 (cond [(match_test "optimize_function_for_size_p (cfun)")
2269 (const_string "imov")
2270 (and (eq_attr "alternative" "0")
2271 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2272 (not (match_test "TARGET_HIMODE_MATH"))))
2273 (const_string "imov")
2274 (and (eq_attr "alternative" "1,2")
2275 (match_operand:HI 1 "aligned_operand" ""))
2276 (const_string "imov")
2277 (and (match_test "TARGET_MOVX")
2278 (eq_attr "alternative" "0,2"))
2279 (const_string "imovx")
2281 (const_string "imov")))
2283 (cond [(eq_attr "type" "imovx")
2285 (and (eq_attr "alternative" "1,2")
2286 (match_operand:HI 1 "aligned_operand" ""))
2288 (and (eq_attr "alternative" "0")
2289 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2290 (not (match_test "TARGET_HIMODE_MATH"))))
2293 (const_string "HI")))])
2295 ;; Situation is quite tricky about when to choose full sized (SImode) move
2296 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2297 ;; partial register dependency machines (such as AMD Athlon), where QImode
2298 ;; moves issue extra dependency and for partial register stalls machines
2299 ;; that don't use QImode patterns (and QImode move cause stall on the next
2302 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2303 ;; register stall machines with, where we use QImode instructions, since
2304 ;; partial register stall can be caused there. Then we use movzx.
2305 (define_insn "*movqi_internal"
2306 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2307 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2308 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2310 switch (get_attr_type (insn))
2313 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2314 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2316 if (get_attr_mode (insn) == MODE_SI)
2317 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2319 return "mov{b}\t{%1, %0|%0, %1}";
2323 (cond [(and (eq_attr "alternative" "5")
2324 (not (match_operand:QI 1 "aligned_operand" "")))
2325 (const_string "imovx")
2326 (match_test "optimize_function_for_size_p (cfun)")
2327 (const_string "imov")
2328 (and (eq_attr "alternative" "3")
2329 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2330 (not (match_test "TARGET_QIMODE_MATH"))))
2331 (const_string "imov")
2332 (eq_attr "alternative" "3,5")
2333 (const_string "imovx")
2334 (and (match_test "TARGET_MOVX")
2335 (eq_attr "alternative" "2"))
2336 (const_string "imovx")
2338 (const_string "imov")))
2340 (cond [(eq_attr "alternative" "3,4,5")
2342 (eq_attr "alternative" "6")
2344 (eq_attr "type" "imovx")
2346 (and (eq_attr "type" "imov")
2347 (and (eq_attr "alternative" "0,1")
2348 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2349 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2350 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2352 ;; Avoid partial register stalls when not using QImode arithmetic
2353 (and (eq_attr "type" "imov")
2354 (and (eq_attr "alternative" "0,1")
2355 (and (match_test "TARGET_PARTIAL_REG_STALL")
2356 (not (match_test "TARGET_QIMODE_MATH")))))
2359 (const_string "QI")))])
2361 ;; Stores and loads of ax to arbitrary constant address.
2362 ;; We fake an second form of instruction to force reload to load address
2363 ;; into register when rax is not available
2364 (define_insn "*movabs<mode>_1"
2365 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2366 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2367 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2369 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2370 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2371 [(set_attr "type" "imov")
2372 (set_attr "modrm" "0,*")
2373 (set_attr "length_address" "8,0")
2374 (set_attr "length_immediate" "0,*")
2375 (set_attr "memory" "store")
2376 (set_attr "mode" "<MODE>")])
2378 (define_insn "*movabs<mode>_2"
2379 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2380 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2381 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2383 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2384 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
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" "load")
2390 (set_attr "mode" "<MODE>")])
2392 (define_insn "*swap<mode>"
2393 [(set (match_operand:SWI48 0 "register_operand" "+r")
2394 (match_operand:SWI48 1 "register_operand" "+r"))
2398 "xchg{<imodesuffix>}\t%1, %0"
2399 [(set_attr "type" "imov")
2400 (set_attr "mode" "<MODE>")
2401 (set_attr "pent_pair" "np")
2402 (set_attr "athlon_decode" "vector")
2403 (set_attr "amdfam10_decode" "double")
2404 (set_attr "bdver1_decode" "double")])
2406 (define_insn "*swap<mode>_1"
2407 [(set (match_operand:SWI12 0 "register_operand" "+r")
2408 (match_operand:SWI12 1 "register_operand" "+r"))
2411 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2413 [(set_attr "type" "imov")
2414 (set_attr "mode" "SI")
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 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2421 ;; is disabled for AMDFAM10
2422 (define_insn "*swap<mode>_2"
2423 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2424 (match_operand:SWI12 1 "register_operand" "+<r>"))
2427 "TARGET_PARTIAL_REG_STALL"
2428 "xchg{<imodesuffix>}\t%1, %0"
2429 [(set_attr "type" "imov")
2430 (set_attr "mode" "<MODE>")
2431 (set_attr "pent_pair" "np")
2432 (set_attr "athlon_decode" "vector")])
2434 (define_expand "movstrict<mode>"
2435 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2436 (match_operand:SWI12 1 "general_operand" ""))]
2439 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2441 if (GET_CODE (operands[0]) == SUBREG
2442 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2444 /* Don't generate memory->memory moves, go through a register */
2445 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2446 operands[1] = force_reg (<MODE>mode, operands[1]);
2449 (define_insn "*movstrict<mode>_1"
2450 [(set (strict_low_part
2451 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2452 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2453 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2454 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2455 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2456 [(set_attr "type" "imov")
2457 (set_attr "mode" "<MODE>")])
2459 (define_insn "*movstrict<mode>_xor"
2460 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2461 (match_operand:SWI12 1 "const0_operand" ""))
2462 (clobber (reg:CC FLAGS_REG))]
2464 "xor{<imodesuffix>}\t%0, %0"
2465 [(set_attr "type" "alu1")
2466 (set_attr "mode" "<MODE>")
2467 (set_attr "length_immediate" "0")])
2469 (define_insn "*mov<mode>_extv_1"
2470 [(set (match_operand:SWI24 0 "register_operand" "=R")
2471 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2475 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2476 [(set_attr "type" "imovx")
2477 (set_attr "mode" "SI")])
2479 (define_insn "*movqi_extv_1_rex64"
2480 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2481 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2486 switch (get_attr_type (insn))
2489 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2491 return "mov{b}\t{%h1, %0|%0, %h1}";
2495 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2496 (match_test "TARGET_MOVX"))
2497 (const_string "imovx")
2498 (const_string "imov")))
2500 (if_then_else (eq_attr "type" "imovx")
2502 (const_string "QI")))])
2504 (define_insn "*movqi_extv_1"
2505 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2506 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2511 switch (get_attr_type (insn))
2514 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2516 return "mov{b}\t{%h1, %0|%0, %h1}";
2520 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2521 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2522 (match_test "TARGET_MOVX")))
2523 (const_string "imovx")
2524 (const_string "imov")))
2526 (if_then_else (eq_attr "type" "imovx")
2528 (const_string "QI")))])
2530 (define_insn "*mov<mode>_extzv_1"
2531 [(set (match_operand:SWI48 0 "register_operand" "=R")
2532 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2536 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2537 [(set_attr "type" "imovx")
2538 (set_attr "mode" "SI")])
2540 (define_insn "*movqi_extzv_2_rex64"
2541 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2543 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2548 switch (get_attr_type (insn))
2551 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2553 return "mov{b}\t{%h1, %0|%0, %h1}";
2557 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2558 (match_test "TARGET_MOVX"))
2559 (const_string "imovx")
2560 (const_string "imov")))
2562 (if_then_else (eq_attr "type" "imovx")
2564 (const_string "QI")))])
2566 (define_insn "*movqi_extzv_2"
2567 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2569 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2574 switch (get_attr_type (insn))
2577 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2579 return "mov{b}\t{%h1, %0|%0, %h1}";
2583 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2584 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2585 (match_test "TARGET_MOVX")))
2586 (const_string "imovx")
2587 (const_string "imov")))
2589 (if_then_else (eq_attr "type" "imovx")
2591 (const_string "QI")))])
2593 (define_expand "mov<mode>_insv_1"
2594 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2597 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2599 (define_insn "*mov<mode>_insv_1_rex64"
2600 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2603 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2605 "mov{b}\t{%b1, %h0|%h0, %b1}"
2606 [(set_attr "type" "imov")
2607 (set_attr "mode" "QI")])
2609 (define_insn "*movsi_insv_1"
2610 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2613 (match_operand:SI 1 "general_operand" "Qmn"))]
2615 "mov{b}\t{%b1, %h0|%h0, %b1}"
2616 [(set_attr "type" "imov")
2617 (set_attr "mode" "QI")])
2619 (define_insn "*movqi_insv_2"
2620 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2623 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2626 "mov{b}\t{%h1, %h0|%h0, %h1}"
2627 [(set_attr "type" "imov")
2628 (set_attr "mode" "QI")])
2630 ;; Floating point push instructions.
2632 (define_insn "*pushtf"
2633 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2634 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2637 /* This insn should be already split before reg-stack. */
2640 [(set_attr "type" "multi")
2641 (set_attr "unit" "sse,*,*")
2642 (set_attr "mode" "TF,SI,SI")])
2644 ;; %%% Kill this when call knows how to work this out.
2646 [(set (match_operand:TF 0 "push_operand" "")
2647 (match_operand:TF 1 "sse_reg_operand" ""))]
2648 "TARGET_SSE2 && reload_completed"
2649 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2650 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2652 (define_insn "*pushxf"
2653 [(set (match_operand:XF 0 "push_operand" "=<,<")
2654 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2655 "optimize_function_for_speed_p (cfun)"
2657 /* This insn should be already split before reg-stack. */
2660 [(set_attr "type" "multi")
2661 (set_attr "unit" "i387,*")
2662 (set_attr "mode" "XF,SI")])
2664 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2665 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2666 ;; Pushing using integer instructions is longer except for constants
2667 ;; and direct memory references (assuming that any given constant is pushed
2668 ;; only once, but this ought to be handled elsewhere).
2670 (define_insn "*pushxf_nointeger"
2671 [(set (match_operand:XF 0 "push_operand" "=<,<")
2672 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2673 "optimize_function_for_size_p (cfun)"
2675 /* This insn should be already split before reg-stack. */
2678 [(set_attr "type" "multi")
2679 (set_attr "unit" "i387,*")
2680 (set_attr "mode" "XF,SI")])
2682 ;; %%% Kill this when call knows how to work this out.
2684 [(set (match_operand:XF 0 "push_operand" "")
2685 (match_operand:XF 1 "fp_register_operand" ""))]
2687 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2688 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2689 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2691 (define_insn "*pushdf_rex64"
2692 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2693 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2696 /* This insn should be already split before reg-stack. */
2699 [(set_attr "type" "multi")
2700 (set_attr "unit" "i387,*,*")
2701 (set_attr "mode" "DF,DI,DF")])
2703 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2704 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2705 ;; On the average, pushdf using integers can be still shorter.
2707 (define_insn "*pushdf"
2708 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2709 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2712 /* This insn should be already split before reg-stack. */
2715 [(set_attr "isa" "*,*,sse2")
2716 (set_attr "type" "multi")
2717 (set_attr "unit" "i387,*,*")
2718 (set_attr "mode" "DF,DI,DF")])
2720 ;; %%% Kill this when call knows how to work this out.
2722 [(set (match_operand:DF 0 "push_operand" "")
2723 (match_operand:DF 1 "any_fp_register_operand" ""))]
2725 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2726 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2728 (define_insn "*pushsf_rex64"
2729 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2730 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2733 /* Anything else should be already split before reg-stack. */
2734 gcc_assert (which_alternative == 1);
2735 return "push{q}\t%q1";
2737 [(set_attr "type" "multi,push,multi")
2738 (set_attr "unit" "i387,*,*")
2739 (set_attr "mode" "SF,DI,SF")])
2741 (define_insn "*pushsf"
2742 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2743 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2746 /* Anything else should be already split before reg-stack. */
2747 gcc_assert (which_alternative == 1);
2748 return "push{l}\t%1";
2750 [(set_attr "type" "multi,push,multi")
2751 (set_attr "unit" "i387,*,*")
2752 (set_attr "mode" "SF,SI,SF")])
2754 ;; %%% Kill this when call knows how to work this out.
2756 [(set (match_operand:SF 0 "push_operand" "")
2757 (match_operand:SF 1 "any_fp_register_operand" ""))]
2759 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2760 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2761 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2764 [(set (match_operand:SF 0 "push_operand" "")
2765 (match_operand:SF 1 "memory_operand" ""))]
2767 && (operands[2] = find_constant_src (insn))"
2768 [(set (match_dup 0) (match_dup 2))])
2771 [(set (match_operand 0 "push_operand" "")
2772 (match_operand 1 "general_operand" ""))]
2774 && (GET_MODE (operands[0]) == TFmode
2775 || GET_MODE (operands[0]) == XFmode
2776 || GET_MODE (operands[0]) == DFmode)
2777 && !ANY_FP_REG_P (operands[1])"
2779 "ix86_split_long_move (operands); DONE;")
2781 ;; Floating point move instructions.
2783 (define_expand "movtf"
2784 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2785 (match_operand:TF 1 "nonimmediate_operand" ""))]
2788 ix86_expand_move (TFmode, operands);
2792 (define_expand "mov<mode>"
2793 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2794 (match_operand:X87MODEF 1 "general_operand" ""))]
2796 "ix86_expand_move (<MODE>mode, operands); DONE;")
2798 (define_insn "*movtf_internal"
2799 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2800 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2802 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2803 && (!can_create_pseudo_p ()
2804 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2805 || GET_CODE (operands[1]) != CONST_DOUBLE
2806 || (optimize_function_for_size_p (cfun)
2807 && standard_sse_constant_p (operands[1])
2808 && !memory_operand (operands[0], TFmode))
2809 || (!TARGET_MEMORY_MISMATCH_STALL
2810 && memory_operand (operands[0], TFmode)))"
2812 switch (which_alternative)
2816 /* Handle misaligned load/store since we
2817 don't have movmisaligntf pattern. */
2818 if (misaligned_operand (operands[0], TFmode)
2819 || misaligned_operand (operands[1], TFmode))
2821 if (get_attr_mode (insn) == MODE_V4SF)
2822 return "%vmovups\t{%1, %0|%0, %1}";
2824 return "%vmovdqu\t{%1, %0|%0, %1}";
2828 if (get_attr_mode (insn) == MODE_V4SF)
2829 return "%vmovaps\t{%1, %0|%0, %1}";
2831 return "%vmovdqa\t{%1, %0|%0, %1}";
2835 return standard_sse_constant_opcode (insn, operands[1]);
2845 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2846 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2848 (cond [(eq_attr "alternative" "0,2")
2850 (match_test "optimize_function_for_size_p (cfun)")
2851 (const_string "V4SF")
2852 (const_string "TI"))
2853 (eq_attr "alternative" "1")
2855 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2856 (match_test "optimize_function_for_size_p (cfun)"))
2857 (const_string "V4SF")
2858 (const_string "TI"))]
2859 (const_string "DI")))])
2861 ;; Possible store forwarding (partial memory) stall in alternative 4.
2862 (define_insn "*movxf_internal"
2863 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2864 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2865 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2866 && (!can_create_pseudo_p ()
2867 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2868 || GET_CODE (operands[1]) != CONST_DOUBLE
2869 || (optimize_function_for_size_p (cfun)
2870 && standard_80387_constant_p (operands[1]) > 0
2871 && !memory_operand (operands[0], XFmode))
2872 || (!TARGET_MEMORY_MISMATCH_STALL
2873 && memory_operand (operands[0], XFmode)))"
2875 switch (which_alternative)
2879 return output_387_reg_move (insn, operands);
2882 return standard_80387_constant_opcode (operands[1]);
2892 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2893 (set_attr "mode" "XF,XF,XF,SI,SI")])
2895 (define_insn "*movdf_internal_rex64"
2896 [(set (match_operand:DF 0 "nonimmediate_operand"
2897 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2898 (match_operand:DF 1 "general_operand"
2899 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2900 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2901 && (!can_create_pseudo_p ()
2902 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2903 || GET_CODE (operands[1]) != CONST_DOUBLE
2904 || (optimize_function_for_size_p (cfun)
2905 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2906 && standard_80387_constant_p (operands[1]) > 0)
2907 || (TARGET_SSE2 && TARGET_SSE_MATH
2908 && standard_sse_constant_p (operands[1]))))
2909 || memory_operand (operands[0], DFmode))"
2911 switch (which_alternative)
2915 return output_387_reg_move (insn, operands);
2918 return standard_80387_constant_opcode (operands[1]);
2922 return "mov{q}\t{%1, %0|%0, %1}";
2925 return "movabs{q}\t{%1, %0|%0, %1}";
2931 return standard_sse_constant_opcode (insn, operands[1]);
2936 switch (get_attr_mode (insn))
2939 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2940 return "%vmovapd\t{%1, %0|%0, %1}";
2942 return "%vmovaps\t{%1, %0|%0, %1}";
2945 return "%vmovq\t{%1, %0|%0, %1}";
2947 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2948 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2949 return "%vmovsd\t{%1, %0|%0, %1}";
2951 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2953 return "%vmovlps\t{%1, %d0|%d0, %1}";
2960 /* Handle broken assemblers that require movd instead of movq. */
2961 return "%vmovd\t{%1, %0|%0, %1}";
2968 (cond [(eq_attr "alternative" "0,1,2")
2969 (const_string "fmov")
2970 (eq_attr "alternative" "3,4,5")
2971 (const_string "imov")
2972 (eq_attr "alternative" "6")
2973 (const_string "multi")
2974 (eq_attr "alternative" "7")
2975 (const_string "sselog1")
2977 (const_string "ssemov")))
2980 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2982 (const_string "*")))
2983 (set (attr "length_immediate")
2985 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2987 (const_string "*")))
2988 (set (attr "prefix")
2989 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2990 (const_string "orig")
2991 (const_string "maybe_vex")))
2992 (set (attr "prefix_data16")
2993 (if_then_else (eq_attr "mode" "V1DF")
2995 (const_string "*")))
2997 (cond [(eq_attr "alternative" "0,1,2")
2999 (eq_attr "alternative" "3,4,5,6,11,12")
3002 /* xorps is one byte shorter. */
3003 (eq_attr "alternative" "7")
3004 (cond [(match_test "optimize_function_for_size_p (cfun)")
3005 (const_string "V4SF")
3006 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3009 (const_string "V2DF"))
3011 /* For architectures resolving dependencies on
3012 whole SSE registers use APD move to break dependency
3013 chains, otherwise use short move to avoid extra work.
3015 movaps encodes one byte shorter. */
3016 (eq_attr "alternative" "8")
3018 [(match_test "optimize_function_for_size_p (cfun)")
3019 (const_string "V4SF")
3020 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3021 (const_string "V2DF")
3023 (const_string "DF"))
3024 /* For architectures resolving dependencies on register
3025 parts we may avoid extra work to zero out upper part
3027 (eq_attr "alternative" "9")
3029 (match_test "TARGET_SSE_SPLIT_REGS")
3030 (const_string "V1DF")
3031 (const_string "DF"))
3033 (const_string "DF")))])
3035 ;; Possible store forwarding (partial memory) stall in alternative 4.
3036 (define_insn "*movdf_internal"
3037 [(set (match_operand:DF 0 "nonimmediate_operand"
3038 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3039 (match_operand:DF 1 "general_operand"
3040 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3041 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3042 && (!can_create_pseudo_p ()
3043 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3044 || GET_CODE (operands[1]) != CONST_DOUBLE
3045 || (optimize_function_for_size_p (cfun)
3046 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3047 && standard_80387_constant_p (operands[1]) > 0)
3048 || (TARGET_SSE2 && TARGET_SSE_MATH
3049 && standard_sse_constant_p (operands[1])))
3050 && !memory_operand (operands[0], DFmode))
3051 || (!TARGET_MEMORY_MISMATCH_STALL
3052 && memory_operand (operands[0], DFmode)))"
3054 switch (which_alternative)
3058 return output_387_reg_move (insn, operands);
3061 return standard_80387_constant_opcode (operands[1]);
3069 return standard_sse_constant_opcode (insn, operands[1]);
3077 switch (get_attr_mode (insn))
3080 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3081 return "%vmovapd\t{%1, %0|%0, %1}";
3083 return "%vmovaps\t{%1, %0|%0, %1}";
3086 return "%vmovq\t{%1, %0|%0, %1}";
3088 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3089 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3090 return "%vmovsd\t{%1, %0|%0, %1}";
3092 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3094 return "%vmovlps\t{%1, %d0|%d0, %1}";
3104 (if_then_else (eq_attr "alternative" "5,6,7,8")
3105 (const_string "sse2")
3106 (const_string "*")))
3108 (cond [(eq_attr "alternative" "0,1,2")
3109 (const_string "fmov")
3110 (eq_attr "alternative" "3,4")
3111 (const_string "multi")
3112 (eq_attr "alternative" "5,9")
3113 (const_string "sselog1")
3115 (const_string "ssemov")))
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118 (const_string "orig")
3119 (const_string "maybe_vex")))
3120 (set (attr "prefix_data16")
3121 (if_then_else (eq_attr "mode" "V1DF")
3123 (const_string "*")))
3125 (cond [(eq_attr "alternative" "0,1,2")
3127 (eq_attr "alternative" "3,4")
3130 /* For SSE1, we have many fewer alternatives. */
3131 (not (match_test "TARGET_SSE2"))
3133 (eq_attr "alternative" "5,6,9,10")
3134 (const_string "V4SF")
3135 (const_string "V2SF"))
3137 /* xorps is one byte shorter. */
3138 (eq_attr "alternative" "5,9")
3139 (cond [(match_test "optimize_function_for_size_p (cfun)")
3140 (const_string "V4SF")
3141 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3144 (const_string "V2DF"))
3146 /* For architectures resolving dependencies on
3147 whole SSE registers use APD move to break dependency
3148 chains, otherwise use short move to avoid extra work.
3150 movaps encodes one byte shorter. */
3151 (eq_attr "alternative" "6,10")
3153 [(match_test "optimize_function_for_size_p (cfun)")
3154 (const_string "V4SF")
3155 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3156 (const_string "V2DF")
3158 (const_string "DF"))
3159 /* For architectures resolving dependencies on register
3160 parts we may avoid extra work to zero out upper part
3162 (eq_attr "alternative" "7,11")
3164 (match_test "TARGET_SSE_SPLIT_REGS")
3165 (const_string "V1DF")
3166 (const_string "DF"))
3168 (const_string "DF")))])
3170 (define_insn "*movsf_internal"
3171 [(set (match_operand:SF 0 "nonimmediate_operand"
3172 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3173 (match_operand:SF 1 "general_operand"
3174 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3175 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3176 && (!can_create_pseudo_p ()
3177 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3178 || GET_CODE (operands[1]) != CONST_DOUBLE
3179 || (optimize_function_for_size_p (cfun)
3180 && ((!TARGET_SSE_MATH
3181 && standard_80387_constant_p (operands[1]) > 0)
3183 && standard_sse_constant_p (operands[1]))))
3184 || memory_operand (operands[0], SFmode))"
3186 switch (which_alternative)
3190 return output_387_reg_move (insn, operands);
3193 return standard_80387_constant_opcode (operands[1]);
3197 return "mov{l}\t{%1, %0|%0, %1}";
3200 return standard_sse_constant_opcode (insn, operands[1]);
3203 if (get_attr_mode (insn) == MODE_V4SF)
3204 return "%vmovaps\t{%1, %0|%0, %1}";
3206 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3210 return "%vmovss\t{%1, %0|%0, %1}";
3216 return "movd\t{%1, %0|%0, %1}";
3219 return "movq\t{%1, %0|%0, %1}";
3223 return "%vmovd\t{%1, %0|%0, %1}";
3230 (cond [(eq_attr "alternative" "0,1,2")
3231 (const_string "fmov")
3232 (eq_attr "alternative" "3,4")
3233 (const_string "multi")
3234 (eq_attr "alternative" "5")
3235 (const_string "sselog1")
3236 (eq_attr "alternative" "9,10,11,14,15")
3237 (const_string "mmxmov")
3239 (const_string "ssemov")))
3240 (set (attr "prefix")
3241 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3242 (const_string "maybe_vex")
3243 (const_string "orig")))
3245 (cond [(eq_attr "alternative" "3,4,9,10")
3247 (eq_attr "alternative" "5")
3249 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3250 (match_test "TARGET_SSE2"))
3251 (not (match_test "optimize_function_for_size_p (cfun)")))
3253 (const_string "V4SF"))
3254 /* For architectures resolving dependencies on
3255 whole SSE registers use APS move to break dependency
3256 chains, otherwise use short move to avoid extra work.
3258 Do the same for architectures resolving dependencies on
3259 the parts. While in DF mode it is better to always handle
3260 just register parts, the SF mode is different due to lack
3261 of instructions to load just part of the register. It is
3262 better to maintain the whole registers in single format
3263 to avoid problems on using packed logical operations. */
3264 (eq_attr "alternative" "6")
3266 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3267 (match_test "TARGET_SSE_SPLIT_REGS"))
3268 (const_string "V4SF")
3269 (const_string "SF"))
3270 (eq_attr "alternative" "11")
3271 (const_string "DI")]
3272 (const_string "SF")))])
3275 [(set (match_operand 0 "any_fp_register_operand" "")
3276 (match_operand 1 "memory_operand" ""))]
3278 && (GET_MODE (operands[0]) == TFmode
3279 || GET_MODE (operands[0]) == XFmode
3280 || GET_MODE (operands[0]) == DFmode
3281 || GET_MODE (operands[0]) == SFmode)
3282 && (operands[2] = find_constant_src (insn))"
3283 [(set (match_dup 0) (match_dup 2))]
3285 rtx c = operands[2];
3286 int r = REGNO (operands[0]);
3288 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3289 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3294 [(set (match_operand 0 "any_fp_register_operand" "")
3295 (float_extend (match_operand 1 "memory_operand" "")))]
3297 && (GET_MODE (operands[0]) == TFmode
3298 || GET_MODE (operands[0]) == XFmode
3299 || GET_MODE (operands[0]) == DFmode)
3300 && (operands[2] = find_constant_src (insn))"
3301 [(set (match_dup 0) (match_dup 2))]
3303 rtx c = operands[2];
3304 int r = REGNO (operands[0]);
3306 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3307 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3311 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3313 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3314 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3316 && (standard_80387_constant_p (operands[1]) == 8
3317 || standard_80387_constant_p (operands[1]) == 9)"
3318 [(set (match_dup 0)(match_dup 1))
3320 (neg:X87MODEF (match_dup 0)))]
3324 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3325 if (real_isnegzero (&r))
3326 operands[1] = CONST0_RTX (<MODE>mode);
3328 operands[1] = CONST1_RTX (<MODE>mode);
3332 [(set (match_operand 0 "nonimmediate_operand" "")
3333 (match_operand 1 "general_operand" ""))]
3335 && (GET_MODE (operands[0]) == TFmode
3336 || GET_MODE (operands[0]) == XFmode
3337 || GET_MODE (operands[0]) == DFmode)
3338 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3340 "ix86_split_long_move (operands); DONE;")
3342 (define_insn "swapxf"
3343 [(set (match_operand:XF 0 "register_operand" "+f")
3344 (match_operand:XF 1 "register_operand" "+f"))
3349 if (STACK_TOP_P (operands[0]))
3354 [(set_attr "type" "fxch")
3355 (set_attr "mode" "XF")])
3357 (define_insn "*swap<mode>"
3358 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3359 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3362 "TARGET_80387 || reload_completed"
3364 if (STACK_TOP_P (operands[0]))
3369 [(set_attr "type" "fxch")
3370 (set_attr "mode" "<MODE>")])
3372 ;; Zero extension instructions
3374 (define_expand "zero_extendsidi2"
3375 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3376 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))])
3378 (define_insn "*zero_extendsidi2_rex64"
3379 [(set (match_operand:DI 0 "nonimmediate_operand"
3380 "=r ,o,?*Ym,?*y,?*Yi,!*x")
3382 (match_operand:SI 1 "x86_64_zext_general_operand"
3383 "rmZ,0,r ,m ,r ,m*x")))]
3386 mov{l}\t{%1, %k0|%k0, %1}
3388 movd\t{%1, %0|%0, %1}
3389 movd\t{%1, %0|%0, %1}
3390 %vmovd\t{%1, %0|%0, %1}
3391 %vmovd\t{%1, %0|%0, %1}"
3392 [(set_attr "isa" "*,*,*,*,*,sse2")
3393 (set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3394 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3395 (set_attr "prefix_0f" "0,*,*,*,*,*")
3396 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3398 (define_insn "*zero_extendsidi2"
3399 [(set (match_operand:DI 0 "nonimmediate_operand"
3400 "=ro,?r,?o,?*Ym,?*y,?*Yi,!*x")
3401 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3402 "0 ,rm,r ,r ,m ,r ,m*x")))]
3408 movd\t{%1, %0|%0, %1}
3409 movd\t{%1, %0|%0, %1}
3410 %vmovd\t{%1, %0|%0, %1}
3411 %vmovd\t{%1, %0|%0, %1}"
3412 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3413 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3414 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3415 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3418 [(set (match_operand:DI 0 "memory_operand" "")
3419 (zero_extend:DI (match_operand:SI 1 "memory_operand" "")))]
3421 [(set (match_dup 4) (const_int 0))]
3422 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3425 [(set (match_operand:DI 0 "register_operand" "")
3426 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3427 "!TARGET_64BIT && reload_completed
3428 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3429 && true_regnum (operands[0]) == true_regnum (operands[1])"
3430 [(set (match_dup 4) (const_int 0))]
3431 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3434 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3435 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3436 "!TARGET_64BIT && reload_completed
3437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3438 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3439 [(set (match_dup 3) (match_dup 1))
3440 (set (match_dup 4) (const_int 0))]
3441 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3443 (define_insn "zero_extend<mode>di2"
3444 [(set (match_operand:DI 0 "register_operand" "=r")
3446 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3448 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3449 [(set_attr "type" "imovx")
3450 (set_attr "mode" "SI")])
3452 (define_expand "zero_extend<mode>si2"
3453 [(set (match_operand:SI 0 "register_operand" "")
3454 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand" "")))]
3457 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3459 operands[1] = force_reg (<MODE>mode, operands[1]);
3460 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3465 (define_insn_and_split "zero_extend<mode>si2_and"
3466 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3468 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3469 (clobber (reg:CC FLAGS_REG))]
3470 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3472 "&& reload_completed"
3473 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3474 (clobber (reg:CC FLAGS_REG))])]
3476 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3478 ix86_expand_clear (operands[0]);
3480 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3481 emit_insn (gen_movstrict<mode>
3482 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3486 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3488 [(set_attr "type" "alu1")
3489 (set_attr "mode" "SI")])
3491 (define_insn "*zero_extend<mode>si2"
3492 [(set (match_operand:SI 0 "register_operand" "=r")
3494 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3495 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3496 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3497 [(set_attr "type" "imovx")
3498 (set_attr "mode" "SI")])
3500 (define_expand "zero_extendqihi2"
3501 [(set (match_operand:HI 0 "register_operand" "")
3502 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3505 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3507 operands[1] = force_reg (QImode, operands[1]);
3508 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3513 (define_insn_and_split "zero_extendqihi2_and"
3514 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3515 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3516 (clobber (reg:CC FLAGS_REG))]
3517 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3519 "&& reload_completed"
3520 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3521 (clobber (reg:CC FLAGS_REG))])]
3523 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3525 ix86_expand_clear (operands[0]);
3527 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3528 emit_insn (gen_movstrictqi
3529 (gen_lowpart (QImode, operands[0]), operands[1]));
3533 operands[0] = gen_lowpart (SImode, operands[0]);
3535 [(set_attr "type" "alu1")
3536 (set_attr "mode" "SI")])
3538 ; zero extend to SImode to avoid partial register stalls
3539 (define_insn "*zero_extendqihi2"
3540 [(set (match_operand:HI 0 "register_operand" "=r")
3541 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3542 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3543 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3544 [(set_attr "type" "imovx")
3545 (set_attr "mode" "SI")])
3547 ;; Sign extension instructions
3549 (define_expand "extendsidi2"
3550 [(set (match_operand:DI 0 "register_operand" "")
3551 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3556 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3561 (define_insn "*extendsidi2_rex64"
3562 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3563 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3567 movs{lq|x}\t{%1, %0|%0, %1}"
3568 [(set_attr "type" "imovx")
3569 (set_attr "mode" "DI")
3570 (set_attr "prefix_0f" "0")
3571 (set_attr "modrm" "0,1")])
3573 (define_insn "extendsidi2_1"
3574 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3575 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3576 (clobber (reg:CC FLAGS_REG))
3577 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3581 ;; Extend to memory case when source register does die.
3583 [(set (match_operand:DI 0 "memory_operand" "")
3584 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3585 (clobber (reg:CC FLAGS_REG))
3586 (clobber (match_operand:SI 2 "register_operand" ""))]
3588 && dead_or_set_p (insn, operands[1])
3589 && !reg_mentioned_p (operands[1], operands[0]))"
3590 [(set (match_dup 3) (match_dup 1))
3591 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3592 (clobber (reg:CC FLAGS_REG))])
3593 (set (match_dup 4) (match_dup 1))]
3594 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3596 ;; Extend to memory case when source register does not die.
3598 [(set (match_operand:DI 0 "memory_operand" "")
3599 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3600 (clobber (reg:CC FLAGS_REG))
3601 (clobber (match_operand:SI 2 "register_operand" ""))]
3605 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3607 emit_move_insn (operands[3], operands[1]);
3609 /* Generate a cltd if possible and doing so it profitable. */
3610 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3611 && true_regnum (operands[1]) == AX_REG
3612 && true_regnum (operands[2]) == DX_REG)
3614 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3618 emit_move_insn (operands[2], operands[1]);
3619 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3621 emit_move_insn (operands[4], operands[2]);
3625 ;; Extend to register case. Optimize case where source and destination
3626 ;; registers match and cases where we can use cltd.
3628 [(set (match_operand:DI 0 "register_operand" "")
3629 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3630 (clobber (reg:CC FLAGS_REG))
3631 (clobber (match_scratch:SI 2 ""))]
3635 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3637 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3638 emit_move_insn (operands[3], operands[1]);
3640 /* Generate a cltd if possible and doing so it profitable. */
3641 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3642 && true_regnum (operands[3]) == AX_REG
3643 && true_regnum (operands[4]) == DX_REG)
3645 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3649 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3650 emit_move_insn (operands[4], operands[1]);
3652 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3656 (define_insn "extend<mode>di2"
3657 [(set (match_operand:DI 0 "register_operand" "=r")
3659 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3661 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3662 [(set_attr "type" "imovx")
3663 (set_attr "mode" "DI")])
3665 (define_insn "extendhisi2"
3666 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3667 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3670 switch (get_attr_prefix_0f (insn))
3673 return "{cwtl|cwde}";
3675 return "movs{wl|x}\t{%1, %0|%0, %1}";
3678 [(set_attr "type" "imovx")
3679 (set_attr "mode" "SI")
3680 (set (attr "prefix_0f")
3681 ;; movsx is short decodable while cwtl is vector decoded.
3682 (if_then_else (and (eq_attr "cpu" "!k6")
3683 (eq_attr "alternative" "0"))
3685 (const_string "1")))
3687 (if_then_else (eq_attr "prefix_0f" "0")
3689 (const_string "1")))])
3691 (define_insn "*extendhisi2_zext"
3692 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3695 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3698 switch (get_attr_prefix_0f (insn))
3701 return "{cwtl|cwde}";
3703 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3706 [(set_attr "type" "imovx")
3707 (set_attr "mode" "SI")
3708 (set (attr "prefix_0f")
3709 ;; movsx is short decodable while cwtl is vector decoded.
3710 (if_then_else (and (eq_attr "cpu" "!k6")
3711 (eq_attr "alternative" "0"))
3713 (const_string "1")))
3715 (if_then_else (eq_attr "prefix_0f" "0")
3717 (const_string "1")))])
3719 (define_insn "extendqisi2"
3720 [(set (match_operand:SI 0 "register_operand" "=r")
3721 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3723 "movs{bl|x}\t{%1, %0|%0, %1}"
3724 [(set_attr "type" "imovx")
3725 (set_attr "mode" "SI")])
3727 (define_insn "*extendqisi2_zext"
3728 [(set (match_operand:DI 0 "register_operand" "=r")
3730 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3732 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3733 [(set_attr "type" "imovx")
3734 (set_attr "mode" "SI")])
3736 (define_insn "extendqihi2"
3737 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3738 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3741 switch (get_attr_prefix_0f (insn))
3744 return "{cbtw|cbw}";
3746 return "movs{bw|x}\t{%1, %0|%0, %1}";
3749 [(set_attr "type" "imovx")
3750 (set_attr "mode" "HI")
3751 (set (attr "prefix_0f")
3752 ;; movsx is short decodable while cwtl is vector decoded.
3753 (if_then_else (and (eq_attr "cpu" "!k6")
3754 (eq_attr "alternative" "0"))
3756 (const_string "1")))
3758 (if_then_else (eq_attr "prefix_0f" "0")
3760 (const_string "1")))])
3762 ;; Conversions between float and double.
3764 ;; These are all no-ops in the model used for the 80387.
3765 ;; So just emit moves.
3767 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3769 [(set (match_operand:DF 0 "push_operand" "")
3770 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3772 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3773 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3776 [(set (match_operand:XF 0 "push_operand" "")
3777 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3779 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3780 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3781 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3783 (define_expand "extendsfdf2"
3784 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3785 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3786 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3788 /* ??? Needed for compress_float_constant since all fp constants
3789 are TARGET_LEGITIMATE_CONSTANT_P. */
3790 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3792 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3793 && standard_80387_constant_p (operands[1]) > 0)
3795 operands[1] = simplify_const_unary_operation
3796 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3797 emit_move_insn_1 (operands[0], operands[1]);
3800 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3804 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3806 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3808 We do the conversion post reload to avoid producing of 128bit spills
3809 that might lead to ICE on 32bit target. The sequence unlikely combine
3812 [(set (match_operand:DF 0 "register_operand" "")
3814 (match_operand:SF 1 "nonimmediate_operand" "")))]
3815 "TARGET_USE_VECTOR_FP_CONVERTS
3816 && optimize_insn_for_speed_p ()
3817 && reload_completed && SSE_REG_P (operands[0])"
3822 (parallel [(const_int 0) (const_int 1)]))))]
3824 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3825 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3826 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3827 Try to avoid move when unpacking can be done in source. */
3828 if (REG_P (operands[1]))
3830 /* If it is unsafe to overwrite upper half of source, we need
3831 to move to destination and unpack there. */
3832 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3833 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3834 && true_regnum (operands[0]) != true_regnum (operands[1]))
3836 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3837 emit_move_insn (tmp, operands[1]);
3840 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3841 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3845 emit_insn (gen_vec_setv4sf_0 (operands[3],
3846 CONST0_RTX (V4SFmode), operands[1]));
3849 (define_insn "*extendsfdf2_mixed"
3850 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3852 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3853 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3855 switch (which_alternative)
3859 return output_387_reg_move (insn, operands);
3862 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3868 [(set_attr "type" "fmov,fmov,ssecvt")
3869 (set_attr "prefix" "orig,orig,maybe_vex")
3870 (set_attr "mode" "SF,XF,DF")])
3872 (define_insn "*extendsfdf2_sse"
3873 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3874 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3875 "TARGET_SSE2 && TARGET_SSE_MATH"
3876 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3877 [(set_attr "type" "ssecvt")
3878 (set_attr "prefix" "maybe_vex")
3879 (set_attr "mode" "DF")])
3881 (define_insn "*extendsfdf2_i387"
3882 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3883 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3885 "* return output_387_reg_move (insn, operands);"
3886 [(set_attr "type" "fmov")
3887 (set_attr "mode" "SF,XF")])
3889 (define_expand "extend<mode>xf2"
3890 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3891 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3894 /* ??? Needed for compress_float_constant since all fp constants
3895 are TARGET_LEGITIMATE_CONSTANT_P. */
3896 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3898 if (standard_80387_constant_p (operands[1]) > 0)
3900 operands[1] = simplify_const_unary_operation
3901 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3902 emit_move_insn_1 (operands[0], operands[1]);
3905 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3909 (define_insn "*extend<mode>xf2_i387"
3910 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3912 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3914 "* return output_387_reg_move (insn, operands);"
3915 [(set_attr "type" "fmov")
3916 (set_attr "mode" "<MODE>,XF")])
3918 ;; %%% This seems bad bad news.
3919 ;; This cannot output into an f-reg because there is no way to be sure
3920 ;; of truncating in that case. Otherwise this is just like a simple move
3921 ;; insn. So we pretend we can output to a reg in order to get better
3922 ;; register preferencing, but we really use a stack slot.
3924 ;; Conversion from DFmode to SFmode.
3926 (define_expand "truncdfsf2"
3927 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3929 (match_operand:DF 1 "nonimmediate_operand" "")))]
3930 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3932 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3934 else if (flag_unsafe_math_optimizations)
3938 enum ix86_stack_slot slot = (virtuals_instantiated
3941 rtx temp = assign_386_stack_local (SFmode, slot);
3942 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3947 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3949 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3951 We do the conversion post reload to avoid producing of 128bit spills
3952 that might lead to ICE on 32bit target. The sequence unlikely combine
3955 [(set (match_operand:SF 0 "register_operand" "")
3957 (match_operand:DF 1 "nonimmediate_operand" "")))]
3958 "TARGET_USE_VECTOR_FP_CONVERTS
3959 && optimize_insn_for_speed_p ()
3960 && reload_completed && SSE_REG_P (operands[0])"
3963 (float_truncate:V2SF
3967 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3968 operands[3] = CONST0_RTX (V2SFmode);
3969 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3970 /* Use movsd for loading from memory, unpcklpd for registers.
3971 Try to avoid move when unpacking can be done in source, or SSE3
3972 movddup is available. */
3973 if (REG_P (operands[1]))
3976 && true_regnum (operands[0]) != true_regnum (operands[1])
3977 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3978 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3980 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3981 emit_move_insn (tmp, operands[1]);
3984 else if (!TARGET_SSE3)
3985 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3986 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3989 emit_insn (gen_sse2_loadlpd (operands[4],
3990 CONST0_RTX (V2DFmode), operands[1]));
3993 (define_expand "truncdfsf2_with_temp"
3994 [(parallel [(set (match_operand:SF 0 "" "")
3995 (float_truncate:SF (match_operand:DF 1 "" "")))
3996 (clobber (match_operand:SF 2 "" ""))])])
3998 (define_insn "*truncdfsf_fast_mixed"
3999 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4001 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4002 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4004 switch (which_alternative)
4007 return output_387_reg_move (insn, operands);
4009 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4014 [(set_attr "type" "fmov,ssecvt")
4015 (set_attr "prefix" "orig,maybe_vex")
4016 (set_attr "mode" "SF")])
4018 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4019 ;; because nothing we do here is unsafe.
4020 (define_insn "*truncdfsf_fast_sse"
4021 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4023 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4024 "TARGET_SSE2 && TARGET_SSE_MATH"
4025 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4026 [(set_attr "type" "ssecvt")
4027 (set_attr "prefix" "maybe_vex")
4028 (set_attr "mode" "SF")])
4030 (define_insn "*truncdfsf_fast_i387"
4031 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4033 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4034 "TARGET_80387 && flag_unsafe_math_optimizations"
4035 "* return output_387_reg_move (insn, operands);"
4036 [(set_attr "type" "fmov")
4037 (set_attr "mode" "SF")])
4039 (define_insn "*truncdfsf_mixed"
4040 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4042 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4043 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4044 "TARGET_MIX_SSE_I387"
4046 switch (which_alternative)
4049 return output_387_reg_move (insn, operands);
4051 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4057 [(set_attr "isa" "*,sse2,*,*,*")
4058 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4059 (set_attr "unit" "*,*,i387,i387,i387")
4060 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4061 (set_attr "mode" "SF")])
4063 (define_insn "*truncdfsf_i387"
4064 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4066 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4067 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4070 switch (which_alternative)
4073 return output_387_reg_move (insn, operands);
4079 [(set_attr "type" "fmov,multi,multi,multi")
4080 (set_attr "unit" "*,i387,i387,i387")
4081 (set_attr "mode" "SF")])
4083 (define_insn "*truncdfsf2_i387_1"
4084 [(set (match_operand:SF 0 "memory_operand" "=m")
4086 (match_operand:DF 1 "register_operand" "f")))]
4088 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4089 && !TARGET_MIX_SSE_I387"
4090 "* return output_387_reg_move (insn, operands);"
4091 [(set_attr "type" "fmov")
4092 (set_attr "mode" "SF")])
4095 [(set (match_operand:SF 0 "register_operand" "")
4097 (match_operand:DF 1 "fp_register_operand" "")))
4098 (clobber (match_operand 2 "" ""))]
4100 [(set (match_dup 2) (match_dup 1))
4101 (set (match_dup 0) (match_dup 2))]
4102 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4104 ;; Conversion from XFmode to {SF,DF}mode
4106 (define_expand "truncxf<mode>2"
4107 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4108 (float_truncate:MODEF
4109 (match_operand:XF 1 "register_operand" "")))
4110 (clobber (match_dup 2))])]
4113 if (flag_unsafe_math_optimizations)
4115 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4116 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4117 if (reg != operands[0])
4118 emit_move_insn (operands[0], reg);
4123 enum ix86_stack_slot slot = (virtuals_instantiated
4126 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4130 (define_insn "*truncxfsf2_mixed"
4131 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4133 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4134 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4137 gcc_assert (!which_alternative);
4138 return output_387_reg_move (insn, operands);
4140 [(set_attr "type" "fmov,multi,multi,multi")
4141 (set_attr "unit" "*,i387,i387,i387")
4142 (set_attr "mode" "SF")])
4144 (define_insn "*truncxfdf2_mixed"
4145 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4147 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4148 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4151 gcc_assert (!which_alternative);
4152 return output_387_reg_move (insn, operands);
4154 [(set_attr "isa" "*,*,sse2,*")
4155 (set_attr "type" "fmov,multi,multi,multi")
4156 (set_attr "unit" "*,i387,i387,i387")
4157 (set_attr "mode" "DF")])
4159 (define_insn "truncxf<mode>2_i387_noop"
4160 [(set (match_operand:MODEF 0 "register_operand" "=f")
4161 (float_truncate:MODEF
4162 (match_operand:XF 1 "register_operand" "f")))]
4163 "TARGET_80387 && flag_unsafe_math_optimizations"
4164 "* return output_387_reg_move (insn, operands);"
4165 [(set_attr "type" "fmov")
4166 (set_attr "mode" "<MODE>")])
4168 (define_insn "*truncxf<mode>2_i387"
4169 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4170 (float_truncate:MODEF
4171 (match_operand:XF 1 "register_operand" "f")))]
4173 "* return output_387_reg_move (insn, operands);"
4174 [(set_attr "type" "fmov")
4175 (set_attr "mode" "<MODE>")])
4178 [(set (match_operand:MODEF 0 "register_operand" "")
4179 (float_truncate:MODEF
4180 (match_operand:XF 1 "register_operand" "")))
4181 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4182 "TARGET_80387 && reload_completed"
4183 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4184 (set (match_dup 0) (match_dup 2))])
4187 [(set (match_operand:MODEF 0 "memory_operand" "")
4188 (float_truncate:MODEF
4189 (match_operand:XF 1 "register_operand" "")))
4190 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4192 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4194 ;; Signed conversion to DImode.
4196 (define_expand "fix_truncxfdi2"
4197 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4198 (fix:DI (match_operand:XF 1 "register_operand" "")))
4199 (clobber (reg:CC FLAGS_REG))])]
4204 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4209 (define_expand "fix_trunc<mode>di2"
4210 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4211 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4212 (clobber (reg:CC FLAGS_REG))])]
4213 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4216 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4218 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4221 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4223 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4224 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4225 if (out != operands[0])
4226 emit_move_insn (operands[0], out);
4231 ;; Signed conversion to SImode.
4233 (define_expand "fix_truncxfsi2"
4234 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4235 (fix:SI (match_operand:XF 1 "register_operand" "")))
4236 (clobber (reg:CC FLAGS_REG))])]
4241 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4246 (define_expand "fix_trunc<mode>si2"
4247 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4248 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4249 (clobber (reg:CC FLAGS_REG))])]
4250 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4253 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4255 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4258 if (SSE_FLOAT_MODE_P (<MODE>mode))
4260 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4261 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4262 if (out != operands[0])
4263 emit_move_insn (operands[0], out);
4268 ;; Signed conversion to HImode.
4270 (define_expand "fix_trunc<mode>hi2"
4271 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4272 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4273 (clobber (reg:CC FLAGS_REG))])]
4275 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4279 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4284 ;; Unsigned conversion to SImode.
4286 (define_expand "fixuns_trunc<mode>si2"
4288 [(set (match_operand:SI 0 "register_operand" "")
4290 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4292 (clobber (match_scratch:<ssevecmode> 3 ""))
4293 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4294 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4296 enum machine_mode mode = <MODE>mode;
4297 enum machine_mode vecmode = <ssevecmode>mode;
4298 REAL_VALUE_TYPE TWO31r;
4301 if (optimize_insn_for_size_p ())
4304 real_ldexp (&TWO31r, &dconst1, 31);
4305 two31 = const_double_from_real_value (TWO31r, mode);
4306 two31 = ix86_build_const_vector (vecmode, true, two31);
4307 operands[2] = force_reg (vecmode, two31);
4310 (define_insn_and_split "*fixuns_trunc<mode>_1"
4311 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4313 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4314 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4315 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4316 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4317 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4318 && optimize_function_for_speed_p (cfun)"
4320 "&& reload_completed"
4323 ix86_split_convert_uns_si_sse (operands);
4327 ;; Unsigned conversion to HImode.
4328 ;; Without these patterns, we'll try the unsigned SI conversion which
4329 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4331 (define_expand "fixuns_trunc<mode>hi2"
4333 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4334 (set (match_operand:HI 0 "nonimmediate_operand" "")
4335 (subreg:HI (match_dup 2) 0))]
4336 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4337 "operands[2] = gen_reg_rtx (SImode);")
4339 ;; When SSE is available, it is always faster to use it!
4340 (define_insn "fix_trunc<mode>di_sse"
4341 [(set (match_operand:DI 0 "register_operand" "=r,r")
4342 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4343 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4344 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4345 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4346 [(set_attr "type" "sseicvt")
4347 (set_attr "prefix" "maybe_vex")
4348 (set_attr "prefix_rex" "1")
4349 (set_attr "mode" "<MODE>")
4350 (set_attr "athlon_decode" "double,vector")
4351 (set_attr "amdfam10_decode" "double,double")
4352 (set_attr "bdver1_decode" "double,double")])
4354 (define_insn "fix_trunc<mode>si_sse"
4355 [(set (match_operand:SI 0 "register_operand" "=r,r")
4356 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4357 "SSE_FLOAT_MODE_P (<MODE>mode)
4358 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4359 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4360 [(set_attr "type" "sseicvt")
4361 (set_attr "prefix" "maybe_vex")
4362 (set_attr "mode" "<MODE>")
4363 (set_attr "athlon_decode" "double,vector")
4364 (set_attr "amdfam10_decode" "double,double")
4365 (set_attr "bdver1_decode" "double,double")])
4367 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4369 [(set (match_operand:MODEF 0 "register_operand" "")
4370 (match_operand:MODEF 1 "memory_operand" ""))
4371 (set (match_operand:SWI48x 2 "register_operand" "")
4372 (fix:SWI48x (match_dup 0)))]
4373 "TARGET_SHORTEN_X87_SSE
4374 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4375 && peep2_reg_dead_p (2, operands[0])"
4376 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4378 ;; Avoid vector decoded forms of the instruction.
4380 [(match_scratch:DF 2 "x")
4381 (set (match_operand:SWI48x 0 "register_operand" "")
4382 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4383 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4384 [(set (match_dup 2) (match_dup 1))
4385 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4388 [(match_scratch:SF 2 "x")
4389 (set (match_operand:SWI48x 0 "register_operand" "")
4390 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4391 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4392 [(set (match_dup 2) (match_dup 1))
4393 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4395 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4396 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4397 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4398 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4400 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4401 && (TARGET_64BIT || <MODE>mode != DImode))
4403 && can_create_pseudo_p ()"
4408 if (memory_operand (operands[0], VOIDmode))
4409 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4412 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4413 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4419 [(set_attr "type" "fisttp")
4420 (set_attr "mode" "<MODE>")])
4422 (define_insn "fix_trunc<mode>_i387_fisttp"
4423 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4424 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4425 (clobber (match_scratch:XF 2 "=&1f"))]
4426 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4428 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4429 && (TARGET_64BIT || <MODE>mode != DImode))
4430 && TARGET_SSE_MATH)"
4431 "* return output_fix_trunc (insn, operands, true);"
4432 [(set_attr "type" "fisttp")
4433 (set_attr "mode" "<MODE>")])
4435 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4436 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4437 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4438 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4439 (clobber (match_scratch:XF 3 "=&1f,&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)"
4446 [(set_attr "type" "fisttp")
4447 (set_attr "mode" "<MODE>")])
4450 [(set (match_operand:SWI248x 0 "register_operand" "")
4451 (fix:SWI248x (match_operand 1 "register_operand" "")))
4452 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4453 (clobber (match_scratch 3 ""))]
4455 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4456 (clobber (match_dup 3))])
4457 (set (match_dup 0) (match_dup 2))])
4460 [(set (match_operand:SWI248x 0 "memory_operand" "")
4461 (fix:SWI248x (match_operand 1 "register_operand" "")))
4462 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4463 (clobber (match_scratch 3 ""))]
4465 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4466 (clobber (match_dup 3))])])
4468 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4469 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4470 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4471 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4472 ;; function in i386.c.
4473 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4474 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4475 (fix:SWI248x (match_operand 1 "register_operand" "")))
4476 (clobber (reg:CC FLAGS_REG))]
4477 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4479 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4480 && (TARGET_64BIT || <MODE>mode != DImode))
4481 && can_create_pseudo_p ()"
4486 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4488 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4489 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4490 if (memory_operand (operands[0], VOIDmode))
4491 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4492 operands[2], operands[3]));
4495 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4496 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4497 operands[2], operands[3],
4502 [(set_attr "type" "fistp")
4503 (set_attr "i387_cw" "trunc")
4504 (set_attr "mode" "<MODE>")])
4506 (define_insn "fix_truncdi_i387"
4507 [(set (match_operand:DI 0 "memory_operand" "=m")
4508 (fix:DI (match_operand 1 "register_operand" "f")))
4509 (use (match_operand:HI 2 "memory_operand" "m"))
4510 (use (match_operand:HI 3 "memory_operand" "m"))
4511 (clobber (match_scratch:XF 4 "=&1f"))]
4512 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4514 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4515 "* return output_fix_trunc (insn, operands, false);"
4516 [(set_attr "type" "fistp")
4517 (set_attr "i387_cw" "trunc")
4518 (set_attr "mode" "DI")])
4520 (define_insn "fix_truncdi_i387_with_temp"
4521 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4522 (fix:DI (match_operand 1 "register_operand" "f,f")))
4523 (use (match_operand:HI 2 "memory_operand" "m,m"))
4524 (use (match_operand:HI 3 "memory_operand" "m,m"))
4525 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4526 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4527 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4529 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4531 [(set_attr "type" "fistp")
4532 (set_attr "i387_cw" "trunc")
4533 (set_attr "mode" "DI")])
4536 [(set (match_operand:DI 0 "register_operand" "")
4537 (fix:DI (match_operand 1 "register_operand" "")))
4538 (use (match_operand:HI 2 "memory_operand" ""))
4539 (use (match_operand:HI 3 "memory_operand" ""))
4540 (clobber (match_operand:DI 4 "memory_operand" ""))
4541 (clobber (match_scratch 5 ""))]
4543 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4546 (clobber (match_dup 5))])
4547 (set (match_dup 0) (match_dup 4))])
4550 [(set (match_operand:DI 0 "memory_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 0) (fix:DI (match_dup 1)))
4560 (clobber (match_dup 5))])])
4562 (define_insn "fix_trunc<mode>_i387"
4563 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4564 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4565 (use (match_operand:HI 2 "memory_operand" "m"))
4566 (use (match_operand:HI 3 "memory_operand" "m"))]
4567 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4569 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4570 "* return output_fix_trunc (insn, operands, false);"
4571 [(set_attr "type" "fistp")
4572 (set_attr "i387_cw" "trunc")
4573 (set_attr "mode" "<MODE>")])
4575 (define_insn "fix_trunc<mode>_i387_with_temp"
4576 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4577 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4578 (use (match_operand:HI 2 "memory_operand" "m,m"))
4579 (use (match_operand:HI 3 "memory_operand" "m,m"))
4580 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4581 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4585 [(set_attr "type" "fistp")
4586 (set_attr "i387_cw" "trunc")
4587 (set_attr "mode" "<MODE>")])
4590 [(set (match_operand:SWI24 0 "register_operand" "")
4591 (fix:SWI24 (match_operand 1 "register_operand" "")))
4592 (use (match_operand:HI 2 "memory_operand" ""))
4593 (use (match_operand:HI 3 "memory_operand" ""))
4594 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4596 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4598 (use (match_dup 3))])
4599 (set (match_dup 0) (match_dup 4))])
4602 [(set (match_operand:SWI24 0 "memory_operand" "")
4603 (fix:SWI24 (match_operand 1 "register_operand" "")))
4604 (use (match_operand:HI 2 "memory_operand" ""))
4605 (use (match_operand:HI 3 "memory_operand" ""))
4606 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4608 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4610 (use (match_dup 3))])])
4612 (define_insn "x86_fnstcw_1"
4613 [(set (match_operand:HI 0 "memory_operand" "=m")
4614 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4617 [(set (attr "length")
4618 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4619 (set_attr "mode" "HI")
4620 (set_attr "unit" "i387")
4621 (set_attr "bdver1_decode" "vector")])
4623 (define_insn "x86_fldcw_1"
4624 [(set (reg:HI FPCR_REG)
4625 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4628 [(set (attr "length")
4629 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4630 (set_attr "mode" "HI")
4631 (set_attr "unit" "i387")
4632 (set_attr "athlon_decode" "vector")
4633 (set_attr "amdfam10_decode" "vector")
4634 (set_attr "bdver1_decode" "vector")])
4636 ;; Conversion between fixed point and floating point.
4638 ;; Even though we only accept memory inputs, the backend _really_
4639 ;; wants to be able to do this between registers.
4641 (define_expand "floathi<mode>2"
4642 [(set (match_operand:X87MODEF 0 "register_operand" "")
4643 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4645 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4646 || TARGET_MIX_SSE_I387)")
4648 ;; Pre-reload splitter to add memory clobber to the pattern.
4649 (define_insn_and_split "*floathi<mode>2_1"
4650 [(set (match_operand:X87MODEF 0 "register_operand" "")
4651 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4654 || TARGET_MIX_SSE_I387)
4655 && can_create_pseudo_p ()"
4658 [(parallel [(set (match_dup 0)
4659 (float:X87MODEF (match_dup 1)))
4660 (clobber (match_dup 2))])]
4661 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4663 (define_insn "*floathi<mode>2_i387_with_temp"
4664 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4665 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4666 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4669 || TARGET_MIX_SSE_I387)"
4671 [(set_attr "type" "fmov,multi")
4672 (set_attr "mode" "<MODE>")
4673 (set_attr "unit" "*,i387")
4674 (set_attr "fp_int_src" "true")])
4676 (define_insn "*floathi<mode>2_i387"
4677 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4678 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4680 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4681 || TARGET_MIX_SSE_I387)"
4683 [(set_attr "type" "fmov")
4684 (set_attr "mode" "<MODE>")
4685 (set_attr "fp_int_src" "true")])
4688 [(set (match_operand:X87MODEF 0 "register_operand" "")
4689 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4690 (clobber (match_operand:HI 2 "memory_operand" ""))]
4692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4693 || TARGET_MIX_SSE_I387)
4694 && reload_completed"
4695 [(set (match_dup 2) (match_dup 1))
4696 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4699 [(set (match_operand:X87MODEF 0 "register_operand" "")
4700 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4701 (clobber (match_operand:HI 2 "memory_operand" ""))]
4703 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4704 || TARGET_MIX_SSE_I387)
4705 && reload_completed"
4706 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4708 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4709 [(set (match_operand:X87MODEF 0 "register_operand" "")
4711 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4713 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4714 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4716 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4717 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4718 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4720 rtx reg = gen_reg_rtx (XFmode);
4721 rtx (*insn)(rtx, rtx);
4723 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4725 if (<X87MODEF:MODE>mode == SFmode)
4726 insn = gen_truncxfsf2;
4727 else if (<X87MODEF:MODE>mode == DFmode)
4728 insn = gen_truncxfdf2;
4732 emit_insn (insn (operands[0], reg));
4737 ;; Pre-reload splitter to add memory clobber to the pattern.
4738 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4739 [(set (match_operand:X87MODEF 0 "register_operand" "")
4740 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4742 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4743 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4744 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4745 || TARGET_MIX_SSE_I387))
4746 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4747 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4748 && ((<SWI48x:MODE>mode == SImode
4749 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4750 && optimize_function_for_speed_p (cfun)
4751 && flag_trapping_math)
4752 || !(TARGET_INTER_UNIT_CONVERSIONS
4753 || optimize_function_for_size_p (cfun)))))
4754 && can_create_pseudo_p ()"
4757 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4758 (clobber (match_dup 2))])]
4760 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4762 /* Avoid store forwarding (partial memory) stall penalty
4763 by passing DImode value through XMM registers. */
4764 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4765 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4766 && optimize_function_for_speed_p (cfun))
4768 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4775 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4776 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4778 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4779 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4780 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4781 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4783 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4784 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4785 (set_attr "unit" "*,i387,*,*,*")
4786 (set_attr "athlon_decode" "*,*,double,direct,double")
4787 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4788 (set_attr "bdver1_decode" "*,*,double,direct,double")
4789 (set_attr "fp_int_src" "true")])
4791 (define_insn "*floatsi<mode>2_vector_mixed"
4792 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4793 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4794 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4795 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4799 [(set_attr "type" "fmov,sseicvt")
4800 (set_attr "mode" "<MODE>,<ssevecmode>")
4801 (set_attr "unit" "i387,*")
4802 (set_attr "athlon_decode" "*,direct")
4803 (set_attr "amdfam10_decode" "*,double")
4804 (set_attr "bdver1_decode" "*,direct")
4805 (set_attr "fp_int_src" "true")])
4807 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4808 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4810 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4811 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4812 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4813 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4815 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4816 (set_attr "mode" "<MODEF:MODE>")
4817 (set_attr "unit" "*,i387,*,*")
4818 (set_attr "athlon_decode" "*,*,double,direct")
4819 (set_attr "amdfam10_decode" "*,*,vector,double")
4820 (set_attr "bdver1_decode" "*,*,double,direct")
4821 (set_attr "fp_int_src" "true")])
4824 [(set (match_operand:MODEF 0 "register_operand" "")
4825 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4826 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4827 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4828 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4829 && TARGET_INTER_UNIT_CONVERSIONS
4831 && (SSE_REG_P (operands[0])
4832 || (GET_CODE (operands[0]) == SUBREG
4833 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4834 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4837 [(set (match_operand:MODEF 0 "register_operand" "")
4838 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4839 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4840 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4841 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4842 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4844 && (SSE_REG_P (operands[0])
4845 || (GET_CODE (operands[0]) == SUBREG
4846 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4847 [(set (match_dup 2) (match_dup 1))
4848 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4850 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4851 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4853 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
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))"
4859 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4860 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4861 [(set_attr "type" "fmov,sseicvt,sseicvt")
4862 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4863 (set_attr "mode" "<MODEF:MODE>")
4864 (set (attr "prefix_rex")
4866 (and (eq_attr "prefix" "maybe_vex")
4867 (match_test "<SWI48x:MODE>mode == DImode"))
4869 (const_string "*")))
4870 (set_attr "unit" "i387,*,*")
4871 (set_attr "athlon_decode" "*,double,direct")
4872 (set_attr "amdfam10_decode" "*,vector,double")
4873 (set_attr "bdver1_decode" "*,double,direct")
4874 (set_attr "fp_int_src" "true")])
4876 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4877 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4879 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4880 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4881 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4882 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4885 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4886 [(set_attr "type" "fmov,sseicvt")
4887 (set_attr "prefix" "orig,maybe_vex")
4888 (set_attr "mode" "<MODEF:MODE>")
4889 (set (attr "prefix_rex")
4891 (and (eq_attr "prefix" "maybe_vex")
4892 (match_test "<SWI48x:MODE>mode == DImode"))
4894 (const_string "*")))
4895 (set_attr "athlon_decode" "*,direct")
4896 (set_attr "amdfam10_decode" "*,double")
4897 (set_attr "bdver1_decode" "*,direct")
4898 (set_attr "fp_int_src" "true")])
4900 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4901 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4903 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4904 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4905 "TARGET_SSE2 && TARGET_SSE_MATH
4906 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4908 [(set_attr "type" "sseicvt")
4909 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4910 (set_attr "athlon_decode" "double,direct,double")
4911 (set_attr "amdfam10_decode" "vector,double,double")
4912 (set_attr "bdver1_decode" "double,direct,double")
4913 (set_attr "fp_int_src" "true")])
4915 (define_insn "*floatsi<mode>2_vector_sse"
4916 [(set (match_operand:MODEF 0 "register_operand" "=x")
4917 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4918 "TARGET_SSE2 && TARGET_SSE_MATH
4919 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4921 [(set_attr "type" "sseicvt")
4922 (set_attr "mode" "<MODE>")
4923 (set_attr "athlon_decode" "direct")
4924 (set_attr "amdfam10_decode" "double")
4925 (set_attr "bdver1_decode" "direct")
4926 (set_attr "fp_int_src" "true")])
4929 [(set (match_operand:MODEF 0 "register_operand" "")
4930 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4931 (clobber (match_operand:SI 2 "memory_operand" ""))]
4932 "TARGET_SSE2 && TARGET_SSE_MATH
4933 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4935 && (SSE_REG_P (operands[0])
4936 || (GET_CODE (operands[0]) == SUBREG
4937 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4940 rtx op1 = operands[1];
4942 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4944 if (GET_CODE (op1) == SUBREG)
4945 op1 = SUBREG_REG (op1);
4947 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4949 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4950 emit_insn (gen_sse2_loadld (operands[4],
4951 CONST0_RTX (V4SImode), operands[1]));
4953 /* We can ignore possible trapping value in the
4954 high part of SSE register for non-trapping math. */
4955 else if (SSE_REG_P (op1) && !flag_trapping_math)
4956 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4959 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4960 emit_move_insn (operands[2], operands[1]);
4961 emit_insn (gen_sse2_loadld (operands[4],
4962 CONST0_RTX (V4SImode), operands[2]));
4964 if (<ssevecmode>mode == V4SFmode)
4965 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4967 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4972 [(set (match_operand:MODEF 0 "register_operand" "")
4973 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4974 (clobber (match_operand:SI 2 "memory_operand" ""))]
4975 "TARGET_SSE2 && TARGET_SSE_MATH
4976 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4978 && (SSE_REG_P (operands[0])
4979 || (GET_CODE (operands[0]) == SUBREG
4980 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4983 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4985 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4987 emit_insn (gen_sse2_loadld (operands[4],
4988 CONST0_RTX (V4SImode), operands[1]));
4989 if (<ssevecmode>mode == V4SFmode)
4990 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4992 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4997 [(set (match_operand:MODEF 0 "register_operand" "")
4998 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
4999 "TARGET_SSE2 && TARGET_SSE_MATH
5000 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5002 && (SSE_REG_P (operands[0])
5003 || (GET_CODE (operands[0]) == SUBREG
5004 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5007 rtx op1 = operands[1];
5009 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5011 if (GET_CODE (op1) == SUBREG)
5012 op1 = SUBREG_REG (op1);
5014 if (GENERAL_REG_P (op1))
5016 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5017 if (TARGET_INTER_UNIT_MOVES)
5018 emit_insn (gen_sse2_loadld (operands[4],
5019 CONST0_RTX (V4SImode), operands[1]));
5022 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5024 emit_insn (gen_sse2_loadld (operands[4],
5025 CONST0_RTX (V4SImode), operands[5]));
5026 ix86_free_from_memory (GET_MODE (operands[1]));
5029 /* We can ignore possible trapping value in the
5030 high part of SSE register for non-trapping math. */
5031 else if (SSE_REG_P (op1) && !flag_trapping_math)
5032 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5035 if (<ssevecmode>mode == V4SFmode)
5036 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5038 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5043 [(set (match_operand:MODEF 0 "register_operand" "")
5044 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5045 "TARGET_SSE2 && TARGET_SSE_MATH
5046 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5048 && (SSE_REG_P (operands[0])
5049 || (GET_CODE (operands[0]) == SUBREG
5050 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5053 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5055 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5057 emit_insn (gen_sse2_loadld (operands[4],
5058 CONST0_RTX (V4SImode), operands[1]));
5059 if (<ssevecmode>mode == V4SFmode)
5060 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5062 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5066 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5067 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5069 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5070 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5071 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5072 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5074 [(set_attr "type" "sseicvt")
5075 (set_attr "mode" "<MODEF:MODE>")
5076 (set_attr "athlon_decode" "double,direct")
5077 (set_attr "amdfam10_decode" "vector,double")
5078 (set_attr "bdver1_decode" "double,direct")
5079 (set_attr "fp_int_src" "true")])
5081 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5082 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5084 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5085 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5086 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5087 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5088 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5089 [(set_attr "type" "sseicvt")
5090 (set_attr "prefix" "maybe_vex")
5091 (set_attr "mode" "<MODEF:MODE>")
5092 (set (attr "prefix_rex")
5094 (and (eq_attr "prefix" "maybe_vex")
5095 (match_test "<SWI48x:MODE>mode == DImode"))
5097 (const_string "*")))
5098 (set_attr "athlon_decode" "double,direct")
5099 (set_attr "amdfam10_decode" "vector,double")
5100 (set_attr "bdver1_decode" "double,direct")
5101 (set_attr "fp_int_src" "true")])
5104 [(set (match_operand:MODEF 0 "register_operand" "")
5105 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5106 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5107 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5108 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5109 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5111 && (SSE_REG_P (operands[0])
5112 || (GET_CODE (operands[0]) == SUBREG
5113 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5114 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5116 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5117 [(set (match_operand:MODEF 0 "register_operand" "=x")
5119 (match_operand:SWI48x 1 "memory_operand" "m")))]
5120 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5121 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5122 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5123 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5124 [(set_attr "type" "sseicvt")
5125 (set_attr "prefix" "maybe_vex")
5126 (set_attr "mode" "<MODEF:MODE>")
5127 (set (attr "prefix_rex")
5129 (and (eq_attr "prefix" "maybe_vex")
5130 (match_test "<SWI48x:MODE>mode == DImode"))
5132 (const_string "*")))
5133 (set_attr "athlon_decode" "direct")
5134 (set_attr "amdfam10_decode" "double")
5135 (set_attr "bdver1_decode" "direct")
5136 (set_attr "fp_int_src" "true")])
5139 [(set (match_operand:MODEF 0 "register_operand" "")
5140 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5141 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5142 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5143 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5144 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5146 && (SSE_REG_P (operands[0])
5147 || (GET_CODE (operands[0]) == SUBREG
5148 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5149 [(set (match_dup 2) (match_dup 1))
5150 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5153 [(set (match_operand:MODEF 0 "register_operand" "")
5154 (float:MODEF (match_operand:SWI48x 1 "memory_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
5159 && (SSE_REG_P (operands[0])
5160 || (GET_CODE (operands[0]) == SUBREG
5161 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5162 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5164 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5165 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5167 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5168 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5170 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5174 [(set_attr "type" "fmov,multi")
5175 (set_attr "mode" "<X87MODEF:MODE>")
5176 (set_attr "unit" "*,i387")
5177 (set_attr "fp_int_src" "true")])
5179 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5180 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5182 (match_operand:SWI48x 1 "memory_operand" "m")))]
5184 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5186 [(set_attr "type" "fmov")
5187 (set_attr "mode" "<X87MODEF:MODE>")
5188 (set_attr "fp_int_src" "true")])
5191 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5192 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5193 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5195 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5196 && reload_completed"
5197 [(set (match_dup 2) (match_dup 1))
5198 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5201 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5202 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5203 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5205 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5206 && reload_completed"
5207 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5209 ;; Avoid store forwarding (partial memory) stall penalty
5210 ;; by passing DImode value through XMM registers. */
5212 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5213 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5215 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5216 (clobber (match_scratch:V4SI 3 "=X,x"))
5217 (clobber (match_scratch:V4SI 4 "=X,x"))
5218 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5219 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5220 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5221 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5223 [(set_attr "type" "multi")
5224 (set_attr "mode" "<X87MODEF:MODE>")
5225 (set_attr "unit" "i387")
5226 (set_attr "fp_int_src" "true")])
5229 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5230 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5231 (clobber (match_scratch:V4SI 3 ""))
5232 (clobber (match_scratch:V4SI 4 ""))
5233 (clobber (match_operand:DI 2 "memory_operand" ""))]
5234 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5235 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5236 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5237 && reload_completed"
5238 [(set (match_dup 2) (match_dup 3))
5239 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5241 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5242 Assemble the 64-bit DImode value in an xmm register. */
5243 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5244 gen_rtx_SUBREG (SImode, operands[1], 0)));
5245 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5246 gen_rtx_SUBREG (SImode, operands[1], 4)));
5247 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5250 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5254 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5255 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5256 (clobber (match_scratch:V4SI 3 ""))
5257 (clobber (match_scratch:V4SI 4 ""))
5258 (clobber (match_operand:DI 2 "memory_operand" ""))]
5259 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5260 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5261 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5262 && reload_completed"
5263 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5265 ;; Avoid store forwarding (partial memory) stall penalty by extending
5266 ;; SImode value to DImode through XMM register instead of pushing two
5267 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5268 ;; targets benefit from this optimization. Also note that fild
5269 ;; loads from memory only.
5271 (define_insn "*floatunssi<mode>2_1"
5272 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5273 (unsigned_float:X87MODEF
5274 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5275 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5276 (clobber (match_scratch:SI 3 "=X,x"))]
5278 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5281 [(set_attr "type" "multi")
5282 (set_attr "mode" "<MODE>")])
5285 [(set (match_operand:X87MODEF 0 "register_operand" "")
5286 (unsigned_float:X87MODEF
5287 (match_operand:SI 1 "register_operand" "")))
5288 (clobber (match_operand:DI 2 "memory_operand" ""))
5289 (clobber (match_scratch:SI 3 ""))]
5291 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5293 && reload_completed"
5294 [(set (match_dup 2) (match_dup 1))
5296 (float:X87MODEF (match_dup 2)))]
5297 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5300 [(set (match_operand:X87MODEF 0 "register_operand" "")
5301 (unsigned_float:X87MODEF
5302 (match_operand:SI 1 "memory_operand" "")))
5303 (clobber (match_operand:DI 2 "memory_operand" ""))
5304 (clobber (match_scratch:SI 3 ""))]
5306 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5308 && reload_completed"
5309 [(set (match_dup 2) (match_dup 3))
5311 (float:X87MODEF (match_dup 2)))]
5313 emit_move_insn (operands[3], operands[1]);
5314 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5317 (define_expand "floatunssi<mode>2"
5319 [(set (match_operand:X87MODEF 0 "register_operand" "")
5320 (unsigned_float:X87MODEF
5321 (match_operand:SI 1 "nonimmediate_operand" "")))
5322 (clobber (match_dup 2))
5323 (clobber (match_scratch:SI 3 ""))])]
5325 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5327 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5329 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5331 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5336 enum ix86_stack_slot slot = (virtuals_instantiated
5339 operands[2] = assign_386_stack_local (DImode, slot);
5343 (define_expand "floatunsdisf2"
5344 [(use (match_operand:SF 0 "register_operand" ""))
5345 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5346 "TARGET_64BIT && TARGET_SSE_MATH"
5347 "x86_emit_floatuns (operands); DONE;")
5349 (define_expand "floatunsdidf2"
5350 [(use (match_operand:DF 0 "register_operand" ""))
5351 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5352 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5353 && TARGET_SSE2 && TARGET_SSE_MATH"
5356 x86_emit_floatuns (operands);
5358 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5364 (define_expand "add<mode>3"
5365 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5366 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5367 (match_operand:SDWIM 2 "<general_operand>" "")))]
5369 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5371 (define_insn_and_split "*add<dwi>3_doubleword"
5372 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5374 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5375 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5376 (clobber (reg:CC FLAGS_REG))]
5377 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5380 [(parallel [(set (reg:CC FLAGS_REG)
5381 (unspec:CC [(match_dup 1) (match_dup 2)]
5384 (plus:DWIH (match_dup 1) (match_dup 2)))])
5385 (parallel [(set (match_dup 3)
5389 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5391 (clobber (reg:CC FLAGS_REG))])]
5392 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5394 (define_insn "*add<mode>3_cc"
5395 [(set (reg:CC FLAGS_REG)
5397 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5398 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5400 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5401 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5402 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5403 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5404 [(set_attr "type" "alu")
5405 (set_attr "mode" "<MODE>")])
5407 (define_insn "addqi3_cc"
5408 [(set (reg:CC FLAGS_REG)
5410 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5411 (match_operand:QI 2 "general_operand" "qn,qm")]
5413 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5414 (plus:QI (match_dup 1) (match_dup 2)))]
5415 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5416 "add{b}\t{%2, %0|%0, %2}"
5417 [(set_attr "type" "alu")
5418 (set_attr "mode" "QI")])
5420 (define_insn_and_split "*lea_1"
5421 [(set (match_operand:SI 0 "register_operand" "=r")
5422 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5424 "lea{l}\t{%a1, %0|%0, %a1}"
5425 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5428 ix86_split_lea_for_addr (operands, SImode);
5431 [(set_attr "type" "lea")
5432 (set_attr "mode" "SI")])
5434 (define_insn_and_split "*lea<mode>_2"
5435 [(set (match_operand:SWI48 0 "register_operand" "=r")
5436 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5438 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5439 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5442 ix86_split_lea_for_addr (operands, <MODE>mode);
5445 [(set_attr "type" "lea")
5446 (set_attr "mode" "<MODE>")])
5448 (define_insn "*lea_3_zext"
5449 [(set (match_operand:DI 0 "register_operand" "=r")
5451 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5453 "lea{l}\t{%a1, %k0|%k0, %a1}"
5454 [(set_attr "type" "lea")
5455 (set_attr "mode" "SI")])
5457 (define_insn "*lea_4_zext"
5458 [(set (match_operand:DI 0 "register_operand" "=r")
5460 (match_operand:SI 1 "lea_address_operand" "j")))]
5462 "lea{l}\t{%a1, %k0|%k0, %a1}"
5463 [(set_attr "type" "lea")
5464 (set_attr "mode" "SI")])
5466 (define_insn "*lea_5_zext"
5467 [(set (match_operand:DI 0 "register_operand" "=r")
5469 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5470 (match_operand:DI 2 "const_32bit_mask" "n")))]
5472 "lea{l}\t{%a1, %k0|%k0, %a1}"
5473 [(set_attr "type" "lea")
5474 (set_attr "mode" "SI")])
5476 (define_insn "*lea_6_zext"
5477 [(set (match_operand:DI 0 "register_operand" "=r")
5479 (match_operand:DI 1 "lea_address_operand" "p")
5480 (match_operand:DI 2 "const_32bit_mask" "n")))]
5482 "lea{l}\t{%a1, %k0|%k0, %a1}"
5483 [(set_attr "type" "lea")
5484 (set_attr "mode" "SI")])
5486 (define_insn "*add<mode>_1"
5487 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5489 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5490 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5491 (clobber (reg:CC FLAGS_REG))]
5492 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5494 switch (get_attr_type (insn))
5500 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5501 if (operands[2] == const1_rtx)
5502 return "inc{<imodesuffix>}\t%0";
5505 gcc_assert (operands[2] == constm1_rtx);
5506 return "dec{<imodesuffix>}\t%0";
5510 /* For most processors, ADD is faster than LEA. This alternative
5511 was added to use ADD as much as possible. */
5512 if (which_alternative == 2)
5515 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5518 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5519 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5520 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5522 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5526 (cond [(eq_attr "alternative" "3")
5527 (const_string "lea")
5528 (match_operand:SWI48 2 "incdec_operand" "")
5529 (const_string "incdec")
5531 (const_string "alu")))
5532 (set (attr "length_immediate")
5534 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5536 (const_string "*")))
5537 (set_attr "mode" "<MODE>")])
5539 ;; It may seem that nonimmediate operand is proper one for operand 1.
5540 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5541 ;; we take care in ix86_binary_operator_ok to not allow two memory
5542 ;; operands so proper swapping will be done in reload. This allow
5543 ;; patterns constructed from addsi_1 to match.
5545 (define_insn "addsi_1_zext"
5546 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5548 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5549 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5550 (clobber (reg:CC FLAGS_REG))]
5551 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5553 switch (get_attr_type (insn))
5559 if (operands[2] == const1_rtx)
5560 return "inc{l}\t%k0";
5563 gcc_assert (operands[2] == constm1_rtx);
5564 return "dec{l}\t%k0";
5568 /* For most processors, ADD is faster than LEA. This alternative
5569 was added to use ADD as much as possible. */
5570 if (which_alternative == 1)
5573 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5576 if (x86_maybe_negate_const_int (&operands[2], SImode))
5577 return "sub{l}\t{%2, %k0|%k0, %2}";
5579 return "add{l}\t{%2, %k0|%k0, %2}";
5583 (cond [(eq_attr "alternative" "2")
5584 (const_string "lea")
5585 (match_operand:SI 2 "incdec_operand" "")
5586 (const_string "incdec")
5588 (const_string "alu")))
5589 (set (attr "length_immediate")
5591 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5593 (const_string "*")))
5594 (set_attr "mode" "SI")])
5596 (define_insn "*addhi_1"
5597 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5598 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5599 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5600 (clobber (reg:CC FLAGS_REG))]
5601 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5603 switch (get_attr_type (insn))
5609 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5610 if (operands[2] == const1_rtx)
5611 return "inc{w}\t%0";
5614 gcc_assert (operands[2] == constm1_rtx);
5615 return "dec{w}\t%0";
5619 /* For most processors, ADD is faster than LEA. This alternative
5620 was added to use ADD as much as possible. */
5621 if (which_alternative == 2)
5624 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5627 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5628 if (x86_maybe_negate_const_int (&operands[2], HImode))
5629 return "sub{w}\t{%2, %0|%0, %2}";
5631 return "add{w}\t{%2, %0|%0, %2}";
5635 (cond [(eq_attr "alternative" "3")
5636 (const_string "lea")
5637 (match_operand:HI 2 "incdec_operand" "")
5638 (const_string "incdec")
5640 (const_string "alu")))
5641 (set (attr "length_immediate")
5643 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5645 (const_string "*")))
5646 (set_attr "mode" "HI,HI,HI,SI")])
5648 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5649 (define_insn "*addqi_1"
5650 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5651 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5652 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5653 (clobber (reg:CC FLAGS_REG))]
5654 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5656 bool widen = (which_alternative == 3 || which_alternative == 4);
5658 switch (get_attr_type (insn))
5664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5665 if (operands[2] == const1_rtx)
5666 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5669 gcc_assert (operands[2] == constm1_rtx);
5670 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5674 /* For most processors, ADD is faster than LEA. These alternatives
5675 were added to use ADD as much as possible. */
5676 if (which_alternative == 2 || which_alternative == 4)
5679 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5682 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5683 if (x86_maybe_negate_const_int (&operands[2], QImode))
5686 return "sub{l}\t{%2, %k0|%k0, %2}";
5688 return "sub{b}\t{%2, %0|%0, %2}";
5691 return "add{l}\t{%k2, %k0|%k0, %k2}";
5693 return "add{b}\t{%2, %0|%0, %2}";
5697 (cond [(eq_attr "alternative" "5")
5698 (const_string "lea")
5699 (match_operand:QI 2 "incdec_operand" "")
5700 (const_string "incdec")
5702 (const_string "alu")))
5703 (set (attr "length_immediate")
5705 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5707 (const_string "*")))
5708 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5710 (define_insn "*addqi_1_slp"
5711 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5712 (plus:QI (match_dup 0)
5713 (match_operand:QI 1 "general_operand" "qn,qm")))
5714 (clobber (reg:CC FLAGS_REG))]
5715 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5716 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5718 switch (get_attr_type (insn))
5721 if (operands[1] == const1_rtx)
5722 return "inc{b}\t%0";
5725 gcc_assert (operands[1] == constm1_rtx);
5726 return "dec{b}\t%0";
5730 if (x86_maybe_negate_const_int (&operands[1], QImode))
5731 return "sub{b}\t{%1, %0|%0, %1}";
5733 return "add{b}\t{%1, %0|%0, %1}";
5737 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5738 (const_string "incdec")
5739 (const_string "alu1")))
5740 (set (attr "memory")
5741 (if_then_else (match_operand 1 "memory_operand" "")
5742 (const_string "load")
5743 (const_string "none")))
5744 (set_attr "mode" "QI")])
5746 ;; Split non destructive adds if we cannot use lea.
5748 [(set (match_operand:SWI48 0 "register_operand" "")
5749 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5750 (match_operand:SWI48 2 "nonmemory_operand" "")))
5751 (clobber (reg:CC FLAGS_REG))]
5752 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5753 [(set (match_dup 0) (match_dup 1))
5754 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5755 (clobber (reg:CC FLAGS_REG))])])
5757 ;; Convert add to the lea pattern to avoid flags dependency.
5759 [(set (match_operand:SWI 0 "register_operand" "")
5760 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5761 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5762 (clobber (reg:CC FLAGS_REG))]
5763 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5766 enum machine_mode mode = <MODE>mode;
5769 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5772 operands[0] = gen_lowpart (mode, operands[0]);
5773 operands[1] = gen_lowpart (mode, operands[1]);
5774 operands[2] = gen_lowpart (mode, operands[2]);
5777 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5779 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5783 ;; Convert add to the lea pattern to avoid flags dependency.
5785 [(set (match_operand:DI 0 "register_operand" "")
5787 (plus:SI (match_operand:SI 1 "register_operand" "")
5788 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5789 (clobber (reg:CC FLAGS_REG))]
5790 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5792 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5794 (define_insn "*add<mode>_2"
5795 [(set (reg FLAGS_REG)
5798 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5799 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5801 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5802 (plus:SWI (match_dup 1) (match_dup 2)))]
5803 "ix86_match_ccmode (insn, CCGOCmode)
5804 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5806 switch (get_attr_type (insn))
5809 if (operands[2] == const1_rtx)
5810 return "inc{<imodesuffix>}\t%0";
5813 gcc_assert (operands[2] == constm1_rtx);
5814 return "dec{<imodesuffix>}\t%0";
5818 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5819 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5821 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5825 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5826 (const_string "incdec")
5827 (const_string "alu")))
5828 (set (attr "length_immediate")
5830 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5832 (const_string "*")))
5833 (set_attr "mode" "<MODE>")])
5835 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5836 (define_insn "*addsi_2_zext"
5837 [(set (reg FLAGS_REG)
5839 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5840 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5842 (set (match_operand:DI 0 "register_operand" "=r")
5843 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5844 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5845 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5847 switch (get_attr_type (insn))
5850 if (operands[2] == const1_rtx)
5851 return "inc{l}\t%k0";
5854 gcc_assert (operands[2] == constm1_rtx);
5855 return "dec{l}\t%k0";
5859 if (x86_maybe_negate_const_int (&operands[2], SImode))
5860 return "sub{l}\t{%2, %k0|%k0, %2}";
5862 return "add{l}\t{%2, %k0|%k0, %2}";
5866 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5867 (const_string "incdec")
5868 (const_string "alu")))
5869 (set (attr "length_immediate")
5871 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5873 (const_string "*")))
5874 (set_attr "mode" "SI")])
5876 (define_insn "*add<mode>_3"
5877 [(set (reg FLAGS_REG)
5879 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5880 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5881 (clobber (match_scratch:SWI 0 "=<r>"))]
5882 "ix86_match_ccmode (insn, CCZmode)
5883 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5885 switch (get_attr_type (insn))
5888 if (operands[2] == const1_rtx)
5889 return "inc{<imodesuffix>}\t%0";
5892 gcc_assert (operands[2] == constm1_rtx);
5893 return "dec{<imodesuffix>}\t%0";
5897 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5898 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5900 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5904 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5905 (const_string "incdec")
5906 (const_string "alu")))
5907 (set (attr "length_immediate")
5909 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5911 (const_string "*")))
5912 (set_attr "mode" "<MODE>")])
5914 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5915 (define_insn "*addsi_3_zext"
5916 [(set (reg FLAGS_REG)
5918 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5919 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5920 (set (match_operand:DI 0 "register_operand" "=r")
5921 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5922 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5923 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5925 switch (get_attr_type (insn))
5928 if (operands[2] == const1_rtx)
5929 return "inc{l}\t%k0";
5932 gcc_assert (operands[2] == constm1_rtx);
5933 return "dec{l}\t%k0";
5937 if (x86_maybe_negate_const_int (&operands[2], SImode))
5938 return "sub{l}\t{%2, %k0|%k0, %2}";
5940 return "add{l}\t{%2, %k0|%k0, %2}";
5944 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5945 (const_string "incdec")
5946 (const_string "alu")))
5947 (set (attr "length_immediate")
5949 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5951 (const_string "*")))
5952 (set_attr "mode" "SI")])
5954 ; For comparisons against 1, -1 and 128, we may generate better code
5955 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5956 ; is matched then. We can't accept general immediate, because for
5957 ; case of overflows, the result is messed up.
5958 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5959 ; only for comparisons not depending on it.
5961 (define_insn "*adddi_4"
5962 [(set (reg FLAGS_REG)
5964 (match_operand:DI 1 "nonimmediate_operand" "0")
5965 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5966 (clobber (match_scratch:DI 0 "=rm"))]
5968 && ix86_match_ccmode (insn, CCGCmode)"
5970 switch (get_attr_type (insn))
5973 if (operands[2] == constm1_rtx)
5974 return "inc{q}\t%0";
5977 gcc_assert (operands[2] == const1_rtx);
5978 return "dec{q}\t%0";
5982 if (x86_maybe_negate_const_int (&operands[2], DImode))
5983 return "add{q}\t{%2, %0|%0, %2}";
5985 return "sub{q}\t{%2, %0|%0, %2}";
5989 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5990 (const_string "incdec")
5991 (const_string "alu")))
5992 (set (attr "length_immediate")
5994 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5996 (const_string "*")))
5997 (set_attr "mode" "DI")])
5999 ; For comparisons against 1, -1 and 128, we may generate better code
6000 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6001 ; is matched then. We can't accept general immediate, because for
6002 ; case of overflows, the result is messed up.
6003 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6004 ; only for comparisons not depending on it.
6006 (define_insn "*add<mode>_4"
6007 [(set (reg FLAGS_REG)
6009 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6010 (match_operand:SWI124 2 "const_int_operand" "n")))
6011 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6012 "ix86_match_ccmode (insn, CCGCmode)"
6014 switch (get_attr_type (insn))
6017 if (operands[2] == constm1_rtx)
6018 return "inc{<imodesuffix>}\t%0";
6021 gcc_assert (operands[2] == const1_rtx);
6022 return "dec{<imodesuffix>}\t%0";
6026 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6027 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6029 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6033 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6034 (const_string "incdec")
6035 (const_string "alu")))
6036 (set (attr "length_immediate")
6038 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6040 (const_string "*")))
6041 (set_attr "mode" "<MODE>")])
6043 (define_insn "*add<mode>_5"
6044 [(set (reg FLAGS_REG)
6047 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6048 (match_operand:SWI 2 "<general_operand>" "<g>"))
6050 (clobber (match_scratch:SWI 0 "=<r>"))]
6051 "ix86_match_ccmode (insn, CCGOCmode)
6052 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6054 switch (get_attr_type (insn))
6057 if (operands[2] == const1_rtx)
6058 return "inc{<imodesuffix>}\t%0";
6061 gcc_assert (operands[2] == constm1_rtx);
6062 return "dec{<imodesuffix>}\t%0";
6066 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6067 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6069 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6073 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6074 (const_string "incdec")
6075 (const_string "alu")))
6076 (set (attr "length_immediate")
6078 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6080 (const_string "*")))
6081 (set_attr "mode" "<MODE>")])
6083 (define_insn "*addqi_ext_1_rex64"
6084 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6089 (match_operand 1 "ext_register_operand" "0")
6092 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6093 (clobber (reg:CC FLAGS_REG))]
6096 switch (get_attr_type (insn))
6099 if (operands[2] == const1_rtx)
6100 return "inc{b}\t%h0";
6103 gcc_assert (operands[2] == constm1_rtx);
6104 return "dec{b}\t%h0";
6108 return "add{b}\t{%2, %h0|%h0, %2}";
6112 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6113 (const_string "incdec")
6114 (const_string "alu")))
6115 (set_attr "modrm" "1")
6116 (set_attr "mode" "QI")])
6118 (define_insn "addqi_ext_1"
6119 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6124 (match_operand 1 "ext_register_operand" "0")
6127 (match_operand:QI 2 "general_operand" "Qmn")))
6128 (clobber (reg:CC FLAGS_REG))]
6131 switch (get_attr_type (insn))
6134 if (operands[2] == const1_rtx)
6135 return "inc{b}\t%h0";
6138 gcc_assert (operands[2] == constm1_rtx);
6139 return "dec{b}\t%h0";
6143 return "add{b}\t{%2, %h0|%h0, %2}";
6147 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6148 (const_string "incdec")
6149 (const_string "alu")))
6150 (set_attr "modrm" "1")
6151 (set_attr "mode" "QI")])
6153 (define_insn "*addqi_ext_2"
6154 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6159 (match_operand 1 "ext_register_operand" "%0")
6163 (match_operand 2 "ext_register_operand" "Q")
6166 (clobber (reg:CC FLAGS_REG))]
6168 "add{b}\t{%h2, %h0|%h0, %h2}"
6169 [(set_attr "type" "alu")
6170 (set_attr "mode" "QI")])
6172 ;; The lea patterns for modes less than 32 bits need to be matched by
6173 ;; several insns converted to real lea by splitters.
6175 (define_insn_and_split "*lea_general_1"
6176 [(set (match_operand 0 "register_operand" "=r")
6177 (plus (plus (match_operand 1 "index_register_operand" "l")
6178 (match_operand 2 "register_operand" "r"))
6179 (match_operand 3 "immediate_operand" "i")))]
6180 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6181 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6182 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6183 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6184 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6185 || GET_MODE (operands[3]) == VOIDmode)"
6187 "&& reload_completed"
6190 enum machine_mode mode = SImode;
6193 operands[0] = gen_lowpart (mode, operands[0]);
6194 operands[1] = gen_lowpart (mode, operands[1]);
6195 operands[2] = gen_lowpart (mode, operands[2]);
6196 operands[3] = gen_lowpart (mode, operands[3]);
6198 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6201 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6204 [(set_attr "type" "lea")
6205 (set_attr "mode" "SI")])
6207 (define_insn_and_split "*lea_general_2"
6208 [(set (match_operand 0 "register_operand" "=r")
6209 (plus (mult (match_operand 1 "index_register_operand" "l")
6210 (match_operand 2 "const248_operand" "n"))
6211 (match_operand 3 "nonmemory_operand" "ri")))]
6212 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6213 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6214 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6215 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6216 || GET_MODE (operands[3]) == VOIDmode)"
6218 "&& reload_completed"
6221 enum machine_mode mode = SImode;
6224 operands[0] = gen_lowpart (mode, operands[0]);
6225 operands[1] = gen_lowpart (mode, operands[1]);
6226 operands[3] = gen_lowpart (mode, operands[3]);
6228 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6231 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6234 [(set_attr "type" "lea")
6235 (set_attr "mode" "SI")])
6237 (define_insn_and_split "*lea_general_3"
6238 [(set (match_operand 0 "register_operand" "=r")
6239 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6240 (match_operand 2 "const248_operand" "n"))
6241 (match_operand 3 "register_operand" "r"))
6242 (match_operand 4 "immediate_operand" "i")))]
6243 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6244 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6245 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6246 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6248 "&& reload_completed"
6251 enum machine_mode mode = SImode;
6254 operands[0] = gen_lowpart (mode, operands[0]);
6255 operands[1] = gen_lowpart (mode, operands[1]);
6256 operands[3] = gen_lowpart (mode, operands[3]);
6257 operands[4] = gen_lowpart (mode, operands[4]);
6259 pat = gen_rtx_PLUS (mode,
6261 gen_rtx_MULT (mode, operands[1],
6266 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6269 [(set_attr "type" "lea")
6270 (set_attr "mode" "SI")])
6272 (define_insn_and_split "*lea_general_4"
6273 [(set (match_operand 0 "register_operand" "=r")
6275 (match_operand 1 "index_register_operand" "l")
6276 (match_operand 2 "const_int_operand" "n"))
6277 (match_operand 3 "const_int_operand" "n")))]
6278 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6279 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6280 || GET_MODE (operands[0]) == SImode
6281 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6282 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6283 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6284 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6285 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6287 "&& reload_completed"
6290 enum machine_mode mode = GET_MODE (operands[0]);
6293 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6296 operands[0] = gen_lowpart (mode, operands[0]);
6297 operands[1] = gen_lowpart (mode, operands[1]);
6300 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6302 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6303 INTVAL (operands[3]));
6305 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6308 [(set_attr "type" "lea")
6310 (if_then_else (match_operand:DI 0 "" "")
6312 (const_string "SI")))])
6314 ;; Subtract instructions
6316 (define_expand "sub<mode>3"
6317 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6318 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6319 (match_operand:SDWIM 2 "<general_operand>" "")))]
6321 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6323 (define_insn_and_split "*sub<dwi>3_doubleword"
6324 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6326 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6327 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6328 (clobber (reg:CC FLAGS_REG))]
6329 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6332 [(parallel [(set (reg:CC FLAGS_REG)
6333 (compare:CC (match_dup 1) (match_dup 2)))
6335 (minus:DWIH (match_dup 1) (match_dup 2)))])
6336 (parallel [(set (match_dup 3)
6340 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6342 (clobber (reg:CC FLAGS_REG))])]
6343 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6345 (define_insn "*sub<mode>_1"
6346 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6348 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6349 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6350 (clobber (reg:CC FLAGS_REG))]
6351 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6352 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6353 [(set_attr "type" "alu")
6354 (set_attr "mode" "<MODE>")])
6356 (define_insn "*subsi_1_zext"
6357 [(set (match_operand:DI 0 "register_operand" "=r")
6359 (minus:SI (match_operand:SI 1 "register_operand" "0")
6360 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6361 (clobber (reg:CC FLAGS_REG))]
6362 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6363 "sub{l}\t{%2, %k0|%k0, %2}"
6364 [(set_attr "type" "alu")
6365 (set_attr "mode" "SI")])
6367 (define_insn "*subqi_1_slp"
6368 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6369 (minus:QI (match_dup 0)
6370 (match_operand:QI 1 "general_operand" "qn,qm")))
6371 (clobber (reg:CC FLAGS_REG))]
6372 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6373 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6374 "sub{b}\t{%1, %0|%0, %1}"
6375 [(set_attr "type" "alu1")
6376 (set_attr "mode" "QI")])
6378 (define_insn "*sub<mode>_2"
6379 [(set (reg FLAGS_REG)
6382 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6383 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6385 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6386 (minus:SWI (match_dup 1) (match_dup 2)))]
6387 "ix86_match_ccmode (insn, CCGOCmode)
6388 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6389 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6390 [(set_attr "type" "alu")
6391 (set_attr "mode" "<MODE>")])
6393 (define_insn "*subsi_2_zext"
6394 [(set (reg FLAGS_REG)
6396 (minus:SI (match_operand:SI 1 "register_operand" "0")
6397 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6399 (set (match_operand:DI 0 "register_operand" "=r")
6401 (minus:SI (match_dup 1)
6403 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6404 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6405 "sub{l}\t{%2, %k0|%k0, %2}"
6406 [(set_attr "type" "alu")
6407 (set_attr "mode" "SI")])
6409 (define_insn "*sub<mode>_3"
6410 [(set (reg FLAGS_REG)
6411 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6412 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6413 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6414 (minus:SWI (match_dup 1) (match_dup 2)))]
6415 "ix86_match_ccmode (insn, CCmode)
6416 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6417 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6418 [(set_attr "type" "alu")
6419 (set_attr "mode" "<MODE>")])
6421 (define_insn "*subsi_3_zext"
6422 [(set (reg FLAGS_REG)
6423 (compare (match_operand:SI 1 "register_operand" "0")
6424 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6425 (set (match_operand:DI 0 "register_operand" "=r")
6427 (minus:SI (match_dup 1)
6429 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6430 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6431 "sub{l}\t{%2, %1|%1, %2}"
6432 [(set_attr "type" "alu")
6433 (set_attr "mode" "SI")])
6435 ;; Add with carry and subtract with borrow
6437 (define_expand "<plusminus_insn><mode>3_carry"
6439 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6441 (match_operand:SWI 1 "nonimmediate_operand" "")
6442 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6443 [(match_operand 3 "flags_reg_operand" "")
6445 (match_operand:SWI 2 "<general_operand>" ""))))
6446 (clobber (reg:CC FLAGS_REG))])]
6447 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6449 (define_insn "*<plusminus_insn><mode>3_carry"
6450 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6452 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6454 (match_operator 3 "ix86_carry_flag_operator"
6455 [(reg FLAGS_REG) (const_int 0)])
6456 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6457 (clobber (reg:CC FLAGS_REG))]
6458 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6459 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6460 [(set_attr "type" "alu")
6461 (set_attr "use_carry" "1")
6462 (set_attr "pent_pair" "pu")
6463 (set_attr "mode" "<MODE>")])
6465 (define_insn "*addsi3_carry_zext"
6466 [(set (match_operand:DI 0 "register_operand" "=r")
6468 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6469 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6470 [(reg FLAGS_REG) (const_int 0)])
6471 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6472 (clobber (reg:CC FLAGS_REG))]
6473 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6474 "adc{l}\t{%2, %k0|%k0, %2}"
6475 [(set_attr "type" "alu")
6476 (set_attr "use_carry" "1")
6477 (set_attr "pent_pair" "pu")
6478 (set_attr "mode" "SI")])
6480 (define_insn "*subsi3_carry_zext"
6481 [(set (match_operand:DI 0 "register_operand" "=r")
6483 (minus:SI (match_operand:SI 1 "register_operand" "0")
6484 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6485 [(reg FLAGS_REG) (const_int 0)])
6486 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6487 (clobber (reg:CC FLAGS_REG))]
6488 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6489 "sbb{l}\t{%2, %k0|%k0, %2}"
6490 [(set_attr "type" "alu")
6491 (set_attr "pent_pair" "pu")
6492 (set_attr "mode" "SI")])
6494 ;; Overflow setting add and subtract instructions
6496 (define_insn "*add<mode>3_cconly_overflow"
6497 [(set (reg:CCC FLAGS_REG)
6500 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6501 (match_operand:SWI 2 "<general_operand>" "<g>"))
6503 (clobber (match_scratch:SWI 0 "=<r>"))]
6504 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6505 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6506 [(set_attr "type" "alu")
6507 (set_attr "mode" "<MODE>")])
6509 (define_insn "*sub<mode>3_cconly_overflow"
6510 [(set (reg:CCC FLAGS_REG)
6513 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6514 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6517 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6518 [(set_attr "type" "icmp")
6519 (set_attr "mode" "<MODE>")])
6521 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6522 [(set (reg:CCC FLAGS_REG)
6525 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6526 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6528 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6529 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6530 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6531 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6532 [(set_attr "type" "alu")
6533 (set_attr "mode" "<MODE>")])
6535 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6536 [(set (reg:CCC FLAGS_REG)
6539 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6540 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6542 (set (match_operand:DI 0 "register_operand" "=r")
6543 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6544 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6545 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6546 [(set_attr "type" "alu")
6547 (set_attr "mode" "SI")])
6549 ;; The patterns that match these are at the end of this file.
6551 (define_expand "<plusminus_insn>xf3"
6552 [(set (match_operand:XF 0 "register_operand" "")
6554 (match_operand:XF 1 "register_operand" "")
6555 (match_operand:XF 2 "register_operand" "")))]
6558 (define_expand "<plusminus_insn><mode>3"
6559 [(set (match_operand:MODEF 0 "register_operand" "")
6561 (match_operand:MODEF 1 "register_operand" "")
6562 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6563 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6564 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6566 ;; Multiply instructions
6568 (define_expand "mul<mode>3"
6569 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6571 (match_operand:SWIM248 1 "register_operand" "")
6572 (match_operand:SWIM248 2 "<general_operand>" "")))
6573 (clobber (reg:CC FLAGS_REG))])])
6575 (define_expand "mulqi3"
6576 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6578 (match_operand:QI 1 "register_operand" "")
6579 (match_operand:QI 2 "nonimmediate_operand" "")))
6580 (clobber (reg:CC FLAGS_REG))])]
6581 "TARGET_QIMODE_MATH")
6584 ;; IMUL reg32/64, reg32/64, imm8 Direct
6585 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6586 ;; IMUL reg32/64, reg32/64, imm32 Direct
6587 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6588 ;; IMUL reg32/64, reg32/64 Direct
6589 ;; IMUL reg32/64, mem32/64 Direct
6591 ;; On BDVER1, all above IMULs use DirectPath
6593 (define_insn "*mul<mode>3_1"
6594 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6596 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6597 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6598 (clobber (reg:CC FLAGS_REG))]
6599 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6601 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6602 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6603 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6604 [(set_attr "type" "imul")
6605 (set_attr "prefix_0f" "0,0,1")
6606 (set (attr "athlon_decode")
6607 (cond [(eq_attr "cpu" "athlon")
6608 (const_string "vector")
6609 (eq_attr "alternative" "1")
6610 (const_string "vector")
6611 (and (eq_attr "alternative" "2")
6612 (match_operand 1 "memory_operand" ""))
6613 (const_string "vector")]
6614 (const_string "direct")))
6615 (set (attr "amdfam10_decode")
6616 (cond [(and (eq_attr "alternative" "0,1")
6617 (match_operand 1 "memory_operand" ""))
6618 (const_string "vector")]
6619 (const_string "direct")))
6620 (set_attr "bdver1_decode" "direct")
6621 (set_attr "mode" "<MODE>")])
6623 (define_insn "*mulsi3_1_zext"
6624 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6626 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6627 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6628 (clobber (reg:CC FLAGS_REG))]
6630 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6632 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6633 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6634 imul{l}\t{%2, %k0|%k0, %2}"
6635 [(set_attr "type" "imul")
6636 (set_attr "prefix_0f" "0,0,1")
6637 (set (attr "athlon_decode")
6638 (cond [(eq_attr "cpu" "athlon")
6639 (const_string "vector")
6640 (eq_attr "alternative" "1")
6641 (const_string "vector")
6642 (and (eq_attr "alternative" "2")
6643 (match_operand 1 "memory_operand" ""))
6644 (const_string "vector")]
6645 (const_string "direct")))
6646 (set (attr "amdfam10_decode")
6647 (cond [(and (eq_attr "alternative" "0,1")
6648 (match_operand 1 "memory_operand" ""))
6649 (const_string "vector")]
6650 (const_string "direct")))
6651 (set_attr "bdver1_decode" "direct")
6652 (set_attr "mode" "SI")])
6655 ;; IMUL reg16, reg16, imm8 VectorPath
6656 ;; IMUL reg16, mem16, imm8 VectorPath
6657 ;; IMUL reg16, reg16, imm16 VectorPath
6658 ;; IMUL reg16, mem16, imm16 VectorPath
6659 ;; IMUL reg16, reg16 Direct
6660 ;; IMUL reg16, mem16 Direct
6662 ;; On BDVER1, all HI MULs use DoublePath
6664 (define_insn "*mulhi3_1"
6665 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6666 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6667 (match_operand:HI 2 "general_operand" "K,n,mr")))
6668 (clobber (reg:CC FLAGS_REG))]
6670 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6672 imul{w}\t{%2, %1, %0|%0, %1, %2}
6673 imul{w}\t{%2, %1, %0|%0, %1, %2}
6674 imul{w}\t{%2, %0|%0, %2}"
6675 [(set_attr "type" "imul")
6676 (set_attr "prefix_0f" "0,0,1")
6677 (set (attr "athlon_decode")
6678 (cond [(eq_attr "cpu" "athlon")
6679 (const_string "vector")
6680 (eq_attr "alternative" "1,2")
6681 (const_string "vector")]
6682 (const_string "direct")))
6683 (set (attr "amdfam10_decode")
6684 (cond [(eq_attr "alternative" "0,1")
6685 (const_string "vector")]
6686 (const_string "direct")))
6687 (set_attr "bdver1_decode" "double")
6688 (set_attr "mode" "HI")])
6690 ;;On AMDFAM10 and BDVER1
6694 (define_insn "*mulqi3_1"
6695 [(set (match_operand:QI 0 "register_operand" "=a")
6696 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6697 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6698 (clobber (reg:CC FLAGS_REG))]
6700 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6702 [(set_attr "type" "imul")
6703 (set_attr "length_immediate" "0")
6704 (set (attr "athlon_decode")
6705 (if_then_else (eq_attr "cpu" "athlon")
6706 (const_string "vector")
6707 (const_string "direct")))
6708 (set_attr "amdfam10_decode" "direct")
6709 (set_attr "bdver1_decode" "direct")
6710 (set_attr "mode" "QI")])
6712 (define_expand "<u>mul<mode><dwi>3"
6713 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6716 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6718 (match_operand:DWIH 2 "register_operand" ""))))
6719 (clobber (reg:CC FLAGS_REG))])])
6721 (define_expand "<u>mulqihi3"
6722 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6725 (match_operand:QI 1 "nonimmediate_operand" ""))
6727 (match_operand:QI 2 "register_operand" ""))))
6728 (clobber (reg:CC FLAGS_REG))])]
6729 "TARGET_QIMODE_MATH")
6731 (define_insn "*bmi2_umulditi3_1"
6732 [(set (match_operand:DI 0 "register_operand" "=r")
6734 (match_operand:DI 2 "nonimmediate_operand" "%d")
6735 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6736 (set (match_operand:DI 1 "register_operand" "=r")
6739 (mult:TI (zero_extend:TI (match_dup 2))
6740 (zero_extend:TI (match_dup 3)))
6742 "TARGET_64BIT && TARGET_BMI2
6743 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6744 "mulx\t{%3, %0, %1|%1, %0, %3}"
6745 [(set_attr "type" "imulx")
6746 (set_attr "prefix" "vex")
6747 (set_attr "mode" "DI")])
6749 (define_insn "*bmi2_umulsidi3_1"
6750 [(set (match_operand:SI 0 "register_operand" "=r")
6752 (match_operand:SI 2 "nonimmediate_operand" "%d")
6753 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6754 (set (match_operand:SI 1 "register_operand" "=r")
6757 (mult:DI (zero_extend:DI (match_dup 2))
6758 (zero_extend:DI (match_dup 3)))
6760 "!TARGET_64BIT && TARGET_BMI2
6761 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6762 "mulx\t{%3, %0, %1|%1, %0, %3}"
6763 [(set_attr "type" "imulx")
6764 (set_attr "prefix" "vex")
6765 (set_attr "mode" "SI")])
6767 (define_insn "*umul<mode><dwi>3_1"
6768 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6771 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6773 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6774 (clobber (reg:CC FLAGS_REG))]
6775 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6777 mul{<imodesuffix>}\t%2
6779 [(set_attr "isa" "*,bmi2")
6780 (set_attr "type" "imul,imulx")
6781 (set_attr "length_immediate" "0,*")
6782 (set (attr "athlon_decode")
6783 (cond [(eq_attr "alternative" "0")
6784 (if_then_else (eq_attr "cpu" "athlon")
6785 (const_string "vector")
6786 (const_string "double"))]
6787 (const_string "*")))
6788 (set_attr "amdfam10_decode" "double,*")
6789 (set_attr "bdver1_decode" "direct,*")
6790 (set_attr "prefix" "orig,vex")
6791 (set_attr "mode" "<MODE>")])
6793 ;; Convert mul to the mulx pattern to avoid flags dependency.
6795 [(set (match_operand:<DWI> 0 "register_operand" "")
6798 (match_operand:DWIH 1 "register_operand" ""))
6800 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6801 (clobber (reg:CC FLAGS_REG))]
6802 "TARGET_BMI2 && reload_completed
6803 && true_regnum (operands[1]) == DX_REG"
6804 [(parallel [(set (match_dup 3)
6805 (mult:DWIH (match_dup 1) (match_dup 2)))
6809 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6810 (zero_extend:<DWI> (match_dup 2)))
6813 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6815 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6818 (define_insn "*mul<mode><dwi>3_1"
6819 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6822 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6824 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6825 (clobber (reg:CC FLAGS_REG))]
6826 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6827 "imul{<imodesuffix>}\t%2"
6828 [(set_attr "type" "imul")
6829 (set_attr "length_immediate" "0")
6830 (set (attr "athlon_decode")
6831 (if_then_else (eq_attr "cpu" "athlon")
6832 (const_string "vector")
6833 (const_string "double")))
6834 (set_attr "amdfam10_decode" "double")
6835 (set_attr "bdver1_decode" "direct")
6836 (set_attr "mode" "<MODE>")])
6838 (define_insn "*<u>mulqihi3_1"
6839 [(set (match_operand:HI 0 "register_operand" "=a")
6842 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6844 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6845 (clobber (reg:CC FLAGS_REG))]
6847 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6848 "<sgnprefix>mul{b}\t%2"
6849 [(set_attr "type" "imul")
6850 (set_attr "length_immediate" "0")
6851 (set (attr "athlon_decode")
6852 (if_then_else (eq_attr "cpu" "athlon")
6853 (const_string "vector")
6854 (const_string "direct")))
6855 (set_attr "amdfam10_decode" "direct")
6856 (set_attr "bdver1_decode" "direct")
6857 (set_attr "mode" "QI")])
6859 (define_expand "<s>mul<mode>3_highpart"
6860 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6865 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6867 (match_operand:SWI48 2 "register_operand" "")))
6869 (clobber (match_scratch:SWI48 3 ""))
6870 (clobber (reg:CC FLAGS_REG))])]
6872 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6874 (define_insn "*<s>muldi3_highpart_1"
6875 [(set (match_operand:DI 0 "register_operand" "=d")
6880 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6882 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6884 (clobber (match_scratch:DI 3 "=1"))
6885 (clobber (reg:CC FLAGS_REG))]
6887 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888 "<sgnprefix>mul{q}\t%2"
6889 [(set_attr "type" "imul")
6890 (set_attr "length_immediate" "0")
6891 (set (attr "athlon_decode")
6892 (if_then_else (eq_attr "cpu" "athlon")
6893 (const_string "vector")
6894 (const_string "double")))
6895 (set_attr "amdfam10_decode" "double")
6896 (set_attr "bdver1_decode" "direct")
6897 (set_attr "mode" "DI")])
6899 (define_insn "*<s>mulsi3_highpart_1"
6900 [(set (match_operand:SI 0 "register_operand" "=d")
6905 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6907 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6909 (clobber (match_scratch:SI 3 "=1"))
6910 (clobber (reg:CC FLAGS_REG))]
6911 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6912 "<sgnprefix>mul{l}\t%2"
6913 [(set_attr "type" "imul")
6914 (set_attr "length_immediate" "0")
6915 (set (attr "athlon_decode")
6916 (if_then_else (eq_attr "cpu" "athlon")
6917 (const_string "vector")
6918 (const_string "double")))
6919 (set_attr "amdfam10_decode" "double")
6920 (set_attr "bdver1_decode" "direct")
6921 (set_attr "mode" "SI")])
6923 (define_insn "*<s>mulsi3_highpart_zext"
6924 [(set (match_operand:DI 0 "register_operand" "=d")
6925 (zero_extend:DI (truncate:SI
6927 (mult:DI (any_extend:DI
6928 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6930 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6932 (clobber (match_scratch:SI 3 "=1"))
6933 (clobber (reg:CC FLAGS_REG))]
6935 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6936 "<sgnprefix>mul{l}\t%2"
6937 [(set_attr "type" "imul")
6938 (set_attr "length_immediate" "0")
6939 (set (attr "athlon_decode")
6940 (if_then_else (eq_attr "cpu" "athlon")
6941 (const_string "vector")
6942 (const_string "double")))
6943 (set_attr "amdfam10_decode" "double")
6944 (set_attr "bdver1_decode" "direct")
6945 (set_attr "mode" "SI")])
6947 ;; The patterns that match these are at the end of this file.
6949 (define_expand "mulxf3"
6950 [(set (match_operand:XF 0 "register_operand" "")
6951 (mult:XF (match_operand:XF 1 "register_operand" "")
6952 (match_operand:XF 2 "register_operand" "")))]
6955 (define_expand "mul<mode>3"
6956 [(set (match_operand:MODEF 0 "register_operand" "")
6957 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6958 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6959 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6960 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6962 ;; Divide instructions
6964 ;; The patterns that match these are at the end of this file.
6966 (define_expand "divxf3"
6967 [(set (match_operand:XF 0 "register_operand" "")
6968 (div:XF (match_operand:XF 1 "register_operand" "")
6969 (match_operand:XF 2 "register_operand" "")))]
6972 (define_expand "divdf3"
6973 [(set (match_operand:DF 0 "register_operand" "")
6974 (div:DF (match_operand:DF 1 "register_operand" "")
6975 (match_operand:DF 2 "nonimmediate_operand" "")))]
6976 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6977 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6979 (define_expand "divsf3"
6980 [(set (match_operand:SF 0 "register_operand" "")
6981 (div:SF (match_operand:SF 1 "register_operand" "")
6982 (match_operand:SF 2 "nonimmediate_operand" "")))]
6983 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6988 && optimize_insn_for_speed_p ()
6989 && flag_finite_math_only && !flag_trapping_math
6990 && flag_unsafe_math_optimizations)
6992 ix86_emit_swdivsf (operands[0], operands[1],
6993 operands[2], SFmode);
6998 ;; Divmod instructions.
7000 (define_expand "divmod<mode>4"
7001 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7003 (match_operand:SWIM248 1 "register_operand" "")
7004 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7005 (set (match_operand:SWIM248 3 "register_operand" "")
7006 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7007 (clobber (reg:CC FLAGS_REG))])])
7009 ;; Split with 8bit unsigned divide:
7010 ;; if (dividend an divisor are in [0-255])
7011 ;; use 8bit unsigned integer divide
7013 ;; use original integer divide
7015 [(set (match_operand:SWI48 0 "register_operand" "")
7016 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7017 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7018 (set (match_operand:SWI48 1 "register_operand" "")
7019 (mod:SWI48 (match_dup 2) (match_dup 3)))
7020 (clobber (reg:CC FLAGS_REG))]
7021 "TARGET_USE_8BIT_IDIV
7022 && TARGET_QIMODE_MATH
7023 && can_create_pseudo_p ()
7024 && !optimize_insn_for_size_p ()"
7026 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7028 (define_insn_and_split "divmod<mode>4_1"
7029 [(set (match_operand:SWI48 0 "register_operand" "=a")
7030 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7031 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7032 (set (match_operand:SWI48 1 "register_operand" "=&d")
7033 (mod:SWI48 (match_dup 2) (match_dup 3)))
7034 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7035 (clobber (reg:CC FLAGS_REG))]
7039 [(parallel [(set (match_dup 1)
7040 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7041 (clobber (reg:CC FLAGS_REG))])
7042 (parallel [(set (match_dup 0)
7043 (div:SWI48 (match_dup 2) (match_dup 3)))
7045 (mod:SWI48 (match_dup 2) (match_dup 3)))
7047 (clobber (reg:CC FLAGS_REG))])]
7049 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7051 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7052 operands[4] = operands[2];
7055 /* Avoid use of cltd in favor of a mov+shift. */
7056 emit_move_insn (operands[1], operands[2]);
7057 operands[4] = operands[1];
7060 [(set_attr "type" "multi")
7061 (set_attr "mode" "<MODE>")])
7063 (define_insn_and_split "*divmod<mode>4"
7064 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7065 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7066 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7067 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7068 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7069 (clobber (reg:CC FLAGS_REG))]
7073 [(parallel [(set (match_dup 1)
7074 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7075 (clobber (reg:CC FLAGS_REG))])
7076 (parallel [(set (match_dup 0)
7077 (div:SWIM248 (match_dup 2) (match_dup 3)))
7079 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7081 (clobber (reg:CC FLAGS_REG))])]
7083 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7085 if (<MODE>mode != HImode
7086 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7087 operands[4] = operands[2];
7090 /* Avoid use of cltd in favor of a mov+shift. */
7091 emit_move_insn (operands[1], operands[2]);
7092 operands[4] = operands[1];
7095 [(set_attr "type" "multi")
7096 (set_attr "mode" "<MODE>")])
7098 (define_insn "*divmod<mode>4_noext"
7099 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7100 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7101 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7102 (set (match_operand:SWIM248 1 "register_operand" "=d")
7103 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7104 (use (match_operand:SWIM248 4 "register_operand" "1"))
7105 (clobber (reg:CC FLAGS_REG))]
7107 "idiv{<imodesuffix>}\t%3"
7108 [(set_attr "type" "idiv")
7109 (set_attr "mode" "<MODE>")])
7111 (define_expand "divmodqi4"
7112 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7114 (match_operand:QI 1 "register_operand" "")
7115 (match_operand:QI 2 "nonimmediate_operand" "")))
7116 (set (match_operand:QI 3 "register_operand" "")
7117 (mod:QI (match_dup 1) (match_dup 2)))
7118 (clobber (reg:CC FLAGS_REG))])]
7119 "TARGET_QIMODE_MATH"
7124 tmp0 = gen_reg_rtx (HImode);
7125 tmp1 = gen_reg_rtx (HImode);
7127 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7129 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7130 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7132 /* Extract remainder from AH. */
7133 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7134 insn = emit_move_insn (operands[3], tmp1);
7136 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7137 set_unique_reg_note (insn, REG_EQUAL, mod);
7139 /* Extract quotient from AL. */
7140 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7142 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7143 set_unique_reg_note (insn, REG_EQUAL, div);
7148 ;; Divide AX by r/m8, with result stored in
7151 ;; Change div/mod to HImode and extend the second argument to HImode
7152 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7153 ;; combine may fail.
7154 (define_insn "divmodhiqi3"
7155 [(set (match_operand:HI 0 "register_operand" "=a")
7160 (mod:HI (match_operand:HI 1 "register_operand" "0")
7162 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7166 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7167 (clobber (reg:CC FLAGS_REG))]
7168 "TARGET_QIMODE_MATH"
7170 [(set_attr "type" "idiv")
7171 (set_attr "mode" "QI")])
7173 (define_expand "udivmod<mode>4"
7174 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7176 (match_operand:SWIM248 1 "register_operand" "")
7177 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7178 (set (match_operand:SWIM248 3 "register_operand" "")
7179 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7180 (clobber (reg:CC FLAGS_REG))])])
7182 ;; Split with 8bit unsigned divide:
7183 ;; if (dividend an divisor are in [0-255])
7184 ;; use 8bit unsigned integer divide
7186 ;; use original integer divide
7188 [(set (match_operand:SWI48 0 "register_operand" "")
7189 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7190 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7191 (set (match_operand:SWI48 1 "register_operand" "")
7192 (umod:SWI48 (match_dup 2) (match_dup 3)))
7193 (clobber (reg:CC FLAGS_REG))]
7194 "TARGET_USE_8BIT_IDIV
7195 && TARGET_QIMODE_MATH
7196 && can_create_pseudo_p ()
7197 && !optimize_insn_for_size_p ()"
7199 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7201 (define_insn_and_split "udivmod<mode>4_1"
7202 [(set (match_operand:SWI48 0 "register_operand" "=a")
7203 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7204 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7205 (set (match_operand:SWI48 1 "register_operand" "=&d")
7206 (umod:SWI48 (match_dup 2) (match_dup 3)))
7207 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7208 (clobber (reg:CC FLAGS_REG))]
7212 [(set (match_dup 1) (const_int 0))
7213 (parallel [(set (match_dup 0)
7214 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7216 (umod:SWI48 (match_dup 2) (match_dup 3)))
7218 (clobber (reg:CC FLAGS_REG))])]
7220 [(set_attr "type" "multi")
7221 (set_attr "mode" "<MODE>")])
7223 (define_insn_and_split "*udivmod<mode>4"
7224 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7225 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7226 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7227 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7228 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7229 (clobber (reg:CC FLAGS_REG))]
7233 [(set (match_dup 1) (const_int 0))
7234 (parallel [(set (match_dup 0)
7235 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7237 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7239 (clobber (reg:CC FLAGS_REG))])]
7241 [(set_attr "type" "multi")
7242 (set_attr "mode" "<MODE>")])
7244 (define_insn "*udivmod<mode>4_noext"
7245 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7246 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7247 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7248 (set (match_operand:SWIM248 1 "register_operand" "=d")
7249 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7250 (use (match_operand:SWIM248 4 "register_operand" "1"))
7251 (clobber (reg:CC FLAGS_REG))]
7253 "div{<imodesuffix>}\t%3"
7254 [(set_attr "type" "idiv")
7255 (set_attr "mode" "<MODE>")])
7257 (define_expand "udivmodqi4"
7258 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7260 (match_operand:QI 1 "register_operand" "")
7261 (match_operand:QI 2 "nonimmediate_operand" "")))
7262 (set (match_operand:QI 3 "register_operand" "")
7263 (umod:QI (match_dup 1) (match_dup 2)))
7264 (clobber (reg:CC FLAGS_REG))])]
7265 "TARGET_QIMODE_MATH"
7270 tmp0 = gen_reg_rtx (HImode);
7271 tmp1 = gen_reg_rtx (HImode);
7273 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7275 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7276 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7278 /* Extract remainder from AH. */
7279 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7280 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7281 insn = emit_move_insn (operands[3], tmp1);
7283 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7284 set_unique_reg_note (insn, REG_EQUAL, mod);
7286 /* Extract quotient from AL. */
7287 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7289 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7290 set_unique_reg_note (insn, REG_EQUAL, div);
7295 (define_insn "udivmodhiqi3"
7296 [(set (match_operand:HI 0 "register_operand" "=a")
7301 (mod:HI (match_operand:HI 1 "register_operand" "0")
7303 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7307 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7308 (clobber (reg:CC FLAGS_REG))]
7309 "TARGET_QIMODE_MATH"
7311 [(set_attr "type" "idiv")
7312 (set_attr "mode" "QI")])
7314 ;; We cannot use div/idiv for double division, because it causes
7315 ;; "division by zero" on the overflow and that's not what we expect
7316 ;; from truncate. Because true (non truncating) double division is
7317 ;; never generated, we can't create this insn anyway.
7320 ; [(set (match_operand:SI 0 "register_operand" "=a")
7322 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7324 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7325 ; (set (match_operand:SI 3 "register_operand" "=d")
7327 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7328 ; (clobber (reg:CC FLAGS_REG))]
7330 ; "div{l}\t{%2, %0|%0, %2}"
7331 ; [(set_attr "type" "idiv")])
7333 ;;- Logical AND instructions
7335 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7336 ;; Note that this excludes ah.
7338 (define_expand "testsi_ccno_1"
7339 [(set (reg:CCNO FLAGS_REG)
7341 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7342 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7345 (define_expand "testqi_ccz_1"
7346 [(set (reg:CCZ FLAGS_REG)
7347 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7348 (match_operand:QI 1 "nonmemory_operand" ""))
7351 (define_expand "testdi_ccno_1"
7352 [(set (reg:CCNO FLAGS_REG)
7354 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7355 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7357 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7359 (define_insn "*testdi_1"
7360 [(set (reg FLAGS_REG)
7363 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7364 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7366 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7367 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7369 test{l}\t{%k1, %k0|%k0, %k1}
7370 test{l}\t{%k1, %k0|%k0, %k1}
7371 test{q}\t{%1, %0|%0, %1}
7372 test{q}\t{%1, %0|%0, %1}
7373 test{q}\t{%1, %0|%0, %1}"
7374 [(set_attr "type" "test")
7375 (set_attr "modrm" "0,1,0,1,1")
7376 (set_attr "mode" "SI,SI,DI,DI,DI")])
7378 (define_insn "*testqi_1_maybe_si"
7379 [(set (reg FLAGS_REG)
7382 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7383 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7385 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7386 && ix86_match_ccmode (insn,
7387 CONST_INT_P (operands[1])
7388 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7390 if (which_alternative == 3)
7392 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7393 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7394 return "test{l}\t{%1, %k0|%k0, %1}";
7396 return "test{b}\t{%1, %0|%0, %1}";
7398 [(set_attr "type" "test")
7399 (set_attr "modrm" "0,1,1,1")
7400 (set_attr "mode" "QI,QI,QI,SI")
7401 (set_attr "pent_pair" "uv,np,uv,np")])
7403 (define_insn "*test<mode>_1"
7404 [(set (reg FLAGS_REG)
7407 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7408 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7410 "ix86_match_ccmode (insn, CCNOmode)
7411 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7412 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7413 [(set_attr "type" "test")
7414 (set_attr "modrm" "0,1,1")
7415 (set_attr "mode" "<MODE>")
7416 (set_attr "pent_pair" "uv,np,uv")])
7418 (define_expand "testqi_ext_ccno_0"
7419 [(set (reg:CCNO FLAGS_REG)
7423 (match_operand 0 "ext_register_operand" "")
7426 (match_operand 1 "const_int_operand" ""))
7429 (define_insn "*testqi_ext_0"
7430 [(set (reg FLAGS_REG)
7434 (match_operand 0 "ext_register_operand" "Q")
7437 (match_operand 1 "const_int_operand" "n"))
7439 "ix86_match_ccmode (insn, CCNOmode)"
7440 "test{b}\t{%1, %h0|%h0, %1}"
7441 [(set_attr "type" "test")
7442 (set_attr "mode" "QI")
7443 (set_attr "length_immediate" "1")
7444 (set_attr "modrm" "1")
7445 (set_attr "pent_pair" "np")])
7447 (define_insn "*testqi_ext_1_rex64"
7448 [(set (reg FLAGS_REG)
7452 (match_operand 0 "ext_register_operand" "Q")
7456 (match_operand:QI 1 "register_operand" "Q")))
7458 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7459 "test{b}\t{%1, %h0|%h0, %1}"
7460 [(set_attr "type" "test")
7461 (set_attr "mode" "QI")])
7463 (define_insn "*testqi_ext_1"
7464 [(set (reg FLAGS_REG)
7468 (match_operand 0 "ext_register_operand" "Q")
7472 (match_operand:QI 1 "general_operand" "Qm")))
7474 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7475 "test{b}\t{%1, %h0|%h0, %1}"
7476 [(set_attr "type" "test")
7477 (set_attr "mode" "QI")])
7479 (define_insn "*testqi_ext_2"
7480 [(set (reg FLAGS_REG)
7484 (match_operand 0 "ext_register_operand" "Q")
7488 (match_operand 1 "ext_register_operand" "Q")
7492 "ix86_match_ccmode (insn, CCNOmode)"
7493 "test{b}\t{%h1, %h0|%h0, %h1}"
7494 [(set_attr "type" "test")
7495 (set_attr "mode" "QI")])
7497 (define_insn "*testqi_ext_3_rex64"
7498 [(set (reg FLAGS_REG)
7499 (compare (zero_extract:DI
7500 (match_operand 0 "nonimmediate_operand" "rm")
7501 (match_operand:DI 1 "const_int_operand" "")
7502 (match_operand:DI 2 "const_int_operand" ""))
7505 && ix86_match_ccmode (insn, CCNOmode)
7506 && INTVAL (operands[1]) > 0
7507 && INTVAL (operands[2]) >= 0
7508 /* Ensure that resulting mask is zero or sign extended operand. */
7509 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7510 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7511 && INTVAL (operands[1]) > 32))
7512 && (GET_MODE (operands[0]) == SImode
7513 || GET_MODE (operands[0]) == DImode
7514 || GET_MODE (operands[0]) == HImode
7515 || GET_MODE (operands[0]) == QImode)"
7518 ;; Combine likes to form bit extractions for some tests. Humor it.
7519 (define_insn "*testqi_ext_3"
7520 [(set (reg FLAGS_REG)
7521 (compare (zero_extract:SI
7522 (match_operand 0 "nonimmediate_operand" "rm")
7523 (match_operand:SI 1 "const_int_operand" "")
7524 (match_operand:SI 2 "const_int_operand" ""))
7526 "ix86_match_ccmode (insn, CCNOmode)
7527 && INTVAL (operands[1]) > 0
7528 && INTVAL (operands[2]) >= 0
7529 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7530 && (GET_MODE (operands[0]) == SImode
7531 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7532 || GET_MODE (operands[0]) == HImode
7533 || GET_MODE (operands[0]) == QImode)"
7537 [(set (match_operand 0 "flags_reg_operand" "")
7538 (match_operator 1 "compare_operator"
7540 (match_operand 2 "nonimmediate_operand" "")
7541 (match_operand 3 "const_int_operand" "")
7542 (match_operand 4 "const_int_operand" ""))
7544 "ix86_match_ccmode (insn, CCNOmode)"
7545 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7547 rtx val = operands[2];
7548 HOST_WIDE_INT len = INTVAL (operands[3]);
7549 HOST_WIDE_INT pos = INTVAL (operands[4]);
7551 enum machine_mode mode, submode;
7553 mode = GET_MODE (val);
7556 /* ??? Combine likes to put non-volatile mem extractions in QImode
7557 no matter the size of the test. So find a mode that works. */
7558 if (! MEM_VOLATILE_P (val))
7560 mode = smallest_mode_for_size (pos + len, MODE_INT);
7561 val = adjust_address (val, mode, 0);
7564 else if (GET_CODE (val) == SUBREG
7565 && (submode = GET_MODE (SUBREG_REG (val)),
7566 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7567 && pos + len <= GET_MODE_BITSIZE (submode)
7568 && GET_MODE_CLASS (submode) == MODE_INT)
7570 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7572 val = SUBREG_REG (val);
7574 else if (mode == HImode && pos + len <= 8)
7576 /* Small HImode tests can be converted to QImode. */
7578 val = gen_lowpart (QImode, val);
7581 if (len == HOST_BITS_PER_WIDE_INT)
7584 mask = ((HOST_WIDE_INT)1 << len) - 1;
7587 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7590 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7591 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7592 ;; this is relatively important trick.
7593 ;; Do the conversion only post-reload to avoid limiting of the register class
7596 [(set (match_operand 0 "flags_reg_operand" "")
7597 (match_operator 1 "compare_operator"
7598 [(and (match_operand 2 "register_operand" "")
7599 (match_operand 3 "const_int_operand" ""))
7602 && QI_REG_P (operands[2])
7603 && GET_MODE (operands[2]) != QImode
7604 && ((ix86_match_ccmode (insn, CCZmode)
7605 && !(INTVAL (operands[3]) & ~(255 << 8)))
7606 || (ix86_match_ccmode (insn, CCNOmode)
7607 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7610 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7614 operands[2] = gen_lowpart (SImode, operands[2]);
7615 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7619 [(set (match_operand 0 "flags_reg_operand" "")
7620 (match_operator 1 "compare_operator"
7621 [(and (match_operand 2 "nonimmediate_operand" "")
7622 (match_operand 3 "const_int_operand" ""))
7625 && GET_MODE (operands[2]) != QImode
7626 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7627 && ((ix86_match_ccmode (insn, CCZmode)
7628 && !(INTVAL (operands[3]) & ~255))
7629 || (ix86_match_ccmode (insn, CCNOmode)
7630 && !(INTVAL (operands[3]) & ~127)))"
7632 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7635 operands[2] = gen_lowpart (QImode, operands[2]);
7636 operands[3] = gen_lowpart (QImode, operands[3]);
7639 ;; %%% This used to optimize known byte-wide and operations to memory,
7640 ;; and sometimes to QImode registers. If this is considered useful,
7641 ;; it should be done with splitters.
7643 (define_expand "and<mode>3"
7644 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7645 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7646 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7648 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7650 (define_insn "*anddi_1"
7651 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7653 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7654 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7655 (clobber (reg:CC FLAGS_REG))]
7656 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7658 switch (get_attr_type (insn))
7664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7665 if (get_attr_mode (insn) == MODE_SI)
7666 return "and{l}\t{%k2, %k0|%k0, %k2}";
7668 return "and{q}\t{%2, %0|%0, %2}";
7671 [(set_attr "type" "alu,alu,alu,imovx")
7672 (set_attr "length_immediate" "*,*,*,0")
7673 (set (attr "prefix_rex")
7675 (and (eq_attr "type" "imovx")
7676 (and (match_test "INTVAL (operands[2]) == 0xff")
7677 (match_operand 1 "ext_QIreg_operand" "")))
7679 (const_string "*")))
7680 (set_attr "mode" "SI,DI,DI,SI")])
7682 (define_insn "*andsi_1"
7683 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7684 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7685 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7686 (clobber (reg:CC FLAGS_REG))]
7687 "ix86_binary_operator_ok (AND, SImode, operands)"
7689 switch (get_attr_type (insn))
7695 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7696 return "and{l}\t{%2, %0|%0, %2}";
7699 [(set_attr "type" "alu,alu,imovx")
7700 (set (attr "prefix_rex")
7702 (and (eq_attr "type" "imovx")
7703 (and (match_test "INTVAL (operands[2]) == 0xff")
7704 (match_operand 1 "ext_QIreg_operand" "")))
7706 (const_string "*")))
7707 (set_attr "length_immediate" "*,*,0")
7708 (set_attr "mode" "SI")])
7710 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7711 (define_insn "*andsi_1_zext"
7712 [(set (match_operand:DI 0 "register_operand" "=r")
7714 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7715 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7716 (clobber (reg:CC FLAGS_REG))]
7717 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7718 "and{l}\t{%2, %k0|%k0, %2}"
7719 [(set_attr "type" "alu")
7720 (set_attr "mode" "SI")])
7722 (define_insn "*andhi_1"
7723 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7724 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7725 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7726 (clobber (reg:CC FLAGS_REG))]
7727 "ix86_binary_operator_ok (AND, HImode, operands)"
7729 switch (get_attr_type (insn))
7735 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7736 return "and{w}\t{%2, %0|%0, %2}";
7739 [(set_attr "type" "alu,alu,imovx")
7740 (set_attr "length_immediate" "*,*,0")
7741 (set (attr "prefix_rex")
7743 (and (eq_attr "type" "imovx")
7744 (match_operand 1 "ext_QIreg_operand" ""))
7746 (const_string "*")))
7747 (set_attr "mode" "HI,HI,SI")])
7749 ;; %%% Potential partial reg stall on alternative 2. What to do?
7750 (define_insn "*andqi_1"
7751 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7752 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7753 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7754 (clobber (reg:CC FLAGS_REG))]
7755 "ix86_binary_operator_ok (AND, QImode, operands)"
7757 and{b}\t{%2, %0|%0, %2}
7758 and{b}\t{%2, %0|%0, %2}
7759 and{l}\t{%k2, %k0|%k0, %k2}"
7760 [(set_attr "type" "alu")
7761 (set_attr "mode" "QI,QI,SI")])
7763 (define_insn "*andqi_1_slp"
7764 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7765 (and:QI (match_dup 0)
7766 (match_operand:QI 1 "general_operand" "qn,qmn")))
7767 (clobber (reg:CC FLAGS_REG))]
7768 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7769 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7770 "and{b}\t{%1, %0|%0, %1}"
7771 [(set_attr "type" "alu1")
7772 (set_attr "mode" "QI")])
7775 [(set (match_operand:SWI248 0 "register_operand" "")
7776 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "")
7777 (match_operand:SWI248 2 "const_int_operand" "")))
7778 (clobber (reg:CC FLAGS_REG))]
7780 && true_regnum (operands[0]) != true_regnum (operands[1])"
7783 enum machine_mode mode;
7785 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7787 else if (INTVAL (operands[2]) == 0xffff)
7791 gcc_assert (INTVAL (operands[2]) == 0xff);
7795 operands[1] = gen_lowpart (mode, operands[1]);
7798 emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
7801 rtx (*insn) (rtx, rtx);
7803 /* Zero extend to SImode to avoid partial register stalls. */
7804 operands[0] = gen_lowpart (SImode, operands[0]);
7806 insn = (mode == HImode) ? gen_zero_extendhisi2 : gen_zero_extendqisi2;
7807 emit_insn (insn (operands[0], operands[1]));
7813 [(set (match_operand 0 "register_operand" "")
7815 (const_int -65536)))
7816 (clobber (reg:CC FLAGS_REG))]
7817 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7818 || optimize_function_for_size_p (cfun)"
7819 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7820 "operands[1] = gen_lowpart (HImode, operands[0]);")
7823 [(set (match_operand 0 "ext_register_operand" "")
7826 (clobber (reg:CC FLAGS_REG))]
7827 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7828 && reload_completed"
7829 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7830 "operands[1] = gen_lowpart (QImode, operands[0]);")
7833 [(set (match_operand 0 "ext_register_operand" "")
7835 (const_int -65281)))
7836 (clobber (reg:CC FLAGS_REG))]
7837 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7838 && reload_completed"
7839 [(parallel [(set (zero_extract:SI (match_dup 0)
7843 (zero_extract:SI (match_dup 0)
7846 (zero_extract:SI (match_dup 0)
7849 (clobber (reg:CC FLAGS_REG))])]
7850 "operands[0] = gen_lowpart (SImode, operands[0]);")
7852 (define_insn "*anddi_2"
7853 [(set (reg FLAGS_REG)
7856 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7857 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7859 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7860 (and:DI (match_dup 1) (match_dup 2)))]
7861 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7862 && ix86_binary_operator_ok (AND, DImode, operands)"
7864 and{l}\t{%k2, %k0|%k0, %k2}
7865 and{q}\t{%2, %0|%0, %2}
7866 and{q}\t{%2, %0|%0, %2}"
7867 [(set_attr "type" "alu")
7868 (set_attr "mode" "SI,DI,DI")])
7870 (define_insn "*andqi_2_maybe_si"
7871 [(set (reg FLAGS_REG)
7873 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7874 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7876 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7877 (and:QI (match_dup 1) (match_dup 2)))]
7878 "ix86_binary_operator_ok (AND, QImode, operands)
7879 && ix86_match_ccmode (insn,
7880 CONST_INT_P (operands[2])
7881 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7883 if (which_alternative == 2)
7885 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7886 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7887 return "and{l}\t{%2, %k0|%k0, %2}";
7889 return "and{b}\t{%2, %0|%0, %2}";
7891 [(set_attr "type" "alu")
7892 (set_attr "mode" "QI,QI,SI")])
7894 (define_insn "*and<mode>_2"
7895 [(set (reg FLAGS_REG)
7896 (compare (and:SWI124
7897 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7898 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7900 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7901 (and:SWI124 (match_dup 1) (match_dup 2)))]
7902 "ix86_match_ccmode (insn, CCNOmode)
7903 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7904 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7905 [(set_attr "type" "alu")
7906 (set_attr "mode" "<MODE>")])
7908 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7909 (define_insn "*andsi_2_zext"
7910 [(set (reg FLAGS_REG)
7912 (match_operand:SI 1 "nonimmediate_operand" "%0")
7913 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7915 (set (match_operand:DI 0 "register_operand" "=r")
7916 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7917 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7918 && ix86_binary_operator_ok (AND, SImode, operands)"
7919 "and{l}\t{%2, %k0|%k0, %2}"
7920 [(set_attr "type" "alu")
7921 (set_attr "mode" "SI")])
7923 (define_insn "*andqi_2_slp"
7924 [(set (reg FLAGS_REG)
7926 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7927 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7929 (set (strict_low_part (match_dup 0))
7930 (and:QI (match_dup 0) (match_dup 1)))]
7931 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7932 && ix86_match_ccmode (insn, CCNOmode)
7933 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7934 "and{b}\t{%1, %0|%0, %1}"
7935 [(set_attr "type" "alu1")
7936 (set_attr "mode" "QI")])
7938 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7939 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7940 ;; for a QImode operand, which of course failed.
7941 (define_insn "andqi_ext_0"
7942 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7947 (match_operand 1 "ext_register_operand" "0")
7950 (match_operand 2 "const_int_operand" "n")))
7951 (clobber (reg:CC FLAGS_REG))]
7953 "and{b}\t{%2, %h0|%h0, %2}"
7954 [(set_attr "type" "alu")
7955 (set_attr "length_immediate" "1")
7956 (set_attr "modrm" "1")
7957 (set_attr "mode" "QI")])
7959 ;; Generated by peephole translating test to and. This shows up
7960 ;; often in fp comparisons.
7961 (define_insn "*andqi_ext_0_cc"
7962 [(set (reg FLAGS_REG)
7966 (match_operand 1 "ext_register_operand" "0")
7969 (match_operand 2 "const_int_operand" "n"))
7971 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7980 "ix86_match_ccmode (insn, CCNOmode)"
7981 "and{b}\t{%2, %h0|%h0, %2}"
7982 [(set_attr "type" "alu")
7983 (set_attr "length_immediate" "1")
7984 (set_attr "modrm" "1")
7985 (set_attr "mode" "QI")])
7987 (define_insn "*andqi_ext_1_rex64"
7988 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7993 (match_operand 1 "ext_register_operand" "0")
7997 (match_operand 2 "ext_register_operand" "Q"))))
7998 (clobber (reg:CC FLAGS_REG))]
8000 "and{b}\t{%2, %h0|%h0, %2}"
8001 [(set_attr "type" "alu")
8002 (set_attr "length_immediate" "0")
8003 (set_attr "mode" "QI")])
8005 (define_insn "*andqi_ext_1"
8006 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8011 (match_operand 1 "ext_register_operand" "0")
8015 (match_operand:QI 2 "general_operand" "Qm"))))
8016 (clobber (reg:CC FLAGS_REG))]
8018 "and{b}\t{%2, %h0|%h0, %2}"
8019 [(set_attr "type" "alu")
8020 (set_attr "length_immediate" "0")
8021 (set_attr "mode" "QI")])
8023 (define_insn "*andqi_ext_2"
8024 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8029 (match_operand 1 "ext_register_operand" "%0")
8033 (match_operand 2 "ext_register_operand" "Q")
8036 (clobber (reg:CC FLAGS_REG))]
8038 "and{b}\t{%h2, %h0|%h0, %h2}"
8039 [(set_attr "type" "alu")
8040 (set_attr "length_immediate" "0")
8041 (set_attr "mode" "QI")])
8043 ;; Convert wide AND instructions with immediate operand to shorter QImode
8044 ;; equivalents when possible.
8045 ;; Don't do the splitting with memory operands, since it introduces risk
8046 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8047 ;; for size, but that can (should?) be handled by generic code instead.
8049 [(set (match_operand 0 "register_operand" "")
8050 (and (match_operand 1 "register_operand" "")
8051 (match_operand 2 "const_int_operand" "")))
8052 (clobber (reg:CC FLAGS_REG))]
8054 && QI_REG_P (operands[0])
8055 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8056 && !(~INTVAL (operands[2]) & ~(255 << 8))
8057 && GET_MODE (operands[0]) != QImode"
8058 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8059 (and:SI (zero_extract:SI (match_dup 1)
8060 (const_int 8) (const_int 8))
8062 (clobber (reg:CC FLAGS_REG))])]
8064 operands[0] = gen_lowpart (SImode, operands[0]);
8065 operands[1] = gen_lowpart (SImode, operands[1]);
8066 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8069 ;; Since AND can be encoded with sign extended immediate, this is only
8070 ;; profitable when 7th bit is not set.
8072 [(set (match_operand 0 "register_operand" "")
8073 (and (match_operand 1 "general_operand" "")
8074 (match_operand 2 "const_int_operand" "")))
8075 (clobber (reg:CC FLAGS_REG))]
8077 && ANY_QI_REG_P (operands[0])
8078 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8079 && !(~INTVAL (operands[2]) & ~255)
8080 && !(INTVAL (operands[2]) & 128)
8081 && GET_MODE (operands[0]) != QImode"
8082 [(parallel [(set (strict_low_part (match_dup 0))
8083 (and:QI (match_dup 1)
8085 (clobber (reg:CC FLAGS_REG))])]
8087 operands[0] = gen_lowpart (QImode, operands[0]);
8088 operands[1] = gen_lowpart (QImode, operands[1]);
8089 operands[2] = gen_lowpart (QImode, operands[2]);
8092 ;; Logical inclusive and exclusive OR instructions
8094 ;; %%% This used to optimize known byte-wide and operations to memory.
8095 ;; If this is considered useful, it should be done with splitters.
8097 (define_expand "<code><mode>3"
8098 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8099 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8100 (match_operand:SWIM 2 "<general_operand>" "")))]
8102 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8104 (define_insn "*<code><mode>_1"
8105 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8107 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8108 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8109 (clobber (reg:CC FLAGS_REG))]
8110 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8111 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8112 [(set_attr "type" "alu")
8113 (set_attr "mode" "<MODE>")])
8115 ;; %%% Potential partial reg stall on alternative 2. What to do?
8116 (define_insn "*<code>qi_1"
8117 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8118 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8119 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8120 (clobber (reg:CC FLAGS_REG))]
8121 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8123 <logic>{b}\t{%2, %0|%0, %2}
8124 <logic>{b}\t{%2, %0|%0, %2}
8125 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8126 [(set_attr "type" "alu")
8127 (set_attr "mode" "QI,QI,SI")])
8129 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8130 (define_insn "*<code>si_1_zext"
8131 [(set (match_operand:DI 0 "register_operand" "=r")
8133 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8134 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8135 (clobber (reg:CC FLAGS_REG))]
8136 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8137 "<logic>{l}\t{%2, %k0|%k0, %2}"
8138 [(set_attr "type" "alu")
8139 (set_attr "mode" "SI")])
8141 (define_insn "*<code>si_1_zext_imm"
8142 [(set (match_operand:DI 0 "register_operand" "=r")
8144 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8145 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8146 (clobber (reg:CC FLAGS_REG))]
8147 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8148 "<logic>{l}\t{%2, %k0|%k0, %2}"
8149 [(set_attr "type" "alu")
8150 (set_attr "mode" "SI")])
8152 (define_insn "*<code>qi_1_slp"
8153 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8154 (any_or:QI (match_dup 0)
8155 (match_operand:QI 1 "general_operand" "qmn,qn")))
8156 (clobber (reg:CC FLAGS_REG))]
8157 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8158 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8159 "<logic>{b}\t{%1, %0|%0, %1}"
8160 [(set_attr "type" "alu1")
8161 (set_attr "mode" "QI")])
8163 (define_insn "*<code><mode>_2"
8164 [(set (reg FLAGS_REG)
8165 (compare (any_or:SWI
8166 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8167 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8169 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8170 (any_or:SWI (match_dup 1) (match_dup 2)))]
8171 "ix86_match_ccmode (insn, CCNOmode)
8172 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8173 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8174 [(set_attr "type" "alu")
8175 (set_attr "mode" "<MODE>")])
8177 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8178 ;; ??? Special case for immediate operand is missing - it is tricky.
8179 (define_insn "*<code>si_2_zext"
8180 [(set (reg FLAGS_REG)
8181 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8182 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8184 (set (match_operand:DI 0 "register_operand" "=r")
8185 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8186 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8187 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8188 "<logic>{l}\t{%2, %k0|%k0, %2}"
8189 [(set_attr "type" "alu")
8190 (set_attr "mode" "SI")])
8192 (define_insn "*<code>si_2_zext_imm"
8193 [(set (reg FLAGS_REG)
8195 (match_operand:SI 1 "nonimmediate_operand" "%0")
8196 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8198 (set (match_operand:DI 0 "register_operand" "=r")
8199 (any_or:DI (zero_extend:DI (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>qi_2_slp"
8207 [(set (reg FLAGS_REG)
8208 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8209 (match_operand:QI 1 "general_operand" "qmn,qn"))
8211 (set (strict_low_part (match_dup 0))
8212 (any_or:QI (match_dup 0) (match_dup 1)))]
8213 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8214 && ix86_match_ccmode (insn, CCNOmode)
8215 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8216 "<logic>{b}\t{%1, %0|%0, %1}"
8217 [(set_attr "type" "alu1")
8218 (set_attr "mode" "QI")])
8220 (define_insn "*<code><mode>_3"
8221 [(set (reg FLAGS_REG)
8222 (compare (any_or:SWI
8223 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8224 (match_operand:SWI 2 "<general_operand>" "<g>"))
8226 (clobber (match_scratch:SWI 0 "=<r>"))]
8227 "ix86_match_ccmode (insn, CCNOmode)
8228 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8229 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8230 [(set_attr "type" "alu")
8231 (set_attr "mode" "<MODE>")])
8233 (define_insn "*<code>qi_ext_0"
8234 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8239 (match_operand 1 "ext_register_operand" "0")
8242 (match_operand 2 "const_int_operand" "n")))
8243 (clobber (reg:CC FLAGS_REG))]
8244 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8245 "<logic>{b}\t{%2, %h0|%h0, %2}"
8246 [(set_attr "type" "alu")
8247 (set_attr "length_immediate" "1")
8248 (set_attr "modrm" "1")
8249 (set_attr "mode" "QI")])
8251 (define_insn "*<code>qi_ext_1_rex64"
8252 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8257 (match_operand 1 "ext_register_operand" "0")
8261 (match_operand 2 "ext_register_operand" "Q"))))
8262 (clobber (reg:CC FLAGS_REG))]
8264 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8265 "<logic>{b}\t{%2, %h0|%h0, %2}"
8266 [(set_attr "type" "alu")
8267 (set_attr "length_immediate" "0")
8268 (set_attr "mode" "QI")])
8270 (define_insn "*<code>qi_ext_1"
8271 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8276 (match_operand 1 "ext_register_operand" "0")
8280 (match_operand:QI 2 "general_operand" "Qm"))))
8281 (clobber (reg:CC FLAGS_REG))]
8283 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8284 "<logic>{b}\t{%2, %h0|%h0, %2}"
8285 [(set_attr "type" "alu")
8286 (set_attr "length_immediate" "0")
8287 (set_attr "mode" "QI")])
8289 (define_insn "*<code>qi_ext_2"
8290 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8294 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8297 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8300 (clobber (reg:CC FLAGS_REG))]
8301 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8302 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8303 [(set_attr "type" "alu")
8304 (set_attr "length_immediate" "0")
8305 (set_attr "mode" "QI")])
8308 [(set (match_operand 0 "register_operand" "")
8309 (any_or (match_operand 1 "register_operand" "")
8310 (match_operand 2 "const_int_operand" "")))
8311 (clobber (reg:CC FLAGS_REG))]
8313 && QI_REG_P (operands[0])
8314 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8315 && !(INTVAL (operands[2]) & ~(255 << 8))
8316 && GET_MODE (operands[0]) != QImode"
8317 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8318 (any_or:SI (zero_extract:SI (match_dup 1)
8319 (const_int 8) (const_int 8))
8321 (clobber (reg:CC FLAGS_REG))])]
8323 operands[0] = gen_lowpart (SImode, operands[0]);
8324 operands[1] = gen_lowpart (SImode, operands[1]);
8325 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8328 ;; Since OR can be encoded with sign extended immediate, this is only
8329 ;; profitable when 7th bit is set.
8331 [(set (match_operand 0 "register_operand" "")
8332 (any_or (match_operand 1 "general_operand" "")
8333 (match_operand 2 "const_int_operand" "")))
8334 (clobber (reg:CC FLAGS_REG))]
8336 && ANY_QI_REG_P (operands[0])
8337 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8338 && !(INTVAL (operands[2]) & ~255)
8339 && (INTVAL (operands[2]) & 128)
8340 && GET_MODE (operands[0]) != QImode"
8341 [(parallel [(set (strict_low_part (match_dup 0))
8342 (any_or:QI (match_dup 1)
8344 (clobber (reg:CC FLAGS_REG))])]
8346 operands[0] = gen_lowpart (QImode, operands[0]);
8347 operands[1] = gen_lowpart (QImode, operands[1]);
8348 operands[2] = gen_lowpart (QImode, operands[2]);
8351 (define_expand "xorqi_cc_ext_1"
8353 (set (reg:CCNO FLAGS_REG)
8357 (match_operand 1 "ext_register_operand" "")
8360 (match_operand:QI 2 "general_operand" ""))
8362 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8372 (define_insn "*xorqi_cc_ext_1_rex64"
8373 [(set (reg FLAGS_REG)
8377 (match_operand 1 "ext_register_operand" "0")
8380 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8382 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8391 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8392 "xor{b}\t{%2, %h0|%h0, %2}"
8393 [(set_attr "type" "alu")
8394 (set_attr "modrm" "1")
8395 (set_attr "mode" "QI")])
8397 (define_insn "*xorqi_cc_ext_1"
8398 [(set (reg FLAGS_REG)
8402 (match_operand 1 "ext_register_operand" "0")
8405 (match_operand:QI 2 "general_operand" "qmn"))
8407 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8416 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8417 "xor{b}\t{%2, %h0|%h0, %2}"
8418 [(set_attr "type" "alu")
8419 (set_attr "modrm" "1")
8420 (set_attr "mode" "QI")])
8422 ;; Negation instructions
8424 (define_expand "neg<mode>2"
8425 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8426 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8428 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8430 (define_insn_and_split "*neg<dwi>2_doubleword"
8431 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8432 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8433 (clobber (reg:CC FLAGS_REG))]
8434 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8438 [(set (reg:CCZ FLAGS_REG)
8439 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8440 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8443 (plus:DWIH (match_dup 3)
8444 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8446 (clobber (reg:CC FLAGS_REG))])
8449 (neg:DWIH (match_dup 2)))
8450 (clobber (reg:CC FLAGS_REG))])]
8451 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8453 (define_insn "*neg<mode>2_1"
8454 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8455 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8456 (clobber (reg:CC FLAGS_REG))]
8457 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8458 "neg{<imodesuffix>}\t%0"
8459 [(set_attr "type" "negnot")
8460 (set_attr "mode" "<MODE>")])
8462 ;; Combine is quite creative about this pattern.
8463 (define_insn "*negsi2_1_zext"
8464 [(set (match_operand:DI 0 "register_operand" "=r")
8466 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8469 (clobber (reg:CC FLAGS_REG))]
8470 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8472 [(set_attr "type" "negnot")
8473 (set_attr "mode" "SI")])
8475 ;; The problem with neg is that it does not perform (compare x 0),
8476 ;; it really performs (compare 0 x), which leaves us with the zero
8477 ;; flag being the only useful item.
8479 (define_insn "*neg<mode>2_cmpz"
8480 [(set (reg:CCZ FLAGS_REG)
8482 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8484 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8485 (neg:SWI (match_dup 1)))]
8486 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8487 "neg{<imodesuffix>}\t%0"
8488 [(set_attr "type" "negnot")
8489 (set_attr "mode" "<MODE>")])
8491 (define_insn "*negsi2_cmpz_zext"
8492 [(set (reg:CCZ FLAGS_REG)
8496 (match_operand:DI 1 "register_operand" "0")
8500 (set (match_operand:DI 0 "register_operand" "=r")
8501 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8504 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8506 [(set_attr "type" "negnot")
8507 (set_attr "mode" "SI")])
8509 ;; Changing of sign for FP values is doable using integer unit too.
8511 (define_expand "<code><mode>2"
8512 [(set (match_operand:X87MODEF 0 "register_operand" "")
8513 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8514 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8515 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8517 (define_insn "*absneg<mode>2_mixed"
8518 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8519 (match_operator:MODEF 3 "absneg_operator"
8520 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8521 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8522 (clobber (reg:CC FLAGS_REG))]
8523 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8526 (define_insn "*absneg<mode>2_sse"
8527 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8528 (match_operator:MODEF 3 "absneg_operator"
8529 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8530 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8531 (clobber (reg:CC FLAGS_REG))]
8532 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8535 (define_insn "*absneg<mode>2_i387"
8536 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8537 (match_operator:X87MODEF 3 "absneg_operator"
8538 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8539 (use (match_operand 2 "" ""))
8540 (clobber (reg:CC FLAGS_REG))]
8541 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8544 (define_expand "<code>tf2"
8545 [(set (match_operand:TF 0 "register_operand" "")
8546 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8548 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8550 (define_insn "*absnegtf2_sse"
8551 [(set (match_operand:TF 0 "register_operand" "=x,x")
8552 (match_operator:TF 3 "absneg_operator"
8553 [(match_operand:TF 1 "register_operand" "0,x")]))
8554 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8555 (clobber (reg:CC FLAGS_REG))]
8559 ;; Splitters for fp abs and neg.
8562 [(set (match_operand 0 "fp_register_operand" "")
8563 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8564 (use (match_operand 2 "" ""))
8565 (clobber (reg:CC FLAGS_REG))]
8567 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8570 [(set (match_operand 0 "register_operand" "")
8571 (match_operator 3 "absneg_operator"
8572 [(match_operand 1 "register_operand" "")]))
8573 (use (match_operand 2 "nonimmediate_operand" ""))
8574 (clobber (reg:CC FLAGS_REG))]
8575 "reload_completed && SSE_REG_P (operands[0])"
8576 [(set (match_dup 0) (match_dup 3))]
8578 enum machine_mode mode = GET_MODE (operands[0]);
8579 enum machine_mode vmode = GET_MODE (operands[2]);
8582 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8583 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8584 if (operands_match_p (operands[0], operands[2]))
8587 operands[1] = operands[2];
8590 if (GET_CODE (operands[3]) == ABS)
8591 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8593 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8598 [(set (match_operand:SF 0 "register_operand" "")
8599 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8600 (use (match_operand:V4SF 2 "" ""))
8601 (clobber (reg:CC FLAGS_REG))]
8603 [(parallel [(set (match_dup 0) (match_dup 1))
8604 (clobber (reg:CC FLAGS_REG))])]
8607 operands[0] = gen_lowpart (SImode, operands[0]);
8608 if (GET_CODE (operands[1]) == ABS)
8610 tmp = gen_int_mode (0x7fffffff, SImode);
8611 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8615 tmp = gen_int_mode (0x80000000, SImode);
8616 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8622 [(set (match_operand:DF 0 "register_operand" "")
8623 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8624 (use (match_operand 2 "" ""))
8625 (clobber (reg:CC FLAGS_REG))]
8627 [(parallel [(set (match_dup 0) (match_dup 1))
8628 (clobber (reg:CC FLAGS_REG))])]
8633 tmp = gen_lowpart (DImode, operands[0]);
8634 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8637 if (GET_CODE (operands[1]) == ABS)
8640 tmp = gen_rtx_NOT (DImode, tmp);
8644 operands[0] = gen_highpart (SImode, operands[0]);
8645 if (GET_CODE (operands[1]) == ABS)
8647 tmp = gen_int_mode (0x7fffffff, SImode);
8648 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8652 tmp = gen_int_mode (0x80000000, SImode);
8653 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8660 [(set (match_operand:XF 0 "register_operand" "")
8661 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8662 (use (match_operand 2 "" ""))
8663 (clobber (reg:CC FLAGS_REG))]
8665 [(parallel [(set (match_dup 0) (match_dup 1))
8666 (clobber (reg:CC FLAGS_REG))])]
8669 operands[0] = gen_rtx_REG (SImode,
8670 true_regnum (operands[0])
8671 + (TARGET_64BIT ? 1 : 2));
8672 if (GET_CODE (operands[1]) == ABS)
8674 tmp = GEN_INT (0x7fff);
8675 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8679 tmp = GEN_INT (0x8000);
8680 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8685 ;; Conditionalize these after reload. If they match before reload, we
8686 ;; lose the clobber and ability to use integer instructions.
8688 (define_insn "*<code><mode>2_1"
8689 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8690 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8692 && (reload_completed
8693 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8694 "f<absneg_mnemonic>"
8695 [(set_attr "type" "fsgn")
8696 (set_attr "mode" "<MODE>")])
8698 (define_insn "*<code>extendsfdf2"
8699 [(set (match_operand:DF 0 "register_operand" "=f")
8700 (absneg:DF (float_extend:DF
8701 (match_operand:SF 1 "register_operand" "0"))))]
8702 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8703 "f<absneg_mnemonic>"
8704 [(set_attr "type" "fsgn")
8705 (set_attr "mode" "DF")])
8707 (define_insn "*<code>extendsfxf2"
8708 [(set (match_operand:XF 0 "register_operand" "=f")
8709 (absneg:XF (float_extend:XF
8710 (match_operand:SF 1 "register_operand" "0"))))]
8712 "f<absneg_mnemonic>"
8713 [(set_attr "type" "fsgn")
8714 (set_attr "mode" "XF")])
8716 (define_insn "*<code>extenddfxf2"
8717 [(set (match_operand:XF 0 "register_operand" "=f")
8718 (absneg:XF (float_extend:XF
8719 (match_operand:DF 1 "register_operand" "0"))))]
8721 "f<absneg_mnemonic>"
8722 [(set_attr "type" "fsgn")
8723 (set_attr "mode" "XF")])
8725 ;; Copysign instructions
8727 (define_mode_iterator CSGNMODE [SF DF TF])
8728 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8730 (define_expand "copysign<mode>3"
8731 [(match_operand:CSGNMODE 0 "register_operand" "")
8732 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8733 (match_operand:CSGNMODE 2 "register_operand" "")]
8734 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8735 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8736 "ix86_expand_copysign (operands); DONE;")
8738 (define_insn_and_split "copysign<mode>3_const"
8739 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8741 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8742 (match_operand:CSGNMODE 2 "register_operand" "0")
8743 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8745 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8746 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8748 "&& reload_completed"
8750 "ix86_split_copysign_const (operands); DONE;")
8752 (define_insn "copysign<mode>3_var"
8753 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8755 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8756 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8757 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8758 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8760 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8761 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8762 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8766 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8768 [(match_operand:CSGNMODE 2 "register_operand" "")
8769 (match_operand:CSGNMODE 3 "register_operand" "")
8770 (match_operand:<CSGNVMODE> 4 "" "")
8771 (match_operand:<CSGNVMODE> 5 "" "")]
8773 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8774 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8775 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8776 && reload_completed"
8778 "ix86_split_copysign_var (operands); DONE;")
8780 ;; One complement instructions
8782 (define_expand "one_cmpl<mode>2"
8783 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8784 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8786 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8788 (define_insn "*one_cmpl<mode>2_1"
8789 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8790 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8791 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8792 "not{<imodesuffix>}\t%0"
8793 [(set_attr "type" "negnot")
8794 (set_attr "mode" "<MODE>")])
8796 ;; %%% Potential partial reg stall on alternative 1. What to do?
8797 (define_insn "*one_cmplqi2_1"
8798 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8799 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8800 "ix86_unary_operator_ok (NOT, QImode, operands)"
8804 [(set_attr "type" "negnot")
8805 (set_attr "mode" "QI,SI")])
8807 ;; ??? Currently never generated - xor is used instead.
8808 (define_insn "*one_cmplsi2_1_zext"
8809 [(set (match_operand:DI 0 "register_operand" "=r")
8811 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8812 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8814 [(set_attr "type" "negnot")
8815 (set_attr "mode" "SI")])
8817 (define_insn "*one_cmpl<mode>2_2"
8818 [(set (reg FLAGS_REG)
8819 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8821 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8822 (not:SWI (match_dup 1)))]
8823 "ix86_match_ccmode (insn, CCNOmode)
8824 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8826 [(set_attr "type" "alu1")
8827 (set_attr "mode" "<MODE>")])
8830 [(set (match_operand 0 "flags_reg_operand" "")
8831 (match_operator 2 "compare_operator"
8832 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8834 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8835 (not:SWI (match_dup 3)))]
8836 "ix86_match_ccmode (insn, CCNOmode)"
8837 [(parallel [(set (match_dup 0)
8838 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8841 (xor:SWI (match_dup 3) (const_int -1)))])])
8843 ;; ??? Currently never generated - xor is used instead.
8844 (define_insn "*one_cmplsi2_2_zext"
8845 [(set (reg FLAGS_REG)
8846 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8848 (set (match_operand:DI 0 "register_operand" "=r")
8849 (zero_extend:DI (not:SI (match_dup 1))))]
8850 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8851 && ix86_unary_operator_ok (NOT, SImode, operands)"
8853 [(set_attr "type" "alu1")
8854 (set_attr "mode" "SI")])
8857 [(set (match_operand 0 "flags_reg_operand" "")
8858 (match_operator 2 "compare_operator"
8859 [(not:SI (match_operand:SI 3 "register_operand" ""))
8861 (set (match_operand:DI 1 "register_operand" "")
8862 (zero_extend:DI (not:SI (match_dup 3))))]
8863 "ix86_match_ccmode (insn, CCNOmode)"
8864 [(parallel [(set (match_dup 0)
8865 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8868 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8870 ;; Shift instructions
8872 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8873 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8874 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8875 ;; from the assembler input.
8877 ;; This instruction shifts the target reg/mem as usual, but instead of
8878 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8879 ;; is a left shift double, bits are taken from the high order bits of
8880 ;; reg, else if the insn is a shift right double, bits are taken from the
8881 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8882 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8884 ;; Since sh[lr]d does not change the `reg' operand, that is done
8885 ;; separately, making all shifts emit pairs of shift double and normal
8886 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8887 ;; support a 63 bit shift, each shift where the count is in a reg expands
8888 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8890 ;; If the shift count is a constant, we need never emit more than one
8891 ;; shift pair, instead using moves and sign extension for counts greater
8894 (define_expand "ashl<mode>3"
8895 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8896 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8897 (match_operand:QI 2 "nonmemory_operand" "")))]
8899 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8901 (define_insn "*ashl<mode>3_doubleword"
8902 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8903 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8904 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8905 (clobber (reg:CC FLAGS_REG))]
8908 [(set_attr "type" "multi")])
8911 [(set (match_operand:DWI 0 "register_operand" "")
8912 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8913 (match_operand:QI 2 "nonmemory_operand" "")))
8914 (clobber (reg:CC FLAGS_REG))]
8915 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8917 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8919 ;; By default we don't ask for a scratch register, because when DWImode
8920 ;; values are manipulated, registers are already at a premium. But if
8921 ;; we have one handy, we won't turn it away.
8924 [(match_scratch:DWIH 3 "r")
8925 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8927 (match_operand:<DWI> 1 "nonmemory_operand" "")
8928 (match_operand:QI 2 "nonmemory_operand" "")))
8929 (clobber (reg:CC FLAGS_REG))])
8933 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8935 (define_insn "x86_64_shld"
8936 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8937 (ior:DI (ashift:DI (match_dup 0)
8938 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8939 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8940 (minus:QI (const_int 64) (match_dup 2)))))
8941 (clobber (reg:CC FLAGS_REG))]
8943 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8944 [(set_attr "type" "ishift")
8945 (set_attr "prefix_0f" "1")
8946 (set_attr "mode" "DI")
8947 (set_attr "athlon_decode" "vector")
8948 (set_attr "amdfam10_decode" "vector")
8949 (set_attr "bdver1_decode" "vector")])
8951 (define_insn "x86_shld"
8952 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8953 (ior:SI (ashift:SI (match_dup 0)
8954 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8955 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8956 (minus:QI (const_int 32) (match_dup 2)))))
8957 (clobber (reg:CC FLAGS_REG))]
8959 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8960 [(set_attr "type" "ishift")
8961 (set_attr "prefix_0f" "1")
8962 (set_attr "mode" "SI")
8963 (set_attr "pent_pair" "np")
8964 (set_attr "athlon_decode" "vector")
8965 (set_attr "amdfam10_decode" "vector")
8966 (set_attr "bdver1_decode" "vector")])
8968 (define_expand "x86_shift<mode>_adj_1"
8969 [(set (reg:CCZ FLAGS_REG)
8970 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8973 (set (match_operand:SWI48 0 "register_operand" "")
8974 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8975 (match_operand:SWI48 1 "register_operand" "")
8978 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8979 (match_operand:SWI48 3 "register_operand" "")
8982 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8984 (define_expand "x86_shift<mode>_adj_2"
8985 [(use (match_operand:SWI48 0 "register_operand" ""))
8986 (use (match_operand:SWI48 1 "register_operand" ""))
8987 (use (match_operand:QI 2 "register_operand" ""))]
8990 rtx label = gen_label_rtx ();
8993 emit_insn (gen_testqi_ccz_1 (operands[2],
8994 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
8996 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
8997 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
8998 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
8999 gen_rtx_LABEL_REF (VOIDmode, label),
9001 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9002 JUMP_LABEL (tmp) = label;
9004 emit_move_insn (operands[0], operands[1]);
9005 ix86_expand_clear (operands[1]);
9008 LABEL_NUSES (label) = 1;
9013 ;; Avoid useless masking of count operand.
9014 (define_insn_and_split "*ashl<mode>3_mask"
9015 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9017 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9020 (match_operand:SI 2 "nonimmediate_operand" "c")
9021 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9022 (clobber (reg:CC FLAGS_REG))]
9023 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9024 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9025 == GET_MODE_BITSIZE (<MODE>mode)-1"
9028 [(parallel [(set (match_dup 0)
9029 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9030 (clobber (reg:CC FLAGS_REG))])]
9032 if (can_create_pseudo_p ())
9033 operands [2] = force_reg (SImode, operands[2]);
9035 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9037 [(set_attr "type" "ishift")
9038 (set_attr "mode" "<MODE>")])
9040 (define_insn "*bmi2_ashl<mode>3_1"
9041 [(set (match_operand:SWI48 0 "register_operand" "=r")
9042 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9043 (match_operand:SWI48 2 "register_operand" "r")))]
9045 "shlx\t{%2, %1, %0|%0, %1, %2}"
9046 [(set_attr "type" "ishiftx")
9047 (set_attr "mode" "<MODE>")])
9049 (define_insn "*ashl<mode>3_1"
9050 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9051 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9052 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9053 (clobber (reg:CC FLAGS_REG))]
9054 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9056 switch (get_attr_type (insn))
9063 gcc_assert (operands[2] == const1_rtx);
9064 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9065 return "add{<imodesuffix>}\t%0, %0";
9068 if (operands[2] == const1_rtx
9069 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9070 return "sal{<imodesuffix>}\t%0";
9072 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9075 [(set_attr "isa" "*,*,bmi2")
9077 (cond [(eq_attr "alternative" "1")
9078 (const_string "lea")
9079 (eq_attr "alternative" "2")
9080 (const_string "ishiftx")
9081 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9082 (match_operand 0 "register_operand" ""))
9083 (match_operand 2 "const1_operand" ""))
9084 (const_string "alu")
9086 (const_string "ishift")))
9087 (set (attr "length_immediate")
9089 (ior (eq_attr "type" "alu")
9090 (and (eq_attr "type" "ishift")
9091 (and (match_operand 2 "const1_operand" "")
9092 (ior (match_test "TARGET_SHIFT1")
9093 (match_test "optimize_function_for_size_p (cfun)")))))
9095 (const_string "*")))
9096 (set_attr "mode" "<MODE>")])
9098 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9100 [(set (match_operand:SWI48 0 "register_operand" "")
9101 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9102 (match_operand:QI 2 "register_operand" "")))
9103 (clobber (reg:CC FLAGS_REG))]
9104 "TARGET_BMI2 && reload_completed"
9106 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9107 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9109 (define_insn "*bmi2_ashlsi3_1_zext"
9110 [(set (match_operand:DI 0 "register_operand" "=r")
9112 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9113 (match_operand:SI 2 "register_operand" "r"))))]
9114 "TARGET_64BIT && TARGET_BMI2"
9115 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9116 [(set_attr "type" "ishiftx")
9117 (set_attr "mode" "SI")])
9119 (define_insn "*ashlsi3_1_zext"
9120 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9122 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9123 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9124 (clobber (reg:CC FLAGS_REG))]
9125 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9127 switch (get_attr_type (insn))
9134 gcc_assert (operands[2] == const1_rtx);
9135 return "add{l}\t%k0, %k0";
9138 if (operands[2] == const1_rtx
9139 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9140 return "sal{l}\t%k0";
9142 return "sal{l}\t{%2, %k0|%k0, %2}";
9145 [(set_attr "isa" "*,*,bmi2")
9147 (cond [(eq_attr "alternative" "1")
9148 (const_string "lea")
9149 (eq_attr "alternative" "2")
9150 (const_string "ishiftx")
9151 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9152 (match_operand 2 "const1_operand" ""))
9153 (const_string "alu")
9155 (const_string "ishift")))
9156 (set (attr "length_immediate")
9158 (ior (eq_attr "type" "alu")
9159 (and (eq_attr "type" "ishift")
9160 (and (match_operand 2 "const1_operand" "")
9161 (ior (match_test "TARGET_SHIFT1")
9162 (match_test "optimize_function_for_size_p (cfun)")))))
9164 (const_string "*")))
9165 (set_attr "mode" "SI")])
9167 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9169 [(set (match_operand:DI 0 "register_operand" "")
9171 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9172 (match_operand:QI 2 "register_operand" ""))))
9173 (clobber (reg:CC FLAGS_REG))]
9174 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9176 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9177 "operands[2] = gen_lowpart (SImode, operands[2]);")
9179 (define_insn "*ashlhi3_1"
9180 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9181 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9182 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9183 (clobber (reg:CC FLAGS_REG))]
9184 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9186 switch (get_attr_type (insn))
9192 gcc_assert (operands[2] == const1_rtx);
9193 return "add{w}\t%0, %0";
9196 if (operands[2] == const1_rtx
9197 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9198 return "sal{w}\t%0";
9200 return "sal{w}\t{%2, %0|%0, %2}";
9204 (cond [(eq_attr "alternative" "1")
9205 (const_string "lea")
9206 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9207 (match_operand 0 "register_operand" ""))
9208 (match_operand 2 "const1_operand" ""))
9209 (const_string "alu")
9211 (const_string "ishift")))
9212 (set (attr "length_immediate")
9214 (ior (eq_attr "type" "alu")
9215 (and (eq_attr "type" "ishift")
9216 (and (match_operand 2 "const1_operand" "")
9217 (ior (match_test "TARGET_SHIFT1")
9218 (match_test "optimize_function_for_size_p (cfun)")))))
9220 (const_string "*")))
9221 (set_attr "mode" "HI,SI")])
9223 ;; %%% Potential partial reg stall on alternative 1. What to do?
9224 (define_insn "*ashlqi3_1"
9225 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9226 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9227 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9228 (clobber (reg:CC FLAGS_REG))]
9229 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9231 switch (get_attr_type (insn))
9237 gcc_assert (operands[2] == const1_rtx);
9238 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9239 return "add{l}\t%k0, %k0";
9241 return "add{b}\t%0, %0";
9244 if (operands[2] == const1_rtx
9245 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9247 if (get_attr_mode (insn) == MODE_SI)
9248 return "sal{l}\t%k0";
9250 return "sal{b}\t%0";
9254 if (get_attr_mode (insn) == MODE_SI)
9255 return "sal{l}\t{%2, %k0|%k0, %2}";
9257 return "sal{b}\t{%2, %0|%0, %2}";
9262 (cond [(eq_attr "alternative" "2")
9263 (const_string "lea")
9264 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9265 (match_operand 0 "register_operand" ""))
9266 (match_operand 2 "const1_operand" ""))
9267 (const_string "alu")
9269 (const_string "ishift")))
9270 (set (attr "length_immediate")
9272 (ior (eq_attr "type" "alu")
9273 (and (eq_attr "type" "ishift")
9274 (and (match_operand 2 "const1_operand" "")
9275 (ior (match_test "TARGET_SHIFT1")
9276 (match_test "optimize_function_for_size_p (cfun)")))))
9278 (const_string "*")))
9279 (set_attr "mode" "QI,SI,SI")])
9281 (define_insn "*ashlqi3_1_slp"
9282 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9283 (ashift:QI (match_dup 0)
9284 (match_operand:QI 1 "nonmemory_operand" "cI")))
9285 (clobber (reg:CC FLAGS_REG))]
9286 "(optimize_function_for_size_p (cfun)
9287 || !TARGET_PARTIAL_FLAG_REG_STALL
9288 || (operands[1] == const1_rtx
9290 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9292 switch (get_attr_type (insn))
9295 gcc_assert (operands[1] == const1_rtx);
9296 return "add{b}\t%0, %0";
9299 if (operands[1] == const1_rtx
9300 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9301 return "sal{b}\t%0";
9303 return "sal{b}\t{%1, %0|%0, %1}";
9307 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9308 (match_operand 0 "register_operand" ""))
9309 (match_operand 1 "const1_operand" ""))
9310 (const_string "alu")
9312 (const_string "ishift1")))
9313 (set (attr "length_immediate")
9315 (ior (eq_attr "type" "alu")
9316 (and (eq_attr "type" "ishift1")
9317 (and (match_operand 1 "const1_operand" "")
9318 (ior (match_test "TARGET_SHIFT1")
9319 (match_test "optimize_function_for_size_p (cfun)")))))
9321 (const_string "*")))
9322 (set_attr "mode" "QI")])
9324 ;; Convert ashift to the lea pattern to avoid flags dependency.
9326 [(set (match_operand 0 "register_operand" "")
9327 (ashift (match_operand 1 "index_register_operand" "")
9328 (match_operand:QI 2 "const_int_operand" "")))
9329 (clobber (reg:CC FLAGS_REG))]
9330 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9332 && true_regnum (operands[0]) != true_regnum (operands[1])"
9335 enum machine_mode mode = GET_MODE (operands[0]);
9338 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9341 operands[0] = gen_lowpart (mode, operands[0]);
9342 operands[1] = gen_lowpart (mode, operands[1]);
9345 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9347 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9349 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9353 ;; Convert ashift to the lea pattern to avoid flags dependency.
9355 [(set (match_operand:DI 0 "register_operand" "")
9357 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9358 (match_operand:QI 2 "const_int_operand" ""))))
9359 (clobber (reg:CC FLAGS_REG))]
9360 "TARGET_64BIT && reload_completed
9361 && true_regnum (operands[0]) != true_regnum (operands[1])"
9363 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9365 operands[1] = gen_lowpart (DImode, operands[1]);
9366 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9369 ;; This pattern can't accept a variable shift count, since shifts by
9370 ;; zero don't affect the flags. We assume that shifts by constant
9371 ;; zero are optimized away.
9372 (define_insn "*ashl<mode>3_cmp"
9373 [(set (reg FLAGS_REG)
9375 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9376 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9378 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9379 (ashift:SWI (match_dup 1) (match_dup 2)))]
9380 "(optimize_function_for_size_p (cfun)
9381 || !TARGET_PARTIAL_FLAG_REG_STALL
9382 || (operands[2] == const1_rtx
9384 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9385 && ix86_match_ccmode (insn, CCGOCmode)
9386 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9388 switch (get_attr_type (insn))
9391 gcc_assert (operands[2] == const1_rtx);
9392 return "add{<imodesuffix>}\t%0, %0";
9395 if (operands[2] == const1_rtx
9396 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9397 return "sal{<imodesuffix>}\t%0";
9399 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9403 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9404 (match_operand 0 "register_operand" ""))
9405 (match_operand 2 "const1_operand" ""))
9406 (const_string "alu")
9408 (const_string "ishift")))
9409 (set (attr "length_immediate")
9411 (ior (eq_attr "type" "alu")
9412 (and (eq_attr "type" "ishift")
9413 (and (match_operand 2 "const1_operand" "")
9414 (ior (match_test "TARGET_SHIFT1")
9415 (match_test "optimize_function_for_size_p (cfun)")))))
9417 (const_string "*")))
9418 (set_attr "mode" "<MODE>")])
9420 (define_insn "*ashlsi3_cmp_zext"
9421 [(set (reg FLAGS_REG)
9423 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9424 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9426 (set (match_operand:DI 0 "register_operand" "=r")
9427 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9429 && (optimize_function_for_size_p (cfun)
9430 || !TARGET_PARTIAL_FLAG_REG_STALL
9431 || (operands[2] == const1_rtx
9433 || TARGET_DOUBLE_WITH_ADD)))
9434 && ix86_match_ccmode (insn, CCGOCmode)
9435 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9437 switch (get_attr_type (insn))
9440 gcc_assert (operands[2] == const1_rtx);
9441 return "add{l}\t%k0, %k0";
9444 if (operands[2] == const1_rtx
9445 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9446 return "sal{l}\t%k0";
9448 return "sal{l}\t{%2, %k0|%k0, %2}";
9452 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9453 (match_operand 2 "const1_operand" ""))
9454 (const_string "alu")
9456 (const_string "ishift")))
9457 (set (attr "length_immediate")
9459 (ior (eq_attr "type" "alu")
9460 (and (eq_attr "type" "ishift")
9461 (and (match_operand 2 "const1_operand" "")
9462 (ior (match_test "TARGET_SHIFT1")
9463 (match_test "optimize_function_for_size_p (cfun)")))))
9465 (const_string "*")))
9466 (set_attr "mode" "SI")])
9468 (define_insn "*ashl<mode>3_cconly"
9469 [(set (reg FLAGS_REG)
9471 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9472 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9474 (clobber (match_scratch:SWI 0 "=<r>"))]
9475 "(optimize_function_for_size_p (cfun)
9476 || !TARGET_PARTIAL_FLAG_REG_STALL
9477 || (operands[2] == const1_rtx
9479 || TARGET_DOUBLE_WITH_ADD)))
9480 && ix86_match_ccmode (insn, CCGOCmode)"
9482 switch (get_attr_type (insn))
9485 gcc_assert (operands[2] == const1_rtx);
9486 return "add{<imodesuffix>}\t%0, %0";
9489 if (operands[2] == const1_rtx
9490 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9491 return "sal{<imodesuffix>}\t%0";
9493 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9497 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9498 (match_operand 0 "register_operand" ""))
9499 (match_operand 2 "const1_operand" ""))
9500 (const_string "alu")
9502 (const_string "ishift")))
9503 (set (attr "length_immediate")
9505 (ior (eq_attr "type" "alu")
9506 (and (eq_attr "type" "ishift")
9507 (and (match_operand 2 "const1_operand" "")
9508 (ior (match_test "TARGET_SHIFT1")
9509 (match_test "optimize_function_for_size_p (cfun)")))))
9511 (const_string "*")))
9512 (set_attr "mode" "<MODE>")])
9514 ;; See comment above `ashl<mode>3' about how this works.
9516 (define_expand "<shift_insn><mode>3"
9517 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9518 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9519 (match_operand:QI 2 "nonmemory_operand" "")))]
9521 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9523 ;; Avoid useless masking of count operand.
9524 (define_insn_and_split "*<shift_insn><mode>3_mask"
9525 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9527 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9530 (match_operand:SI 2 "nonimmediate_operand" "c")
9531 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9532 (clobber (reg:CC FLAGS_REG))]
9533 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9534 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9535 == GET_MODE_BITSIZE (<MODE>mode)-1"
9538 [(parallel [(set (match_dup 0)
9539 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9540 (clobber (reg:CC FLAGS_REG))])]
9542 if (can_create_pseudo_p ())
9543 operands [2] = force_reg (SImode, operands[2]);
9545 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9547 [(set_attr "type" "ishift")
9548 (set_attr "mode" "<MODE>")])
9550 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9551 [(set (match_operand:DWI 0 "register_operand" "=r")
9552 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9553 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9554 (clobber (reg:CC FLAGS_REG))]
9557 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9559 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9560 [(set_attr "type" "multi")])
9562 ;; By default we don't ask for a scratch register, because when DWImode
9563 ;; values are manipulated, registers are already at a premium. But if
9564 ;; we have one handy, we won't turn it away.
9567 [(match_scratch:DWIH 3 "r")
9568 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9570 (match_operand:<DWI> 1 "register_operand" "")
9571 (match_operand:QI 2 "nonmemory_operand" "")))
9572 (clobber (reg:CC FLAGS_REG))])
9576 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9578 (define_insn "x86_64_shrd"
9579 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9580 (ior:DI (ashiftrt:DI (match_dup 0)
9581 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9582 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9583 (minus:QI (const_int 64) (match_dup 2)))))
9584 (clobber (reg:CC FLAGS_REG))]
9586 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9587 [(set_attr "type" "ishift")
9588 (set_attr "prefix_0f" "1")
9589 (set_attr "mode" "DI")
9590 (set_attr "athlon_decode" "vector")
9591 (set_attr "amdfam10_decode" "vector")
9592 (set_attr "bdver1_decode" "vector")])
9594 (define_insn "x86_shrd"
9595 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9596 (ior:SI (ashiftrt:SI (match_dup 0)
9597 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9598 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9599 (minus:QI (const_int 32) (match_dup 2)))))
9600 (clobber (reg:CC FLAGS_REG))]
9602 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9603 [(set_attr "type" "ishift")
9604 (set_attr "prefix_0f" "1")
9605 (set_attr "mode" "SI")
9606 (set_attr "pent_pair" "np")
9607 (set_attr "athlon_decode" "vector")
9608 (set_attr "amdfam10_decode" "vector")
9609 (set_attr "bdver1_decode" "vector")])
9611 (define_insn "ashrdi3_cvt"
9612 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9613 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9614 (match_operand:QI 2 "const_int_operand" "")))
9615 (clobber (reg:CC FLAGS_REG))]
9616 "TARGET_64BIT && INTVAL (operands[2]) == 63
9617 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9618 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9621 sar{q}\t{%2, %0|%0, %2}"
9622 [(set_attr "type" "imovx,ishift")
9623 (set_attr "prefix_0f" "0,*")
9624 (set_attr "length_immediate" "0,*")
9625 (set_attr "modrm" "0,1")
9626 (set_attr "mode" "DI")])
9628 (define_insn "ashrsi3_cvt"
9629 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9630 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9631 (match_operand:QI 2 "const_int_operand" "")))
9632 (clobber (reg:CC FLAGS_REG))]
9633 "INTVAL (operands[2]) == 31
9634 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9635 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9638 sar{l}\t{%2, %0|%0, %2}"
9639 [(set_attr "type" "imovx,ishift")
9640 (set_attr "prefix_0f" "0,*")
9641 (set_attr "length_immediate" "0,*")
9642 (set_attr "modrm" "0,1")
9643 (set_attr "mode" "SI")])
9645 (define_insn "*ashrsi3_cvt_zext"
9646 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9648 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9649 (match_operand:QI 2 "const_int_operand" ""))))
9650 (clobber (reg:CC FLAGS_REG))]
9651 "TARGET_64BIT && INTVAL (operands[2]) == 31
9652 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9653 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9656 sar{l}\t{%2, %k0|%k0, %2}"
9657 [(set_attr "type" "imovx,ishift")
9658 (set_attr "prefix_0f" "0,*")
9659 (set_attr "length_immediate" "0,*")
9660 (set_attr "modrm" "0,1")
9661 (set_attr "mode" "SI")])
9663 (define_expand "x86_shift<mode>_adj_3"
9664 [(use (match_operand:SWI48 0 "register_operand" ""))
9665 (use (match_operand:SWI48 1 "register_operand" ""))
9666 (use (match_operand:QI 2 "register_operand" ""))]
9669 rtx label = gen_label_rtx ();
9672 emit_insn (gen_testqi_ccz_1 (operands[2],
9673 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9675 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9676 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9677 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9678 gen_rtx_LABEL_REF (VOIDmode, label),
9680 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9681 JUMP_LABEL (tmp) = label;
9683 emit_move_insn (operands[0], operands[1]);
9684 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9685 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9687 LABEL_NUSES (label) = 1;
9692 (define_insn "*bmi2_<shift_insn><mode>3_1"
9693 [(set (match_operand:SWI48 0 "register_operand" "=r")
9694 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9695 (match_operand:SWI48 2 "register_operand" "r")))]
9697 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9698 [(set_attr "type" "ishiftx")
9699 (set_attr "mode" "<MODE>")])
9701 (define_insn "*<shift_insn><mode>3_1"
9702 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9704 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9705 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9706 (clobber (reg:CC FLAGS_REG))]
9707 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9709 switch (get_attr_type (insn))
9715 if (operands[2] == const1_rtx
9716 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9717 return "<shift>{<imodesuffix>}\t%0";
9719 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9722 [(set_attr "isa" "*,bmi2")
9723 (set_attr "type" "ishift,ishiftx")
9724 (set (attr "length_immediate")
9726 (and (match_operand 2 "const1_operand" "")
9727 (ior (match_test "TARGET_SHIFT1")
9728 (match_test "optimize_function_for_size_p (cfun)")))
9730 (const_string "*")))
9731 (set_attr "mode" "<MODE>")])
9733 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9735 [(set (match_operand:SWI48 0 "register_operand" "")
9736 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9737 (match_operand:QI 2 "register_operand" "")))
9738 (clobber (reg:CC FLAGS_REG))]
9739 "TARGET_BMI2 && reload_completed"
9741 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9742 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9744 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9745 [(set (match_operand:DI 0 "register_operand" "=r")
9747 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9748 (match_operand:SI 2 "register_operand" "r"))))]
9749 "TARGET_64BIT && TARGET_BMI2"
9750 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9751 [(set_attr "type" "ishiftx")
9752 (set_attr "mode" "SI")])
9754 (define_insn "*<shift_insn>si3_1_zext"
9755 [(set (match_operand:DI 0 "register_operand" "=r,r")
9757 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9758 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9759 (clobber (reg:CC FLAGS_REG))]
9760 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9762 switch (get_attr_type (insn))
9768 if (operands[2] == const1_rtx
9769 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9770 return "<shift>{l}\t%k0";
9772 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9775 [(set_attr "isa" "*,bmi2")
9776 (set_attr "type" "ishift,ishiftx")
9777 (set (attr "length_immediate")
9779 (and (match_operand 2 "const1_operand" "")
9780 (ior (match_test "TARGET_SHIFT1")
9781 (match_test "optimize_function_for_size_p (cfun)")))
9783 (const_string "*")))
9784 (set_attr "mode" "SI")])
9786 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9788 [(set (match_operand:DI 0 "register_operand" "")
9790 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9791 (match_operand:QI 2 "register_operand" ""))))
9792 (clobber (reg:CC FLAGS_REG))]
9793 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9795 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9796 "operands[2] = gen_lowpart (SImode, operands[2]);")
9798 (define_insn "*<shift_insn><mode>3_1"
9799 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9801 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9802 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9803 (clobber (reg:CC FLAGS_REG))]
9804 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9806 if (operands[2] == const1_rtx
9807 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9808 return "<shift>{<imodesuffix>}\t%0";
9810 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9812 [(set_attr "type" "ishift")
9813 (set (attr "length_immediate")
9815 (and (match_operand 2 "const1_operand" "")
9816 (ior (match_test "TARGET_SHIFT1")
9817 (match_test "optimize_function_for_size_p (cfun)")))
9819 (const_string "*")))
9820 (set_attr "mode" "<MODE>")])
9822 (define_insn "*<shift_insn>qi3_1_slp"
9823 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9824 (any_shiftrt:QI (match_dup 0)
9825 (match_operand:QI 1 "nonmemory_operand" "cI")))
9826 (clobber (reg:CC FLAGS_REG))]
9827 "(optimize_function_for_size_p (cfun)
9828 || !TARGET_PARTIAL_REG_STALL
9829 || (operands[1] == const1_rtx
9832 if (operands[1] == const1_rtx
9833 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9834 return "<shift>{b}\t%0";
9836 return "<shift>{b}\t{%1, %0|%0, %1}";
9838 [(set_attr "type" "ishift1")
9839 (set (attr "length_immediate")
9841 (and (match_operand 1 "const1_operand" "")
9842 (ior (match_test "TARGET_SHIFT1")
9843 (match_test "optimize_function_for_size_p (cfun)")))
9845 (const_string "*")))
9846 (set_attr "mode" "QI")])
9848 ;; This pattern can't accept a variable shift count, since shifts by
9849 ;; zero don't affect the flags. We assume that shifts by constant
9850 ;; zero are optimized away.
9851 (define_insn "*<shift_insn><mode>3_cmp"
9852 [(set (reg FLAGS_REG)
9855 (match_operand:SWI 1 "nonimmediate_operand" "0")
9856 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9858 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9859 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9860 "(optimize_function_for_size_p (cfun)
9861 || !TARGET_PARTIAL_FLAG_REG_STALL
9862 || (operands[2] == const1_rtx
9864 && ix86_match_ccmode (insn, CCGOCmode)
9865 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9867 if (operands[2] == const1_rtx
9868 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9869 return "<shift>{<imodesuffix>}\t%0";
9871 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9873 [(set_attr "type" "ishift")
9874 (set (attr "length_immediate")
9876 (and (match_operand 2 "const1_operand" "")
9877 (ior (match_test "TARGET_SHIFT1")
9878 (match_test "optimize_function_for_size_p (cfun)")))
9880 (const_string "*")))
9881 (set_attr "mode" "<MODE>")])
9883 (define_insn "*<shift_insn>si3_cmp_zext"
9884 [(set (reg FLAGS_REG)
9886 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9887 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9889 (set (match_operand:DI 0 "register_operand" "=r")
9890 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9892 && (optimize_function_for_size_p (cfun)
9893 || !TARGET_PARTIAL_FLAG_REG_STALL
9894 || (operands[2] == const1_rtx
9896 && ix86_match_ccmode (insn, CCGOCmode)
9897 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9899 if (operands[2] == const1_rtx
9900 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9901 return "<shift>{l}\t%k0";
9903 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9905 [(set_attr "type" "ishift")
9906 (set (attr "length_immediate")
9908 (and (match_operand 2 "const1_operand" "")
9909 (ior (match_test "TARGET_SHIFT1")
9910 (match_test "optimize_function_for_size_p (cfun)")))
9912 (const_string "*")))
9913 (set_attr "mode" "SI")])
9915 (define_insn "*<shift_insn><mode>3_cconly"
9916 [(set (reg FLAGS_REG)
9919 (match_operand:SWI 1 "register_operand" "0")
9920 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9922 (clobber (match_scratch:SWI 0 "=<r>"))]
9923 "(optimize_function_for_size_p (cfun)
9924 || !TARGET_PARTIAL_FLAG_REG_STALL
9925 || (operands[2] == const1_rtx
9927 && ix86_match_ccmode (insn, CCGOCmode)"
9929 if (operands[2] == const1_rtx
9930 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9931 return "<shift>{<imodesuffix>}\t%0";
9933 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9935 [(set_attr "type" "ishift")
9936 (set (attr "length_immediate")
9938 (and (match_operand 2 "const1_operand" "")
9939 (ior (match_test "TARGET_SHIFT1")
9940 (match_test "optimize_function_for_size_p (cfun)")))
9942 (const_string "*")))
9943 (set_attr "mode" "<MODE>")])
9945 ;; Rotate instructions
9947 (define_expand "<rotate_insn>ti3"
9948 [(set (match_operand:TI 0 "register_operand" "")
9949 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9950 (match_operand:QI 2 "nonmemory_operand" "")))]
9953 if (const_1_to_63_operand (operands[2], VOIDmode))
9954 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9955 (operands[0], operands[1], operands[2]));
9962 (define_expand "<rotate_insn>di3"
9963 [(set (match_operand:DI 0 "shiftdi_operand" "")
9964 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9965 (match_operand:QI 2 "nonmemory_operand" "")))]
9969 ix86_expand_binary_operator (<CODE>, DImode, operands);
9970 else if (const_1_to_31_operand (operands[2], VOIDmode))
9971 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9972 (operands[0], operands[1], operands[2]));
9979 (define_expand "<rotate_insn><mode>3"
9980 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9981 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9982 (match_operand:QI 2 "nonmemory_operand" "")))]
9984 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9986 ;; Avoid useless masking of count operand.
9987 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9988 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9990 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9993 (match_operand:SI 2 "nonimmediate_operand" "c")
9994 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9995 (clobber (reg:CC FLAGS_REG))]
9996 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9997 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9998 == GET_MODE_BITSIZE (<MODE>mode)-1"
10001 [(parallel [(set (match_dup 0)
10002 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10003 (clobber (reg:CC FLAGS_REG))])]
10005 if (can_create_pseudo_p ())
10006 operands [2] = force_reg (SImode, operands[2]);
10008 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10010 [(set_attr "type" "rotate")
10011 (set_attr "mode" "<MODE>")])
10013 ;; Implement rotation using two double-precision
10014 ;; shift instructions and a scratch register.
10016 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10017 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10018 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10019 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10020 (clobber (reg:CC FLAGS_REG))
10021 (clobber (match_scratch:DWIH 3 "=&r"))]
10025 [(set (match_dup 3) (match_dup 4))
10027 [(set (match_dup 4)
10028 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10029 (lshiftrt:DWIH (match_dup 5)
10030 (minus:QI (match_dup 6) (match_dup 2)))))
10031 (clobber (reg:CC FLAGS_REG))])
10033 [(set (match_dup 5)
10034 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10035 (lshiftrt:DWIH (match_dup 3)
10036 (minus:QI (match_dup 6) (match_dup 2)))))
10037 (clobber (reg:CC FLAGS_REG))])]
10039 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10041 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10044 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10045 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10046 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10047 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10048 (clobber (reg:CC FLAGS_REG))
10049 (clobber (match_scratch:DWIH 3 "=&r"))]
10053 [(set (match_dup 3) (match_dup 4))
10055 [(set (match_dup 4)
10056 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10057 (ashift:DWIH (match_dup 5)
10058 (minus:QI (match_dup 6) (match_dup 2)))))
10059 (clobber (reg:CC FLAGS_REG))])
10061 [(set (match_dup 5)
10062 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10063 (ashift:DWIH (match_dup 3)
10064 (minus:QI (match_dup 6) (match_dup 2)))))
10065 (clobber (reg:CC FLAGS_REG))])]
10067 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10069 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10072 (define_insn "*bmi2_rorx<mode>3_1"
10073 [(set (match_operand:SWI48 0 "register_operand" "=r")
10074 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10075 (match_operand:QI 2 "immediate_operand" "<S>")))]
10077 "rorx\t{%2, %1, %0|%0, %1, %2}"
10078 [(set_attr "type" "rotatex")
10079 (set_attr "mode" "<MODE>")])
10081 (define_insn "*<rotate_insn><mode>3_1"
10082 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10084 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10085 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10086 (clobber (reg:CC FLAGS_REG))]
10087 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10089 switch (get_attr_type (insn))
10095 if (operands[2] == const1_rtx
10096 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10097 return "<rotate>{<imodesuffix>}\t%0";
10099 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10102 [(set_attr "isa" "*,bmi2")
10103 (set_attr "type" "rotate,rotatex")
10104 (set (attr "length_immediate")
10106 (and (eq_attr "type" "rotate")
10107 (and (match_operand 2 "const1_operand" "")
10108 (ior (match_test "TARGET_SHIFT1")
10109 (match_test "optimize_function_for_size_p (cfun)"))))
10111 (const_string "*")))
10112 (set_attr "mode" "<MODE>")])
10114 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10116 [(set (match_operand:SWI48 0 "register_operand" "")
10117 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10118 (match_operand:QI 2 "immediate_operand" "")))
10119 (clobber (reg:CC FLAGS_REG))]
10120 "TARGET_BMI2 && reload_completed"
10121 [(set (match_dup 0)
10122 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10125 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10129 [(set (match_operand:SWI48 0 "register_operand" "")
10130 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10131 (match_operand:QI 2 "immediate_operand" "")))
10132 (clobber (reg:CC FLAGS_REG))]
10133 "TARGET_BMI2 && reload_completed"
10134 [(set (match_dup 0)
10135 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10137 (define_insn "*bmi2_rorxsi3_1_zext"
10138 [(set (match_operand:DI 0 "register_operand" "=r")
10140 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10141 (match_operand:QI 2 "immediate_operand" "I"))))]
10142 "TARGET_64BIT && TARGET_BMI2"
10143 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10144 [(set_attr "type" "rotatex")
10145 (set_attr "mode" "SI")])
10147 (define_insn "*<rotate_insn>si3_1_zext"
10148 [(set (match_operand:DI 0 "register_operand" "=r,r")
10150 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10151 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10152 (clobber (reg:CC FLAGS_REG))]
10153 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10155 switch (get_attr_type (insn))
10161 if (operands[2] == const1_rtx
10162 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10163 return "<rotate>{l}\t%k0";
10165 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10168 [(set_attr "isa" "*,bmi2")
10169 (set_attr "type" "rotate,rotatex")
10170 (set (attr "length_immediate")
10172 (and (eq_attr "type" "rotate")
10173 (and (match_operand 2 "const1_operand" "")
10174 (ior (match_test "TARGET_SHIFT1")
10175 (match_test "optimize_function_for_size_p (cfun)"))))
10177 (const_string "*")))
10178 (set_attr "mode" "SI")])
10180 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10182 [(set (match_operand:DI 0 "register_operand" "")
10184 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10185 (match_operand:QI 2 "immediate_operand" ""))))
10186 (clobber (reg:CC FLAGS_REG))]
10187 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10188 [(set (match_dup 0)
10189 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10192 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10196 [(set (match_operand:DI 0 "register_operand" "")
10198 (rotatert: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))))])
10205 (define_insn "*<rotate_insn><mode>3_1"
10206 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10207 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10208 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10209 (clobber (reg:CC FLAGS_REG))]
10210 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10212 if (operands[2] == const1_rtx
10213 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10214 return "<rotate>{<imodesuffix>}\t%0";
10216 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10218 [(set_attr "type" "rotate")
10219 (set (attr "length_immediate")
10221 (and (match_operand 2 "const1_operand" "")
10222 (ior (match_test "TARGET_SHIFT1")
10223 (match_test "optimize_function_for_size_p (cfun)")))
10225 (const_string "*")))
10226 (set_attr "mode" "<MODE>")])
10228 (define_insn "*<rotate_insn>qi3_1_slp"
10229 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10230 (any_rotate:QI (match_dup 0)
10231 (match_operand:QI 1 "nonmemory_operand" "cI")))
10232 (clobber (reg:CC FLAGS_REG))]
10233 "(optimize_function_for_size_p (cfun)
10234 || !TARGET_PARTIAL_REG_STALL
10235 || (operands[1] == const1_rtx
10236 && TARGET_SHIFT1))"
10238 if (operands[1] == const1_rtx
10239 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10240 return "<rotate>{b}\t%0";
10242 return "<rotate>{b}\t{%1, %0|%0, %1}";
10244 [(set_attr "type" "rotate1")
10245 (set (attr "length_immediate")
10247 (and (match_operand 1 "const1_operand" "")
10248 (ior (match_test "TARGET_SHIFT1")
10249 (match_test "optimize_function_for_size_p (cfun)")))
10251 (const_string "*")))
10252 (set_attr "mode" "QI")])
10255 [(set (match_operand:HI 0 "register_operand" "")
10256 (any_rotate:HI (match_dup 0) (const_int 8)))
10257 (clobber (reg:CC FLAGS_REG))]
10259 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10260 [(parallel [(set (strict_low_part (match_dup 0))
10261 (bswap:HI (match_dup 0)))
10262 (clobber (reg:CC FLAGS_REG))])])
10264 ;; Bit set / bit test instructions
10266 (define_expand "extv"
10267 [(set (match_operand:SI 0 "register_operand" "")
10268 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10269 (match_operand:SI 2 "const8_operand" "")
10270 (match_operand:SI 3 "const8_operand" "")))]
10273 /* Handle extractions from %ah et al. */
10274 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10277 /* From mips.md: extract_bit_field doesn't verify that our source
10278 matches the predicate, so check it again here. */
10279 if (! ext_register_operand (operands[1], VOIDmode))
10283 (define_expand "extzv"
10284 [(set (match_operand:SI 0 "register_operand" "")
10285 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10286 (match_operand:SI 2 "const8_operand" "")
10287 (match_operand:SI 3 "const8_operand" "")))]
10290 /* Handle extractions from %ah et al. */
10291 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10294 /* From mips.md: extract_bit_field doesn't verify that our source
10295 matches the predicate, so check it again here. */
10296 if (! ext_register_operand (operands[1], VOIDmode))
10300 (define_expand "insv"
10301 [(set (zero_extract (match_operand 0 "register_operand" "")
10302 (match_operand 1 "const_int_operand" "")
10303 (match_operand 2 "const_int_operand" ""))
10304 (match_operand 3 "register_operand" ""))]
10307 rtx (*gen_mov_insv_1) (rtx, rtx);
10309 if (ix86_expand_pinsr (operands))
10312 /* Handle insertions to %ah et al. */
10313 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10316 /* From mips.md: insert_bit_field doesn't verify that our source
10317 matches the predicate, so check it again here. */
10318 if (! ext_register_operand (operands[0], VOIDmode))
10321 gen_mov_insv_1 = (TARGET_64BIT
10322 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10324 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10328 ;; %%% bts, btr, btc, bt.
10329 ;; In general these instructions are *slow* when applied to memory,
10330 ;; since they enforce atomic operation. When applied to registers,
10331 ;; it depends on the cpu implementation. They're never faster than
10332 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10333 ;; no point. But in 64-bit, we can't hold the relevant immediates
10334 ;; within the instruction itself, so operating on bits in the high
10335 ;; 32-bits of a register becomes easier.
10337 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10338 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10339 ;; negdf respectively, so they can never be disabled entirely.
10341 (define_insn "*btsq"
10342 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10344 (match_operand:DI 1 "const_0_to_63_operand" ""))
10346 (clobber (reg:CC FLAGS_REG))]
10347 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10348 "bts{q}\t{%1, %0|%0, %1}"
10349 [(set_attr "type" "alu1")
10350 (set_attr "prefix_0f" "1")
10351 (set_attr "mode" "DI")])
10353 (define_insn "*btrq"
10354 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10356 (match_operand:DI 1 "const_0_to_63_operand" ""))
10358 (clobber (reg:CC FLAGS_REG))]
10359 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10360 "btr{q}\t{%1, %0|%0, %1}"
10361 [(set_attr "type" "alu1")
10362 (set_attr "prefix_0f" "1")
10363 (set_attr "mode" "DI")])
10365 (define_insn "*btcq"
10366 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10368 (match_operand:DI 1 "const_0_to_63_operand" ""))
10369 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10370 (clobber (reg:CC FLAGS_REG))]
10371 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10372 "btc{q}\t{%1, %0|%0, %1}"
10373 [(set_attr "type" "alu1")
10374 (set_attr "prefix_0f" "1")
10375 (set_attr "mode" "DI")])
10377 ;; Allow Nocona to avoid these instructions if a register is available.
10380 [(match_scratch:DI 2 "r")
10381 (parallel [(set (zero_extract:DI
10382 (match_operand:DI 0 "register_operand" "")
10384 (match_operand:DI 1 "const_0_to_63_operand" ""))
10386 (clobber (reg:CC FLAGS_REG))])]
10387 "TARGET_64BIT && !TARGET_USE_BT"
10390 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10393 if (HOST_BITS_PER_WIDE_INT >= 64)
10394 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10395 else if (i < HOST_BITS_PER_WIDE_INT)
10396 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10398 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10400 op1 = immed_double_const (lo, hi, DImode);
10403 emit_move_insn (operands[2], op1);
10407 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10412 [(match_scratch:DI 2 "r")
10413 (parallel [(set (zero_extract:DI
10414 (match_operand:DI 0 "register_operand" "")
10416 (match_operand:DI 1 "const_0_to_63_operand" ""))
10418 (clobber (reg:CC FLAGS_REG))])]
10419 "TARGET_64BIT && !TARGET_USE_BT"
10422 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10425 if (HOST_BITS_PER_WIDE_INT >= 64)
10426 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10427 else if (i < HOST_BITS_PER_WIDE_INT)
10428 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10430 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10432 op1 = immed_double_const (~lo, ~hi, DImode);
10435 emit_move_insn (operands[2], op1);
10439 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10444 [(match_scratch:DI 2 "r")
10445 (parallel [(set (zero_extract:DI
10446 (match_operand:DI 0 "register_operand" "")
10448 (match_operand:DI 1 "const_0_to_63_operand" ""))
10449 (not:DI (zero_extract:DI
10450 (match_dup 0) (const_int 1) (match_dup 1))))
10451 (clobber (reg:CC FLAGS_REG))])]
10452 "TARGET_64BIT && !TARGET_USE_BT"
10455 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10458 if (HOST_BITS_PER_WIDE_INT >= 64)
10459 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10460 else if (i < HOST_BITS_PER_WIDE_INT)
10461 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10463 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10465 op1 = immed_double_const (lo, hi, DImode);
10468 emit_move_insn (operands[2], op1);
10472 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10476 (define_insn "*bt<mode>"
10477 [(set (reg:CCC FLAGS_REG)
10479 (zero_extract:SWI48
10480 (match_operand:SWI48 0 "register_operand" "r")
10482 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10484 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10485 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10486 [(set_attr "type" "alu1")
10487 (set_attr "prefix_0f" "1")
10488 (set_attr "mode" "<MODE>")])
10490 ;; Store-flag instructions.
10492 ;; For all sCOND expanders, also expand the compare or test insn that
10493 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10495 (define_insn_and_split "*setcc_di_1"
10496 [(set (match_operand:DI 0 "register_operand" "=q")
10497 (match_operator:DI 1 "ix86_comparison_operator"
10498 [(reg FLAGS_REG) (const_int 0)]))]
10499 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10501 "&& reload_completed"
10502 [(set (match_dup 2) (match_dup 1))
10503 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10505 PUT_MODE (operands[1], QImode);
10506 operands[2] = gen_lowpart (QImode, operands[0]);
10509 (define_insn_and_split "*setcc_si_1_and"
10510 [(set (match_operand:SI 0 "register_operand" "=q")
10511 (match_operator:SI 1 "ix86_comparison_operator"
10512 [(reg FLAGS_REG) (const_int 0)]))
10513 (clobber (reg:CC FLAGS_REG))]
10514 "!TARGET_PARTIAL_REG_STALL
10515 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10517 "&& reload_completed"
10518 [(set (match_dup 2) (match_dup 1))
10519 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10520 (clobber (reg:CC FLAGS_REG))])]
10522 PUT_MODE (operands[1], QImode);
10523 operands[2] = gen_lowpart (QImode, operands[0]);
10526 (define_insn_and_split "*setcc_si_1_movzbl"
10527 [(set (match_operand:SI 0 "register_operand" "=q")
10528 (match_operator:SI 1 "ix86_comparison_operator"
10529 [(reg FLAGS_REG) (const_int 0)]))]
10530 "!TARGET_PARTIAL_REG_STALL
10531 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10533 "&& reload_completed"
10534 [(set (match_dup 2) (match_dup 1))
10535 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10537 PUT_MODE (operands[1], QImode);
10538 operands[2] = gen_lowpart (QImode, operands[0]);
10541 (define_insn "*setcc_qi"
10542 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10543 (match_operator:QI 1 "ix86_comparison_operator"
10544 [(reg FLAGS_REG) (const_int 0)]))]
10547 [(set_attr "type" "setcc")
10548 (set_attr "mode" "QI")])
10550 (define_insn "*setcc_qi_slp"
10551 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10552 (match_operator:QI 1 "ix86_comparison_operator"
10553 [(reg FLAGS_REG) (const_int 0)]))]
10556 [(set_attr "type" "setcc")
10557 (set_attr "mode" "QI")])
10559 ;; In general it is not safe to assume too much about CCmode registers,
10560 ;; so simplify-rtx stops when it sees a second one. Under certain
10561 ;; conditions this is safe on x86, so help combine not create
10568 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10569 (ne:QI (match_operator 1 "ix86_comparison_operator"
10570 [(reg FLAGS_REG) (const_int 0)])
10573 [(set (match_dup 0) (match_dup 1))]
10574 "PUT_MODE (operands[1], QImode);")
10577 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10578 (ne:QI (match_operator 1 "ix86_comparison_operator"
10579 [(reg FLAGS_REG) (const_int 0)])
10582 [(set (match_dup 0) (match_dup 1))]
10583 "PUT_MODE (operands[1], QImode);")
10586 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10587 (eq:QI (match_operator 1 "ix86_comparison_operator"
10588 [(reg FLAGS_REG) (const_int 0)])
10591 [(set (match_dup 0) (match_dup 1))]
10593 rtx new_op1 = copy_rtx (operands[1]);
10594 operands[1] = new_op1;
10595 PUT_MODE (new_op1, QImode);
10596 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10597 GET_MODE (XEXP (new_op1, 0))));
10599 /* Make sure that (a) the CCmode we have for the flags is strong
10600 enough for the reversed compare or (b) we have a valid FP compare. */
10601 if (! ix86_comparison_operator (new_op1, VOIDmode))
10606 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10607 (eq:QI (match_operator 1 "ix86_comparison_operator"
10608 [(reg FLAGS_REG) (const_int 0)])
10611 [(set (match_dup 0) (match_dup 1))]
10613 rtx new_op1 = copy_rtx (operands[1]);
10614 operands[1] = new_op1;
10615 PUT_MODE (new_op1, QImode);
10616 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10617 GET_MODE (XEXP (new_op1, 0))));
10619 /* Make sure that (a) the CCmode we have for the flags is strong
10620 enough for the reversed compare or (b) we have a valid FP compare. */
10621 if (! ix86_comparison_operator (new_op1, VOIDmode))
10625 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10626 ;; subsequent logical operations are used to imitate conditional moves.
10627 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10630 (define_insn "setcc_<mode>_sse"
10631 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10632 (match_operator:MODEF 3 "sse_comparison_operator"
10633 [(match_operand:MODEF 1 "register_operand" "0,x")
10634 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10635 "SSE_FLOAT_MODE_P (<MODE>mode)"
10637 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10638 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10639 [(set_attr "isa" "noavx,avx")
10640 (set_attr "type" "ssecmp")
10641 (set_attr "length_immediate" "1")
10642 (set_attr "prefix" "orig,vex")
10643 (set_attr "mode" "<MODE>")])
10645 ;; Basic conditional jump instructions.
10646 ;; We ignore the overflow flag for signed branch instructions.
10648 (define_insn "*jcc_1"
10650 (if_then_else (match_operator 1 "ix86_comparison_operator"
10651 [(reg FLAGS_REG) (const_int 0)])
10652 (label_ref (match_operand 0 "" ""))
10656 [(set_attr "type" "ibr")
10657 (set_attr "modrm" "0")
10658 (set (attr "length")
10659 (if_then_else (and (ge (minus (match_dup 0) (pc))
10661 (lt (minus (match_dup 0) (pc))
10666 (define_insn "*jcc_2"
10668 (if_then_else (match_operator 1 "ix86_comparison_operator"
10669 [(reg FLAGS_REG) (const_int 0)])
10671 (label_ref (match_operand 0 "" ""))))]
10674 [(set_attr "type" "ibr")
10675 (set_attr "modrm" "0")
10676 (set (attr "length")
10677 (if_then_else (and (ge (minus (match_dup 0) (pc))
10679 (lt (minus (match_dup 0) (pc))
10684 ;; In general it is not safe to assume too much about CCmode registers,
10685 ;; so simplify-rtx stops when it sees a second one. Under certain
10686 ;; conditions this is safe on x86, so help combine not create
10694 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10695 [(reg FLAGS_REG) (const_int 0)])
10697 (label_ref (match_operand 1 "" ""))
10701 (if_then_else (match_dup 0)
10702 (label_ref (match_dup 1))
10704 "PUT_MODE (operands[0], VOIDmode);")
10708 (if_then_else (eq (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))
10719 rtx new_op0 = copy_rtx (operands[0]);
10720 operands[0] = new_op0;
10721 PUT_MODE (new_op0, VOIDmode);
10722 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10723 GET_MODE (XEXP (new_op0, 0))));
10725 /* Make sure that (a) the CCmode we have for the flags is strong
10726 enough for the reversed compare or (b) we have a valid FP compare. */
10727 if (! ix86_comparison_operator (new_op0, VOIDmode))
10731 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10732 ;; pass generates from shift insn with QImode operand. Actually, the mode
10733 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10734 ;; appropriate modulo of the bit offset value.
10736 (define_insn_and_split "*jcc_bt<mode>"
10738 (if_then_else (match_operator 0 "bt_comparison_operator"
10739 [(zero_extract:SWI48
10740 (match_operand:SWI48 1 "register_operand" "r")
10743 (match_operand:QI 2 "register_operand" "r")))
10745 (label_ref (match_operand 3 "" ""))
10747 (clobber (reg:CC FLAGS_REG))]
10748 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10751 [(set (reg:CCC FLAGS_REG)
10753 (zero_extract:SWI48
10759 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10760 (label_ref (match_dup 3))
10763 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10765 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10768 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10769 ;; also for DImode, this is what combine produces.
10770 (define_insn_and_split "*jcc_bt<mode>_mask"
10772 (if_then_else (match_operator 0 "bt_comparison_operator"
10773 [(zero_extract:SWI48
10774 (match_operand:SWI48 1 "register_operand" "r")
10777 (match_operand:SI 2 "register_operand" "r")
10778 (match_operand:SI 3 "const_int_operand" "n")))])
10779 (label_ref (match_operand 4 "" ""))
10781 (clobber (reg:CC FLAGS_REG))]
10782 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10783 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10784 == GET_MODE_BITSIZE (<MODE>mode)-1"
10787 [(set (reg:CCC FLAGS_REG)
10789 (zero_extract:SWI48
10795 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10796 (label_ref (match_dup 4))
10799 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10801 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10804 (define_insn_and_split "*jcc_btsi_1"
10806 (if_then_else (match_operator 0 "bt_comparison_operator"
10809 (match_operand:SI 1 "register_operand" "r")
10810 (match_operand:QI 2 "register_operand" "r"))
10813 (label_ref (match_operand 3 "" ""))
10815 (clobber (reg:CC FLAGS_REG))]
10816 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10819 [(set (reg:CCC FLAGS_REG)
10827 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10828 (label_ref (match_dup 3))
10831 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10833 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10836 ;; avoid useless masking of bit offset operand
10837 (define_insn_and_split "*jcc_btsi_mask_1"
10840 (match_operator 0 "bt_comparison_operator"
10843 (match_operand:SI 1 "register_operand" "r")
10846 (match_operand:SI 2 "register_operand" "r")
10847 (match_operand:SI 3 "const_int_operand" "n")) 0))
10850 (label_ref (match_operand 4 "" ""))
10852 (clobber (reg:CC FLAGS_REG))]
10853 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10854 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10857 [(set (reg:CCC FLAGS_REG)
10865 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10866 (label_ref (match_dup 4))
10868 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10870 ;; Define combination compare-and-branch fp compare instructions to help
10873 (define_insn "*fp_jcc_1_387"
10875 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10876 [(match_operand 1 "register_operand" "f")
10877 (match_operand 2 "nonimmediate_operand" "fm")])
10878 (label_ref (match_operand 3 "" ""))
10880 (clobber (reg:CCFP FPSR_REG))
10881 (clobber (reg:CCFP FLAGS_REG))
10882 (clobber (match_scratch:HI 4 "=a"))]
10884 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10885 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10886 && SELECT_CC_MODE (GET_CODE (operands[0]),
10887 operands[1], operands[2]) == CCFPmode
10891 (define_insn "*fp_jcc_1r_387"
10893 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10894 [(match_operand 1 "register_operand" "f")
10895 (match_operand 2 "nonimmediate_operand" "fm")])
10897 (label_ref (match_operand 3 "" ""))))
10898 (clobber (reg:CCFP FPSR_REG))
10899 (clobber (reg:CCFP FLAGS_REG))
10900 (clobber (match_scratch:HI 4 "=a"))]
10902 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10903 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10904 && SELECT_CC_MODE (GET_CODE (operands[0]),
10905 operands[1], operands[2]) == CCFPmode
10909 (define_insn "*fp_jcc_2_387"
10911 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10912 [(match_operand 1 "register_operand" "f")
10913 (match_operand 2 "register_operand" "f")])
10914 (label_ref (match_operand 3 "" ""))
10916 (clobber (reg:CCFP FPSR_REG))
10917 (clobber (reg:CCFP FLAGS_REG))
10918 (clobber (match_scratch:HI 4 "=a"))]
10919 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10920 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10924 (define_insn "*fp_jcc_2r_387"
10926 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10927 [(match_operand 1 "register_operand" "f")
10928 (match_operand 2 "register_operand" "f")])
10930 (label_ref (match_operand 3 "" ""))))
10931 (clobber (reg:CCFP FPSR_REG))
10932 (clobber (reg:CCFP FLAGS_REG))
10933 (clobber (match_scratch:HI 4 "=a"))]
10934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10935 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10939 (define_insn "*fp_jcc_3_387"
10941 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10942 [(match_operand 1 "register_operand" "f")
10943 (match_operand 2 "const0_operand" "")])
10944 (label_ref (match_operand 3 "" ""))
10946 (clobber (reg:CCFP FPSR_REG))
10947 (clobber (reg:CCFP FLAGS_REG))
10948 (clobber (match_scratch:HI 4 "=a"))]
10949 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10950 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10951 && SELECT_CC_MODE (GET_CODE (operands[0]),
10952 operands[1], operands[2]) == CCFPmode
10958 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10959 [(match_operand 1 "register_operand" "")
10960 (match_operand 2 "nonimmediate_operand" "")])
10961 (match_operand 3 "" "")
10962 (match_operand 4 "" "")))
10963 (clobber (reg:CCFP FPSR_REG))
10964 (clobber (reg:CCFP FLAGS_REG))]
10968 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10969 operands[3], operands[4], NULL_RTX, NULL_RTX);
10975 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10976 [(match_operand 1 "register_operand" "")
10977 (match_operand 2 "general_operand" "")])
10978 (match_operand 3 "" "")
10979 (match_operand 4 "" "")))
10980 (clobber (reg:CCFP FPSR_REG))
10981 (clobber (reg:CCFP FLAGS_REG))
10982 (clobber (match_scratch:HI 5 "=a"))]
10986 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10987 operands[3], operands[4], operands[5], NULL_RTX);
10991 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
10992 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
10993 ;; with a precedence over other operators and is always put in the first
10994 ;; place. Swap condition and operands to match ficom instruction.
10996 (define_insn "*fp_jcc_4_<mode>_387"
10999 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11000 [(match_operator 1 "float_operator"
11001 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11002 (match_operand 3 "register_operand" "f,f")])
11003 (label_ref (match_operand 4 "" ""))
11005 (clobber (reg:CCFP FPSR_REG))
11006 (clobber (reg:CCFP FLAGS_REG))
11007 (clobber (match_scratch:HI 5 "=a,a"))]
11008 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11009 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11010 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11011 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11018 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11019 [(match_operator 1 "float_operator"
11020 [(match_operand:SWI24 2 "memory_operand" "")])
11021 (match_operand 3 "register_operand" "")])
11022 (match_operand 4 "" "")
11023 (match_operand 5 "" "")))
11024 (clobber (reg:CCFP FPSR_REG))
11025 (clobber (reg:CCFP FLAGS_REG))
11026 (clobber (match_scratch:HI 6 "=a"))]
11030 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11032 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11033 operands[3], operands[7],
11034 operands[4], operands[5], operands[6], NULL_RTX);
11038 ;; %%% Kill this when reload knows how to do it.
11042 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11043 [(match_operator 1 "float_operator"
11044 [(match_operand:SWI24 2 "register_operand" "")])
11045 (match_operand 3 "register_operand" "")])
11046 (match_operand 4 "" "")
11047 (match_operand 5 "" "")))
11048 (clobber (reg:CCFP FPSR_REG))
11049 (clobber (reg:CCFP FLAGS_REG))
11050 (clobber (match_scratch:HI 6 "=a"))]
11054 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11055 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11057 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11058 operands[3], operands[7],
11059 operands[4], operands[5], operands[6], operands[2]);
11063 ;; Unconditional and other jump instructions
11065 (define_insn "jump"
11067 (label_ref (match_operand 0 "" "")))]
11070 [(set_attr "type" "ibr")
11071 (set (attr "length")
11072 (if_then_else (and (ge (minus (match_dup 0) (pc))
11074 (lt (minus (match_dup 0) (pc))
11078 (set_attr "modrm" "0")])
11080 (define_expand "indirect_jump"
11081 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11083 (define_insn "*indirect_jump"
11084 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11087 [(set_attr "type" "ibr")
11088 (set_attr "length_immediate" "0")])
11090 (define_expand "tablejump"
11091 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11092 (use (label_ref (match_operand 1 "" "")))])]
11095 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11096 relative. Convert the relative address to an absolute address. */
11100 enum rtx_code code;
11102 /* We can't use @GOTOFF for text labels on VxWorks;
11103 see gotoff_operand. */
11104 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11108 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11110 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11114 op1 = pic_offset_table_rtx;
11119 op0 = pic_offset_table_rtx;
11123 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11126 else if (TARGET_X32)
11127 operands[0] = convert_memory_address (Pmode, operands[0]);
11130 (define_insn "*tablejump_1"
11131 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11132 (use (label_ref (match_operand 1 "" "")))]
11135 [(set_attr "type" "ibr")
11136 (set_attr "length_immediate" "0")])
11138 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11141 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11142 (set (match_operand:QI 1 "register_operand" "")
11143 (match_operator:QI 2 "ix86_comparison_operator"
11144 [(reg FLAGS_REG) (const_int 0)]))
11145 (set (match_operand 3 "q_regs_operand" "")
11146 (zero_extend (match_dup 1)))]
11147 "(peep2_reg_dead_p (3, operands[1])
11148 || operands_match_p (operands[1], operands[3]))
11149 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11150 [(set (match_dup 4) (match_dup 0))
11151 (set (strict_low_part (match_dup 5))
11154 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11155 operands[5] = gen_lowpart (QImode, operands[3]);
11156 ix86_expand_clear (operands[3]);
11159 ;; Similar, but match zero extend with andsi3.
11162 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11163 (set (match_operand:QI 1 "register_operand" "")
11164 (match_operator:QI 2 "ix86_comparison_operator"
11165 [(reg FLAGS_REG) (const_int 0)]))
11166 (parallel [(set (match_operand:SI 3 "q_regs_operand" "")
11167 (and:SI (match_dup 3) (const_int 255)))
11168 (clobber (reg:CC FLAGS_REG))])]
11169 "REGNO (operands[1]) == REGNO (operands[3])
11170 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11171 [(set (match_dup 4) (match_dup 0))
11172 (set (strict_low_part (match_dup 5))
11175 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11176 operands[5] = gen_lowpart (QImode, operands[3]);
11177 ix86_expand_clear (operands[3]);
11180 ;; Call instructions.
11182 ;; The predicates normally associated with named expanders are not properly
11183 ;; checked for calls. This is a bug in the generic code, but it isn't that
11184 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11186 ;; P6 processors will jump to the address after the decrement when %esp
11187 ;; is used as a call operand, so they will execute return address as a code.
11188 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11190 ;; Register constraint for call instruction.
11191 (define_mode_attr c [(SI "l") (DI "r")])
11193 ;; Call subroutine returning no value.
11195 (define_expand "call"
11196 [(call (match_operand:QI 0 "" "")
11197 (match_operand 1 "" ""))
11198 (use (match_operand 2 "" ""))]
11201 ix86_expand_call (NULL, operands[0], operands[1],
11202 operands[2], NULL, false);
11206 (define_expand "sibcall"
11207 [(call (match_operand:QI 0 "" "")
11208 (match_operand 1 "" ""))
11209 (use (match_operand 2 "" ""))]
11212 ix86_expand_call (NULL, operands[0], operands[1],
11213 operands[2], NULL, true);
11217 (define_insn_and_split "*call_vzeroupper"
11218 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11219 (match_operand 1 "" ""))
11220 (unspec [(match_operand 2 "const_int_operand" "")]
11221 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11222 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11224 "&& reload_completed"
11226 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11227 [(set_attr "type" "call")])
11229 (define_insn "*call"
11230 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11231 (match_operand 1 "" ""))]
11232 "!SIBLING_CALL_P (insn)"
11233 "* return ix86_output_call_insn (insn, operands[0]);"
11234 [(set_attr "type" "call")])
11236 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11237 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11238 (match_operand 1 "" ""))
11239 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11240 (clobber (reg:TI XMM6_REG))
11241 (clobber (reg:TI XMM7_REG))
11242 (clobber (reg:TI XMM8_REG))
11243 (clobber (reg:TI XMM9_REG))
11244 (clobber (reg:TI XMM10_REG))
11245 (clobber (reg:TI XMM11_REG))
11246 (clobber (reg:TI XMM12_REG))
11247 (clobber (reg:TI XMM13_REG))
11248 (clobber (reg:TI XMM14_REG))
11249 (clobber (reg:TI XMM15_REG))
11250 (clobber (reg:DI SI_REG))
11251 (clobber (reg:DI DI_REG))
11252 (unspec [(match_operand 2 "const_int_operand" "")]
11253 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11254 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11256 "&& reload_completed"
11258 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11259 [(set_attr "type" "call")])
11261 (define_insn "*call_rex64_ms_sysv"
11262 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11263 (match_operand 1 "" ""))
11264 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11265 (clobber (reg:TI XMM6_REG))
11266 (clobber (reg:TI XMM7_REG))
11267 (clobber (reg:TI XMM8_REG))
11268 (clobber (reg:TI XMM9_REG))
11269 (clobber (reg:TI XMM10_REG))
11270 (clobber (reg:TI XMM11_REG))
11271 (clobber (reg:TI XMM12_REG))
11272 (clobber (reg:TI XMM13_REG))
11273 (clobber (reg:TI XMM14_REG))
11274 (clobber (reg:TI XMM15_REG))
11275 (clobber (reg:DI SI_REG))
11276 (clobber (reg:DI DI_REG))]
11277 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11278 "* return ix86_output_call_insn (insn, operands[0]);"
11279 [(set_attr "type" "call")])
11281 (define_insn_and_split "*sibcall_vzeroupper"
11282 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11283 (match_operand 1 "" ""))
11284 (unspec [(match_operand 2 "const_int_operand" "")]
11285 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11286 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11288 "&& reload_completed"
11290 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11291 [(set_attr "type" "call")])
11293 (define_insn "*sibcall"
11294 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11295 (match_operand 1 "" ""))]
11296 "SIBLING_CALL_P (insn)"
11297 "* return ix86_output_call_insn (insn, operands[0]);"
11298 [(set_attr "type" "call")])
11300 (define_expand "call_pop"
11301 [(parallel [(call (match_operand:QI 0 "" "")
11302 (match_operand:SI 1 "" ""))
11303 (set (reg:SI SP_REG)
11304 (plus:SI (reg:SI SP_REG)
11305 (match_operand:SI 3 "" "")))])]
11308 ix86_expand_call (NULL, operands[0], operands[1],
11309 operands[2], operands[3], false);
11313 (define_insn_and_split "*call_pop_vzeroupper"
11314 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11315 (match_operand:SI 1 "" ""))
11316 (set (reg:SI SP_REG)
11317 (plus:SI (reg:SI SP_REG)
11318 (match_operand:SI 2 "immediate_operand" "i")))
11319 (unspec [(match_operand 3 "const_int_operand" "")]
11320 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11321 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11323 "&& reload_completed"
11325 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11326 [(set_attr "type" "call")])
11328 (define_insn "*call_pop"
11329 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11330 (match_operand 1 "" ""))
11331 (set (reg:SI SP_REG)
11332 (plus:SI (reg:SI SP_REG)
11333 (match_operand:SI 2 "immediate_operand" "i")))]
11334 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11335 "* return ix86_output_call_insn (insn, operands[0]);"
11336 [(set_attr "type" "call")])
11338 (define_insn_and_split "*sibcall_pop_vzeroupper"
11339 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11340 (match_operand 1 "" ""))
11341 (set (reg:SI SP_REG)
11342 (plus:SI (reg:SI SP_REG)
11343 (match_operand:SI 2 "immediate_operand" "i")))
11344 (unspec [(match_operand 3 "const_int_operand" "")]
11345 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11346 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11348 "&& reload_completed"
11350 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11351 [(set_attr "type" "call")])
11353 (define_insn "*sibcall_pop"
11354 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11355 (match_operand 1 "" ""))
11356 (set (reg:SI SP_REG)
11357 (plus:SI (reg:SI SP_REG)
11358 (match_operand:SI 2 "immediate_operand" "i")))]
11359 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11360 "* return ix86_output_call_insn (insn, operands[0]);"
11361 [(set_attr "type" "call")])
11363 ;; Call subroutine, returning value in operand 0
11365 (define_expand "call_value"
11366 [(set (match_operand 0 "" "")
11367 (call (match_operand:QI 1 "" "")
11368 (match_operand 2 "" "")))
11369 (use (match_operand 3 "" ""))]
11372 ix86_expand_call (operands[0], operands[1], operands[2],
11373 operands[3], NULL, false);
11377 (define_expand "sibcall_value"
11378 [(set (match_operand 0 "" "")
11379 (call (match_operand:QI 1 "" "")
11380 (match_operand 2 "" "")))
11381 (use (match_operand 3 "" ""))]
11384 ix86_expand_call (operands[0], operands[1], operands[2],
11385 operands[3], NULL, true);
11389 (define_insn_and_split "*call_value_vzeroupper"
11390 [(set (match_operand 0 "" "")
11391 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11392 (match_operand 2 "" "")))
11393 (unspec [(match_operand 3 "const_int_operand" "")]
11394 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11395 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11397 "&& reload_completed"
11399 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11400 [(set_attr "type" "callv")])
11402 (define_insn "*call_value"
11403 [(set (match_operand 0 "" "")
11404 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11405 (match_operand 2 "" "")))]
11406 "!SIBLING_CALL_P (insn)"
11407 "* return ix86_output_call_insn (insn, operands[1]);"
11408 [(set_attr "type" "callv")])
11410 (define_insn_and_split "*sibcall_value_vzeroupper"
11411 [(set (match_operand 0 "" "")
11412 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11413 (match_operand 2 "" "")))
11414 (unspec [(match_operand 3 "const_int_operand" "")]
11415 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11416 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11418 "&& reload_completed"
11420 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11421 [(set_attr "type" "callv")])
11423 (define_insn "*sibcall_value"
11424 [(set (match_operand 0 "" "")
11425 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11426 (match_operand 2 "" "")))]
11427 "SIBLING_CALL_P (insn)"
11428 "* return ix86_output_call_insn (insn, operands[1]);"
11429 [(set_attr "type" "callv")])
11431 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11432 [(set (match_operand 0 "" "")
11433 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11434 (match_operand 2 "" "")))
11435 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11436 (clobber (reg:TI XMM6_REG))
11437 (clobber (reg:TI XMM7_REG))
11438 (clobber (reg:TI XMM8_REG))
11439 (clobber (reg:TI XMM9_REG))
11440 (clobber (reg:TI XMM10_REG))
11441 (clobber (reg:TI XMM11_REG))
11442 (clobber (reg:TI XMM12_REG))
11443 (clobber (reg:TI XMM13_REG))
11444 (clobber (reg:TI XMM14_REG))
11445 (clobber (reg:TI XMM15_REG))
11446 (clobber (reg:DI SI_REG))
11447 (clobber (reg:DI DI_REG))
11448 (unspec [(match_operand 3 "const_int_operand" "")]
11449 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11450 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11452 "&& reload_completed"
11454 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11455 [(set_attr "type" "callv")])
11457 (define_insn "*call_value_rex64_ms_sysv"
11458 [(set (match_operand 0 "" "")
11459 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11460 (match_operand 2 "" "")))
11461 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11462 (clobber (reg:TI XMM6_REG))
11463 (clobber (reg:TI XMM7_REG))
11464 (clobber (reg:TI XMM8_REG))
11465 (clobber (reg:TI XMM9_REG))
11466 (clobber (reg:TI XMM10_REG))
11467 (clobber (reg:TI XMM11_REG))
11468 (clobber (reg:TI XMM12_REG))
11469 (clobber (reg:TI XMM13_REG))
11470 (clobber (reg:TI XMM14_REG))
11471 (clobber (reg:TI XMM15_REG))
11472 (clobber (reg:DI SI_REG))
11473 (clobber (reg:DI DI_REG))]
11474 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11475 "* return ix86_output_call_insn (insn, operands[1]);"
11476 [(set_attr "type" "callv")])
11478 (define_expand "call_value_pop"
11479 [(parallel [(set (match_operand 0 "" "")
11480 (call (match_operand:QI 1 "" "")
11481 (match_operand:SI 2 "" "")))
11482 (set (reg:SI SP_REG)
11483 (plus:SI (reg:SI SP_REG)
11484 (match_operand:SI 4 "" "")))])]
11487 ix86_expand_call (operands[0], operands[1], operands[2],
11488 operands[3], operands[4], false);
11492 (define_insn_and_split "*call_value_pop_vzeroupper"
11493 [(set (match_operand 0 "" "")
11494 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11495 (match_operand 2 "" "")))
11496 (set (reg:SI SP_REG)
11497 (plus:SI (reg:SI SP_REG)
11498 (match_operand:SI 3 "immediate_operand" "i")))
11499 (unspec [(match_operand 4 "const_int_operand" "")]
11500 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11501 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11503 "&& reload_completed"
11505 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11506 [(set_attr "type" "callv")])
11508 (define_insn "*call_value_pop"
11509 [(set (match_operand 0 "" "")
11510 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11511 (match_operand 2 "" "")))
11512 (set (reg:SI SP_REG)
11513 (plus:SI (reg:SI SP_REG)
11514 (match_operand:SI 3 "immediate_operand" "i")))]
11515 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11516 "* return ix86_output_call_insn (insn, operands[1]);"
11517 [(set_attr "type" "callv")])
11519 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11520 [(set (match_operand 0 "" "")
11521 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11522 (match_operand 2 "" "")))
11523 (set (reg:SI SP_REG)
11524 (plus:SI (reg:SI SP_REG)
11525 (match_operand:SI 3 "immediate_operand" "i")))
11526 (unspec [(match_operand 4 "const_int_operand" "")]
11527 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11528 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11530 "&& reload_completed"
11532 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11533 [(set_attr "type" "callv")])
11535 (define_insn "*sibcall_value_pop"
11536 [(set (match_operand 0 "" "")
11537 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11538 (match_operand 2 "" "")))
11539 (set (reg:SI SP_REG)
11540 (plus:SI (reg:SI SP_REG)
11541 (match_operand:SI 3 "immediate_operand" "i")))]
11542 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11543 "* return ix86_output_call_insn (insn, operands[1]);"
11544 [(set_attr "type" "callv")])
11546 ;; Call subroutine returning any type.
11548 (define_expand "untyped_call"
11549 [(parallel [(call (match_operand 0 "" "")
11551 (match_operand 1 "" "")
11552 (match_operand 2 "" "")])]
11557 /* In order to give reg-stack an easier job in validating two
11558 coprocessor registers as containing a possible return value,
11559 simply pretend the untyped call returns a complex long double
11562 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11563 and should have the default ABI. */
11565 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11566 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11567 operands[0], const0_rtx,
11568 GEN_INT ((TARGET_64BIT
11569 ? (ix86_abi == SYSV_ABI
11570 ? X86_64_SSE_REGPARM_MAX
11571 : X86_64_MS_SSE_REGPARM_MAX)
11572 : X86_32_SSE_REGPARM_MAX)
11576 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11578 rtx set = XVECEXP (operands[2], 0, i);
11579 emit_move_insn (SET_DEST (set), SET_SRC (set));
11582 /* The optimizer does not know that the call sets the function value
11583 registers we stored in the result block. We avoid problems by
11584 claiming that all hard registers are used and clobbered at this
11586 emit_insn (gen_blockage ());
11591 ;; Prologue and epilogue instructions
11593 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11594 ;; all of memory. This blocks insns from being moved across this point.
11596 (define_insn "blockage"
11597 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11600 [(set_attr "length" "0")])
11602 ;; Do not schedule instructions accessing memory across this point.
11604 (define_expand "memory_blockage"
11605 [(set (match_dup 0)
11606 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11609 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11610 MEM_VOLATILE_P (operands[0]) = 1;
11613 (define_insn "*memory_blockage"
11614 [(set (match_operand:BLK 0 "" "")
11615 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11618 [(set_attr "length" "0")])
11620 ;; As USE insns aren't meaningful after reload, this is used instead
11621 ;; to prevent deleting instructions setting registers for PIC code
11622 (define_insn "prologue_use"
11623 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11626 [(set_attr "length" "0")])
11628 ;; Insn emitted into the body of a function to return from a function.
11629 ;; This is only done if the function's epilogue is known to be simple.
11630 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11632 (define_expand "return"
11634 "ix86_can_use_return_insn_p ()"
11636 ix86_maybe_emit_epilogue_vzeroupper ();
11637 if (crtl->args.pops_args)
11639 rtx popc = GEN_INT (crtl->args.pops_args);
11640 emit_jump_insn (gen_simple_return_pop_internal (popc));
11645 ;; We need to disable this for TARGET_SEH, as otherwise
11646 ;; shrink-wrapped prologue gets enabled too. This might exceed
11647 ;; the maximum size of prologue in unwind information.
11649 (define_expand "simple_return"
11653 ix86_maybe_emit_epilogue_vzeroupper ();
11654 if (crtl->args.pops_args)
11656 rtx popc = GEN_INT (crtl->args.pops_args);
11657 emit_jump_insn (gen_simple_return_pop_internal (popc));
11662 (define_insn "simple_return_internal"
11666 [(set_attr "length" "1")
11667 (set_attr "atom_unit" "jeu")
11668 (set_attr "length_immediate" "0")
11669 (set_attr "modrm" "0")])
11671 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11672 ;; instruction Athlon and K8 have.
11674 (define_insn "simple_return_internal_long"
11676 (unspec [(const_int 0)] UNSPEC_REP)]
11679 [(set_attr "length" "2")
11680 (set_attr "atom_unit" "jeu")
11681 (set_attr "length_immediate" "0")
11682 (set_attr "prefix_rep" "1")
11683 (set_attr "modrm" "0")])
11685 (define_insn "simple_return_pop_internal"
11687 (use (match_operand:SI 0 "const_int_operand" ""))]
11690 [(set_attr "length" "3")
11691 (set_attr "atom_unit" "jeu")
11692 (set_attr "length_immediate" "2")
11693 (set_attr "modrm" "0")])
11695 (define_insn "simple_return_indirect_internal"
11697 (use (match_operand:SI 0 "register_operand" "r"))]
11700 [(set_attr "type" "ibr")
11701 (set_attr "length_immediate" "0")])
11707 [(set_attr "length" "1")
11708 (set_attr "length_immediate" "0")
11709 (set_attr "modrm" "0")])
11711 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11712 (define_insn "nops"
11713 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11717 int num = INTVAL (operands[0]);
11719 gcc_assert (num >= 1 && num <= 8);
11722 fputs ("\tnop\n", asm_out_file);
11726 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11727 (set_attr "length_immediate" "0")
11728 (set_attr "modrm" "0")])
11730 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11731 ;; branch prediction penalty for the third jump in a 16-byte
11735 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11738 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11739 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11741 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11742 The align insn is used to avoid 3 jump instructions in the row to improve
11743 branch prediction and the benefits hardly outweigh the cost of extra 8
11744 nops on the average inserted by full alignment pseudo operation. */
11748 [(set_attr "length" "16")])
11750 (define_expand "prologue"
11753 "ix86_expand_prologue (); DONE;")
11755 (define_insn "set_got"
11756 [(set (match_operand:SI 0 "register_operand" "=r")
11757 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11758 (clobber (reg:CC FLAGS_REG))]
11760 "* return output_set_got (operands[0], NULL_RTX);"
11761 [(set_attr "type" "multi")
11762 (set_attr "length" "12")])
11764 (define_insn "set_got_labelled"
11765 [(set (match_operand:SI 0 "register_operand" "=r")
11766 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11768 (clobber (reg:CC FLAGS_REG))]
11770 "* return output_set_got (operands[0], operands[1]);"
11771 [(set_attr "type" "multi")
11772 (set_attr "length" "12")])
11774 (define_insn "set_got_rex64"
11775 [(set (match_operand:DI 0 "register_operand" "=r")
11776 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11778 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11779 [(set_attr "type" "lea")
11780 (set_attr "length_address" "4")
11781 (set_attr "mode" "DI")])
11783 (define_insn "set_rip_rex64"
11784 [(set (match_operand:DI 0 "register_operand" "=r")
11785 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11787 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11788 [(set_attr "type" "lea")
11789 (set_attr "length_address" "4")
11790 (set_attr "mode" "DI")])
11792 (define_insn "set_got_offset_rex64"
11793 [(set (match_operand:DI 0 "register_operand" "=r")
11795 [(label_ref (match_operand 1 "" ""))]
11796 UNSPEC_SET_GOT_OFFSET))]
11798 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11799 [(set_attr "type" "imov")
11800 (set_attr "length_immediate" "0")
11801 (set_attr "length_address" "8")
11802 (set_attr "mode" "DI")])
11804 (define_expand "epilogue"
11807 "ix86_expand_epilogue (1); DONE;")
11809 (define_expand "sibcall_epilogue"
11812 "ix86_expand_epilogue (0); DONE;")
11814 (define_expand "eh_return"
11815 [(use (match_operand 0 "register_operand" ""))]
11818 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11820 /* Tricky bit: we write the address of the handler to which we will
11821 be returning into someone else's stack frame, one word below the
11822 stack address we wish to restore. */
11823 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11824 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11825 tmp = gen_rtx_MEM (Pmode, tmp);
11826 emit_move_insn (tmp, ra);
11828 emit_jump_insn (gen_eh_return_internal ());
11833 (define_insn_and_split "eh_return_internal"
11837 "epilogue_completed"
11839 "ix86_expand_epilogue (2); DONE;")
11841 (define_insn "leave"
11842 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11843 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11844 (clobber (mem:BLK (scratch)))]
11847 [(set_attr "type" "leave")])
11849 (define_insn "leave_rex64"
11850 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11851 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11852 (clobber (mem:BLK (scratch)))]
11855 [(set_attr "type" "leave")])
11857 ;; Handle -fsplit-stack.
11859 (define_expand "split_stack_prologue"
11863 ix86_expand_split_stack_prologue ();
11867 ;; In order to support the call/return predictor, we use a return
11868 ;; instruction which the middle-end doesn't see.
11869 (define_insn "split_stack_return"
11870 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11871 UNSPECV_SPLIT_STACK_RETURN)]
11874 if (operands[0] == const0_rtx)
11879 [(set_attr "atom_unit" "jeu")
11880 (set_attr "modrm" "0")
11881 (set (attr "length")
11882 (if_then_else (match_operand:SI 0 "const0_operand" "")
11885 (set (attr "length_immediate")
11886 (if_then_else (match_operand:SI 0 "const0_operand" "")
11890 ;; If there are operand 0 bytes available on the stack, jump to
11893 (define_expand "split_stack_space_check"
11894 [(set (pc) (if_then_else
11895 (ltu (minus (reg SP_REG)
11896 (match_operand 0 "register_operand" ""))
11897 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11898 (label_ref (match_operand 1 "" ""))
11902 rtx reg, size, limit;
11904 reg = gen_reg_rtx (Pmode);
11905 size = force_reg (Pmode, operands[0]);
11906 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11907 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11908 UNSPEC_STACK_CHECK);
11909 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11910 ix86_expand_branch (GEU, reg, limit, operands[1]);
11915 ;; Bit manipulation instructions.
11917 (define_expand "ffs<mode>2"
11918 [(set (match_dup 2) (const_int -1))
11919 (parallel [(set (reg:CCZ FLAGS_REG)
11921 (match_operand:SWI48 1 "nonimmediate_operand" "")
11923 (set (match_operand:SWI48 0 "register_operand" "")
11924 (ctz:SWI48 (match_dup 1)))])
11925 (set (match_dup 0) (if_then_else:SWI48
11926 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11929 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11930 (clobber (reg:CC FLAGS_REG))])]
11933 if (<MODE>mode == SImode && !TARGET_CMOVE)
11935 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11938 operands[2] = gen_reg_rtx (<MODE>mode);
11941 (define_insn_and_split "ffssi2_no_cmove"
11942 [(set (match_operand:SI 0 "register_operand" "=r")
11943 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11944 (clobber (match_scratch:SI 2 "=&q"))
11945 (clobber (reg:CC FLAGS_REG))]
11948 "&& reload_completed"
11949 [(parallel [(set (reg:CCZ FLAGS_REG)
11950 (compare:CCZ (match_dup 1) (const_int 0)))
11951 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11952 (set (strict_low_part (match_dup 3))
11953 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11954 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11955 (clobber (reg:CC FLAGS_REG))])
11956 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11957 (clobber (reg:CC FLAGS_REG))])
11958 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11959 (clobber (reg:CC FLAGS_REG))])]
11961 operands[3] = gen_lowpart (QImode, operands[2]);
11962 ix86_expand_clear (operands[2]);
11965 (define_insn "*ffs<mode>_1"
11966 [(set (reg:CCZ FLAGS_REG)
11967 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11969 (set (match_operand:SWI48 0 "register_operand" "=r")
11970 (ctz:SWI48 (match_dup 1)))]
11972 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11973 [(set_attr "type" "alu1")
11974 (set_attr "prefix_0f" "1")
11975 (set_attr "mode" "<MODE>")])
11977 (define_insn "ctz<mode>2"
11978 [(set (match_operand:SWI248 0 "register_operand" "=r")
11979 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11980 (clobber (reg:CC FLAGS_REG))]
11984 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
11986 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
11988 [(set_attr "type" "alu1")
11989 (set_attr "prefix_0f" "1")
11990 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
11991 (set_attr "mode" "<MODE>")])
11993 (define_expand "clz<mode>2"
11995 [(set (match_operand:SWI248 0 "register_operand" "")
11998 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
11999 (clobber (reg:CC FLAGS_REG))])
12001 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12002 (clobber (reg:CC FLAGS_REG))])]
12007 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12010 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12013 (define_insn "clz<mode>2_lzcnt"
12014 [(set (match_operand:SWI248 0 "register_operand" "=r")
12015 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12016 (clobber (reg:CC FLAGS_REG))]
12018 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12019 [(set_attr "prefix_rep" "1")
12020 (set_attr "type" "bitmanip")
12021 (set_attr "mode" "<MODE>")])
12023 ;; BMI instructions.
12024 (define_insn "*bmi_andn_<mode>"
12025 [(set (match_operand:SWI48 0 "register_operand" "=r")
12028 (match_operand:SWI48 1 "register_operand" "r"))
12029 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12030 (clobber (reg:CC FLAGS_REG))]
12032 "andn\t{%2, %1, %0|%0, %1, %2}"
12033 [(set_attr "type" "bitmanip")
12034 (set_attr "mode" "<MODE>")])
12036 (define_insn "bmi_bextr_<mode>"
12037 [(set (match_operand:SWI48 0 "register_operand" "=r")
12038 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12039 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12041 (clobber (reg:CC FLAGS_REG))]
12043 "bextr\t{%2, %1, %0|%0, %1, %2}"
12044 [(set_attr "type" "bitmanip")
12045 (set_attr "mode" "<MODE>")])
12047 (define_insn "*bmi_blsi_<mode>"
12048 [(set (match_operand:SWI48 0 "register_operand" "=r")
12051 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12053 (clobber (reg:CC FLAGS_REG))]
12055 "blsi\t{%1, %0|%0, %1}"
12056 [(set_attr "type" "bitmanip")
12057 (set_attr "mode" "<MODE>")])
12059 (define_insn "*bmi_blsmsk_<mode>"
12060 [(set (match_operand:SWI48 0 "register_operand" "=r")
12063 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12066 (clobber (reg:CC FLAGS_REG))]
12068 "blsmsk\t{%1, %0|%0, %1}"
12069 [(set_attr "type" "bitmanip")
12070 (set_attr "mode" "<MODE>")])
12072 (define_insn "*bmi_blsr_<mode>"
12073 [(set (match_operand:SWI48 0 "register_operand" "=r")
12076 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12079 (clobber (reg:CC FLAGS_REG))]
12081 "blsr\t{%1, %0|%0, %1}"
12082 [(set_attr "type" "bitmanip")
12083 (set_attr "mode" "<MODE>")])
12085 ;; BMI2 instructions.
12086 (define_insn "bmi2_bzhi_<mode>3"
12087 [(set (match_operand:SWI48 0 "register_operand" "=r")
12088 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12089 (lshiftrt:SWI48 (const_int -1)
12090 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12091 (clobber (reg:CC FLAGS_REG))]
12093 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12094 [(set_attr "type" "bitmanip")
12095 (set_attr "prefix" "vex")
12096 (set_attr "mode" "<MODE>")])
12098 (define_insn "bmi2_pdep_<mode>3"
12099 [(set (match_operand:SWI48 0 "register_operand" "=r")
12100 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12101 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12104 "pdep\t{%2, %1, %0|%0, %1, %2}"
12105 [(set_attr "type" "bitmanip")
12106 (set_attr "prefix" "vex")
12107 (set_attr "mode" "<MODE>")])
12109 (define_insn "bmi2_pext_<mode>3"
12110 [(set (match_operand:SWI48 0 "register_operand" "=r")
12111 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12112 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12115 "pext\t{%2, %1, %0|%0, %1, %2}"
12116 [(set_attr "type" "bitmanip")
12117 (set_attr "prefix" "vex")
12118 (set_attr "mode" "<MODE>")])
12120 ;; TBM instructions.
12121 (define_insn "tbm_bextri_<mode>"
12122 [(set (match_operand:SWI48 0 "register_operand" "=r")
12123 (zero_extract:SWI48
12124 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12125 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12126 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12127 (clobber (reg:CC FLAGS_REG))]
12130 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12131 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12133 [(set_attr "type" "bitmanip")
12134 (set_attr "mode" "<MODE>")])
12136 (define_insn "*tbm_blcfill_<mode>"
12137 [(set (match_operand:SWI48 0 "register_operand" "=r")
12140 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12143 (clobber (reg:CC FLAGS_REG))]
12145 "blcfill\t{%1, %0|%0, %1}"
12146 [(set_attr "type" "bitmanip")
12147 (set_attr "mode" "<MODE>")])
12149 (define_insn "*tbm_blci_<mode>"
12150 [(set (match_operand:SWI48 0 "register_operand" "=r")
12154 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12157 (clobber (reg:CC FLAGS_REG))]
12159 "blci\t{%1, %0|%0, %1}"
12160 [(set_attr "type" "bitmanip")
12161 (set_attr "mode" "<MODE>")])
12163 (define_insn "*tbm_blcic_<mode>"
12164 [(set (match_operand:SWI48 0 "register_operand" "=r")
12167 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12171 (clobber (reg:CC FLAGS_REG))]
12173 "blcic\t{%1, %0|%0, %1}"
12174 [(set_attr "type" "bitmanip")
12175 (set_attr "mode" "<MODE>")])
12177 (define_insn "*tbm_blcmsk_<mode>"
12178 [(set (match_operand:SWI48 0 "register_operand" "=r")
12181 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12184 (clobber (reg:CC FLAGS_REG))]
12186 "blcmsk\t{%1, %0|%0, %1}"
12187 [(set_attr "type" "bitmanip")
12188 (set_attr "mode" "<MODE>")])
12190 (define_insn "*tbm_blcs_<mode>"
12191 [(set (match_operand:SWI48 0 "register_operand" "=r")
12194 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12197 (clobber (reg:CC FLAGS_REG))]
12199 "blcs\t{%1, %0|%0, %1}"
12200 [(set_attr "type" "bitmanip")
12201 (set_attr "mode" "<MODE>")])
12203 (define_insn "*tbm_blsfill_<mode>"
12204 [(set (match_operand:SWI48 0 "register_operand" "=r")
12207 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12210 (clobber (reg:CC FLAGS_REG))]
12212 "blsfill\t{%1, %0|%0, %1}"
12213 [(set_attr "type" "bitmanip")
12214 (set_attr "mode" "<MODE>")])
12216 (define_insn "*tbm_blsic_<mode>"
12217 [(set (match_operand:SWI48 0 "register_operand" "=r")
12220 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12224 (clobber (reg:CC FLAGS_REG))]
12226 "blsic\t{%1, %0|%0, %1}"
12227 [(set_attr "type" "bitmanip")
12228 (set_attr "mode" "<MODE>")])
12230 (define_insn "*tbm_t1mskc_<mode>"
12231 [(set (match_operand:SWI48 0 "register_operand" "=r")
12234 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12238 (clobber (reg:CC FLAGS_REG))]
12240 "t1mskc\t{%1, %0|%0, %1}"
12241 [(set_attr "type" "bitmanip")
12242 (set_attr "mode" "<MODE>")])
12244 (define_insn "*tbm_tzmsk_<mode>"
12245 [(set (match_operand:SWI48 0 "register_operand" "=r")
12248 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12252 (clobber (reg:CC FLAGS_REG))]
12254 "tzmsk\t{%1, %0|%0, %1}"
12255 [(set_attr "type" "bitmanip")
12256 (set_attr "mode" "<MODE>")])
12258 (define_insn "bsr_rex64"
12259 [(set (match_operand:DI 0 "register_operand" "=r")
12260 (minus:DI (const_int 63)
12261 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12262 (clobber (reg:CC FLAGS_REG))]
12264 "bsr{q}\t{%1, %0|%0, %1}"
12265 [(set_attr "type" "alu1")
12266 (set_attr "prefix_0f" "1")
12267 (set_attr "mode" "DI")])
12270 [(set (match_operand:SI 0 "register_operand" "=r")
12271 (minus:SI (const_int 31)
12272 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12273 (clobber (reg:CC FLAGS_REG))]
12275 "bsr{l}\t{%1, %0|%0, %1}"
12276 [(set_attr "type" "alu1")
12277 (set_attr "prefix_0f" "1")
12278 (set_attr "mode" "SI")])
12280 (define_insn "*bsrhi"
12281 [(set (match_operand:HI 0 "register_operand" "=r")
12282 (minus:HI (const_int 15)
12283 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12284 (clobber (reg:CC FLAGS_REG))]
12286 "bsr{w}\t{%1, %0|%0, %1}"
12287 [(set_attr "type" "alu1")
12288 (set_attr "prefix_0f" "1")
12289 (set_attr "mode" "HI")])
12291 (define_insn "popcount<mode>2"
12292 [(set (match_operand:SWI248 0 "register_operand" "=r")
12294 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12295 (clobber (reg:CC FLAGS_REG))]
12299 return "popcnt\t{%1, %0|%0, %1}";
12301 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12304 [(set_attr "prefix_rep" "1")
12305 (set_attr "type" "bitmanip")
12306 (set_attr "mode" "<MODE>")])
12308 (define_insn "*popcount<mode>2_cmp"
12309 [(set (reg FLAGS_REG)
12312 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12314 (set (match_operand:SWI248 0 "register_operand" "=r")
12315 (popcount:SWI248 (match_dup 1)))]
12316 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12319 return "popcnt\t{%1, %0|%0, %1}";
12321 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12324 [(set_attr "prefix_rep" "1")
12325 (set_attr "type" "bitmanip")
12326 (set_attr "mode" "<MODE>")])
12328 (define_insn "*popcountsi2_cmp_zext"
12329 [(set (reg FLAGS_REG)
12331 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12333 (set (match_operand:DI 0 "register_operand" "=r")
12334 (zero_extend:DI(popcount:SI (match_dup 1))))]
12335 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12338 return "popcnt\t{%1, %0|%0, %1}";
12340 return "popcnt{l}\t{%1, %0|%0, %1}";
12343 [(set_attr "prefix_rep" "1")
12344 (set_attr "type" "bitmanip")
12345 (set_attr "mode" "SI")])
12347 (define_expand "bswap<mode>2"
12348 [(set (match_operand:SWI48 0 "register_operand" "")
12349 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12352 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12354 rtx x = operands[0];
12356 emit_move_insn (x, operands[1]);
12357 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12358 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12359 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12364 (define_insn "*bswap<mode>2_movbe"
12365 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12366 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12368 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12371 movbe\t{%1, %0|%0, %1}
12372 movbe\t{%1, %0|%0, %1}"
12373 [(set_attr "type" "bitmanip,imov,imov")
12374 (set_attr "modrm" "0,1,1")
12375 (set_attr "prefix_0f" "*,1,1")
12376 (set_attr "prefix_extra" "*,1,1")
12377 (set_attr "mode" "<MODE>")])
12379 (define_insn "*bswap<mode>2_1"
12380 [(set (match_operand:SWI48 0 "register_operand" "=r")
12381 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12384 [(set_attr "type" "bitmanip")
12385 (set_attr "modrm" "0")
12386 (set_attr "mode" "<MODE>")])
12388 (define_insn "*bswaphi_lowpart_1"
12389 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12390 (bswap:HI (match_dup 0)))
12391 (clobber (reg:CC FLAGS_REG))]
12392 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12394 xchg{b}\t{%h0, %b0|%b0, %h0}
12395 rol{w}\t{$8, %0|%0, 8}"
12396 [(set_attr "length" "2,4")
12397 (set_attr "mode" "QI,HI")])
12399 (define_insn "bswaphi_lowpart"
12400 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12401 (bswap:HI (match_dup 0)))
12402 (clobber (reg:CC FLAGS_REG))]
12404 "rol{w}\t{$8, %0|%0, 8}"
12405 [(set_attr "length" "4")
12406 (set_attr "mode" "HI")])
12408 (define_expand "paritydi2"
12409 [(set (match_operand:DI 0 "register_operand" "")
12410 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12413 rtx scratch = gen_reg_rtx (QImode);
12416 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12417 NULL_RTX, operands[1]));
12419 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12420 gen_rtx_REG (CCmode, FLAGS_REG),
12422 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12425 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12428 rtx tmp = gen_reg_rtx (SImode);
12430 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12431 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12436 (define_expand "paritysi2"
12437 [(set (match_operand:SI 0 "register_operand" "")
12438 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12441 rtx scratch = gen_reg_rtx (QImode);
12444 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12446 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12447 gen_rtx_REG (CCmode, FLAGS_REG),
12449 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12451 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12455 (define_insn_and_split "paritydi2_cmp"
12456 [(set (reg:CC FLAGS_REG)
12457 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12459 (clobber (match_scratch:DI 0 "=r"))
12460 (clobber (match_scratch:SI 1 "=&r"))
12461 (clobber (match_scratch:HI 2 "=Q"))]
12464 "&& reload_completed"
12466 [(set (match_dup 1)
12467 (xor:SI (match_dup 1) (match_dup 4)))
12468 (clobber (reg:CC FLAGS_REG))])
12470 [(set (reg:CC FLAGS_REG)
12471 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12472 (clobber (match_dup 1))
12473 (clobber (match_dup 2))])]
12475 operands[4] = gen_lowpart (SImode, operands[3]);
12479 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12480 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12483 operands[1] = gen_highpart (SImode, operands[3]);
12486 (define_insn_and_split "paritysi2_cmp"
12487 [(set (reg:CC FLAGS_REG)
12488 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12490 (clobber (match_scratch:SI 0 "=r"))
12491 (clobber (match_scratch:HI 1 "=&Q"))]
12494 "&& reload_completed"
12496 [(set (match_dup 1)
12497 (xor:HI (match_dup 1) (match_dup 3)))
12498 (clobber (reg:CC FLAGS_REG))])
12500 [(set (reg:CC FLAGS_REG)
12501 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12502 (clobber (match_dup 1))])]
12504 operands[3] = gen_lowpart (HImode, operands[2]);
12506 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12507 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12510 (define_insn "*parityhi2_cmp"
12511 [(set (reg:CC FLAGS_REG)
12512 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12514 (clobber (match_scratch:HI 0 "=Q"))]
12516 "xor{b}\t{%h0, %b0|%b0, %h0}"
12517 [(set_attr "length" "2")
12518 (set_attr "mode" "HI")])
12521 ;; Thread-local storage patterns for ELF.
12523 ;; Note that these code sequences must appear exactly as shown
12524 ;; in order to allow linker relaxation.
12526 (define_insn "*tls_global_dynamic_32_gnu"
12527 [(set (match_operand:SI 0 "register_operand" "=a")
12529 [(match_operand:SI 1 "register_operand" "b")
12530 (match_operand:SI 2 "tls_symbolic_operand" "")
12531 (match_operand:SI 3 "constant_call_address_operand" "z")]
12533 (clobber (match_scratch:SI 4 "=d"))
12534 (clobber (match_scratch:SI 5 "=c"))
12535 (clobber (reg:CC FLAGS_REG))]
12536 "!TARGET_64BIT && TARGET_GNU_TLS"
12539 ("lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}", operands);
12540 if (TARGET_SUN_TLS)
12541 #ifdef HAVE_AS_IX86_TLSGDPLT
12542 return "call\t%a2@tlsgdplt";
12544 return "call\t%p3@plt";
12546 return "call\t%P3";
12548 [(set_attr "type" "multi")
12549 (set_attr "length" "12")])
12551 (define_expand "tls_global_dynamic_32"
12553 [(set (match_operand:SI 0 "register_operand" "")
12554 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12555 (match_operand:SI 1 "tls_symbolic_operand" "")
12556 (match_operand:SI 3 "constant_call_address_operand" "")]
12558 (clobber (match_scratch:SI 4 ""))
12559 (clobber (match_scratch:SI 5 ""))
12560 (clobber (reg:CC FLAGS_REG))])])
12562 (define_insn "*tls_global_dynamic_64"
12563 [(set (match_operand:DI 0 "register_operand" "=a")
12565 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12566 (match_operand:DI 3 "" "")))
12567 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12572 fputs (ASM_BYTE "0x66\n", asm_out_file);
12574 ("lea{q}\t{%a1@tlsgd(%%rip), %%rdi|rdi, %a1@tlsgd[rip]}", operands);
12575 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12576 fputs ("\trex64\n", asm_out_file);
12577 if (TARGET_SUN_TLS)
12578 return "call\t%p2@plt";
12579 return "call\t%P2";
12581 [(set_attr "type" "multi")
12582 (set (attr "length")
12583 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12585 (define_expand "tls_global_dynamic_64"
12587 [(set (match_operand:DI 0 "register_operand" "")
12589 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12591 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12594 (define_insn "*tls_local_dynamic_base_32_gnu"
12595 [(set (match_operand:SI 0 "register_operand" "=a")
12597 [(match_operand:SI 1 "register_operand" "b")
12598 (match_operand:SI 2 "constant_call_address_operand" "z")]
12599 UNSPEC_TLS_LD_BASE))
12600 (clobber (match_scratch:SI 3 "=d"))
12601 (clobber (match_scratch:SI 4 "=c"))
12602 (clobber (reg:CC FLAGS_REG))]
12603 "!TARGET_64BIT && TARGET_GNU_TLS"
12606 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12607 if (TARGET_SUN_TLS)
12608 #ifdef HAVE_AS_IX86_TLSLDMPLT
12609 return "call\t%&@tlsldmplt";
12611 return "call\t%p2@plt";
12613 return "call\t%P2";
12615 [(set_attr "type" "multi")
12616 (set_attr "length" "11")])
12618 (define_expand "tls_local_dynamic_base_32"
12620 [(set (match_operand:SI 0 "register_operand" "")
12622 [(match_operand:SI 1 "register_operand" "")
12623 (match_operand:SI 2 "constant_call_address_operand" "")]
12624 UNSPEC_TLS_LD_BASE))
12625 (clobber (match_scratch:SI 3 ""))
12626 (clobber (match_scratch:SI 4 ""))
12627 (clobber (reg:CC FLAGS_REG))])])
12629 (define_insn "*tls_local_dynamic_base_64"
12630 [(set (match_operand:DI 0 "register_operand" "=a")
12632 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12633 (match_operand:DI 2 "" "")))
12634 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12638 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12639 if (TARGET_SUN_TLS)
12640 return "call\t%p1@plt";
12641 return "call\t%P1";
12643 [(set_attr "type" "multi")
12644 (set_attr "length" "12")])
12646 (define_expand "tls_local_dynamic_base_64"
12648 [(set (match_operand:DI 0 "register_operand" "")
12650 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12652 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12654 ;; Local dynamic of a single variable is a lose. Show combine how
12655 ;; to convert that back to global dynamic.
12657 (define_insn_and_split "*tls_local_dynamic_32_once"
12658 [(set (match_operand:SI 0 "register_operand" "=a")
12660 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12661 (match_operand:SI 2 "constant_call_address_operand" "z")]
12662 UNSPEC_TLS_LD_BASE)
12663 (const:SI (unspec:SI
12664 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12666 (clobber (match_scratch:SI 4 "=d"))
12667 (clobber (match_scratch:SI 5 "=c"))
12668 (clobber (reg:CC FLAGS_REG))]
12673 [(set (match_dup 0)
12674 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12676 (clobber (match_dup 4))
12677 (clobber (match_dup 5))
12678 (clobber (reg:CC FLAGS_REG))])])
12680 ;; Segment register for the thread base ptr load
12681 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12683 ;; Load and add the thread base pointer from %<tp_seg>:0.
12684 (define_insn "*load_tp_x32"
12685 [(set (match_operand:SI 0 "register_operand" "=r")
12686 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12688 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12689 [(set_attr "type" "imov")
12690 (set_attr "modrm" "0")
12691 (set_attr "length" "7")
12692 (set_attr "memory" "load")
12693 (set_attr "imm_disp" "false")])
12695 (define_insn "*load_tp_x32_zext"
12696 [(set (match_operand:DI 0 "register_operand" "=r")
12697 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12699 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12700 [(set_attr "type" "imov")
12701 (set_attr "modrm" "0")
12702 (set_attr "length" "7")
12703 (set_attr "memory" "load")
12704 (set_attr "imm_disp" "false")])
12706 (define_insn "*load_tp_<mode>"
12707 [(set (match_operand:P 0 "register_operand" "=r")
12708 (unspec:P [(const_int 0)] UNSPEC_TP))]
12710 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12711 [(set_attr "type" "imov")
12712 (set_attr "modrm" "0")
12713 (set_attr "length" "7")
12714 (set_attr "memory" "load")
12715 (set_attr "imm_disp" "false")])
12717 (define_insn "*add_tp_x32"
12718 [(set (match_operand:SI 0 "register_operand" "=r")
12719 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12720 (match_operand:SI 1 "register_operand" "0")))
12721 (clobber (reg:CC FLAGS_REG))]
12723 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12724 [(set_attr "type" "alu")
12725 (set_attr "modrm" "0")
12726 (set_attr "length" "7")
12727 (set_attr "memory" "load")
12728 (set_attr "imm_disp" "false")])
12730 (define_insn "*add_tp_x32_zext"
12731 [(set (match_operand:DI 0 "register_operand" "=r")
12733 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12734 (match_operand:SI 1 "register_operand" "0"))))
12735 (clobber (reg:CC FLAGS_REG))]
12737 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12738 [(set_attr "type" "alu")
12739 (set_attr "modrm" "0")
12740 (set_attr "length" "7")
12741 (set_attr "memory" "load")
12742 (set_attr "imm_disp" "false")])
12744 (define_insn "*add_tp_<mode>"
12745 [(set (match_operand:P 0 "register_operand" "=r")
12746 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12747 (match_operand:P 1 "register_operand" "0")))
12748 (clobber (reg:CC FLAGS_REG))]
12750 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12751 [(set_attr "type" "alu")
12752 (set_attr "modrm" "0")
12753 (set_attr "length" "7")
12754 (set_attr "memory" "load")
12755 (set_attr "imm_disp" "false")])
12757 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12758 ;; %rax as destination of the initial executable code sequence.
12759 (define_insn "tls_initial_exec_64_sun"
12760 [(set (match_operand:DI 0 "register_operand" "=a")
12762 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12763 UNSPEC_TLS_IE_SUN))
12764 (clobber (reg:CC FLAGS_REG))]
12765 "TARGET_64BIT && TARGET_SUN_TLS"
12768 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12769 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12771 [(set_attr "type" "multi")])
12773 ;; GNU2 TLS patterns can be split.
12775 (define_expand "tls_dynamic_gnu2_32"
12776 [(set (match_dup 3)
12777 (plus:SI (match_operand:SI 2 "register_operand" "")
12779 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12782 [(set (match_operand:SI 0 "register_operand" "")
12783 (unspec:SI [(match_dup 1) (match_dup 3)
12784 (match_dup 2) (reg:SI SP_REG)]
12786 (clobber (reg:CC FLAGS_REG))])]
12787 "!TARGET_64BIT && TARGET_GNU2_TLS"
12789 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12790 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12793 (define_insn "*tls_dynamic_gnu2_lea_32"
12794 [(set (match_operand:SI 0 "register_operand" "=r")
12795 (plus:SI (match_operand:SI 1 "register_operand" "b")
12797 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12798 UNSPEC_TLSDESC))))]
12799 "!TARGET_64BIT && TARGET_GNU2_TLS"
12800 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
12801 [(set_attr "type" "lea")
12802 (set_attr "mode" "SI")
12803 (set_attr "length" "6")
12804 (set_attr "length_address" "4")])
12806 (define_insn "*tls_dynamic_gnu2_call_32"
12807 [(set (match_operand:SI 0 "register_operand" "=a")
12808 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12809 (match_operand:SI 2 "register_operand" "0")
12810 ;; we have to make sure %ebx still points to the GOT
12811 (match_operand:SI 3 "register_operand" "b")
12814 (clobber (reg:CC FLAGS_REG))]
12815 "!TARGET_64BIT && TARGET_GNU2_TLS"
12816 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12817 [(set_attr "type" "call")
12818 (set_attr "length" "2")
12819 (set_attr "length_address" "0")])
12821 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12822 [(set (match_operand:SI 0 "register_operand" "=&a")
12824 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12825 (match_operand:SI 4 "" "")
12826 (match_operand:SI 2 "register_operand" "b")
12829 (const:SI (unspec:SI
12830 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12832 (clobber (reg:CC FLAGS_REG))]
12833 "!TARGET_64BIT && TARGET_GNU2_TLS"
12836 [(set (match_dup 0) (match_dup 5))]
12838 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12839 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12842 (define_expand "tls_dynamic_gnu2_64"
12843 [(set (match_dup 2)
12844 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12847 [(set (match_operand:DI 0 "register_operand" "")
12848 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12850 (clobber (reg:CC FLAGS_REG))])]
12851 "TARGET_64BIT && TARGET_GNU2_TLS"
12853 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12854 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12857 (define_insn "*tls_dynamic_gnu2_lea_64"
12858 [(set (match_operand:DI 0 "register_operand" "=r")
12859 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12861 "TARGET_64BIT && TARGET_GNU2_TLS"
12862 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
12863 [(set_attr "type" "lea")
12864 (set_attr "mode" "DI")
12865 (set_attr "length" "7")
12866 (set_attr "length_address" "4")])
12868 (define_insn "*tls_dynamic_gnu2_call_64"
12869 [(set (match_operand:DI 0 "register_operand" "=a")
12870 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12871 (match_operand:DI 2 "register_operand" "0")
12874 (clobber (reg:CC FLAGS_REG))]
12875 "TARGET_64BIT && TARGET_GNU2_TLS"
12876 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12877 [(set_attr "type" "call")
12878 (set_attr "length" "2")
12879 (set_attr "length_address" "0")])
12881 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12882 [(set (match_operand:DI 0 "register_operand" "=&a")
12884 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12885 (match_operand:DI 3 "" "")
12888 (const:DI (unspec:DI
12889 [(match_operand 1 "tls_symbolic_operand" "")]
12891 (clobber (reg:CC FLAGS_REG))]
12892 "TARGET_64BIT && TARGET_GNU2_TLS"
12895 [(set (match_dup 0) (match_dup 4))]
12897 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12898 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12901 ;; These patterns match the binary 387 instructions for addM3, subM3,
12902 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12903 ;; SFmode. The first is the normal insn, the second the same insn but
12904 ;; with one operand a conversion, and the third the same insn but with
12905 ;; the other operand a conversion. The conversion may be SFmode or
12906 ;; SImode if the target mode DFmode, but only SImode if the target mode
12909 ;; Gcc is slightly more smart about handling normal two address instructions
12910 ;; so use special patterns for add and mull.
12912 (define_insn "*fop_<mode>_comm_mixed"
12913 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12914 (match_operator:MODEF 3 "binary_fp_operator"
12915 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12916 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12917 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12918 && COMMUTATIVE_ARITH_P (operands[3])
12919 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12920 "* return output_387_binary_op (insn, operands);"
12921 [(set (attr "type")
12922 (if_then_else (eq_attr "alternative" "1,2")
12923 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12924 (const_string "ssemul")
12925 (const_string "sseadd"))
12926 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12927 (const_string "fmul")
12928 (const_string "fop"))))
12929 (set_attr "isa" "*,noavx,avx")
12930 (set_attr "prefix" "orig,orig,vex")
12931 (set_attr "mode" "<MODE>")])
12933 (define_insn "*fop_<mode>_comm_sse"
12934 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12935 (match_operator:MODEF 3 "binary_fp_operator"
12936 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12937 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12938 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12939 && COMMUTATIVE_ARITH_P (operands[3])
12940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12941 "* return output_387_binary_op (insn, operands);"
12942 [(set (attr "type")
12943 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12944 (const_string "ssemul")
12945 (const_string "sseadd")))
12946 (set_attr "isa" "noavx,avx")
12947 (set_attr "prefix" "orig,vex")
12948 (set_attr "mode" "<MODE>")])
12950 (define_insn "*fop_<mode>_comm_i387"
12951 [(set (match_operand:MODEF 0 "register_operand" "=f")
12952 (match_operator:MODEF 3 "binary_fp_operator"
12953 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12954 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12955 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12956 && COMMUTATIVE_ARITH_P (operands[3])
12957 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12958 "* return output_387_binary_op (insn, operands);"
12959 [(set (attr "type")
12960 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12961 (const_string "fmul")
12962 (const_string "fop")))
12963 (set_attr "mode" "<MODE>")])
12965 (define_insn "*fop_<mode>_1_mixed"
12966 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12967 (match_operator:MODEF 3 "binary_fp_operator"
12968 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12969 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12970 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12971 && !COMMUTATIVE_ARITH_P (operands[3])
12972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12973 "* return output_387_binary_op (insn, operands);"
12974 [(set (attr "type")
12975 (cond [(and (eq_attr "alternative" "2,3")
12976 (match_operand:MODEF 3 "mult_operator" ""))
12977 (const_string "ssemul")
12978 (and (eq_attr "alternative" "2,3")
12979 (match_operand:MODEF 3 "div_operator" ""))
12980 (const_string "ssediv")
12981 (eq_attr "alternative" "2,3")
12982 (const_string "sseadd")
12983 (match_operand:MODEF 3 "mult_operator" "")
12984 (const_string "fmul")
12985 (match_operand:MODEF 3 "div_operator" "")
12986 (const_string "fdiv")
12988 (const_string "fop")))
12989 (set_attr "isa" "*,*,noavx,avx")
12990 (set_attr "prefix" "orig,orig,orig,vex")
12991 (set_attr "mode" "<MODE>")])
12993 (define_insn "*rcpsf2_sse"
12994 [(set (match_operand:SF 0 "register_operand" "=x")
12995 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
12998 "%vrcpss\t{%1, %d0|%d0, %1}"
12999 [(set_attr "type" "sse")
13000 (set_attr "atom_sse_attr" "rcp")
13001 (set_attr "prefix" "maybe_vex")
13002 (set_attr "mode" "SF")])
13004 (define_insn "*fop_<mode>_1_sse"
13005 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13006 (match_operator:MODEF 3 "binary_fp_operator"
13007 [(match_operand:MODEF 1 "register_operand" "0,x")
13008 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13009 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13010 && !COMMUTATIVE_ARITH_P (operands[3])"
13011 "* return output_387_binary_op (insn, operands);"
13012 [(set (attr "type")
13013 (cond [(match_operand:MODEF 3 "mult_operator" "")
13014 (const_string "ssemul")
13015 (match_operand:MODEF 3 "div_operator" "")
13016 (const_string "ssediv")
13018 (const_string "sseadd")))
13019 (set_attr "isa" "noavx,avx")
13020 (set_attr "prefix" "orig,vex")
13021 (set_attr "mode" "<MODE>")])
13023 ;; This pattern is not fully shadowed by the pattern above.
13024 (define_insn "*fop_<mode>_1_i387"
13025 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13026 (match_operator:MODEF 3 "binary_fp_operator"
13027 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13028 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13029 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13030 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13031 && !COMMUTATIVE_ARITH_P (operands[3])
13032 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13033 "* return output_387_binary_op (insn, operands);"
13034 [(set (attr "type")
13035 (cond [(match_operand:MODEF 3 "mult_operator" "")
13036 (const_string "fmul")
13037 (match_operand:MODEF 3 "div_operator" "")
13038 (const_string "fdiv")
13040 (const_string "fop")))
13041 (set_attr "mode" "<MODE>")])
13043 ;; ??? Add SSE splitters for these!
13044 (define_insn "*fop_<MODEF:mode>_2_i387"
13045 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13046 (match_operator:MODEF 3 "binary_fp_operator"
13048 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13049 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13050 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13051 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13052 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13053 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13054 [(set (attr "type")
13055 (cond [(match_operand:MODEF 3 "mult_operator" "")
13056 (const_string "fmul")
13057 (match_operand:MODEF 3 "div_operator" "")
13058 (const_string "fdiv")
13060 (const_string "fop")))
13061 (set_attr "fp_int_src" "true")
13062 (set_attr "mode" "<SWI24:MODE>")])
13064 (define_insn "*fop_<MODEF:mode>_3_i387"
13065 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13066 (match_operator:MODEF 3 "binary_fp_operator"
13067 [(match_operand:MODEF 1 "register_operand" "0,0")
13069 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13070 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13071 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13072 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13073 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13074 [(set (attr "type")
13075 (cond [(match_operand:MODEF 3 "mult_operator" "")
13076 (const_string "fmul")
13077 (match_operand:MODEF 3 "div_operator" "")
13078 (const_string "fdiv")
13080 (const_string "fop")))
13081 (set_attr "fp_int_src" "true")
13082 (set_attr "mode" "<MODE>")])
13084 (define_insn "*fop_df_4_i387"
13085 [(set (match_operand:DF 0 "register_operand" "=f,f")
13086 (match_operator:DF 3 "binary_fp_operator"
13088 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13089 (match_operand:DF 2 "register_operand" "0,f")]))]
13090 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13091 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13092 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13093 "* return output_387_binary_op (insn, operands);"
13094 [(set (attr "type")
13095 (cond [(match_operand:DF 3 "mult_operator" "")
13096 (const_string "fmul")
13097 (match_operand:DF 3 "div_operator" "")
13098 (const_string "fdiv")
13100 (const_string "fop")))
13101 (set_attr "mode" "SF")])
13103 (define_insn "*fop_df_5_i387"
13104 [(set (match_operand:DF 0 "register_operand" "=f,f")
13105 (match_operator:DF 3 "binary_fp_operator"
13106 [(match_operand:DF 1 "register_operand" "0,f")
13108 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13109 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13110 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13111 "* return output_387_binary_op (insn, operands);"
13112 [(set (attr "type")
13113 (cond [(match_operand:DF 3 "mult_operator" "")
13114 (const_string "fmul")
13115 (match_operand:DF 3 "div_operator" "")
13116 (const_string "fdiv")
13118 (const_string "fop")))
13119 (set_attr "mode" "SF")])
13121 (define_insn "*fop_df_6_i387"
13122 [(set (match_operand:DF 0 "register_operand" "=f,f")
13123 (match_operator:DF 3 "binary_fp_operator"
13125 (match_operand:SF 1 "register_operand" "0,f"))
13127 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13128 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13129 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13130 "* return output_387_binary_op (insn, operands);"
13131 [(set (attr "type")
13132 (cond [(match_operand:DF 3 "mult_operator" "")
13133 (const_string "fmul")
13134 (match_operand:DF 3 "div_operator" "")
13135 (const_string "fdiv")
13137 (const_string "fop")))
13138 (set_attr "mode" "SF")])
13140 (define_insn "*fop_xf_comm_i387"
13141 [(set (match_operand:XF 0 "register_operand" "=f")
13142 (match_operator:XF 3 "binary_fp_operator"
13143 [(match_operand:XF 1 "register_operand" "%0")
13144 (match_operand:XF 2 "register_operand" "f")]))]
13146 && COMMUTATIVE_ARITH_P (operands[3])"
13147 "* return output_387_binary_op (insn, operands);"
13148 [(set (attr "type")
13149 (if_then_else (match_operand:XF 3 "mult_operator" "")
13150 (const_string "fmul")
13151 (const_string "fop")))
13152 (set_attr "mode" "XF")])
13154 (define_insn "*fop_xf_1_i387"
13155 [(set (match_operand:XF 0 "register_operand" "=f,f")
13156 (match_operator:XF 3 "binary_fp_operator"
13157 [(match_operand:XF 1 "register_operand" "0,f")
13158 (match_operand:XF 2 "register_operand" "f,0")]))]
13160 && !COMMUTATIVE_ARITH_P (operands[3])"
13161 "* return output_387_binary_op (insn, operands);"
13162 [(set (attr "type")
13163 (cond [(match_operand:XF 3 "mult_operator" "")
13164 (const_string "fmul")
13165 (match_operand:XF 3 "div_operator" "")
13166 (const_string "fdiv")
13168 (const_string "fop")))
13169 (set_attr "mode" "XF")])
13171 (define_insn "*fop_xf_2_i387"
13172 [(set (match_operand:XF 0 "register_operand" "=f,f")
13173 (match_operator:XF 3 "binary_fp_operator"
13175 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13176 (match_operand:XF 2 "register_operand" "0,0")]))]
13177 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13178 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13179 [(set (attr "type")
13180 (cond [(match_operand:XF 3 "mult_operator" "")
13181 (const_string "fmul")
13182 (match_operand:XF 3 "div_operator" "")
13183 (const_string "fdiv")
13185 (const_string "fop")))
13186 (set_attr "fp_int_src" "true")
13187 (set_attr "mode" "<MODE>")])
13189 (define_insn "*fop_xf_3_i387"
13190 [(set (match_operand:XF 0 "register_operand" "=f,f")
13191 (match_operator:XF 3 "binary_fp_operator"
13192 [(match_operand:XF 1 "register_operand" "0,0")
13194 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13195 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13196 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13197 [(set (attr "type")
13198 (cond [(match_operand:XF 3 "mult_operator" "")
13199 (const_string "fmul")
13200 (match_operand:XF 3 "div_operator" "")
13201 (const_string "fdiv")
13203 (const_string "fop")))
13204 (set_attr "fp_int_src" "true")
13205 (set_attr "mode" "<MODE>")])
13207 (define_insn "*fop_xf_4_i387"
13208 [(set (match_operand:XF 0 "register_operand" "=f,f")
13209 (match_operator:XF 3 "binary_fp_operator"
13211 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13212 (match_operand:XF 2 "register_operand" "0,f")]))]
13214 "* return output_387_binary_op (insn, operands);"
13215 [(set (attr "type")
13216 (cond [(match_operand:XF 3 "mult_operator" "")
13217 (const_string "fmul")
13218 (match_operand:XF 3 "div_operator" "")
13219 (const_string "fdiv")
13221 (const_string "fop")))
13222 (set_attr "mode" "<MODE>")])
13224 (define_insn "*fop_xf_5_i387"
13225 [(set (match_operand:XF 0 "register_operand" "=f,f")
13226 (match_operator:XF 3 "binary_fp_operator"
13227 [(match_operand:XF 1 "register_operand" "0,f")
13229 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13231 "* return output_387_binary_op (insn, operands);"
13232 [(set (attr "type")
13233 (cond [(match_operand:XF 3 "mult_operator" "")
13234 (const_string "fmul")
13235 (match_operand:XF 3 "div_operator" "")
13236 (const_string "fdiv")
13238 (const_string "fop")))
13239 (set_attr "mode" "<MODE>")])
13241 (define_insn "*fop_xf_6_i387"
13242 [(set (match_operand:XF 0 "register_operand" "=f,f")
13243 (match_operator:XF 3 "binary_fp_operator"
13245 (match_operand:MODEF 1 "register_operand" "0,f"))
13247 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13249 "* return output_387_binary_op (insn, operands);"
13250 [(set (attr "type")
13251 (cond [(match_operand:XF 3 "mult_operator" "")
13252 (const_string "fmul")
13253 (match_operand:XF 3 "div_operator" "")
13254 (const_string "fdiv")
13256 (const_string "fop")))
13257 (set_attr "mode" "<MODE>")])
13260 [(set (match_operand 0 "register_operand" "")
13261 (match_operator 3 "binary_fp_operator"
13262 [(float (match_operand:SWI24 1 "register_operand" ""))
13263 (match_operand 2 "register_operand" "")]))]
13265 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13266 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13269 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13270 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13271 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13272 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13273 GET_MODE (operands[3]),
13276 ix86_free_from_memory (GET_MODE (operands[1]));
13281 [(set (match_operand 0 "register_operand" "")
13282 (match_operator 3 "binary_fp_operator"
13283 [(match_operand 1 "register_operand" "")
13284 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13286 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13287 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13290 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13291 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13292 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13293 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13294 GET_MODE (operands[3]),
13297 ix86_free_from_memory (GET_MODE (operands[2]));
13301 ;; FPU special functions.
13303 ;; This pattern implements a no-op XFmode truncation for
13304 ;; all fancy i386 XFmode math functions.
13306 (define_insn "truncxf<mode>2_i387_noop_unspec"
13307 [(set (match_operand:MODEF 0 "register_operand" "=f")
13308 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13309 UNSPEC_TRUNC_NOOP))]
13310 "TARGET_USE_FANCY_MATH_387"
13311 "* return output_387_reg_move (insn, operands);"
13312 [(set_attr "type" "fmov")
13313 (set_attr "mode" "<MODE>")])
13315 (define_insn "sqrtxf2"
13316 [(set (match_operand:XF 0 "register_operand" "=f")
13317 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13318 "TARGET_USE_FANCY_MATH_387"
13320 [(set_attr "type" "fpspc")
13321 (set_attr "mode" "XF")
13322 (set_attr "athlon_decode" "direct")
13323 (set_attr "amdfam10_decode" "direct")
13324 (set_attr "bdver1_decode" "direct")])
13326 (define_insn "sqrt_extend<mode>xf2_i387"
13327 [(set (match_operand:XF 0 "register_operand" "=f")
13330 (match_operand:MODEF 1 "register_operand" "0"))))]
13331 "TARGET_USE_FANCY_MATH_387"
13333 [(set_attr "type" "fpspc")
13334 (set_attr "mode" "XF")
13335 (set_attr "athlon_decode" "direct")
13336 (set_attr "amdfam10_decode" "direct")
13337 (set_attr "bdver1_decode" "direct")])
13339 (define_insn "*rsqrtsf2_sse"
13340 [(set (match_operand:SF 0 "register_operand" "=x")
13341 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13344 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13345 [(set_attr "type" "sse")
13346 (set_attr "atom_sse_attr" "rcp")
13347 (set_attr "prefix" "maybe_vex")
13348 (set_attr "mode" "SF")])
13350 (define_expand "rsqrtsf2"
13351 [(set (match_operand:SF 0 "register_operand" "")
13352 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13356 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13360 (define_insn "*sqrt<mode>2_sse"
13361 [(set (match_operand:MODEF 0 "register_operand" "=x")
13363 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13364 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13365 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13366 [(set_attr "type" "sse")
13367 (set_attr "atom_sse_attr" "sqrt")
13368 (set_attr "prefix" "maybe_vex")
13369 (set_attr "mode" "<MODE>")
13370 (set_attr "athlon_decode" "*")
13371 (set_attr "amdfam10_decode" "*")
13372 (set_attr "bdver1_decode" "*")])
13374 (define_expand "sqrt<mode>2"
13375 [(set (match_operand:MODEF 0 "register_operand" "")
13377 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13378 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13379 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13381 if (<MODE>mode == SFmode
13383 && TARGET_RECIP_SQRT
13384 && !optimize_function_for_size_p (cfun)
13385 && flag_finite_math_only && !flag_trapping_math
13386 && flag_unsafe_math_optimizations)
13388 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13392 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13394 rtx op0 = gen_reg_rtx (XFmode);
13395 rtx op1 = force_reg (<MODE>mode, operands[1]);
13397 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13398 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13403 (define_insn "fpremxf4_i387"
13404 [(set (match_operand:XF 0 "register_operand" "=f")
13405 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13406 (match_operand:XF 3 "register_operand" "1")]
13408 (set (match_operand:XF 1 "register_operand" "=u")
13409 (unspec:XF [(match_dup 2) (match_dup 3)]
13411 (set (reg:CCFP FPSR_REG)
13412 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13414 "TARGET_USE_FANCY_MATH_387"
13416 [(set_attr "type" "fpspc")
13417 (set_attr "mode" "XF")])
13419 (define_expand "fmodxf3"
13420 [(use (match_operand:XF 0 "register_operand" ""))
13421 (use (match_operand:XF 1 "general_operand" ""))
13422 (use (match_operand:XF 2 "general_operand" ""))]
13423 "TARGET_USE_FANCY_MATH_387"
13425 rtx label = gen_label_rtx ();
13427 rtx op1 = gen_reg_rtx (XFmode);
13428 rtx op2 = gen_reg_rtx (XFmode);
13430 emit_move_insn (op2, operands[2]);
13431 emit_move_insn (op1, operands[1]);
13433 emit_label (label);
13434 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13435 ix86_emit_fp_unordered_jump (label);
13436 LABEL_NUSES (label) = 1;
13438 emit_move_insn (operands[0], op1);
13442 (define_expand "fmod<mode>3"
13443 [(use (match_operand:MODEF 0 "register_operand" ""))
13444 (use (match_operand:MODEF 1 "general_operand" ""))
13445 (use (match_operand:MODEF 2 "general_operand" ""))]
13446 "TARGET_USE_FANCY_MATH_387"
13448 rtx (*gen_truncxf) (rtx, rtx);
13450 rtx label = gen_label_rtx ();
13452 rtx op1 = gen_reg_rtx (XFmode);
13453 rtx op2 = gen_reg_rtx (XFmode);
13455 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13456 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13458 emit_label (label);
13459 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13460 ix86_emit_fp_unordered_jump (label);
13461 LABEL_NUSES (label) = 1;
13463 /* Truncate the result properly for strict SSE math. */
13464 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13465 && !TARGET_MIX_SSE_I387)
13466 gen_truncxf = gen_truncxf<mode>2;
13468 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13470 emit_insn (gen_truncxf (operands[0], op1));
13474 (define_insn "fprem1xf4_i387"
13475 [(set (match_operand:XF 0 "register_operand" "=f")
13476 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13477 (match_operand:XF 3 "register_operand" "1")]
13479 (set (match_operand:XF 1 "register_operand" "=u")
13480 (unspec:XF [(match_dup 2) (match_dup 3)]
13482 (set (reg:CCFP FPSR_REG)
13483 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13485 "TARGET_USE_FANCY_MATH_387"
13487 [(set_attr "type" "fpspc")
13488 (set_attr "mode" "XF")])
13490 (define_expand "remainderxf3"
13491 [(use (match_operand:XF 0 "register_operand" ""))
13492 (use (match_operand:XF 1 "general_operand" ""))
13493 (use (match_operand:XF 2 "general_operand" ""))]
13494 "TARGET_USE_FANCY_MATH_387"
13496 rtx label = gen_label_rtx ();
13498 rtx op1 = gen_reg_rtx (XFmode);
13499 rtx op2 = gen_reg_rtx (XFmode);
13501 emit_move_insn (op2, operands[2]);
13502 emit_move_insn (op1, operands[1]);
13504 emit_label (label);
13505 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13506 ix86_emit_fp_unordered_jump (label);
13507 LABEL_NUSES (label) = 1;
13509 emit_move_insn (operands[0], op1);
13513 (define_expand "remainder<mode>3"
13514 [(use (match_operand:MODEF 0 "register_operand" ""))
13515 (use (match_operand:MODEF 1 "general_operand" ""))
13516 (use (match_operand:MODEF 2 "general_operand" ""))]
13517 "TARGET_USE_FANCY_MATH_387"
13519 rtx (*gen_truncxf) (rtx, rtx);
13521 rtx label = gen_label_rtx ();
13523 rtx op1 = gen_reg_rtx (XFmode);
13524 rtx op2 = gen_reg_rtx (XFmode);
13526 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13527 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13529 emit_label (label);
13531 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13532 ix86_emit_fp_unordered_jump (label);
13533 LABEL_NUSES (label) = 1;
13535 /* Truncate the result properly for strict SSE math. */
13536 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13537 && !TARGET_MIX_SSE_I387)
13538 gen_truncxf = gen_truncxf<mode>2;
13540 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13542 emit_insn (gen_truncxf (operands[0], op1));
13546 (define_insn "*sinxf2_i387"
13547 [(set (match_operand:XF 0 "register_operand" "=f")
13548 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13549 "TARGET_USE_FANCY_MATH_387
13550 && flag_unsafe_math_optimizations"
13552 [(set_attr "type" "fpspc")
13553 (set_attr "mode" "XF")])
13555 (define_insn "*sin_extend<mode>xf2_i387"
13556 [(set (match_operand:XF 0 "register_operand" "=f")
13557 (unspec:XF [(float_extend:XF
13558 (match_operand:MODEF 1 "register_operand" "0"))]
13560 "TARGET_USE_FANCY_MATH_387
13561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13562 || TARGET_MIX_SSE_I387)
13563 && flag_unsafe_math_optimizations"
13565 [(set_attr "type" "fpspc")
13566 (set_attr "mode" "XF")])
13568 (define_insn "*cosxf2_i387"
13569 [(set (match_operand:XF 0 "register_operand" "=f")
13570 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13571 "TARGET_USE_FANCY_MATH_387
13572 && flag_unsafe_math_optimizations"
13574 [(set_attr "type" "fpspc")
13575 (set_attr "mode" "XF")])
13577 (define_insn "*cos_extend<mode>xf2_i387"
13578 [(set (match_operand:XF 0 "register_operand" "=f")
13579 (unspec:XF [(float_extend:XF
13580 (match_operand:MODEF 1 "register_operand" "0"))]
13582 "TARGET_USE_FANCY_MATH_387
13583 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13584 || TARGET_MIX_SSE_I387)
13585 && flag_unsafe_math_optimizations"
13587 [(set_attr "type" "fpspc")
13588 (set_attr "mode" "XF")])
13590 ;; When sincos pattern is defined, sin and cos builtin functions will be
13591 ;; expanded to sincos pattern with one of its outputs left unused.
13592 ;; CSE pass will figure out if two sincos patterns can be combined,
13593 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13594 ;; depending on the unused output.
13596 (define_insn "sincosxf3"
13597 [(set (match_operand:XF 0 "register_operand" "=f")
13598 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13599 UNSPEC_SINCOS_COS))
13600 (set (match_operand:XF 1 "register_operand" "=u")
13601 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13602 "TARGET_USE_FANCY_MATH_387
13603 && flag_unsafe_math_optimizations"
13605 [(set_attr "type" "fpspc")
13606 (set_attr "mode" "XF")])
13609 [(set (match_operand:XF 0 "register_operand" "")
13610 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13611 UNSPEC_SINCOS_COS))
13612 (set (match_operand:XF 1 "register_operand" "")
13613 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13614 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13615 && can_create_pseudo_p ()"
13616 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13619 [(set (match_operand:XF 0 "register_operand" "")
13620 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13621 UNSPEC_SINCOS_COS))
13622 (set (match_operand:XF 1 "register_operand" "")
13623 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13624 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13625 && can_create_pseudo_p ()"
13626 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13628 (define_insn "sincos_extend<mode>xf3_i387"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(float_extend:XF
13631 (match_operand:MODEF 2 "register_operand" "0"))]
13632 UNSPEC_SINCOS_COS))
13633 (set (match_operand:XF 1 "register_operand" "=u")
13634 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13635 "TARGET_USE_FANCY_MATH_387
13636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13637 || TARGET_MIX_SSE_I387)
13638 && flag_unsafe_math_optimizations"
13640 [(set_attr "type" "fpspc")
13641 (set_attr "mode" "XF")])
13644 [(set (match_operand:XF 0 "register_operand" "")
13645 (unspec:XF [(float_extend:XF
13646 (match_operand:MODEF 2 "register_operand" ""))]
13647 UNSPEC_SINCOS_COS))
13648 (set (match_operand:XF 1 "register_operand" "")
13649 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13650 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13651 && can_create_pseudo_p ()"
13652 [(set (match_dup 1)
13653 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13656 [(set (match_operand:XF 0 "register_operand" "")
13657 (unspec:XF [(float_extend:XF
13658 (match_operand:MODEF 2 "register_operand" ""))]
13659 UNSPEC_SINCOS_COS))
13660 (set (match_operand:XF 1 "register_operand" "")
13661 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13662 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13663 && can_create_pseudo_p ()"
13664 [(set (match_dup 0)
13665 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13667 (define_expand "sincos<mode>3"
13668 [(use (match_operand:MODEF 0 "register_operand" ""))
13669 (use (match_operand:MODEF 1 "register_operand" ""))
13670 (use (match_operand:MODEF 2 "register_operand" ""))]
13671 "TARGET_USE_FANCY_MATH_387
13672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13673 || TARGET_MIX_SSE_I387)
13674 && flag_unsafe_math_optimizations"
13676 rtx op0 = gen_reg_rtx (XFmode);
13677 rtx op1 = gen_reg_rtx (XFmode);
13679 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13680 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13681 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13685 (define_insn "fptanxf4_i387"
13686 [(set (match_operand:XF 0 "register_operand" "=f")
13687 (match_operand:XF 3 "const_double_operand" "F"))
13688 (set (match_operand:XF 1 "register_operand" "=u")
13689 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13691 "TARGET_USE_FANCY_MATH_387
13692 && flag_unsafe_math_optimizations
13693 && standard_80387_constant_p (operands[3]) == 2"
13695 [(set_attr "type" "fpspc")
13696 (set_attr "mode" "XF")])
13698 (define_insn "fptan_extend<mode>xf4_i387"
13699 [(set (match_operand:MODEF 0 "register_operand" "=f")
13700 (match_operand:MODEF 3 "const_double_operand" "F"))
13701 (set (match_operand:XF 1 "register_operand" "=u")
13702 (unspec:XF [(float_extend:XF
13703 (match_operand:MODEF 2 "register_operand" "0"))]
13705 "TARGET_USE_FANCY_MATH_387
13706 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13707 || TARGET_MIX_SSE_I387)
13708 && flag_unsafe_math_optimizations
13709 && standard_80387_constant_p (operands[3]) == 2"
13711 [(set_attr "type" "fpspc")
13712 (set_attr "mode" "XF")])
13714 (define_expand "tanxf2"
13715 [(use (match_operand:XF 0 "register_operand" ""))
13716 (use (match_operand:XF 1 "register_operand" ""))]
13717 "TARGET_USE_FANCY_MATH_387
13718 && flag_unsafe_math_optimizations"
13720 rtx one = gen_reg_rtx (XFmode);
13721 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13723 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13727 (define_expand "tan<mode>2"
13728 [(use (match_operand:MODEF 0 "register_operand" ""))
13729 (use (match_operand:MODEF 1 "register_operand" ""))]
13730 "TARGET_USE_FANCY_MATH_387
13731 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13732 || TARGET_MIX_SSE_I387)
13733 && flag_unsafe_math_optimizations"
13735 rtx op0 = gen_reg_rtx (XFmode);
13737 rtx one = gen_reg_rtx (<MODE>mode);
13738 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13740 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13741 operands[1], op2));
13742 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13746 (define_insn "*fpatanxf3_i387"
13747 [(set (match_operand:XF 0 "register_operand" "=f")
13748 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13749 (match_operand:XF 2 "register_operand" "u")]
13751 (clobber (match_scratch:XF 3 "=2"))]
13752 "TARGET_USE_FANCY_MATH_387
13753 && flag_unsafe_math_optimizations"
13755 [(set_attr "type" "fpspc")
13756 (set_attr "mode" "XF")])
13758 (define_insn "fpatan_extend<mode>xf3_i387"
13759 [(set (match_operand:XF 0 "register_operand" "=f")
13760 (unspec:XF [(float_extend:XF
13761 (match_operand:MODEF 1 "register_operand" "0"))
13763 (match_operand:MODEF 2 "register_operand" "u"))]
13765 (clobber (match_scratch:XF 3 "=2"))]
13766 "TARGET_USE_FANCY_MATH_387
13767 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13768 || TARGET_MIX_SSE_I387)
13769 && flag_unsafe_math_optimizations"
13771 [(set_attr "type" "fpspc")
13772 (set_attr "mode" "XF")])
13774 (define_expand "atan2xf3"
13775 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13776 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13777 (match_operand:XF 1 "register_operand" "")]
13779 (clobber (match_scratch:XF 3 ""))])]
13780 "TARGET_USE_FANCY_MATH_387
13781 && flag_unsafe_math_optimizations")
13783 (define_expand "atan2<mode>3"
13784 [(use (match_operand:MODEF 0 "register_operand" ""))
13785 (use (match_operand:MODEF 1 "register_operand" ""))
13786 (use (match_operand:MODEF 2 "register_operand" ""))]
13787 "TARGET_USE_FANCY_MATH_387
13788 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13789 || TARGET_MIX_SSE_I387)
13790 && flag_unsafe_math_optimizations"
13792 rtx op0 = gen_reg_rtx (XFmode);
13794 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13795 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13799 (define_expand "atanxf2"
13800 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13801 (unspec:XF [(match_dup 2)
13802 (match_operand:XF 1 "register_operand" "")]
13804 (clobber (match_scratch:XF 3 ""))])]
13805 "TARGET_USE_FANCY_MATH_387
13806 && flag_unsafe_math_optimizations"
13808 operands[2] = gen_reg_rtx (XFmode);
13809 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13812 (define_expand "atan<mode>2"
13813 [(use (match_operand:MODEF 0 "register_operand" ""))
13814 (use (match_operand:MODEF 1 "register_operand" ""))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13817 || TARGET_MIX_SSE_I387)
13818 && flag_unsafe_math_optimizations"
13820 rtx op0 = gen_reg_rtx (XFmode);
13822 rtx op2 = gen_reg_rtx (<MODE>mode);
13823 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13825 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13826 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13830 (define_expand "asinxf2"
13831 [(set (match_dup 2)
13832 (mult:XF (match_operand:XF 1 "register_operand" "")
13834 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13835 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13836 (parallel [(set (match_operand:XF 0 "register_operand" "")
13837 (unspec:XF [(match_dup 5) (match_dup 1)]
13839 (clobber (match_scratch:XF 6 ""))])]
13840 "TARGET_USE_FANCY_MATH_387
13841 && flag_unsafe_math_optimizations"
13845 if (optimize_insn_for_size_p ())
13848 for (i = 2; i < 6; i++)
13849 operands[i] = gen_reg_rtx (XFmode);
13851 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13854 (define_expand "asin<mode>2"
13855 [(use (match_operand:MODEF 0 "register_operand" ""))
13856 (use (match_operand:MODEF 1 "general_operand" ""))]
13857 "TARGET_USE_FANCY_MATH_387
13858 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13859 || TARGET_MIX_SSE_I387)
13860 && flag_unsafe_math_optimizations"
13862 rtx op0 = gen_reg_rtx (XFmode);
13863 rtx op1 = gen_reg_rtx (XFmode);
13865 if (optimize_insn_for_size_p ())
13868 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13869 emit_insn (gen_asinxf2 (op0, op1));
13870 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13874 (define_expand "acosxf2"
13875 [(set (match_dup 2)
13876 (mult:XF (match_operand:XF 1 "register_operand" "")
13878 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13879 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13880 (parallel [(set (match_operand:XF 0 "register_operand" "")
13881 (unspec:XF [(match_dup 1) (match_dup 5)]
13883 (clobber (match_scratch:XF 6 ""))])]
13884 "TARGET_USE_FANCY_MATH_387
13885 && flag_unsafe_math_optimizations"
13889 if (optimize_insn_for_size_p ())
13892 for (i = 2; i < 6; i++)
13893 operands[i] = gen_reg_rtx (XFmode);
13895 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13898 (define_expand "acos<mode>2"
13899 [(use (match_operand:MODEF 0 "register_operand" ""))
13900 (use (match_operand:MODEF 1 "general_operand" ""))]
13901 "TARGET_USE_FANCY_MATH_387
13902 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13903 || TARGET_MIX_SSE_I387)
13904 && flag_unsafe_math_optimizations"
13906 rtx op0 = gen_reg_rtx (XFmode);
13907 rtx op1 = gen_reg_rtx (XFmode);
13909 if (optimize_insn_for_size_p ())
13912 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13913 emit_insn (gen_acosxf2 (op0, op1));
13914 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13918 (define_insn "fyl2xxf3_i387"
13919 [(set (match_operand:XF 0 "register_operand" "=f")
13920 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13921 (match_operand:XF 2 "register_operand" "u")]
13923 (clobber (match_scratch:XF 3 "=2"))]
13924 "TARGET_USE_FANCY_MATH_387
13925 && flag_unsafe_math_optimizations"
13927 [(set_attr "type" "fpspc")
13928 (set_attr "mode" "XF")])
13930 (define_insn "fyl2x_extend<mode>xf3_i387"
13931 [(set (match_operand:XF 0 "register_operand" "=f")
13932 (unspec:XF [(float_extend:XF
13933 (match_operand:MODEF 1 "register_operand" "0"))
13934 (match_operand:XF 2 "register_operand" "u")]
13936 (clobber (match_scratch:XF 3 "=2"))]
13937 "TARGET_USE_FANCY_MATH_387
13938 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13939 || TARGET_MIX_SSE_I387)
13940 && flag_unsafe_math_optimizations"
13942 [(set_attr "type" "fpspc")
13943 (set_attr "mode" "XF")])
13945 (define_expand "logxf2"
13946 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13947 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13948 (match_dup 2)] UNSPEC_FYL2X))
13949 (clobber (match_scratch:XF 3 ""))])]
13950 "TARGET_USE_FANCY_MATH_387
13951 && flag_unsafe_math_optimizations"
13953 operands[2] = gen_reg_rtx (XFmode);
13954 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13957 (define_expand "log<mode>2"
13958 [(use (match_operand:MODEF 0 "register_operand" ""))
13959 (use (match_operand:MODEF 1 "register_operand" ""))]
13960 "TARGET_USE_FANCY_MATH_387
13961 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13962 || TARGET_MIX_SSE_I387)
13963 && flag_unsafe_math_optimizations"
13965 rtx op0 = gen_reg_rtx (XFmode);
13967 rtx op2 = gen_reg_rtx (XFmode);
13968 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13970 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13971 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13975 (define_expand "log10xf2"
13976 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13977 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13978 (match_dup 2)] UNSPEC_FYL2X))
13979 (clobber (match_scratch:XF 3 ""))])]
13980 "TARGET_USE_FANCY_MATH_387
13981 && flag_unsafe_math_optimizations"
13983 operands[2] = gen_reg_rtx (XFmode);
13984 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
13987 (define_expand "log10<mode>2"
13988 [(use (match_operand:MODEF 0 "register_operand" ""))
13989 (use (match_operand:MODEF 1 "register_operand" ""))]
13990 "TARGET_USE_FANCY_MATH_387
13991 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13992 || TARGET_MIX_SSE_I387)
13993 && flag_unsafe_math_optimizations"
13995 rtx op0 = gen_reg_rtx (XFmode);
13997 rtx op2 = gen_reg_rtx (XFmode);
13998 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14000 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14001 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14005 (define_expand "log2xf2"
14006 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14007 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14008 (match_dup 2)] UNSPEC_FYL2X))
14009 (clobber (match_scratch:XF 3 ""))])]
14010 "TARGET_USE_FANCY_MATH_387
14011 && flag_unsafe_math_optimizations"
14013 operands[2] = gen_reg_rtx (XFmode);
14014 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14017 (define_expand "log2<mode>2"
14018 [(use (match_operand:MODEF 0 "register_operand" ""))
14019 (use (match_operand:MODEF 1 "register_operand" ""))]
14020 "TARGET_USE_FANCY_MATH_387
14021 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14022 || TARGET_MIX_SSE_I387)
14023 && flag_unsafe_math_optimizations"
14025 rtx op0 = gen_reg_rtx (XFmode);
14027 rtx op2 = gen_reg_rtx (XFmode);
14028 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14030 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14031 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14035 (define_insn "fyl2xp1xf3_i387"
14036 [(set (match_operand:XF 0 "register_operand" "=f")
14037 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14038 (match_operand:XF 2 "register_operand" "u")]
14040 (clobber (match_scratch:XF 3 "=2"))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && flag_unsafe_math_optimizations"
14044 [(set_attr "type" "fpspc")
14045 (set_attr "mode" "XF")])
14047 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14048 [(set (match_operand:XF 0 "register_operand" "=f")
14049 (unspec:XF [(float_extend:XF
14050 (match_operand:MODEF 1 "register_operand" "0"))
14051 (match_operand:XF 2 "register_operand" "u")]
14053 (clobber (match_scratch:XF 3 "=2"))]
14054 "TARGET_USE_FANCY_MATH_387
14055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14056 || TARGET_MIX_SSE_I387)
14057 && flag_unsafe_math_optimizations"
14059 [(set_attr "type" "fpspc")
14060 (set_attr "mode" "XF")])
14062 (define_expand "log1pxf2"
14063 [(use (match_operand:XF 0 "register_operand" ""))
14064 (use (match_operand:XF 1 "register_operand" ""))]
14065 "TARGET_USE_FANCY_MATH_387
14066 && flag_unsafe_math_optimizations"
14068 if (optimize_insn_for_size_p ())
14071 ix86_emit_i387_log1p (operands[0], operands[1]);
14075 (define_expand "log1p<mode>2"
14076 [(use (match_operand:MODEF 0 "register_operand" ""))
14077 (use (match_operand:MODEF 1 "register_operand" ""))]
14078 "TARGET_USE_FANCY_MATH_387
14079 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14080 || TARGET_MIX_SSE_I387)
14081 && flag_unsafe_math_optimizations"
14085 if (optimize_insn_for_size_p ())
14088 op0 = gen_reg_rtx (XFmode);
14090 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14092 ix86_emit_i387_log1p (op0, operands[1]);
14093 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14097 (define_insn "fxtractxf3_i387"
14098 [(set (match_operand:XF 0 "register_operand" "=f")
14099 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14100 UNSPEC_XTRACT_FRACT))
14101 (set (match_operand:XF 1 "register_operand" "=u")
14102 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && flag_unsafe_math_optimizations"
14106 [(set_attr "type" "fpspc")
14107 (set_attr "mode" "XF")])
14109 (define_insn "fxtract_extend<mode>xf3_i387"
14110 [(set (match_operand:XF 0 "register_operand" "=f")
14111 (unspec:XF [(float_extend:XF
14112 (match_operand:MODEF 2 "register_operand" "0"))]
14113 UNSPEC_XTRACT_FRACT))
14114 (set (match_operand:XF 1 "register_operand" "=u")
14115 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14118 || TARGET_MIX_SSE_I387)
14119 && flag_unsafe_math_optimizations"
14121 [(set_attr "type" "fpspc")
14122 (set_attr "mode" "XF")])
14124 (define_expand "logbxf2"
14125 [(parallel [(set (match_dup 2)
14126 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14127 UNSPEC_XTRACT_FRACT))
14128 (set (match_operand:XF 0 "register_operand" "")
14129 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14130 "TARGET_USE_FANCY_MATH_387
14131 && flag_unsafe_math_optimizations"
14132 "operands[2] = gen_reg_rtx (XFmode);")
14134 (define_expand "logb<mode>2"
14135 [(use (match_operand:MODEF 0 "register_operand" ""))
14136 (use (match_operand:MODEF 1 "register_operand" ""))]
14137 "TARGET_USE_FANCY_MATH_387
14138 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14139 || TARGET_MIX_SSE_I387)
14140 && flag_unsafe_math_optimizations"
14142 rtx op0 = gen_reg_rtx (XFmode);
14143 rtx op1 = gen_reg_rtx (XFmode);
14145 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14150 (define_expand "ilogbxf2"
14151 [(use (match_operand:SI 0 "register_operand" ""))
14152 (use (match_operand:XF 1 "register_operand" ""))]
14153 "TARGET_USE_FANCY_MATH_387
14154 && flag_unsafe_math_optimizations"
14158 if (optimize_insn_for_size_p ())
14161 op0 = gen_reg_rtx (XFmode);
14162 op1 = gen_reg_rtx (XFmode);
14164 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14165 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14169 (define_expand "ilogb<mode>2"
14170 [(use (match_operand:SI 0 "register_operand" ""))
14171 (use (match_operand:MODEF 1 "register_operand" ""))]
14172 "TARGET_USE_FANCY_MATH_387
14173 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14174 || TARGET_MIX_SSE_I387)
14175 && flag_unsafe_math_optimizations"
14179 if (optimize_insn_for_size_p ())
14182 op0 = gen_reg_rtx (XFmode);
14183 op1 = gen_reg_rtx (XFmode);
14185 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14186 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14190 (define_insn "*f2xm1xf2_i387"
14191 [(set (match_operand:XF 0 "register_operand" "=f")
14192 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14194 "TARGET_USE_FANCY_MATH_387
14195 && flag_unsafe_math_optimizations"
14197 [(set_attr "type" "fpspc")
14198 (set_attr "mode" "XF")])
14200 (define_insn "*fscalexf4_i387"
14201 [(set (match_operand:XF 0 "register_operand" "=f")
14202 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14203 (match_operand:XF 3 "register_operand" "1")]
14204 UNSPEC_FSCALE_FRACT))
14205 (set (match_operand:XF 1 "register_operand" "=u")
14206 (unspec:XF [(match_dup 2) (match_dup 3)]
14207 UNSPEC_FSCALE_EXP))]
14208 "TARGET_USE_FANCY_MATH_387
14209 && flag_unsafe_math_optimizations"
14211 [(set_attr "type" "fpspc")
14212 (set_attr "mode" "XF")])
14214 (define_expand "expNcorexf3"
14215 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14216 (match_operand:XF 2 "register_operand" "")))
14217 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14218 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14219 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14220 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14221 (parallel [(set (match_operand:XF 0 "register_operand" "")
14222 (unspec:XF [(match_dup 8) (match_dup 4)]
14223 UNSPEC_FSCALE_FRACT))
14225 (unspec:XF [(match_dup 8) (match_dup 4)]
14226 UNSPEC_FSCALE_EXP))])]
14227 "TARGET_USE_FANCY_MATH_387
14228 && flag_unsafe_math_optimizations"
14232 if (optimize_insn_for_size_p ())
14235 for (i = 3; i < 10; i++)
14236 operands[i] = gen_reg_rtx (XFmode);
14238 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14241 (define_expand "expxf2"
14242 [(use (match_operand:XF 0 "register_operand" ""))
14243 (use (match_operand:XF 1 "register_operand" ""))]
14244 "TARGET_USE_FANCY_MATH_387
14245 && flag_unsafe_math_optimizations"
14249 if (optimize_insn_for_size_p ())
14252 op2 = gen_reg_rtx (XFmode);
14253 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14255 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14259 (define_expand "exp<mode>2"
14260 [(use (match_operand:MODEF 0 "register_operand" ""))
14261 (use (match_operand:MODEF 1 "general_operand" ""))]
14262 "TARGET_USE_FANCY_MATH_387
14263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14264 || TARGET_MIX_SSE_I387)
14265 && flag_unsafe_math_optimizations"
14269 if (optimize_insn_for_size_p ())
14272 op0 = gen_reg_rtx (XFmode);
14273 op1 = gen_reg_rtx (XFmode);
14275 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14276 emit_insn (gen_expxf2 (op0, op1));
14277 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14281 (define_expand "exp10xf2"
14282 [(use (match_operand:XF 0 "register_operand" ""))
14283 (use (match_operand:XF 1 "register_operand" ""))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && flag_unsafe_math_optimizations"
14289 if (optimize_insn_for_size_p ())
14292 op2 = gen_reg_rtx (XFmode);
14293 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14295 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14299 (define_expand "exp10<mode>2"
14300 [(use (match_operand:MODEF 0 "register_operand" ""))
14301 (use (match_operand:MODEF 1 "general_operand" ""))]
14302 "TARGET_USE_FANCY_MATH_387
14303 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14304 || TARGET_MIX_SSE_I387)
14305 && flag_unsafe_math_optimizations"
14309 if (optimize_insn_for_size_p ())
14312 op0 = gen_reg_rtx (XFmode);
14313 op1 = gen_reg_rtx (XFmode);
14315 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14316 emit_insn (gen_exp10xf2 (op0, op1));
14317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14321 (define_expand "exp2xf2"
14322 [(use (match_operand:XF 0 "register_operand" ""))
14323 (use (match_operand:XF 1 "register_operand" ""))]
14324 "TARGET_USE_FANCY_MATH_387
14325 && flag_unsafe_math_optimizations"
14329 if (optimize_insn_for_size_p ())
14332 op2 = gen_reg_rtx (XFmode);
14333 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14335 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14339 (define_expand "exp2<mode>2"
14340 [(use (match_operand:MODEF 0 "register_operand" ""))
14341 (use (match_operand:MODEF 1 "general_operand" ""))]
14342 "TARGET_USE_FANCY_MATH_387
14343 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14344 || TARGET_MIX_SSE_I387)
14345 && flag_unsafe_math_optimizations"
14349 if (optimize_insn_for_size_p ())
14352 op0 = gen_reg_rtx (XFmode);
14353 op1 = gen_reg_rtx (XFmode);
14355 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14356 emit_insn (gen_exp2xf2 (op0, op1));
14357 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14361 (define_expand "expm1xf2"
14362 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14364 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14365 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14366 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14367 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14368 (parallel [(set (match_dup 7)
14369 (unspec:XF [(match_dup 6) (match_dup 4)]
14370 UNSPEC_FSCALE_FRACT))
14372 (unspec:XF [(match_dup 6) (match_dup 4)]
14373 UNSPEC_FSCALE_EXP))])
14374 (parallel [(set (match_dup 10)
14375 (unspec:XF [(match_dup 9) (match_dup 8)]
14376 UNSPEC_FSCALE_FRACT))
14377 (set (match_dup 11)
14378 (unspec:XF [(match_dup 9) (match_dup 8)]
14379 UNSPEC_FSCALE_EXP))])
14380 (set (match_dup 12) (minus:XF (match_dup 10)
14381 (float_extend:XF (match_dup 13))))
14382 (set (match_operand:XF 0 "register_operand" "")
14383 (plus:XF (match_dup 12) (match_dup 7)))]
14384 "TARGET_USE_FANCY_MATH_387
14385 && flag_unsafe_math_optimizations"
14389 if (optimize_insn_for_size_p ())
14392 for (i = 2; i < 13; i++)
14393 operands[i] = gen_reg_rtx (XFmode);
14396 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14398 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14401 (define_expand "expm1<mode>2"
14402 [(use (match_operand:MODEF 0 "register_operand" ""))
14403 (use (match_operand:MODEF 1 "general_operand" ""))]
14404 "TARGET_USE_FANCY_MATH_387
14405 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14406 || TARGET_MIX_SSE_I387)
14407 && flag_unsafe_math_optimizations"
14411 if (optimize_insn_for_size_p ())
14414 op0 = gen_reg_rtx (XFmode);
14415 op1 = gen_reg_rtx (XFmode);
14417 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14418 emit_insn (gen_expm1xf2 (op0, op1));
14419 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14423 (define_expand "ldexpxf3"
14424 [(set (match_dup 3)
14425 (float:XF (match_operand:SI 2 "register_operand" "")))
14426 (parallel [(set (match_operand:XF 0 " register_operand" "")
14427 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14429 UNSPEC_FSCALE_FRACT))
14431 (unspec:XF [(match_dup 1) (match_dup 3)]
14432 UNSPEC_FSCALE_EXP))])]
14433 "TARGET_USE_FANCY_MATH_387
14434 && flag_unsafe_math_optimizations"
14436 if (optimize_insn_for_size_p ())
14439 operands[3] = gen_reg_rtx (XFmode);
14440 operands[4] = gen_reg_rtx (XFmode);
14443 (define_expand "ldexp<mode>3"
14444 [(use (match_operand:MODEF 0 "register_operand" ""))
14445 (use (match_operand:MODEF 1 "general_operand" ""))
14446 (use (match_operand:SI 2 "register_operand" ""))]
14447 "TARGET_USE_FANCY_MATH_387
14448 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14449 || TARGET_MIX_SSE_I387)
14450 && flag_unsafe_math_optimizations"
14454 if (optimize_insn_for_size_p ())
14457 op0 = gen_reg_rtx (XFmode);
14458 op1 = gen_reg_rtx (XFmode);
14460 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14461 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14462 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14466 (define_expand "scalbxf3"
14467 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14468 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14469 (match_operand:XF 2 "register_operand" "")]
14470 UNSPEC_FSCALE_FRACT))
14472 (unspec:XF [(match_dup 1) (match_dup 2)]
14473 UNSPEC_FSCALE_EXP))])]
14474 "TARGET_USE_FANCY_MATH_387
14475 && flag_unsafe_math_optimizations"
14477 if (optimize_insn_for_size_p ())
14480 operands[3] = gen_reg_rtx (XFmode);
14483 (define_expand "scalb<mode>3"
14484 [(use (match_operand:MODEF 0 "register_operand" ""))
14485 (use (match_operand:MODEF 1 "general_operand" ""))
14486 (use (match_operand:MODEF 2 "general_operand" ""))]
14487 "TARGET_USE_FANCY_MATH_387
14488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14489 || TARGET_MIX_SSE_I387)
14490 && flag_unsafe_math_optimizations"
14494 if (optimize_insn_for_size_p ())
14497 op0 = gen_reg_rtx (XFmode);
14498 op1 = gen_reg_rtx (XFmode);
14499 op2 = gen_reg_rtx (XFmode);
14501 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14502 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14503 emit_insn (gen_scalbxf3 (op0, op1, op2));
14504 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14508 (define_expand "significandxf2"
14509 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14510 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14511 UNSPEC_XTRACT_FRACT))
14513 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14514 "TARGET_USE_FANCY_MATH_387
14515 && flag_unsafe_math_optimizations"
14516 "operands[2] = gen_reg_rtx (XFmode);")
14518 (define_expand "significand<mode>2"
14519 [(use (match_operand:MODEF 0 "register_operand" ""))
14520 (use (match_operand:MODEF 1 "register_operand" ""))]
14521 "TARGET_USE_FANCY_MATH_387
14522 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14523 || TARGET_MIX_SSE_I387)
14524 && flag_unsafe_math_optimizations"
14526 rtx op0 = gen_reg_rtx (XFmode);
14527 rtx op1 = gen_reg_rtx (XFmode);
14529 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14530 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14535 (define_insn "sse4_1_round<mode>2"
14536 [(set (match_operand:MODEF 0 "register_operand" "=x")
14537 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14538 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14541 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14542 [(set_attr "type" "ssecvt")
14543 (set_attr "prefix_extra" "1")
14544 (set_attr "prefix" "maybe_vex")
14545 (set_attr "mode" "<MODE>")])
14547 (define_insn "rintxf2"
14548 [(set (match_operand:XF 0 "register_operand" "=f")
14549 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14551 "TARGET_USE_FANCY_MATH_387
14552 && flag_unsafe_math_optimizations"
14554 [(set_attr "type" "fpspc")
14555 (set_attr "mode" "XF")])
14557 (define_expand "rint<mode>2"
14558 [(use (match_operand:MODEF 0 "register_operand" ""))
14559 (use (match_operand:MODEF 1 "register_operand" ""))]
14560 "(TARGET_USE_FANCY_MATH_387
14561 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14562 || TARGET_MIX_SSE_I387)
14563 && flag_unsafe_math_optimizations)
14564 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14565 && !flag_trapping_math)"
14567 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14568 && !flag_trapping_math)
14571 emit_insn (gen_sse4_1_round<mode>2
14572 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14573 else if (optimize_insn_for_size_p ())
14576 ix86_expand_rint (operands[0], operands[1]);
14580 rtx op0 = gen_reg_rtx (XFmode);
14581 rtx op1 = gen_reg_rtx (XFmode);
14583 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14584 emit_insn (gen_rintxf2 (op0, op1));
14586 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14591 (define_expand "round<mode>2"
14592 [(match_operand:X87MODEF 0 "register_operand" "")
14593 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14594 "(TARGET_USE_FANCY_MATH_387
14595 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14596 || TARGET_MIX_SSE_I387)
14597 && flag_unsafe_math_optimizations)
14598 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14599 && !flag_trapping_math && !flag_rounding_math)"
14601 if (optimize_insn_for_size_p ())
14604 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14605 && !flag_trapping_math && !flag_rounding_math)
14609 operands[1] = force_reg (<MODE>mode, operands[1]);
14610 ix86_expand_round_sse4 (operands[0], operands[1]);
14612 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14613 ix86_expand_round (operands[0], operands[1]);
14615 ix86_expand_rounddf_32 (operands[0], operands[1]);
14619 operands[1] = force_reg (<MODE>mode, operands[1]);
14620 ix86_emit_i387_round (operands[0], operands[1]);
14625 (define_insn_and_split "*fistdi2_1"
14626 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14627 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14629 "TARGET_USE_FANCY_MATH_387
14630 && can_create_pseudo_p ()"
14635 if (memory_operand (operands[0], VOIDmode))
14636 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14639 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14640 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14645 [(set_attr "type" "fpspc")
14646 (set_attr "mode" "DI")])
14648 (define_insn "fistdi2"
14649 [(set (match_operand:DI 0 "memory_operand" "=m")
14650 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14652 (clobber (match_scratch:XF 2 "=&1f"))]
14653 "TARGET_USE_FANCY_MATH_387"
14654 "* return output_fix_trunc (insn, operands, false);"
14655 [(set_attr "type" "fpspc")
14656 (set_attr "mode" "DI")])
14658 (define_insn "fistdi2_with_temp"
14659 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14660 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14662 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14663 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14664 "TARGET_USE_FANCY_MATH_387"
14666 [(set_attr "type" "fpspc")
14667 (set_attr "mode" "DI")])
14670 [(set (match_operand:DI 0 "register_operand" "")
14671 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14673 (clobber (match_operand:DI 2 "memory_operand" ""))
14674 (clobber (match_scratch 3 ""))]
14676 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14677 (clobber (match_dup 3))])
14678 (set (match_dup 0) (match_dup 2))])
14681 [(set (match_operand:DI 0 "memory_operand" "")
14682 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14684 (clobber (match_operand:DI 2 "memory_operand" ""))
14685 (clobber (match_scratch 3 ""))]
14687 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14688 (clobber (match_dup 3))])])
14690 (define_insn_and_split "*fist<mode>2_1"
14691 [(set (match_operand:SWI24 0 "register_operand" "")
14692 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14694 "TARGET_USE_FANCY_MATH_387
14695 && can_create_pseudo_p ()"
14700 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14701 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14705 [(set_attr "type" "fpspc")
14706 (set_attr "mode" "<MODE>")])
14708 (define_insn "fist<mode>2"
14709 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14710 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14712 "TARGET_USE_FANCY_MATH_387"
14713 "* return output_fix_trunc (insn, operands, false);"
14714 [(set_attr "type" "fpspc")
14715 (set_attr "mode" "<MODE>")])
14717 (define_insn "fist<mode>2_with_temp"
14718 [(set (match_operand:SWI24 0 "register_operand" "=r")
14719 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14721 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14722 "TARGET_USE_FANCY_MATH_387"
14724 [(set_attr "type" "fpspc")
14725 (set_attr "mode" "<MODE>")])
14728 [(set (match_operand:SWI24 0 "register_operand" "")
14729 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14731 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14733 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14734 (set (match_dup 0) (match_dup 2))])
14737 [(set (match_operand:SWI24 0 "memory_operand" "")
14738 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14740 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14742 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14744 (define_expand "lrintxf<mode>2"
14745 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14746 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14748 "TARGET_USE_FANCY_MATH_387")
14750 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14751 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14752 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14753 UNSPEC_FIX_NOTRUNC))]
14754 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14755 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14757 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14758 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14759 (match_operand:X87MODEF 1 "register_operand" "")]
14760 "(TARGET_USE_FANCY_MATH_387
14761 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14762 || TARGET_MIX_SSE_I387)
14763 && flag_unsafe_math_optimizations)
14764 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14765 && <SWI248x:MODE>mode != HImode
14766 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14767 && !flag_trapping_math && !flag_rounding_math)"
14769 if (optimize_insn_for_size_p ())
14772 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14773 && <SWI248x:MODE>mode != HImode
14774 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14775 && !flag_trapping_math && !flag_rounding_math)
14776 ix86_expand_lround (operands[0], operands[1]);
14778 ix86_emit_i387_round (operands[0], operands[1]);
14782 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14783 (define_insn_and_split "frndintxf2_floor"
14784 [(set (match_operand:XF 0 "register_operand" "")
14785 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14786 UNSPEC_FRNDINT_FLOOR))
14787 (clobber (reg:CC FLAGS_REG))]
14788 "TARGET_USE_FANCY_MATH_387
14789 && flag_unsafe_math_optimizations
14790 && can_create_pseudo_p ()"
14795 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14797 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14798 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14800 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14801 operands[2], operands[3]));
14804 [(set_attr "type" "frndint")
14805 (set_attr "i387_cw" "floor")
14806 (set_attr "mode" "XF")])
14808 (define_insn "frndintxf2_floor_i387"
14809 [(set (match_operand:XF 0 "register_operand" "=f")
14810 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14811 UNSPEC_FRNDINT_FLOOR))
14812 (use (match_operand:HI 2 "memory_operand" "m"))
14813 (use (match_operand:HI 3 "memory_operand" "m"))]
14814 "TARGET_USE_FANCY_MATH_387
14815 && flag_unsafe_math_optimizations"
14816 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14817 [(set_attr "type" "frndint")
14818 (set_attr "i387_cw" "floor")
14819 (set_attr "mode" "XF")])
14821 (define_expand "floorxf2"
14822 [(use (match_operand:XF 0 "register_operand" ""))
14823 (use (match_operand:XF 1 "register_operand" ""))]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations"
14827 if (optimize_insn_for_size_p ())
14829 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14833 (define_expand "floor<mode>2"
14834 [(use (match_operand:MODEF 0 "register_operand" ""))
14835 (use (match_operand:MODEF 1 "register_operand" ""))]
14836 "(TARGET_USE_FANCY_MATH_387
14837 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14838 || TARGET_MIX_SSE_I387)
14839 && flag_unsafe_math_optimizations)
14840 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14841 && !flag_trapping_math)"
14843 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14844 && !flag_trapping_math)
14847 emit_insn (gen_sse4_1_round<mode>2
14848 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14849 else if (optimize_insn_for_size_p ())
14851 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14852 ix86_expand_floorceil (operands[0], operands[1], true);
14854 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14860 if (optimize_insn_for_size_p ())
14863 op0 = gen_reg_rtx (XFmode);
14864 op1 = gen_reg_rtx (XFmode);
14865 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14866 emit_insn (gen_frndintxf2_floor (op0, op1));
14868 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14873 (define_insn_and_split "*fist<mode>2_floor_1"
14874 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14875 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14876 UNSPEC_FIST_FLOOR))
14877 (clobber (reg:CC FLAGS_REG))]
14878 "TARGET_USE_FANCY_MATH_387
14879 && flag_unsafe_math_optimizations
14880 && can_create_pseudo_p ()"
14885 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14887 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14888 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14889 if (memory_operand (operands[0], VOIDmode))
14890 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14891 operands[2], operands[3]));
14894 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14895 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14896 operands[2], operands[3],
14901 [(set_attr "type" "fistp")
14902 (set_attr "i387_cw" "floor")
14903 (set_attr "mode" "<MODE>")])
14905 (define_insn "fistdi2_floor"
14906 [(set (match_operand:DI 0 "memory_operand" "=m")
14907 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14908 UNSPEC_FIST_FLOOR))
14909 (use (match_operand:HI 2 "memory_operand" "m"))
14910 (use (match_operand:HI 3 "memory_operand" "m"))
14911 (clobber (match_scratch:XF 4 "=&1f"))]
14912 "TARGET_USE_FANCY_MATH_387
14913 && flag_unsafe_math_optimizations"
14914 "* return output_fix_trunc (insn, operands, false);"
14915 [(set_attr "type" "fistp")
14916 (set_attr "i387_cw" "floor")
14917 (set_attr "mode" "DI")])
14919 (define_insn "fistdi2_floor_with_temp"
14920 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14921 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14922 UNSPEC_FIST_FLOOR))
14923 (use (match_operand:HI 2 "memory_operand" "m,m"))
14924 (use (match_operand:HI 3 "memory_operand" "m,m"))
14925 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14926 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14927 "TARGET_USE_FANCY_MATH_387
14928 && flag_unsafe_math_optimizations"
14930 [(set_attr "type" "fistp")
14931 (set_attr "i387_cw" "floor")
14932 (set_attr "mode" "DI")])
14935 [(set (match_operand:DI 0 "register_operand" "")
14936 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14937 UNSPEC_FIST_FLOOR))
14938 (use (match_operand:HI 2 "memory_operand" ""))
14939 (use (match_operand:HI 3 "memory_operand" ""))
14940 (clobber (match_operand:DI 4 "memory_operand" ""))
14941 (clobber (match_scratch 5 ""))]
14943 [(parallel [(set (match_dup 4)
14944 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14945 (use (match_dup 2))
14946 (use (match_dup 3))
14947 (clobber (match_dup 5))])
14948 (set (match_dup 0) (match_dup 4))])
14951 [(set (match_operand:DI 0 "memory_operand" "")
14952 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14953 UNSPEC_FIST_FLOOR))
14954 (use (match_operand:HI 2 "memory_operand" ""))
14955 (use (match_operand:HI 3 "memory_operand" ""))
14956 (clobber (match_operand:DI 4 "memory_operand" ""))
14957 (clobber (match_scratch 5 ""))]
14959 [(parallel [(set (match_dup 0)
14960 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14961 (use (match_dup 2))
14962 (use (match_dup 3))
14963 (clobber (match_dup 5))])])
14965 (define_insn "fist<mode>2_floor"
14966 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14967 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14968 UNSPEC_FIST_FLOOR))
14969 (use (match_operand:HI 2 "memory_operand" "m"))
14970 (use (match_operand:HI 3 "memory_operand" "m"))]
14971 "TARGET_USE_FANCY_MATH_387
14972 && flag_unsafe_math_optimizations"
14973 "* return output_fix_trunc (insn, operands, false);"
14974 [(set_attr "type" "fistp")
14975 (set_attr "i387_cw" "floor")
14976 (set_attr "mode" "<MODE>")])
14978 (define_insn "fist<mode>2_floor_with_temp"
14979 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
14980 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
14981 UNSPEC_FIST_FLOOR))
14982 (use (match_operand:HI 2 "memory_operand" "m,m"))
14983 (use (match_operand:HI 3 "memory_operand" "m,m"))
14984 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
14985 "TARGET_USE_FANCY_MATH_387
14986 && flag_unsafe_math_optimizations"
14988 [(set_attr "type" "fistp")
14989 (set_attr "i387_cw" "floor")
14990 (set_attr "mode" "<MODE>")])
14993 [(set (match_operand:SWI24 0 "register_operand" "")
14994 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14995 UNSPEC_FIST_FLOOR))
14996 (use (match_operand:HI 2 "memory_operand" ""))
14997 (use (match_operand:HI 3 "memory_operand" ""))
14998 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15000 [(parallel [(set (match_dup 4)
15001 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15002 (use (match_dup 2))
15003 (use (match_dup 3))])
15004 (set (match_dup 0) (match_dup 4))])
15007 [(set (match_operand:SWI24 0 "memory_operand" "")
15008 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15009 UNSPEC_FIST_FLOOR))
15010 (use (match_operand:HI 2 "memory_operand" ""))
15011 (use (match_operand:HI 3 "memory_operand" ""))
15012 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15014 [(parallel [(set (match_dup 0)
15015 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15016 (use (match_dup 2))
15017 (use (match_dup 3))])])
15019 (define_expand "lfloorxf<mode>2"
15020 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15021 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15022 UNSPEC_FIST_FLOOR))
15023 (clobber (reg:CC FLAGS_REG))])]
15024 "TARGET_USE_FANCY_MATH_387
15025 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15026 && flag_unsafe_math_optimizations")
15028 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15029 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15030 (match_operand:MODEF 1 "register_operand" "")]
15031 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15032 && !flag_trapping_math"
15034 if (TARGET_64BIT && optimize_insn_for_size_p ())
15036 ix86_expand_lfloorceil (operands[0], operands[1], true);
15040 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15041 (define_insn_and_split "frndintxf2_ceil"
15042 [(set (match_operand:XF 0 "register_operand" "")
15043 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15044 UNSPEC_FRNDINT_CEIL))
15045 (clobber (reg:CC FLAGS_REG))]
15046 "TARGET_USE_FANCY_MATH_387
15047 && flag_unsafe_math_optimizations
15048 && can_create_pseudo_p ()"
15053 ix86_optimize_mode_switching[I387_CEIL] = 1;
15055 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15056 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15058 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15059 operands[2], operands[3]));
15062 [(set_attr "type" "frndint")
15063 (set_attr "i387_cw" "ceil")
15064 (set_attr "mode" "XF")])
15066 (define_insn "frndintxf2_ceil_i387"
15067 [(set (match_operand:XF 0 "register_operand" "=f")
15068 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15069 UNSPEC_FRNDINT_CEIL))
15070 (use (match_operand:HI 2 "memory_operand" "m"))
15071 (use (match_operand:HI 3 "memory_operand" "m"))]
15072 "TARGET_USE_FANCY_MATH_387
15073 && flag_unsafe_math_optimizations"
15074 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15075 [(set_attr "type" "frndint")
15076 (set_attr "i387_cw" "ceil")
15077 (set_attr "mode" "XF")])
15079 (define_expand "ceilxf2"
15080 [(use (match_operand:XF 0 "register_operand" ""))
15081 (use (match_operand:XF 1 "register_operand" ""))]
15082 "TARGET_USE_FANCY_MATH_387
15083 && flag_unsafe_math_optimizations"
15085 if (optimize_insn_for_size_p ())
15087 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15091 (define_expand "ceil<mode>2"
15092 [(use (match_operand:MODEF 0 "register_operand" ""))
15093 (use (match_operand:MODEF 1 "register_operand" ""))]
15094 "(TARGET_USE_FANCY_MATH_387
15095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15096 || TARGET_MIX_SSE_I387)
15097 && flag_unsafe_math_optimizations)
15098 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15099 && !flag_trapping_math)"
15101 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15102 && !flag_trapping_math)
15105 emit_insn (gen_sse4_1_round<mode>2
15106 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15107 else if (optimize_insn_for_size_p ())
15109 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15110 ix86_expand_floorceil (operands[0], operands[1], false);
15112 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15118 if (optimize_insn_for_size_p ())
15121 op0 = gen_reg_rtx (XFmode);
15122 op1 = gen_reg_rtx (XFmode);
15123 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15124 emit_insn (gen_frndintxf2_ceil (op0, op1));
15126 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15131 (define_insn_and_split "*fist<mode>2_ceil_1"
15132 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15133 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15135 (clobber (reg:CC FLAGS_REG))]
15136 "TARGET_USE_FANCY_MATH_387
15137 && flag_unsafe_math_optimizations
15138 && can_create_pseudo_p ()"
15143 ix86_optimize_mode_switching[I387_CEIL] = 1;
15145 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15146 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15147 if (memory_operand (operands[0], VOIDmode))
15148 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15149 operands[2], operands[3]));
15152 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15153 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15154 operands[2], operands[3],
15159 [(set_attr "type" "fistp")
15160 (set_attr "i387_cw" "ceil")
15161 (set_attr "mode" "<MODE>")])
15163 (define_insn "fistdi2_ceil"
15164 [(set (match_operand:DI 0 "memory_operand" "=m")
15165 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15167 (use (match_operand:HI 2 "memory_operand" "m"))
15168 (use (match_operand:HI 3 "memory_operand" "m"))
15169 (clobber (match_scratch:XF 4 "=&1f"))]
15170 "TARGET_USE_FANCY_MATH_387
15171 && flag_unsafe_math_optimizations"
15172 "* return output_fix_trunc (insn, operands, false);"
15173 [(set_attr "type" "fistp")
15174 (set_attr "i387_cw" "ceil")
15175 (set_attr "mode" "DI")])
15177 (define_insn "fistdi2_ceil_with_temp"
15178 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15179 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15181 (use (match_operand:HI 2 "memory_operand" "m,m"))
15182 (use (match_operand:HI 3 "memory_operand" "m,m"))
15183 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15184 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15185 "TARGET_USE_FANCY_MATH_387
15186 && flag_unsafe_math_optimizations"
15188 [(set_attr "type" "fistp")
15189 (set_attr "i387_cw" "ceil")
15190 (set_attr "mode" "DI")])
15193 [(set (match_operand:DI 0 "register_operand" "")
15194 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15196 (use (match_operand:HI 2 "memory_operand" ""))
15197 (use (match_operand:HI 3 "memory_operand" ""))
15198 (clobber (match_operand:DI 4 "memory_operand" ""))
15199 (clobber (match_scratch 5 ""))]
15201 [(parallel [(set (match_dup 4)
15202 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15203 (use (match_dup 2))
15204 (use (match_dup 3))
15205 (clobber (match_dup 5))])
15206 (set (match_dup 0) (match_dup 4))])
15209 [(set (match_operand:DI 0 "memory_operand" "")
15210 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15212 (use (match_operand:HI 2 "memory_operand" ""))
15213 (use (match_operand:HI 3 "memory_operand" ""))
15214 (clobber (match_operand:DI 4 "memory_operand" ""))
15215 (clobber (match_scratch 5 ""))]
15217 [(parallel [(set (match_dup 0)
15218 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15219 (use (match_dup 2))
15220 (use (match_dup 3))
15221 (clobber (match_dup 5))])])
15223 (define_insn "fist<mode>2_ceil"
15224 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15225 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15227 (use (match_operand:HI 2 "memory_operand" "m"))
15228 (use (match_operand:HI 3 "memory_operand" "m"))]
15229 "TARGET_USE_FANCY_MATH_387
15230 && flag_unsafe_math_optimizations"
15231 "* return output_fix_trunc (insn, operands, false);"
15232 [(set_attr "type" "fistp")
15233 (set_attr "i387_cw" "ceil")
15234 (set_attr "mode" "<MODE>")])
15236 (define_insn "fist<mode>2_ceil_with_temp"
15237 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15238 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15240 (use (match_operand:HI 2 "memory_operand" "m,m"))
15241 (use (match_operand:HI 3 "memory_operand" "m,m"))
15242 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15243 "TARGET_USE_FANCY_MATH_387
15244 && flag_unsafe_math_optimizations"
15246 [(set_attr "type" "fistp")
15247 (set_attr "i387_cw" "ceil")
15248 (set_attr "mode" "<MODE>")])
15251 [(set (match_operand:SWI24 0 "register_operand" "")
15252 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15254 (use (match_operand:HI 2 "memory_operand" ""))
15255 (use (match_operand:HI 3 "memory_operand" ""))
15256 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15258 [(parallel [(set (match_dup 4)
15259 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15260 (use (match_dup 2))
15261 (use (match_dup 3))])
15262 (set (match_dup 0) (match_dup 4))])
15265 [(set (match_operand:SWI24 0 "memory_operand" "")
15266 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15268 (use (match_operand:HI 2 "memory_operand" ""))
15269 (use (match_operand:HI 3 "memory_operand" ""))
15270 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15272 [(parallel [(set (match_dup 0)
15273 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15274 (use (match_dup 2))
15275 (use (match_dup 3))])])
15277 (define_expand "lceilxf<mode>2"
15278 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15279 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15281 (clobber (reg:CC FLAGS_REG))])]
15282 "TARGET_USE_FANCY_MATH_387
15283 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15284 && flag_unsafe_math_optimizations")
15286 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15287 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15288 (match_operand:MODEF 1 "register_operand" "")]
15289 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15290 && !flag_trapping_math"
15292 ix86_expand_lfloorceil (operands[0], operands[1], false);
15296 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15297 (define_insn_and_split "frndintxf2_trunc"
15298 [(set (match_operand:XF 0 "register_operand" "")
15299 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15300 UNSPEC_FRNDINT_TRUNC))
15301 (clobber (reg:CC FLAGS_REG))]
15302 "TARGET_USE_FANCY_MATH_387
15303 && flag_unsafe_math_optimizations
15304 && can_create_pseudo_p ()"
15309 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15311 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15312 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15314 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15315 operands[2], operands[3]));
15318 [(set_attr "type" "frndint")
15319 (set_attr "i387_cw" "trunc")
15320 (set_attr "mode" "XF")])
15322 (define_insn "frndintxf2_trunc_i387"
15323 [(set (match_operand:XF 0 "register_operand" "=f")
15324 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15325 UNSPEC_FRNDINT_TRUNC))
15326 (use (match_operand:HI 2 "memory_operand" "m"))
15327 (use (match_operand:HI 3 "memory_operand" "m"))]
15328 "TARGET_USE_FANCY_MATH_387
15329 && flag_unsafe_math_optimizations"
15330 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15331 [(set_attr "type" "frndint")
15332 (set_attr "i387_cw" "trunc")
15333 (set_attr "mode" "XF")])
15335 (define_expand "btruncxf2"
15336 [(use (match_operand:XF 0 "register_operand" ""))
15337 (use (match_operand:XF 1 "register_operand" ""))]
15338 "TARGET_USE_FANCY_MATH_387
15339 && flag_unsafe_math_optimizations"
15341 if (optimize_insn_for_size_p ())
15343 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15347 (define_expand "btrunc<mode>2"
15348 [(use (match_operand:MODEF 0 "register_operand" ""))
15349 (use (match_operand:MODEF 1 "register_operand" ""))]
15350 "(TARGET_USE_FANCY_MATH_387
15351 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15352 || TARGET_MIX_SSE_I387)
15353 && flag_unsafe_math_optimizations)
15354 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15355 && !flag_trapping_math)"
15357 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15358 && !flag_trapping_math)
15361 emit_insn (gen_sse4_1_round<mode>2
15362 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15363 else if (optimize_insn_for_size_p ())
15365 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15366 ix86_expand_trunc (operands[0], operands[1]);
15368 ix86_expand_truncdf_32 (operands[0], operands[1]);
15374 if (optimize_insn_for_size_p ())
15377 op0 = gen_reg_rtx (XFmode);
15378 op1 = gen_reg_rtx (XFmode);
15379 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15380 emit_insn (gen_frndintxf2_trunc (op0, op1));
15382 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15387 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15388 (define_insn_and_split "frndintxf2_mask_pm"
15389 [(set (match_operand:XF 0 "register_operand" "")
15390 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15391 UNSPEC_FRNDINT_MASK_PM))
15392 (clobber (reg:CC FLAGS_REG))]
15393 "TARGET_USE_FANCY_MATH_387
15394 && flag_unsafe_math_optimizations
15395 && can_create_pseudo_p ()"
15400 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15402 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15403 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15405 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15406 operands[2], operands[3]));
15409 [(set_attr "type" "frndint")
15410 (set_attr "i387_cw" "mask_pm")
15411 (set_attr "mode" "XF")])
15413 (define_insn "frndintxf2_mask_pm_i387"
15414 [(set (match_operand:XF 0 "register_operand" "=f")
15415 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15416 UNSPEC_FRNDINT_MASK_PM))
15417 (use (match_operand:HI 2 "memory_operand" "m"))
15418 (use (match_operand:HI 3 "memory_operand" "m"))]
15419 "TARGET_USE_FANCY_MATH_387
15420 && flag_unsafe_math_optimizations"
15421 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15422 [(set_attr "type" "frndint")
15423 (set_attr "i387_cw" "mask_pm")
15424 (set_attr "mode" "XF")])
15426 (define_expand "nearbyintxf2"
15427 [(use (match_operand:XF 0 "register_operand" ""))
15428 (use (match_operand:XF 1 "register_operand" ""))]
15429 "TARGET_USE_FANCY_MATH_387
15430 && flag_unsafe_math_optimizations"
15432 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15436 (define_expand "nearbyint<mode>2"
15437 [(use (match_operand:MODEF 0 "register_operand" ""))
15438 (use (match_operand:MODEF 1 "register_operand" ""))]
15439 "TARGET_USE_FANCY_MATH_387
15440 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15441 || TARGET_MIX_SSE_I387)
15442 && flag_unsafe_math_optimizations"
15444 rtx op0 = gen_reg_rtx (XFmode);
15445 rtx op1 = gen_reg_rtx (XFmode);
15447 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15448 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15450 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15454 (define_insn "fxam<mode>2_i387"
15455 [(set (match_operand:HI 0 "register_operand" "=a")
15457 [(match_operand:X87MODEF 1 "register_operand" "f")]
15459 "TARGET_USE_FANCY_MATH_387"
15460 "fxam\n\tfnstsw\t%0"
15461 [(set_attr "type" "multi")
15462 (set_attr "length" "4")
15463 (set_attr "unit" "i387")
15464 (set_attr "mode" "<MODE>")])
15466 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15467 [(set (match_operand:HI 0 "register_operand" "")
15469 [(match_operand:MODEF 1 "memory_operand" "")]
15471 "TARGET_USE_FANCY_MATH_387
15472 && can_create_pseudo_p ()"
15475 [(set (match_dup 2)(match_dup 1))
15477 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15479 operands[2] = gen_reg_rtx (<MODE>mode);
15481 MEM_VOLATILE_P (operands[1]) = 1;
15483 [(set_attr "type" "multi")
15484 (set_attr "unit" "i387")
15485 (set_attr "mode" "<MODE>")])
15487 (define_expand "isinfxf2"
15488 [(use (match_operand:SI 0 "register_operand" ""))
15489 (use (match_operand:XF 1 "register_operand" ""))]
15490 "TARGET_USE_FANCY_MATH_387
15491 && TARGET_C99_FUNCTIONS"
15493 rtx mask = GEN_INT (0x45);
15494 rtx val = GEN_INT (0x05);
15498 rtx scratch = gen_reg_rtx (HImode);
15499 rtx res = gen_reg_rtx (QImode);
15501 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15503 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15504 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15505 cond = gen_rtx_fmt_ee (EQ, QImode,
15506 gen_rtx_REG (CCmode, FLAGS_REG),
15508 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15509 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15513 (define_expand "isinf<mode>2"
15514 [(use (match_operand:SI 0 "register_operand" ""))
15515 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15516 "TARGET_USE_FANCY_MATH_387
15517 && TARGET_C99_FUNCTIONS
15518 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15520 rtx mask = GEN_INT (0x45);
15521 rtx val = GEN_INT (0x05);
15525 rtx scratch = gen_reg_rtx (HImode);
15526 rtx res = gen_reg_rtx (QImode);
15528 /* Remove excess precision by forcing value through memory. */
15529 if (memory_operand (operands[1], VOIDmode))
15530 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15533 enum ix86_stack_slot slot = (virtuals_instantiated
15536 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15538 emit_move_insn (temp, operands[1]);
15539 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15542 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15543 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15544 cond = gen_rtx_fmt_ee (EQ, QImode,
15545 gen_rtx_REG (CCmode, FLAGS_REG),
15547 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15548 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15552 (define_expand "signbitxf2"
15553 [(use (match_operand:SI 0 "register_operand" ""))
15554 (use (match_operand:XF 1 "register_operand" ""))]
15555 "TARGET_USE_FANCY_MATH_387"
15557 rtx scratch = gen_reg_rtx (HImode);
15559 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15560 emit_insn (gen_andsi3 (operands[0],
15561 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15565 (define_insn "movmsk_df"
15566 [(set (match_operand:SI 0 "register_operand" "=r")
15568 [(match_operand:DF 1 "register_operand" "x")]
15570 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15571 "%vmovmskpd\t{%1, %0|%0, %1}"
15572 [(set_attr "type" "ssemov")
15573 (set_attr "prefix" "maybe_vex")
15574 (set_attr "mode" "DF")])
15576 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15577 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15578 (define_expand "signbitdf2"
15579 [(use (match_operand:SI 0 "register_operand" ""))
15580 (use (match_operand:DF 1 "register_operand" ""))]
15581 "TARGET_USE_FANCY_MATH_387
15582 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15584 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15586 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15587 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15591 rtx scratch = gen_reg_rtx (HImode);
15593 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15594 emit_insn (gen_andsi3 (operands[0],
15595 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15600 (define_expand "signbitsf2"
15601 [(use (match_operand:SI 0 "register_operand" ""))
15602 (use (match_operand:SF 1 "register_operand" ""))]
15603 "TARGET_USE_FANCY_MATH_387
15604 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15606 rtx scratch = gen_reg_rtx (HImode);
15608 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15609 emit_insn (gen_andsi3 (operands[0],
15610 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15614 ;; Block operation instructions
15617 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15620 [(set_attr "length" "1")
15621 (set_attr "length_immediate" "0")
15622 (set_attr "modrm" "0")])
15624 (define_expand "movmem<mode>"
15625 [(use (match_operand:BLK 0 "memory_operand" ""))
15626 (use (match_operand:BLK 1 "memory_operand" ""))
15627 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15628 (use (match_operand:SWI48 3 "const_int_operand" ""))
15629 (use (match_operand:SI 4 "const_int_operand" ""))
15630 (use (match_operand:SI 5 "const_int_operand" ""))]
15633 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15634 operands[4], operands[5]))
15640 ;; Most CPUs don't like single string operations
15641 ;; Handle this case here to simplify previous expander.
15643 (define_expand "strmov"
15644 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15645 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15646 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15647 (clobber (reg:CC FLAGS_REG))])
15648 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15649 (clobber (reg:CC FLAGS_REG))])]
15652 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15654 /* If .md ever supports :P for Pmode, these can be directly
15655 in the pattern above. */
15656 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15657 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15659 /* Can't use this if the user has appropriated esi or edi. */
15660 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15661 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15663 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15664 operands[2], operands[3],
15665 operands[5], operands[6]));
15669 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15672 (define_expand "strmov_singleop"
15673 [(parallel [(set (match_operand 1 "memory_operand" "")
15674 (match_operand 3 "memory_operand" ""))
15675 (set (match_operand 0 "register_operand" "")
15676 (match_operand 4 "" ""))
15677 (set (match_operand 2 "register_operand" "")
15678 (match_operand 5 "" ""))])]
15680 "ix86_current_function_needs_cld = 1;")
15682 (define_insn "*strmovdi_rex_1"
15683 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15684 (mem:DI (match_operand:P 3 "register_operand" "1")))
15685 (set (match_operand:P 0 "register_operand" "=D")
15686 (plus:P (match_dup 2)
15688 (set (match_operand:P 1 "register_operand" "=S")
15689 (plus:P (match_dup 3)
15692 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15694 [(set_attr "type" "str")
15695 (set_attr "memory" "both")
15696 (set_attr "mode" "DI")])
15698 (define_insn "*strmovsi_1"
15699 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15700 (mem:SI (match_operand:P 3 "register_operand" "1")))
15701 (set (match_operand:P 0 "register_operand" "=D")
15702 (plus:P (match_dup 2)
15704 (set (match_operand:P 1 "register_operand" "=S")
15705 (plus:P (match_dup 3)
15707 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15709 [(set_attr "type" "str")
15710 (set_attr "memory" "both")
15711 (set_attr "mode" "SI")])
15713 (define_insn "*strmovhi_1"
15714 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15715 (mem:HI (match_operand:P 3 "register_operand" "1")))
15716 (set (match_operand:P 0 "register_operand" "=D")
15717 (plus:P (match_dup 2)
15719 (set (match_operand:P 1 "register_operand" "=S")
15720 (plus:P (match_dup 3)
15722 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15724 [(set_attr "type" "str")
15725 (set_attr "memory" "both")
15726 (set_attr "mode" "HI")])
15728 (define_insn "*strmovqi_1"
15729 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15730 (mem:QI (match_operand:P 3 "register_operand" "1")))
15731 (set (match_operand:P 0 "register_operand" "=D")
15732 (plus:P (match_dup 2)
15734 (set (match_operand:P 1 "register_operand" "=S")
15735 (plus:P (match_dup 3)
15737 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15739 [(set_attr "type" "str")
15740 (set_attr "memory" "both")
15741 (set (attr "prefix_rex")
15743 (match_test "<P:MODE>mode == DImode")
15745 (const_string "*")))
15746 (set_attr "mode" "QI")])
15748 (define_expand "rep_mov"
15749 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15750 (set (match_operand 0 "register_operand" "")
15751 (match_operand 5 "" ""))
15752 (set (match_operand 2 "register_operand" "")
15753 (match_operand 6 "" ""))
15754 (set (match_operand 1 "memory_operand" "")
15755 (match_operand 3 "memory_operand" ""))
15756 (use (match_dup 4))])]
15758 "ix86_current_function_needs_cld = 1;")
15760 (define_insn "*rep_movdi_rex64"
15761 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15762 (set (match_operand:P 0 "register_operand" "=D")
15763 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15765 (match_operand:P 3 "register_operand" "0")))
15766 (set (match_operand:P 1 "register_operand" "=S")
15767 (plus:P (ashift:P (match_dup 5) (const_int 3))
15768 (match_operand:P 4 "register_operand" "1")))
15769 (set (mem:BLK (match_dup 3))
15770 (mem:BLK (match_dup 4)))
15771 (use (match_dup 5))]
15773 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15775 [(set_attr "type" "str")
15776 (set_attr "prefix_rep" "1")
15777 (set_attr "memory" "both")
15778 (set_attr "mode" "DI")])
15780 (define_insn "*rep_movsi"
15781 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15782 (set (match_operand:P 0 "register_operand" "=D")
15783 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15785 (match_operand:P 3 "register_operand" "0")))
15786 (set (match_operand:P 1 "register_operand" "=S")
15787 (plus:P (ashift:P (match_dup 5) (const_int 2))
15788 (match_operand:P 4 "register_operand" "1")))
15789 (set (mem:BLK (match_dup 3))
15790 (mem:BLK (match_dup 4)))
15791 (use (match_dup 5))]
15792 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15793 "%^rep{%;} movs{l|d}"
15794 [(set_attr "type" "str")
15795 (set_attr "prefix_rep" "1")
15796 (set_attr "memory" "both")
15797 (set_attr "mode" "SI")])
15799 (define_insn "*rep_movqi"
15800 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15801 (set (match_operand:P 0 "register_operand" "=D")
15802 (plus:P (match_operand:P 3 "register_operand" "0")
15803 (match_operand:P 5 "register_operand" "2")))
15804 (set (match_operand:P 1 "register_operand" "=S")
15805 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15806 (set (mem:BLK (match_dup 3))
15807 (mem:BLK (match_dup 4)))
15808 (use (match_dup 5))]
15809 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15811 [(set_attr "type" "str")
15812 (set_attr "prefix_rep" "1")
15813 (set_attr "memory" "both")
15814 (set_attr "mode" "QI")])
15816 (define_expand "setmem<mode>"
15817 [(use (match_operand:BLK 0 "memory_operand" ""))
15818 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15819 (use (match_operand:QI 2 "nonmemory_operand" ""))
15820 (use (match_operand 3 "const_int_operand" ""))
15821 (use (match_operand:SI 4 "const_int_operand" ""))
15822 (use (match_operand:SI 5 "const_int_operand" ""))]
15825 if (ix86_expand_setmem (operands[0], operands[1],
15826 operands[2], operands[3],
15827 operands[4], operands[5]))
15833 ;; Most CPUs don't like single string operations
15834 ;; Handle this case here to simplify previous expander.
15836 (define_expand "strset"
15837 [(set (match_operand 1 "memory_operand" "")
15838 (match_operand 2 "register_operand" ""))
15839 (parallel [(set (match_operand 0 "register_operand" "")
15841 (clobber (reg:CC FLAGS_REG))])]
15844 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15845 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15847 /* If .md ever supports :P for Pmode, this can be directly
15848 in the pattern above. */
15849 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15850 GEN_INT (GET_MODE_SIZE (GET_MODE
15852 /* Can't use this if the user has appropriated eax or edi. */
15853 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15854 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15856 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15862 (define_expand "strset_singleop"
15863 [(parallel [(set (match_operand 1 "memory_operand" "")
15864 (match_operand 2 "register_operand" ""))
15865 (set (match_operand 0 "register_operand" "")
15866 (match_operand 3 "" ""))])]
15868 "ix86_current_function_needs_cld = 1;")
15870 (define_insn "*strsetdi_rex_1"
15871 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15872 (match_operand:DI 2 "register_operand" "a"))
15873 (set (match_operand:P 0 "register_operand" "=D")
15874 (plus:P (match_dup 1)
15877 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15879 [(set_attr "type" "str")
15880 (set_attr "memory" "store")
15881 (set_attr "mode" "DI")])
15883 (define_insn "*strsetsi_1"
15884 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15885 (match_operand:SI 2 "register_operand" "a"))
15886 (set (match_operand:P 0 "register_operand" "=D")
15887 (plus:P (match_dup 1)
15889 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15891 [(set_attr "type" "str")
15892 (set_attr "memory" "store")
15893 (set_attr "mode" "SI")])
15895 (define_insn "*strsethi_1"
15896 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15897 (match_operand:HI 2 "register_operand" "a"))
15898 (set (match_operand:P 0 "register_operand" "=D")
15899 (plus:P (match_dup 1)
15901 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15903 [(set_attr "type" "str")
15904 (set_attr "memory" "store")
15905 (set_attr "mode" "HI")])
15907 (define_insn "*strsetqi_1"
15908 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15909 (match_operand:QI 2 "register_operand" "a"))
15910 (set (match_operand:P 0 "register_operand" "=D")
15911 (plus:P (match_dup 1)
15913 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15915 [(set_attr "type" "str")
15916 (set_attr "memory" "store")
15917 (set (attr "prefix_rex")
15919 (match_test "<P:MODE>mode == DImode")
15921 (const_string "*")))
15922 (set_attr "mode" "QI")])
15924 (define_expand "rep_stos"
15925 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15926 (set (match_operand 0 "register_operand" "")
15927 (match_operand 4 "" ""))
15928 (set (match_operand 2 "memory_operand" "") (const_int 0))
15929 (use (match_operand 3 "register_operand" ""))
15930 (use (match_dup 1))])]
15932 "ix86_current_function_needs_cld = 1;")
15934 (define_insn "*rep_stosdi_rex64"
15935 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15936 (set (match_operand:P 0 "register_operand" "=D")
15937 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15939 (match_operand:P 3 "register_operand" "0")))
15940 (set (mem:BLK (match_dup 3))
15942 (use (match_operand:DI 2 "register_operand" "a"))
15943 (use (match_dup 4))]
15945 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15947 [(set_attr "type" "str")
15948 (set_attr "prefix_rep" "1")
15949 (set_attr "memory" "store")
15950 (set_attr "mode" "DI")])
15952 (define_insn "*rep_stossi"
15953 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15954 (set (match_operand:P 0 "register_operand" "=D")
15955 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15957 (match_operand:P 3 "register_operand" "0")))
15958 (set (mem:BLK (match_dup 3))
15960 (use (match_operand:SI 2 "register_operand" "a"))
15961 (use (match_dup 4))]
15962 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15963 "%^rep{%;} stos{l|d}"
15964 [(set_attr "type" "str")
15965 (set_attr "prefix_rep" "1")
15966 (set_attr "memory" "store")
15967 (set_attr "mode" "SI")])
15969 (define_insn "*rep_stosqi"
15970 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15971 (set (match_operand:P 0 "register_operand" "=D")
15972 (plus:P (match_operand:P 3 "register_operand" "0")
15973 (match_operand:P 4 "register_operand" "1")))
15974 (set (mem:BLK (match_dup 3))
15976 (use (match_operand:QI 2 "register_operand" "a"))
15977 (use (match_dup 4))]
15978 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15980 [(set_attr "type" "str")
15981 (set_attr "prefix_rep" "1")
15982 (set_attr "memory" "store")
15983 (set (attr "prefix_rex")
15985 (match_test "<P:MODE>mode == DImode")
15987 (const_string "*")))
15988 (set_attr "mode" "QI")])
15990 (define_expand "cmpstrnsi"
15991 [(set (match_operand:SI 0 "register_operand" "")
15992 (compare:SI (match_operand:BLK 1 "general_operand" "")
15993 (match_operand:BLK 2 "general_operand" "")))
15994 (use (match_operand 3 "general_operand" ""))
15995 (use (match_operand 4 "immediate_operand" ""))]
15998 rtx addr1, addr2, out, outlow, count, countreg, align;
16000 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16003 /* Can't use this if the user has appropriated ecx, esi or edi. */
16004 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16009 out = gen_reg_rtx (SImode);
16011 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16012 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16013 if (addr1 != XEXP (operands[1], 0))
16014 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16015 if (addr2 != XEXP (operands[2], 0))
16016 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16018 count = operands[3];
16019 countreg = ix86_zero_extend_to_Pmode (count);
16021 /* %%% Iff we are testing strict equality, we can use known alignment
16022 to good advantage. This may be possible with combine, particularly
16023 once cc0 is dead. */
16024 align = operands[4];
16026 if (CONST_INT_P (count))
16028 if (INTVAL (count) == 0)
16030 emit_move_insn (operands[0], const0_rtx);
16033 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16034 operands[1], operands[2]));
16038 rtx (*gen_cmp) (rtx, rtx);
16040 gen_cmp = (TARGET_64BIT
16041 ? gen_cmpdi_1 : gen_cmpsi_1);
16043 emit_insn (gen_cmp (countreg, countreg));
16044 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16045 operands[1], operands[2]));
16048 outlow = gen_lowpart (QImode, out);
16049 emit_insn (gen_cmpintqi (outlow));
16050 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16052 if (operands[0] != out)
16053 emit_move_insn (operands[0], out);
16058 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16060 (define_expand "cmpintqi"
16061 [(set (match_dup 1)
16062 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16064 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16065 (parallel [(set (match_operand:QI 0 "register_operand" "")
16066 (minus:QI (match_dup 1)
16068 (clobber (reg:CC FLAGS_REG))])]
16071 operands[1] = gen_reg_rtx (QImode);
16072 operands[2] = gen_reg_rtx (QImode);
16075 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16076 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16078 (define_expand "cmpstrnqi_nz_1"
16079 [(parallel [(set (reg:CC FLAGS_REG)
16080 (compare:CC (match_operand 4 "memory_operand" "")
16081 (match_operand 5 "memory_operand" "")))
16082 (use (match_operand 2 "register_operand" ""))
16083 (use (match_operand:SI 3 "immediate_operand" ""))
16084 (clobber (match_operand 0 "register_operand" ""))
16085 (clobber (match_operand 1 "register_operand" ""))
16086 (clobber (match_dup 2))])]
16088 "ix86_current_function_needs_cld = 1;")
16090 (define_insn "*cmpstrnqi_nz_1"
16091 [(set (reg:CC FLAGS_REG)
16092 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16093 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16094 (use (match_operand:P 6 "register_operand" "2"))
16095 (use (match_operand:SI 3 "immediate_operand" "i"))
16096 (clobber (match_operand:P 0 "register_operand" "=S"))
16097 (clobber (match_operand:P 1 "register_operand" "=D"))
16098 (clobber (match_operand:P 2 "register_operand" "=c"))]
16099 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16101 [(set_attr "type" "str")
16102 (set_attr "mode" "QI")
16103 (set (attr "prefix_rex")
16105 (match_test "<P:MODE>mode == DImode")
16107 (const_string "*")))
16108 (set_attr "prefix_rep" "1")])
16110 ;; The same, but the count is not known to not be zero.
16112 (define_expand "cmpstrnqi_1"
16113 [(parallel [(set (reg:CC FLAGS_REG)
16114 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16116 (compare:CC (match_operand 4 "memory_operand" "")
16117 (match_operand 5 "memory_operand" ""))
16119 (use (match_operand:SI 3 "immediate_operand" ""))
16120 (use (reg:CC FLAGS_REG))
16121 (clobber (match_operand 0 "register_operand" ""))
16122 (clobber (match_operand 1 "register_operand" ""))
16123 (clobber (match_dup 2))])]
16125 "ix86_current_function_needs_cld = 1;")
16127 (define_insn "*cmpstrnqi_1"
16128 [(set (reg:CC FLAGS_REG)
16129 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16131 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16132 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16134 (use (match_operand:SI 3 "immediate_operand" "i"))
16135 (use (reg:CC FLAGS_REG))
16136 (clobber (match_operand:P 0 "register_operand" "=S"))
16137 (clobber (match_operand:P 1 "register_operand" "=D"))
16138 (clobber (match_operand:P 2 "register_operand" "=c"))]
16139 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16141 [(set_attr "type" "str")
16142 (set_attr "mode" "QI")
16143 (set (attr "prefix_rex")
16145 (match_test "<P:MODE>mode == DImode")
16147 (const_string "*")))
16148 (set_attr "prefix_rep" "1")])
16150 (define_expand "strlen<mode>"
16151 [(set (match_operand:P 0 "register_operand" "")
16152 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16153 (match_operand:QI 2 "immediate_operand" "")
16154 (match_operand 3 "immediate_operand" "")]
16158 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16164 (define_expand "strlenqi_1"
16165 [(parallel [(set (match_operand 0 "register_operand" "")
16166 (match_operand 2 "" ""))
16167 (clobber (match_operand 1 "register_operand" ""))
16168 (clobber (reg:CC FLAGS_REG))])]
16170 "ix86_current_function_needs_cld = 1;")
16172 (define_insn "*strlenqi_1"
16173 [(set (match_operand:P 0 "register_operand" "=&c")
16174 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16175 (match_operand:QI 2 "register_operand" "a")
16176 (match_operand:P 3 "immediate_operand" "i")
16177 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16178 (clobber (match_operand:P 1 "register_operand" "=D"))
16179 (clobber (reg:CC FLAGS_REG))]
16180 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16181 "%^repnz{%;} scasb"
16182 [(set_attr "type" "str")
16183 (set_attr "mode" "QI")
16184 (set (attr "prefix_rex")
16186 (match_test "<P:MODE>mode == DImode")
16188 (const_string "*")))
16189 (set_attr "prefix_rep" "1")])
16191 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16192 ;; handled in combine, but it is not currently up to the task.
16193 ;; When used for their truth value, the cmpstrn* expanders generate
16202 ;; The intermediate three instructions are unnecessary.
16204 ;; This one handles cmpstrn*_nz_1...
16207 (set (reg:CC FLAGS_REG)
16208 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16209 (mem:BLK (match_operand 5 "register_operand" ""))))
16210 (use (match_operand 6 "register_operand" ""))
16211 (use (match_operand:SI 3 "immediate_operand" ""))
16212 (clobber (match_operand 0 "register_operand" ""))
16213 (clobber (match_operand 1 "register_operand" ""))
16214 (clobber (match_operand 2 "register_operand" ""))])
16215 (set (match_operand:QI 7 "register_operand" "")
16216 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16217 (set (match_operand:QI 8 "register_operand" "")
16218 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16219 (set (reg FLAGS_REG)
16220 (compare (match_dup 7) (match_dup 8)))
16222 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16224 (set (reg:CC FLAGS_REG)
16225 (compare:CC (mem:BLK (match_dup 4))
16226 (mem:BLK (match_dup 5))))
16227 (use (match_dup 6))
16228 (use (match_dup 3))
16229 (clobber (match_dup 0))
16230 (clobber (match_dup 1))
16231 (clobber (match_dup 2))])])
16233 ;; ...and this one handles cmpstrn*_1.
16236 (set (reg:CC FLAGS_REG)
16237 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16239 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16240 (mem:BLK (match_operand 5 "register_operand" "")))
16242 (use (match_operand:SI 3 "immediate_operand" ""))
16243 (use (reg:CC FLAGS_REG))
16244 (clobber (match_operand 0 "register_operand" ""))
16245 (clobber (match_operand 1 "register_operand" ""))
16246 (clobber (match_operand 2 "register_operand" ""))])
16247 (set (match_operand:QI 7 "register_operand" "")
16248 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16249 (set (match_operand:QI 8 "register_operand" "")
16250 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16251 (set (reg FLAGS_REG)
16252 (compare (match_dup 7) (match_dup 8)))
16254 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16256 (set (reg:CC FLAGS_REG)
16257 (if_then_else:CC (ne (match_dup 6)
16259 (compare:CC (mem:BLK (match_dup 4))
16260 (mem:BLK (match_dup 5)))
16262 (use (match_dup 3))
16263 (use (reg:CC FLAGS_REG))
16264 (clobber (match_dup 0))
16265 (clobber (match_dup 1))
16266 (clobber (match_dup 2))])])
16268 ;; Conditional move instructions.
16270 (define_expand "mov<mode>cc"
16271 [(set (match_operand:SWIM 0 "register_operand" "")
16272 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16273 (match_operand:SWIM 2 "<general_operand>" "")
16274 (match_operand:SWIM 3 "<general_operand>" "")))]
16276 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16278 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16279 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16280 ;; So just document what we're doing explicitly.
16282 (define_expand "x86_mov<mode>cc_0_m1"
16284 [(set (match_operand:SWI48 0 "register_operand" "")
16285 (if_then_else:SWI48
16286 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16287 [(match_operand 1 "flags_reg_operand" "")
16291 (clobber (reg:CC FLAGS_REG))])])
16293 (define_insn "*x86_mov<mode>cc_0_m1"
16294 [(set (match_operand:SWI48 0 "register_operand" "=r")
16295 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16296 [(reg FLAGS_REG) (const_int 0)])
16299 (clobber (reg:CC FLAGS_REG))]
16301 "sbb{<imodesuffix>}\t%0, %0"
16302 ; Since we don't have the proper number of operands for an alu insn,
16303 ; fill in all the blanks.
16304 [(set_attr "type" "alu")
16305 (set_attr "use_carry" "1")
16306 (set_attr "pent_pair" "pu")
16307 (set_attr "memory" "none")
16308 (set_attr "imm_disp" "false")
16309 (set_attr "mode" "<MODE>")
16310 (set_attr "length_immediate" "0")])
16312 (define_insn "*x86_mov<mode>cc_0_m1_se"
16313 [(set (match_operand:SWI48 0 "register_operand" "=r")
16314 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16315 [(reg FLAGS_REG) (const_int 0)])
16318 (clobber (reg:CC FLAGS_REG))]
16320 "sbb{<imodesuffix>}\t%0, %0"
16321 [(set_attr "type" "alu")
16322 (set_attr "use_carry" "1")
16323 (set_attr "pent_pair" "pu")
16324 (set_attr "memory" "none")
16325 (set_attr "imm_disp" "false")
16326 (set_attr "mode" "<MODE>")
16327 (set_attr "length_immediate" "0")])
16329 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16330 [(set (match_operand:SWI48 0 "register_operand" "=r")
16331 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16332 [(reg FLAGS_REG) (const_int 0)])))]
16334 "sbb{<imodesuffix>}\t%0, %0"
16335 [(set_attr "type" "alu")
16336 (set_attr "use_carry" "1")
16337 (set_attr "pent_pair" "pu")
16338 (set_attr "memory" "none")
16339 (set_attr "imm_disp" "false")
16340 (set_attr "mode" "<MODE>")
16341 (set_attr "length_immediate" "0")])
16343 (define_insn "*mov<mode>cc_noc"
16344 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16345 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16346 [(reg FLAGS_REG) (const_int 0)])
16347 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16348 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16349 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16351 cmov%O2%C1\t{%2, %0|%0, %2}
16352 cmov%O2%c1\t{%3, %0|%0, %3}"
16353 [(set_attr "type" "icmov")
16354 (set_attr "mode" "<MODE>")])
16356 (define_insn_and_split "*movqicc_noc"
16357 [(set (match_operand:QI 0 "register_operand" "=r,r")
16358 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16359 [(match_operand 4 "flags_reg_operand" "")
16361 (match_operand:QI 2 "register_operand" "r,0")
16362 (match_operand:QI 3 "register_operand" "0,r")))]
16363 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16365 "&& reload_completed"
16366 [(set (match_dup 0)
16367 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16370 "operands[0] = gen_lowpart (SImode, operands[0]);
16371 operands[2] = gen_lowpart (SImode, operands[2]);
16372 operands[3] = gen_lowpart (SImode, operands[3]);"
16373 [(set_attr "type" "icmov")
16374 (set_attr "mode" "SI")])
16376 (define_expand "mov<mode>cc"
16377 [(set (match_operand:X87MODEF 0 "register_operand" "")
16378 (if_then_else:X87MODEF
16379 (match_operand 1 "ix86_fp_comparison_operator" "")
16380 (match_operand:X87MODEF 2 "register_operand" "")
16381 (match_operand:X87MODEF 3 "register_operand" "")))]
16382 "(TARGET_80387 && TARGET_CMOVE)
16383 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16384 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16386 (define_insn "*movxfcc_1"
16387 [(set (match_operand:XF 0 "register_operand" "=f,f")
16388 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16389 [(reg FLAGS_REG) (const_int 0)])
16390 (match_operand:XF 2 "register_operand" "f,0")
16391 (match_operand:XF 3 "register_operand" "0,f")))]
16392 "TARGET_80387 && TARGET_CMOVE"
16394 fcmov%F1\t{%2, %0|%0, %2}
16395 fcmov%f1\t{%3, %0|%0, %3}"
16396 [(set_attr "type" "fcmov")
16397 (set_attr "mode" "XF")])
16399 (define_insn "*movdfcc_1_rex64"
16400 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16401 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16402 [(reg FLAGS_REG) (const_int 0)])
16403 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16404 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16405 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16406 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16408 fcmov%F1\t{%2, %0|%0, %2}
16409 fcmov%f1\t{%3, %0|%0, %3}
16410 cmov%O2%C1\t{%2, %0|%0, %2}
16411 cmov%O2%c1\t{%3, %0|%0, %3}"
16412 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16413 (set_attr "mode" "DF,DF,DI,DI")])
16415 (define_insn "*movdfcc_1"
16416 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16417 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16418 [(reg FLAGS_REG) (const_int 0)])
16419 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16420 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16421 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16422 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16424 fcmov%F1\t{%2, %0|%0, %2}
16425 fcmov%f1\t{%3, %0|%0, %3}
16428 [(set_attr "type" "fcmov,fcmov,multi,multi")
16429 (set_attr "mode" "DF,DF,DI,DI")])
16432 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16433 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16434 [(match_operand 4 "flags_reg_operand" "")
16436 (match_operand:DF 2 "nonimmediate_operand" "")
16437 (match_operand:DF 3 "nonimmediate_operand" "")))]
16438 "!TARGET_64BIT && reload_completed"
16439 [(set (match_dup 2)
16440 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16444 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16448 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16449 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16452 (define_insn "*movsfcc_1_387"
16453 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16454 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16455 [(reg FLAGS_REG) (const_int 0)])
16456 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16457 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16458 "TARGET_80387 && TARGET_CMOVE
16459 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16461 fcmov%F1\t{%2, %0|%0, %2}
16462 fcmov%f1\t{%3, %0|%0, %3}
16463 cmov%O2%C1\t{%2, %0|%0, %2}
16464 cmov%O2%c1\t{%3, %0|%0, %3}"
16465 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16466 (set_attr "mode" "SF,SF,SI,SI")])
16468 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16469 ;; the scalar versions to have only XMM registers as operands.
16471 ;; XOP conditional move
16472 (define_insn "*xop_pcmov_<mode>"
16473 [(set (match_operand:MODEF 0 "register_operand" "=x")
16474 (if_then_else:MODEF
16475 (match_operand:MODEF 1 "register_operand" "x")
16476 (match_operand:MODEF 2 "register_operand" "x")
16477 (match_operand:MODEF 3 "register_operand" "x")))]
16479 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16480 [(set_attr "type" "sse4arg")])
16482 ;; These versions of the min/max patterns are intentionally ignorant of
16483 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16484 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16485 ;; are undefined in this condition, we're certain this is correct.
16487 (define_insn "<code><mode>3"
16488 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16490 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16491 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16492 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16494 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16495 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16496 [(set_attr "isa" "noavx,avx")
16497 (set_attr "prefix" "orig,vex")
16498 (set_attr "type" "sseadd")
16499 (set_attr "mode" "<MODE>")])
16501 ;; These versions of the min/max patterns implement exactly the operations
16502 ;; min = (op1 < op2 ? op1 : op2)
16503 ;; max = (!(op1 < op2) ? op1 : op2)
16504 ;; Their operands are not commutative, and thus they may be used in the
16505 ;; presence of -0.0 and NaN.
16507 (define_insn "*ieee_smin<mode>3"
16508 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16510 [(match_operand:MODEF 1 "register_operand" "0,x")
16511 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16513 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16515 min<ssemodesuffix>\t{%2, %0|%0, %2}
16516 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16517 [(set_attr "isa" "noavx,avx")
16518 (set_attr "prefix" "orig,vex")
16519 (set_attr "type" "sseadd")
16520 (set_attr "mode" "<MODE>")])
16522 (define_insn "*ieee_smax<mode>3"
16523 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16525 [(match_operand:MODEF 1 "register_operand" "0,x")
16526 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16528 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16530 max<ssemodesuffix>\t{%2, %0|%0, %2}
16531 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16532 [(set_attr "isa" "noavx,avx")
16533 (set_attr "prefix" "orig,vex")
16534 (set_attr "type" "sseadd")
16535 (set_attr "mode" "<MODE>")])
16537 ;; Make two stack loads independent:
16539 ;; fld %st(0) -> fld bb
16540 ;; fmul bb fmul %st(1), %st
16542 ;; Actually we only match the last two instructions for simplicity.
16544 [(set (match_operand 0 "fp_register_operand" "")
16545 (match_operand 1 "fp_register_operand" ""))
16547 (match_operator 2 "binary_fp_operator"
16549 (match_operand 3 "memory_operand" "")]))]
16550 "REGNO (operands[0]) != REGNO (operands[1])"
16551 [(set (match_dup 0) (match_dup 3))
16552 (set (match_dup 0) (match_dup 4))]
16554 ;; The % modifier is not operational anymore in peephole2's, so we have to
16555 ;; swap the operands manually in the case of addition and multiplication.
16559 if (COMMUTATIVE_ARITH_P (operands[2]))
16560 op0 = operands[0], op1 = operands[1];
16562 op0 = operands[1], op1 = operands[0];
16564 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16565 GET_MODE (operands[2]),
16569 ;; Conditional addition patterns
16570 (define_expand "add<mode>cc"
16571 [(match_operand:SWI 0 "register_operand" "")
16572 (match_operand 1 "ordered_comparison_operator" "")
16573 (match_operand:SWI 2 "register_operand" "")
16574 (match_operand:SWI 3 "const_int_operand" "")]
16576 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16578 ;; Misc patterns (?)
16580 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16581 ;; Otherwise there will be nothing to keep
16583 ;; [(set (reg ebp) (reg esp))]
16584 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16585 ;; (clobber (eflags)]
16586 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16588 ;; in proper program order.
16590 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16591 [(set (match_operand:P 0 "register_operand" "=r,r")
16592 (plus:P (match_operand:P 1 "register_operand" "0,r")
16593 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16594 (clobber (reg:CC FLAGS_REG))
16595 (clobber (mem:BLK (scratch)))]
16598 switch (get_attr_type (insn))
16601 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16604 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16605 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16606 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16608 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16611 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16612 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
16615 [(set (attr "type")
16616 (cond [(and (eq_attr "alternative" "0")
16617 (not (match_test "TARGET_OPT_AGU")))
16618 (const_string "alu")
16619 (match_operand:<MODE> 2 "const0_operand" "")
16620 (const_string "imov")
16622 (const_string "lea")))
16623 (set (attr "length_immediate")
16624 (cond [(eq_attr "type" "imov")
16626 (and (eq_attr "type" "alu")
16627 (match_operand 2 "const128_operand" ""))
16630 (const_string "*")))
16631 (set_attr "mode" "<MODE>")])
16633 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16634 [(set (match_operand:P 0 "register_operand" "=r")
16635 (minus:P (match_operand:P 1 "register_operand" "0")
16636 (match_operand:P 2 "register_operand" "r")))
16637 (clobber (reg:CC FLAGS_REG))
16638 (clobber (mem:BLK (scratch)))]
16640 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16641 [(set_attr "type" "alu")
16642 (set_attr "mode" "<MODE>")])
16644 (define_insn "allocate_stack_worker_probe_<mode>"
16645 [(set (match_operand:P 0 "register_operand" "=a")
16646 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16647 UNSPECV_STACK_PROBE))
16648 (clobber (reg:CC FLAGS_REG))]
16649 "ix86_target_stack_probe ()"
16650 "call\t___chkstk_ms"
16651 [(set_attr "type" "multi")
16652 (set_attr "length" "5")])
16654 (define_expand "allocate_stack"
16655 [(match_operand 0 "register_operand" "")
16656 (match_operand 1 "general_operand" "")]
16657 "ix86_target_stack_probe ()"
16661 #ifndef CHECK_STACK_LIMIT
16662 #define CHECK_STACK_LIMIT 0
16665 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16666 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16668 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16669 stack_pointer_rtx, 0, OPTAB_DIRECT);
16670 if (x != stack_pointer_rtx)
16671 emit_move_insn (stack_pointer_rtx, x);
16675 x = copy_to_mode_reg (Pmode, operands[1]);
16677 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16679 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16680 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16681 stack_pointer_rtx, 0, OPTAB_DIRECT);
16682 if (x != stack_pointer_rtx)
16683 emit_move_insn (stack_pointer_rtx, x);
16686 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16690 ;; Use IOR for stack probes, this is shorter.
16691 (define_expand "probe_stack"
16692 [(match_operand 0 "memory_operand" "")]
16695 rtx (*gen_ior3) (rtx, rtx, rtx);
16697 gen_ior3 = (GET_MODE (operands[0]) == DImode
16698 ? gen_iordi3 : gen_iorsi3);
16700 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16704 (define_insn "adjust_stack_and_probe<mode>"
16705 [(set (match_operand:P 0 "register_operand" "=r")
16706 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16707 UNSPECV_PROBE_STACK_RANGE))
16708 (set (reg:P SP_REG)
16709 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16710 (clobber (reg:CC FLAGS_REG))
16711 (clobber (mem:BLK (scratch)))]
16713 "* return output_adjust_stack_and_probe (operands[0]);"
16714 [(set_attr "type" "multi")])
16716 (define_insn "probe_stack_range<mode>"
16717 [(set (match_operand:P 0 "register_operand" "=r")
16718 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16719 (match_operand:P 2 "const_int_operand" "n")]
16720 UNSPECV_PROBE_STACK_RANGE))
16721 (clobber (reg:CC FLAGS_REG))]
16723 "* return output_probe_stack_range (operands[0], operands[2]);"
16724 [(set_attr "type" "multi")])
16726 (define_expand "builtin_setjmp_receiver"
16727 [(label_ref (match_operand 0 "" ""))]
16728 "!TARGET_64BIT && flag_pic"
16734 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16735 rtx label_rtx = gen_label_rtx ();
16736 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16737 xops[0] = xops[1] = picreg;
16738 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16739 ix86_expand_binary_operator (MINUS, SImode, xops);
16743 emit_insn (gen_set_got (pic_offset_table_rtx));
16747 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16750 [(set (match_operand 0 "register_operand" "")
16751 (match_operator 3 "promotable_binary_operator"
16752 [(match_operand 1 "register_operand" "")
16753 (match_operand 2 "aligned_operand" "")]))
16754 (clobber (reg:CC FLAGS_REG))]
16755 "! TARGET_PARTIAL_REG_STALL && reload_completed
16756 && ((GET_MODE (operands[0]) == HImode
16757 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16758 /* ??? next two lines just !satisfies_constraint_K (...) */
16759 || !CONST_INT_P (operands[2])
16760 || satisfies_constraint_K (operands[2])))
16761 || (GET_MODE (operands[0]) == QImode
16762 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16763 [(parallel [(set (match_dup 0)
16764 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16765 (clobber (reg:CC FLAGS_REG))])]
16767 operands[0] = gen_lowpart (SImode, operands[0]);
16768 operands[1] = gen_lowpart (SImode, operands[1]);
16769 if (GET_CODE (operands[3]) != ASHIFT)
16770 operands[2] = gen_lowpart (SImode, operands[2]);
16771 PUT_MODE (operands[3], SImode);
16774 ; Promote the QImode tests, as i386 has encoding of the AND
16775 ; instruction with 32-bit sign-extended immediate and thus the
16776 ; instruction size is unchanged, except in the %eax case for
16777 ; which it is increased by one byte, hence the ! optimize_size.
16779 [(set (match_operand 0 "flags_reg_operand" "")
16780 (match_operator 2 "compare_operator"
16781 [(and (match_operand 3 "aligned_operand" "")
16782 (match_operand 4 "const_int_operand" ""))
16784 (set (match_operand 1 "register_operand" "")
16785 (and (match_dup 3) (match_dup 4)))]
16786 "! TARGET_PARTIAL_REG_STALL && reload_completed
16787 && optimize_insn_for_speed_p ()
16788 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16789 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16790 /* Ensure that the operand will remain sign-extended immediate. */
16791 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16792 [(parallel [(set (match_dup 0)
16793 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16796 (and:SI (match_dup 3) (match_dup 4)))])]
16799 = gen_int_mode (INTVAL (operands[4])
16800 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16801 operands[1] = gen_lowpart (SImode, operands[1]);
16802 operands[3] = gen_lowpart (SImode, operands[3]);
16805 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16806 ; the TEST instruction with 32-bit sign-extended immediate and thus
16807 ; the instruction size would at least double, which is not what we
16808 ; want even with ! optimize_size.
16810 [(set (match_operand 0 "flags_reg_operand" "")
16811 (match_operator 1 "compare_operator"
16812 [(and (match_operand:HI 2 "aligned_operand" "")
16813 (match_operand:HI 3 "const_int_operand" ""))
16815 "! TARGET_PARTIAL_REG_STALL && reload_completed
16816 && ! TARGET_FAST_PREFIX
16817 && optimize_insn_for_speed_p ()
16818 /* Ensure that the operand will remain sign-extended immediate. */
16819 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16820 [(set (match_dup 0)
16821 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16825 = gen_int_mode (INTVAL (operands[3])
16826 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16827 operands[2] = gen_lowpart (SImode, operands[2]);
16831 [(set (match_operand 0 "register_operand" "")
16832 (neg (match_operand 1 "register_operand" "")))
16833 (clobber (reg:CC FLAGS_REG))]
16834 "! TARGET_PARTIAL_REG_STALL && reload_completed
16835 && (GET_MODE (operands[0]) == HImode
16836 || (GET_MODE (operands[0]) == QImode
16837 && (TARGET_PROMOTE_QImode
16838 || optimize_insn_for_size_p ())))"
16839 [(parallel [(set (match_dup 0)
16840 (neg:SI (match_dup 1)))
16841 (clobber (reg:CC FLAGS_REG))])]
16843 operands[0] = gen_lowpart (SImode, operands[0]);
16844 operands[1] = gen_lowpart (SImode, operands[1]);
16848 [(set (match_operand 0 "register_operand" "")
16849 (not (match_operand 1 "register_operand" "")))]
16850 "! TARGET_PARTIAL_REG_STALL && reload_completed
16851 && (GET_MODE (operands[0]) == HImode
16852 || (GET_MODE (operands[0]) == QImode
16853 && (TARGET_PROMOTE_QImode
16854 || optimize_insn_for_size_p ())))"
16855 [(set (match_dup 0)
16856 (not:SI (match_dup 1)))]
16858 operands[0] = gen_lowpart (SImode, operands[0]);
16859 operands[1] = gen_lowpart (SImode, operands[1]);
16863 [(set (match_operand 0 "register_operand" "")
16864 (if_then_else (match_operator 1 "ordered_comparison_operator"
16865 [(reg FLAGS_REG) (const_int 0)])
16866 (match_operand 2 "register_operand" "")
16867 (match_operand 3 "register_operand" "")))]
16868 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16869 && (GET_MODE (operands[0]) == HImode
16870 || (GET_MODE (operands[0]) == QImode
16871 && (TARGET_PROMOTE_QImode
16872 || optimize_insn_for_size_p ())))"
16873 [(set (match_dup 0)
16874 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16876 operands[0] = gen_lowpart (SImode, operands[0]);
16877 operands[2] = gen_lowpart (SImode, operands[2]);
16878 operands[3] = gen_lowpart (SImode, operands[3]);
16881 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16882 ;; transform a complex memory operation into two memory to register operations.
16884 ;; Don't push memory operands
16886 [(set (match_operand:SWI 0 "push_operand" "")
16887 (match_operand:SWI 1 "memory_operand" ""))
16888 (match_scratch:SWI 2 "<r>")]
16889 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16890 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16891 [(set (match_dup 2) (match_dup 1))
16892 (set (match_dup 0) (match_dup 2))])
16894 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16897 [(set (match_operand:SF 0 "push_operand" "")
16898 (match_operand:SF 1 "memory_operand" ""))
16899 (match_scratch:SF 2 "r")]
16900 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16901 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16902 [(set (match_dup 2) (match_dup 1))
16903 (set (match_dup 0) (match_dup 2))])
16905 ;; Don't move an immediate directly to memory when the instruction
16908 [(match_scratch:SWI124 1 "<r>")
16909 (set (match_operand:SWI124 0 "memory_operand" "")
16911 "optimize_insn_for_speed_p ()
16912 && !TARGET_USE_MOV0
16913 && TARGET_SPLIT_LONG_MOVES
16914 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16915 && peep2_regno_dead_p (0, FLAGS_REG)"
16916 [(parallel [(set (match_dup 2) (const_int 0))
16917 (clobber (reg:CC FLAGS_REG))])
16918 (set (match_dup 0) (match_dup 1))]
16919 "operands[2] = gen_lowpart (SImode, operands[1]);")
16922 [(match_scratch:SWI124 2 "<r>")
16923 (set (match_operand:SWI124 0 "memory_operand" "")
16924 (match_operand:SWI124 1 "immediate_operand" ""))]
16925 "optimize_insn_for_speed_p ()
16926 && TARGET_SPLIT_LONG_MOVES
16927 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16928 [(set (match_dup 2) (match_dup 1))
16929 (set (match_dup 0) (match_dup 2))])
16931 ;; Don't compare memory with zero, load and use a test instead.
16933 [(set (match_operand 0 "flags_reg_operand" "")
16934 (match_operator 1 "compare_operator"
16935 [(match_operand:SI 2 "memory_operand" "")
16937 (match_scratch:SI 3 "r")]
16938 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16939 [(set (match_dup 3) (match_dup 2))
16940 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16942 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16943 ;; Don't split NOTs with a displacement operand, because resulting XOR
16944 ;; will not be pairable anyway.
16946 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16947 ;; represented using a modRM byte. The XOR replacement is long decoded,
16948 ;; so this split helps here as well.
16950 ;; Note: Can't do this as a regular split because we can't get proper
16951 ;; lifetime information then.
16954 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16955 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16956 "optimize_insn_for_speed_p ()
16957 && ((TARGET_NOT_UNPAIRABLE
16958 && (!MEM_P (operands[0])
16959 || !memory_displacement_operand (operands[0], <MODE>mode)))
16960 || (TARGET_NOT_VECTORMODE
16961 && long_memory_operand (operands[0], <MODE>mode)))
16962 && peep2_regno_dead_p (0, FLAGS_REG)"
16963 [(parallel [(set (match_dup 0)
16964 (xor:SWI124 (match_dup 1) (const_int -1)))
16965 (clobber (reg:CC FLAGS_REG))])])
16967 ;; Non pairable "test imm, reg" instructions can be translated to
16968 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16969 ;; byte opcode instead of two, have a short form for byte operands),
16970 ;; so do it for other CPUs as well. Given that the value was dead,
16971 ;; this should not create any new dependencies. Pass on the sub-word
16972 ;; versions if we're concerned about partial register stalls.
16975 [(set (match_operand 0 "flags_reg_operand" "")
16976 (match_operator 1 "compare_operator"
16977 [(and:SI (match_operand:SI 2 "register_operand" "")
16978 (match_operand:SI 3 "immediate_operand" ""))
16980 "ix86_match_ccmode (insn, CCNOmode)
16981 && (true_regnum (operands[2]) != AX_REG
16982 || satisfies_constraint_K (operands[3]))
16983 && peep2_reg_dead_p (1, operands[2])"
16985 [(set (match_dup 0)
16986 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16989 (and:SI (match_dup 2) (match_dup 3)))])])
16991 ;; We don't need to handle HImode case, because it will be promoted to SImode
16992 ;; on ! TARGET_PARTIAL_REG_STALL
16995 [(set (match_operand 0 "flags_reg_operand" "")
16996 (match_operator 1 "compare_operator"
16997 [(and:QI (match_operand:QI 2 "register_operand" "")
16998 (match_operand:QI 3 "immediate_operand" ""))
17000 "! TARGET_PARTIAL_REG_STALL
17001 && ix86_match_ccmode (insn, CCNOmode)
17002 && true_regnum (operands[2]) != AX_REG
17003 && peep2_reg_dead_p (1, operands[2])"
17005 [(set (match_dup 0)
17006 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17009 (and:QI (match_dup 2) (match_dup 3)))])])
17012 [(set (match_operand 0 "flags_reg_operand" "")
17013 (match_operator 1 "compare_operator"
17016 (match_operand 2 "ext_register_operand" "")
17019 (match_operand 3 "const_int_operand" ""))
17021 "! TARGET_PARTIAL_REG_STALL
17022 && ix86_match_ccmode (insn, CCNOmode)
17023 && true_regnum (operands[2]) != AX_REG
17024 && peep2_reg_dead_p (1, operands[2])"
17025 [(parallel [(set (match_dup 0)
17034 (set (zero_extract:SI (match_dup 2)
17042 (match_dup 3)))])])
17044 ;; Don't do logical operations with memory inputs.
17046 [(match_scratch:SI 2 "r")
17047 (parallel [(set (match_operand:SI 0 "register_operand" "")
17048 (match_operator:SI 3 "arith_or_logical_operator"
17050 (match_operand:SI 1 "memory_operand" "")]))
17051 (clobber (reg:CC FLAGS_REG))])]
17052 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17053 [(set (match_dup 2) (match_dup 1))
17054 (parallel [(set (match_dup 0)
17055 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17056 (clobber (reg:CC FLAGS_REG))])])
17059 [(match_scratch:SI 2 "r")
17060 (parallel [(set (match_operand:SI 0 "register_operand" "")
17061 (match_operator:SI 3 "arith_or_logical_operator"
17062 [(match_operand:SI 1 "memory_operand" "")
17064 (clobber (reg:CC FLAGS_REG))])]
17065 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17066 [(set (match_dup 2) (match_dup 1))
17067 (parallel [(set (match_dup 0)
17068 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17069 (clobber (reg:CC FLAGS_REG))])])
17071 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17072 ;; refers to the destination of the load!
17075 [(set (match_operand:SI 0 "register_operand" "")
17076 (match_operand:SI 1 "register_operand" ""))
17077 (parallel [(set (match_dup 0)
17078 (match_operator:SI 3 "commutative_operator"
17080 (match_operand:SI 2 "memory_operand" "")]))
17081 (clobber (reg:CC FLAGS_REG))])]
17082 "REGNO (operands[0]) != REGNO (operands[1])
17083 && GENERAL_REGNO_P (REGNO (operands[0]))
17084 && GENERAL_REGNO_P (REGNO (operands[1]))"
17085 [(set (match_dup 0) (match_dup 4))
17086 (parallel [(set (match_dup 0)
17087 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17088 (clobber (reg:CC FLAGS_REG))])]
17089 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17092 [(set (match_operand 0 "register_operand" "")
17093 (match_operand 1 "register_operand" ""))
17095 (match_operator 3 "commutative_operator"
17097 (match_operand 2 "memory_operand" "")]))]
17098 "REGNO (operands[0]) != REGNO (operands[1])
17099 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17100 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17101 [(set (match_dup 0) (match_dup 2))
17103 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17105 ; Don't do logical operations with memory outputs
17107 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17108 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17109 ; the same decoder scheduling characteristics as the original.
17112 [(match_scratch:SI 2 "r")
17113 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17114 (match_operator:SI 3 "arith_or_logical_operator"
17116 (match_operand:SI 1 "nonmemory_operand" "")]))
17117 (clobber (reg:CC FLAGS_REG))])]
17118 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17119 /* Do not split stack checking probes. */
17120 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17121 [(set (match_dup 2) (match_dup 0))
17122 (parallel [(set (match_dup 2)
17123 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17124 (clobber (reg:CC FLAGS_REG))])
17125 (set (match_dup 0) (match_dup 2))])
17128 [(match_scratch:SI 2 "r")
17129 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17130 (match_operator:SI 3 "arith_or_logical_operator"
17131 [(match_operand:SI 1 "nonmemory_operand" "")
17133 (clobber (reg:CC FLAGS_REG))])]
17134 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17135 /* Do not split stack checking probes. */
17136 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17137 [(set (match_dup 2) (match_dup 0))
17138 (parallel [(set (match_dup 2)
17139 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17140 (clobber (reg:CC FLAGS_REG))])
17141 (set (match_dup 0) (match_dup 2))])
17143 ;; Attempt to use arith or logical operations with memory outputs with
17144 ;; setting of flags.
17146 [(set (match_operand:SWI 0 "register_operand" "")
17147 (match_operand:SWI 1 "memory_operand" ""))
17148 (parallel [(set (match_dup 0)
17149 (match_operator:SWI 3 "plusminuslogic_operator"
17151 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17152 (clobber (reg:CC FLAGS_REG))])
17153 (set (match_dup 1) (match_dup 0))
17154 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17155 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17156 && peep2_reg_dead_p (4, operands[0])
17157 && !reg_overlap_mentioned_p (operands[0], operands[1])
17158 && ix86_match_ccmode (peep2_next_insn (3),
17159 (GET_CODE (operands[3]) == PLUS
17160 || GET_CODE (operands[3]) == MINUS)
17161 ? CCGOCmode : CCNOmode)"
17162 [(parallel [(set (match_dup 4) (match_dup 5))
17163 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17164 (match_dup 2)]))])]
17166 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17167 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17168 copy_rtx (operands[1]),
17169 copy_rtx (operands[2]));
17170 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17171 operands[5], const0_rtx);
17175 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17176 (match_operator:SWI 2 "plusminuslogic_operator"
17178 (match_operand:SWI 1 "memory_operand" "")]))
17179 (clobber (reg:CC FLAGS_REG))])
17180 (set (match_dup 1) (match_dup 0))
17181 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17182 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17183 && GET_CODE (operands[2]) != MINUS
17184 && peep2_reg_dead_p (3, operands[0])
17185 && !reg_overlap_mentioned_p (operands[0], operands[1])
17186 && ix86_match_ccmode (peep2_next_insn (2),
17187 GET_CODE (operands[2]) == PLUS
17188 ? CCGOCmode : CCNOmode)"
17189 [(parallel [(set (match_dup 3) (match_dup 4))
17190 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17191 (match_dup 0)]))])]
17193 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17194 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17195 copy_rtx (operands[1]),
17196 copy_rtx (operands[0]));
17197 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17198 operands[4], const0_rtx);
17202 [(set (match_operand:SWI12 0 "register_operand" "")
17203 (match_operand:SWI12 1 "memory_operand" ""))
17204 (parallel [(set (match_operand:SI 4 "register_operand" "")
17205 (match_operator:SI 3 "plusminuslogic_operator"
17207 (match_operand:SI 2 "nonmemory_operand" "")]))
17208 (clobber (reg:CC FLAGS_REG))])
17209 (set (match_dup 1) (match_dup 0))
17210 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17211 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17212 && REG_P (operands[0]) && REG_P (operands[4])
17213 && REGNO (operands[0]) == REGNO (operands[4])
17214 && peep2_reg_dead_p (4, operands[0])
17215 && (<MODE>mode != QImode
17216 || immediate_operand (operands[2], SImode)
17217 || q_regs_operand (operands[2], SImode))
17218 && !reg_overlap_mentioned_p (operands[0], operands[1])
17219 && ix86_match_ccmode (peep2_next_insn (3),
17220 (GET_CODE (operands[3]) == PLUS
17221 || GET_CODE (operands[3]) == MINUS)
17222 ? CCGOCmode : CCNOmode)"
17223 [(parallel [(set (match_dup 4) (match_dup 5))
17224 (set (match_dup 1) (match_dup 6))])]
17226 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17227 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17228 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17229 copy_rtx (operands[1]), operands[2]);
17230 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17231 operands[5], const0_rtx);
17232 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17233 copy_rtx (operands[1]),
17234 copy_rtx (operands[2]));
17237 ;; Attempt to always use XOR for zeroing registers.
17239 [(set (match_operand 0 "register_operand" "")
17240 (match_operand 1 "const0_operand" ""))]
17241 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17242 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17243 && GENERAL_REG_P (operands[0])
17244 && peep2_regno_dead_p (0, FLAGS_REG)"
17245 [(parallel [(set (match_dup 0) (const_int 0))
17246 (clobber (reg:CC FLAGS_REG))])]
17247 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17250 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17252 "(GET_MODE (operands[0]) == QImode
17253 || GET_MODE (operands[0]) == HImode)
17254 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17255 && peep2_regno_dead_p (0, FLAGS_REG)"
17256 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17257 (clobber (reg:CC FLAGS_REG))])])
17259 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17261 [(set (match_operand:SWI248 0 "register_operand" "")
17263 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17264 && peep2_regno_dead_p (0, FLAGS_REG)"
17265 [(parallel [(set (match_dup 0) (const_int -1))
17266 (clobber (reg:CC FLAGS_REG))])]
17268 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17269 operands[0] = gen_lowpart (SImode, operands[0]);
17272 ;; Attempt to convert simple lea to add/shift.
17273 ;; These can be created by move expanders.
17276 [(set (match_operand:SWI48 0 "register_operand" "")
17277 (plus:SWI48 (match_dup 0)
17278 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17279 "peep2_regno_dead_p (0, FLAGS_REG)"
17280 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17281 (clobber (reg:CC FLAGS_REG))])])
17284 [(set (match_operand:SI 0 "register_operand" "")
17285 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17286 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17288 && peep2_regno_dead_p (0, FLAGS_REG)
17289 && REGNO (operands[0]) == REGNO (operands[1])"
17290 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17291 (clobber (reg:CC FLAGS_REG))])]
17292 "operands[2] = gen_lowpart (SImode, operands[2]);")
17295 [(set (match_operand:SWI48 0 "register_operand" "")
17296 (mult:SWI48 (match_dup 0)
17297 (match_operand:SWI48 1 "const_int_operand" "")))]
17298 "exact_log2 (INTVAL (operands[1])) >= 0
17299 && peep2_regno_dead_p (0, FLAGS_REG)"
17300 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17301 (clobber (reg:CC FLAGS_REG))])]
17302 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17305 [(set (match_operand:SI 0 "register_operand" "")
17306 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17307 (match_operand:DI 2 "const_int_operand" "")) 0))]
17309 && exact_log2 (INTVAL (operands[2])) >= 0
17310 && REGNO (operands[0]) == REGNO (operands[1])
17311 && peep2_regno_dead_p (0, FLAGS_REG)"
17312 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17313 (clobber (reg:CC FLAGS_REG))])]
17314 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17316 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17317 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17318 ;; On many CPUs it is also faster, since special hardware to avoid esp
17319 ;; dependencies is present.
17321 ;; While some of these conversions may be done using splitters, we use
17322 ;; peepholes in order to allow combine_stack_adjustments pass to see
17323 ;; nonobfuscated RTL.
17325 ;; Convert prologue esp subtractions to push.
17326 ;; We need register to push. In order to keep verify_flow_info happy we have
17328 ;; - use scratch and clobber it in order to avoid dependencies
17329 ;; - use already live register
17330 ;; We can't use the second way right now, since there is no reliable way how to
17331 ;; verify that given register is live. First choice will also most likely in
17332 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17333 ;; call clobbered registers are dead. We may want to use base pointer as an
17334 ;; alternative when no register is available later.
17337 [(match_scratch:P 1 "r")
17338 (parallel [(set (reg:P SP_REG)
17339 (plus:P (reg:P SP_REG)
17340 (match_operand:P 0 "const_int_operand" "")))
17341 (clobber (reg:CC FLAGS_REG))
17342 (clobber (mem:BLK (scratch)))])]
17343 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17344 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17345 [(clobber (match_dup 1))
17346 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17347 (clobber (mem:BLK (scratch)))])])
17350 [(match_scratch:P 1 "r")
17351 (parallel [(set (reg:P SP_REG)
17352 (plus:P (reg:P SP_REG)
17353 (match_operand:P 0 "const_int_operand" "")))
17354 (clobber (reg:CC FLAGS_REG))
17355 (clobber (mem:BLK (scratch)))])]
17356 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17357 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17358 [(clobber (match_dup 1))
17359 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17360 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17361 (clobber (mem:BLK (scratch)))])])
17363 ;; Convert esp subtractions to push.
17365 [(match_scratch:P 1 "r")
17366 (parallel [(set (reg:P SP_REG)
17367 (plus:P (reg:P SP_REG)
17368 (match_operand:P 0 "const_int_operand" "")))
17369 (clobber (reg:CC FLAGS_REG))])]
17370 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17371 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17372 [(clobber (match_dup 1))
17373 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17376 [(match_scratch:P 1 "r")
17377 (parallel [(set (reg:P SP_REG)
17378 (plus:P (reg:P SP_REG)
17379 (match_operand:P 0 "const_int_operand" "")))
17380 (clobber (reg:CC FLAGS_REG))])]
17381 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17382 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17383 [(clobber (match_dup 1))
17384 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17385 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17387 ;; Convert epilogue deallocator to pop.
17389 [(match_scratch:P 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand" "")))
17393 (clobber (reg:CC FLAGS_REG))
17394 (clobber (mem:BLK (scratch)))])]
17395 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17396 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17397 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17398 (clobber (mem:BLK (scratch)))])])
17400 ;; Two pops case is tricky, since pop causes dependency
17401 ;; on destination register. We use two registers if available.
17403 [(match_scratch:P 1 "r")
17404 (match_scratch:P 2 "r")
17405 (parallel [(set (reg:P SP_REG)
17406 (plus:P (reg:P SP_REG)
17407 (match_operand:P 0 "const_int_operand" "")))
17408 (clobber (reg:CC FLAGS_REG))
17409 (clobber (mem:BLK (scratch)))])]
17410 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17411 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17412 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17413 (clobber (mem:BLK (scratch)))])
17414 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17417 [(match_scratch:P 1 "r")
17418 (parallel [(set (reg:P SP_REG)
17419 (plus:P (reg:P SP_REG)
17420 (match_operand:P 0 "const_int_operand" "")))
17421 (clobber (reg:CC FLAGS_REG))
17422 (clobber (mem:BLK (scratch)))])]
17423 "optimize_insn_for_size_p ()
17424 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17425 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17426 (clobber (mem:BLK (scratch)))])
17427 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17429 ;; Convert esp additions to pop.
17431 [(match_scratch:P 1 "r")
17432 (parallel [(set (reg:P SP_REG)
17433 (plus:P (reg:P SP_REG)
17434 (match_operand:P 0 "const_int_operand" "")))
17435 (clobber (reg:CC FLAGS_REG))])]
17436 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17437 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17439 ;; Two pops case is tricky, since pop causes dependency
17440 ;; on destination register. We use two registers if available.
17442 [(match_scratch:P 1 "r")
17443 (match_scratch:P 2 "r")
17444 (parallel [(set (reg:P SP_REG)
17445 (plus:P (reg:P SP_REG)
17446 (match_operand:P 0 "const_int_operand" "")))
17447 (clobber (reg:CC FLAGS_REG))])]
17448 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17449 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17450 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17453 [(match_scratch:P 1 "r")
17454 (parallel [(set (reg:P SP_REG)
17455 (plus:P (reg:P SP_REG)
17456 (match_operand:P 0 "const_int_operand" "")))
17457 (clobber (reg:CC FLAGS_REG))])]
17458 "optimize_insn_for_size_p ()
17459 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17460 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17461 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17463 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17464 ;; required and register dies. Similarly for 128 to -128.
17466 [(set (match_operand 0 "flags_reg_operand" "")
17467 (match_operator 1 "compare_operator"
17468 [(match_operand 2 "register_operand" "")
17469 (match_operand 3 "const_int_operand" "")]))]
17470 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17471 && incdec_operand (operands[3], GET_MODE (operands[3])))
17472 || (!TARGET_FUSE_CMP_AND_BRANCH
17473 && INTVAL (operands[3]) == 128))
17474 && ix86_match_ccmode (insn, CCGCmode)
17475 && peep2_reg_dead_p (1, operands[2])"
17476 [(parallel [(set (match_dup 0)
17477 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17478 (clobber (match_dup 2))])])
17480 ;; Convert imul by three, five and nine into lea
17483 [(set (match_operand:SWI48 0 "register_operand" "")
17484 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17485 (match_operand:SWI48 2 "const359_operand" "")))
17486 (clobber (reg:CC FLAGS_REG))])]
17487 "!TARGET_PARTIAL_REG_STALL
17488 || <MODE>mode == SImode
17489 || optimize_function_for_size_p (cfun)"
17490 [(set (match_dup 0)
17491 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17493 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17497 [(set (match_operand:SWI48 0 "register_operand" "")
17498 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17499 (match_operand:SWI48 2 "const359_operand" "")))
17500 (clobber (reg:CC FLAGS_REG))])]
17501 "optimize_insn_for_speed_p ()
17502 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17503 [(set (match_dup 0) (match_dup 1))
17505 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17507 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17509 ;; imul $32bit_imm, mem, reg is vector decoded, while
17510 ;; imul $32bit_imm, reg, reg is direct decoded.
17512 [(match_scratch:SWI48 3 "r")
17513 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17514 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17515 (match_operand:SWI48 2 "immediate_operand" "")))
17516 (clobber (reg:CC FLAGS_REG))])]
17517 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17518 && !satisfies_constraint_K (operands[2])"
17519 [(set (match_dup 3) (match_dup 1))
17520 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17521 (clobber (reg:CC FLAGS_REG))])])
17524 [(match_scratch:SI 3 "r")
17525 (parallel [(set (match_operand:DI 0 "register_operand" "")
17527 (mult:SI (match_operand:SI 1 "memory_operand" "")
17528 (match_operand:SI 2 "immediate_operand" ""))))
17529 (clobber (reg:CC FLAGS_REG))])]
17531 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17532 && !satisfies_constraint_K (operands[2])"
17533 [(set (match_dup 3) (match_dup 1))
17534 (parallel [(set (match_dup 0)
17535 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17536 (clobber (reg:CC FLAGS_REG))])])
17538 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17539 ;; Convert it into imul reg, reg
17540 ;; It would be better to force assembler to encode instruction using long
17541 ;; immediate, but there is apparently no way to do so.
17543 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17545 (match_operand:SWI248 1 "nonimmediate_operand" "")
17546 (match_operand:SWI248 2 "const_int_operand" "")))
17547 (clobber (reg:CC FLAGS_REG))])
17548 (match_scratch:SWI248 3 "r")]
17549 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17550 && satisfies_constraint_K (operands[2])"
17551 [(set (match_dup 3) (match_dup 2))
17552 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17553 (clobber (reg:CC FLAGS_REG))])]
17555 if (!rtx_equal_p (operands[0], operands[1]))
17556 emit_move_insn (operands[0], operands[1]);
17559 ;; After splitting up read-modify operations, array accesses with memory
17560 ;; operands might end up in form:
17562 ;; movl 4(%esp), %edx
17564 ;; instead of pre-splitting:
17566 ;; addl 4(%esp), %eax
17568 ;; movl 4(%esp), %edx
17569 ;; leal (%edx,%eax,4), %eax
17572 [(match_scratch:P 5 "r")
17573 (parallel [(set (match_operand 0 "register_operand" "")
17574 (ashift (match_operand 1 "register_operand" "")
17575 (match_operand 2 "const_int_operand" "")))
17576 (clobber (reg:CC FLAGS_REG))])
17577 (parallel [(set (match_operand 3 "register_operand" "")
17578 (plus (match_dup 0)
17579 (match_operand 4 "x86_64_general_operand" "")))
17580 (clobber (reg:CC FLAGS_REG))])]
17581 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17582 /* Validate MODE for lea. */
17583 && ((!TARGET_PARTIAL_REG_STALL
17584 && (GET_MODE (operands[0]) == QImode
17585 || GET_MODE (operands[0]) == HImode))
17586 || GET_MODE (operands[0]) == SImode
17587 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17588 && (rtx_equal_p (operands[0], operands[3])
17589 || peep2_reg_dead_p (2, operands[0]))
17590 /* We reorder load and the shift. */
17591 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17592 [(set (match_dup 5) (match_dup 4))
17593 (set (match_dup 0) (match_dup 1))]
17595 enum machine_mode op1mode = GET_MODE (operands[1]);
17596 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17597 int scale = 1 << INTVAL (operands[2]);
17598 rtx index = gen_lowpart (Pmode, operands[1]);
17599 rtx base = gen_lowpart (Pmode, operands[5]);
17600 rtx dest = gen_lowpart (mode, operands[3]);
17602 operands[1] = gen_rtx_PLUS (Pmode, base,
17603 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17604 operands[5] = base;
17606 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17607 if (op1mode != Pmode)
17608 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17609 operands[0] = dest;
17612 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17613 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17614 ;; caught for use by garbage collectors and the like. Using an insn that
17615 ;; maps to SIGILL makes it more likely the program will rightfully die.
17616 ;; Keeping with tradition, "6" is in honor of #UD.
17617 (define_insn "trap"
17618 [(trap_if (const_int 1) (const_int 6))]
17620 { return ASM_SHORT "0x0b0f"; }
17621 [(set_attr "length" "2")])
17623 (define_expand "prefetch"
17624 [(prefetch (match_operand 0 "address_operand" "")
17625 (match_operand:SI 1 "const_int_operand" "")
17626 (match_operand:SI 2 "const_int_operand" ""))]
17627 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17629 int rw = INTVAL (operands[1]);
17630 int locality = INTVAL (operands[2]);
17632 gcc_assert (rw == 0 || rw == 1);
17633 gcc_assert (locality >= 0 && locality <= 3);
17634 gcc_assert (GET_MODE (operands[0]) == Pmode
17635 || GET_MODE (operands[0]) == VOIDmode);
17637 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17638 supported by SSE counterpart or the SSE prefetch is not available
17639 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17641 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17642 operands[2] = GEN_INT (3);
17644 operands[1] = const0_rtx;
17647 (define_insn "*prefetch_sse_<mode>"
17648 [(prefetch (match_operand:P 0 "address_operand" "p")
17650 (match_operand:SI 1 "const_int_operand" ""))]
17651 "TARGET_PREFETCH_SSE"
17653 static const char * const patterns[4] = {
17654 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17657 int locality = INTVAL (operands[1]);
17658 gcc_assert (locality >= 0 && locality <= 3);
17660 return patterns[locality];
17662 [(set_attr "type" "sse")
17663 (set_attr "atom_sse_attr" "prefetch")
17664 (set (attr "length_address")
17665 (symbol_ref "memory_address_length (operands[0])"))
17666 (set_attr "memory" "none")])
17668 (define_insn "*prefetch_3dnow_<mode>"
17669 [(prefetch (match_operand:P 0 "address_operand" "p")
17670 (match_operand:SI 1 "const_int_operand" "n")
17674 if (INTVAL (operands[1]) == 0)
17675 return "prefetch\t%a0";
17677 return "prefetchw\t%a0";
17679 [(set_attr "type" "mmx")
17680 (set (attr "length_address")
17681 (symbol_ref "memory_address_length (operands[0])"))
17682 (set_attr "memory" "none")])
17684 (define_expand "stack_protect_set"
17685 [(match_operand 0 "memory_operand" "")
17686 (match_operand 1 "memory_operand" "")]
17689 rtx (*insn)(rtx, rtx);
17691 #ifdef TARGET_THREAD_SSP_OFFSET
17692 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17693 insn = (TARGET_LP64
17694 ? gen_stack_tls_protect_set_di
17695 : gen_stack_tls_protect_set_si);
17697 insn = (TARGET_LP64
17698 ? gen_stack_protect_set_di
17699 : gen_stack_protect_set_si);
17702 emit_insn (insn (operands[0], operands[1]));
17706 (define_insn "stack_protect_set_<mode>"
17707 [(set (match_operand:PTR 0 "memory_operand" "=m")
17708 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17710 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17711 (clobber (reg:CC FLAGS_REG))]
17713 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17714 [(set_attr "type" "multi")])
17716 (define_insn "stack_tls_protect_set_<mode>"
17717 [(set (match_operand:PTR 0 "memory_operand" "=m")
17718 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17719 UNSPEC_SP_TLS_SET))
17720 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17721 (clobber (reg:CC FLAGS_REG))]
17723 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17724 [(set_attr "type" "multi")])
17726 (define_expand "stack_protect_test"
17727 [(match_operand 0 "memory_operand" "")
17728 (match_operand 1 "memory_operand" "")
17729 (match_operand 2 "" "")]
17732 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17734 rtx (*insn)(rtx, rtx, rtx);
17736 #ifdef TARGET_THREAD_SSP_OFFSET
17737 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17738 insn = (TARGET_LP64
17739 ? gen_stack_tls_protect_test_di
17740 : gen_stack_tls_protect_test_si);
17742 insn = (TARGET_LP64
17743 ? gen_stack_protect_test_di
17744 : gen_stack_protect_test_si);
17747 emit_insn (insn (flags, operands[0], operands[1]));
17749 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17750 flags, const0_rtx, operands[2]));
17754 (define_insn "stack_protect_test_<mode>"
17755 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17756 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17757 (match_operand:PTR 2 "memory_operand" "m")]
17759 (clobber (match_scratch:PTR 3 "=&r"))]
17761 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17762 [(set_attr "type" "multi")])
17764 (define_insn "stack_tls_protect_test_<mode>"
17765 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17766 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17767 (match_operand:PTR 2 "const_int_operand" "i")]
17768 UNSPEC_SP_TLS_TEST))
17769 (clobber (match_scratch:PTR 3 "=r"))]
17771 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17772 [(set_attr "type" "multi")])
17774 (define_insn "sse4_2_crc32<mode>"
17775 [(set (match_operand:SI 0 "register_operand" "=r")
17777 [(match_operand:SI 1 "register_operand" "0")
17778 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17780 "TARGET_SSE4_2 || TARGET_CRC32"
17781 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17782 [(set_attr "type" "sselog1")
17783 (set_attr "prefix_rep" "1")
17784 (set_attr "prefix_extra" "1")
17785 (set (attr "prefix_data16")
17786 (if_then_else (match_operand:HI 2 "" "")
17788 (const_string "*")))
17789 (set (attr "prefix_rex")
17790 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17792 (const_string "*")))
17793 (set_attr "mode" "SI")])
17795 (define_insn "sse4_2_crc32di"
17796 [(set (match_operand:DI 0 "register_operand" "=r")
17798 [(match_operand:DI 1 "register_operand" "0")
17799 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17801 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17802 "crc32{q}\t{%2, %0|%0, %2}"
17803 [(set_attr "type" "sselog1")
17804 (set_attr "prefix_rep" "1")
17805 (set_attr "prefix_extra" "1")
17806 (set_attr "mode" "DI")])
17808 (define_expand "rdpmc"
17809 [(match_operand:DI 0 "register_operand" "")
17810 (match_operand:SI 1 "register_operand" "")]
17813 rtx reg = gen_reg_rtx (DImode);
17816 /* Force operand 1 into ECX. */
17817 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17818 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17819 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17824 rtvec vec = rtvec_alloc (2);
17825 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17826 rtx upper = gen_reg_rtx (DImode);
17827 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17828 gen_rtvec (1, const0_rtx),
17830 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17831 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17833 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17834 NULL, 1, OPTAB_DIRECT);
17835 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17839 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17840 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17844 (define_insn "*rdpmc"
17845 [(set (match_operand:DI 0 "register_operand" "=A")
17846 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17850 [(set_attr "type" "other")
17851 (set_attr "length" "2")])
17853 (define_insn "*rdpmc_rex64"
17854 [(set (match_operand:DI 0 "register_operand" "=a")
17855 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17857 (set (match_operand:DI 1 "register_operand" "=d")
17858 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17861 [(set_attr "type" "other")
17862 (set_attr "length" "2")])
17864 (define_expand "rdtsc"
17865 [(set (match_operand:DI 0 "register_operand" "")
17866 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17871 rtvec vec = rtvec_alloc (2);
17872 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17873 rtx upper = gen_reg_rtx (DImode);
17874 rtx lower = gen_reg_rtx (DImode);
17875 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17876 gen_rtvec (1, const0_rtx),
17878 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17879 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17881 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17882 NULL, 1, OPTAB_DIRECT);
17883 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17885 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17890 (define_insn "*rdtsc"
17891 [(set (match_operand:DI 0 "register_operand" "=A")
17892 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17895 [(set_attr "type" "other")
17896 (set_attr "length" "2")])
17898 (define_insn "*rdtsc_rex64"
17899 [(set (match_operand:DI 0 "register_operand" "=a")
17900 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17901 (set (match_operand:DI 1 "register_operand" "=d")
17902 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17905 [(set_attr "type" "other")
17906 (set_attr "length" "2")])
17908 (define_expand "rdtscp"
17909 [(match_operand:DI 0 "register_operand" "")
17910 (match_operand:SI 1 "memory_operand" "")]
17913 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17914 gen_rtvec (1, const0_rtx),
17916 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17917 gen_rtvec (1, const0_rtx),
17919 rtx reg = gen_reg_rtx (DImode);
17920 rtx tmp = gen_reg_rtx (SImode);
17924 rtvec vec = rtvec_alloc (3);
17925 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17926 rtx upper = gen_reg_rtx (DImode);
17927 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17928 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17929 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17931 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17932 NULL, 1, OPTAB_DIRECT);
17933 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17938 rtvec vec = rtvec_alloc (2);
17939 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17940 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17941 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17944 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17945 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17949 (define_insn "*rdtscp"
17950 [(set (match_operand:DI 0 "register_operand" "=A")
17951 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17952 (set (match_operand:SI 1 "register_operand" "=c")
17953 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17956 [(set_attr "type" "other")
17957 (set_attr "length" "3")])
17959 (define_insn "*rdtscp_rex64"
17960 [(set (match_operand:DI 0 "register_operand" "=a")
17961 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17962 (set (match_operand:DI 1 "register_operand" "=d")
17963 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17964 (set (match_operand:SI 2 "register_operand" "=c")
17965 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17968 [(set_attr "type" "other")
17969 (set_attr "length" "3")])
17971 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17973 ;; LWP instructions
17975 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17977 (define_expand "lwp_llwpcb"
17978 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17979 UNSPECV_LLWP_INTRINSIC)]
17982 (define_insn "*lwp_llwpcb<mode>1"
17983 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17984 UNSPECV_LLWP_INTRINSIC)]
17987 [(set_attr "type" "lwp")
17988 (set_attr "mode" "<MODE>")
17989 (set_attr "length" "5")])
17991 (define_expand "lwp_slwpcb"
17992 [(set (match_operand 0 "register_operand" "=r")
17993 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
17998 insn = (TARGET_64BIT
18000 : gen_lwp_slwpcbsi);
18002 emit_insn (insn (operands[0]));
18006 (define_insn "lwp_slwpcb<mode>"
18007 [(set (match_operand:P 0 "register_operand" "=r")
18008 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18011 [(set_attr "type" "lwp")
18012 (set_attr "mode" "<MODE>")
18013 (set_attr "length" "5")])
18015 (define_expand "lwp_lwpval<mode>3"
18016 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18017 (match_operand:SI 2 "nonimmediate_operand" "rm")
18018 (match_operand:SI 3 "const_int_operand" "i")]
18019 UNSPECV_LWPVAL_INTRINSIC)]
18021 ;; Avoid unused variable warning.
18022 "(void) operands[0];")
18024 (define_insn "*lwp_lwpval<mode>3_1"
18025 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18026 (match_operand:SI 1 "nonimmediate_operand" "rm")
18027 (match_operand:SI 2 "const_int_operand" "i")]
18028 UNSPECV_LWPVAL_INTRINSIC)]
18030 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18031 [(set_attr "type" "lwp")
18032 (set_attr "mode" "<MODE>")
18033 (set (attr "length")
18034 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18036 (define_expand "lwp_lwpins<mode>3"
18037 [(set (reg:CCC FLAGS_REG)
18038 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18039 (match_operand:SI 2 "nonimmediate_operand" "rm")
18040 (match_operand:SI 3 "const_int_operand" "i")]
18041 UNSPECV_LWPINS_INTRINSIC))
18042 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18043 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18046 (define_insn "*lwp_lwpins<mode>3_1"
18047 [(set (reg:CCC FLAGS_REG)
18048 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18049 (match_operand:SI 1 "nonimmediate_operand" "rm")
18050 (match_operand:SI 2 "const_int_operand" "i")]
18051 UNSPECV_LWPINS_INTRINSIC))]
18053 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18054 [(set_attr "type" "lwp")
18055 (set_attr "mode" "<MODE>")
18056 (set (attr "length")
18057 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18059 (define_insn "rdfsbase<mode>"
18060 [(set (match_operand:SWI48 0 "register_operand" "=r")
18061 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18062 "TARGET_64BIT && TARGET_FSGSBASE"
18064 [(set_attr "type" "other")
18065 (set_attr "prefix_extra" "2")])
18067 (define_insn "rdgsbase<mode>"
18068 [(set (match_operand:SWI48 0 "register_operand" "=r")
18069 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18070 "TARGET_64BIT && TARGET_FSGSBASE"
18072 [(set_attr "type" "other")
18073 (set_attr "prefix_extra" "2")])
18075 (define_insn "wrfsbase<mode>"
18076 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18078 "TARGET_64BIT && TARGET_FSGSBASE"
18080 [(set_attr "type" "other")
18081 (set_attr "prefix_extra" "2")])
18083 (define_insn "wrgsbase<mode>"
18084 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18086 "TARGET_64BIT && TARGET_FSGSBASE"
18088 [(set_attr "type" "other")
18089 (set_attr "prefix_extra" "2")])
18091 (define_insn "rdrand<mode>_1"
18092 [(set (match_operand:SWI248 0 "register_operand" "=r")
18093 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18094 (set (reg:CCC FLAGS_REG)
18095 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18098 [(set_attr "type" "other")
18099 (set_attr "prefix_extra" "1")])
18101 (define_expand "pause"
18102 [(set (match_dup 0)
18103 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18106 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18107 MEM_VOLATILE_P (operands[0]) = 1;
18110 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18111 ;; They have the same encoding.
18112 (define_insn "*pause"
18113 [(set (match_operand:BLK 0 "" "")
18114 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18117 [(set_attr "length" "2")
18118 (set_attr "memory" "unknown")])
18122 (include "sync.md")