1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; Y -- print condition for XOP pcom* instruction.
62 ;; + -- print a branch hint as 'cs' or 'ds' prefix
63 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; ~ -- print "i" if TARGET_AVX2, "f" otherwise.
65 ;; @ -- print a segment register of thread base pointer load
66 ;; ^ -- print addr32 prefix if TARGET_64BIT and Pmode != word_mode
68 (define_c_enum "unspec" [
69 ;; Relocation specifiers
80 UNSPEC_MACHOPIC_OFFSET
90 UNSPEC_MEMORY_BLOCKAGE
101 ;; Other random patterns
110 UNSPEC_LD_MPIC ; load_macho_picbase
112 UNSPEC_DIV_ALREADY_SPLIT
113 UNSPEC_MS_TO_SYSV_CALL
114 UNSPEC_CALL_NEEDS_VZEROUPPER
118 ;; For SSE/MMX support:
126 ;; Generic math support
128 UNSPEC_IEEE_MIN ; not commutative
129 UNSPEC_IEEE_MAX ; not commutative
131 ;; x87 Floating point
147 UNSPEC_FRNDINT_MASK_PM
151 ;; x87 Double output FP
178 ;; For RDRAND support
189 (define_c_enum "unspecv" [
192 UNSPECV_PROBE_STACK_RANGE
195 UNSPECV_SPLIT_STACK_RETURN
201 UNSPECV_LLWP_INTRINSIC
202 UNSPECV_SLWP_INTRINSIC
203 UNSPECV_LWPVAL_INTRINSIC
204 UNSPECV_LWPINS_INTRINSIC
211 ;; Constants to represent rounding modes in the ROUND instruction
220 ;; Constants to represent pcomtrue/pcomfalse variants
230 ;; Constants used in the XOP pperm instruction
232 [(PPERM_SRC 0x00) /* copy source */
233 (PPERM_INVERT 0x20) /* invert source */
234 (PPERM_REVERSE 0x40) /* bit reverse source */
235 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
236 (PPERM_ZERO 0x80) /* all 0's */
237 (PPERM_ONES 0xa0) /* all 1's */
238 (PPERM_SIGN 0xc0) /* propagate sign bit */
239 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
240 (PPERM_SRC1 0x00) /* use first source byte */
241 (PPERM_SRC2 0x10) /* use second source byte */
244 ;; Registers by name.
297 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
300 ;; In C guard expressions, put expressions which may be compile-time
301 ;; constants first. This allows for better optimization. For
302 ;; example, write "TARGET_64BIT && reload_completed", not
303 ;; "reload_completed && TARGET_64BIT".
307 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
308 atom,generic64,amdfam10,bdver1,bdver2,btver1"
309 (const (symbol_ref "ix86_schedule")))
311 ;; A basic instruction type. Refinements due to arguments to be
312 ;; provided in other attributes.
315 alu,alu1,negnot,imov,imovx,lea,
316 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
317 icmp,test,ibr,setcc,icmov,
318 push,pop,call,callv,leave,
320 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
321 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
322 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
323 ssemuladd,sse4arg,lwp,
324 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
325 (const_string "other"))
327 ;; Main data type used by the insn
329 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
330 (const_string "unknown"))
332 ;; The CPU unit operations uses.
333 (define_attr "unit" "integer,i387,sse,mmx,unknown"
334 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
335 (const_string "i387")
336 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
337 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
338 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
340 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
342 (eq_attr "type" "other")
343 (const_string "unknown")]
344 (const_string "integer")))
346 ;; The (bounding maximum) length of an instruction immediate.
347 (define_attr "length_immediate" ""
348 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
351 (eq_attr "unit" "i387,sse,mmx")
353 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
354 rotate,rotatex,rotate1,imul,icmp,push,pop")
355 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
356 (eq_attr "type" "imov,test")
357 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
358 (eq_attr "type" "call")
359 (if_then_else (match_operand 0 "constant_call_address_operand" "")
362 (eq_attr "type" "callv")
363 (if_then_else (match_operand 1 "constant_call_address_operand" "")
366 ;; We don't know the size before shorten_branches. Expect
367 ;; the instruction to fit for better scheduling.
368 (eq_attr "type" "ibr")
371 (symbol_ref "/* Update immediate_length and other attributes! */
372 gcc_unreachable (),1")))
374 ;; The (bounding maximum) length of an instruction address.
375 (define_attr "length_address" ""
376 (cond [(eq_attr "type" "str,other,multi,fxch")
378 (and (eq_attr "type" "call")
379 (match_operand 0 "constant_call_address_operand" ""))
381 (and (eq_attr "type" "callv")
382 (match_operand 1 "constant_call_address_operand" ""))
385 (symbol_ref "ix86_attr_length_address_default (insn)")))
387 ;; Set when length prefix is used.
388 (define_attr "prefix_data16" ""
389 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
391 (eq_attr "mode" "HI")
393 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
398 ;; Set when string REP prefix is used.
399 (define_attr "prefix_rep" ""
400 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
402 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
407 ;; Set when 0f opcode prefix is used.
408 (define_attr "prefix_0f" ""
410 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
411 (eq_attr "unit" "sse,mmx"))
415 ;; Set when REX opcode prefix is used.
416 (define_attr "prefix_rex" ""
417 (cond [(not (match_test "TARGET_64BIT"))
419 (and (eq_attr "mode" "DI")
420 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
421 (eq_attr "unit" "!mmx")))
423 (and (eq_attr "mode" "QI")
424 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
426 (match_test "x86_extended_reg_mentioned_p (insn)")
428 (and (eq_attr "type" "imovx")
429 (match_operand:QI 1 "ext_QIreg_operand" ""))
434 ;; There are also additional prefixes in 3DNOW, SSSE3.
435 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
436 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
437 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
438 (define_attr "prefix_extra" ""
439 (cond [(eq_attr "type" "ssemuladd,sse4arg")
441 (eq_attr "type" "sseiadd1,ssecvt1")
446 ;; Prefix used: original, VEX or maybe VEX.
447 (define_attr "prefix" "orig,vex,maybe_vex"
448 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
450 (const_string "orig")))
452 ;; VEX W bit is used.
453 (define_attr "prefix_vex_w" "" (const_int 0))
455 ;; The length of VEX prefix
456 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
457 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
458 ;; still prefix_0f 1, with prefix_extra 1.
459 (define_attr "length_vex" ""
460 (if_then_else (and (eq_attr "prefix_0f" "1")
461 (eq_attr "prefix_extra" "0"))
462 (if_then_else (eq_attr "prefix_vex_w" "1")
463 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
464 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
465 (if_then_else (eq_attr "prefix_vex_w" "1")
466 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
467 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
469 ;; Set when modrm byte is used.
470 (define_attr "modrm" ""
471 (cond [(eq_attr "type" "str,leave")
473 (eq_attr "unit" "i387")
475 (and (eq_attr "type" "incdec")
476 (and (not (match_test "TARGET_64BIT"))
477 (ior (match_operand:SI 1 "register_operand" "")
478 (match_operand:HI 1 "register_operand" ""))))
480 (and (eq_attr "type" "push")
481 (not (match_operand 1 "memory_operand" "")))
483 (and (eq_attr "type" "pop")
484 (not (match_operand 0 "memory_operand" "")))
486 (and (eq_attr "type" "imov")
487 (and (not (eq_attr "mode" "DI"))
488 (ior (and (match_operand 0 "register_operand" "")
489 (match_operand 1 "immediate_operand" ""))
490 (ior (and (match_operand 0 "ax_reg_operand" "")
491 (match_operand 1 "memory_displacement_only_operand" ""))
492 (and (match_operand 0 "memory_displacement_only_operand" "")
493 (match_operand 1 "ax_reg_operand" ""))))))
495 (and (eq_attr "type" "call")
496 (match_operand 0 "constant_call_address_operand" ""))
498 (and (eq_attr "type" "callv")
499 (match_operand 1 "constant_call_address_operand" ""))
501 (and (eq_attr "type" "alu,alu1,icmp,test")
502 (match_operand 0 "ax_reg_operand" ""))
503 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
507 ;; The (bounding maximum) length of an instruction in bytes.
508 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
509 ;; Later we may want to split them and compute proper length as for
511 (define_attr "length" ""
512 (cond [(eq_attr "type" "other,multi,fistp,frndint")
514 (eq_attr "type" "fcmp")
516 (eq_attr "unit" "i387")
518 (plus (attr "prefix_data16")
519 (attr "length_address")))
520 (ior (eq_attr "prefix" "vex")
521 (and (eq_attr "prefix" "maybe_vex")
522 (match_test "TARGET_AVX")))
523 (plus (attr "length_vex")
524 (plus (attr "length_immediate")
526 (attr "length_address"))))]
527 (plus (plus (attr "modrm")
528 (plus (attr "prefix_0f")
529 (plus (attr "prefix_rex")
530 (plus (attr "prefix_extra")
532 (plus (attr "prefix_rep")
533 (plus (attr "prefix_data16")
534 (plus (attr "length_immediate")
535 (attr "length_address")))))))
537 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
538 ;; `store' if there is a simple memory reference therein, or `unknown'
539 ;; if the instruction is complex.
541 (define_attr "memory" "none,load,store,both,unknown"
542 (cond [(eq_attr "type" "other,multi,str,lwp")
543 (const_string "unknown")
544 (eq_attr "type" "lea,fcmov,fpspc")
545 (const_string "none")
546 (eq_attr "type" "fistp,leave")
547 (const_string "both")
548 (eq_attr "type" "frndint")
549 (const_string "load")
550 (eq_attr "type" "push")
551 (if_then_else (match_operand 1 "memory_operand" "")
552 (const_string "both")
553 (const_string "store"))
554 (eq_attr "type" "pop")
555 (if_then_else (match_operand 0 "memory_operand" "")
556 (const_string "both")
557 (const_string "load"))
558 (eq_attr "type" "setcc")
559 (if_then_else (match_operand 0 "memory_operand" "")
560 (const_string "store")
561 (const_string "none"))
562 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
563 (if_then_else (ior (match_operand 0 "memory_operand" "")
564 (match_operand 1 "memory_operand" ""))
565 (const_string "load")
566 (const_string "none"))
567 (eq_attr "type" "ibr")
568 (if_then_else (match_operand 0 "memory_operand" "")
569 (const_string "load")
570 (const_string "none"))
571 (eq_attr "type" "call")
572 (if_then_else (match_operand 0 "constant_call_address_operand" "")
573 (const_string "none")
574 (const_string "load"))
575 (eq_attr "type" "callv")
576 (if_then_else (match_operand 1 "constant_call_address_operand" "")
577 (const_string "none")
578 (const_string "load"))
579 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
580 (match_operand 1 "memory_operand" ""))
581 (const_string "both")
582 (and (match_operand 0 "memory_operand" "")
583 (match_operand 1 "memory_operand" ""))
584 (const_string "both")
585 (match_operand 0 "memory_operand" "")
586 (const_string "store")
587 (match_operand 1 "memory_operand" "")
588 (const_string "load")
590 "!alu1,negnot,ishift1,
591 imov,imovx,icmp,test,bitmanip,
593 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
594 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
595 (match_operand 2 "memory_operand" ""))
596 (const_string "load")
597 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
598 (match_operand 3 "memory_operand" ""))
599 (const_string "load")
601 (const_string "none")))
603 ;; Indicates if an instruction has both an immediate and a displacement.
605 (define_attr "imm_disp" "false,true,unknown"
606 (cond [(eq_attr "type" "other,multi")
607 (const_string "unknown")
608 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
609 (and (match_operand 0 "memory_displacement_operand" "")
610 (match_operand 1 "immediate_operand" "")))
611 (const_string "true")
612 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
613 (and (match_operand 0 "memory_displacement_operand" "")
614 (match_operand 2 "immediate_operand" "")))
615 (const_string "true")
617 (const_string "false")))
619 ;; Indicates if an FP operation has an integer source.
621 (define_attr "fp_int_src" "false,true"
622 (const_string "false"))
624 ;; Defines rounding mode of an FP operation.
626 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
627 (const_string "any"))
629 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
630 (define_attr "use_carry" "0,1" (const_string "0"))
632 ;; Define attribute to indicate unaligned ssemov insns
633 (define_attr "movu" "0,1" (const_string "0"))
635 ;; Used to control the "enabled" attribute on a per-instruction basis.
636 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
637 (const_string "base"))
639 (define_attr "enabled" ""
640 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
641 (eq_attr "isa" "sse2_noavx")
642 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
643 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
644 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
645 (eq_attr "isa" "sse4_noavx")
646 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
647 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
648 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
649 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
653 ;; Describe a user's asm statement.
654 (define_asm_attributes
655 [(set_attr "length" "128")
656 (set_attr "type" "multi")])
658 (define_code_iterator plusminus [plus minus])
660 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
662 ;; Base name for define_insn
663 (define_code_attr plusminus_insn
664 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
665 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
667 ;; Base name for insn mnemonic.
668 (define_code_attr plusminus_mnemonic
669 [(plus "add") (ss_plus "adds") (us_plus "addus")
670 (minus "sub") (ss_minus "subs") (us_minus "subus")])
671 (define_code_attr plusminus_carry_mnemonic
672 [(plus "adc") (minus "sbb")])
674 ;; Mark commutative operators as such in constraints.
675 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
676 (minus "") (ss_minus "") (us_minus "")])
678 ;; Mapping of max and min
679 (define_code_iterator maxmin [smax smin umax umin])
681 ;; Mapping of signed max and min
682 (define_code_iterator smaxmin [smax smin])
684 ;; Mapping of unsigned max and min
685 (define_code_iterator umaxmin [umax umin])
687 ;; Base name for integer and FP insn mnemonic
688 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
689 (umax "maxu") (umin "minu")])
690 (define_code_attr maxmin_float [(smax "max") (smin "min")])
692 ;; Mapping of logic operators
693 (define_code_iterator any_logic [and ior xor])
694 (define_code_iterator any_or [ior xor])
696 ;; Base name for insn mnemonic.
697 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
699 ;; Mapping of logic-shift operators
700 (define_code_iterator any_lshift [ashift lshiftrt])
702 ;; Mapping of shift-right operators
703 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
705 ;; Base name for define_insn
706 (define_code_attr shift_insn
707 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
709 ;; Base name for insn mnemonic.
710 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
711 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
713 ;; Mapping of rotate operators
714 (define_code_iterator any_rotate [rotate rotatert])
716 ;; Base name for define_insn
717 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
719 ;; Base name for insn mnemonic.
720 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
722 ;; Mapping of abs neg operators
723 (define_code_iterator absneg [abs neg])
725 ;; Base name for x87 insn mnemonic.
726 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
728 ;; Used in signed and unsigned widening multiplications.
729 (define_code_iterator any_extend [sign_extend zero_extend])
731 ;; Prefix for insn menmonic.
732 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
734 ;; Prefix for define_insn
735 (define_code_attr u [(sign_extend "") (zero_extend "u")])
736 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
738 ;; All integer modes.
739 (define_mode_iterator SWI1248x [QI HI SI DI])
741 ;; All integer modes without QImode.
742 (define_mode_iterator SWI248x [HI SI DI])
744 ;; All integer modes without QImode and HImode.
745 (define_mode_iterator SWI48x [SI DI])
747 ;; All integer modes without SImode and DImode.
748 (define_mode_iterator SWI12 [QI HI])
750 ;; All integer modes without DImode.
751 (define_mode_iterator SWI124 [QI HI SI])
753 ;; All integer modes without QImode and DImode.
754 (define_mode_iterator SWI24 [HI SI])
756 ;; Single word integer modes.
757 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
759 ;; Single word integer modes without QImode.
760 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
762 ;; Single word integer modes without QImode and HImode.
763 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
765 ;; All math-dependant single and double word integer modes.
766 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
767 (HI "TARGET_HIMODE_MATH")
768 SI DI (TI "TARGET_64BIT")])
770 ;; Math-dependant single word integer modes.
771 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
772 (HI "TARGET_HIMODE_MATH")
773 SI (DI "TARGET_64BIT")])
775 ;; Math-dependant integer modes without DImode.
776 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
777 (HI "TARGET_HIMODE_MATH")
780 ;; Math-dependant single word integer modes without QImode.
781 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
782 SI (DI "TARGET_64BIT")])
784 ;; Double word integer modes.
785 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
786 (TI "TARGET_64BIT")])
788 ;; Double word integer modes as mode attribute.
789 (define_mode_attr DWI [(SI "DI") (DI "TI")])
790 (define_mode_attr dwi [(SI "di") (DI "ti")])
792 ;; Half mode for double word integer modes.
793 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
794 (DI "TARGET_64BIT")])
796 ;; Instruction suffix for integer modes.
797 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
799 ;; Pointer size prefix for integer modes (Intel asm dialect)
800 (define_mode_attr iptrsize [(QI "BYTE")
805 ;; Register class for integer modes.
806 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
808 ;; Immediate operand constraint for integer modes.
809 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
811 ;; General operand constraint for word modes.
812 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
814 ;; Immediate operand constraint for double integer modes.
815 (define_mode_attr di [(SI "nF") (DI "e")])
817 ;; Immediate operand constraint for shifts.
818 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
820 ;; General operand predicate for integer modes.
821 (define_mode_attr general_operand
822 [(QI "general_operand")
823 (HI "general_operand")
824 (SI "x86_64_general_operand")
825 (DI "x86_64_general_operand")
826 (TI "x86_64_general_operand")])
828 ;; General sign/zero extend operand predicate for integer modes.
829 (define_mode_attr general_szext_operand
830 [(QI "general_operand")
831 (HI "general_operand")
832 (SI "x86_64_szext_general_operand")
833 (DI "x86_64_szext_general_operand")])
835 ;; Immediate operand predicate for integer modes.
836 (define_mode_attr immediate_operand
837 [(QI "immediate_operand")
838 (HI "immediate_operand")
839 (SI "x86_64_immediate_operand")
840 (DI "x86_64_immediate_operand")])
842 ;; Nonmemory operand predicate for integer modes.
843 (define_mode_attr nonmemory_operand
844 [(QI "nonmemory_operand")
845 (HI "nonmemory_operand")
846 (SI "x86_64_nonmemory_operand")
847 (DI "x86_64_nonmemory_operand")])
849 ;; Operand predicate for shifts.
850 (define_mode_attr shift_operand
851 [(QI "nonimmediate_operand")
852 (HI "nonimmediate_operand")
853 (SI "nonimmediate_operand")
854 (DI "shiftdi_operand")
855 (TI "register_operand")])
857 ;; Operand predicate for shift argument.
858 (define_mode_attr shift_immediate_operand
859 [(QI "const_1_to_31_operand")
860 (HI "const_1_to_31_operand")
861 (SI "const_1_to_31_operand")
862 (DI "const_1_to_63_operand")])
864 ;; Input operand predicate for arithmetic left shifts.
865 (define_mode_attr ashl_input_operand
866 [(QI "nonimmediate_operand")
867 (HI "nonimmediate_operand")
868 (SI "nonimmediate_operand")
869 (DI "ashldi_input_operand")
870 (TI "reg_or_pm1_operand")])
872 ;; SSE and x87 SFmode and DFmode floating point modes
873 (define_mode_iterator MODEF [SF DF])
875 ;; All x87 floating point modes
876 (define_mode_iterator X87MODEF [SF DF XF])
878 ;; SSE instruction suffix for various modes
879 (define_mode_attr ssemodesuffix
881 (V8SF "ps") (V4DF "pd")
882 (V4SF "ps") (V2DF "pd")
883 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
884 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
886 ;; SSE vector suffix for floating point modes
887 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
889 ;; SSE vector mode corresponding to a scalar mode
890 (define_mode_attr ssevecmode
891 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
893 ;; Instruction suffix for REX 64bit operators.
894 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
896 ;; This mode iterator allows :P to be used for patterns that operate on
897 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
898 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
900 ;; This mode iterator allows :W to be used for patterns that operate on
901 ;; word_mode sized quantities.
902 (define_mode_iterator W
903 [(SI "word_mode == SImode") (DI "word_mode == DImode")])
905 ;; This mode iterator allows :PTR to be used for patterns that operate on
906 ;; ptr_mode sized quantities.
907 (define_mode_iterator PTR
908 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
910 ;; Scheduling descriptions
912 (include "pentium.md")
915 (include "athlon.md")
916 (include "bdver1.md")
922 ;; Operand and operator predicates and constraints
924 (include "predicates.md")
925 (include "constraints.md")
928 ;; Compare and branch/compare and store instructions.
930 (define_expand "cbranch<mode>4"
931 [(set (reg:CC FLAGS_REG)
932 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
933 (match_operand:SDWIM 2 "<general_operand>" "")))
934 (set (pc) (if_then_else
935 (match_operator 0 "ordered_comparison_operator"
936 [(reg:CC FLAGS_REG) (const_int 0)])
937 (label_ref (match_operand 3 "" ""))
941 if (MEM_P (operands[1]) && MEM_P (operands[2]))
942 operands[1] = force_reg (<MODE>mode, operands[1]);
943 ix86_expand_branch (GET_CODE (operands[0]),
944 operands[1], operands[2], operands[3]);
948 (define_expand "cstore<mode>4"
949 [(set (reg:CC FLAGS_REG)
950 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
951 (match_operand:SWIM 3 "<general_operand>" "")))
952 (set (match_operand:QI 0 "register_operand" "")
953 (match_operator 1 "ordered_comparison_operator"
954 [(reg:CC FLAGS_REG) (const_int 0)]))]
957 if (MEM_P (operands[2]) && MEM_P (operands[3]))
958 operands[2] = force_reg (<MODE>mode, operands[2]);
959 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
960 operands[2], operands[3]);
964 (define_expand "cmp<mode>_1"
965 [(set (reg:CC FLAGS_REG)
966 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
967 (match_operand:SWI48 1 "<general_operand>" "")))])
969 (define_insn "*cmp<mode>_ccno_1"
970 [(set (reg FLAGS_REG)
971 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
972 (match_operand:SWI 1 "const0_operand" "")))]
973 "ix86_match_ccmode (insn, CCNOmode)"
975 test{<imodesuffix>}\t%0, %0
976 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
977 [(set_attr "type" "test,icmp")
978 (set_attr "length_immediate" "0,1")
979 (set_attr "mode" "<MODE>")])
981 (define_insn "*cmp<mode>_1"
982 [(set (reg FLAGS_REG)
983 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
984 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
985 "ix86_match_ccmode (insn, CCmode)"
986 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
987 [(set_attr "type" "icmp")
988 (set_attr "mode" "<MODE>")])
990 (define_insn "*cmp<mode>_minus_1"
991 [(set (reg FLAGS_REG)
993 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
994 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
996 "ix86_match_ccmode (insn, CCGOCmode)"
997 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
998 [(set_attr "type" "icmp")
999 (set_attr "mode" "<MODE>")])
1001 (define_insn "*cmpqi_ext_1"
1002 [(set (reg FLAGS_REG)
1004 (match_operand:QI 0 "general_operand" "Qm")
1007 (match_operand 1 "ext_register_operand" "Q")
1009 (const_int 8)) 0)))]
1010 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1011 "cmp{b}\t{%h1, %0|%0, %h1}"
1012 [(set_attr "type" "icmp")
1013 (set_attr "mode" "QI")])
1015 (define_insn "*cmpqi_ext_1_rex64"
1016 [(set (reg FLAGS_REG)
1018 (match_operand:QI 0 "register_operand" "Q")
1021 (match_operand 1 "ext_register_operand" "Q")
1023 (const_int 8)) 0)))]
1024 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1025 "cmp{b}\t{%h1, %0|%0, %h1}"
1026 [(set_attr "type" "icmp")
1027 (set_attr "mode" "QI")])
1029 (define_insn "*cmpqi_ext_2"
1030 [(set (reg FLAGS_REG)
1034 (match_operand 0 "ext_register_operand" "Q")
1037 (match_operand:QI 1 "const0_operand" "")))]
1038 "ix86_match_ccmode (insn, CCNOmode)"
1040 [(set_attr "type" "test")
1041 (set_attr "length_immediate" "0")
1042 (set_attr "mode" "QI")])
1044 (define_expand "cmpqi_ext_3"
1045 [(set (reg:CC FLAGS_REG)
1049 (match_operand 0 "ext_register_operand" "")
1052 (match_operand:QI 1 "immediate_operand" "")))])
1054 (define_insn "*cmpqi_ext_3_insn"
1055 [(set (reg FLAGS_REG)
1059 (match_operand 0 "ext_register_operand" "Q")
1062 (match_operand:QI 1 "general_operand" "Qmn")))]
1063 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1064 "cmp{b}\t{%1, %h0|%h0, %1}"
1065 [(set_attr "type" "icmp")
1066 (set_attr "modrm" "1")
1067 (set_attr "mode" "QI")])
1069 (define_insn "*cmpqi_ext_3_insn_rex64"
1070 [(set (reg FLAGS_REG)
1074 (match_operand 0 "ext_register_operand" "Q")
1077 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1078 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1079 "cmp{b}\t{%1, %h0|%h0, %1}"
1080 [(set_attr "type" "icmp")
1081 (set_attr "modrm" "1")
1082 (set_attr "mode" "QI")])
1084 (define_insn "*cmpqi_ext_4"
1085 [(set (reg FLAGS_REG)
1089 (match_operand 0 "ext_register_operand" "Q")
1094 (match_operand 1 "ext_register_operand" "Q")
1096 (const_int 8)) 0)))]
1097 "ix86_match_ccmode (insn, CCmode)"
1098 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1099 [(set_attr "type" "icmp")
1100 (set_attr "mode" "QI")])
1102 ;; These implement float point compares.
1103 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1104 ;; which would allow mix and match FP modes on the compares. Which is what
1105 ;; the old patterns did, but with many more of them.
1107 (define_expand "cbranchxf4"
1108 [(set (reg:CC FLAGS_REG)
1109 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1110 (match_operand:XF 2 "nonmemory_operand" "")))
1111 (set (pc) (if_then_else
1112 (match_operator 0 "ix86_fp_comparison_operator"
1115 (label_ref (match_operand 3 "" ""))
1119 ix86_expand_branch (GET_CODE (operands[0]),
1120 operands[1], operands[2], operands[3]);
1124 (define_expand "cstorexf4"
1125 [(set (reg:CC FLAGS_REG)
1126 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1127 (match_operand:XF 3 "nonmemory_operand" "")))
1128 (set (match_operand:QI 0 "register_operand" "")
1129 (match_operator 1 "ix86_fp_comparison_operator"
1134 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1135 operands[2], operands[3]);
1139 (define_expand "cbranch<mode>4"
1140 [(set (reg:CC FLAGS_REG)
1141 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1142 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1143 (set (pc) (if_then_else
1144 (match_operator 0 "ix86_fp_comparison_operator"
1147 (label_ref (match_operand 3 "" ""))
1149 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1151 ix86_expand_branch (GET_CODE (operands[0]),
1152 operands[1], operands[2], operands[3]);
1156 (define_expand "cstore<mode>4"
1157 [(set (reg:CC FLAGS_REG)
1158 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1159 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1160 (set (match_operand:QI 0 "register_operand" "")
1161 (match_operator 1 "ix86_fp_comparison_operator"
1164 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1166 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1167 operands[2], operands[3]);
1171 (define_expand "cbranchcc4"
1172 [(set (pc) (if_then_else
1173 (match_operator 0 "comparison_operator"
1174 [(match_operand 1 "flags_reg_operand" "")
1175 (match_operand 2 "const0_operand" "")])
1176 (label_ref (match_operand 3 "" ""))
1180 ix86_expand_branch (GET_CODE (operands[0]),
1181 operands[1], operands[2], operands[3]);
1185 (define_expand "cstorecc4"
1186 [(set (match_operand:QI 0 "register_operand" "")
1187 (match_operator 1 "comparison_operator"
1188 [(match_operand 2 "flags_reg_operand" "")
1189 (match_operand 3 "const0_operand" "")]))]
1192 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1193 operands[2], operands[3]);
1198 ;; FP compares, step 1:
1199 ;; Set the FP condition codes.
1201 ;; CCFPmode compare with exceptions
1202 ;; CCFPUmode compare with no exceptions
1204 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1205 ;; used to manage the reg stack popping would not be preserved.
1207 (define_insn "*cmpfp_0"
1208 [(set (match_operand:HI 0 "register_operand" "=a")
1211 (match_operand 1 "register_operand" "f")
1212 (match_operand 2 "const0_operand" ""))]
1214 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1215 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1216 "* return output_fp_compare (insn, operands, false, false);"
1217 [(set_attr "type" "multi")
1218 (set_attr "unit" "i387")
1220 (cond [(match_operand:SF 1 "" "")
1222 (match_operand:DF 1 "" "")
1225 (const_string "XF")))])
1227 (define_insn_and_split "*cmpfp_0_cc"
1228 [(set (reg:CCFP FLAGS_REG)
1230 (match_operand 1 "register_operand" "f")
1231 (match_operand 2 "const0_operand" "")))
1232 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1233 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1234 && TARGET_SAHF && !TARGET_CMOVE
1235 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1237 "&& reload_completed"
1240 [(compare:CCFP (match_dup 1)(match_dup 2))]
1242 (set (reg:CC FLAGS_REG)
1243 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1245 [(set_attr "type" "multi")
1246 (set_attr "unit" "i387")
1248 (cond [(match_operand:SF 1 "" "")
1250 (match_operand:DF 1 "" "")
1253 (const_string "XF")))])
1255 (define_insn "*cmpfp_xf"
1256 [(set (match_operand:HI 0 "register_operand" "=a")
1259 (match_operand:XF 1 "register_operand" "f")
1260 (match_operand:XF 2 "register_operand" "f"))]
1263 "* return output_fp_compare (insn, operands, false, false);"
1264 [(set_attr "type" "multi")
1265 (set_attr "unit" "i387")
1266 (set_attr "mode" "XF")])
1268 (define_insn_and_split "*cmpfp_xf_cc"
1269 [(set (reg:CCFP FLAGS_REG)
1271 (match_operand:XF 1 "register_operand" "f")
1272 (match_operand:XF 2 "register_operand" "f")))
1273 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1275 && TARGET_SAHF && !TARGET_CMOVE"
1277 "&& reload_completed"
1280 [(compare:CCFP (match_dup 1)(match_dup 2))]
1282 (set (reg:CC FLAGS_REG)
1283 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1285 [(set_attr "type" "multi")
1286 (set_attr "unit" "i387")
1287 (set_attr "mode" "XF")])
1289 (define_insn "*cmpfp_<mode>"
1290 [(set (match_operand:HI 0 "register_operand" "=a")
1293 (match_operand:MODEF 1 "register_operand" "f")
1294 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1297 "* return output_fp_compare (insn, operands, false, false);"
1298 [(set_attr "type" "multi")
1299 (set_attr "unit" "i387")
1300 (set_attr "mode" "<MODE>")])
1302 (define_insn_and_split "*cmpfp_<mode>_cc"
1303 [(set (reg:CCFP FLAGS_REG)
1305 (match_operand:MODEF 1 "register_operand" "f")
1306 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1307 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1309 && TARGET_SAHF && !TARGET_CMOVE"
1311 "&& reload_completed"
1314 [(compare:CCFP (match_dup 1)(match_dup 2))]
1316 (set (reg:CC FLAGS_REG)
1317 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1319 [(set_attr "type" "multi")
1320 (set_attr "unit" "i387")
1321 (set_attr "mode" "<MODE>")])
1323 (define_insn "*cmpfp_u"
1324 [(set (match_operand:HI 0 "register_operand" "=a")
1327 (match_operand 1 "register_operand" "f")
1328 (match_operand 2 "register_operand" "f"))]
1330 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1331 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1332 "* return output_fp_compare (insn, operands, false, true);"
1333 [(set_attr "type" "multi")
1334 (set_attr "unit" "i387")
1336 (cond [(match_operand:SF 1 "" "")
1338 (match_operand:DF 1 "" "")
1341 (const_string "XF")))])
1343 (define_insn_and_split "*cmpfp_u_cc"
1344 [(set (reg:CCFPU FLAGS_REG)
1346 (match_operand 1 "register_operand" "f")
1347 (match_operand 2 "register_operand" "f")))
1348 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1349 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1350 && TARGET_SAHF && !TARGET_CMOVE
1351 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1353 "&& reload_completed"
1356 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1358 (set (reg:CC FLAGS_REG)
1359 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1361 [(set_attr "type" "multi")
1362 (set_attr "unit" "i387")
1364 (cond [(match_operand:SF 1 "" "")
1366 (match_operand:DF 1 "" "")
1369 (const_string "XF")))])
1371 (define_insn "*cmpfp_<mode>"
1372 [(set (match_operand:HI 0 "register_operand" "=a")
1375 (match_operand 1 "register_operand" "f")
1376 (match_operator 3 "float_operator"
1377 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1379 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1380 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1381 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1382 "* return output_fp_compare (insn, operands, false, false);"
1383 [(set_attr "type" "multi")
1384 (set_attr "unit" "i387")
1385 (set_attr "fp_int_src" "true")
1386 (set_attr "mode" "<MODE>")])
1388 (define_insn_and_split "*cmpfp_<mode>_cc"
1389 [(set (reg:CCFP FLAGS_REG)
1391 (match_operand 1 "register_operand" "f")
1392 (match_operator 3 "float_operator"
1393 [(match_operand:SWI24 2 "memory_operand" "m")])))
1394 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1395 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1396 && TARGET_SAHF && !TARGET_CMOVE
1397 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1398 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1400 "&& reload_completed"
1405 (match_op_dup 3 [(match_dup 2)]))]
1407 (set (reg:CC FLAGS_REG)
1408 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1410 [(set_attr "type" "multi")
1411 (set_attr "unit" "i387")
1412 (set_attr "fp_int_src" "true")
1413 (set_attr "mode" "<MODE>")])
1415 ;; FP compares, step 2
1416 ;; Move the fpsw to ax.
1418 (define_insn "x86_fnstsw_1"
1419 [(set (match_operand:HI 0 "register_operand" "=a")
1420 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1423 [(set (attr "length")
1424 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1425 (set_attr "mode" "SI")
1426 (set_attr "unit" "i387")])
1428 ;; FP compares, step 3
1429 ;; Get ax into flags, general case.
1431 (define_insn "x86_sahf_1"
1432 [(set (reg:CC FLAGS_REG)
1433 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1437 #ifndef HAVE_AS_IX86_SAHF
1439 return ASM_BYTE "0x9e";
1444 [(set_attr "length" "1")
1445 (set_attr "athlon_decode" "vector")
1446 (set_attr "amdfam10_decode" "direct")
1447 (set_attr "bdver1_decode" "direct")
1448 (set_attr "mode" "SI")])
1450 ;; Pentium Pro can do steps 1 through 3 in one go.
1451 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1452 ;; (these i387 instructions set flags directly)
1453 (define_insn "*cmpfp_i_mixed"
1454 [(set (reg:CCFP FLAGS_REG)
1455 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1456 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1457 "TARGET_MIX_SSE_I387
1458 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1459 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1460 "* return output_fp_compare (insn, operands, true, false);"
1461 [(set_attr "type" "fcmp,ssecomi")
1462 (set_attr "prefix" "orig,maybe_vex")
1464 (if_then_else (match_operand:SF 1 "" "")
1466 (const_string "DF")))
1467 (set (attr "prefix_rep")
1468 (if_then_else (eq_attr "type" "ssecomi")
1470 (const_string "*")))
1471 (set (attr "prefix_data16")
1472 (cond [(eq_attr "type" "fcmp")
1474 (eq_attr "mode" "DF")
1477 (const_string "0")))
1478 (set_attr "athlon_decode" "vector")
1479 (set_attr "amdfam10_decode" "direct")
1480 (set_attr "bdver1_decode" "double")])
1482 (define_insn "*cmpfp_i_sse"
1483 [(set (reg:CCFP FLAGS_REG)
1484 (compare:CCFP (match_operand 0 "register_operand" "x")
1485 (match_operand 1 "nonimmediate_operand" "xm")))]
1487 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1488 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1489 "* return output_fp_compare (insn, operands, true, false);"
1490 [(set_attr "type" "ssecomi")
1491 (set_attr "prefix" "maybe_vex")
1493 (if_then_else (match_operand:SF 1 "" "")
1495 (const_string "DF")))
1496 (set_attr "prefix_rep" "0")
1497 (set (attr "prefix_data16")
1498 (if_then_else (eq_attr "mode" "DF")
1500 (const_string "0")))
1501 (set_attr "athlon_decode" "vector")
1502 (set_attr "amdfam10_decode" "direct")
1503 (set_attr "bdver1_decode" "double")])
1505 (define_insn "*cmpfp_i_i387"
1506 [(set (reg:CCFP FLAGS_REG)
1507 (compare:CCFP (match_operand 0 "register_operand" "f")
1508 (match_operand 1 "register_operand" "f")))]
1509 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1511 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1512 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1513 "* return output_fp_compare (insn, operands, true, false);"
1514 [(set_attr "type" "fcmp")
1516 (cond [(match_operand:SF 1 "" "")
1518 (match_operand:DF 1 "" "")
1521 (const_string "XF")))
1522 (set_attr "athlon_decode" "vector")
1523 (set_attr "amdfam10_decode" "direct")
1524 (set_attr "bdver1_decode" "double")])
1526 (define_insn "*cmpfp_iu_mixed"
1527 [(set (reg:CCFPU FLAGS_REG)
1528 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1529 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1530 "TARGET_MIX_SSE_I387
1531 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1532 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1533 "* return output_fp_compare (insn, operands, true, true);"
1534 [(set_attr "type" "fcmp,ssecomi")
1535 (set_attr "prefix" "orig,maybe_vex")
1537 (if_then_else (match_operand:SF 1 "" "")
1539 (const_string "DF")))
1540 (set (attr "prefix_rep")
1541 (if_then_else (eq_attr "type" "ssecomi")
1543 (const_string "*")))
1544 (set (attr "prefix_data16")
1545 (cond [(eq_attr "type" "fcmp")
1547 (eq_attr "mode" "DF")
1550 (const_string "0")))
1551 (set_attr "athlon_decode" "vector")
1552 (set_attr "amdfam10_decode" "direct")
1553 (set_attr "bdver1_decode" "double")])
1555 (define_insn "*cmpfp_iu_sse"
1556 [(set (reg:CCFPU FLAGS_REG)
1557 (compare:CCFPU (match_operand 0 "register_operand" "x")
1558 (match_operand 1 "nonimmediate_operand" "xm")))]
1560 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1561 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1562 "* return output_fp_compare (insn, operands, true, true);"
1563 [(set_attr "type" "ssecomi")
1564 (set_attr "prefix" "maybe_vex")
1566 (if_then_else (match_operand:SF 1 "" "")
1568 (const_string "DF")))
1569 (set_attr "prefix_rep" "0")
1570 (set (attr "prefix_data16")
1571 (if_then_else (eq_attr "mode" "DF")
1573 (const_string "0")))
1574 (set_attr "athlon_decode" "vector")
1575 (set_attr "amdfam10_decode" "direct")
1576 (set_attr "bdver1_decode" "double")])
1578 (define_insn "*cmpfp_iu_387"
1579 [(set (reg:CCFPU FLAGS_REG)
1580 (compare:CCFPU (match_operand 0 "register_operand" "f")
1581 (match_operand 1 "register_operand" "f")))]
1582 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1584 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1585 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1586 "* return output_fp_compare (insn, operands, true, true);"
1587 [(set_attr "type" "fcmp")
1589 (cond [(match_operand:SF 1 "" "")
1591 (match_operand:DF 1 "" "")
1594 (const_string "XF")))
1595 (set_attr "athlon_decode" "vector")
1596 (set_attr "amdfam10_decode" "direct")
1597 (set_attr "bdver1_decode" "direct")])
1599 ;; Push/pop instructions.
1601 (define_insn "*push<mode>2"
1602 [(set (match_operand:DWI 0 "push_operand" "=<")
1603 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1606 [(set_attr "type" "multi")
1607 (set_attr "mode" "<MODE>")])
1610 [(set (match_operand:TI 0 "push_operand" "")
1611 (match_operand:TI 1 "general_operand" ""))]
1612 "TARGET_64BIT && reload_completed
1613 && !SSE_REG_P (operands[1])"
1615 "ix86_split_long_move (operands); DONE;")
1617 (define_insn "*pushdi2_rex64"
1618 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1619 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1624 [(set_attr "type" "push,multi")
1625 (set_attr "mode" "DI")])
1627 ;; Convert impossible pushes of immediate to existing instructions.
1628 ;; First try to get scratch register and go through it. In case this
1629 ;; fails, push sign extended lower part first and then overwrite
1630 ;; upper part by 32bit move.
1632 [(match_scratch:DI 2 "r")
1633 (set (match_operand:DI 0 "push_operand" "")
1634 (match_operand:DI 1 "immediate_operand" ""))]
1635 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1636 && !x86_64_immediate_operand (operands[1], DImode)"
1637 [(set (match_dup 2) (match_dup 1))
1638 (set (match_dup 0) (match_dup 2))])
1640 ;; We need to define this as both peepholer and splitter for case
1641 ;; peephole2 pass is not run.
1642 ;; "&& 1" is needed to keep it from matching the previous pattern.
1644 [(set (match_operand:DI 0 "push_operand" "")
1645 (match_operand:DI 1 "immediate_operand" ""))]
1646 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1647 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1648 [(set (match_dup 0) (match_dup 1))
1649 (set (match_dup 2) (match_dup 3))]
1651 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1653 operands[1] = gen_lowpart (DImode, operands[2]);
1654 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1659 [(set (match_operand:DI 0 "push_operand" "")
1660 (match_operand:DI 1 "immediate_operand" ""))]
1661 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1662 ? epilogue_completed : reload_completed)
1663 && !symbolic_operand (operands[1], DImode)
1664 && !x86_64_immediate_operand (operands[1], DImode)"
1665 [(set (match_dup 0) (match_dup 1))
1666 (set (match_dup 2) (match_dup 3))]
1668 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1670 operands[1] = gen_lowpart (DImode, operands[2]);
1671 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1676 [(set (match_operand:DI 0 "push_operand" "")
1677 (match_operand:DI 1 "general_operand" ""))]
1678 "!TARGET_64BIT && reload_completed
1679 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1681 "ix86_split_long_move (operands); DONE;")
1683 (define_insn "*pushsi2"
1684 [(set (match_operand:SI 0 "push_operand" "=<")
1685 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1688 [(set_attr "type" "push")
1689 (set_attr "mode" "SI")])
1691 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1692 ;; "push a byte/word". But actually we use pushl, which has the effect
1693 ;; of rounding the amount pushed up to a word.
1695 ;; For TARGET_64BIT we always round up to 8 bytes.
1696 (define_insn "*push<mode>2_rex64"
1697 [(set (match_operand:SWI124 0 "push_operand" "=X")
1698 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1701 [(set_attr "type" "push")
1702 (set_attr "mode" "DI")])
1704 (define_insn "*push<mode>2"
1705 [(set (match_operand:SWI12 0 "push_operand" "=X")
1706 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1709 [(set_attr "type" "push")
1710 (set_attr "mode" "SI")])
1712 (define_insn "*push<mode>2_prologue"
1713 [(set (match_operand:W 0 "push_operand" "=<")
1714 (match_operand:W 1 "general_no_elim_operand" "r<i>*m"))
1715 (clobber (mem:BLK (scratch)))]
1717 "push{<imodesuffix>}\t%1"
1718 [(set_attr "type" "push")
1719 (set_attr "mode" "<MODE>")])
1721 (define_insn "*pop<mode>1"
1722 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1723 (match_operand:W 1 "pop_operand" ">"))]
1725 "pop{<imodesuffix>}\t%0"
1726 [(set_attr "type" "pop")
1727 (set_attr "mode" "<MODE>")])
1729 (define_insn "*pop<mode>1_epilogue"
1730 [(set (match_operand:W 0 "nonimmediate_operand" "=r*m")
1731 (match_operand:W 1 "pop_operand" ">"))
1732 (clobber (mem:BLK (scratch)))]
1734 "pop{<imodesuffix>}\t%0"
1735 [(set_attr "type" "pop")
1736 (set_attr "mode" "<MODE>")])
1738 ;; Move instructions.
1740 (define_expand "movoi"
1741 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1742 (match_operand:OI 1 "general_operand" ""))]
1744 "ix86_expand_move (OImode, operands); DONE;")
1746 (define_expand "movti"
1747 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1748 (match_operand:TI 1 "nonimmediate_operand" ""))]
1749 "TARGET_64BIT || TARGET_SSE"
1752 ix86_expand_move (TImode, operands);
1753 else if (push_operand (operands[0], TImode))
1754 ix86_expand_push (TImode, operands[1]);
1756 ix86_expand_vector_move (TImode, operands);
1760 ;; This expands to what emit_move_complex would generate if we didn't
1761 ;; have a movti pattern. Having this avoids problems with reload on
1762 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1763 ;; to have around all the time.
1764 (define_expand "movcdi"
1765 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1766 (match_operand:CDI 1 "general_operand" ""))]
1769 if (push_operand (operands[0], CDImode))
1770 emit_move_complex_push (CDImode, operands[0], operands[1]);
1772 emit_move_complex_parts (operands[0], operands[1]);
1776 (define_expand "mov<mode>"
1777 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1778 (match_operand:SWI1248x 1 "general_operand" ""))]
1780 "ix86_expand_move (<MODE>mode, operands); DONE;")
1782 (define_insn "*mov<mode>_xor"
1783 [(set (match_operand:SWI48 0 "register_operand" "=r")
1784 (match_operand:SWI48 1 "const0_operand" ""))
1785 (clobber (reg:CC FLAGS_REG))]
1788 [(set_attr "type" "alu1")
1789 (set_attr "mode" "SI")
1790 (set_attr "length_immediate" "0")])
1792 (define_insn "*mov<mode>_or"
1793 [(set (match_operand:SWI48 0 "register_operand" "=r")
1794 (match_operand:SWI48 1 "const_int_operand" ""))
1795 (clobber (reg:CC FLAGS_REG))]
1797 && operands[1] == constm1_rtx"
1798 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1799 [(set_attr "type" "alu1")
1800 (set_attr "mode" "<MODE>")
1801 (set_attr "length_immediate" "1")])
1803 (define_insn "*movoi_internal_avx"
1804 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1805 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1806 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1808 switch (which_alternative)
1811 return standard_sse_constant_opcode (insn, operands[1]);
1814 if (misaligned_operand (operands[0], OImode)
1815 || misaligned_operand (operands[1], OImode))
1816 return "vmovdqu\t{%1, %0|%0, %1}";
1818 return "vmovdqa\t{%1, %0|%0, %1}";
1823 [(set_attr "type" "sselog1,ssemov,ssemov")
1824 (set_attr "prefix" "vex")
1825 (set_attr "mode" "OI")])
1827 (define_insn "*movti_internal_rex64"
1828 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1829 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1830 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1832 switch (which_alternative)
1838 return standard_sse_constant_opcode (insn, operands[1]);
1841 /* TDmode values are passed as TImode on the stack. Moving them
1842 to stack may result in unaligned memory access. */
1843 if (misaligned_operand (operands[0], TImode)
1844 || misaligned_operand (operands[1], TImode))
1846 if (get_attr_mode (insn) == MODE_V4SF)
1847 return "%vmovups\t{%1, %0|%0, %1}";
1849 return "%vmovdqu\t{%1, %0|%0, %1}";
1853 if (get_attr_mode (insn) == MODE_V4SF)
1854 return "%vmovaps\t{%1, %0|%0, %1}";
1856 return "%vmovdqa\t{%1, %0|%0, %1}";
1862 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1863 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1865 (cond [(eq_attr "alternative" "2,3")
1867 (match_test "optimize_function_for_size_p (cfun)")
1868 (const_string "V4SF")
1869 (const_string "TI"))
1870 (eq_attr "alternative" "4")
1872 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1873 (match_test "optimize_function_for_size_p (cfun)"))
1874 (const_string "V4SF")
1875 (const_string "TI"))]
1876 (const_string "DI")))])
1879 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1880 (match_operand:TI 1 "general_operand" ""))]
1882 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1884 "ix86_split_long_move (operands); DONE;")
1886 (define_insn "*movti_internal_sse"
1887 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1888 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1889 "TARGET_SSE && !TARGET_64BIT
1890 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1892 switch (which_alternative)
1895 return standard_sse_constant_opcode (insn, operands[1]);
1898 /* TDmode values are passed as TImode on the stack. Moving them
1899 to stack may result in unaligned memory access. */
1900 if (misaligned_operand (operands[0], TImode)
1901 || misaligned_operand (operands[1], TImode))
1903 if (get_attr_mode (insn) == MODE_V4SF)
1904 return "%vmovups\t{%1, %0|%0, %1}";
1906 return "%vmovdqu\t{%1, %0|%0, %1}";
1910 if (get_attr_mode (insn) == MODE_V4SF)
1911 return "%vmovaps\t{%1, %0|%0, %1}";
1913 return "%vmovdqa\t{%1, %0|%0, %1}";
1919 [(set_attr "type" "sselog1,ssemov,ssemov")
1920 (set_attr "prefix" "maybe_vex")
1922 (cond [(ior (not (match_test "TARGET_SSE2"))
1923 (match_test "optimize_function_for_size_p (cfun)"))
1924 (const_string "V4SF")
1925 (and (eq_attr "alternative" "2")
1926 (match_test "TARGET_SSE_TYPELESS_STORES"))
1927 (const_string "V4SF")]
1928 (const_string "TI")))])
1930 (define_insn "*movdi_internal_rex64"
1931 [(set (match_operand:DI 0 "nonimmediate_operand"
1932 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1933 (match_operand:DI 1 "general_operand"
1934 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1935 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1937 switch (get_attr_type (insn))
1940 if (SSE_REG_P (operands[0]))
1941 return "movq2dq\t{%1, %0|%0, %1}";
1943 return "movdq2q\t{%1, %0|%0, %1}";
1946 if (get_attr_mode (insn) == MODE_TI)
1947 return "%vmovdqa\t{%1, %0|%0, %1}";
1948 /* Handle broken assemblers that require movd instead of movq. */
1949 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1950 return "%vmovd\t{%1, %0|%0, %1}";
1952 return "%vmovq\t{%1, %0|%0, %1}";
1955 /* Handle broken assemblers that require movd instead of movq. */
1956 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1957 return "movd\t{%1, %0|%0, %1}";
1959 return "movq\t{%1, %0|%0, %1}";
1962 return standard_sse_constant_opcode (insn, operands[1]);
1965 return "pxor\t%0, %0";
1971 return "lea{q}\t{%E1, %0|%0, %E1}";
1974 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1975 if (get_attr_mode (insn) == MODE_SI)
1976 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1977 else if (which_alternative == 2)
1978 return "movabs{q}\t{%1, %0|%0, %1}";
1979 else if (ix86_use_lea_for_mov (insn, operands))
1980 return "lea{q}\t{%E1, %0|%0, %E1}";
1982 return "mov{q}\t{%1, %0|%0, %1}";
1986 (cond [(eq_attr "alternative" "4")
1987 (const_string "multi")
1988 (eq_attr "alternative" "5")
1989 (const_string "mmx")
1990 (eq_attr "alternative" "6,7,8,9")
1991 (const_string "mmxmov")
1992 (eq_attr "alternative" "10")
1993 (const_string "sselog1")
1994 (eq_attr "alternative" "11,12,13,14,15")
1995 (const_string "ssemov")
1996 (eq_attr "alternative" "16,17")
1997 (const_string "ssecvt")
1998 (match_operand 1 "pic_32bit_operand" "")
1999 (const_string "lea")
2001 (const_string "imov")))
2004 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2006 (const_string "*")))
2007 (set (attr "length_immediate")
2009 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2011 (const_string "*")))
2012 (set (attr "prefix_rex")
2013 (if_then_else (eq_attr "alternative" "8,9")
2015 (const_string "*")))
2016 (set (attr "prefix_data16")
2017 (if_then_else (eq_attr "alternative" "11")
2019 (const_string "*")))
2020 (set (attr "prefix")
2021 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2022 (const_string "maybe_vex")
2023 (const_string "orig")))
2024 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2026 ;; Reload patterns to support multi-word load/store
2027 ;; with non-offsetable address.
2028 (define_expand "reload_noff_store"
2029 [(parallel [(match_operand 0 "memory_operand" "=m")
2030 (match_operand 1 "register_operand" "r")
2031 (match_operand:DI 2 "register_operand" "=&r")])]
2034 rtx mem = operands[0];
2035 rtx addr = XEXP (mem, 0);
2037 emit_move_insn (operands[2], addr);
2038 mem = replace_equiv_address_nv (mem, operands[2]);
2040 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2044 (define_expand "reload_noff_load"
2045 [(parallel [(match_operand 0 "register_operand" "=r")
2046 (match_operand 1 "memory_operand" "m")
2047 (match_operand:DI 2 "register_operand" "=r")])]
2050 rtx mem = operands[1];
2051 rtx addr = XEXP (mem, 0);
2053 emit_move_insn (operands[2], addr);
2054 mem = replace_equiv_address_nv (mem, operands[2]);
2056 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2060 ;; Convert impossible stores of immediate to existing instructions.
2061 ;; First try to get scratch register and go through it. In case this
2062 ;; fails, move by 32bit parts.
2064 [(match_scratch:DI 2 "r")
2065 (set (match_operand:DI 0 "memory_operand" "")
2066 (match_operand:DI 1 "immediate_operand" ""))]
2067 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2068 && !x86_64_immediate_operand (operands[1], DImode)"
2069 [(set (match_dup 2) (match_dup 1))
2070 (set (match_dup 0) (match_dup 2))])
2072 ;; We need to define this as both peepholer and splitter for case
2073 ;; peephole2 pass is not run.
2074 ;; "&& 1" is needed to keep it from matching the previous pattern.
2076 [(set (match_operand:DI 0 "memory_operand" "")
2077 (match_operand:DI 1 "immediate_operand" ""))]
2078 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2079 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2080 [(set (match_dup 2) (match_dup 3))
2081 (set (match_dup 4) (match_dup 5))]
2082 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2085 [(set (match_operand:DI 0 "memory_operand" "")
2086 (match_operand:DI 1 "immediate_operand" ""))]
2087 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2088 ? epilogue_completed : reload_completed)
2089 && !symbolic_operand (operands[1], DImode)
2090 && !x86_64_immediate_operand (operands[1], DImode)"
2091 [(set (match_dup 2) (match_dup 3))
2092 (set (match_dup 4) (match_dup 5))]
2093 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2095 (define_insn "*movdi_internal"
2096 [(set (match_operand:DI 0 "nonimmediate_operand"
2097 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2098 (match_operand:DI 1 "general_operand"
2099 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2100 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2102 switch (get_attr_type (insn))
2105 if (SSE_REG_P (operands[0]))
2106 return "movq2dq\t{%1, %0|%0, %1}";
2108 return "movdq2q\t{%1, %0|%0, %1}";
2111 switch (get_attr_mode (insn))
2114 return "%vmovdqa\t{%1, %0|%0, %1}";
2116 return "%vmovq\t{%1, %0|%0, %1}";
2118 return "movaps\t{%1, %0|%0, %1}";
2120 return "movlps\t{%1, %0|%0, %1}";
2126 return "movq\t{%1, %0|%0, %1}";
2129 return standard_sse_constant_opcode (insn, operands[1]);
2132 return "pxor\t%0, %0";
2142 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2143 (const_string "sse2")
2144 (eq_attr "alternative" "9,10,11,12")
2145 (const_string "noavx")
2147 (const_string "*")))
2149 (cond [(eq_attr "alternative" "0,1")
2150 (const_string "multi")
2151 (eq_attr "alternative" "2")
2152 (const_string "mmx")
2153 (eq_attr "alternative" "3,4")
2154 (const_string "mmxmov")
2155 (eq_attr "alternative" "5,9")
2156 (const_string "sselog1")
2157 (eq_attr "alternative" "13,14")
2158 (const_string "ssecvt")
2160 (const_string "ssemov")))
2161 (set (attr "prefix")
2162 (if_then_else (eq_attr "alternative" "5,6,7,8")
2163 (const_string "maybe_vex")
2164 (const_string "orig")))
2165 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2168 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2169 (match_operand:DI 1 "general_operand" ""))]
2170 "!TARGET_64BIT && reload_completed
2171 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2172 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2174 "ix86_split_long_move (operands); DONE;")
2176 (define_insn "*movsi_internal"
2177 [(set (match_operand:SI 0 "nonimmediate_operand"
2178 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2179 (match_operand:SI 1 "general_operand"
2180 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2181 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2183 switch (get_attr_type (insn))
2186 return standard_sse_constant_opcode (insn, operands[1]);
2189 switch (get_attr_mode (insn))
2192 return "%vmovdqa\t{%1, %0|%0, %1}";
2194 return "%vmovaps\t{%1, %0|%0, %1}";
2196 return "%vmovd\t{%1, %0|%0, %1}";
2198 return "%vmovss\t{%1, %0|%0, %1}";
2204 return "pxor\t%0, %0";
2207 if (get_attr_mode (insn) == MODE_DI)
2208 return "movq\t{%1, %0|%0, %1}";
2209 return "movd\t{%1, %0|%0, %1}";
2212 return "lea{l}\t{%E1, %0|%0, %E1}";
2215 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2216 if (ix86_use_lea_for_mov (insn, operands))
2217 return "lea{l}\t{%E1, %0|%0, %E1}";
2219 return "mov{l}\t{%1, %0|%0, %1}";
2223 (cond [(eq_attr "alternative" "2")
2224 (const_string "mmx")
2225 (eq_attr "alternative" "3,4,5")
2226 (const_string "mmxmov")
2227 (eq_attr "alternative" "6")
2228 (const_string "sselog1")
2229 (eq_attr "alternative" "7,8,9,10,11")
2230 (const_string "ssemov")
2231 (match_operand 1 "pic_32bit_operand" "")
2232 (const_string "lea")
2234 (const_string "imov")))
2235 (set (attr "prefix")
2236 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2237 (const_string "orig")
2238 (const_string "maybe_vex")))
2239 (set (attr "prefix_data16")
2240 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2242 (const_string "*")))
2244 (cond [(eq_attr "alternative" "2,3")
2246 (eq_attr "alternative" "6,7")
2248 (not (match_test "TARGET_SSE2"))
2249 (const_string "V4SF")
2250 (const_string "TI"))
2251 (and (eq_attr "alternative" "8,9,10,11")
2252 (not (match_test "TARGET_SSE2")))
2255 (const_string "SI")))])
2257 (define_insn "*movhi_internal"
2258 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2259 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2260 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2262 switch (get_attr_type (insn))
2265 /* movzwl is faster than movw on p2 due to partial word stalls,
2266 though not as fast as an aligned movl. */
2267 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2269 if (get_attr_mode (insn) == MODE_SI)
2270 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2272 return "mov{w}\t{%1, %0|%0, %1}";
2276 (cond [(match_test "optimize_function_for_size_p (cfun)")
2277 (const_string "imov")
2278 (and (eq_attr "alternative" "0")
2279 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2280 (not (match_test "TARGET_HIMODE_MATH"))))
2281 (const_string "imov")
2282 (and (eq_attr "alternative" "1,2")
2283 (match_operand:HI 1 "aligned_operand" ""))
2284 (const_string "imov")
2285 (and (match_test "TARGET_MOVX")
2286 (eq_attr "alternative" "0,2"))
2287 (const_string "imovx")
2289 (const_string "imov")))
2291 (cond [(eq_attr "type" "imovx")
2293 (and (eq_attr "alternative" "1,2")
2294 (match_operand:HI 1 "aligned_operand" ""))
2296 (and (eq_attr "alternative" "0")
2297 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2298 (not (match_test "TARGET_HIMODE_MATH"))))
2301 (const_string "HI")))])
2303 ;; Situation is quite tricky about when to choose full sized (SImode) move
2304 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2305 ;; partial register dependency machines (such as AMD Athlon), where QImode
2306 ;; moves issue extra dependency and for partial register stalls machines
2307 ;; that don't use QImode patterns (and QImode move cause stall on the next
2310 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2311 ;; register stall machines with, where we use QImode instructions, since
2312 ;; partial register stall can be caused there. Then we use movzx.
2313 (define_insn "*movqi_internal"
2314 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2315 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2316 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2318 switch (get_attr_type (insn))
2321 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2322 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2324 if (get_attr_mode (insn) == MODE_SI)
2325 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2327 return "mov{b}\t{%1, %0|%0, %1}";
2331 (cond [(and (eq_attr "alternative" "5")
2332 (not (match_operand:QI 1 "aligned_operand" "")))
2333 (const_string "imovx")
2334 (match_test "optimize_function_for_size_p (cfun)")
2335 (const_string "imov")
2336 (and (eq_attr "alternative" "3")
2337 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2338 (not (match_test "TARGET_QIMODE_MATH"))))
2339 (const_string "imov")
2340 (eq_attr "alternative" "3,5")
2341 (const_string "imovx")
2342 (and (match_test "TARGET_MOVX")
2343 (eq_attr "alternative" "2"))
2344 (const_string "imovx")
2346 (const_string "imov")))
2348 (cond [(eq_attr "alternative" "3,4,5")
2350 (eq_attr "alternative" "6")
2352 (eq_attr "type" "imovx")
2354 (and (eq_attr "type" "imov")
2355 (and (eq_attr "alternative" "0,1")
2356 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2357 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2358 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2360 ;; Avoid partial register stalls when not using QImode arithmetic
2361 (and (eq_attr "type" "imov")
2362 (and (eq_attr "alternative" "0,1")
2363 (and (match_test "TARGET_PARTIAL_REG_STALL")
2364 (not (match_test "TARGET_QIMODE_MATH")))))
2367 (const_string "QI")))])
2369 ;; Stores and loads of ax to arbitrary constant address.
2370 ;; We fake an second form of instruction to force reload to load address
2371 ;; into register when rax is not available
2372 (define_insn "*movabs<mode>_1"
2373 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2374 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2375 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2377 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2378 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2379 [(set_attr "type" "imov")
2380 (set_attr "modrm" "0,*")
2381 (set_attr "length_address" "8,0")
2382 (set_attr "length_immediate" "0,*")
2383 (set_attr "memory" "store")
2384 (set_attr "mode" "<MODE>")])
2386 (define_insn "*movabs<mode>_2"
2387 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2388 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2389 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2391 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2392 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2393 [(set_attr "type" "imov")
2394 (set_attr "modrm" "0,*")
2395 (set_attr "length_address" "8,0")
2396 (set_attr "length_immediate" "0")
2397 (set_attr "memory" "load")
2398 (set_attr "mode" "<MODE>")])
2400 (define_insn "*swap<mode>"
2401 [(set (match_operand:SWI48 0 "register_operand" "+r")
2402 (match_operand:SWI48 1 "register_operand" "+r"))
2406 "xchg{<imodesuffix>}\t%1, %0"
2407 [(set_attr "type" "imov")
2408 (set_attr "mode" "<MODE>")
2409 (set_attr "pent_pair" "np")
2410 (set_attr "athlon_decode" "vector")
2411 (set_attr "amdfam10_decode" "double")
2412 (set_attr "bdver1_decode" "double")])
2414 (define_insn "*swap<mode>_1"
2415 [(set (match_operand:SWI12 0 "register_operand" "+r")
2416 (match_operand:SWI12 1 "register_operand" "+r"))
2419 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2421 [(set_attr "type" "imov")
2422 (set_attr "mode" "SI")
2423 (set_attr "pent_pair" "np")
2424 (set_attr "athlon_decode" "vector")
2425 (set_attr "amdfam10_decode" "double")
2426 (set_attr "bdver1_decode" "double")])
2428 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2429 ;; is disabled for AMDFAM10
2430 (define_insn "*swap<mode>_2"
2431 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2432 (match_operand:SWI12 1 "register_operand" "+<r>"))
2435 "TARGET_PARTIAL_REG_STALL"
2436 "xchg{<imodesuffix>}\t%1, %0"
2437 [(set_attr "type" "imov")
2438 (set_attr "mode" "<MODE>")
2439 (set_attr "pent_pair" "np")
2440 (set_attr "athlon_decode" "vector")])
2442 (define_expand "movstrict<mode>"
2443 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2444 (match_operand:SWI12 1 "general_operand" ""))]
2447 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2449 if (GET_CODE (operands[0]) == SUBREG
2450 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2452 /* Don't generate memory->memory moves, go through a register */
2453 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2454 operands[1] = force_reg (<MODE>mode, operands[1]);
2457 (define_insn "*movstrict<mode>_1"
2458 [(set (strict_low_part
2459 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2460 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2461 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2462 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2463 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2464 [(set_attr "type" "imov")
2465 (set_attr "mode" "<MODE>")])
2467 (define_insn "*movstrict<mode>_xor"
2468 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2469 (match_operand:SWI12 1 "const0_operand" ""))
2470 (clobber (reg:CC FLAGS_REG))]
2472 "xor{<imodesuffix>}\t%0, %0"
2473 [(set_attr "type" "alu1")
2474 (set_attr "mode" "<MODE>")
2475 (set_attr "length_immediate" "0")])
2477 (define_insn "*mov<mode>_extv_1"
2478 [(set (match_operand:SWI24 0 "register_operand" "=R")
2479 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2483 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2484 [(set_attr "type" "imovx")
2485 (set_attr "mode" "SI")])
2487 (define_insn "*movqi_extv_1_rex64"
2488 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2489 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2494 switch (get_attr_type (insn))
2497 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2499 return "mov{b}\t{%h1, %0|%0, %h1}";
2503 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2504 (match_test "TARGET_MOVX"))
2505 (const_string "imovx")
2506 (const_string "imov")))
2508 (if_then_else (eq_attr "type" "imovx")
2510 (const_string "QI")))])
2512 (define_insn "*movqi_extv_1"
2513 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2514 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2519 switch (get_attr_type (insn))
2522 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2524 return "mov{b}\t{%h1, %0|%0, %h1}";
2528 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2529 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2530 (match_test "TARGET_MOVX")))
2531 (const_string "imovx")
2532 (const_string "imov")))
2534 (if_then_else (eq_attr "type" "imovx")
2536 (const_string "QI")))])
2538 (define_insn "*mov<mode>_extzv_1"
2539 [(set (match_operand:SWI48 0 "register_operand" "=R")
2540 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2544 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2545 [(set_attr "type" "imovx")
2546 (set_attr "mode" "SI")])
2548 (define_insn "*movqi_extzv_2_rex64"
2549 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2551 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2556 switch (get_attr_type (insn))
2559 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2561 return "mov{b}\t{%h1, %0|%0, %h1}";
2565 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2566 (match_test "TARGET_MOVX"))
2567 (const_string "imovx")
2568 (const_string "imov")))
2570 (if_then_else (eq_attr "type" "imovx")
2572 (const_string "QI")))])
2574 (define_insn "*movqi_extzv_2"
2575 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2577 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2582 switch (get_attr_type (insn))
2585 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2587 return "mov{b}\t{%h1, %0|%0, %h1}";
2591 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2592 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2593 (match_test "TARGET_MOVX")))
2594 (const_string "imovx")
2595 (const_string "imov")))
2597 (if_then_else (eq_attr "type" "imovx")
2599 (const_string "QI")))])
2601 (define_expand "mov<mode>_insv_1"
2602 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2605 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2607 (define_insn "*mov<mode>_insv_1_rex64"
2608 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2611 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2613 "mov{b}\t{%b1, %h0|%h0, %b1}"
2614 [(set_attr "type" "imov")
2615 (set_attr "mode" "QI")])
2617 (define_insn "*movsi_insv_1"
2618 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2621 (match_operand:SI 1 "general_operand" "Qmn"))]
2623 "mov{b}\t{%b1, %h0|%h0, %b1}"
2624 [(set_attr "type" "imov")
2625 (set_attr "mode" "QI")])
2627 (define_insn "*movqi_insv_2"
2628 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2631 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2634 "mov{b}\t{%h1, %h0|%h0, %h1}"
2635 [(set_attr "type" "imov")
2636 (set_attr "mode" "QI")])
2638 ;; Floating point push instructions.
2640 (define_insn "*pushtf"
2641 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2642 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2645 /* This insn should be already split before reg-stack. */
2648 [(set_attr "type" "multi")
2649 (set_attr "unit" "sse,*,*")
2650 (set_attr "mode" "TF,SI,SI")])
2652 ;; %%% Kill this when call knows how to work this out.
2654 [(set (match_operand:TF 0 "push_operand" "")
2655 (match_operand:TF 1 "sse_reg_operand" ""))]
2656 "TARGET_SSE2 && reload_completed"
2657 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2658 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2660 (define_insn "*pushxf"
2661 [(set (match_operand:XF 0 "push_operand" "=<,<")
2662 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2663 "optimize_function_for_speed_p (cfun)"
2665 /* This insn should be already split before reg-stack. */
2668 [(set_attr "type" "multi")
2669 (set_attr "unit" "i387,*")
2670 (set_attr "mode" "XF,SI")])
2672 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2673 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2674 ;; Pushing using integer instructions is longer except for constants
2675 ;; and direct memory references (assuming that any given constant is pushed
2676 ;; only once, but this ought to be handled elsewhere).
2678 (define_insn "*pushxf_nointeger"
2679 [(set (match_operand:XF 0 "push_operand" "=<,<")
2680 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2681 "optimize_function_for_size_p (cfun)"
2683 /* This insn should be already split before reg-stack. */
2686 [(set_attr "type" "multi")
2687 (set_attr "unit" "i387,*")
2688 (set_attr "mode" "XF,SI")])
2690 ;; %%% Kill this when call knows how to work this out.
2692 [(set (match_operand:XF 0 "push_operand" "")
2693 (match_operand:XF 1 "fp_register_operand" ""))]
2695 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2696 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2697 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2699 (define_insn "*pushdf_rex64"
2700 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2701 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2704 /* This insn should be already split before reg-stack. */
2707 [(set_attr "type" "multi")
2708 (set_attr "unit" "i387,*,*")
2709 (set_attr "mode" "DF,DI,DF")])
2711 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2712 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2713 ;; On the average, pushdf using integers can be still shorter.
2715 (define_insn "*pushdf"
2716 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2717 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2720 /* This insn should be already split before reg-stack. */
2723 [(set_attr "isa" "*,*,sse2")
2724 (set_attr "type" "multi")
2725 (set_attr "unit" "i387,*,*")
2726 (set_attr "mode" "DF,DI,DF")])
2728 ;; %%% Kill this when call knows how to work this out.
2730 [(set (match_operand:DF 0 "push_operand" "")
2731 (match_operand:DF 1 "any_fp_register_operand" ""))]
2733 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2734 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2736 (define_insn "*pushsf_rex64"
2737 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2738 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2741 /* Anything else should be already split before reg-stack. */
2742 gcc_assert (which_alternative == 1);
2743 return "push{q}\t%q1";
2745 [(set_attr "type" "multi,push,multi")
2746 (set_attr "unit" "i387,*,*")
2747 (set_attr "mode" "SF,DI,SF")])
2749 (define_insn "*pushsf"
2750 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2751 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2754 /* Anything else should be already split before reg-stack. */
2755 gcc_assert (which_alternative == 1);
2756 return "push{l}\t%1";
2758 [(set_attr "type" "multi,push,multi")
2759 (set_attr "unit" "i387,*,*")
2760 (set_attr "mode" "SF,SI,SF")])
2762 ;; %%% Kill this when call knows how to work this out.
2764 [(set (match_operand:SF 0 "push_operand" "")
2765 (match_operand:SF 1 "any_fp_register_operand" ""))]
2767 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2768 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2769 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2772 [(set (match_operand:SF 0 "push_operand" "")
2773 (match_operand:SF 1 "memory_operand" ""))]
2775 && (operands[2] = find_constant_src (insn))"
2776 [(set (match_dup 0) (match_dup 2))])
2779 [(set (match_operand 0 "push_operand" "")
2780 (match_operand 1 "general_operand" ""))]
2782 && (GET_MODE (operands[0]) == TFmode
2783 || GET_MODE (operands[0]) == XFmode
2784 || GET_MODE (operands[0]) == DFmode)
2785 && !ANY_FP_REG_P (operands[1])"
2787 "ix86_split_long_move (operands); DONE;")
2789 ;; Floating point move instructions.
2791 (define_expand "movtf"
2792 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2793 (match_operand:TF 1 "nonimmediate_operand" ""))]
2796 ix86_expand_move (TFmode, operands);
2800 (define_expand "mov<mode>"
2801 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2802 (match_operand:X87MODEF 1 "general_operand" ""))]
2804 "ix86_expand_move (<MODE>mode, operands); DONE;")
2806 (define_insn "*movtf_internal"
2807 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2808 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2810 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2811 && (!can_create_pseudo_p ()
2812 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2813 || GET_CODE (operands[1]) != CONST_DOUBLE
2814 || (optimize_function_for_size_p (cfun)
2815 && standard_sse_constant_p (operands[1])
2816 && !memory_operand (operands[0], TFmode))
2817 || (!TARGET_MEMORY_MISMATCH_STALL
2818 && memory_operand (operands[0], TFmode)))"
2820 switch (which_alternative)
2824 /* Handle misaligned load/store since we
2825 don't have movmisaligntf pattern. */
2826 if (misaligned_operand (operands[0], TFmode)
2827 || misaligned_operand (operands[1], TFmode))
2829 if (get_attr_mode (insn) == MODE_V4SF)
2830 return "%vmovups\t{%1, %0|%0, %1}";
2832 return "%vmovdqu\t{%1, %0|%0, %1}";
2836 if (get_attr_mode (insn) == MODE_V4SF)
2837 return "%vmovaps\t{%1, %0|%0, %1}";
2839 return "%vmovdqa\t{%1, %0|%0, %1}";
2843 return standard_sse_constant_opcode (insn, operands[1]);
2853 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2854 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2856 (cond [(eq_attr "alternative" "0,2")
2858 (match_test "optimize_function_for_size_p (cfun)")
2859 (const_string "V4SF")
2860 (const_string "TI"))
2861 (eq_attr "alternative" "1")
2863 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2864 (match_test "optimize_function_for_size_p (cfun)"))
2865 (const_string "V4SF")
2866 (const_string "TI"))]
2867 (const_string "DI")))])
2869 ;; Possible store forwarding (partial memory) stall in alternative 4.
2870 (define_insn "*movxf_internal"
2871 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2872 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2873 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2874 && (!can_create_pseudo_p ()
2875 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2876 || GET_CODE (operands[1]) != CONST_DOUBLE
2877 || (optimize_function_for_size_p (cfun)
2878 && standard_80387_constant_p (operands[1]) > 0
2879 && !memory_operand (operands[0], XFmode))
2880 || (!TARGET_MEMORY_MISMATCH_STALL
2881 && memory_operand (operands[0], XFmode)))"
2883 switch (which_alternative)
2887 return output_387_reg_move (insn, operands);
2890 return standard_80387_constant_opcode (operands[1]);
2900 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2901 (set_attr "mode" "XF,XF,XF,SI,SI")])
2903 (define_insn "*movdf_internal_rex64"
2904 [(set (match_operand:DF 0 "nonimmediate_operand"
2905 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2906 (match_operand:DF 1 "general_operand"
2907 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2908 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2909 && (!can_create_pseudo_p ()
2910 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2911 || GET_CODE (operands[1]) != CONST_DOUBLE
2912 || (optimize_function_for_size_p (cfun)
2913 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2914 && standard_80387_constant_p (operands[1]) > 0)
2915 || (TARGET_SSE2 && TARGET_SSE_MATH
2916 && standard_sse_constant_p (operands[1]))))
2917 || memory_operand (operands[0], DFmode))"
2919 switch (which_alternative)
2923 return output_387_reg_move (insn, operands);
2926 return standard_80387_constant_opcode (operands[1]);
2930 return "mov{q}\t{%1, %0|%0, %1}";
2933 return "movabs{q}\t{%1, %0|%0, %1}";
2939 return standard_sse_constant_opcode (insn, operands[1]);
2944 switch (get_attr_mode (insn))
2947 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2948 return "%vmovapd\t{%1, %0|%0, %1}";
2950 return "%vmovaps\t{%1, %0|%0, %1}";
2953 return "%vmovq\t{%1, %0|%0, %1}";
2955 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2956 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2957 return "%vmovsd\t{%1, %0|%0, %1}";
2959 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2961 return "%vmovlps\t{%1, %d0|%d0, %1}";
2968 /* Handle broken assemblers that require movd instead of movq. */
2969 return "%vmovd\t{%1, %0|%0, %1}";
2976 (cond [(eq_attr "alternative" "0,1,2")
2977 (const_string "fmov")
2978 (eq_attr "alternative" "3,4,5")
2979 (const_string "imov")
2980 (eq_attr "alternative" "6")
2981 (const_string "multi")
2982 (eq_attr "alternative" "7")
2983 (const_string "sselog1")
2985 (const_string "ssemov")))
2988 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2990 (const_string "*")))
2991 (set (attr "length_immediate")
2993 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2995 (const_string "*")))
2996 (set (attr "prefix")
2997 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2998 (const_string "orig")
2999 (const_string "maybe_vex")))
3000 (set (attr "prefix_data16")
3001 (if_then_else (eq_attr "mode" "V1DF")
3003 (const_string "*")))
3005 (cond [(eq_attr "alternative" "0,1,2")
3007 (eq_attr "alternative" "3,4,5,6,11,12")
3010 /* xorps is one byte shorter. */
3011 (eq_attr "alternative" "7")
3012 (cond [(match_test "optimize_function_for_size_p (cfun)")
3013 (const_string "V4SF")
3014 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3017 (const_string "V2DF"))
3019 /* For architectures resolving dependencies on
3020 whole SSE registers use APD move to break dependency
3021 chains, otherwise use short move to avoid extra work.
3023 movaps encodes one byte shorter. */
3024 (eq_attr "alternative" "8")
3026 [(match_test "optimize_function_for_size_p (cfun)")
3027 (const_string "V4SF")
3028 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3029 (const_string "V2DF")
3031 (const_string "DF"))
3032 /* For architectures resolving dependencies on register
3033 parts we may avoid extra work to zero out upper part
3035 (eq_attr "alternative" "9")
3037 (match_test "TARGET_SSE_SPLIT_REGS")
3038 (const_string "V1DF")
3039 (const_string "DF"))
3041 (const_string "DF")))])
3043 ;; Possible store forwarding (partial memory) stall in alternative 4.
3044 (define_insn "*movdf_internal"
3045 [(set (match_operand:DF 0 "nonimmediate_operand"
3046 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3047 (match_operand:DF 1 "general_operand"
3048 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3049 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3050 && (!can_create_pseudo_p ()
3051 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3052 || GET_CODE (operands[1]) != CONST_DOUBLE
3053 || (optimize_function_for_size_p (cfun)
3054 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3055 && standard_80387_constant_p (operands[1]) > 0)
3056 || (TARGET_SSE2 && TARGET_SSE_MATH
3057 && standard_sse_constant_p (operands[1])))
3058 && !memory_operand (operands[0], DFmode))
3059 || (!TARGET_MEMORY_MISMATCH_STALL
3060 && memory_operand (operands[0], DFmode)))"
3062 switch (which_alternative)
3066 return output_387_reg_move (insn, operands);
3069 return standard_80387_constant_opcode (operands[1]);
3077 return standard_sse_constant_opcode (insn, operands[1]);
3085 switch (get_attr_mode (insn))
3088 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3089 return "%vmovapd\t{%1, %0|%0, %1}";
3091 return "%vmovaps\t{%1, %0|%0, %1}";
3094 return "%vmovq\t{%1, %0|%0, %1}";
3096 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3097 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3098 return "%vmovsd\t{%1, %0|%0, %1}";
3100 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3102 return "%vmovlps\t{%1, %d0|%d0, %1}";
3112 (if_then_else (eq_attr "alternative" "5,6,7,8")
3113 (const_string "sse2")
3114 (const_string "*")))
3116 (cond [(eq_attr "alternative" "0,1,2")
3117 (const_string "fmov")
3118 (eq_attr "alternative" "3,4")
3119 (const_string "multi")
3120 (eq_attr "alternative" "5,9")
3121 (const_string "sselog1")
3123 (const_string "ssemov")))
3124 (set (attr "prefix")
3125 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3126 (const_string "orig")
3127 (const_string "maybe_vex")))
3128 (set (attr "prefix_data16")
3129 (if_then_else (eq_attr "mode" "V1DF")
3131 (const_string "*")))
3133 (cond [(eq_attr "alternative" "0,1,2")
3135 (eq_attr "alternative" "3,4")
3138 /* For SSE1, we have many fewer alternatives. */
3139 (not (match_test "TARGET_SSE2"))
3141 (eq_attr "alternative" "5,6,9,10")
3142 (const_string "V4SF")
3143 (const_string "V2SF"))
3145 /* xorps is one byte shorter. */
3146 (eq_attr "alternative" "5,9")
3147 (cond [(match_test "optimize_function_for_size_p (cfun)")
3148 (const_string "V4SF")
3149 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3152 (const_string "V2DF"))
3154 /* For architectures resolving dependencies on
3155 whole SSE registers use APD move to break dependency
3156 chains, otherwise use short move to avoid extra work.
3158 movaps encodes one byte shorter. */
3159 (eq_attr "alternative" "6,10")
3161 [(match_test "optimize_function_for_size_p (cfun)")
3162 (const_string "V4SF")
3163 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3164 (const_string "V2DF")
3166 (const_string "DF"))
3167 /* For architectures resolving dependencies on register
3168 parts we may avoid extra work to zero out upper part
3170 (eq_attr "alternative" "7,11")
3172 (match_test "TARGET_SSE_SPLIT_REGS")
3173 (const_string "V1DF")
3174 (const_string "DF"))
3176 (const_string "DF")))])
3178 (define_insn "*movsf_internal"
3179 [(set (match_operand:SF 0 "nonimmediate_operand"
3180 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3181 (match_operand:SF 1 "general_operand"
3182 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3183 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3184 && (!can_create_pseudo_p ()
3185 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3186 || GET_CODE (operands[1]) != CONST_DOUBLE
3187 || (optimize_function_for_size_p (cfun)
3188 && ((!TARGET_SSE_MATH
3189 && standard_80387_constant_p (operands[1]) > 0)
3191 && standard_sse_constant_p (operands[1]))))
3192 || memory_operand (operands[0], SFmode))"
3194 switch (which_alternative)
3198 return output_387_reg_move (insn, operands);
3201 return standard_80387_constant_opcode (operands[1]);
3205 return "mov{l}\t{%1, %0|%0, %1}";
3208 return standard_sse_constant_opcode (insn, operands[1]);
3211 if (get_attr_mode (insn) == MODE_V4SF)
3212 return "%vmovaps\t{%1, %0|%0, %1}";
3214 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3218 return "%vmovss\t{%1, %0|%0, %1}";
3224 return "movd\t{%1, %0|%0, %1}";
3227 return "movq\t{%1, %0|%0, %1}";
3231 return "%vmovd\t{%1, %0|%0, %1}";
3238 (cond [(eq_attr "alternative" "0,1,2")
3239 (const_string "fmov")
3240 (eq_attr "alternative" "3,4")
3241 (const_string "multi")
3242 (eq_attr "alternative" "5")
3243 (const_string "sselog1")
3244 (eq_attr "alternative" "9,10,11,14,15")
3245 (const_string "mmxmov")
3247 (const_string "ssemov")))
3248 (set (attr "prefix")
3249 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3250 (const_string "maybe_vex")
3251 (const_string "orig")))
3253 (cond [(eq_attr "alternative" "3,4,9,10")
3255 (eq_attr "alternative" "5")
3257 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3258 (match_test "TARGET_SSE2"))
3259 (not (match_test "optimize_function_for_size_p (cfun)")))
3261 (const_string "V4SF"))
3262 /* For architectures resolving dependencies on
3263 whole SSE registers use APS move to break dependency
3264 chains, otherwise use short move to avoid extra work.
3266 Do the same for architectures resolving dependencies on
3267 the parts. While in DF mode it is better to always handle
3268 just register parts, the SF mode is different due to lack
3269 of instructions to load just part of the register. It is
3270 better to maintain the whole registers in single format
3271 to avoid problems on using packed logical operations. */
3272 (eq_attr "alternative" "6")
3274 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3275 (match_test "TARGET_SSE_SPLIT_REGS"))
3276 (const_string "V4SF")
3277 (const_string "SF"))
3278 (eq_attr "alternative" "11")
3279 (const_string "DI")]
3280 (const_string "SF")))])
3283 [(set (match_operand 0 "any_fp_register_operand" "")
3284 (match_operand 1 "memory_operand" ""))]
3286 && (GET_MODE (operands[0]) == TFmode
3287 || GET_MODE (operands[0]) == XFmode
3288 || GET_MODE (operands[0]) == DFmode
3289 || GET_MODE (operands[0]) == SFmode)
3290 && (operands[2] = find_constant_src (insn))"
3291 [(set (match_dup 0) (match_dup 2))]
3293 rtx c = operands[2];
3294 int r = REGNO (operands[0]);
3296 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3297 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3302 [(set (match_operand 0 "any_fp_register_operand" "")
3303 (float_extend (match_operand 1 "memory_operand" "")))]
3305 && (GET_MODE (operands[0]) == TFmode
3306 || GET_MODE (operands[0]) == XFmode
3307 || GET_MODE (operands[0]) == DFmode)
3308 && (operands[2] = find_constant_src (insn))"
3309 [(set (match_dup 0) (match_dup 2))]
3311 rtx c = operands[2];
3312 int r = REGNO (operands[0]);
3314 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3315 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3319 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3321 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3322 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3324 && (standard_80387_constant_p (operands[1]) == 8
3325 || standard_80387_constant_p (operands[1]) == 9)"
3326 [(set (match_dup 0)(match_dup 1))
3328 (neg:X87MODEF (match_dup 0)))]
3332 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3333 if (real_isnegzero (&r))
3334 operands[1] = CONST0_RTX (<MODE>mode);
3336 operands[1] = CONST1_RTX (<MODE>mode);
3340 [(set (match_operand 0 "nonimmediate_operand" "")
3341 (match_operand 1 "general_operand" ""))]
3343 && (GET_MODE (operands[0]) == TFmode
3344 || GET_MODE (operands[0]) == XFmode
3345 || GET_MODE (operands[0]) == DFmode)
3346 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3348 "ix86_split_long_move (operands); DONE;")
3350 (define_insn "swapxf"
3351 [(set (match_operand:XF 0 "register_operand" "+f")
3352 (match_operand:XF 1 "register_operand" "+f"))
3357 if (STACK_TOP_P (operands[0]))
3362 [(set_attr "type" "fxch")
3363 (set_attr "mode" "XF")])
3365 (define_insn "*swap<mode>"
3366 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3367 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3370 "TARGET_80387 || reload_completed"
3372 if (STACK_TOP_P (operands[0]))
3377 [(set_attr "type" "fxch")
3378 (set_attr "mode" "<MODE>")])
3380 ;; Zero extension instructions
3382 (define_expand "zero_extendsidi2"
3383 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3384 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))])
3386 (define_insn "*zero_extendsidi2_rex64"
3387 [(set (match_operand:DI 0 "nonimmediate_operand"
3388 "=r ,o,?*Ym,?*y,?*Yi,!*x")
3390 (match_operand:SI 1 "x86_64_zext_general_operand"
3391 "rmZ,0,r ,m ,r ,m*x")))]
3394 mov{l}\t{%1, %k0|%k0, %1}
3396 movd\t{%1, %0|%0, %1}
3397 movd\t{%1, %0|%0, %1}
3398 %vmovd\t{%1, %0|%0, %1}
3399 %vmovd\t{%1, %0|%0, %1}"
3400 [(set_attr "isa" "*,*,*,*,*,sse2")
3401 (set_attr "type" "imovx,multi,mmxmov,mmxmov,ssemov,ssemov")
3402 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3403 (set_attr "prefix_0f" "0,*,*,*,*,*")
3404 (set_attr "mode" "SI,SI,DI,DI,TI,TI")])
3406 (define_insn "*zero_extendsidi2"
3407 [(set (match_operand:DI 0 "nonimmediate_operand"
3408 "=ro,?r,?o,?*Ym,?*y,?*Yi,!*x")
3409 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand"
3410 "0 ,rm,r ,r ,m ,r ,m*x")))]
3416 movd\t{%1, %0|%0, %1}
3417 movd\t{%1, %0|%0, %1}
3418 %vmovd\t{%1, %0|%0, %1}
3419 %vmovd\t{%1, %0|%0, %1}"
3420 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3421 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3422 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3423 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3426 [(set (match_operand:DI 0 "memory_operand" "")
3427 (zero_extend:DI (match_operand:SI 1 "memory_operand" "")))]
3429 [(set (match_dup 4) (const_int 0))]
3430 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3433 [(set (match_operand:DI 0 "register_operand" "")
3434 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))]
3435 "!TARGET_64BIT && reload_completed
3436 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
3437 && true_regnum (operands[0]) == true_regnum (operands[1])"
3438 [(set (match_dup 4) (const_int 0))]
3439 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3442 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3443 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3444 "!TARGET_64BIT && reload_completed
3445 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3446 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3447 [(set (match_dup 3) (match_dup 1))
3448 (set (match_dup 4) (const_int 0))]
3449 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3451 (define_insn "zero_extend<mode>di2"
3452 [(set (match_operand:DI 0 "register_operand" "=r")
3454 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3456 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3457 [(set_attr "type" "imovx")
3458 (set_attr "mode" "SI")])
3460 (define_expand "zero_extend<mode>si2"
3461 [(set (match_operand:SI 0 "register_operand" "")
3462 (zero_extend:SI (match_operand:SWI12 1 "nonimmediate_operand" "")))]
3465 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3467 operands[1] = force_reg (<MODE>mode, operands[1]);
3468 emit_insn (gen_zero_extend<mode>si2_and (operands[0], operands[1]));
3473 (define_insn_and_split "zero_extend<mode>si2_and"
3474 [(set (match_operand:SI 0 "register_operand" "=r,?&<r>")
3476 (match_operand:SWI12 1 "nonimmediate_operand" "0,<r>m")))
3477 (clobber (reg:CC FLAGS_REG))]
3478 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3480 "&& reload_completed"
3481 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (match_dup 2)))
3482 (clobber (reg:CC FLAGS_REG))])]
3484 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3486 ix86_expand_clear (operands[0]);
3488 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3489 emit_insn (gen_movstrict<mode>
3490 (gen_lowpart (<MODE>mode, operands[0]), operands[1]));
3494 operands[2] = GEN_INT (GET_MODE_MASK (<MODE>mode));
3496 [(set_attr "type" "alu1")
3497 (set_attr "mode" "SI")])
3499 (define_insn "*zero_extend<mode>si2"
3500 [(set (match_operand:SI 0 "register_operand" "=r")
3502 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3503 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3504 "movz{<imodesuffix>l|x}\t{%1, %0|%0, %1}"
3505 [(set_attr "type" "imovx")
3506 (set_attr "mode" "SI")])
3508 (define_expand "zero_extendqihi2"
3509 [(set (match_operand:HI 0 "register_operand" "")
3510 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))]
3513 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3515 operands[1] = force_reg (QImode, operands[1]);
3516 emit_insn (gen_zero_extendqihi2_and (operands[0], operands[1]));
3521 (define_insn_and_split "zero_extendqihi2_and"
3522 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3523 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3524 (clobber (reg:CC FLAGS_REG))]
3525 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3527 "&& reload_completed"
3528 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3529 (clobber (reg:CC FLAGS_REG))])]
3531 if (true_regnum (operands[0]) != true_regnum (operands[1]))
3533 ix86_expand_clear (operands[0]);
3535 gcc_assert (!TARGET_PARTIAL_REG_STALL);
3536 emit_insn (gen_movstrictqi
3537 (gen_lowpart (QImode, operands[0]), operands[1]));
3541 operands[0] = gen_lowpart (SImode, operands[0]);
3543 [(set_attr "type" "alu1")
3544 (set_attr "mode" "SI")])
3546 ; zero extend to SImode to avoid partial register stalls
3547 (define_insn "*zero_extendqihi2"
3548 [(set (match_operand:HI 0 "register_operand" "=r")
3549 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3550 "!(TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))"
3551 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3552 [(set_attr "type" "imovx")
3553 (set_attr "mode" "SI")])
3555 ;; Sign extension instructions
3557 (define_expand "extendsidi2"
3558 [(set (match_operand:DI 0 "register_operand" "")
3559 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3564 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3569 (define_insn "*extendsidi2_rex64"
3570 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3571 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3575 movs{lq|x}\t{%1, %0|%0, %1}"
3576 [(set_attr "type" "imovx")
3577 (set_attr "mode" "DI")
3578 (set_attr "prefix_0f" "0")
3579 (set_attr "modrm" "0,1")])
3581 (define_insn "extendsidi2_1"
3582 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3583 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3584 (clobber (reg:CC FLAGS_REG))
3585 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3589 ;; Extend to memory case when source register does die.
3591 [(set (match_operand:DI 0 "memory_operand" "")
3592 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3593 (clobber (reg:CC FLAGS_REG))
3594 (clobber (match_operand:SI 2 "register_operand" ""))]
3596 && dead_or_set_p (insn, operands[1])
3597 && !reg_mentioned_p (operands[1], operands[0]))"
3598 [(set (match_dup 3) (match_dup 1))
3599 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3600 (clobber (reg:CC FLAGS_REG))])
3601 (set (match_dup 4) (match_dup 1))]
3602 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3604 ;; Extend to memory case when source register does not die.
3606 [(set (match_operand:DI 0 "memory_operand" "")
3607 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3608 (clobber (reg:CC FLAGS_REG))
3609 (clobber (match_operand:SI 2 "register_operand" ""))]
3613 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3615 emit_move_insn (operands[3], operands[1]);
3617 /* Generate a cltd if possible and doing so it profitable. */
3618 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3619 && true_regnum (operands[1]) == AX_REG
3620 && true_regnum (operands[2]) == DX_REG)
3622 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3626 emit_move_insn (operands[2], operands[1]);
3627 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3629 emit_move_insn (operands[4], operands[2]);
3633 ;; Extend to register case. Optimize case where source and destination
3634 ;; registers match and cases where we can use cltd.
3636 [(set (match_operand:DI 0 "register_operand" "")
3637 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3638 (clobber (reg:CC FLAGS_REG))
3639 (clobber (match_scratch:SI 2 ""))]
3643 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3645 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3646 emit_move_insn (operands[3], operands[1]);
3648 /* Generate a cltd if possible and doing so it profitable. */
3649 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3650 && true_regnum (operands[3]) == AX_REG
3651 && true_regnum (operands[4]) == DX_REG)
3653 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3657 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3658 emit_move_insn (operands[4], operands[1]);
3660 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3664 (define_insn "extend<mode>di2"
3665 [(set (match_operand:DI 0 "register_operand" "=r")
3667 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3669 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3670 [(set_attr "type" "imovx")
3671 (set_attr "mode" "DI")])
3673 (define_insn "extendhisi2"
3674 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3675 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3678 switch (get_attr_prefix_0f (insn))
3681 return "{cwtl|cwde}";
3683 return "movs{wl|x}\t{%1, %0|%0, %1}";
3686 [(set_attr "type" "imovx")
3687 (set_attr "mode" "SI")
3688 (set (attr "prefix_0f")
3689 ;; movsx is short decodable while cwtl is vector decoded.
3690 (if_then_else (and (eq_attr "cpu" "!k6")
3691 (eq_attr "alternative" "0"))
3693 (const_string "1")))
3695 (if_then_else (eq_attr "prefix_0f" "0")
3697 (const_string "1")))])
3699 (define_insn "*extendhisi2_zext"
3700 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3703 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3706 switch (get_attr_prefix_0f (insn))
3709 return "{cwtl|cwde}";
3711 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3714 [(set_attr "type" "imovx")
3715 (set_attr "mode" "SI")
3716 (set (attr "prefix_0f")
3717 ;; movsx is short decodable while cwtl is vector decoded.
3718 (if_then_else (and (eq_attr "cpu" "!k6")
3719 (eq_attr "alternative" "0"))
3721 (const_string "1")))
3723 (if_then_else (eq_attr "prefix_0f" "0")
3725 (const_string "1")))])
3727 (define_insn "extendqisi2"
3728 [(set (match_operand:SI 0 "register_operand" "=r")
3729 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3731 "movs{bl|x}\t{%1, %0|%0, %1}"
3732 [(set_attr "type" "imovx")
3733 (set_attr "mode" "SI")])
3735 (define_insn "*extendqisi2_zext"
3736 [(set (match_operand:DI 0 "register_operand" "=r")
3738 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3740 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3741 [(set_attr "type" "imovx")
3742 (set_attr "mode" "SI")])
3744 (define_insn "extendqihi2"
3745 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3746 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3749 switch (get_attr_prefix_0f (insn))
3752 return "{cbtw|cbw}";
3754 return "movs{bw|x}\t{%1, %0|%0, %1}";
3757 [(set_attr "type" "imovx")
3758 (set_attr "mode" "HI")
3759 (set (attr "prefix_0f")
3760 ;; movsx is short decodable while cwtl is vector decoded.
3761 (if_then_else (and (eq_attr "cpu" "!k6")
3762 (eq_attr "alternative" "0"))
3764 (const_string "1")))
3766 (if_then_else (eq_attr "prefix_0f" "0")
3768 (const_string "1")))])
3770 ;; Conversions between float and double.
3772 ;; These are all no-ops in the model used for the 80387.
3773 ;; So just emit moves.
3775 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3777 [(set (match_operand:DF 0 "push_operand" "")
3778 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3780 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3781 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3784 [(set (match_operand:XF 0 "push_operand" "")
3785 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3787 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3788 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3789 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3791 (define_expand "extendsfdf2"
3792 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3793 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3794 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3796 /* ??? Needed for compress_float_constant since all fp constants
3797 are TARGET_LEGITIMATE_CONSTANT_P. */
3798 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3800 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3801 && standard_80387_constant_p (operands[1]) > 0)
3803 operands[1] = simplify_const_unary_operation
3804 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3805 emit_move_insn_1 (operands[0], operands[1]);
3808 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3812 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3814 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3816 We do the conversion post reload to avoid producing of 128bit spills
3817 that might lead to ICE on 32bit target. The sequence unlikely combine
3820 [(set (match_operand:DF 0 "register_operand" "")
3822 (match_operand:SF 1 "nonimmediate_operand" "")))]
3823 "TARGET_USE_VECTOR_FP_CONVERTS
3824 && optimize_insn_for_speed_p ()
3825 && reload_completed && SSE_REG_P (operands[0])"
3830 (parallel [(const_int 0) (const_int 1)]))))]
3832 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3833 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3834 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3835 Try to avoid move when unpacking can be done in source. */
3836 if (REG_P (operands[1]))
3838 /* If it is unsafe to overwrite upper half of source, we need
3839 to move to destination and unpack there. */
3840 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3841 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3842 && true_regnum (operands[0]) != true_regnum (operands[1]))
3844 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3845 emit_move_insn (tmp, operands[1]);
3848 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3849 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3853 emit_insn (gen_vec_setv4sf_0 (operands[3],
3854 CONST0_RTX (V4SFmode), operands[1]));
3857 (define_insn "*extendsfdf2_mixed"
3858 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3860 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3861 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3863 switch (which_alternative)
3867 return output_387_reg_move (insn, operands);
3870 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3876 [(set_attr "type" "fmov,fmov,ssecvt")
3877 (set_attr "prefix" "orig,orig,maybe_vex")
3878 (set_attr "mode" "SF,XF,DF")])
3880 (define_insn "*extendsfdf2_sse"
3881 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3882 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3883 "TARGET_SSE2 && TARGET_SSE_MATH"
3884 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3885 [(set_attr "type" "ssecvt")
3886 (set_attr "prefix" "maybe_vex")
3887 (set_attr "mode" "DF")])
3889 (define_insn "*extendsfdf2_i387"
3890 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3891 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3893 "* return output_387_reg_move (insn, operands);"
3894 [(set_attr "type" "fmov")
3895 (set_attr "mode" "SF,XF")])
3897 (define_expand "extend<mode>xf2"
3898 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3899 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3902 /* ??? Needed for compress_float_constant since all fp constants
3903 are TARGET_LEGITIMATE_CONSTANT_P. */
3904 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3906 if (standard_80387_constant_p (operands[1]) > 0)
3908 operands[1] = simplify_const_unary_operation
3909 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3910 emit_move_insn_1 (operands[0], operands[1]);
3913 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3917 (define_insn "*extend<mode>xf2_i387"
3918 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3920 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3922 "* return output_387_reg_move (insn, operands);"
3923 [(set_attr "type" "fmov")
3924 (set_attr "mode" "<MODE>,XF")])
3926 ;; %%% This seems bad bad news.
3927 ;; This cannot output into an f-reg because there is no way to be sure
3928 ;; of truncating in that case. Otherwise this is just like a simple move
3929 ;; insn. So we pretend we can output to a reg in order to get better
3930 ;; register preferencing, but we really use a stack slot.
3932 ;; Conversion from DFmode to SFmode.
3934 (define_expand "truncdfsf2"
3935 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3937 (match_operand:DF 1 "nonimmediate_operand" "")))]
3938 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3940 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3942 else if (flag_unsafe_math_optimizations)
3946 enum ix86_stack_slot slot = (virtuals_instantiated
3949 rtx temp = assign_386_stack_local (SFmode, slot);
3950 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3955 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3957 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3959 We do the conversion post reload to avoid producing of 128bit spills
3960 that might lead to ICE on 32bit target. The sequence unlikely combine
3963 [(set (match_operand:SF 0 "register_operand" "")
3965 (match_operand:DF 1 "nonimmediate_operand" "")))]
3966 "TARGET_USE_VECTOR_FP_CONVERTS
3967 && optimize_insn_for_speed_p ()
3968 && reload_completed && SSE_REG_P (operands[0])"
3971 (float_truncate:V2SF
3975 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3976 operands[3] = CONST0_RTX (V2SFmode);
3977 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3978 /* Use movsd for loading from memory, unpcklpd for registers.
3979 Try to avoid move when unpacking can be done in source, or SSE3
3980 movddup is available. */
3981 if (REG_P (operands[1]))
3984 && true_regnum (operands[0]) != true_regnum (operands[1])
3985 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3986 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3988 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3989 emit_move_insn (tmp, operands[1]);
3992 else if (!TARGET_SSE3)
3993 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
3994 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
3997 emit_insn (gen_sse2_loadlpd (operands[4],
3998 CONST0_RTX (V2DFmode), operands[1]));
4001 (define_expand "truncdfsf2_with_temp"
4002 [(parallel [(set (match_operand:SF 0 "" "")
4003 (float_truncate:SF (match_operand:DF 1 "" "")))
4004 (clobber (match_operand:SF 2 "" ""))])])
4006 (define_insn "*truncdfsf_fast_mixed"
4007 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4009 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4010 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4012 switch (which_alternative)
4015 return output_387_reg_move (insn, operands);
4017 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4022 [(set_attr "type" "fmov,ssecvt")
4023 (set_attr "prefix" "orig,maybe_vex")
4024 (set_attr "mode" "SF")])
4026 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4027 ;; because nothing we do here is unsafe.
4028 (define_insn "*truncdfsf_fast_sse"
4029 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4031 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4032 "TARGET_SSE2 && TARGET_SSE_MATH"
4033 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4034 [(set_attr "type" "ssecvt")
4035 (set_attr "prefix" "maybe_vex")
4036 (set_attr "mode" "SF")])
4038 (define_insn "*truncdfsf_fast_i387"
4039 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4041 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4042 "TARGET_80387 && flag_unsafe_math_optimizations"
4043 "* return output_387_reg_move (insn, operands);"
4044 [(set_attr "type" "fmov")
4045 (set_attr "mode" "SF")])
4047 (define_insn "*truncdfsf_mixed"
4048 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4050 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4051 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4052 "TARGET_MIX_SSE_I387"
4054 switch (which_alternative)
4057 return output_387_reg_move (insn, operands);
4059 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4065 [(set_attr "isa" "*,sse2,*,*,*")
4066 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4067 (set_attr "unit" "*,*,i387,i387,i387")
4068 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4069 (set_attr "mode" "SF")])
4071 (define_insn "*truncdfsf_i387"
4072 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4074 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4075 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4078 switch (which_alternative)
4081 return output_387_reg_move (insn, operands);
4087 [(set_attr "type" "fmov,multi,multi,multi")
4088 (set_attr "unit" "*,i387,i387,i387")
4089 (set_attr "mode" "SF")])
4091 (define_insn "*truncdfsf2_i387_1"
4092 [(set (match_operand:SF 0 "memory_operand" "=m")
4094 (match_operand:DF 1 "register_operand" "f")))]
4096 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4097 && !TARGET_MIX_SSE_I387"
4098 "* return output_387_reg_move (insn, operands);"
4099 [(set_attr "type" "fmov")
4100 (set_attr "mode" "SF")])
4103 [(set (match_operand:SF 0 "register_operand" "")
4105 (match_operand:DF 1 "fp_register_operand" "")))
4106 (clobber (match_operand 2 "" ""))]
4108 [(set (match_dup 2) (match_dup 1))
4109 (set (match_dup 0) (match_dup 2))]
4110 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4112 ;; Conversion from XFmode to {SF,DF}mode
4114 (define_expand "truncxf<mode>2"
4115 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4116 (float_truncate:MODEF
4117 (match_operand:XF 1 "register_operand" "")))
4118 (clobber (match_dup 2))])]
4121 if (flag_unsafe_math_optimizations)
4123 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4124 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4125 if (reg != operands[0])
4126 emit_move_insn (operands[0], reg);
4131 enum ix86_stack_slot slot = (virtuals_instantiated
4134 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4138 (define_insn "*truncxfsf2_mixed"
4139 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4141 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4142 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4145 gcc_assert (!which_alternative);
4146 return output_387_reg_move (insn, operands);
4148 [(set_attr "type" "fmov,multi,multi,multi")
4149 (set_attr "unit" "*,i387,i387,i387")
4150 (set_attr "mode" "SF")])
4152 (define_insn "*truncxfdf2_mixed"
4153 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4155 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4156 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4159 gcc_assert (!which_alternative);
4160 return output_387_reg_move (insn, operands);
4162 [(set_attr "isa" "*,*,sse2,*")
4163 (set_attr "type" "fmov,multi,multi,multi")
4164 (set_attr "unit" "*,i387,i387,i387")
4165 (set_attr "mode" "DF")])
4167 (define_insn "truncxf<mode>2_i387_noop"
4168 [(set (match_operand:MODEF 0 "register_operand" "=f")
4169 (float_truncate:MODEF
4170 (match_operand:XF 1 "register_operand" "f")))]
4171 "TARGET_80387 && flag_unsafe_math_optimizations"
4172 "* return output_387_reg_move (insn, operands);"
4173 [(set_attr "type" "fmov")
4174 (set_attr "mode" "<MODE>")])
4176 (define_insn "*truncxf<mode>2_i387"
4177 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4178 (float_truncate:MODEF
4179 (match_operand:XF 1 "register_operand" "f")))]
4181 "* return output_387_reg_move (insn, operands);"
4182 [(set_attr "type" "fmov")
4183 (set_attr "mode" "<MODE>")])
4186 [(set (match_operand:MODEF 0 "register_operand" "")
4187 (float_truncate:MODEF
4188 (match_operand:XF 1 "register_operand" "")))
4189 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4190 "TARGET_80387 && reload_completed"
4191 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4192 (set (match_dup 0) (match_dup 2))])
4195 [(set (match_operand:MODEF 0 "memory_operand" "")
4196 (float_truncate:MODEF
4197 (match_operand:XF 1 "register_operand" "")))
4198 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4200 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4202 ;; Signed conversion to DImode.
4204 (define_expand "fix_truncxfdi2"
4205 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4206 (fix:DI (match_operand:XF 1 "register_operand" "")))
4207 (clobber (reg:CC FLAGS_REG))])]
4212 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4217 (define_expand "fix_trunc<mode>di2"
4218 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4219 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4220 (clobber (reg:CC FLAGS_REG))])]
4221 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4224 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4226 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4229 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4231 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4232 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4233 if (out != operands[0])
4234 emit_move_insn (operands[0], out);
4239 ;; Signed conversion to SImode.
4241 (define_expand "fix_truncxfsi2"
4242 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4243 (fix:SI (match_operand:XF 1 "register_operand" "")))
4244 (clobber (reg:CC FLAGS_REG))])]
4249 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4254 (define_expand "fix_trunc<mode>si2"
4255 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4256 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4257 (clobber (reg:CC FLAGS_REG))])]
4258 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4261 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4263 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4266 if (SSE_FLOAT_MODE_P (<MODE>mode))
4268 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4269 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4270 if (out != operands[0])
4271 emit_move_insn (operands[0], out);
4276 ;; Signed conversion to HImode.
4278 (define_expand "fix_trunc<mode>hi2"
4279 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4280 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4281 (clobber (reg:CC FLAGS_REG))])]
4283 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4287 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4292 ;; Unsigned conversion to SImode.
4294 (define_expand "fixuns_trunc<mode>si2"
4296 [(set (match_operand:SI 0 "register_operand" "")
4298 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4300 (clobber (match_scratch:<ssevecmode> 3 ""))
4301 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4302 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4304 enum machine_mode mode = <MODE>mode;
4305 enum machine_mode vecmode = <ssevecmode>mode;
4306 REAL_VALUE_TYPE TWO31r;
4309 if (optimize_insn_for_size_p ())
4312 real_ldexp (&TWO31r, &dconst1, 31);
4313 two31 = const_double_from_real_value (TWO31r, mode);
4314 two31 = ix86_build_const_vector (vecmode, true, two31);
4315 operands[2] = force_reg (vecmode, two31);
4318 (define_insn_and_split "*fixuns_trunc<mode>_1"
4319 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4321 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4322 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4323 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4324 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4325 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4326 && optimize_function_for_speed_p (cfun)"
4328 "&& reload_completed"
4331 ix86_split_convert_uns_si_sse (operands);
4335 ;; Unsigned conversion to HImode.
4336 ;; Without these patterns, we'll try the unsigned SI conversion which
4337 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4339 (define_expand "fixuns_trunc<mode>hi2"
4341 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4342 (set (match_operand:HI 0 "nonimmediate_operand" "")
4343 (subreg:HI (match_dup 2) 0))]
4344 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4345 "operands[2] = gen_reg_rtx (SImode);")
4347 ;; When SSE is available, it is always faster to use it!
4348 (define_insn "fix_trunc<mode>di_sse"
4349 [(set (match_operand:DI 0 "register_operand" "=r,r")
4350 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4351 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4352 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4353 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4354 [(set_attr "type" "sseicvt")
4355 (set_attr "prefix" "maybe_vex")
4356 (set_attr "prefix_rex" "1")
4357 (set_attr "mode" "<MODE>")
4358 (set_attr "athlon_decode" "double,vector")
4359 (set_attr "amdfam10_decode" "double,double")
4360 (set_attr "bdver1_decode" "double,double")])
4362 (define_insn "fix_trunc<mode>si_sse"
4363 [(set (match_operand:SI 0 "register_operand" "=r,r")
4364 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4365 "SSE_FLOAT_MODE_P (<MODE>mode)
4366 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4367 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4368 [(set_attr "type" "sseicvt")
4369 (set_attr "prefix" "maybe_vex")
4370 (set_attr "mode" "<MODE>")
4371 (set_attr "athlon_decode" "double,vector")
4372 (set_attr "amdfam10_decode" "double,double")
4373 (set_attr "bdver1_decode" "double,double")])
4375 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4377 [(set (match_operand:MODEF 0 "register_operand" "")
4378 (match_operand:MODEF 1 "memory_operand" ""))
4379 (set (match_operand:SWI48x 2 "register_operand" "")
4380 (fix:SWI48x (match_dup 0)))]
4381 "TARGET_SHORTEN_X87_SSE
4382 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4383 && peep2_reg_dead_p (2, operands[0])"
4384 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4386 ;; Avoid vector decoded forms of the instruction.
4388 [(match_scratch:DF 2 "x")
4389 (set (match_operand:SWI48x 0 "register_operand" "")
4390 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4391 "TARGET_SSE2 && 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)))])
4396 [(match_scratch:SF 2 "x")
4397 (set (match_operand:SWI48x 0 "register_operand" "")
4398 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4399 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4400 [(set (match_dup 2) (match_dup 1))
4401 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4403 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4404 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4405 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4406 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4408 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4409 && (TARGET_64BIT || <MODE>mode != DImode))
4411 && can_create_pseudo_p ()"
4416 if (memory_operand (operands[0], VOIDmode))
4417 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4420 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4421 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4427 [(set_attr "type" "fisttp")
4428 (set_attr "mode" "<MODE>")])
4430 (define_insn "fix_trunc<mode>_i387_fisttp"
4431 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4432 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4433 (clobber (match_scratch:XF 2 "=&1f"))]
4434 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4436 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4437 && (TARGET_64BIT || <MODE>mode != DImode))
4438 && TARGET_SSE_MATH)"
4439 "* return output_fix_trunc (insn, operands, true);"
4440 [(set_attr "type" "fisttp")
4441 (set_attr "mode" "<MODE>")])
4443 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4444 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4445 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4446 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4447 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4448 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4450 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4451 && (TARGET_64BIT || <MODE>mode != DImode))
4452 && TARGET_SSE_MATH)"
4454 [(set_attr "type" "fisttp")
4455 (set_attr "mode" "<MODE>")])
4458 [(set (match_operand:SWI248x 0 "register_operand" "")
4459 (fix:SWI248x (match_operand 1 "register_operand" "")))
4460 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4461 (clobber (match_scratch 3 ""))]
4463 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4464 (clobber (match_dup 3))])
4465 (set (match_dup 0) (match_dup 2))])
4468 [(set (match_operand:SWI248x 0 "memory_operand" "")
4469 (fix:SWI248x (match_operand 1 "register_operand" "")))
4470 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4471 (clobber (match_scratch 3 ""))]
4473 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4474 (clobber (match_dup 3))])])
4476 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4477 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4478 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4479 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4480 ;; function in i386.c.
4481 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4482 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4483 (fix:SWI248x (match_operand 1 "register_operand" "")))
4484 (clobber (reg:CC FLAGS_REG))]
4485 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4487 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4488 && (TARGET_64BIT || <MODE>mode != DImode))
4489 && can_create_pseudo_p ()"
4494 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4496 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4497 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4498 if (memory_operand (operands[0], VOIDmode))
4499 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4500 operands[2], operands[3]));
4503 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4504 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4505 operands[2], operands[3],
4510 [(set_attr "type" "fistp")
4511 (set_attr "i387_cw" "trunc")
4512 (set_attr "mode" "<MODE>")])
4514 (define_insn "fix_truncdi_i387"
4515 [(set (match_operand:DI 0 "memory_operand" "=m")
4516 (fix:DI (match_operand 1 "register_operand" "f")))
4517 (use (match_operand:HI 2 "memory_operand" "m"))
4518 (use (match_operand:HI 3 "memory_operand" "m"))
4519 (clobber (match_scratch:XF 4 "=&1f"))]
4520 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4522 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4523 "* return output_fix_trunc (insn, operands, false);"
4524 [(set_attr "type" "fistp")
4525 (set_attr "i387_cw" "trunc")
4526 (set_attr "mode" "DI")])
4528 (define_insn "fix_truncdi_i387_with_temp"
4529 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4530 (fix:DI (match_operand 1 "register_operand" "f,f")))
4531 (use (match_operand:HI 2 "memory_operand" "m,m"))
4532 (use (match_operand:HI 3 "memory_operand" "m,m"))
4533 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4534 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4535 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4537 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4539 [(set_attr "type" "fistp")
4540 (set_attr "i387_cw" "trunc")
4541 (set_attr "mode" "DI")])
4544 [(set (match_operand:DI 0 "register_operand" "")
4545 (fix:DI (match_operand 1 "register_operand" "")))
4546 (use (match_operand:HI 2 "memory_operand" ""))
4547 (use (match_operand:HI 3 "memory_operand" ""))
4548 (clobber (match_operand:DI 4 "memory_operand" ""))
4549 (clobber (match_scratch 5 ""))]
4551 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4554 (clobber (match_dup 5))])
4555 (set (match_dup 0) (match_dup 4))])
4558 [(set (match_operand:DI 0 "memory_operand" "")
4559 (fix:DI (match_operand 1 "register_operand" "")))
4560 (use (match_operand:HI 2 "memory_operand" ""))
4561 (use (match_operand:HI 3 "memory_operand" ""))
4562 (clobber (match_operand:DI 4 "memory_operand" ""))
4563 (clobber (match_scratch 5 ""))]
4565 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4568 (clobber (match_dup 5))])])
4570 (define_insn "fix_trunc<mode>_i387"
4571 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4572 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4573 (use (match_operand:HI 2 "memory_operand" "m"))
4574 (use (match_operand:HI 3 "memory_operand" "m"))]
4575 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4577 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4578 "* return output_fix_trunc (insn, operands, false);"
4579 [(set_attr "type" "fistp")
4580 (set_attr "i387_cw" "trunc")
4581 (set_attr "mode" "<MODE>")])
4583 (define_insn "fix_trunc<mode>_i387_with_temp"
4584 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4585 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4586 (use (match_operand:HI 2 "memory_operand" "m,m"))
4587 (use (match_operand:HI 3 "memory_operand" "m,m"))
4588 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4589 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4591 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4593 [(set_attr "type" "fistp")
4594 (set_attr "i387_cw" "trunc")
4595 (set_attr "mode" "<MODE>")])
4598 [(set (match_operand:SWI24 0 "register_operand" "")
4599 (fix:SWI24 (match_operand 1 "register_operand" "")))
4600 (use (match_operand:HI 2 "memory_operand" ""))
4601 (use (match_operand:HI 3 "memory_operand" ""))
4602 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4604 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4606 (use (match_dup 3))])
4607 (set (match_dup 0) (match_dup 4))])
4610 [(set (match_operand:SWI24 0 "memory_operand" "")
4611 (fix:SWI24 (match_operand 1 "register_operand" "")))
4612 (use (match_operand:HI 2 "memory_operand" ""))
4613 (use (match_operand:HI 3 "memory_operand" ""))
4614 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4616 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4618 (use (match_dup 3))])])
4620 (define_insn "x86_fnstcw_1"
4621 [(set (match_operand:HI 0 "memory_operand" "=m")
4622 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4625 [(set (attr "length")
4626 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4627 (set_attr "mode" "HI")
4628 (set_attr "unit" "i387")
4629 (set_attr "bdver1_decode" "vector")])
4631 (define_insn "x86_fldcw_1"
4632 [(set (reg:HI FPCR_REG)
4633 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4636 [(set (attr "length")
4637 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4638 (set_attr "mode" "HI")
4639 (set_attr "unit" "i387")
4640 (set_attr "athlon_decode" "vector")
4641 (set_attr "amdfam10_decode" "vector")
4642 (set_attr "bdver1_decode" "vector")])
4644 ;; Conversion between fixed point and floating point.
4646 ;; Even though we only accept memory inputs, the backend _really_
4647 ;; wants to be able to do this between registers.
4649 (define_expand "floathi<mode>2"
4650 [(set (match_operand:X87MODEF 0 "register_operand" "")
4651 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4653 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4654 || TARGET_MIX_SSE_I387)")
4656 ;; Pre-reload splitter to add memory clobber to the pattern.
4657 (define_insn_and_split "*floathi<mode>2_1"
4658 [(set (match_operand:X87MODEF 0 "register_operand" "")
4659 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4662 || TARGET_MIX_SSE_I387)
4663 && can_create_pseudo_p ()"
4666 [(parallel [(set (match_dup 0)
4667 (float:X87MODEF (match_dup 1)))
4668 (clobber (match_dup 2))])]
4669 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4671 (define_insn "*floathi<mode>2_i387_with_temp"
4672 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4673 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4674 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4676 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4677 || TARGET_MIX_SSE_I387)"
4679 [(set_attr "type" "fmov,multi")
4680 (set_attr "mode" "<MODE>")
4681 (set_attr "unit" "*,i387")
4682 (set_attr "fp_int_src" "true")])
4684 (define_insn "*floathi<mode>2_i387"
4685 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4686 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4688 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4689 || TARGET_MIX_SSE_I387)"
4691 [(set_attr "type" "fmov")
4692 (set_attr "mode" "<MODE>")
4693 (set_attr "fp_int_src" "true")])
4696 [(set (match_operand:X87MODEF 0 "register_operand" "")
4697 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4698 (clobber (match_operand:HI 2 "memory_operand" ""))]
4700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4701 || TARGET_MIX_SSE_I387)
4702 && reload_completed"
4703 [(set (match_dup 2) (match_dup 1))
4704 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4707 [(set (match_operand:X87MODEF 0 "register_operand" "")
4708 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4709 (clobber (match_operand:HI 2 "memory_operand" ""))]
4711 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4712 || TARGET_MIX_SSE_I387)
4713 && reload_completed"
4714 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4716 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4717 [(set (match_operand:X87MODEF 0 "register_operand" "")
4719 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4721 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4722 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4724 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4725 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4726 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4728 rtx reg = gen_reg_rtx (XFmode);
4729 rtx (*insn)(rtx, rtx);
4731 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4733 if (<X87MODEF:MODE>mode == SFmode)
4734 insn = gen_truncxfsf2;
4735 else if (<X87MODEF:MODE>mode == DFmode)
4736 insn = gen_truncxfdf2;
4740 emit_insn (insn (operands[0], reg));
4745 ;; Pre-reload splitter to add memory clobber to the pattern.
4746 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4747 [(set (match_operand:X87MODEF 0 "register_operand" "")
4748 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4750 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4751 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4752 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4753 || TARGET_MIX_SSE_I387))
4754 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4755 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4756 && ((<SWI48x:MODE>mode == SImode
4757 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4758 && optimize_function_for_speed_p (cfun)
4759 && flag_trapping_math)
4760 || !(TARGET_INTER_UNIT_CONVERSIONS
4761 || optimize_function_for_size_p (cfun)))))
4762 && can_create_pseudo_p ()"
4765 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4766 (clobber (match_dup 2))])]
4768 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4770 /* Avoid store forwarding (partial memory) stall penalty
4771 by passing DImode value through XMM registers. */
4772 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4773 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4774 && optimize_function_for_speed_p (cfun))
4776 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4783 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4784 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4786 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4787 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4788 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4789 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4791 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4792 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4793 (set_attr "unit" "*,i387,*,*,*")
4794 (set_attr "athlon_decode" "*,*,double,direct,double")
4795 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4796 (set_attr "bdver1_decode" "*,*,double,direct,double")
4797 (set_attr "fp_int_src" "true")])
4799 (define_insn "*floatsi<mode>2_vector_mixed"
4800 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4801 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4802 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4803 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4807 [(set_attr "type" "fmov,sseicvt")
4808 (set_attr "mode" "<MODE>,<ssevecmode>")
4809 (set_attr "unit" "i387,*")
4810 (set_attr "athlon_decode" "*,direct")
4811 (set_attr "amdfam10_decode" "*,double")
4812 (set_attr "bdver1_decode" "*,direct")
4813 (set_attr "fp_int_src" "true")])
4815 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4816 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4818 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4819 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4820 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4821 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4823 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4824 (set_attr "mode" "<MODEF:MODE>")
4825 (set_attr "unit" "*,i387,*,*")
4826 (set_attr "athlon_decode" "*,*,double,direct")
4827 (set_attr "amdfam10_decode" "*,*,vector,double")
4828 (set_attr "bdver1_decode" "*,*,double,direct")
4829 (set_attr "fp_int_src" "true")])
4832 [(set (match_operand:MODEF 0 "register_operand" "")
4833 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4834 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4835 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4836 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4837 && TARGET_INTER_UNIT_CONVERSIONS
4839 && (SSE_REG_P (operands[0])
4840 || (GET_CODE (operands[0]) == SUBREG
4841 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4842 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4845 [(set (match_operand:MODEF 0 "register_operand" "")
4846 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4847 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4848 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4849 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4850 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4852 && (SSE_REG_P (operands[0])
4853 || (GET_CODE (operands[0]) == SUBREG
4854 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4855 [(set (match_dup 2) (match_dup 1))
4856 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4858 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4859 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4861 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4862 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4863 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4864 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4867 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4868 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4869 [(set_attr "type" "fmov,sseicvt,sseicvt")
4870 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4871 (set_attr "mode" "<MODEF:MODE>")
4872 (set (attr "prefix_rex")
4874 (and (eq_attr "prefix" "maybe_vex")
4875 (match_test "<SWI48x:MODE>mode == DImode"))
4877 (const_string "*")))
4878 (set_attr "unit" "i387,*,*")
4879 (set_attr "athlon_decode" "*,double,direct")
4880 (set_attr "amdfam10_decode" "*,vector,double")
4881 (set_attr "bdver1_decode" "*,double,direct")
4882 (set_attr "fp_int_src" "true")])
4884 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4885 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4887 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4888 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4889 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4890 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4893 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4894 [(set_attr "type" "fmov,sseicvt")
4895 (set_attr "prefix" "orig,maybe_vex")
4896 (set_attr "mode" "<MODEF:MODE>")
4897 (set (attr "prefix_rex")
4899 (and (eq_attr "prefix" "maybe_vex")
4900 (match_test "<SWI48x:MODE>mode == DImode"))
4902 (const_string "*")))
4903 (set_attr "athlon_decode" "*,direct")
4904 (set_attr "amdfam10_decode" "*,double")
4905 (set_attr "bdver1_decode" "*,direct")
4906 (set_attr "fp_int_src" "true")])
4908 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4909 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4911 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4912 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4913 "TARGET_SSE2 && TARGET_SSE_MATH
4914 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4916 [(set_attr "type" "sseicvt")
4917 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4918 (set_attr "athlon_decode" "double,direct,double")
4919 (set_attr "amdfam10_decode" "vector,double,double")
4920 (set_attr "bdver1_decode" "double,direct,double")
4921 (set_attr "fp_int_src" "true")])
4923 (define_insn "*floatsi<mode>2_vector_sse"
4924 [(set (match_operand:MODEF 0 "register_operand" "=x")
4925 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4926 "TARGET_SSE2 && TARGET_SSE_MATH
4927 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4929 [(set_attr "type" "sseicvt")
4930 (set_attr "mode" "<MODE>")
4931 (set_attr "athlon_decode" "direct")
4932 (set_attr "amdfam10_decode" "double")
4933 (set_attr "bdver1_decode" "direct")
4934 (set_attr "fp_int_src" "true")])
4937 [(set (match_operand:MODEF 0 "register_operand" "")
4938 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4939 (clobber (match_operand:SI 2 "memory_operand" ""))]
4940 "TARGET_SSE2 && TARGET_SSE_MATH
4941 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4943 && (SSE_REG_P (operands[0])
4944 || (GET_CODE (operands[0]) == SUBREG
4945 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4948 rtx op1 = operands[1];
4950 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4952 if (GET_CODE (op1) == SUBREG)
4953 op1 = SUBREG_REG (op1);
4955 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4957 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4958 emit_insn (gen_sse2_loadld (operands[4],
4959 CONST0_RTX (V4SImode), operands[1]));
4961 /* We can ignore possible trapping value in the
4962 high part of SSE register for non-trapping math. */
4963 else if (SSE_REG_P (op1) && !flag_trapping_math)
4964 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4967 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4968 emit_move_insn (operands[2], operands[1]);
4969 emit_insn (gen_sse2_loadld (operands[4],
4970 CONST0_RTX (V4SImode), operands[2]));
4972 if (<ssevecmode>mode == V4SFmode)
4973 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4975 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4980 [(set (match_operand:MODEF 0 "register_operand" "")
4981 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4982 (clobber (match_operand:SI 2 "memory_operand" ""))]
4983 "TARGET_SSE2 && TARGET_SSE_MATH
4984 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4986 && (SSE_REG_P (operands[0])
4987 || (GET_CODE (operands[0]) == SUBREG
4988 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4991 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4993 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4995 emit_insn (gen_sse2_loadld (operands[4],
4996 CONST0_RTX (V4SImode), operands[1]));
4997 if (<ssevecmode>mode == V4SFmode)
4998 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5000 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5005 [(set (match_operand:MODEF 0 "register_operand" "")
5006 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5007 "TARGET_SSE2 && TARGET_SSE_MATH
5008 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5010 && (SSE_REG_P (operands[0])
5011 || (GET_CODE (operands[0]) == SUBREG
5012 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5015 rtx op1 = operands[1];
5017 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5019 if (GET_CODE (op1) == SUBREG)
5020 op1 = SUBREG_REG (op1);
5022 if (GENERAL_REG_P (op1))
5024 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5025 if (TARGET_INTER_UNIT_MOVES)
5026 emit_insn (gen_sse2_loadld (operands[4],
5027 CONST0_RTX (V4SImode), operands[1]));
5030 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5032 emit_insn (gen_sse2_loadld (operands[4],
5033 CONST0_RTX (V4SImode), operands[5]));
5034 ix86_free_from_memory (GET_MODE (operands[1]));
5037 /* We can ignore possible trapping value in the
5038 high part of SSE register for non-trapping math. */
5039 else if (SSE_REG_P (op1) && !flag_trapping_math)
5040 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5043 if (<ssevecmode>mode == V4SFmode)
5044 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5046 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5051 [(set (match_operand:MODEF 0 "register_operand" "")
5052 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5053 "TARGET_SSE2 && TARGET_SSE_MATH
5054 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5056 && (SSE_REG_P (operands[0])
5057 || (GET_CODE (operands[0]) == SUBREG
5058 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5061 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5063 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5065 emit_insn (gen_sse2_loadld (operands[4],
5066 CONST0_RTX (V4SImode), operands[1]));
5067 if (<ssevecmode>mode == V4SFmode)
5068 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5070 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5074 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5075 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5077 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5078 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5079 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5080 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5082 [(set_attr "type" "sseicvt")
5083 (set_attr "mode" "<MODEF:MODE>")
5084 (set_attr "athlon_decode" "double,direct")
5085 (set_attr "amdfam10_decode" "vector,double")
5086 (set_attr "bdver1_decode" "double,direct")
5087 (set_attr "fp_int_src" "true")])
5089 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5090 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5092 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5093 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5094 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5095 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5096 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5097 [(set_attr "type" "sseicvt")
5098 (set_attr "prefix" "maybe_vex")
5099 (set_attr "mode" "<MODEF:MODE>")
5100 (set (attr "prefix_rex")
5102 (and (eq_attr "prefix" "maybe_vex")
5103 (match_test "<SWI48x:MODE>mode == DImode"))
5105 (const_string "*")))
5106 (set_attr "athlon_decode" "double,direct")
5107 (set_attr "amdfam10_decode" "vector,double")
5108 (set_attr "bdver1_decode" "double,direct")
5109 (set_attr "fp_int_src" "true")])
5112 [(set (match_operand:MODEF 0 "register_operand" "")
5113 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5114 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5115 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5116 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5117 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5119 && (SSE_REG_P (operands[0])
5120 || (GET_CODE (operands[0]) == SUBREG
5121 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5122 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5124 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5125 [(set (match_operand:MODEF 0 "register_operand" "=x")
5127 (match_operand:SWI48x 1 "memory_operand" "m")))]
5128 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5129 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5130 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5131 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5132 [(set_attr "type" "sseicvt")
5133 (set_attr "prefix" "maybe_vex")
5134 (set_attr "mode" "<MODEF:MODE>")
5135 (set (attr "prefix_rex")
5137 (and (eq_attr "prefix" "maybe_vex")
5138 (match_test "<SWI48x:MODE>mode == DImode"))
5140 (const_string "*")))
5141 (set_attr "athlon_decode" "direct")
5142 (set_attr "amdfam10_decode" "double")
5143 (set_attr "bdver1_decode" "direct")
5144 (set_attr "fp_int_src" "true")])
5147 [(set (match_operand:MODEF 0 "register_operand" "")
5148 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5149 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5150 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5151 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5152 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5154 && (SSE_REG_P (operands[0])
5155 || (GET_CODE (operands[0]) == SUBREG
5156 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5157 [(set (match_dup 2) (match_dup 1))
5158 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5161 [(set (match_operand:MODEF 0 "register_operand" "")
5162 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5163 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5164 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5165 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5167 && (SSE_REG_P (operands[0])
5168 || (GET_CODE (operands[0]) == SUBREG
5169 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5170 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5172 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5173 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5175 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5176 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5178 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5182 [(set_attr "type" "fmov,multi")
5183 (set_attr "mode" "<X87MODEF:MODE>")
5184 (set_attr "unit" "*,i387")
5185 (set_attr "fp_int_src" "true")])
5187 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5188 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5190 (match_operand:SWI48x 1 "memory_operand" "m")))]
5192 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5194 [(set_attr "type" "fmov")
5195 (set_attr "mode" "<X87MODEF:MODE>")
5196 (set_attr "fp_int_src" "true")])
5199 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5200 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5201 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5203 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5204 && reload_completed"
5205 [(set (match_dup 2) (match_dup 1))
5206 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5209 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5210 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5211 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5213 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5214 && reload_completed"
5215 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5217 ;; Avoid store forwarding (partial memory) stall penalty
5218 ;; by passing DImode value through XMM registers. */
5220 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5221 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5223 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5224 (clobber (match_scratch:V4SI 3 "=X,x"))
5225 (clobber (match_scratch:V4SI 4 "=X,x"))
5226 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5227 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5228 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5229 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5231 [(set_attr "type" "multi")
5232 (set_attr "mode" "<X87MODEF:MODE>")
5233 (set_attr "unit" "i387")
5234 (set_attr "fp_int_src" "true")])
5237 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5238 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5239 (clobber (match_scratch:V4SI 3 ""))
5240 (clobber (match_scratch:V4SI 4 ""))
5241 (clobber (match_operand:DI 2 "memory_operand" ""))]
5242 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5243 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5244 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5245 && reload_completed"
5246 [(set (match_dup 2) (match_dup 3))
5247 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5249 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5250 Assemble the 64-bit DImode value in an xmm register. */
5251 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5252 gen_rtx_SUBREG (SImode, operands[1], 0)));
5253 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5254 gen_rtx_SUBREG (SImode, operands[1], 4)));
5255 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5258 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5262 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5263 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5264 (clobber (match_scratch:V4SI 3 ""))
5265 (clobber (match_scratch:V4SI 4 ""))
5266 (clobber (match_operand:DI 2 "memory_operand" ""))]
5267 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5268 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5269 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5270 && reload_completed"
5271 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5273 ;; Avoid store forwarding (partial memory) stall penalty by extending
5274 ;; SImode value to DImode through XMM register instead of pushing two
5275 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5276 ;; targets benefit from this optimization. Also note that fild
5277 ;; loads from memory only.
5279 (define_insn "*floatunssi<mode>2_1"
5280 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5281 (unsigned_float:X87MODEF
5282 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5283 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5284 (clobber (match_scratch:SI 3 "=X,x"))]
5286 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5289 [(set_attr "type" "multi")
5290 (set_attr "mode" "<MODE>")])
5293 [(set (match_operand:X87MODEF 0 "register_operand" "")
5294 (unsigned_float:X87MODEF
5295 (match_operand:SI 1 "register_operand" "")))
5296 (clobber (match_operand:DI 2 "memory_operand" ""))
5297 (clobber (match_scratch:SI 3 ""))]
5299 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5301 && reload_completed"
5302 [(set (match_dup 2) (match_dup 1))
5304 (float:X87MODEF (match_dup 2)))]
5305 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5308 [(set (match_operand:X87MODEF 0 "register_operand" "")
5309 (unsigned_float:X87MODEF
5310 (match_operand:SI 1 "memory_operand" "")))
5311 (clobber (match_operand:DI 2 "memory_operand" ""))
5312 (clobber (match_scratch:SI 3 ""))]
5314 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5316 && reload_completed"
5317 [(set (match_dup 2) (match_dup 3))
5319 (float:X87MODEF (match_dup 2)))]
5321 emit_move_insn (operands[3], operands[1]);
5322 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5325 (define_expand "floatunssi<mode>2"
5327 [(set (match_operand:X87MODEF 0 "register_operand" "")
5328 (unsigned_float:X87MODEF
5329 (match_operand:SI 1 "nonimmediate_operand" "")))
5330 (clobber (match_dup 2))
5331 (clobber (match_scratch:SI 3 ""))])]
5333 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5335 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5337 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5339 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5344 enum ix86_stack_slot slot = (virtuals_instantiated
5347 operands[2] = assign_386_stack_local (DImode, slot);
5351 (define_expand "floatunsdisf2"
5352 [(use (match_operand:SF 0 "register_operand" ""))
5353 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5354 "TARGET_64BIT && TARGET_SSE_MATH"
5355 "x86_emit_floatuns (operands); DONE;")
5357 (define_expand "floatunsdidf2"
5358 [(use (match_operand:DF 0 "register_operand" ""))
5359 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5360 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5361 && TARGET_SSE2 && TARGET_SSE_MATH"
5364 x86_emit_floatuns (operands);
5366 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5372 (define_expand "add<mode>3"
5373 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5374 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5375 (match_operand:SDWIM 2 "<general_operand>" "")))]
5377 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5379 (define_insn_and_split "*add<dwi>3_doubleword"
5380 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5382 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5383 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5384 (clobber (reg:CC FLAGS_REG))]
5385 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5388 [(parallel [(set (reg:CC FLAGS_REG)
5389 (unspec:CC [(match_dup 1) (match_dup 2)]
5392 (plus:DWIH (match_dup 1) (match_dup 2)))])
5393 (parallel [(set (match_dup 3)
5397 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5399 (clobber (reg:CC FLAGS_REG))])]
5400 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5402 (define_insn "*add<mode>3_cc"
5403 [(set (reg:CC FLAGS_REG)
5405 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5406 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5408 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5409 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5410 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5411 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5412 [(set_attr "type" "alu")
5413 (set_attr "mode" "<MODE>")])
5415 (define_insn "addqi3_cc"
5416 [(set (reg:CC FLAGS_REG)
5418 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5419 (match_operand:QI 2 "general_operand" "qn,qm")]
5421 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5422 (plus:QI (match_dup 1) (match_dup 2)))]
5423 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5424 "add{b}\t{%2, %0|%0, %2}"
5425 [(set_attr "type" "alu")
5426 (set_attr "mode" "QI")])
5428 (define_insn_and_split "*lea_1"
5429 [(set (match_operand:SI 0 "register_operand" "=r")
5430 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5432 "lea{l}\t{%E1, %0|%0, %E1}"
5433 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5436 ix86_split_lea_for_addr (operands, SImode);
5439 [(set_attr "type" "lea")
5440 (set_attr "mode" "SI")])
5442 (define_insn_and_split "*lea<mode>_2"
5443 [(set (match_operand:SWI48 0 "register_operand" "=r")
5444 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5446 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5447 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5450 ix86_split_lea_for_addr (operands, <MODE>mode);
5453 [(set_attr "type" "lea")
5454 (set_attr "mode" "<MODE>")])
5456 (define_insn "*lea_3_zext"
5457 [(set (match_operand:DI 0 "register_operand" "=r")
5459 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5461 "lea{l}\t{%E1, %k0|%k0, %E1}"
5462 [(set_attr "type" "lea")
5463 (set_attr "mode" "SI")])
5465 (define_insn "*lea_4_zext"
5466 [(set (match_operand:DI 0 "register_operand" "=r")
5468 (match_operand:SI 1 "lea_address_operand" "j")))]
5470 "lea{l}\t{%E1, %k0|%k0, %E1}"
5471 [(set_attr "type" "lea")
5472 (set_attr "mode" "SI")])
5474 (define_insn "*lea_5_zext"
5475 [(set (match_operand:DI 0 "register_operand" "=r")
5477 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5478 (match_operand:DI 2 "const_32bit_mask" "n")))]
5480 "lea{l}\t{%E1, %k0|%k0, %E1}"
5481 [(set_attr "type" "lea")
5482 (set_attr "mode" "SI")])
5484 (define_insn "*lea_6_zext"
5485 [(set (match_operand:DI 0 "register_operand" "=r")
5487 (match_operand:DI 1 "lea_address_operand" "p")
5488 (match_operand:DI 2 "const_32bit_mask" "n")))]
5490 "lea{l}\t{%E1, %k0|%k0, %E1}"
5491 [(set_attr "type" "lea")
5492 (set_attr "mode" "SI")])
5494 (define_insn "*add<mode>_1"
5495 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5497 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5498 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5499 (clobber (reg:CC FLAGS_REG))]
5500 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5502 switch (get_attr_type (insn))
5508 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5509 if (operands[2] == const1_rtx)
5510 return "inc{<imodesuffix>}\t%0";
5513 gcc_assert (operands[2] == constm1_rtx);
5514 return "dec{<imodesuffix>}\t%0";
5518 /* For most processors, ADD is faster than LEA. This alternative
5519 was added to use ADD as much as possible. */
5520 if (which_alternative == 2)
5523 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5526 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5527 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5528 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5530 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5534 (cond [(eq_attr "alternative" "3")
5535 (const_string "lea")
5536 (match_operand:SWI48 2 "incdec_operand" "")
5537 (const_string "incdec")
5539 (const_string "alu")))
5540 (set (attr "length_immediate")
5542 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5544 (const_string "*")))
5545 (set_attr "mode" "<MODE>")])
5547 ;; It may seem that nonimmediate operand is proper one for operand 1.
5548 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5549 ;; we take care in ix86_binary_operator_ok to not allow two memory
5550 ;; operands so proper swapping will be done in reload. This allow
5551 ;; patterns constructed from addsi_1 to match.
5553 (define_insn "addsi_1_zext"
5554 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5556 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5557 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5558 (clobber (reg:CC FLAGS_REG))]
5559 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5561 switch (get_attr_type (insn))
5567 if (operands[2] == const1_rtx)
5568 return "inc{l}\t%k0";
5571 gcc_assert (operands[2] == constm1_rtx);
5572 return "dec{l}\t%k0";
5576 /* For most processors, ADD is faster than LEA. This alternative
5577 was added to use ADD as much as possible. */
5578 if (which_alternative == 1)
5581 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5584 if (x86_maybe_negate_const_int (&operands[2], SImode))
5585 return "sub{l}\t{%2, %k0|%k0, %2}";
5587 return "add{l}\t{%2, %k0|%k0, %2}";
5591 (cond [(eq_attr "alternative" "2")
5592 (const_string "lea")
5593 (match_operand:SI 2 "incdec_operand" "")
5594 (const_string "incdec")
5596 (const_string "alu")))
5597 (set (attr "length_immediate")
5599 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5601 (const_string "*")))
5602 (set_attr "mode" "SI")])
5604 (define_insn "*addhi_1"
5605 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5606 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5607 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5608 (clobber (reg:CC FLAGS_REG))]
5609 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5611 switch (get_attr_type (insn))
5617 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5618 if (operands[2] == const1_rtx)
5619 return "inc{w}\t%0";
5622 gcc_assert (operands[2] == constm1_rtx);
5623 return "dec{w}\t%0";
5627 /* For most processors, ADD is faster than LEA. This alternative
5628 was added to use ADD as much as possible. */
5629 if (which_alternative == 2)
5632 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5635 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5636 if (x86_maybe_negate_const_int (&operands[2], HImode))
5637 return "sub{w}\t{%2, %0|%0, %2}";
5639 return "add{w}\t{%2, %0|%0, %2}";
5643 (cond [(eq_attr "alternative" "3")
5644 (const_string "lea")
5645 (match_operand:HI 2 "incdec_operand" "")
5646 (const_string "incdec")
5648 (const_string "alu")))
5649 (set (attr "length_immediate")
5651 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5653 (const_string "*")))
5654 (set_attr "mode" "HI,HI,HI,SI")])
5656 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5657 (define_insn "*addqi_1"
5658 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5659 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5660 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5661 (clobber (reg:CC FLAGS_REG))]
5662 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5664 bool widen = (which_alternative == 3 || which_alternative == 4);
5666 switch (get_attr_type (insn))
5672 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5673 if (operands[2] == const1_rtx)
5674 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5677 gcc_assert (operands[2] == constm1_rtx);
5678 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5682 /* For most processors, ADD is faster than LEA. These alternatives
5683 were added to use ADD as much as possible. */
5684 if (which_alternative == 2 || which_alternative == 4)
5687 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5690 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5691 if (x86_maybe_negate_const_int (&operands[2], QImode))
5694 return "sub{l}\t{%2, %k0|%k0, %2}";
5696 return "sub{b}\t{%2, %0|%0, %2}";
5699 return "add{l}\t{%k2, %k0|%k0, %k2}";
5701 return "add{b}\t{%2, %0|%0, %2}";
5705 (cond [(eq_attr "alternative" "5")
5706 (const_string "lea")
5707 (match_operand:QI 2 "incdec_operand" "")
5708 (const_string "incdec")
5710 (const_string "alu")))
5711 (set (attr "length_immediate")
5713 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5715 (const_string "*")))
5716 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5718 (define_insn "*addqi_1_slp"
5719 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5720 (plus:QI (match_dup 0)
5721 (match_operand:QI 1 "general_operand" "qn,qm")))
5722 (clobber (reg:CC FLAGS_REG))]
5723 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5724 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5726 switch (get_attr_type (insn))
5729 if (operands[1] == const1_rtx)
5730 return "inc{b}\t%0";
5733 gcc_assert (operands[1] == constm1_rtx);
5734 return "dec{b}\t%0";
5738 if (x86_maybe_negate_const_int (&operands[1], QImode))
5739 return "sub{b}\t{%1, %0|%0, %1}";
5741 return "add{b}\t{%1, %0|%0, %1}";
5745 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5746 (const_string "incdec")
5747 (const_string "alu1")))
5748 (set (attr "memory")
5749 (if_then_else (match_operand 1 "memory_operand" "")
5750 (const_string "load")
5751 (const_string "none")))
5752 (set_attr "mode" "QI")])
5754 ;; Split non destructive adds if we cannot use lea.
5756 [(set (match_operand:SWI48 0 "register_operand" "")
5757 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5758 (match_operand:SWI48 2 "nonmemory_operand" "")))
5759 (clobber (reg:CC FLAGS_REG))]
5760 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5761 [(set (match_dup 0) (match_dup 1))
5762 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5763 (clobber (reg:CC FLAGS_REG))])])
5765 ;; Convert add to the lea pattern to avoid flags dependency.
5767 [(set (match_operand:SWI 0 "register_operand" "")
5768 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5769 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5770 (clobber (reg:CC FLAGS_REG))]
5771 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5774 enum machine_mode mode = <MODE>mode;
5777 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5780 operands[0] = gen_lowpart (mode, operands[0]);
5781 operands[1] = gen_lowpart (mode, operands[1]);
5782 operands[2] = gen_lowpart (mode, operands[2]);
5785 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5787 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5791 ;; Convert add to the lea pattern to avoid flags dependency.
5793 [(set (match_operand:DI 0 "register_operand" "")
5795 (plus:SI (match_operand:SI 1 "register_operand" "")
5796 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5797 (clobber (reg:CC FLAGS_REG))]
5798 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5800 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5802 (define_insn "*add<mode>_2"
5803 [(set (reg FLAGS_REG)
5806 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
5807 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
5809 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
5810 (plus:SWI (match_dup 1) (match_dup 2)))]
5811 "ix86_match_ccmode (insn, CCGOCmode)
5812 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5814 switch (get_attr_type (insn))
5817 if (operands[2] == const1_rtx)
5818 return "inc{<imodesuffix>}\t%0";
5821 gcc_assert (operands[2] == constm1_rtx);
5822 return "dec{<imodesuffix>}\t%0";
5826 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5827 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5829 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5833 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5834 (const_string "incdec")
5835 (const_string "alu")))
5836 (set (attr "length_immediate")
5838 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5840 (const_string "*")))
5841 (set_attr "mode" "<MODE>")])
5843 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5844 (define_insn "*addsi_2_zext"
5845 [(set (reg FLAGS_REG)
5847 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
5848 (match_operand:SI 2 "x86_64_general_operand" "rme"))
5850 (set (match_operand:DI 0 "register_operand" "=r")
5851 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5852 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5853 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5855 switch (get_attr_type (insn))
5858 if (operands[2] == const1_rtx)
5859 return "inc{l}\t%k0";
5862 gcc_assert (operands[2] == constm1_rtx);
5863 return "dec{l}\t%k0";
5867 if (x86_maybe_negate_const_int (&operands[2], SImode))
5868 return "sub{l}\t{%2, %k0|%k0, %2}";
5870 return "add{l}\t{%2, %k0|%k0, %2}";
5874 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5875 (const_string "incdec")
5876 (const_string "alu")))
5877 (set (attr "length_immediate")
5879 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5881 (const_string "*")))
5882 (set_attr "mode" "SI")])
5884 (define_insn "*add<mode>_3"
5885 [(set (reg FLAGS_REG)
5887 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>"))
5888 (match_operand:SWI 1 "nonimmediate_operand" "%0")))
5889 (clobber (match_scratch:SWI 0 "=<r>"))]
5890 "ix86_match_ccmode (insn, CCZmode)
5891 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5893 switch (get_attr_type (insn))
5896 if (operands[2] == const1_rtx)
5897 return "inc{<imodesuffix>}\t%0";
5900 gcc_assert (operands[2] == constm1_rtx);
5901 return "dec{<imodesuffix>}\t%0";
5905 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5906 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5908 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5912 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5913 (const_string "incdec")
5914 (const_string "alu")))
5915 (set (attr "length_immediate")
5917 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5919 (const_string "*")))
5920 (set_attr "mode" "<MODE>")])
5922 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5923 (define_insn "*addsi_3_zext"
5924 [(set (reg FLAGS_REG)
5926 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme"))
5927 (match_operand:SI 1 "nonimmediate_operand" "%0")))
5928 (set (match_operand:DI 0 "register_operand" "=r")
5929 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5930 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5931 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5933 switch (get_attr_type (insn))
5936 if (operands[2] == const1_rtx)
5937 return "inc{l}\t%k0";
5940 gcc_assert (operands[2] == constm1_rtx);
5941 return "dec{l}\t%k0";
5945 if (x86_maybe_negate_const_int (&operands[2], SImode))
5946 return "sub{l}\t{%2, %k0|%k0, %2}";
5948 return "add{l}\t{%2, %k0|%k0, %2}";
5952 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5953 (const_string "incdec")
5954 (const_string "alu")))
5955 (set (attr "length_immediate")
5957 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5959 (const_string "*")))
5960 (set_attr "mode" "SI")])
5962 ; For comparisons against 1, -1 and 128, we may generate better code
5963 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5964 ; is matched then. We can't accept general immediate, because for
5965 ; case of overflows, the result is messed up.
5966 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5967 ; only for comparisons not depending on it.
5969 (define_insn "*adddi_4"
5970 [(set (reg FLAGS_REG)
5972 (match_operand:DI 1 "nonimmediate_operand" "0")
5973 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5974 (clobber (match_scratch:DI 0 "=rm"))]
5976 && ix86_match_ccmode (insn, CCGCmode)"
5978 switch (get_attr_type (insn))
5981 if (operands[2] == constm1_rtx)
5982 return "inc{q}\t%0";
5985 gcc_assert (operands[2] == const1_rtx);
5986 return "dec{q}\t%0";
5990 if (x86_maybe_negate_const_int (&operands[2], DImode))
5991 return "add{q}\t{%2, %0|%0, %2}";
5993 return "sub{q}\t{%2, %0|%0, %2}";
5997 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5998 (const_string "incdec")
5999 (const_string "alu")))
6000 (set (attr "length_immediate")
6002 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6004 (const_string "*")))
6005 (set_attr "mode" "DI")])
6007 ; For comparisons against 1, -1 and 128, we may generate better code
6008 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6009 ; is matched then. We can't accept general immediate, because for
6010 ; case of overflows, the result is messed up.
6011 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6012 ; only for comparisons not depending on it.
6014 (define_insn "*add<mode>_4"
6015 [(set (reg FLAGS_REG)
6017 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6018 (match_operand:SWI124 2 "const_int_operand" "n")))
6019 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6020 "ix86_match_ccmode (insn, CCGCmode)"
6022 switch (get_attr_type (insn))
6025 if (operands[2] == constm1_rtx)
6026 return "inc{<imodesuffix>}\t%0";
6029 gcc_assert (operands[2] == const1_rtx);
6030 return "dec{<imodesuffix>}\t%0";
6034 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6035 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6037 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6041 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6042 (const_string "incdec")
6043 (const_string "alu")))
6044 (set (attr "length_immediate")
6046 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6048 (const_string "*")))
6049 (set_attr "mode" "<MODE>")])
6051 (define_insn "*add<mode>_5"
6052 [(set (reg FLAGS_REG)
6055 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6056 (match_operand:SWI 2 "<general_operand>" "<g>"))
6058 (clobber (match_scratch:SWI 0 "=<r>"))]
6059 "ix86_match_ccmode (insn, CCGOCmode)
6060 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6062 switch (get_attr_type (insn))
6065 if (operands[2] == const1_rtx)
6066 return "inc{<imodesuffix>}\t%0";
6069 gcc_assert (operands[2] == constm1_rtx);
6070 return "dec{<imodesuffix>}\t%0";
6074 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6075 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6077 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6081 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6082 (const_string "incdec")
6083 (const_string "alu")))
6084 (set (attr "length_immediate")
6086 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6088 (const_string "*")))
6089 (set_attr "mode" "<MODE>")])
6091 (define_insn "*addqi_ext_1_rex64"
6092 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6097 (match_operand 1 "ext_register_operand" "0")
6100 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6101 (clobber (reg:CC FLAGS_REG))]
6104 switch (get_attr_type (insn))
6107 if (operands[2] == const1_rtx)
6108 return "inc{b}\t%h0";
6111 gcc_assert (operands[2] == constm1_rtx);
6112 return "dec{b}\t%h0";
6116 return "add{b}\t{%2, %h0|%h0, %2}";
6120 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6121 (const_string "incdec")
6122 (const_string "alu")))
6123 (set_attr "modrm" "1")
6124 (set_attr "mode" "QI")])
6126 (define_insn "addqi_ext_1"
6127 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6132 (match_operand 1 "ext_register_operand" "0")
6135 (match_operand:QI 2 "general_operand" "Qmn")))
6136 (clobber (reg:CC FLAGS_REG))]
6139 switch (get_attr_type (insn))
6142 if (operands[2] == const1_rtx)
6143 return "inc{b}\t%h0";
6146 gcc_assert (operands[2] == constm1_rtx);
6147 return "dec{b}\t%h0";
6151 return "add{b}\t{%2, %h0|%h0, %2}";
6155 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6156 (const_string "incdec")
6157 (const_string "alu")))
6158 (set_attr "modrm" "1")
6159 (set_attr "mode" "QI")])
6161 (define_insn "*addqi_ext_2"
6162 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6167 (match_operand 1 "ext_register_operand" "%0")
6171 (match_operand 2 "ext_register_operand" "Q")
6174 (clobber (reg:CC FLAGS_REG))]
6176 "add{b}\t{%h2, %h0|%h0, %h2}"
6177 [(set_attr "type" "alu")
6178 (set_attr "mode" "QI")])
6180 ;; The lea patterns for modes less than 32 bits need to be matched by
6181 ;; several insns converted to real lea by splitters.
6183 (define_insn_and_split "*lea_general_1"
6184 [(set (match_operand 0 "register_operand" "=r")
6185 (plus (plus (match_operand 1 "index_register_operand" "l")
6186 (match_operand 2 "register_operand" "r"))
6187 (match_operand 3 "immediate_operand" "i")))]
6188 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6189 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6190 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6191 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6192 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6193 || GET_MODE (operands[3]) == VOIDmode)"
6195 "&& reload_completed"
6198 enum machine_mode mode = SImode;
6201 operands[0] = gen_lowpart (mode, operands[0]);
6202 operands[1] = gen_lowpart (mode, operands[1]);
6203 operands[2] = gen_lowpart (mode, operands[2]);
6204 operands[3] = gen_lowpart (mode, operands[3]);
6206 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6209 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6212 [(set_attr "type" "lea")
6213 (set_attr "mode" "SI")])
6215 (define_insn_and_split "*lea_general_2"
6216 [(set (match_operand 0 "register_operand" "=r")
6217 (plus (mult (match_operand 1 "index_register_operand" "l")
6218 (match_operand 2 "const248_operand" "n"))
6219 (match_operand 3 "nonmemory_operand" "ri")))]
6220 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6221 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6222 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6223 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6224 || GET_MODE (operands[3]) == VOIDmode)"
6226 "&& reload_completed"
6229 enum machine_mode mode = SImode;
6232 operands[0] = gen_lowpart (mode, operands[0]);
6233 operands[1] = gen_lowpart (mode, operands[1]);
6234 operands[3] = gen_lowpart (mode, operands[3]);
6236 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6239 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6242 [(set_attr "type" "lea")
6243 (set_attr "mode" "SI")])
6245 (define_insn_and_split "*lea_general_3"
6246 [(set (match_operand 0 "register_operand" "=r")
6247 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6248 (match_operand 2 "const248_operand" "n"))
6249 (match_operand 3 "register_operand" "r"))
6250 (match_operand 4 "immediate_operand" "i")))]
6251 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6252 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6253 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6254 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6256 "&& reload_completed"
6259 enum machine_mode mode = SImode;
6262 operands[0] = gen_lowpart (mode, operands[0]);
6263 operands[1] = gen_lowpart (mode, operands[1]);
6264 operands[3] = gen_lowpart (mode, operands[3]);
6265 operands[4] = gen_lowpart (mode, operands[4]);
6267 pat = gen_rtx_PLUS (mode,
6269 gen_rtx_MULT (mode, operands[1],
6274 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6277 [(set_attr "type" "lea")
6278 (set_attr "mode" "SI")])
6280 (define_insn_and_split "*lea_general_4"
6281 [(set (match_operand 0 "register_operand" "=r")
6283 (match_operand 1 "index_register_operand" "l")
6284 (match_operand 2 "const_int_operand" "n"))
6285 (match_operand 3 "const_int_operand" "n")))]
6286 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6287 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6288 || GET_MODE (operands[0]) == SImode
6289 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6290 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6291 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6292 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6293 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6295 "&& reload_completed"
6298 enum machine_mode mode = GET_MODE (operands[0]);
6301 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6304 operands[0] = gen_lowpart (mode, operands[0]);
6305 operands[1] = gen_lowpart (mode, operands[1]);
6308 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6310 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6311 INTVAL (operands[3]));
6313 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6316 [(set_attr "type" "lea")
6318 (if_then_else (match_operand:DI 0 "" "")
6320 (const_string "SI")))])
6322 ;; Subtract instructions
6324 (define_expand "sub<mode>3"
6325 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6326 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6327 (match_operand:SDWIM 2 "<general_operand>" "")))]
6329 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6331 (define_insn_and_split "*sub<dwi>3_doubleword"
6332 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6334 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6335 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6336 (clobber (reg:CC FLAGS_REG))]
6337 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6340 [(parallel [(set (reg:CC FLAGS_REG)
6341 (compare:CC (match_dup 1) (match_dup 2)))
6343 (minus:DWIH (match_dup 1) (match_dup 2)))])
6344 (parallel [(set (match_dup 3)
6348 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6350 (clobber (reg:CC FLAGS_REG))])]
6351 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6353 (define_insn "*sub<mode>_1"
6354 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6356 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6357 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6358 (clobber (reg:CC FLAGS_REG))]
6359 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6360 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6361 [(set_attr "type" "alu")
6362 (set_attr "mode" "<MODE>")])
6364 (define_insn "*subsi_1_zext"
6365 [(set (match_operand:DI 0 "register_operand" "=r")
6367 (minus:SI (match_operand:SI 1 "register_operand" "0")
6368 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6369 (clobber (reg:CC FLAGS_REG))]
6370 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6371 "sub{l}\t{%2, %k0|%k0, %2}"
6372 [(set_attr "type" "alu")
6373 (set_attr "mode" "SI")])
6375 (define_insn "*subqi_1_slp"
6376 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6377 (minus:QI (match_dup 0)
6378 (match_operand:QI 1 "general_operand" "qn,qm")))
6379 (clobber (reg:CC FLAGS_REG))]
6380 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6381 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6382 "sub{b}\t{%1, %0|%0, %1}"
6383 [(set_attr "type" "alu1")
6384 (set_attr "mode" "QI")])
6386 (define_insn "*sub<mode>_2"
6387 [(set (reg FLAGS_REG)
6390 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6391 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6393 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6394 (minus:SWI (match_dup 1) (match_dup 2)))]
6395 "ix86_match_ccmode (insn, CCGOCmode)
6396 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6397 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6398 [(set_attr "type" "alu")
6399 (set_attr "mode" "<MODE>")])
6401 (define_insn "*subsi_2_zext"
6402 [(set (reg FLAGS_REG)
6404 (minus:SI (match_operand:SI 1 "register_operand" "0")
6405 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6407 (set (match_operand:DI 0 "register_operand" "=r")
6409 (minus:SI (match_dup 1)
6411 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6412 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6413 "sub{l}\t{%2, %k0|%k0, %2}"
6414 [(set_attr "type" "alu")
6415 (set_attr "mode" "SI")])
6417 (define_insn "*sub<mode>_3"
6418 [(set (reg FLAGS_REG)
6419 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6420 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6421 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6422 (minus:SWI (match_dup 1) (match_dup 2)))]
6423 "ix86_match_ccmode (insn, CCmode)
6424 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6425 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6426 [(set_attr "type" "alu")
6427 (set_attr "mode" "<MODE>")])
6429 (define_insn "*subsi_3_zext"
6430 [(set (reg FLAGS_REG)
6431 (compare (match_operand:SI 1 "register_operand" "0")
6432 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6433 (set (match_operand:DI 0 "register_operand" "=r")
6435 (minus:SI (match_dup 1)
6437 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6438 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6439 "sub{l}\t{%2, %1|%1, %2}"
6440 [(set_attr "type" "alu")
6441 (set_attr "mode" "SI")])
6443 ;; Add with carry and subtract with borrow
6445 (define_expand "<plusminus_insn><mode>3_carry"
6447 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6449 (match_operand:SWI 1 "nonimmediate_operand" "")
6450 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6451 [(match_operand 3 "flags_reg_operand" "")
6453 (match_operand:SWI 2 "<general_operand>" ""))))
6454 (clobber (reg:CC FLAGS_REG))])]
6455 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6457 (define_insn "*<plusminus_insn><mode>3_carry"
6458 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6460 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6462 (match_operator 3 "ix86_carry_flag_operator"
6463 [(reg FLAGS_REG) (const_int 0)])
6464 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6465 (clobber (reg:CC FLAGS_REG))]
6466 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6467 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6468 [(set_attr "type" "alu")
6469 (set_attr "use_carry" "1")
6470 (set_attr "pent_pair" "pu")
6471 (set_attr "mode" "<MODE>")])
6473 (define_insn "*addsi3_carry_zext"
6474 [(set (match_operand:DI 0 "register_operand" "=r")
6476 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6477 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6478 [(reg FLAGS_REG) (const_int 0)])
6479 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6480 (clobber (reg:CC FLAGS_REG))]
6481 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6482 "adc{l}\t{%2, %k0|%k0, %2}"
6483 [(set_attr "type" "alu")
6484 (set_attr "use_carry" "1")
6485 (set_attr "pent_pair" "pu")
6486 (set_attr "mode" "SI")])
6488 (define_insn "*subsi3_carry_zext"
6489 [(set (match_operand:DI 0 "register_operand" "=r")
6491 (minus:SI (match_operand:SI 1 "register_operand" "0")
6492 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6493 [(reg FLAGS_REG) (const_int 0)])
6494 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6495 (clobber (reg:CC FLAGS_REG))]
6496 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6497 "sbb{l}\t{%2, %k0|%k0, %2}"
6498 [(set_attr "type" "alu")
6499 (set_attr "pent_pair" "pu")
6500 (set_attr "mode" "SI")])
6502 ;; Overflow setting add and subtract instructions
6504 (define_insn "*add<mode>3_cconly_overflow"
6505 [(set (reg:CCC FLAGS_REG)
6508 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6509 (match_operand:SWI 2 "<general_operand>" "<g>"))
6511 (clobber (match_scratch:SWI 0 "=<r>"))]
6512 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6513 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6514 [(set_attr "type" "alu")
6515 (set_attr "mode" "<MODE>")])
6517 (define_insn "*sub<mode>3_cconly_overflow"
6518 [(set (reg:CCC FLAGS_REG)
6521 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6522 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6525 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6526 [(set_attr "type" "icmp")
6527 (set_attr "mode" "<MODE>")])
6529 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6530 [(set (reg:CCC FLAGS_REG)
6533 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6534 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6536 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6537 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6538 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6539 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6540 [(set_attr "type" "alu")
6541 (set_attr "mode" "<MODE>")])
6543 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6544 [(set (reg:CCC FLAGS_REG)
6547 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6548 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6550 (set (match_operand:DI 0 "register_operand" "=r")
6551 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6552 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6553 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6554 [(set_attr "type" "alu")
6555 (set_attr "mode" "SI")])
6557 ;; The patterns that match these are at the end of this file.
6559 (define_expand "<plusminus_insn>xf3"
6560 [(set (match_operand:XF 0 "register_operand" "")
6562 (match_operand:XF 1 "register_operand" "")
6563 (match_operand:XF 2 "register_operand" "")))]
6566 (define_expand "<plusminus_insn><mode>3"
6567 [(set (match_operand:MODEF 0 "register_operand" "")
6569 (match_operand:MODEF 1 "register_operand" "")
6570 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6571 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6572 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6574 ;; Multiply instructions
6576 (define_expand "mul<mode>3"
6577 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6579 (match_operand:SWIM248 1 "register_operand" "")
6580 (match_operand:SWIM248 2 "<general_operand>" "")))
6581 (clobber (reg:CC FLAGS_REG))])])
6583 (define_expand "mulqi3"
6584 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6586 (match_operand:QI 1 "register_operand" "")
6587 (match_operand:QI 2 "nonimmediate_operand" "")))
6588 (clobber (reg:CC FLAGS_REG))])]
6589 "TARGET_QIMODE_MATH")
6592 ;; IMUL reg32/64, reg32/64, imm8 Direct
6593 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6594 ;; IMUL reg32/64, reg32/64, imm32 Direct
6595 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6596 ;; IMUL reg32/64, reg32/64 Direct
6597 ;; IMUL reg32/64, mem32/64 Direct
6599 ;; On BDVER1, all above IMULs use DirectPath
6601 (define_insn "*mul<mode>3_1"
6602 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6604 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6605 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6606 (clobber (reg:CC FLAGS_REG))]
6607 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6609 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6610 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6611 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6612 [(set_attr "type" "imul")
6613 (set_attr "prefix_0f" "0,0,1")
6614 (set (attr "athlon_decode")
6615 (cond [(eq_attr "cpu" "athlon")
6616 (const_string "vector")
6617 (eq_attr "alternative" "1")
6618 (const_string "vector")
6619 (and (eq_attr "alternative" "2")
6620 (match_operand 1 "memory_operand" ""))
6621 (const_string "vector")]
6622 (const_string "direct")))
6623 (set (attr "amdfam10_decode")
6624 (cond [(and (eq_attr "alternative" "0,1")
6625 (match_operand 1 "memory_operand" ""))
6626 (const_string "vector")]
6627 (const_string "direct")))
6628 (set_attr "bdver1_decode" "direct")
6629 (set_attr "mode" "<MODE>")])
6631 (define_insn "*mulsi3_1_zext"
6632 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6634 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6635 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6636 (clobber (reg:CC FLAGS_REG))]
6638 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6640 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6641 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6642 imul{l}\t{%2, %k0|%k0, %2}"
6643 [(set_attr "type" "imul")
6644 (set_attr "prefix_0f" "0,0,1")
6645 (set (attr "athlon_decode")
6646 (cond [(eq_attr "cpu" "athlon")
6647 (const_string "vector")
6648 (eq_attr "alternative" "1")
6649 (const_string "vector")
6650 (and (eq_attr "alternative" "2")
6651 (match_operand 1 "memory_operand" ""))
6652 (const_string "vector")]
6653 (const_string "direct")))
6654 (set (attr "amdfam10_decode")
6655 (cond [(and (eq_attr "alternative" "0,1")
6656 (match_operand 1 "memory_operand" ""))
6657 (const_string "vector")]
6658 (const_string "direct")))
6659 (set_attr "bdver1_decode" "direct")
6660 (set_attr "mode" "SI")])
6663 ;; IMUL reg16, reg16, imm8 VectorPath
6664 ;; IMUL reg16, mem16, imm8 VectorPath
6665 ;; IMUL reg16, reg16, imm16 VectorPath
6666 ;; IMUL reg16, mem16, imm16 VectorPath
6667 ;; IMUL reg16, reg16 Direct
6668 ;; IMUL reg16, mem16 Direct
6670 ;; On BDVER1, all HI MULs use DoublePath
6672 (define_insn "*mulhi3_1"
6673 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6674 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6675 (match_operand:HI 2 "general_operand" "K,n,mr")))
6676 (clobber (reg:CC FLAGS_REG))]
6678 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6680 imul{w}\t{%2, %1, %0|%0, %1, %2}
6681 imul{w}\t{%2, %1, %0|%0, %1, %2}
6682 imul{w}\t{%2, %0|%0, %2}"
6683 [(set_attr "type" "imul")
6684 (set_attr "prefix_0f" "0,0,1")
6685 (set (attr "athlon_decode")
6686 (cond [(eq_attr "cpu" "athlon")
6687 (const_string "vector")
6688 (eq_attr "alternative" "1,2")
6689 (const_string "vector")]
6690 (const_string "direct")))
6691 (set (attr "amdfam10_decode")
6692 (cond [(eq_attr "alternative" "0,1")
6693 (const_string "vector")]
6694 (const_string "direct")))
6695 (set_attr "bdver1_decode" "double")
6696 (set_attr "mode" "HI")])
6698 ;;On AMDFAM10 and BDVER1
6702 (define_insn "*mulqi3_1"
6703 [(set (match_operand:QI 0 "register_operand" "=a")
6704 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6705 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6706 (clobber (reg:CC FLAGS_REG))]
6708 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6710 [(set_attr "type" "imul")
6711 (set_attr "length_immediate" "0")
6712 (set (attr "athlon_decode")
6713 (if_then_else (eq_attr "cpu" "athlon")
6714 (const_string "vector")
6715 (const_string "direct")))
6716 (set_attr "amdfam10_decode" "direct")
6717 (set_attr "bdver1_decode" "direct")
6718 (set_attr "mode" "QI")])
6720 (define_expand "<u>mul<mode><dwi>3"
6721 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6724 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6726 (match_operand:DWIH 2 "register_operand" ""))))
6727 (clobber (reg:CC FLAGS_REG))])])
6729 (define_expand "<u>mulqihi3"
6730 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6733 (match_operand:QI 1 "nonimmediate_operand" ""))
6735 (match_operand:QI 2 "register_operand" ""))))
6736 (clobber (reg:CC FLAGS_REG))])]
6737 "TARGET_QIMODE_MATH")
6739 (define_insn "*bmi2_umulditi3_1"
6740 [(set (match_operand:DI 0 "register_operand" "=r")
6742 (match_operand:DI 2 "nonimmediate_operand" "%d")
6743 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6744 (set (match_operand:DI 1 "register_operand" "=r")
6747 (mult:TI (zero_extend:TI (match_dup 2))
6748 (zero_extend:TI (match_dup 3)))
6750 "TARGET_64BIT && TARGET_BMI2
6751 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6752 "mulx\t{%3, %0, %1|%1, %0, %3}"
6753 [(set_attr "type" "imulx")
6754 (set_attr "prefix" "vex")
6755 (set_attr "mode" "DI")])
6757 (define_insn "*bmi2_umulsidi3_1"
6758 [(set (match_operand:SI 0 "register_operand" "=r")
6760 (match_operand:SI 2 "nonimmediate_operand" "%d")
6761 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6762 (set (match_operand:SI 1 "register_operand" "=r")
6765 (mult:DI (zero_extend:DI (match_dup 2))
6766 (zero_extend:DI (match_dup 3)))
6768 "!TARGET_64BIT && TARGET_BMI2
6769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6770 "mulx\t{%3, %0, %1|%1, %0, %3}"
6771 [(set_attr "type" "imulx")
6772 (set_attr "prefix" "vex")
6773 (set_attr "mode" "SI")])
6775 (define_insn "*umul<mode><dwi>3_1"
6776 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6779 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6781 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6782 (clobber (reg:CC FLAGS_REG))]
6783 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6785 mul{<imodesuffix>}\t%2
6787 [(set_attr "isa" "*,bmi2")
6788 (set_attr "type" "imul,imulx")
6789 (set_attr "length_immediate" "0,*")
6790 (set (attr "athlon_decode")
6791 (cond [(eq_attr "alternative" "0")
6792 (if_then_else (eq_attr "cpu" "athlon")
6793 (const_string "vector")
6794 (const_string "double"))]
6795 (const_string "*")))
6796 (set_attr "amdfam10_decode" "double,*")
6797 (set_attr "bdver1_decode" "direct,*")
6798 (set_attr "prefix" "orig,vex")
6799 (set_attr "mode" "<MODE>")])
6801 ;; Convert mul to the mulx pattern to avoid flags dependency.
6803 [(set (match_operand:<DWI> 0 "register_operand" "")
6806 (match_operand:DWIH 1 "register_operand" ""))
6808 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6809 (clobber (reg:CC FLAGS_REG))]
6810 "TARGET_BMI2 && reload_completed
6811 && true_regnum (operands[1]) == DX_REG"
6812 [(parallel [(set (match_dup 3)
6813 (mult:DWIH (match_dup 1) (match_dup 2)))
6817 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6818 (zero_extend:<DWI> (match_dup 2)))
6821 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6823 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6826 (define_insn "*mul<mode><dwi>3_1"
6827 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6830 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6832 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6833 (clobber (reg:CC FLAGS_REG))]
6834 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6835 "imul{<imodesuffix>}\t%2"
6836 [(set_attr "type" "imul")
6837 (set_attr "length_immediate" "0")
6838 (set (attr "athlon_decode")
6839 (if_then_else (eq_attr "cpu" "athlon")
6840 (const_string "vector")
6841 (const_string "double")))
6842 (set_attr "amdfam10_decode" "double")
6843 (set_attr "bdver1_decode" "direct")
6844 (set_attr "mode" "<MODE>")])
6846 (define_insn "*<u>mulqihi3_1"
6847 [(set (match_operand:HI 0 "register_operand" "=a")
6850 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6852 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6853 (clobber (reg:CC FLAGS_REG))]
6855 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6856 "<sgnprefix>mul{b}\t%2"
6857 [(set_attr "type" "imul")
6858 (set_attr "length_immediate" "0")
6859 (set (attr "athlon_decode")
6860 (if_then_else (eq_attr "cpu" "athlon")
6861 (const_string "vector")
6862 (const_string "direct")))
6863 (set_attr "amdfam10_decode" "direct")
6864 (set_attr "bdver1_decode" "direct")
6865 (set_attr "mode" "QI")])
6867 (define_expand "<s>mul<mode>3_highpart"
6868 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6873 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6875 (match_operand:SWI48 2 "register_operand" "")))
6877 (clobber (match_scratch:SWI48 3 ""))
6878 (clobber (reg:CC FLAGS_REG))])]
6880 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6882 (define_insn "*<s>muldi3_highpart_1"
6883 [(set (match_operand:DI 0 "register_operand" "=d")
6888 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6890 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6892 (clobber (match_scratch:DI 3 "=1"))
6893 (clobber (reg:CC FLAGS_REG))]
6895 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6896 "<sgnprefix>mul{q}\t%2"
6897 [(set_attr "type" "imul")
6898 (set_attr "length_immediate" "0")
6899 (set (attr "athlon_decode")
6900 (if_then_else (eq_attr "cpu" "athlon")
6901 (const_string "vector")
6902 (const_string "double")))
6903 (set_attr "amdfam10_decode" "double")
6904 (set_attr "bdver1_decode" "direct")
6905 (set_attr "mode" "DI")])
6907 (define_insn "*<s>mulsi3_highpart_1"
6908 [(set (match_operand:SI 0 "register_operand" "=d")
6913 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6915 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6917 (clobber (match_scratch:SI 3 "=1"))
6918 (clobber (reg:CC FLAGS_REG))]
6919 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6920 "<sgnprefix>mul{l}\t%2"
6921 [(set_attr "type" "imul")
6922 (set_attr "length_immediate" "0")
6923 (set (attr "athlon_decode")
6924 (if_then_else (eq_attr "cpu" "athlon")
6925 (const_string "vector")
6926 (const_string "double")))
6927 (set_attr "amdfam10_decode" "double")
6928 (set_attr "bdver1_decode" "direct")
6929 (set_attr "mode" "SI")])
6931 (define_insn "*<s>mulsi3_highpart_zext"
6932 [(set (match_operand:DI 0 "register_operand" "=d")
6933 (zero_extend:DI (truncate:SI
6935 (mult:DI (any_extend:DI
6936 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6938 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6940 (clobber (match_scratch:SI 3 "=1"))
6941 (clobber (reg:CC FLAGS_REG))]
6943 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6944 "<sgnprefix>mul{l}\t%2"
6945 [(set_attr "type" "imul")
6946 (set_attr "length_immediate" "0")
6947 (set (attr "athlon_decode")
6948 (if_then_else (eq_attr "cpu" "athlon")
6949 (const_string "vector")
6950 (const_string "double")))
6951 (set_attr "amdfam10_decode" "double")
6952 (set_attr "bdver1_decode" "direct")
6953 (set_attr "mode" "SI")])
6955 ;; The patterns that match these are at the end of this file.
6957 (define_expand "mulxf3"
6958 [(set (match_operand:XF 0 "register_operand" "")
6959 (mult:XF (match_operand:XF 1 "register_operand" "")
6960 (match_operand:XF 2 "register_operand" "")))]
6963 (define_expand "mul<mode>3"
6964 [(set (match_operand:MODEF 0 "register_operand" "")
6965 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6966 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6967 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6968 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6970 ;; Divide instructions
6972 ;; The patterns that match these are at the end of this file.
6974 (define_expand "divxf3"
6975 [(set (match_operand:XF 0 "register_operand" "")
6976 (div:XF (match_operand:XF 1 "register_operand" "")
6977 (match_operand:XF 2 "register_operand" "")))]
6980 (define_expand "divdf3"
6981 [(set (match_operand:DF 0 "register_operand" "")
6982 (div:DF (match_operand:DF 1 "register_operand" "")
6983 (match_operand:DF 2 "nonimmediate_operand" "")))]
6984 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6985 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6987 (define_expand "divsf3"
6988 [(set (match_operand:SF 0 "register_operand" "")
6989 (div:SF (match_operand:SF 1 "register_operand" "")
6990 (match_operand:SF 2 "nonimmediate_operand" "")))]
6991 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6996 && optimize_insn_for_speed_p ()
6997 && flag_finite_math_only && !flag_trapping_math
6998 && flag_unsafe_math_optimizations)
7000 ix86_emit_swdivsf (operands[0], operands[1],
7001 operands[2], SFmode);
7006 ;; Divmod instructions.
7008 (define_expand "divmod<mode>4"
7009 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7011 (match_operand:SWIM248 1 "register_operand" "")
7012 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7013 (set (match_operand:SWIM248 3 "register_operand" "")
7014 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7015 (clobber (reg:CC FLAGS_REG))])])
7017 ;; Split with 8bit unsigned divide:
7018 ;; if (dividend an divisor are in [0-255])
7019 ;; use 8bit unsigned integer divide
7021 ;; use original integer divide
7023 [(set (match_operand:SWI48 0 "register_operand" "")
7024 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7025 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7026 (set (match_operand:SWI48 1 "register_operand" "")
7027 (mod:SWI48 (match_dup 2) (match_dup 3)))
7028 (clobber (reg:CC FLAGS_REG))]
7029 "TARGET_USE_8BIT_IDIV
7030 && TARGET_QIMODE_MATH
7031 && can_create_pseudo_p ()
7032 && !optimize_insn_for_size_p ()"
7034 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7036 (define_insn_and_split "divmod<mode>4_1"
7037 [(set (match_operand:SWI48 0 "register_operand" "=a")
7038 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7039 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7040 (set (match_operand:SWI48 1 "register_operand" "=&d")
7041 (mod:SWI48 (match_dup 2) (match_dup 3)))
7042 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7043 (clobber (reg:CC FLAGS_REG))]
7047 [(parallel [(set (match_dup 1)
7048 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7049 (clobber (reg:CC FLAGS_REG))])
7050 (parallel [(set (match_dup 0)
7051 (div:SWI48 (match_dup 2) (match_dup 3)))
7053 (mod:SWI48 (match_dup 2) (match_dup 3)))
7055 (clobber (reg:CC FLAGS_REG))])]
7057 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7059 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7060 operands[4] = operands[2];
7063 /* Avoid use of cltd in favor of a mov+shift. */
7064 emit_move_insn (operands[1], operands[2]);
7065 operands[4] = operands[1];
7068 [(set_attr "type" "multi")
7069 (set_attr "mode" "<MODE>")])
7071 (define_insn_and_split "*divmod<mode>4"
7072 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7073 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7074 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7075 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7076 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7077 (clobber (reg:CC FLAGS_REG))]
7081 [(parallel [(set (match_dup 1)
7082 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7083 (clobber (reg:CC FLAGS_REG))])
7084 (parallel [(set (match_dup 0)
7085 (div:SWIM248 (match_dup 2) (match_dup 3)))
7087 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7089 (clobber (reg:CC FLAGS_REG))])]
7091 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7093 if (<MODE>mode != HImode
7094 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7095 operands[4] = operands[2];
7098 /* Avoid use of cltd in favor of a mov+shift. */
7099 emit_move_insn (operands[1], operands[2]);
7100 operands[4] = operands[1];
7103 [(set_attr "type" "multi")
7104 (set_attr "mode" "<MODE>")])
7106 (define_insn "*divmod<mode>4_noext"
7107 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7108 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7109 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7110 (set (match_operand:SWIM248 1 "register_operand" "=d")
7111 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7112 (use (match_operand:SWIM248 4 "register_operand" "1"))
7113 (clobber (reg:CC FLAGS_REG))]
7115 "idiv{<imodesuffix>}\t%3"
7116 [(set_attr "type" "idiv")
7117 (set_attr "mode" "<MODE>")])
7119 (define_expand "divmodqi4"
7120 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7122 (match_operand:QI 1 "register_operand" "")
7123 (match_operand:QI 2 "nonimmediate_operand" "")))
7124 (set (match_operand:QI 3 "register_operand" "")
7125 (mod:QI (match_dup 1) (match_dup 2)))
7126 (clobber (reg:CC FLAGS_REG))])]
7127 "TARGET_QIMODE_MATH"
7132 tmp0 = gen_reg_rtx (HImode);
7133 tmp1 = gen_reg_rtx (HImode);
7135 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7137 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7138 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7140 /* Extract remainder from AH. */
7141 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7142 insn = emit_move_insn (operands[3], tmp1);
7144 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7145 set_unique_reg_note (insn, REG_EQUAL, mod);
7147 /* Extract quotient from AL. */
7148 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7150 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7151 set_unique_reg_note (insn, REG_EQUAL, div);
7156 ;; Divide AX by r/m8, with result stored in
7159 ;; Change div/mod to HImode and extend the second argument to HImode
7160 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7161 ;; combine may fail.
7162 (define_insn "divmodhiqi3"
7163 [(set (match_operand:HI 0 "register_operand" "=a")
7168 (mod:HI (match_operand:HI 1 "register_operand" "0")
7170 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7174 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7175 (clobber (reg:CC FLAGS_REG))]
7176 "TARGET_QIMODE_MATH"
7178 [(set_attr "type" "idiv")
7179 (set_attr "mode" "QI")])
7181 (define_expand "udivmod<mode>4"
7182 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7184 (match_operand:SWIM248 1 "register_operand" "")
7185 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7186 (set (match_operand:SWIM248 3 "register_operand" "")
7187 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7188 (clobber (reg:CC FLAGS_REG))])])
7190 ;; Split with 8bit unsigned divide:
7191 ;; if (dividend an divisor are in [0-255])
7192 ;; use 8bit unsigned integer divide
7194 ;; use original integer divide
7196 [(set (match_operand:SWI48 0 "register_operand" "")
7197 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7198 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7199 (set (match_operand:SWI48 1 "register_operand" "")
7200 (umod:SWI48 (match_dup 2) (match_dup 3)))
7201 (clobber (reg:CC FLAGS_REG))]
7202 "TARGET_USE_8BIT_IDIV
7203 && TARGET_QIMODE_MATH
7204 && can_create_pseudo_p ()
7205 && !optimize_insn_for_size_p ()"
7207 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7209 (define_insn_and_split "udivmod<mode>4_1"
7210 [(set (match_operand:SWI48 0 "register_operand" "=a")
7211 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7212 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7213 (set (match_operand:SWI48 1 "register_operand" "=&d")
7214 (umod:SWI48 (match_dup 2) (match_dup 3)))
7215 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7216 (clobber (reg:CC FLAGS_REG))]
7220 [(set (match_dup 1) (const_int 0))
7221 (parallel [(set (match_dup 0)
7222 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7224 (umod:SWI48 (match_dup 2) (match_dup 3)))
7226 (clobber (reg:CC FLAGS_REG))])]
7228 [(set_attr "type" "multi")
7229 (set_attr "mode" "<MODE>")])
7231 (define_insn_and_split "*udivmod<mode>4"
7232 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7233 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7234 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7235 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7236 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7237 (clobber (reg:CC FLAGS_REG))]
7241 [(set (match_dup 1) (const_int 0))
7242 (parallel [(set (match_dup 0)
7243 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7245 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7247 (clobber (reg:CC FLAGS_REG))])]
7249 [(set_attr "type" "multi")
7250 (set_attr "mode" "<MODE>")])
7252 (define_insn "*udivmod<mode>4_noext"
7253 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7254 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7255 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7256 (set (match_operand:SWIM248 1 "register_operand" "=d")
7257 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7258 (use (match_operand:SWIM248 4 "register_operand" "1"))
7259 (clobber (reg:CC FLAGS_REG))]
7261 "div{<imodesuffix>}\t%3"
7262 [(set_attr "type" "idiv")
7263 (set_attr "mode" "<MODE>")])
7265 (define_expand "udivmodqi4"
7266 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7268 (match_operand:QI 1 "register_operand" "")
7269 (match_operand:QI 2 "nonimmediate_operand" "")))
7270 (set (match_operand:QI 3 "register_operand" "")
7271 (umod:QI (match_dup 1) (match_dup 2)))
7272 (clobber (reg:CC FLAGS_REG))])]
7273 "TARGET_QIMODE_MATH"
7278 tmp0 = gen_reg_rtx (HImode);
7279 tmp1 = gen_reg_rtx (HImode);
7281 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7283 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7284 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7286 /* Extract remainder from AH. */
7287 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7288 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7289 insn = emit_move_insn (operands[3], tmp1);
7291 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7292 set_unique_reg_note (insn, REG_EQUAL, mod);
7294 /* Extract quotient from AL. */
7295 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7297 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7298 set_unique_reg_note (insn, REG_EQUAL, div);
7303 (define_insn "udivmodhiqi3"
7304 [(set (match_operand:HI 0 "register_operand" "=a")
7309 (mod:HI (match_operand:HI 1 "register_operand" "0")
7311 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7315 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7316 (clobber (reg:CC FLAGS_REG))]
7317 "TARGET_QIMODE_MATH"
7319 [(set_attr "type" "idiv")
7320 (set_attr "mode" "QI")])
7322 ;; We cannot use div/idiv for double division, because it causes
7323 ;; "division by zero" on the overflow and that's not what we expect
7324 ;; from truncate. Because true (non truncating) double division is
7325 ;; never generated, we can't create this insn anyway.
7328 ; [(set (match_operand:SI 0 "register_operand" "=a")
7330 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7332 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7333 ; (set (match_operand:SI 3 "register_operand" "=d")
7335 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7336 ; (clobber (reg:CC FLAGS_REG))]
7338 ; "div{l}\t{%2, %0|%0, %2}"
7339 ; [(set_attr "type" "idiv")])
7341 ;;- Logical AND instructions
7343 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7344 ;; Note that this excludes ah.
7346 (define_expand "testsi_ccno_1"
7347 [(set (reg:CCNO FLAGS_REG)
7349 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7350 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7353 (define_expand "testqi_ccz_1"
7354 [(set (reg:CCZ FLAGS_REG)
7355 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7356 (match_operand:QI 1 "nonmemory_operand" ""))
7359 (define_expand "testdi_ccno_1"
7360 [(set (reg:CCNO FLAGS_REG)
7362 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7363 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7365 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7367 (define_insn "*testdi_1"
7368 [(set (reg FLAGS_REG)
7371 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7372 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7374 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7375 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7377 test{l}\t{%k1, %k0|%k0, %k1}
7378 test{l}\t{%k1, %k0|%k0, %k1}
7379 test{q}\t{%1, %0|%0, %1}
7380 test{q}\t{%1, %0|%0, %1}
7381 test{q}\t{%1, %0|%0, %1}"
7382 [(set_attr "type" "test")
7383 (set_attr "modrm" "0,1,0,1,1")
7384 (set_attr "mode" "SI,SI,DI,DI,DI")])
7386 (define_insn "*testqi_1_maybe_si"
7387 [(set (reg FLAGS_REG)
7390 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7391 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7393 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7394 && ix86_match_ccmode (insn,
7395 CONST_INT_P (operands[1])
7396 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7398 if (which_alternative == 3)
7400 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7401 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7402 return "test{l}\t{%1, %k0|%k0, %1}";
7404 return "test{b}\t{%1, %0|%0, %1}";
7406 [(set_attr "type" "test")
7407 (set_attr "modrm" "0,1,1,1")
7408 (set_attr "mode" "QI,QI,QI,SI")
7409 (set_attr "pent_pair" "uv,np,uv,np")])
7411 (define_insn "*test<mode>_1"
7412 [(set (reg FLAGS_REG)
7415 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7416 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7418 "ix86_match_ccmode (insn, CCNOmode)
7419 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7420 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7421 [(set_attr "type" "test")
7422 (set_attr "modrm" "0,1,1")
7423 (set_attr "mode" "<MODE>")
7424 (set_attr "pent_pair" "uv,np,uv")])
7426 (define_expand "testqi_ext_ccno_0"
7427 [(set (reg:CCNO FLAGS_REG)
7431 (match_operand 0 "ext_register_operand" "")
7434 (match_operand 1 "const_int_operand" ""))
7437 (define_insn "*testqi_ext_0"
7438 [(set (reg FLAGS_REG)
7442 (match_operand 0 "ext_register_operand" "Q")
7445 (match_operand 1 "const_int_operand" "n"))
7447 "ix86_match_ccmode (insn, CCNOmode)"
7448 "test{b}\t{%1, %h0|%h0, %1}"
7449 [(set_attr "type" "test")
7450 (set_attr "mode" "QI")
7451 (set_attr "length_immediate" "1")
7452 (set_attr "modrm" "1")
7453 (set_attr "pent_pair" "np")])
7455 (define_insn "*testqi_ext_1_rex64"
7456 [(set (reg FLAGS_REG)
7460 (match_operand 0 "ext_register_operand" "Q")
7464 (match_operand:QI 1 "register_operand" "Q")))
7466 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7467 "test{b}\t{%1, %h0|%h0, %1}"
7468 [(set_attr "type" "test")
7469 (set_attr "mode" "QI")])
7471 (define_insn "*testqi_ext_1"
7472 [(set (reg FLAGS_REG)
7476 (match_operand 0 "ext_register_operand" "Q")
7480 (match_operand:QI 1 "general_operand" "Qm")))
7482 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7483 "test{b}\t{%1, %h0|%h0, %1}"
7484 [(set_attr "type" "test")
7485 (set_attr "mode" "QI")])
7487 (define_insn "*testqi_ext_2"
7488 [(set (reg FLAGS_REG)
7492 (match_operand 0 "ext_register_operand" "Q")
7496 (match_operand 1 "ext_register_operand" "Q")
7500 "ix86_match_ccmode (insn, CCNOmode)"
7501 "test{b}\t{%h1, %h0|%h0, %h1}"
7502 [(set_attr "type" "test")
7503 (set_attr "mode" "QI")])
7505 (define_insn "*testqi_ext_3_rex64"
7506 [(set (reg FLAGS_REG)
7507 (compare (zero_extract:DI
7508 (match_operand 0 "nonimmediate_operand" "rm")
7509 (match_operand:DI 1 "const_int_operand" "")
7510 (match_operand:DI 2 "const_int_operand" ""))
7513 && ix86_match_ccmode (insn, CCNOmode)
7514 && INTVAL (operands[1]) > 0
7515 && INTVAL (operands[2]) >= 0
7516 /* Ensure that resulting mask is zero or sign extended operand. */
7517 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7518 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7519 && INTVAL (operands[1]) > 32))
7520 && (GET_MODE (operands[0]) == SImode
7521 || GET_MODE (operands[0]) == DImode
7522 || GET_MODE (operands[0]) == HImode
7523 || GET_MODE (operands[0]) == QImode)"
7526 ;; Combine likes to form bit extractions for some tests. Humor it.
7527 (define_insn "*testqi_ext_3"
7528 [(set (reg FLAGS_REG)
7529 (compare (zero_extract:SI
7530 (match_operand 0 "nonimmediate_operand" "rm")
7531 (match_operand:SI 1 "const_int_operand" "")
7532 (match_operand:SI 2 "const_int_operand" ""))
7534 "ix86_match_ccmode (insn, CCNOmode)
7535 && INTVAL (operands[1]) > 0
7536 && INTVAL (operands[2]) >= 0
7537 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7538 && (GET_MODE (operands[0]) == SImode
7539 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7540 || GET_MODE (operands[0]) == HImode
7541 || GET_MODE (operands[0]) == QImode)"
7545 [(set (match_operand 0 "flags_reg_operand" "")
7546 (match_operator 1 "compare_operator"
7548 (match_operand 2 "nonimmediate_operand" "")
7549 (match_operand 3 "const_int_operand" "")
7550 (match_operand 4 "const_int_operand" ""))
7552 "ix86_match_ccmode (insn, CCNOmode)"
7553 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7555 rtx val = operands[2];
7556 HOST_WIDE_INT len = INTVAL (operands[3]);
7557 HOST_WIDE_INT pos = INTVAL (operands[4]);
7559 enum machine_mode mode, submode;
7561 mode = GET_MODE (val);
7564 /* ??? Combine likes to put non-volatile mem extractions in QImode
7565 no matter the size of the test. So find a mode that works. */
7566 if (! MEM_VOLATILE_P (val))
7568 mode = smallest_mode_for_size (pos + len, MODE_INT);
7569 val = adjust_address (val, mode, 0);
7572 else if (GET_CODE (val) == SUBREG
7573 && (submode = GET_MODE (SUBREG_REG (val)),
7574 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7575 && pos + len <= GET_MODE_BITSIZE (submode)
7576 && GET_MODE_CLASS (submode) == MODE_INT)
7578 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7580 val = SUBREG_REG (val);
7582 else if (mode == HImode && pos + len <= 8)
7584 /* Small HImode tests can be converted to QImode. */
7586 val = gen_lowpart (QImode, val);
7589 if (len == HOST_BITS_PER_WIDE_INT)
7592 mask = ((HOST_WIDE_INT)1 << len) - 1;
7595 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7598 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7599 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7600 ;; this is relatively important trick.
7601 ;; Do the conversion only post-reload to avoid limiting of the register class
7604 [(set (match_operand 0 "flags_reg_operand" "")
7605 (match_operator 1 "compare_operator"
7606 [(and (match_operand 2 "register_operand" "")
7607 (match_operand 3 "const_int_operand" ""))
7610 && QI_REG_P (operands[2])
7611 && GET_MODE (operands[2]) != QImode
7612 && ((ix86_match_ccmode (insn, CCZmode)
7613 && !(INTVAL (operands[3]) & ~(255 << 8)))
7614 || (ix86_match_ccmode (insn, CCNOmode)
7615 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7618 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7622 operands[2] = gen_lowpart (SImode, operands[2]);
7623 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7627 [(set (match_operand 0 "flags_reg_operand" "")
7628 (match_operator 1 "compare_operator"
7629 [(and (match_operand 2 "nonimmediate_operand" "")
7630 (match_operand 3 "const_int_operand" ""))
7633 && GET_MODE (operands[2]) != QImode
7634 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7635 && ((ix86_match_ccmode (insn, CCZmode)
7636 && !(INTVAL (operands[3]) & ~255))
7637 || (ix86_match_ccmode (insn, CCNOmode)
7638 && !(INTVAL (operands[3]) & ~127)))"
7640 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7643 operands[2] = gen_lowpart (QImode, operands[2]);
7644 operands[3] = gen_lowpart (QImode, operands[3]);
7647 ;; %%% This used to optimize known byte-wide and operations to memory,
7648 ;; and sometimes to QImode registers. If this is considered useful,
7649 ;; it should be done with splitters.
7651 (define_expand "and<mode>3"
7652 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7653 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7654 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7656 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
7658 (define_insn "*anddi_1"
7659 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7661 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7662 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7663 (clobber (reg:CC FLAGS_REG))]
7664 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7666 switch (get_attr_type (insn))
7672 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7673 if (get_attr_mode (insn) == MODE_SI)
7674 return "and{l}\t{%k2, %k0|%k0, %k2}";
7676 return "and{q}\t{%2, %0|%0, %2}";
7679 [(set_attr "type" "alu,alu,alu,imovx")
7680 (set_attr "length_immediate" "*,*,*,0")
7681 (set (attr "prefix_rex")
7683 (and (eq_attr "type" "imovx")
7684 (and (match_test "INTVAL (operands[2]) == 0xff")
7685 (match_operand 1 "ext_QIreg_operand" "")))
7687 (const_string "*")))
7688 (set_attr "mode" "SI,DI,DI,SI")])
7690 (define_insn "*andsi_1"
7691 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,Ya")
7692 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7693 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7694 (clobber (reg:CC FLAGS_REG))]
7695 "ix86_binary_operator_ok (AND, SImode, operands)"
7697 switch (get_attr_type (insn))
7703 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7704 return "and{l}\t{%2, %0|%0, %2}";
7707 [(set_attr "type" "alu,alu,imovx")
7708 (set (attr "prefix_rex")
7710 (and (eq_attr "type" "imovx")
7711 (and (match_test "INTVAL (operands[2]) == 0xff")
7712 (match_operand 1 "ext_QIreg_operand" "")))
7714 (const_string "*")))
7715 (set_attr "length_immediate" "*,*,0")
7716 (set_attr "mode" "SI")])
7718 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7719 (define_insn "*andsi_1_zext"
7720 [(set (match_operand:DI 0 "register_operand" "=r")
7722 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7723 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7724 (clobber (reg:CC FLAGS_REG))]
7725 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7726 "and{l}\t{%2, %k0|%k0, %2}"
7727 [(set_attr "type" "alu")
7728 (set_attr "mode" "SI")])
7730 (define_insn "*andhi_1"
7731 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,Ya")
7732 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7733 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7734 (clobber (reg:CC FLAGS_REG))]
7735 "ix86_binary_operator_ok (AND, HImode, operands)"
7737 switch (get_attr_type (insn))
7743 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7744 return "and{w}\t{%2, %0|%0, %2}";
7747 [(set_attr "type" "alu,alu,imovx")
7748 (set_attr "length_immediate" "*,*,0")
7749 (set (attr "prefix_rex")
7751 (and (eq_attr "type" "imovx")
7752 (match_operand 1 "ext_QIreg_operand" ""))
7754 (const_string "*")))
7755 (set_attr "mode" "HI,HI,SI")])
7757 ;; %%% Potential partial reg stall on alternative 2. What to do?
7758 (define_insn "*andqi_1"
7759 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7760 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7761 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7762 (clobber (reg:CC FLAGS_REG))]
7763 "ix86_binary_operator_ok (AND, QImode, operands)"
7765 and{b}\t{%2, %0|%0, %2}
7766 and{b}\t{%2, %0|%0, %2}
7767 and{l}\t{%k2, %k0|%k0, %k2}"
7768 [(set_attr "type" "alu")
7769 (set_attr "mode" "QI,QI,SI")])
7771 (define_insn "*andqi_1_slp"
7772 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7773 (and:QI (match_dup 0)
7774 (match_operand:QI 1 "general_operand" "qn,qmn")))
7775 (clobber (reg:CC FLAGS_REG))]
7776 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7777 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7778 "and{b}\t{%1, %0|%0, %1}"
7779 [(set_attr "type" "alu1")
7780 (set_attr "mode" "QI")])
7783 [(set (match_operand:SWI248 0 "register_operand" "")
7784 (and:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "")
7785 (match_operand:SWI248 2 "const_int_operand" "")))
7786 (clobber (reg:CC FLAGS_REG))]
7788 && true_regnum (operands[0]) != true_regnum (operands[1])"
7791 enum machine_mode mode;
7793 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7795 else if (INTVAL (operands[2]) == 0xffff)
7799 gcc_assert (INTVAL (operands[2]) == 0xff);
7803 operands[1] = gen_lowpart (mode, operands[1]);
7806 emit_insn (gen_zero_extendsidi2 (operands[0], operands[1]));
7809 rtx (*insn) (rtx, rtx);
7811 /* Zero extend to SImode to avoid partial register stalls. */
7812 operands[0] = gen_lowpart (SImode, operands[0]);
7814 insn = (mode == HImode) ? gen_zero_extendhisi2 : gen_zero_extendqisi2;
7815 emit_insn (insn (operands[0], operands[1]));
7821 [(set (match_operand 0 "register_operand" "")
7823 (const_int -65536)))
7824 (clobber (reg:CC FLAGS_REG))]
7825 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7826 || optimize_function_for_size_p (cfun)"
7827 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7828 "operands[1] = gen_lowpart (HImode, operands[0]);")
7831 [(set (match_operand 0 "ext_register_operand" "")
7834 (clobber (reg:CC FLAGS_REG))]
7835 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7836 && reload_completed"
7837 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7838 "operands[1] = gen_lowpart (QImode, operands[0]);")
7841 [(set (match_operand 0 "ext_register_operand" "")
7843 (const_int -65281)))
7844 (clobber (reg:CC FLAGS_REG))]
7845 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7846 && reload_completed"
7847 [(parallel [(set (zero_extract:SI (match_dup 0)
7851 (zero_extract:SI (match_dup 0)
7854 (zero_extract:SI (match_dup 0)
7857 (clobber (reg:CC FLAGS_REG))])]
7858 "operands[0] = gen_lowpart (SImode, operands[0]);")
7860 (define_insn "*anddi_2"
7861 [(set (reg FLAGS_REG)
7864 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7865 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7867 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7868 (and:DI (match_dup 1) (match_dup 2)))]
7869 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7870 && ix86_binary_operator_ok (AND, DImode, operands)"
7872 and{l}\t{%k2, %k0|%k0, %k2}
7873 and{q}\t{%2, %0|%0, %2}
7874 and{q}\t{%2, %0|%0, %2}"
7875 [(set_attr "type" "alu")
7876 (set_attr "mode" "SI,DI,DI")])
7878 (define_insn "*andqi_2_maybe_si"
7879 [(set (reg FLAGS_REG)
7881 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7882 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7884 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7885 (and:QI (match_dup 1) (match_dup 2)))]
7886 "ix86_binary_operator_ok (AND, QImode, operands)
7887 && ix86_match_ccmode (insn,
7888 CONST_INT_P (operands[2])
7889 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7891 if (which_alternative == 2)
7893 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7894 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7895 return "and{l}\t{%2, %k0|%k0, %2}";
7897 return "and{b}\t{%2, %0|%0, %2}";
7899 [(set_attr "type" "alu")
7900 (set_attr "mode" "QI,QI,SI")])
7902 (define_insn "*and<mode>_2"
7903 [(set (reg FLAGS_REG)
7904 (compare (and:SWI124
7905 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7906 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7908 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7909 (and:SWI124 (match_dup 1) (match_dup 2)))]
7910 "ix86_match_ccmode (insn, CCNOmode)
7911 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7912 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7913 [(set_attr "type" "alu")
7914 (set_attr "mode" "<MODE>")])
7916 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7917 (define_insn "*andsi_2_zext"
7918 [(set (reg FLAGS_REG)
7920 (match_operand:SI 1 "nonimmediate_operand" "%0")
7921 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7923 (set (match_operand:DI 0 "register_operand" "=r")
7924 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7925 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7926 && ix86_binary_operator_ok (AND, SImode, operands)"
7927 "and{l}\t{%2, %k0|%k0, %2}"
7928 [(set_attr "type" "alu")
7929 (set_attr "mode" "SI")])
7931 (define_insn "*andqi_2_slp"
7932 [(set (reg FLAGS_REG)
7934 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7935 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7937 (set (strict_low_part (match_dup 0))
7938 (and:QI (match_dup 0) (match_dup 1)))]
7939 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7940 && ix86_match_ccmode (insn, CCNOmode)
7941 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7942 "and{b}\t{%1, %0|%0, %1}"
7943 [(set_attr "type" "alu1")
7944 (set_attr "mode" "QI")])
7946 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7947 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7948 ;; for a QImode operand, which of course failed.
7949 (define_insn "andqi_ext_0"
7950 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7955 (match_operand 1 "ext_register_operand" "0")
7958 (match_operand 2 "const_int_operand" "n")))
7959 (clobber (reg:CC FLAGS_REG))]
7961 "and{b}\t{%2, %h0|%h0, %2}"
7962 [(set_attr "type" "alu")
7963 (set_attr "length_immediate" "1")
7964 (set_attr "modrm" "1")
7965 (set_attr "mode" "QI")])
7967 ;; Generated by peephole translating test to and. This shows up
7968 ;; often in fp comparisons.
7969 (define_insn "*andqi_ext_0_cc"
7970 [(set (reg FLAGS_REG)
7974 (match_operand 1 "ext_register_operand" "0")
7977 (match_operand 2 "const_int_operand" "n"))
7979 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7988 "ix86_match_ccmode (insn, CCNOmode)"
7989 "and{b}\t{%2, %h0|%h0, %2}"
7990 [(set_attr "type" "alu")
7991 (set_attr "length_immediate" "1")
7992 (set_attr "modrm" "1")
7993 (set_attr "mode" "QI")])
7995 (define_insn "*andqi_ext_1_rex64"
7996 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8001 (match_operand 1 "ext_register_operand" "0")
8005 (match_operand 2 "ext_register_operand" "Q"))))
8006 (clobber (reg:CC FLAGS_REG))]
8008 "and{b}\t{%2, %h0|%h0, %2}"
8009 [(set_attr "type" "alu")
8010 (set_attr "length_immediate" "0")
8011 (set_attr "mode" "QI")])
8013 (define_insn "*andqi_ext_1"
8014 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8019 (match_operand 1 "ext_register_operand" "0")
8023 (match_operand:QI 2 "general_operand" "Qm"))))
8024 (clobber (reg:CC FLAGS_REG))]
8026 "and{b}\t{%2, %h0|%h0, %2}"
8027 [(set_attr "type" "alu")
8028 (set_attr "length_immediate" "0")
8029 (set_attr "mode" "QI")])
8031 (define_insn "*andqi_ext_2"
8032 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8037 (match_operand 1 "ext_register_operand" "%0")
8041 (match_operand 2 "ext_register_operand" "Q")
8044 (clobber (reg:CC FLAGS_REG))]
8046 "and{b}\t{%h2, %h0|%h0, %h2}"
8047 [(set_attr "type" "alu")
8048 (set_attr "length_immediate" "0")
8049 (set_attr "mode" "QI")])
8051 ;; Convert wide AND instructions with immediate operand to shorter QImode
8052 ;; equivalents when possible.
8053 ;; Don't do the splitting with memory operands, since it introduces risk
8054 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8055 ;; for size, but that can (should?) be handled by generic code instead.
8057 [(set (match_operand 0 "register_operand" "")
8058 (and (match_operand 1 "register_operand" "")
8059 (match_operand 2 "const_int_operand" "")))
8060 (clobber (reg:CC FLAGS_REG))]
8062 && QI_REG_P (operands[0])
8063 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8064 && !(~INTVAL (operands[2]) & ~(255 << 8))
8065 && GET_MODE (operands[0]) != QImode"
8066 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8067 (and:SI (zero_extract:SI (match_dup 1)
8068 (const_int 8) (const_int 8))
8070 (clobber (reg:CC FLAGS_REG))])]
8072 operands[0] = gen_lowpart (SImode, operands[0]);
8073 operands[1] = gen_lowpart (SImode, operands[1]);
8074 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8077 ;; Since AND can be encoded with sign extended immediate, this is only
8078 ;; profitable when 7th bit is not set.
8080 [(set (match_operand 0 "register_operand" "")
8081 (and (match_operand 1 "general_operand" "")
8082 (match_operand 2 "const_int_operand" "")))
8083 (clobber (reg:CC FLAGS_REG))]
8085 && ANY_QI_REG_P (operands[0])
8086 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8087 && !(~INTVAL (operands[2]) & ~255)
8088 && !(INTVAL (operands[2]) & 128)
8089 && GET_MODE (operands[0]) != QImode"
8090 [(parallel [(set (strict_low_part (match_dup 0))
8091 (and:QI (match_dup 1)
8093 (clobber (reg:CC FLAGS_REG))])]
8095 operands[0] = gen_lowpart (QImode, operands[0]);
8096 operands[1] = gen_lowpart (QImode, operands[1]);
8097 operands[2] = gen_lowpart (QImode, operands[2]);
8100 ;; Logical inclusive and exclusive OR instructions
8102 ;; %%% This used to optimize known byte-wide and operations to memory.
8103 ;; If this is considered useful, it should be done with splitters.
8105 (define_expand "<code><mode>3"
8106 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8107 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8108 (match_operand:SWIM 2 "<general_operand>" "")))]
8110 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8112 (define_insn "*<code><mode>_1"
8113 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8115 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8116 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8117 (clobber (reg:CC FLAGS_REG))]
8118 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8119 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8120 [(set_attr "type" "alu")
8121 (set_attr "mode" "<MODE>")])
8123 ;; %%% Potential partial reg stall on alternative 2. What to do?
8124 (define_insn "*<code>qi_1"
8125 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8126 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8127 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8128 (clobber (reg:CC FLAGS_REG))]
8129 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8131 <logic>{b}\t{%2, %0|%0, %2}
8132 <logic>{b}\t{%2, %0|%0, %2}
8133 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8134 [(set_attr "type" "alu")
8135 (set_attr "mode" "QI,QI,SI")])
8137 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8138 (define_insn "*<code>si_1_zext"
8139 [(set (match_operand:DI 0 "register_operand" "=r")
8141 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8142 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8143 (clobber (reg:CC FLAGS_REG))]
8144 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8145 "<logic>{l}\t{%2, %k0|%k0, %2}"
8146 [(set_attr "type" "alu")
8147 (set_attr "mode" "SI")])
8149 (define_insn "*<code>si_1_zext_imm"
8150 [(set (match_operand:DI 0 "register_operand" "=r")
8152 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8153 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8154 (clobber (reg:CC FLAGS_REG))]
8155 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8156 "<logic>{l}\t{%2, %k0|%k0, %2}"
8157 [(set_attr "type" "alu")
8158 (set_attr "mode" "SI")])
8160 (define_insn "*<code>qi_1_slp"
8161 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8162 (any_or:QI (match_dup 0)
8163 (match_operand:QI 1 "general_operand" "qmn,qn")))
8164 (clobber (reg:CC FLAGS_REG))]
8165 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8166 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8167 "<logic>{b}\t{%1, %0|%0, %1}"
8168 [(set_attr "type" "alu1")
8169 (set_attr "mode" "QI")])
8171 (define_insn "*<code><mode>_2"
8172 [(set (reg FLAGS_REG)
8173 (compare (any_or:SWI
8174 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8175 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8177 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8178 (any_or:SWI (match_dup 1) (match_dup 2)))]
8179 "ix86_match_ccmode (insn, CCNOmode)
8180 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8181 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8182 [(set_attr "type" "alu")
8183 (set_attr "mode" "<MODE>")])
8185 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8186 ;; ??? Special case for immediate operand is missing - it is tricky.
8187 (define_insn "*<code>si_2_zext"
8188 [(set (reg FLAGS_REG)
8189 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8190 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8192 (set (match_operand:DI 0 "register_operand" "=r")
8193 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8194 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8195 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8196 "<logic>{l}\t{%2, %k0|%k0, %2}"
8197 [(set_attr "type" "alu")
8198 (set_attr "mode" "SI")])
8200 (define_insn "*<code>si_2_zext_imm"
8201 [(set (reg FLAGS_REG)
8203 (match_operand:SI 1 "nonimmediate_operand" "%0")
8204 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8206 (set (match_operand:DI 0 "register_operand" "=r")
8207 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8208 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8209 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8210 "<logic>{l}\t{%2, %k0|%k0, %2}"
8211 [(set_attr "type" "alu")
8212 (set_attr "mode" "SI")])
8214 (define_insn "*<code>qi_2_slp"
8215 [(set (reg FLAGS_REG)
8216 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8217 (match_operand:QI 1 "general_operand" "qmn,qn"))
8219 (set (strict_low_part (match_dup 0))
8220 (any_or:QI (match_dup 0) (match_dup 1)))]
8221 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8222 && ix86_match_ccmode (insn, CCNOmode)
8223 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8224 "<logic>{b}\t{%1, %0|%0, %1}"
8225 [(set_attr "type" "alu1")
8226 (set_attr "mode" "QI")])
8228 (define_insn "*<code><mode>_3"
8229 [(set (reg FLAGS_REG)
8230 (compare (any_or:SWI
8231 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8232 (match_operand:SWI 2 "<general_operand>" "<g>"))
8234 (clobber (match_scratch:SWI 0 "=<r>"))]
8235 "ix86_match_ccmode (insn, CCNOmode)
8236 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8237 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8238 [(set_attr "type" "alu")
8239 (set_attr "mode" "<MODE>")])
8241 (define_insn "*<code>qi_ext_0"
8242 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8247 (match_operand 1 "ext_register_operand" "0")
8250 (match_operand 2 "const_int_operand" "n")))
8251 (clobber (reg:CC FLAGS_REG))]
8252 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8253 "<logic>{b}\t{%2, %h0|%h0, %2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "length_immediate" "1")
8256 (set_attr "modrm" "1")
8257 (set_attr "mode" "QI")])
8259 (define_insn "*<code>qi_ext_1_rex64"
8260 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8265 (match_operand 1 "ext_register_operand" "0")
8269 (match_operand 2 "ext_register_operand" "Q"))))
8270 (clobber (reg:CC FLAGS_REG))]
8272 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8273 "<logic>{b}\t{%2, %h0|%h0, %2}"
8274 [(set_attr "type" "alu")
8275 (set_attr "length_immediate" "0")
8276 (set_attr "mode" "QI")])
8278 (define_insn "*<code>qi_ext_1"
8279 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8284 (match_operand 1 "ext_register_operand" "0")
8288 (match_operand:QI 2 "general_operand" "Qm"))))
8289 (clobber (reg:CC FLAGS_REG))]
8291 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8292 "<logic>{b}\t{%2, %h0|%h0, %2}"
8293 [(set_attr "type" "alu")
8294 (set_attr "length_immediate" "0")
8295 (set_attr "mode" "QI")])
8297 (define_insn "*<code>qi_ext_2"
8298 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8302 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8305 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8308 (clobber (reg:CC FLAGS_REG))]
8309 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8310 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8311 [(set_attr "type" "alu")
8312 (set_attr "length_immediate" "0")
8313 (set_attr "mode" "QI")])
8316 [(set (match_operand 0 "register_operand" "")
8317 (any_or (match_operand 1 "register_operand" "")
8318 (match_operand 2 "const_int_operand" "")))
8319 (clobber (reg:CC FLAGS_REG))]
8321 && QI_REG_P (operands[0])
8322 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8323 && !(INTVAL (operands[2]) & ~(255 << 8))
8324 && GET_MODE (operands[0]) != QImode"
8325 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8326 (any_or:SI (zero_extract:SI (match_dup 1)
8327 (const_int 8) (const_int 8))
8329 (clobber (reg:CC FLAGS_REG))])]
8331 operands[0] = gen_lowpart (SImode, operands[0]);
8332 operands[1] = gen_lowpart (SImode, operands[1]);
8333 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8336 ;; Since OR can be encoded with sign extended immediate, this is only
8337 ;; profitable when 7th bit is set.
8339 [(set (match_operand 0 "register_operand" "")
8340 (any_or (match_operand 1 "general_operand" "")
8341 (match_operand 2 "const_int_operand" "")))
8342 (clobber (reg:CC FLAGS_REG))]
8344 && ANY_QI_REG_P (operands[0])
8345 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8346 && !(INTVAL (operands[2]) & ~255)
8347 && (INTVAL (operands[2]) & 128)
8348 && GET_MODE (operands[0]) != QImode"
8349 [(parallel [(set (strict_low_part (match_dup 0))
8350 (any_or:QI (match_dup 1)
8352 (clobber (reg:CC FLAGS_REG))])]
8354 operands[0] = gen_lowpart (QImode, operands[0]);
8355 operands[1] = gen_lowpart (QImode, operands[1]);
8356 operands[2] = gen_lowpart (QImode, operands[2]);
8359 (define_expand "xorqi_cc_ext_1"
8361 (set (reg:CCNO FLAGS_REG)
8365 (match_operand 1 "ext_register_operand" "")
8368 (match_operand:QI 2 "general_operand" ""))
8370 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8380 (define_insn "*xorqi_cc_ext_1_rex64"
8381 [(set (reg FLAGS_REG)
8385 (match_operand 1 "ext_register_operand" "0")
8388 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8390 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8399 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8400 "xor{b}\t{%2, %h0|%h0, %2}"
8401 [(set_attr "type" "alu")
8402 (set_attr "modrm" "1")
8403 (set_attr "mode" "QI")])
8405 (define_insn "*xorqi_cc_ext_1"
8406 [(set (reg FLAGS_REG)
8410 (match_operand 1 "ext_register_operand" "0")
8413 (match_operand:QI 2 "general_operand" "qmn"))
8415 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8424 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8425 "xor{b}\t{%2, %h0|%h0, %2}"
8426 [(set_attr "type" "alu")
8427 (set_attr "modrm" "1")
8428 (set_attr "mode" "QI")])
8430 ;; Negation instructions
8432 (define_expand "neg<mode>2"
8433 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8434 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8436 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8438 (define_insn_and_split "*neg<dwi>2_doubleword"
8439 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8440 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8441 (clobber (reg:CC FLAGS_REG))]
8442 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8446 [(set (reg:CCZ FLAGS_REG)
8447 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8448 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8451 (plus:DWIH (match_dup 3)
8452 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8454 (clobber (reg:CC FLAGS_REG))])
8457 (neg:DWIH (match_dup 2)))
8458 (clobber (reg:CC FLAGS_REG))])]
8459 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8461 (define_insn "*neg<mode>2_1"
8462 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8463 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8464 (clobber (reg:CC FLAGS_REG))]
8465 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8466 "neg{<imodesuffix>}\t%0"
8467 [(set_attr "type" "negnot")
8468 (set_attr "mode" "<MODE>")])
8470 ;; Combine is quite creative about this pattern.
8471 (define_insn "*negsi2_1_zext"
8472 [(set (match_operand:DI 0 "register_operand" "=r")
8474 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8477 (clobber (reg:CC FLAGS_REG))]
8478 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8480 [(set_attr "type" "negnot")
8481 (set_attr "mode" "SI")])
8483 ;; The problem with neg is that it does not perform (compare x 0),
8484 ;; it really performs (compare 0 x), which leaves us with the zero
8485 ;; flag being the only useful item.
8487 (define_insn "*neg<mode>2_cmpz"
8488 [(set (reg:CCZ FLAGS_REG)
8490 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8492 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8493 (neg:SWI (match_dup 1)))]
8494 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8495 "neg{<imodesuffix>}\t%0"
8496 [(set_attr "type" "negnot")
8497 (set_attr "mode" "<MODE>")])
8499 (define_insn "*negsi2_cmpz_zext"
8500 [(set (reg:CCZ FLAGS_REG)
8504 (match_operand:DI 1 "register_operand" "0")
8508 (set (match_operand:DI 0 "register_operand" "=r")
8509 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8512 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8514 [(set_attr "type" "negnot")
8515 (set_attr "mode" "SI")])
8517 ;; Changing of sign for FP values is doable using integer unit too.
8519 (define_expand "<code><mode>2"
8520 [(set (match_operand:X87MODEF 0 "register_operand" "")
8521 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8522 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8523 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8525 (define_insn "*absneg<mode>2_mixed"
8526 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8527 (match_operator:MODEF 3 "absneg_operator"
8528 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8529 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8530 (clobber (reg:CC FLAGS_REG))]
8531 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8534 (define_insn "*absneg<mode>2_sse"
8535 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8536 (match_operator:MODEF 3 "absneg_operator"
8537 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8538 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8539 (clobber (reg:CC FLAGS_REG))]
8540 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8543 (define_insn "*absneg<mode>2_i387"
8544 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8545 (match_operator:X87MODEF 3 "absneg_operator"
8546 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8547 (use (match_operand 2 "" ""))
8548 (clobber (reg:CC FLAGS_REG))]
8549 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8552 (define_expand "<code>tf2"
8553 [(set (match_operand:TF 0 "register_operand" "")
8554 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8556 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8558 (define_insn "*absnegtf2_sse"
8559 [(set (match_operand:TF 0 "register_operand" "=x,x")
8560 (match_operator:TF 3 "absneg_operator"
8561 [(match_operand:TF 1 "register_operand" "0,x")]))
8562 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8563 (clobber (reg:CC FLAGS_REG))]
8567 ;; Splitters for fp abs and neg.
8570 [(set (match_operand 0 "fp_register_operand" "")
8571 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8572 (use (match_operand 2 "" ""))
8573 (clobber (reg:CC FLAGS_REG))]
8575 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8578 [(set (match_operand 0 "register_operand" "")
8579 (match_operator 3 "absneg_operator"
8580 [(match_operand 1 "register_operand" "")]))
8581 (use (match_operand 2 "nonimmediate_operand" ""))
8582 (clobber (reg:CC FLAGS_REG))]
8583 "reload_completed && SSE_REG_P (operands[0])"
8584 [(set (match_dup 0) (match_dup 3))]
8586 enum machine_mode mode = GET_MODE (operands[0]);
8587 enum machine_mode vmode = GET_MODE (operands[2]);
8590 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8591 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8592 if (operands_match_p (operands[0], operands[2]))
8595 operands[1] = operands[2];
8598 if (GET_CODE (operands[3]) == ABS)
8599 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8601 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8606 [(set (match_operand:SF 0 "register_operand" "")
8607 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8608 (use (match_operand:V4SF 2 "" ""))
8609 (clobber (reg:CC FLAGS_REG))]
8611 [(parallel [(set (match_dup 0) (match_dup 1))
8612 (clobber (reg:CC FLAGS_REG))])]
8615 operands[0] = gen_lowpart (SImode, operands[0]);
8616 if (GET_CODE (operands[1]) == ABS)
8618 tmp = gen_int_mode (0x7fffffff, SImode);
8619 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8623 tmp = gen_int_mode (0x80000000, SImode);
8624 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8630 [(set (match_operand:DF 0 "register_operand" "")
8631 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8632 (use (match_operand 2 "" ""))
8633 (clobber (reg:CC FLAGS_REG))]
8635 [(parallel [(set (match_dup 0) (match_dup 1))
8636 (clobber (reg:CC FLAGS_REG))])]
8641 tmp = gen_lowpart (DImode, operands[0]);
8642 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8645 if (GET_CODE (operands[1]) == ABS)
8648 tmp = gen_rtx_NOT (DImode, tmp);
8652 operands[0] = gen_highpart (SImode, operands[0]);
8653 if (GET_CODE (operands[1]) == ABS)
8655 tmp = gen_int_mode (0x7fffffff, SImode);
8656 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8660 tmp = gen_int_mode (0x80000000, SImode);
8661 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8668 [(set (match_operand:XF 0 "register_operand" "")
8669 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8670 (use (match_operand 2 "" ""))
8671 (clobber (reg:CC FLAGS_REG))]
8673 [(parallel [(set (match_dup 0) (match_dup 1))
8674 (clobber (reg:CC FLAGS_REG))])]
8677 operands[0] = gen_rtx_REG (SImode,
8678 true_regnum (operands[0])
8679 + (TARGET_64BIT ? 1 : 2));
8680 if (GET_CODE (operands[1]) == ABS)
8682 tmp = GEN_INT (0x7fff);
8683 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8687 tmp = GEN_INT (0x8000);
8688 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8693 ;; Conditionalize these after reload. If they match before reload, we
8694 ;; lose the clobber and ability to use integer instructions.
8696 (define_insn "*<code><mode>2_1"
8697 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8698 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8700 && (reload_completed
8701 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8702 "f<absneg_mnemonic>"
8703 [(set_attr "type" "fsgn")
8704 (set_attr "mode" "<MODE>")])
8706 (define_insn "*<code>extendsfdf2"
8707 [(set (match_operand:DF 0 "register_operand" "=f")
8708 (absneg:DF (float_extend:DF
8709 (match_operand:SF 1 "register_operand" "0"))))]
8710 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8711 "f<absneg_mnemonic>"
8712 [(set_attr "type" "fsgn")
8713 (set_attr "mode" "DF")])
8715 (define_insn "*<code>extendsfxf2"
8716 [(set (match_operand:XF 0 "register_operand" "=f")
8717 (absneg:XF (float_extend:XF
8718 (match_operand:SF 1 "register_operand" "0"))))]
8720 "f<absneg_mnemonic>"
8721 [(set_attr "type" "fsgn")
8722 (set_attr "mode" "XF")])
8724 (define_insn "*<code>extenddfxf2"
8725 [(set (match_operand:XF 0 "register_operand" "=f")
8726 (absneg:XF (float_extend:XF
8727 (match_operand:DF 1 "register_operand" "0"))))]
8729 "f<absneg_mnemonic>"
8730 [(set_attr "type" "fsgn")
8731 (set_attr "mode" "XF")])
8733 ;; Copysign instructions
8735 (define_mode_iterator CSGNMODE [SF DF TF])
8736 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8738 (define_expand "copysign<mode>3"
8739 [(match_operand:CSGNMODE 0 "register_operand" "")
8740 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8741 (match_operand:CSGNMODE 2 "register_operand" "")]
8742 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8743 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8744 "ix86_expand_copysign (operands); DONE;")
8746 (define_insn_and_split "copysign<mode>3_const"
8747 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8749 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8750 (match_operand:CSGNMODE 2 "register_operand" "0")
8751 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8753 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8754 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8756 "&& reload_completed"
8758 "ix86_split_copysign_const (operands); DONE;")
8760 (define_insn "copysign<mode>3_var"
8761 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8763 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8764 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8765 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8766 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8768 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8769 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8770 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8774 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8776 [(match_operand:CSGNMODE 2 "register_operand" "")
8777 (match_operand:CSGNMODE 3 "register_operand" "")
8778 (match_operand:<CSGNVMODE> 4 "" "")
8779 (match_operand:<CSGNVMODE> 5 "" "")]
8781 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8782 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8783 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8784 && reload_completed"
8786 "ix86_split_copysign_var (operands); DONE;")
8788 ;; One complement instructions
8790 (define_expand "one_cmpl<mode>2"
8791 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8792 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8794 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8796 (define_insn "*one_cmpl<mode>2_1"
8797 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8798 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8799 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8800 "not{<imodesuffix>}\t%0"
8801 [(set_attr "type" "negnot")
8802 (set_attr "mode" "<MODE>")])
8804 ;; %%% Potential partial reg stall on alternative 1. What to do?
8805 (define_insn "*one_cmplqi2_1"
8806 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8807 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8808 "ix86_unary_operator_ok (NOT, QImode, operands)"
8812 [(set_attr "type" "negnot")
8813 (set_attr "mode" "QI,SI")])
8815 ;; ??? Currently never generated - xor is used instead.
8816 (define_insn "*one_cmplsi2_1_zext"
8817 [(set (match_operand:DI 0 "register_operand" "=r")
8819 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8820 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8822 [(set_attr "type" "negnot")
8823 (set_attr "mode" "SI")])
8825 (define_insn "*one_cmpl<mode>2_2"
8826 [(set (reg FLAGS_REG)
8827 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8829 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8830 (not:SWI (match_dup 1)))]
8831 "ix86_match_ccmode (insn, CCNOmode)
8832 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8834 [(set_attr "type" "alu1")
8835 (set_attr "mode" "<MODE>")])
8838 [(set (match_operand 0 "flags_reg_operand" "")
8839 (match_operator 2 "compare_operator"
8840 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8842 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8843 (not:SWI (match_dup 3)))]
8844 "ix86_match_ccmode (insn, CCNOmode)"
8845 [(parallel [(set (match_dup 0)
8846 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8849 (xor:SWI (match_dup 3) (const_int -1)))])])
8851 ;; ??? Currently never generated - xor is used instead.
8852 (define_insn "*one_cmplsi2_2_zext"
8853 [(set (reg FLAGS_REG)
8854 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8856 (set (match_operand:DI 0 "register_operand" "=r")
8857 (zero_extend:DI (not:SI (match_dup 1))))]
8858 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8859 && ix86_unary_operator_ok (NOT, SImode, operands)"
8861 [(set_attr "type" "alu1")
8862 (set_attr "mode" "SI")])
8865 [(set (match_operand 0 "flags_reg_operand" "")
8866 (match_operator 2 "compare_operator"
8867 [(not:SI (match_operand:SI 3 "register_operand" ""))
8869 (set (match_operand:DI 1 "register_operand" "")
8870 (zero_extend:DI (not:SI (match_dup 3))))]
8871 "ix86_match_ccmode (insn, CCNOmode)"
8872 [(parallel [(set (match_dup 0)
8873 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8876 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8878 ;; Shift instructions
8880 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8881 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8882 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8883 ;; from the assembler input.
8885 ;; This instruction shifts the target reg/mem as usual, but instead of
8886 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8887 ;; is a left shift double, bits are taken from the high order bits of
8888 ;; reg, else if the insn is a shift right double, bits are taken from the
8889 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8890 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8892 ;; Since sh[lr]d does not change the `reg' operand, that is done
8893 ;; separately, making all shifts emit pairs of shift double and normal
8894 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8895 ;; support a 63 bit shift, each shift where the count is in a reg expands
8896 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8898 ;; If the shift count is a constant, we need never emit more than one
8899 ;; shift pair, instead using moves and sign extension for counts greater
8902 (define_expand "ashl<mode>3"
8903 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8904 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8905 (match_operand:QI 2 "nonmemory_operand" "")))]
8907 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8909 (define_insn "*ashl<mode>3_doubleword"
8910 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8911 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8912 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8913 (clobber (reg:CC FLAGS_REG))]
8916 [(set_attr "type" "multi")])
8919 [(set (match_operand:DWI 0 "register_operand" "")
8920 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8921 (match_operand:QI 2 "nonmemory_operand" "")))
8922 (clobber (reg:CC FLAGS_REG))]
8923 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8925 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8927 ;; By default we don't ask for a scratch register, because when DWImode
8928 ;; values are manipulated, registers are already at a premium. But if
8929 ;; we have one handy, we won't turn it away.
8932 [(match_scratch:DWIH 3 "r")
8933 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8935 (match_operand:<DWI> 1 "nonmemory_operand" "")
8936 (match_operand:QI 2 "nonmemory_operand" "")))
8937 (clobber (reg:CC FLAGS_REG))])
8941 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8943 (define_insn "x86_64_shld"
8944 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8945 (ior:DI (ashift:DI (match_dup 0)
8946 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8947 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8948 (minus:QI (const_int 64) (match_dup 2)))))
8949 (clobber (reg:CC FLAGS_REG))]
8951 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8952 [(set_attr "type" "ishift")
8953 (set_attr "prefix_0f" "1")
8954 (set_attr "mode" "DI")
8955 (set_attr "athlon_decode" "vector")
8956 (set_attr "amdfam10_decode" "vector")
8957 (set_attr "bdver1_decode" "vector")])
8959 (define_insn "x86_shld"
8960 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8961 (ior:SI (ashift:SI (match_dup 0)
8962 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8963 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8964 (minus:QI (const_int 32) (match_dup 2)))))
8965 (clobber (reg:CC FLAGS_REG))]
8967 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8968 [(set_attr "type" "ishift")
8969 (set_attr "prefix_0f" "1")
8970 (set_attr "mode" "SI")
8971 (set_attr "pent_pair" "np")
8972 (set_attr "athlon_decode" "vector")
8973 (set_attr "amdfam10_decode" "vector")
8974 (set_attr "bdver1_decode" "vector")])
8976 (define_expand "x86_shift<mode>_adj_1"
8977 [(set (reg:CCZ FLAGS_REG)
8978 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8981 (set (match_operand:SWI48 0 "register_operand" "")
8982 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8983 (match_operand:SWI48 1 "register_operand" "")
8986 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8987 (match_operand:SWI48 3 "register_operand" "")
8990 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
8992 (define_expand "x86_shift<mode>_adj_2"
8993 [(use (match_operand:SWI48 0 "register_operand" ""))
8994 (use (match_operand:SWI48 1 "register_operand" ""))
8995 (use (match_operand:QI 2 "register_operand" ""))]
8998 rtx label = gen_label_rtx ();
9001 emit_insn (gen_testqi_ccz_1 (operands[2],
9002 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9004 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9005 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9006 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9007 gen_rtx_LABEL_REF (VOIDmode, label),
9009 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9010 JUMP_LABEL (tmp) = label;
9012 emit_move_insn (operands[0], operands[1]);
9013 ix86_expand_clear (operands[1]);
9016 LABEL_NUSES (label) = 1;
9021 ;; Avoid useless masking of count operand.
9022 (define_insn_and_split "*ashl<mode>3_mask"
9023 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9025 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9028 (match_operand:SI 2 "nonimmediate_operand" "c")
9029 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9030 (clobber (reg:CC FLAGS_REG))]
9031 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9032 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9033 == GET_MODE_BITSIZE (<MODE>mode)-1"
9036 [(parallel [(set (match_dup 0)
9037 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9038 (clobber (reg:CC FLAGS_REG))])]
9040 if (can_create_pseudo_p ())
9041 operands [2] = force_reg (SImode, operands[2]);
9043 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9045 [(set_attr "type" "ishift")
9046 (set_attr "mode" "<MODE>")])
9048 (define_insn "*bmi2_ashl<mode>3_1"
9049 [(set (match_operand:SWI48 0 "register_operand" "=r")
9050 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9051 (match_operand:SWI48 2 "register_operand" "r")))]
9053 "shlx\t{%2, %1, %0|%0, %1, %2}"
9054 [(set_attr "type" "ishiftx")
9055 (set_attr "mode" "<MODE>")])
9057 (define_insn "*ashl<mode>3_1"
9058 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9059 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9060 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9061 (clobber (reg:CC FLAGS_REG))]
9062 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9064 switch (get_attr_type (insn))
9071 gcc_assert (operands[2] == const1_rtx);
9072 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9073 return "add{<imodesuffix>}\t%0, %0";
9076 if (operands[2] == const1_rtx
9077 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9078 return "sal{<imodesuffix>}\t%0";
9080 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9083 [(set_attr "isa" "*,*,bmi2")
9085 (cond [(eq_attr "alternative" "1")
9086 (const_string "lea")
9087 (eq_attr "alternative" "2")
9088 (const_string "ishiftx")
9089 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9090 (match_operand 0 "register_operand" ""))
9091 (match_operand 2 "const1_operand" ""))
9092 (const_string "alu")
9094 (const_string "ishift")))
9095 (set (attr "length_immediate")
9097 (ior (eq_attr "type" "alu")
9098 (and (eq_attr "type" "ishift")
9099 (and (match_operand 2 "const1_operand" "")
9100 (ior (match_test "TARGET_SHIFT1")
9101 (match_test "optimize_function_for_size_p (cfun)")))))
9103 (const_string "*")))
9104 (set_attr "mode" "<MODE>")])
9106 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9108 [(set (match_operand:SWI48 0 "register_operand" "")
9109 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9110 (match_operand:QI 2 "register_operand" "")))
9111 (clobber (reg:CC FLAGS_REG))]
9112 "TARGET_BMI2 && reload_completed"
9114 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9115 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9117 (define_insn "*bmi2_ashlsi3_1_zext"
9118 [(set (match_operand:DI 0 "register_operand" "=r")
9120 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9121 (match_operand:SI 2 "register_operand" "r"))))]
9122 "TARGET_64BIT && TARGET_BMI2"
9123 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9124 [(set_attr "type" "ishiftx")
9125 (set_attr "mode" "SI")])
9127 (define_insn "*ashlsi3_1_zext"
9128 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9130 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9131 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9132 (clobber (reg:CC FLAGS_REG))]
9133 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9135 switch (get_attr_type (insn))
9142 gcc_assert (operands[2] == const1_rtx);
9143 return "add{l}\t%k0, %k0";
9146 if (operands[2] == const1_rtx
9147 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9148 return "sal{l}\t%k0";
9150 return "sal{l}\t{%2, %k0|%k0, %2}";
9153 [(set_attr "isa" "*,*,bmi2")
9155 (cond [(eq_attr "alternative" "1")
9156 (const_string "lea")
9157 (eq_attr "alternative" "2")
9158 (const_string "ishiftx")
9159 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9160 (match_operand 2 "const1_operand" ""))
9161 (const_string "alu")
9163 (const_string "ishift")))
9164 (set (attr "length_immediate")
9166 (ior (eq_attr "type" "alu")
9167 (and (eq_attr "type" "ishift")
9168 (and (match_operand 2 "const1_operand" "")
9169 (ior (match_test "TARGET_SHIFT1")
9170 (match_test "optimize_function_for_size_p (cfun)")))))
9172 (const_string "*")))
9173 (set_attr "mode" "SI")])
9175 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9177 [(set (match_operand:DI 0 "register_operand" "")
9179 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9180 (match_operand:QI 2 "register_operand" ""))))
9181 (clobber (reg:CC FLAGS_REG))]
9182 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9184 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9185 "operands[2] = gen_lowpart (SImode, operands[2]);")
9187 (define_insn "*ashlhi3_1"
9188 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9189 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9190 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9191 (clobber (reg:CC FLAGS_REG))]
9192 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9194 switch (get_attr_type (insn))
9200 gcc_assert (operands[2] == const1_rtx);
9201 return "add{w}\t%0, %0";
9204 if (operands[2] == const1_rtx
9205 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9206 return "sal{w}\t%0";
9208 return "sal{w}\t{%2, %0|%0, %2}";
9212 (cond [(eq_attr "alternative" "1")
9213 (const_string "lea")
9214 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9215 (match_operand 0 "register_operand" ""))
9216 (match_operand 2 "const1_operand" ""))
9217 (const_string "alu")
9219 (const_string "ishift")))
9220 (set (attr "length_immediate")
9222 (ior (eq_attr "type" "alu")
9223 (and (eq_attr "type" "ishift")
9224 (and (match_operand 2 "const1_operand" "")
9225 (ior (match_test "TARGET_SHIFT1")
9226 (match_test "optimize_function_for_size_p (cfun)")))))
9228 (const_string "*")))
9229 (set_attr "mode" "HI,SI")])
9231 ;; %%% Potential partial reg stall on alternative 1. What to do?
9232 (define_insn "*ashlqi3_1"
9233 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9234 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9235 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9236 (clobber (reg:CC FLAGS_REG))]
9237 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9239 switch (get_attr_type (insn))
9245 gcc_assert (operands[2] == const1_rtx);
9246 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9247 return "add{l}\t%k0, %k0";
9249 return "add{b}\t%0, %0";
9252 if (operands[2] == const1_rtx
9253 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9255 if (get_attr_mode (insn) == MODE_SI)
9256 return "sal{l}\t%k0";
9258 return "sal{b}\t%0";
9262 if (get_attr_mode (insn) == MODE_SI)
9263 return "sal{l}\t{%2, %k0|%k0, %2}";
9265 return "sal{b}\t{%2, %0|%0, %2}";
9270 (cond [(eq_attr "alternative" "2")
9271 (const_string "lea")
9272 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9273 (match_operand 0 "register_operand" ""))
9274 (match_operand 2 "const1_operand" ""))
9275 (const_string "alu")
9277 (const_string "ishift")))
9278 (set (attr "length_immediate")
9280 (ior (eq_attr "type" "alu")
9281 (and (eq_attr "type" "ishift")
9282 (and (match_operand 2 "const1_operand" "")
9283 (ior (match_test "TARGET_SHIFT1")
9284 (match_test "optimize_function_for_size_p (cfun)")))))
9286 (const_string "*")))
9287 (set_attr "mode" "QI,SI,SI")])
9289 (define_insn "*ashlqi3_1_slp"
9290 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9291 (ashift:QI (match_dup 0)
9292 (match_operand:QI 1 "nonmemory_operand" "cI")))
9293 (clobber (reg:CC FLAGS_REG))]
9294 "(optimize_function_for_size_p (cfun)
9295 || !TARGET_PARTIAL_FLAG_REG_STALL
9296 || (operands[1] == const1_rtx
9298 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9300 switch (get_attr_type (insn))
9303 gcc_assert (operands[1] == const1_rtx);
9304 return "add{b}\t%0, %0";
9307 if (operands[1] == const1_rtx
9308 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9309 return "sal{b}\t%0";
9311 return "sal{b}\t{%1, %0|%0, %1}";
9315 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9316 (match_operand 0 "register_operand" ""))
9317 (match_operand 1 "const1_operand" ""))
9318 (const_string "alu")
9320 (const_string "ishift1")))
9321 (set (attr "length_immediate")
9323 (ior (eq_attr "type" "alu")
9324 (and (eq_attr "type" "ishift1")
9325 (and (match_operand 1 "const1_operand" "")
9326 (ior (match_test "TARGET_SHIFT1")
9327 (match_test "optimize_function_for_size_p (cfun)")))))
9329 (const_string "*")))
9330 (set_attr "mode" "QI")])
9332 ;; Convert ashift to the lea pattern to avoid flags dependency.
9334 [(set (match_operand 0 "register_operand" "")
9335 (ashift (match_operand 1 "index_register_operand" "")
9336 (match_operand:QI 2 "const_int_operand" "")))
9337 (clobber (reg:CC FLAGS_REG))]
9338 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9340 && true_regnum (operands[0]) != true_regnum (operands[1])"
9343 enum machine_mode mode = GET_MODE (operands[0]);
9346 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9349 operands[0] = gen_lowpart (mode, operands[0]);
9350 operands[1] = gen_lowpart (mode, operands[1]);
9353 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9355 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9357 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9361 ;; Convert ashift to the lea pattern to avoid flags dependency.
9363 [(set (match_operand:DI 0 "register_operand" "")
9365 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9366 (match_operand:QI 2 "const_int_operand" ""))))
9367 (clobber (reg:CC FLAGS_REG))]
9368 "TARGET_64BIT && reload_completed
9369 && true_regnum (operands[0]) != true_regnum (operands[1])"
9371 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9373 operands[1] = gen_lowpart (DImode, operands[1]);
9374 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9377 ;; This pattern can't accept a variable shift count, since shifts by
9378 ;; zero don't affect the flags. We assume that shifts by constant
9379 ;; zero are optimized away.
9380 (define_insn "*ashl<mode>3_cmp"
9381 [(set (reg FLAGS_REG)
9383 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9384 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9386 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9387 (ashift:SWI (match_dup 1) (match_dup 2)))]
9388 "(optimize_function_for_size_p (cfun)
9389 || !TARGET_PARTIAL_FLAG_REG_STALL
9390 || (operands[2] == const1_rtx
9392 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9393 && ix86_match_ccmode (insn, CCGOCmode)
9394 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9396 switch (get_attr_type (insn))
9399 gcc_assert (operands[2] == const1_rtx);
9400 return "add{<imodesuffix>}\t%0, %0";
9403 if (operands[2] == const1_rtx
9404 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9405 return "sal{<imodesuffix>}\t%0";
9407 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9411 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9412 (match_operand 0 "register_operand" ""))
9413 (match_operand 2 "const1_operand" ""))
9414 (const_string "alu")
9416 (const_string "ishift")))
9417 (set (attr "length_immediate")
9419 (ior (eq_attr "type" "alu")
9420 (and (eq_attr "type" "ishift")
9421 (and (match_operand 2 "const1_operand" "")
9422 (ior (match_test "TARGET_SHIFT1")
9423 (match_test "optimize_function_for_size_p (cfun)")))))
9425 (const_string "*")))
9426 (set_attr "mode" "<MODE>")])
9428 (define_insn "*ashlsi3_cmp_zext"
9429 [(set (reg FLAGS_REG)
9431 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9432 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9434 (set (match_operand:DI 0 "register_operand" "=r")
9435 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9437 && (optimize_function_for_size_p (cfun)
9438 || !TARGET_PARTIAL_FLAG_REG_STALL
9439 || (operands[2] == const1_rtx
9441 || TARGET_DOUBLE_WITH_ADD)))
9442 && ix86_match_ccmode (insn, CCGOCmode)
9443 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9445 switch (get_attr_type (insn))
9448 gcc_assert (operands[2] == const1_rtx);
9449 return "add{l}\t%k0, %k0";
9452 if (operands[2] == const1_rtx
9453 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9454 return "sal{l}\t%k0";
9456 return "sal{l}\t{%2, %k0|%k0, %2}";
9460 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9461 (match_operand 2 "const1_operand" ""))
9462 (const_string "alu")
9464 (const_string "ishift")))
9465 (set (attr "length_immediate")
9467 (ior (eq_attr "type" "alu")
9468 (and (eq_attr "type" "ishift")
9469 (and (match_operand 2 "const1_operand" "")
9470 (ior (match_test "TARGET_SHIFT1")
9471 (match_test "optimize_function_for_size_p (cfun)")))))
9473 (const_string "*")))
9474 (set_attr "mode" "SI")])
9476 (define_insn "*ashl<mode>3_cconly"
9477 [(set (reg FLAGS_REG)
9479 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9480 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9482 (clobber (match_scratch:SWI 0 "=<r>"))]
9483 "(optimize_function_for_size_p (cfun)
9484 || !TARGET_PARTIAL_FLAG_REG_STALL
9485 || (operands[2] == const1_rtx
9487 || TARGET_DOUBLE_WITH_ADD)))
9488 && ix86_match_ccmode (insn, CCGOCmode)"
9490 switch (get_attr_type (insn))
9493 gcc_assert (operands[2] == const1_rtx);
9494 return "add{<imodesuffix>}\t%0, %0";
9497 if (operands[2] == const1_rtx
9498 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9499 return "sal{<imodesuffix>}\t%0";
9501 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9505 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9506 (match_operand 0 "register_operand" ""))
9507 (match_operand 2 "const1_operand" ""))
9508 (const_string "alu")
9510 (const_string "ishift")))
9511 (set (attr "length_immediate")
9513 (ior (eq_attr "type" "alu")
9514 (and (eq_attr "type" "ishift")
9515 (and (match_operand 2 "const1_operand" "")
9516 (ior (match_test "TARGET_SHIFT1")
9517 (match_test "optimize_function_for_size_p (cfun)")))))
9519 (const_string "*")))
9520 (set_attr "mode" "<MODE>")])
9522 ;; See comment above `ashl<mode>3' about how this works.
9524 (define_expand "<shift_insn><mode>3"
9525 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9526 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9527 (match_operand:QI 2 "nonmemory_operand" "")))]
9529 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9531 ;; Avoid useless masking of count operand.
9532 (define_insn_and_split "*<shift_insn><mode>3_mask"
9533 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9535 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9538 (match_operand:SI 2 "nonimmediate_operand" "c")
9539 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9540 (clobber (reg:CC FLAGS_REG))]
9541 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9542 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9543 == GET_MODE_BITSIZE (<MODE>mode)-1"
9546 [(parallel [(set (match_dup 0)
9547 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9548 (clobber (reg:CC FLAGS_REG))])]
9550 if (can_create_pseudo_p ())
9551 operands [2] = force_reg (SImode, operands[2]);
9553 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9555 [(set_attr "type" "ishift")
9556 (set_attr "mode" "<MODE>")])
9558 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9559 [(set (match_operand:DWI 0 "register_operand" "=r")
9560 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9561 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9562 (clobber (reg:CC FLAGS_REG))]
9565 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9567 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9568 [(set_attr "type" "multi")])
9570 ;; By default we don't ask for a scratch register, because when DWImode
9571 ;; values are manipulated, registers are already at a premium. But if
9572 ;; we have one handy, we won't turn it away.
9575 [(match_scratch:DWIH 3 "r")
9576 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9578 (match_operand:<DWI> 1 "register_operand" "")
9579 (match_operand:QI 2 "nonmemory_operand" "")))
9580 (clobber (reg:CC FLAGS_REG))])
9584 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9586 (define_insn "x86_64_shrd"
9587 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9588 (ior:DI (ashiftrt:DI (match_dup 0)
9589 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9590 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9591 (minus:QI (const_int 64) (match_dup 2)))))
9592 (clobber (reg:CC FLAGS_REG))]
9594 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9595 [(set_attr "type" "ishift")
9596 (set_attr "prefix_0f" "1")
9597 (set_attr "mode" "DI")
9598 (set_attr "athlon_decode" "vector")
9599 (set_attr "amdfam10_decode" "vector")
9600 (set_attr "bdver1_decode" "vector")])
9602 (define_insn "x86_shrd"
9603 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9604 (ior:SI (ashiftrt:SI (match_dup 0)
9605 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9606 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9607 (minus:QI (const_int 32) (match_dup 2)))))
9608 (clobber (reg:CC FLAGS_REG))]
9610 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9611 [(set_attr "type" "ishift")
9612 (set_attr "prefix_0f" "1")
9613 (set_attr "mode" "SI")
9614 (set_attr "pent_pair" "np")
9615 (set_attr "athlon_decode" "vector")
9616 (set_attr "amdfam10_decode" "vector")
9617 (set_attr "bdver1_decode" "vector")])
9619 (define_insn "ashrdi3_cvt"
9620 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9621 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9622 (match_operand:QI 2 "const_int_operand" "")))
9623 (clobber (reg:CC FLAGS_REG))]
9624 "TARGET_64BIT && INTVAL (operands[2]) == 63
9625 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9626 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9629 sar{q}\t{%2, %0|%0, %2}"
9630 [(set_attr "type" "imovx,ishift")
9631 (set_attr "prefix_0f" "0,*")
9632 (set_attr "length_immediate" "0,*")
9633 (set_attr "modrm" "0,1")
9634 (set_attr "mode" "DI")])
9636 (define_insn "ashrsi3_cvt"
9637 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9638 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9639 (match_operand:QI 2 "const_int_operand" "")))
9640 (clobber (reg:CC FLAGS_REG))]
9641 "INTVAL (operands[2]) == 31
9642 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9643 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9646 sar{l}\t{%2, %0|%0, %2}"
9647 [(set_attr "type" "imovx,ishift")
9648 (set_attr "prefix_0f" "0,*")
9649 (set_attr "length_immediate" "0,*")
9650 (set_attr "modrm" "0,1")
9651 (set_attr "mode" "SI")])
9653 (define_insn "*ashrsi3_cvt_zext"
9654 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9656 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9657 (match_operand:QI 2 "const_int_operand" ""))))
9658 (clobber (reg:CC FLAGS_REG))]
9659 "TARGET_64BIT && INTVAL (operands[2]) == 31
9660 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9661 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9664 sar{l}\t{%2, %k0|%k0, %2}"
9665 [(set_attr "type" "imovx,ishift")
9666 (set_attr "prefix_0f" "0,*")
9667 (set_attr "length_immediate" "0,*")
9668 (set_attr "modrm" "0,1")
9669 (set_attr "mode" "SI")])
9671 (define_expand "x86_shift<mode>_adj_3"
9672 [(use (match_operand:SWI48 0 "register_operand" ""))
9673 (use (match_operand:SWI48 1 "register_operand" ""))
9674 (use (match_operand:QI 2 "register_operand" ""))]
9677 rtx label = gen_label_rtx ();
9680 emit_insn (gen_testqi_ccz_1 (operands[2],
9681 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9683 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9684 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9685 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9686 gen_rtx_LABEL_REF (VOIDmode, label),
9688 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9689 JUMP_LABEL (tmp) = label;
9691 emit_move_insn (operands[0], operands[1]);
9692 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9693 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9695 LABEL_NUSES (label) = 1;
9700 (define_insn "*bmi2_<shift_insn><mode>3_1"
9701 [(set (match_operand:SWI48 0 "register_operand" "=r")
9702 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9703 (match_operand:SWI48 2 "register_operand" "r")))]
9705 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9706 [(set_attr "type" "ishiftx")
9707 (set_attr "mode" "<MODE>")])
9709 (define_insn "*<shift_insn><mode>3_1"
9710 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9712 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9713 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9714 (clobber (reg:CC FLAGS_REG))]
9715 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9717 switch (get_attr_type (insn))
9723 if (operands[2] == const1_rtx
9724 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9725 return "<shift>{<imodesuffix>}\t%0";
9727 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9730 [(set_attr "isa" "*,bmi2")
9731 (set_attr "type" "ishift,ishiftx")
9732 (set (attr "length_immediate")
9734 (and (match_operand 2 "const1_operand" "")
9735 (ior (match_test "TARGET_SHIFT1")
9736 (match_test "optimize_function_for_size_p (cfun)")))
9738 (const_string "*")))
9739 (set_attr "mode" "<MODE>")])
9741 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9743 [(set (match_operand:SWI48 0 "register_operand" "")
9744 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9745 (match_operand:QI 2 "register_operand" "")))
9746 (clobber (reg:CC FLAGS_REG))]
9747 "TARGET_BMI2 && reload_completed"
9749 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9750 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9752 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9753 [(set (match_operand:DI 0 "register_operand" "=r")
9755 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9756 (match_operand:SI 2 "register_operand" "r"))))]
9757 "TARGET_64BIT && TARGET_BMI2"
9758 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9759 [(set_attr "type" "ishiftx")
9760 (set_attr "mode" "SI")])
9762 (define_insn "*<shift_insn>si3_1_zext"
9763 [(set (match_operand:DI 0 "register_operand" "=r,r")
9765 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9766 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9767 (clobber (reg:CC FLAGS_REG))]
9768 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9770 switch (get_attr_type (insn))
9776 if (operands[2] == const1_rtx
9777 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9778 return "<shift>{l}\t%k0";
9780 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9783 [(set_attr "isa" "*,bmi2")
9784 (set_attr "type" "ishift,ishiftx")
9785 (set (attr "length_immediate")
9787 (and (match_operand 2 "const1_operand" "")
9788 (ior (match_test "TARGET_SHIFT1")
9789 (match_test "optimize_function_for_size_p (cfun)")))
9791 (const_string "*")))
9792 (set_attr "mode" "SI")])
9794 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9796 [(set (match_operand:DI 0 "register_operand" "")
9798 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9799 (match_operand:QI 2 "register_operand" ""))))
9800 (clobber (reg:CC FLAGS_REG))]
9801 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9803 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9804 "operands[2] = gen_lowpart (SImode, operands[2]);")
9806 (define_insn "*<shift_insn><mode>3_1"
9807 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9809 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9810 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9811 (clobber (reg:CC FLAGS_REG))]
9812 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9814 if (operands[2] == const1_rtx
9815 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9816 return "<shift>{<imodesuffix>}\t%0";
9818 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9820 [(set_attr "type" "ishift")
9821 (set (attr "length_immediate")
9823 (and (match_operand 2 "const1_operand" "")
9824 (ior (match_test "TARGET_SHIFT1")
9825 (match_test "optimize_function_for_size_p (cfun)")))
9827 (const_string "*")))
9828 (set_attr "mode" "<MODE>")])
9830 (define_insn "*<shift_insn>qi3_1_slp"
9831 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9832 (any_shiftrt:QI (match_dup 0)
9833 (match_operand:QI 1 "nonmemory_operand" "cI")))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "(optimize_function_for_size_p (cfun)
9836 || !TARGET_PARTIAL_REG_STALL
9837 || (operands[1] == const1_rtx
9840 if (operands[1] == const1_rtx
9841 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9842 return "<shift>{b}\t%0";
9844 return "<shift>{b}\t{%1, %0|%0, %1}";
9846 [(set_attr "type" "ishift1")
9847 (set (attr "length_immediate")
9849 (and (match_operand 1 "const1_operand" "")
9850 (ior (match_test "TARGET_SHIFT1")
9851 (match_test "optimize_function_for_size_p (cfun)")))
9853 (const_string "*")))
9854 (set_attr "mode" "QI")])
9856 ;; This pattern can't accept a variable shift count, since shifts by
9857 ;; zero don't affect the flags. We assume that shifts by constant
9858 ;; zero are optimized away.
9859 (define_insn "*<shift_insn><mode>3_cmp"
9860 [(set (reg FLAGS_REG)
9863 (match_operand:SWI 1 "nonimmediate_operand" "0")
9864 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9866 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9867 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9868 "(optimize_function_for_size_p (cfun)
9869 || !TARGET_PARTIAL_FLAG_REG_STALL
9870 || (operands[2] == const1_rtx
9872 && ix86_match_ccmode (insn, CCGOCmode)
9873 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9875 if (operands[2] == const1_rtx
9876 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9877 return "<shift>{<imodesuffix>}\t%0";
9879 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9881 [(set_attr "type" "ishift")
9882 (set (attr "length_immediate")
9884 (and (match_operand 2 "const1_operand" "")
9885 (ior (match_test "TARGET_SHIFT1")
9886 (match_test "optimize_function_for_size_p (cfun)")))
9888 (const_string "*")))
9889 (set_attr "mode" "<MODE>")])
9891 (define_insn "*<shift_insn>si3_cmp_zext"
9892 [(set (reg FLAGS_REG)
9894 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9895 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9897 (set (match_operand:DI 0 "register_operand" "=r")
9898 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9900 && (optimize_function_for_size_p (cfun)
9901 || !TARGET_PARTIAL_FLAG_REG_STALL
9902 || (operands[2] == const1_rtx
9904 && ix86_match_ccmode (insn, CCGOCmode)
9905 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9907 if (operands[2] == const1_rtx
9908 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9909 return "<shift>{l}\t%k0";
9911 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9913 [(set_attr "type" "ishift")
9914 (set (attr "length_immediate")
9916 (and (match_operand 2 "const1_operand" "")
9917 (ior (match_test "TARGET_SHIFT1")
9918 (match_test "optimize_function_for_size_p (cfun)")))
9920 (const_string "*")))
9921 (set_attr "mode" "SI")])
9923 (define_insn "*<shift_insn><mode>3_cconly"
9924 [(set (reg FLAGS_REG)
9927 (match_operand:SWI 1 "register_operand" "0")
9928 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9930 (clobber (match_scratch:SWI 0 "=<r>"))]
9931 "(optimize_function_for_size_p (cfun)
9932 || !TARGET_PARTIAL_FLAG_REG_STALL
9933 || (operands[2] == const1_rtx
9935 && ix86_match_ccmode (insn, CCGOCmode)"
9937 if (operands[2] == const1_rtx
9938 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9939 return "<shift>{<imodesuffix>}\t%0";
9941 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9943 [(set_attr "type" "ishift")
9944 (set (attr "length_immediate")
9946 (and (match_operand 2 "const1_operand" "")
9947 (ior (match_test "TARGET_SHIFT1")
9948 (match_test "optimize_function_for_size_p (cfun)")))
9950 (const_string "*")))
9951 (set_attr "mode" "<MODE>")])
9953 ;; Rotate instructions
9955 (define_expand "<rotate_insn>ti3"
9956 [(set (match_operand:TI 0 "register_operand" "")
9957 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9958 (match_operand:QI 2 "nonmemory_operand" "")))]
9961 if (const_1_to_63_operand (operands[2], VOIDmode))
9962 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9963 (operands[0], operands[1], operands[2]));
9970 (define_expand "<rotate_insn>di3"
9971 [(set (match_operand:DI 0 "shiftdi_operand" "")
9972 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9973 (match_operand:QI 2 "nonmemory_operand" "")))]
9977 ix86_expand_binary_operator (<CODE>, DImode, operands);
9978 else if (const_1_to_31_operand (operands[2], VOIDmode))
9979 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9980 (operands[0], operands[1], operands[2]));
9987 (define_expand "<rotate_insn><mode>3"
9988 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
9989 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
9990 (match_operand:QI 2 "nonmemory_operand" "")))]
9992 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9994 ;; Avoid useless masking of count operand.
9995 (define_insn_and_split "*<rotate_insn><mode>3_mask"
9996 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9998 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10001 (match_operand:SI 2 "nonimmediate_operand" "c")
10002 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10003 (clobber (reg:CC FLAGS_REG))]
10004 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10005 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10006 == GET_MODE_BITSIZE (<MODE>mode)-1"
10009 [(parallel [(set (match_dup 0)
10010 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10011 (clobber (reg:CC FLAGS_REG))])]
10013 if (can_create_pseudo_p ())
10014 operands [2] = force_reg (SImode, operands[2]);
10016 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10018 [(set_attr "type" "rotate")
10019 (set_attr "mode" "<MODE>")])
10021 ;; Implement rotation using two double-precision
10022 ;; shift instructions and a scratch register.
10024 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10025 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10026 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10027 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10028 (clobber (reg:CC FLAGS_REG))
10029 (clobber (match_scratch:DWIH 3 "=&r"))]
10033 [(set (match_dup 3) (match_dup 4))
10035 [(set (match_dup 4)
10036 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10037 (lshiftrt:DWIH (match_dup 5)
10038 (minus:QI (match_dup 6) (match_dup 2)))))
10039 (clobber (reg:CC FLAGS_REG))])
10041 [(set (match_dup 5)
10042 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10043 (lshiftrt:DWIH (match_dup 3)
10044 (minus:QI (match_dup 6) (match_dup 2)))))
10045 (clobber (reg:CC FLAGS_REG))])]
10047 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10049 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10052 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10053 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10054 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10055 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10056 (clobber (reg:CC FLAGS_REG))
10057 (clobber (match_scratch:DWIH 3 "=&r"))]
10061 [(set (match_dup 3) (match_dup 4))
10063 [(set (match_dup 4)
10064 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10065 (ashift:DWIH (match_dup 5)
10066 (minus:QI (match_dup 6) (match_dup 2)))))
10067 (clobber (reg:CC FLAGS_REG))])
10069 [(set (match_dup 5)
10070 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10071 (ashift:DWIH (match_dup 3)
10072 (minus:QI (match_dup 6) (match_dup 2)))))
10073 (clobber (reg:CC FLAGS_REG))])]
10075 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10077 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10080 (define_insn "*bmi2_rorx<mode>3_1"
10081 [(set (match_operand:SWI48 0 "register_operand" "=r")
10082 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10083 (match_operand:QI 2 "immediate_operand" "<S>")))]
10085 "rorx\t{%2, %1, %0|%0, %1, %2}"
10086 [(set_attr "type" "rotatex")
10087 (set_attr "mode" "<MODE>")])
10089 (define_insn "*<rotate_insn><mode>3_1"
10090 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10092 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10093 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10094 (clobber (reg:CC FLAGS_REG))]
10095 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10097 switch (get_attr_type (insn))
10103 if (operands[2] == const1_rtx
10104 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10105 return "<rotate>{<imodesuffix>}\t%0";
10107 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10110 [(set_attr "isa" "*,bmi2")
10111 (set_attr "type" "rotate,rotatex")
10112 (set (attr "length_immediate")
10114 (and (eq_attr "type" "rotate")
10115 (and (match_operand 2 "const1_operand" "")
10116 (ior (match_test "TARGET_SHIFT1")
10117 (match_test "optimize_function_for_size_p (cfun)"))))
10119 (const_string "*")))
10120 (set_attr "mode" "<MODE>")])
10122 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10124 [(set (match_operand:SWI48 0 "register_operand" "")
10125 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10126 (match_operand:QI 2 "immediate_operand" "")))
10127 (clobber (reg:CC FLAGS_REG))]
10128 "TARGET_BMI2 && reload_completed"
10129 [(set (match_dup 0)
10130 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10133 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10137 [(set (match_operand:SWI48 0 "register_operand" "")
10138 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10139 (match_operand:QI 2 "immediate_operand" "")))
10140 (clobber (reg:CC FLAGS_REG))]
10141 "TARGET_BMI2 && reload_completed"
10142 [(set (match_dup 0)
10143 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10145 (define_insn "*bmi2_rorxsi3_1_zext"
10146 [(set (match_operand:DI 0 "register_operand" "=r")
10148 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10149 (match_operand:QI 2 "immediate_operand" "I"))))]
10150 "TARGET_64BIT && TARGET_BMI2"
10151 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10152 [(set_attr "type" "rotatex")
10153 (set_attr "mode" "SI")])
10155 (define_insn "*<rotate_insn>si3_1_zext"
10156 [(set (match_operand:DI 0 "register_operand" "=r,r")
10158 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10159 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10160 (clobber (reg:CC FLAGS_REG))]
10161 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10163 switch (get_attr_type (insn))
10169 if (operands[2] == const1_rtx
10170 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10171 return "<rotate>{l}\t%k0";
10173 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10176 [(set_attr "isa" "*,bmi2")
10177 (set_attr "type" "rotate,rotatex")
10178 (set (attr "length_immediate")
10180 (and (eq_attr "type" "rotate")
10181 (and (match_operand 2 "const1_operand" "")
10182 (ior (match_test "TARGET_SHIFT1")
10183 (match_test "optimize_function_for_size_p (cfun)"))))
10185 (const_string "*")))
10186 (set_attr "mode" "SI")])
10188 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10190 [(set (match_operand:DI 0 "register_operand" "")
10192 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10193 (match_operand:QI 2 "immediate_operand" ""))))
10194 (clobber (reg:CC FLAGS_REG))]
10195 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10196 [(set (match_dup 0)
10197 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10200 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10204 [(set (match_operand:DI 0 "register_operand" "")
10206 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10207 (match_operand:QI 2 "immediate_operand" ""))))
10208 (clobber (reg:CC FLAGS_REG))]
10209 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10210 [(set (match_dup 0)
10211 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10213 (define_insn "*<rotate_insn><mode>3_1"
10214 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10215 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10216 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10217 (clobber (reg:CC FLAGS_REG))]
10218 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10220 if (operands[2] == const1_rtx
10221 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10222 return "<rotate>{<imodesuffix>}\t%0";
10224 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10226 [(set_attr "type" "rotate")
10227 (set (attr "length_immediate")
10229 (and (match_operand 2 "const1_operand" "")
10230 (ior (match_test "TARGET_SHIFT1")
10231 (match_test "optimize_function_for_size_p (cfun)")))
10233 (const_string "*")))
10234 (set_attr "mode" "<MODE>")])
10236 (define_insn "*<rotate_insn>qi3_1_slp"
10237 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10238 (any_rotate:QI (match_dup 0)
10239 (match_operand:QI 1 "nonmemory_operand" "cI")))
10240 (clobber (reg:CC FLAGS_REG))]
10241 "(optimize_function_for_size_p (cfun)
10242 || !TARGET_PARTIAL_REG_STALL
10243 || (operands[1] == const1_rtx
10244 && TARGET_SHIFT1))"
10246 if (operands[1] == const1_rtx
10247 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10248 return "<rotate>{b}\t%0";
10250 return "<rotate>{b}\t{%1, %0|%0, %1}";
10252 [(set_attr "type" "rotate1")
10253 (set (attr "length_immediate")
10255 (and (match_operand 1 "const1_operand" "")
10256 (ior (match_test "TARGET_SHIFT1")
10257 (match_test "optimize_function_for_size_p (cfun)")))
10259 (const_string "*")))
10260 (set_attr "mode" "QI")])
10263 [(set (match_operand:HI 0 "register_operand" "")
10264 (any_rotate:HI (match_dup 0) (const_int 8)))
10265 (clobber (reg:CC FLAGS_REG))]
10267 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10268 [(parallel [(set (strict_low_part (match_dup 0))
10269 (bswap:HI (match_dup 0)))
10270 (clobber (reg:CC FLAGS_REG))])])
10272 ;; Bit set / bit test instructions
10274 (define_expand "extv"
10275 [(set (match_operand:SI 0 "register_operand" "")
10276 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10277 (match_operand:SI 2 "const8_operand" "")
10278 (match_operand:SI 3 "const8_operand" "")))]
10281 /* Handle extractions from %ah et al. */
10282 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10285 /* From mips.md: extract_bit_field doesn't verify that our source
10286 matches the predicate, so check it again here. */
10287 if (! ext_register_operand (operands[1], VOIDmode))
10291 (define_expand "extzv"
10292 [(set (match_operand:SI 0 "register_operand" "")
10293 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10294 (match_operand:SI 2 "const8_operand" "")
10295 (match_operand:SI 3 "const8_operand" "")))]
10298 /* Handle extractions from %ah et al. */
10299 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10302 /* From mips.md: extract_bit_field doesn't verify that our source
10303 matches the predicate, so check it again here. */
10304 if (! ext_register_operand (operands[1], VOIDmode))
10308 (define_expand "insv"
10309 [(set (zero_extract (match_operand 0 "register_operand" "")
10310 (match_operand 1 "const_int_operand" "")
10311 (match_operand 2 "const_int_operand" ""))
10312 (match_operand 3 "register_operand" ""))]
10315 rtx (*gen_mov_insv_1) (rtx, rtx);
10317 if (ix86_expand_pinsr (operands))
10320 /* Handle insertions to %ah et al. */
10321 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10324 /* From mips.md: insert_bit_field doesn't verify that our source
10325 matches the predicate, so check it again here. */
10326 if (! ext_register_operand (operands[0], VOIDmode))
10329 gen_mov_insv_1 = (TARGET_64BIT
10330 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10332 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10336 ;; %%% bts, btr, btc, bt.
10337 ;; In general these instructions are *slow* when applied to memory,
10338 ;; since they enforce atomic operation. When applied to registers,
10339 ;; it depends on the cpu implementation. They're never faster than
10340 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10341 ;; no point. But in 64-bit, we can't hold the relevant immediates
10342 ;; within the instruction itself, so operating on bits in the high
10343 ;; 32-bits of a register becomes easier.
10345 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10346 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10347 ;; negdf respectively, so they can never be disabled entirely.
10349 (define_insn "*btsq"
10350 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10352 (match_operand:DI 1 "const_0_to_63_operand" ""))
10354 (clobber (reg:CC FLAGS_REG))]
10355 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10356 "bts{q}\t{%1, %0|%0, %1}"
10357 [(set_attr "type" "alu1")
10358 (set_attr "prefix_0f" "1")
10359 (set_attr "mode" "DI")])
10361 (define_insn "*btrq"
10362 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10364 (match_operand:DI 1 "const_0_to_63_operand" ""))
10366 (clobber (reg:CC FLAGS_REG))]
10367 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10368 "btr{q}\t{%1, %0|%0, %1}"
10369 [(set_attr "type" "alu1")
10370 (set_attr "prefix_0f" "1")
10371 (set_attr "mode" "DI")])
10373 (define_insn "*btcq"
10374 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10376 (match_operand:DI 1 "const_0_to_63_operand" ""))
10377 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10378 (clobber (reg:CC FLAGS_REG))]
10379 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10380 "btc{q}\t{%1, %0|%0, %1}"
10381 [(set_attr "type" "alu1")
10382 (set_attr "prefix_0f" "1")
10383 (set_attr "mode" "DI")])
10385 ;; Allow Nocona to avoid these instructions if a register is available.
10388 [(match_scratch:DI 2 "r")
10389 (parallel [(set (zero_extract:DI
10390 (match_operand:DI 0 "register_operand" "")
10392 (match_operand:DI 1 "const_0_to_63_operand" ""))
10394 (clobber (reg:CC FLAGS_REG))])]
10395 "TARGET_64BIT && !TARGET_USE_BT"
10398 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10401 if (HOST_BITS_PER_WIDE_INT >= 64)
10402 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10403 else if (i < HOST_BITS_PER_WIDE_INT)
10404 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10406 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10408 op1 = immed_double_const (lo, hi, DImode);
10411 emit_move_insn (operands[2], op1);
10415 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10420 [(match_scratch:DI 2 "r")
10421 (parallel [(set (zero_extract:DI
10422 (match_operand:DI 0 "register_operand" "")
10424 (match_operand:DI 1 "const_0_to_63_operand" ""))
10426 (clobber (reg:CC FLAGS_REG))])]
10427 "TARGET_64BIT && !TARGET_USE_BT"
10430 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10433 if (HOST_BITS_PER_WIDE_INT >= 64)
10434 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10435 else if (i < HOST_BITS_PER_WIDE_INT)
10436 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10438 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10440 op1 = immed_double_const (~lo, ~hi, DImode);
10443 emit_move_insn (operands[2], op1);
10447 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10452 [(match_scratch:DI 2 "r")
10453 (parallel [(set (zero_extract:DI
10454 (match_operand:DI 0 "register_operand" "")
10456 (match_operand:DI 1 "const_0_to_63_operand" ""))
10457 (not:DI (zero_extract:DI
10458 (match_dup 0) (const_int 1) (match_dup 1))))
10459 (clobber (reg:CC FLAGS_REG))])]
10460 "TARGET_64BIT && !TARGET_USE_BT"
10463 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10466 if (HOST_BITS_PER_WIDE_INT >= 64)
10467 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10468 else if (i < HOST_BITS_PER_WIDE_INT)
10469 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10471 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10473 op1 = immed_double_const (lo, hi, DImode);
10476 emit_move_insn (operands[2], op1);
10480 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10484 (define_insn "*bt<mode>"
10485 [(set (reg:CCC FLAGS_REG)
10487 (zero_extract:SWI48
10488 (match_operand:SWI48 0 "register_operand" "r")
10490 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10492 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10493 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10494 [(set_attr "type" "alu1")
10495 (set_attr "prefix_0f" "1")
10496 (set_attr "mode" "<MODE>")])
10498 ;; Store-flag instructions.
10500 ;; For all sCOND expanders, also expand the compare or test insn that
10501 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10503 (define_insn_and_split "*setcc_di_1"
10504 [(set (match_operand:DI 0 "register_operand" "=q")
10505 (match_operator:DI 1 "ix86_comparison_operator"
10506 [(reg FLAGS_REG) (const_int 0)]))]
10507 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10509 "&& reload_completed"
10510 [(set (match_dup 2) (match_dup 1))
10511 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10513 PUT_MODE (operands[1], QImode);
10514 operands[2] = gen_lowpart (QImode, operands[0]);
10517 (define_insn_and_split "*setcc_si_1_and"
10518 [(set (match_operand:SI 0 "register_operand" "=q")
10519 (match_operator:SI 1 "ix86_comparison_operator"
10520 [(reg FLAGS_REG) (const_int 0)]))
10521 (clobber (reg:CC FLAGS_REG))]
10522 "!TARGET_PARTIAL_REG_STALL
10523 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10525 "&& reload_completed"
10526 [(set (match_dup 2) (match_dup 1))
10527 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10528 (clobber (reg:CC FLAGS_REG))])]
10530 PUT_MODE (operands[1], QImode);
10531 operands[2] = gen_lowpart (QImode, operands[0]);
10534 (define_insn_and_split "*setcc_si_1_movzbl"
10535 [(set (match_operand:SI 0 "register_operand" "=q")
10536 (match_operator:SI 1 "ix86_comparison_operator"
10537 [(reg FLAGS_REG) (const_int 0)]))]
10538 "!TARGET_PARTIAL_REG_STALL
10539 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10541 "&& reload_completed"
10542 [(set (match_dup 2) (match_dup 1))
10543 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10545 PUT_MODE (operands[1], QImode);
10546 operands[2] = gen_lowpart (QImode, operands[0]);
10549 (define_insn "*setcc_qi"
10550 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10551 (match_operator:QI 1 "ix86_comparison_operator"
10552 [(reg FLAGS_REG) (const_int 0)]))]
10555 [(set_attr "type" "setcc")
10556 (set_attr "mode" "QI")])
10558 (define_insn "*setcc_qi_slp"
10559 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10560 (match_operator:QI 1 "ix86_comparison_operator"
10561 [(reg FLAGS_REG) (const_int 0)]))]
10564 [(set_attr "type" "setcc")
10565 (set_attr "mode" "QI")])
10567 ;; In general it is not safe to assume too much about CCmode registers,
10568 ;; so simplify-rtx stops when it sees a second one. Under certain
10569 ;; conditions this is safe on x86, so help combine not create
10576 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10577 (ne:QI (match_operator 1 "ix86_comparison_operator"
10578 [(reg FLAGS_REG) (const_int 0)])
10581 [(set (match_dup 0) (match_dup 1))]
10582 "PUT_MODE (operands[1], QImode);")
10585 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10586 (ne:QI (match_operator 1 "ix86_comparison_operator"
10587 [(reg FLAGS_REG) (const_int 0)])
10590 [(set (match_dup 0) (match_dup 1))]
10591 "PUT_MODE (operands[1], QImode);")
10594 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10595 (eq:QI (match_operator 1 "ix86_comparison_operator"
10596 [(reg FLAGS_REG) (const_int 0)])
10599 [(set (match_dup 0) (match_dup 1))]
10601 rtx new_op1 = copy_rtx (operands[1]);
10602 operands[1] = new_op1;
10603 PUT_MODE (new_op1, QImode);
10604 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10605 GET_MODE (XEXP (new_op1, 0))));
10607 /* Make sure that (a) the CCmode we have for the flags is strong
10608 enough for the reversed compare or (b) we have a valid FP compare. */
10609 if (! ix86_comparison_operator (new_op1, VOIDmode))
10614 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10615 (eq:QI (match_operator 1 "ix86_comparison_operator"
10616 [(reg FLAGS_REG) (const_int 0)])
10619 [(set (match_dup 0) (match_dup 1))]
10621 rtx new_op1 = copy_rtx (operands[1]);
10622 operands[1] = new_op1;
10623 PUT_MODE (new_op1, QImode);
10624 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10625 GET_MODE (XEXP (new_op1, 0))));
10627 /* Make sure that (a) the CCmode we have for the flags is strong
10628 enough for the reversed compare or (b) we have a valid FP compare. */
10629 if (! ix86_comparison_operator (new_op1, VOIDmode))
10633 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10634 ;; subsequent logical operations are used to imitate conditional moves.
10635 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10638 (define_insn "setcc_<mode>_sse"
10639 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10640 (match_operator:MODEF 3 "sse_comparison_operator"
10641 [(match_operand:MODEF 1 "register_operand" "0,x")
10642 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10643 "SSE_FLOAT_MODE_P (<MODE>mode)"
10645 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10646 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10647 [(set_attr "isa" "noavx,avx")
10648 (set_attr "type" "ssecmp")
10649 (set_attr "length_immediate" "1")
10650 (set_attr "prefix" "orig,vex")
10651 (set_attr "mode" "<MODE>")])
10653 ;; Basic conditional jump instructions.
10654 ;; We ignore the overflow flag for signed branch instructions.
10656 (define_insn "*jcc_1"
10658 (if_then_else (match_operator 1 "ix86_comparison_operator"
10659 [(reg FLAGS_REG) (const_int 0)])
10660 (label_ref (match_operand 0 "" ""))
10664 [(set_attr "type" "ibr")
10665 (set_attr "modrm" "0")
10666 (set (attr "length")
10667 (if_then_else (and (ge (minus (match_dup 0) (pc))
10669 (lt (minus (match_dup 0) (pc))
10674 (define_insn "*jcc_2"
10676 (if_then_else (match_operator 1 "ix86_comparison_operator"
10677 [(reg FLAGS_REG) (const_int 0)])
10679 (label_ref (match_operand 0 "" ""))))]
10682 [(set_attr "type" "ibr")
10683 (set_attr "modrm" "0")
10684 (set (attr "length")
10685 (if_then_else (and (ge (minus (match_dup 0) (pc))
10687 (lt (minus (match_dup 0) (pc))
10692 ;; In general it is not safe to assume too much about CCmode registers,
10693 ;; so simplify-rtx stops when it sees a second one. Under certain
10694 ;; conditions this is safe on x86, so help combine not create
10702 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10703 [(reg FLAGS_REG) (const_int 0)])
10705 (label_ref (match_operand 1 "" ""))
10709 (if_then_else (match_dup 0)
10710 (label_ref (match_dup 1))
10712 "PUT_MODE (operands[0], VOIDmode);")
10716 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10717 [(reg FLAGS_REG) (const_int 0)])
10719 (label_ref (match_operand 1 "" ""))
10723 (if_then_else (match_dup 0)
10724 (label_ref (match_dup 1))
10727 rtx new_op0 = copy_rtx (operands[0]);
10728 operands[0] = new_op0;
10729 PUT_MODE (new_op0, VOIDmode);
10730 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10731 GET_MODE (XEXP (new_op0, 0))));
10733 /* Make sure that (a) the CCmode we have for the flags is strong
10734 enough for the reversed compare or (b) we have a valid FP compare. */
10735 if (! ix86_comparison_operator (new_op0, VOIDmode))
10739 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10740 ;; pass generates from shift insn with QImode operand. Actually, the mode
10741 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10742 ;; appropriate modulo of the bit offset value.
10744 (define_insn_and_split "*jcc_bt<mode>"
10746 (if_then_else (match_operator 0 "bt_comparison_operator"
10747 [(zero_extract:SWI48
10748 (match_operand:SWI48 1 "register_operand" "r")
10751 (match_operand:QI 2 "register_operand" "r")))
10753 (label_ref (match_operand 3 "" ""))
10755 (clobber (reg:CC FLAGS_REG))]
10756 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10759 [(set (reg:CCC FLAGS_REG)
10761 (zero_extract:SWI48
10767 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10768 (label_ref (match_dup 3))
10771 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10773 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10776 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10777 ;; also for DImode, this is what combine produces.
10778 (define_insn_and_split "*jcc_bt<mode>_mask"
10780 (if_then_else (match_operator 0 "bt_comparison_operator"
10781 [(zero_extract:SWI48
10782 (match_operand:SWI48 1 "register_operand" "r")
10785 (match_operand:SI 2 "register_operand" "r")
10786 (match_operand:SI 3 "const_int_operand" "n")))])
10787 (label_ref (match_operand 4 "" ""))
10789 (clobber (reg:CC FLAGS_REG))]
10790 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10791 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10792 == GET_MODE_BITSIZE (<MODE>mode)-1"
10795 [(set (reg:CCC FLAGS_REG)
10797 (zero_extract:SWI48
10803 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10804 (label_ref (match_dup 4))
10807 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10809 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10812 (define_insn_and_split "*jcc_btsi_1"
10814 (if_then_else (match_operator 0 "bt_comparison_operator"
10817 (match_operand:SI 1 "register_operand" "r")
10818 (match_operand:QI 2 "register_operand" "r"))
10821 (label_ref (match_operand 3 "" ""))
10823 (clobber (reg:CC FLAGS_REG))]
10824 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10827 [(set (reg:CCC FLAGS_REG)
10835 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10836 (label_ref (match_dup 3))
10839 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10841 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10844 ;; avoid useless masking of bit offset operand
10845 (define_insn_and_split "*jcc_btsi_mask_1"
10848 (match_operator 0 "bt_comparison_operator"
10851 (match_operand:SI 1 "register_operand" "r")
10854 (match_operand:SI 2 "register_operand" "r")
10855 (match_operand:SI 3 "const_int_operand" "n")) 0))
10858 (label_ref (match_operand 4 "" ""))
10860 (clobber (reg:CC FLAGS_REG))]
10861 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10862 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10865 [(set (reg:CCC FLAGS_REG)
10873 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10874 (label_ref (match_dup 4))
10876 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10878 ;; Define combination compare-and-branch fp compare instructions to help
10881 (define_insn "*fp_jcc_1_387"
10883 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10884 [(match_operand 1 "register_operand" "f")
10885 (match_operand 2 "nonimmediate_operand" "fm")])
10886 (label_ref (match_operand 3 "" ""))
10888 (clobber (reg:CCFP FPSR_REG))
10889 (clobber (reg:CCFP FLAGS_REG))
10890 (clobber (match_scratch:HI 4 "=a"))]
10892 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10893 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10894 && SELECT_CC_MODE (GET_CODE (operands[0]),
10895 operands[1], operands[2]) == CCFPmode
10899 (define_insn "*fp_jcc_1r_387"
10901 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10902 [(match_operand 1 "register_operand" "f")
10903 (match_operand 2 "nonimmediate_operand" "fm")])
10905 (label_ref (match_operand 3 "" ""))))
10906 (clobber (reg:CCFP FPSR_REG))
10907 (clobber (reg:CCFP FLAGS_REG))
10908 (clobber (match_scratch:HI 4 "=a"))]
10910 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10911 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10912 && SELECT_CC_MODE (GET_CODE (operands[0]),
10913 operands[1], operands[2]) == CCFPmode
10917 (define_insn "*fp_jcc_2_387"
10919 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10920 [(match_operand 1 "register_operand" "f")
10921 (match_operand 2 "register_operand" "f")])
10922 (label_ref (match_operand 3 "" ""))
10924 (clobber (reg:CCFP FPSR_REG))
10925 (clobber (reg:CCFP FLAGS_REG))
10926 (clobber (match_scratch:HI 4 "=a"))]
10927 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10928 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10932 (define_insn "*fp_jcc_2r_387"
10934 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10935 [(match_operand 1 "register_operand" "f")
10936 (match_operand 2 "register_operand" "f")])
10938 (label_ref (match_operand 3 "" ""))))
10939 (clobber (reg:CCFP FPSR_REG))
10940 (clobber (reg:CCFP FLAGS_REG))
10941 (clobber (match_scratch:HI 4 "=a"))]
10942 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10943 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10947 (define_insn "*fp_jcc_3_387"
10949 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10950 [(match_operand 1 "register_operand" "f")
10951 (match_operand 2 "const0_operand" "")])
10952 (label_ref (match_operand 3 "" ""))
10954 (clobber (reg:CCFP FPSR_REG))
10955 (clobber (reg:CCFP FLAGS_REG))
10956 (clobber (match_scratch:HI 4 "=a"))]
10957 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10958 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10959 && SELECT_CC_MODE (GET_CODE (operands[0]),
10960 operands[1], operands[2]) == CCFPmode
10966 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10967 [(match_operand 1 "register_operand" "")
10968 (match_operand 2 "nonimmediate_operand" "")])
10969 (match_operand 3 "" "")
10970 (match_operand 4 "" "")))
10971 (clobber (reg:CCFP FPSR_REG))
10972 (clobber (reg:CCFP FLAGS_REG))]
10976 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10977 operands[3], operands[4], NULL_RTX, NULL_RTX);
10983 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10984 [(match_operand 1 "register_operand" "")
10985 (match_operand 2 "general_operand" "")])
10986 (match_operand 3 "" "")
10987 (match_operand 4 "" "")))
10988 (clobber (reg:CCFP FPSR_REG))
10989 (clobber (reg:CCFP FLAGS_REG))
10990 (clobber (match_scratch:HI 5 "=a"))]
10994 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10995 operands[3], operands[4], operands[5], NULL_RTX);
10999 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11000 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11001 ;; with a precedence over other operators and is always put in the first
11002 ;; place. Swap condition and operands to match ficom instruction.
11004 (define_insn "*fp_jcc_4_<mode>_387"
11007 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11008 [(match_operator 1 "float_operator"
11009 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11010 (match_operand 3 "register_operand" "f,f")])
11011 (label_ref (match_operand 4 "" ""))
11013 (clobber (reg:CCFP FPSR_REG))
11014 (clobber (reg:CCFP FLAGS_REG))
11015 (clobber (match_scratch:HI 5 "=a,a"))]
11016 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11017 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11018 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11019 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11026 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11027 [(match_operator 1 "float_operator"
11028 [(match_operand:SWI24 2 "memory_operand" "")])
11029 (match_operand 3 "register_operand" "")])
11030 (match_operand 4 "" "")
11031 (match_operand 5 "" "")))
11032 (clobber (reg:CCFP FPSR_REG))
11033 (clobber (reg:CCFP FLAGS_REG))
11034 (clobber (match_scratch:HI 6 "=a"))]
11038 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11040 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11041 operands[3], operands[7],
11042 operands[4], operands[5], operands[6], NULL_RTX);
11046 ;; %%% Kill this when reload knows how to do it.
11050 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11051 [(match_operator 1 "float_operator"
11052 [(match_operand:SWI24 2 "register_operand" "")])
11053 (match_operand 3 "register_operand" "")])
11054 (match_operand 4 "" "")
11055 (match_operand 5 "" "")))
11056 (clobber (reg:CCFP FPSR_REG))
11057 (clobber (reg:CCFP FLAGS_REG))
11058 (clobber (match_scratch:HI 6 "=a"))]
11062 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11063 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11065 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11066 operands[3], operands[7],
11067 operands[4], operands[5], operands[6], operands[2]);
11071 ;; Unconditional and other jump instructions
11073 (define_insn "jump"
11075 (label_ref (match_operand 0 "" "")))]
11078 [(set_attr "type" "ibr")
11079 (set (attr "length")
11080 (if_then_else (and (ge (minus (match_dup 0) (pc))
11082 (lt (minus (match_dup 0) (pc))
11086 (set_attr "modrm" "0")])
11088 (define_expand "indirect_jump"
11089 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))]
11093 operands[0] = convert_memory_address (word_mode, operands[0]);
11096 (define_insn "*indirect_jump"
11097 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))]
11100 [(set_attr "type" "ibr")
11101 (set_attr "length_immediate" "0")])
11103 (define_expand "tablejump"
11104 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11105 (use (label_ref (match_operand 1 "" "")))])]
11108 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11109 relative. Convert the relative address to an absolute address. */
11113 enum rtx_code code;
11115 /* We can't use @GOTOFF for text labels on VxWorks;
11116 see gotoff_operand. */
11117 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11121 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11123 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11127 op1 = pic_offset_table_rtx;
11132 op0 = pic_offset_table_rtx;
11136 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11141 operands[0] = convert_memory_address (word_mode, operands[0]);
11144 (define_insn "*tablejump_1"
11145 [(set (pc) (match_operand:W 0 "indirect_branch_operand" "rw"))
11146 (use (label_ref (match_operand 1 "" "")))]
11149 [(set_attr "type" "ibr")
11150 (set_attr "length_immediate" "0")])
11152 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11155 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11156 (set (match_operand:QI 1 "register_operand" "")
11157 (match_operator:QI 2 "ix86_comparison_operator"
11158 [(reg FLAGS_REG) (const_int 0)]))
11159 (set (match_operand 3 "q_regs_operand" "")
11160 (zero_extend (match_dup 1)))]
11161 "(peep2_reg_dead_p (3, operands[1])
11162 || operands_match_p (operands[1], operands[3]))
11163 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11164 [(set (match_dup 4) (match_dup 0))
11165 (set (strict_low_part (match_dup 5))
11168 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11169 operands[5] = gen_lowpart (QImode, operands[3]);
11170 ix86_expand_clear (operands[3]);
11173 ;; Similar, but match zero extend with andsi3.
11176 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11177 (set (match_operand:QI 1 "register_operand" "")
11178 (match_operator:QI 2 "ix86_comparison_operator"
11179 [(reg FLAGS_REG) (const_int 0)]))
11180 (parallel [(set (match_operand:SI 3 "q_regs_operand" "")
11181 (and:SI (match_dup 3) (const_int 255)))
11182 (clobber (reg:CC FLAGS_REG))])]
11183 "REGNO (operands[1]) == REGNO (operands[3])
11184 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11185 [(set (match_dup 4) (match_dup 0))
11186 (set (strict_low_part (match_dup 5))
11189 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11190 operands[5] = gen_lowpart (QImode, operands[3]);
11191 ix86_expand_clear (operands[3]);
11194 ;; Call instructions.
11196 ;; The predicates normally associated with named expanders are not properly
11197 ;; checked for calls. This is a bug in the generic code, but it isn't that
11198 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11200 ;; P6 processors will jump to the address after the decrement when %esp
11201 ;; is used as a call operand, so they will execute return address as a code.
11202 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11204 ;; Register constraint for call instruction.
11205 (define_mode_attr c [(SI "l") (DI "r")])
11207 ;; Call subroutine returning no value.
11209 (define_expand "call"
11210 [(call (match_operand:QI 0 "" "")
11211 (match_operand 1 "" ""))
11212 (use (match_operand 2 "" ""))]
11215 ix86_expand_call (NULL, operands[0], operands[1],
11216 operands[2], NULL, false);
11220 (define_expand "sibcall"
11221 [(call (match_operand:QI 0 "" "")
11222 (match_operand 1 "" ""))
11223 (use (match_operand 2 "" ""))]
11226 ix86_expand_call (NULL, operands[0], operands[1],
11227 operands[2], NULL, true);
11231 (define_insn_and_split "*call_vzeroupper"
11232 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11233 (match_operand 1 "" ""))
11234 (unspec [(match_operand 2 "const_int_operand" "")]
11235 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11236 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11238 "&& reload_completed"
11240 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11241 [(set_attr "type" "call")])
11243 (define_insn "*call"
11244 [(call (mem:QI (match_operand:W 0 "call_insn_operand" "<c>zw"))
11245 (match_operand 1 "" ""))]
11246 "!SIBLING_CALL_P (insn)"
11247 "* return ix86_output_call_insn (insn, operands[0]);"
11248 [(set_attr "type" "call")])
11250 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11251 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11252 (match_operand 1 "" ""))
11253 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11254 (clobber (reg:TI XMM6_REG))
11255 (clobber (reg:TI XMM7_REG))
11256 (clobber (reg:TI XMM8_REG))
11257 (clobber (reg:TI XMM9_REG))
11258 (clobber (reg:TI XMM10_REG))
11259 (clobber (reg:TI XMM11_REG))
11260 (clobber (reg:TI XMM12_REG))
11261 (clobber (reg:TI XMM13_REG))
11262 (clobber (reg:TI XMM14_REG))
11263 (clobber (reg:TI XMM15_REG))
11264 (clobber (reg:DI SI_REG))
11265 (clobber (reg:DI DI_REG))
11266 (unspec [(match_operand 2 "const_int_operand" "")]
11267 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11268 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11270 "&& reload_completed"
11272 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11273 [(set_attr "type" "call")])
11275 (define_insn "*call_rex64_ms_sysv"
11276 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11277 (match_operand 1 "" ""))
11278 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11279 (clobber (reg:TI XMM6_REG))
11280 (clobber (reg:TI XMM7_REG))
11281 (clobber (reg:TI XMM8_REG))
11282 (clobber (reg:TI XMM9_REG))
11283 (clobber (reg:TI XMM10_REG))
11284 (clobber (reg:TI XMM11_REG))
11285 (clobber (reg:TI XMM12_REG))
11286 (clobber (reg:TI XMM13_REG))
11287 (clobber (reg:TI XMM14_REG))
11288 (clobber (reg:TI XMM15_REG))
11289 (clobber (reg:DI SI_REG))
11290 (clobber (reg:DI DI_REG))]
11291 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11292 "* return ix86_output_call_insn (insn, operands[0]);"
11293 [(set_attr "type" "call")])
11295 (define_insn_and_split "*sibcall_vzeroupper"
11296 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11297 (match_operand 1 "" ""))
11298 (unspec [(match_operand 2 "const_int_operand" "")]
11299 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11300 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11302 "&& reload_completed"
11304 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11305 [(set_attr "type" "call")])
11307 (define_insn "*sibcall"
11308 [(call (mem:QI (match_operand:W 0 "sibcall_insn_operand" "Uz"))
11309 (match_operand 1 "" ""))]
11310 "SIBLING_CALL_P (insn)"
11311 "* return ix86_output_call_insn (insn, operands[0]);"
11312 [(set_attr "type" "call")])
11314 (define_expand "call_pop"
11315 [(parallel [(call (match_operand:QI 0 "" "")
11316 (match_operand:SI 1 "" ""))
11317 (set (reg:SI SP_REG)
11318 (plus:SI (reg:SI SP_REG)
11319 (match_operand:SI 3 "" "")))])]
11322 ix86_expand_call (NULL, operands[0], operands[1],
11323 operands[2], operands[3], false);
11327 (define_insn_and_split "*call_pop_vzeroupper"
11328 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11329 (match_operand:SI 1 "" ""))
11330 (set (reg:SI SP_REG)
11331 (plus:SI (reg:SI SP_REG)
11332 (match_operand:SI 2 "immediate_operand" "i")))
11333 (unspec [(match_operand 3 "const_int_operand" "")]
11334 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11335 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11337 "&& reload_completed"
11339 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11340 [(set_attr "type" "call")])
11342 (define_insn "*call_pop"
11343 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11344 (match_operand 1 "" ""))
11345 (set (reg:SI SP_REG)
11346 (plus:SI (reg:SI SP_REG)
11347 (match_operand:SI 2 "immediate_operand" "i")))]
11348 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11349 "* return ix86_output_call_insn (insn, operands[0]);"
11350 [(set_attr "type" "call")])
11352 (define_insn_and_split "*sibcall_pop_vzeroupper"
11353 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11354 (match_operand 1 "" ""))
11355 (set (reg:SI SP_REG)
11356 (plus:SI (reg:SI SP_REG)
11357 (match_operand:SI 2 "immediate_operand" "i")))
11358 (unspec [(match_operand 3 "const_int_operand" "")]
11359 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11360 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11362 "&& reload_completed"
11364 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11365 [(set_attr "type" "call")])
11367 (define_insn "*sibcall_pop"
11368 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11369 (match_operand 1 "" ""))
11370 (set (reg:SI SP_REG)
11371 (plus:SI (reg:SI SP_REG)
11372 (match_operand:SI 2 "immediate_operand" "i")))]
11373 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11374 "* return ix86_output_call_insn (insn, operands[0]);"
11375 [(set_attr "type" "call")])
11377 ;; Call subroutine, returning value in operand 0
11379 (define_expand "call_value"
11380 [(set (match_operand 0 "" "")
11381 (call (match_operand:QI 1 "" "")
11382 (match_operand 2 "" "")))
11383 (use (match_operand 3 "" ""))]
11386 ix86_expand_call (operands[0], operands[1], operands[2],
11387 operands[3], NULL, false);
11391 (define_expand "sibcall_value"
11392 [(set (match_operand 0 "" "")
11393 (call (match_operand:QI 1 "" "")
11394 (match_operand 2 "" "")))
11395 (use (match_operand 3 "" ""))]
11398 ix86_expand_call (operands[0], operands[1], operands[2],
11399 operands[3], NULL, true);
11403 (define_insn_and_split "*call_value_vzeroupper"
11404 [(set (match_operand 0 "" "")
11405 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11406 (match_operand 2 "" "")))
11407 (unspec [(match_operand 3 "const_int_operand" "")]
11408 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11409 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11411 "&& reload_completed"
11413 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11414 [(set_attr "type" "callv")])
11416 (define_insn "*call_value"
11417 [(set (match_operand 0 "" "")
11418 (call (mem:QI (match_operand:W 1 "call_insn_operand" "<c>zw"))
11419 (match_operand 2 "" "")))]
11420 "!SIBLING_CALL_P (insn)"
11421 "* return ix86_output_call_insn (insn, operands[1]);"
11422 [(set_attr "type" "callv")])
11424 (define_insn_and_split "*sibcall_value_vzeroupper"
11425 [(set (match_operand 0 "" "")
11426 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11427 (match_operand 2 "" "")))
11428 (unspec [(match_operand 3 "const_int_operand" "")]
11429 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11430 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11432 "&& reload_completed"
11434 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11435 [(set_attr "type" "callv")])
11437 (define_insn "*sibcall_value"
11438 [(set (match_operand 0 "" "")
11439 (call (mem:QI (match_operand:W 1 "sibcall_insn_operand" "Uz"))
11440 (match_operand 2 "" "")))]
11441 "SIBLING_CALL_P (insn)"
11442 "* return ix86_output_call_insn (insn, operands[1]);"
11443 [(set_attr "type" "callv")])
11445 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11446 [(set (match_operand 0 "" "")
11447 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11448 (match_operand 2 "" "")))
11449 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11450 (clobber (reg:TI XMM6_REG))
11451 (clobber (reg:TI XMM7_REG))
11452 (clobber (reg:TI XMM8_REG))
11453 (clobber (reg:TI XMM9_REG))
11454 (clobber (reg:TI XMM10_REG))
11455 (clobber (reg:TI XMM11_REG))
11456 (clobber (reg:TI XMM12_REG))
11457 (clobber (reg:TI XMM13_REG))
11458 (clobber (reg:TI XMM14_REG))
11459 (clobber (reg:TI XMM15_REG))
11460 (clobber (reg:DI SI_REG))
11461 (clobber (reg:DI DI_REG))
11462 (unspec [(match_operand 3 "const_int_operand" "")]
11463 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11464 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11466 "&& reload_completed"
11468 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11469 [(set_attr "type" "callv")])
11471 (define_insn "*call_value_rex64_ms_sysv"
11472 [(set (match_operand 0 "" "")
11473 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11474 (match_operand 2 "" "")))
11475 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11476 (clobber (reg:TI XMM6_REG))
11477 (clobber (reg:TI XMM7_REG))
11478 (clobber (reg:TI XMM8_REG))
11479 (clobber (reg:TI XMM9_REG))
11480 (clobber (reg:TI XMM10_REG))
11481 (clobber (reg:TI XMM11_REG))
11482 (clobber (reg:TI XMM12_REG))
11483 (clobber (reg:TI XMM13_REG))
11484 (clobber (reg:TI XMM14_REG))
11485 (clobber (reg:TI XMM15_REG))
11486 (clobber (reg:DI SI_REG))
11487 (clobber (reg:DI DI_REG))]
11488 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11489 "* return ix86_output_call_insn (insn, operands[1]);"
11490 [(set_attr "type" "callv")])
11492 (define_expand "call_value_pop"
11493 [(parallel [(set (match_operand 0 "" "")
11494 (call (match_operand:QI 1 "" "")
11495 (match_operand:SI 2 "" "")))
11496 (set (reg:SI SP_REG)
11497 (plus:SI (reg:SI SP_REG)
11498 (match_operand:SI 4 "" "")))])]
11501 ix86_expand_call (operands[0], operands[1], operands[2],
11502 operands[3], operands[4], false);
11506 (define_insn_and_split "*call_value_pop_vzeroupper"
11507 [(set (match_operand 0 "" "")
11508 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11509 (match_operand 2 "" "")))
11510 (set (reg:SI SP_REG)
11511 (plus:SI (reg:SI SP_REG)
11512 (match_operand:SI 3 "immediate_operand" "i")))
11513 (unspec [(match_operand 4 "const_int_operand" "")]
11514 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11515 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11517 "&& reload_completed"
11519 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11520 [(set_attr "type" "callv")])
11522 (define_insn "*call_value_pop"
11523 [(set (match_operand 0 "" "")
11524 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11525 (match_operand 2 "" "")))
11526 (set (reg:SI SP_REG)
11527 (plus:SI (reg:SI SP_REG)
11528 (match_operand:SI 3 "immediate_operand" "i")))]
11529 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11530 "* return ix86_output_call_insn (insn, operands[1]);"
11531 [(set_attr "type" "callv")])
11533 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11534 [(set (match_operand 0 "" "")
11535 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11536 (match_operand 2 "" "")))
11537 (set (reg:SI SP_REG)
11538 (plus:SI (reg:SI SP_REG)
11539 (match_operand:SI 3 "immediate_operand" "i")))
11540 (unspec [(match_operand 4 "const_int_operand" "")]
11541 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11542 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11544 "&& reload_completed"
11546 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11547 [(set_attr "type" "callv")])
11549 (define_insn "*sibcall_value_pop"
11550 [(set (match_operand 0 "" "")
11551 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11552 (match_operand 2 "" "")))
11553 (set (reg:SI SP_REG)
11554 (plus:SI (reg:SI SP_REG)
11555 (match_operand:SI 3 "immediate_operand" "i")))]
11556 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11557 "* return ix86_output_call_insn (insn, operands[1]);"
11558 [(set_attr "type" "callv")])
11560 ;; Call subroutine returning any type.
11562 (define_expand "untyped_call"
11563 [(parallel [(call (match_operand 0 "" "")
11565 (match_operand 1 "" "")
11566 (match_operand 2 "" "")])]
11571 /* In order to give reg-stack an easier job in validating two
11572 coprocessor registers as containing a possible return value,
11573 simply pretend the untyped call returns a complex long double
11576 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11577 and should have the default ABI. */
11579 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11580 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11581 operands[0], const0_rtx,
11582 GEN_INT ((TARGET_64BIT
11583 ? (ix86_abi == SYSV_ABI
11584 ? X86_64_SSE_REGPARM_MAX
11585 : X86_64_MS_SSE_REGPARM_MAX)
11586 : X86_32_SSE_REGPARM_MAX)
11590 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11592 rtx set = XVECEXP (operands[2], 0, i);
11593 emit_move_insn (SET_DEST (set), SET_SRC (set));
11596 /* The optimizer does not know that the call sets the function value
11597 registers we stored in the result block. We avoid problems by
11598 claiming that all hard registers are used and clobbered at this
11600 emit_insn (gen_blockage ());
11605 ;; Prologue and epilogue instructions
11607 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11608 ;; all of memory. This blocks insns from being moved across this point.
11610 (define_insn "blockage"
11611 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11614 [(set_attr "length" "0")])
11616 ;; Do not schedule instructions accessing memory across this point.
11618 (define_expand "memory_blockage"
11619 [(set (match_dup 0)
11620 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11623 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11624 MEM_VOLATILE_P (operands[0]) = 1;
11627 (define_insn "*memory_blockage"
11628 [(set (match_operand:BLK 0 "" "")
11629 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11632 [(set_attr "length" "0")])
11634 ;; As USE insns aren't meaningful after reload, this is used instead
11635 ;; to prevent deleting instructions setting registers for PIC code
11636 (define_insn "prologue_use"
11637 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11640 [(set_attr "length" "0")])
11642 ;; Insn emitted into the body of a function to return from a function.
11643 ;; This is only done if the function's epilogue is known to be simple.
11644 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11646 (define_expand "return"
11648 "ix86_can_use_return_insn_p ()"
11650 ix86_maybe_emit_epilogue_vzeroupper ();
11651 if (crtl->args.pops_args)
11653 rtx popc = GEN_INT (crtl->args.pops_args);
11654 emit_jump_insn (gen_simple_return_pop_internal (popc));
11659 ;; We need to disable this for TARGET_SEH, as otherwise
11660 ;; shrink-wrapped prologue gets enabled too. This might exceed
11661 ;; the maximum size of prologue in unwind information.
11663 (define_expand "simple_return"
11667 ix86_maybe_emit_epilogue_vzeroupper ();
11668 if (crtl->args.pops_args)
11670 rtx popc = GEN_INT (crtl->args.pops_args);
11671 emit_jump_insn (gen_simple_return_pop_internal (popc));
11676 (define_insn "simple_return_internal"
11680 [(set_attr "length" "1")
11681 (set_attr "atom_unit" "jeu")
11682 (set_attr "length_immediate" "0")
11683 (set_attr "modrm" "0")])
11685 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11686 ;; instruction Athlon and K8 have.
11688 (define_insn "simple_return_internal_long"
11690 (unspec [(const_int 0)] UNSPEC_REP)]
11693 [(set_attr "length" "2")
11694 (set_attr "atom_unit" "jeu")
11695 (set_attr "length_immediate" "0")
11696 (set_attr "prefix_rep" "1")
11697 (set_attr "modrm" "0")])
11699 (define_insn "simple_return_pop_internal"
11701 (use (match_operand:SI 0 "const_int_operand" ""))]
11704 [(set_attr "length" "3")
11705 (set_attr "atom_unit" "jeu")
11706 (set_attr "length_immediate" "2")
11707 (set_attr "modrm" "0")])
11709 (define_insn "simple_return_indirect_internal"
11711 (use (match_operand:SI 0 "register_operand" "r"))]
11714 [(set_attr "type" "ibr")
11715 (set_attr "length_immediate" "0")])
11721 [(set_attr "length" "1")
11722 (set_attr "length_immediate" "0")
11723 (set_attr "modrm" "0")])
11725 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11726 (define_insn "nops"
11727 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11731 int num = INTVAL (operands[0]);
11733 gcc_assert (num >= 1 && num <= 8);
11736 fputs ("\tnop\n", asm_out_file);
11740 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11741 (set_attr "length_immediate" "0")
11742 (set_attr "modrm" "0")])
11744 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11745 ;; branch prediction penalty for the third jump in a 16-byte
11749 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11752 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11753 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11755 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11756 The align insn is used to avoid 3 jump instructions in the row to improve
11757 branch prediction and the benefits hardly outweigh the cost of extra 8
11758 nops on the average inserted by full alignment pseudo operation. */
11762 [(set_attr "length" "16")])
11764 (define_expand "prologue"
11767 "ix86_expand_prologue (); DONE;")
11769 (define_insn "set_got"
11770 [(set (match_operand:SI 0 "register_operand" "=r")
11771 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11772 (clobber (reg:CC FLAGS_REG))]
11774 "* return output_set_got (operands[0], NULL_RTX);"
11775 [(set_attr "type" "multi")
11776 (set_attr "length" "12")])
11778 (define_insn "set_got_labelled"
11779 [(set (match_operand:SI 0 "register_operand" "=r")
11780 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11782 (clobber (reg:CC FLAGS_REG))]
11784 "* return output_set_got (operands[0], operands[1]);"
11785 [(set_attr "type" "multi")
11786 (set_attr "length" "12")])
11788 (define_insn "set_got_rex64"
11789 [(set (match_operand:DI 0 "register_operand" "=r")
11790 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11792 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11793 [(set_attr "type" "lea")
11794 (set_attr "length_address" "4")
11795 (set_attr "mode" "DI")])
11797 (define_insn "set_rip_rex64"
11798 [(set (match_operand:DI 0 "register_operand" "=r")
11799 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11801 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11802 [(set_attr "type" "lea")
11803 (set_attr "length_address" "4")
11804 (set_attr "mode" "DI")])
11806 (define_insn "set_got_offset_rex64"
11807 [(set (match_operand:DI 0 "register_operand" "=r")
11809 [(label_ref (match_operand 1 "" ""))]
11810 UNSPEC_SET_GOT_OFFSET))]
11812 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11813 [(set_attr "type" "imov")
11814 (set_attr "length_immediate" "0")
11815 (set_attr "length_address" "8")
11816 (set_attr "mode" "DI")])
11818 (define_expand "epilogue"
11821 "ix86_expand_epilogue (1); DONE;")
11823 (define_expand "sibcall_epilogue"
11826 "ix86_expand_epilogue (0); DONE;")
11828 (define_expand "eh_return"
11829 [(use (match_operand 0 "register_operand" ""))]
11832 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11834 /* Tricky bit: we write the address of the handler to which we will
11835 be returning into someone else's stack frame, one word below the
11836 stack address we wish to restore. */
11837 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11838 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11839 tmp = gen_rtx_MEM (Pmode, tmp);
11840 emit_move_insn (tmp, ra);
11842 emit_jump_insn (gen_eh_return_internal ());
11847 (define_insn_and_split "eh_return_internal"
11851 "epilogue_completed"
11853 "ix86_expand_epilogue (2); DONE;")
11855 (define_insn "leave"
11856 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11857 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11858 (clobber (mem:BLK (scratch)))]
11861 [(set_attr "type" "leave")])
11863 (define_insn "leave_rex64"
11864 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11865 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11866 (clobber (mem:BLK (scratch)))]
11869 [(set_attr "type" "leave")])
11871 ;; Handle -fsplit-stack.
11873 (define_expand "split_stack_prologue"
11877 ix86_expand_split_stack_prologue ();
11881 ;; In order to support the call/return predictor, we use a return
11882 ;; instruction which the middle-end doesn't see.
11883 (define_insn "split_stack_return"
11884 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11885 UNSPECV_SPLIT_STACK_RETURN)]
11888 if (operands[0] == const0_rtx)
11893 [(set_attr "atom_unit" "jeu")
11894 (set_attr "modrm" "0")
11895 (set (attr "length")
11896 (if_then_else (match_operand:SI 0 "const0_operand" "")
11899 (set (attr "length_immediate")
11900 (if_then_else (match_operand:SI 0 "const0_operand" "")
11904 ;; If there are operand 0 bytes available on the stack, jump to
11907 (define_expand "split_stack_space_check"
11908 [(set (pc) (if_then_else
11909 (ltu (minus (reg SP_REG)
11910 (match_operand 0 "register_operand" ""))
11911 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11912 (label_ref (match_operand 1 "" ""))
11916 rtx reg, size, limit;
11918 reg = gen_reg_rtx (Pmode);
11919 size = force_reg (Pmode, operands[0]);
11920 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11921 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11922 UNSPEC_STACK_CHECK);
11923 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11924 ix86_expand_branch (GEU, reg, limit, operands[1]);
11929 ;; Bit manipulation instructions.
11931 (define_expand "ffs<mode>2"
11932 [(set (match_dup 2) (const_int -1))
11933 (parallel [(set (reg:CCZ FLAGS_REG)
11935 (match_operand:SWI48 1 "nonimmediate_operand" "")
11937 (set (match_operand:SWI48 0 "register_operand" "")
11938 (ctz:SWI48 (match_dup 1)))])
11939 (set (match_dup 0) (if_then_else:SWI48
11940 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11943 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11944 (clobber (reg:CC FLAGS_REG))])]
11947 if (<MODE>mode == SImode && !TARGET_CMOVE)
11949 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11952 operands[2] = gen_reg_rtx (<MODE>mode);
11955 (define_insn_and_split "ffssi2_no_cmove"
11956 [(set (match_operand:SI 0 "register_operand" "=r")
11957 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11958 (clobber (match_scratch:SI 2 "=&q"))
11959 (clobber (reg:CC FLAGS_REG))]
11962 "&& reload_completed"
11963 [(parallel [(set (reg:CCZ FLAGS_REG)
11964 (compare:CCZ (match_dup 1) (const_int 0)))
11965 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11966 (set (strict_low_part (match_dup 3))
11967 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11968 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11969 (clobber (reg:CC FLAGS_REG))])
11970 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11971 (clobber (reg:CC FLAGS_REG))])
11972 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11973 (clobber (reg:CC FLAGS_REG))])]
11975 operands[3] = gen_lowpart (QImode, operands[2]);
11976 ix86_expand_clear (operands[2]);
11979 (define_insn "*ffs<mode>_1"
11980 [(set (reg:CCZ FLAGS_REG)
11981 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11983 (set (match_operand:SWI48 0 "register_operand" "=r")
11984 (ctz:SWI48 (match_dup 1)))]
11986 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11987 [(set_attr "type" "alu1")
11988 (set_attr "prefix_0f" "1")
11989 (set_attr "mode" "<MODE>")])
11991 (define_insn "ctz<mode>2"
11992 [(set (match_operand:SWI248 0 "register_operand" "=r")
11993 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
11994 (clobber (reg:CC FLAGS_REG))]
11998 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12000 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12002 [(set_attr "type" "alu1")
12003 (set_attr "prefix_0f" "1")
12004 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12005 (set_attr "mode" "<MODE>")])
12007 (define_expand "clz<mode>2"
12009 [(set (match_operand:SWI248 0 "register_operand" "")
12012 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12013 (clobber (reg:CC FLAGS_REG))])
12015 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12016 (clobber (reg:CC FLAGS_REG))])]
12021 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12024 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12027 (define_insn "clz<mode>2_lzcnt"
12028 [(set (match_operand:SWI248 0 "register_operand" "=r")
12029 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12030 (clobber (reg:CC FLAGS_REG))]
12032 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12033 [(set_attr "prefix_rep" "1")
12034 (set_attr "type" "bitmanip")
12035 (set_attr "mode" "<MODE>")])
12037 ;; BMI instructions.
12038 (define_insn "*bmi_andn_<mode>"
12039 [(set (match_operand:SWI48 0 "register_operand" "=r")
12042 (match_operand:SWI48 1 "register_operand" "r"))
12043 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12044 (clobber (reg:CC FLAGS_REG))]
12046 "andn\t{%2, %1, %0|%0, %1, %2}"
12047 [(set_attr "type" "bitmanip")
12048 (set_attr "mode" "<MODE>")])
12050 (define_insn "bmi_bextr_<mode>"
12051 [(set (match_operand:SWI48 0 "register_operand" "=r")
12052 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12053 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12055 (clobber (reg:CC FLAGS_REG))]
12057 "bextr\t{%2, %1, %0|%0, %1, %2}"
12058 [(set_attr "type" "bitmanip")
12059 (set_attr "mode" "<MODE>")])
12061 (define_insn "*bmi_blsi_<mode>"
12062 [(set (match_operand:SWI48 0 "register_operand" "=r")
12065 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12067 (clobber (reg:CC FLAGS_REG))]
12069 "blsi\t{%1, %0|%0, %1}"
12070 [(set_attr "type" "bitmanip")
12071 (set_attr "mode" "<MODE>")])
12073 (define_insn "*bmi_blsmsk_<mode>"
12074 [(set (match_operand:SWI48 0 "register_operand" "=r")
12077 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12080 (clobber (reg:CC FLAGS_REG))]
12082 "blsmsk\t{%1, %0|%0, %1}"
12083 [(set_attr "type" "bitmanip")
12084 (set_attr "mode" "<MODE>")])
12086 (define_insn "*bmi_blsr_<mode>"
12087 [(set (match_operand:SWI48 0 "register_operand" "=r")
12090 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12093 (clobber (reg:CC FLAGS_REG))]
12095 "blsr\t{%1, %0|%0, %1}"
12096 [(set_attr "type" "bitmanip")
12097 (set_attr "mode" "<MODE>")])
12099 ;; BMI2 instructions.
12100 (define_insn "bmi2_bzhi_<mode>3"
12101 [(set (match_operand:SWI48 0 "register_operand" "=r")
12102 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12103 (lshiftrt:SWI48 (const_int -1)
12104 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12105 (clobber (reg:CC FLAGS_REG))]
12107 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12108 [(set_attr "type" "bitmanip")
12109 (set_attr "prefix" "vex")
12110 (set_attr "mode" "<MODE>")])
12112 (define_insn "bmi2_pdep_<mode>3"
12113 [(set (match_operand:SWI48 0 "register_operand" "=r")
12114 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12115 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12118 "pdep\t{%2, %1, %0|%0, %1, %2}"
12119 [(set_attr "type" "bitmanip")
12120 (set_attr "prefix" "vex")
12121 (set_attr "mode" "<MODE>")])
12123 (define_insn "bmi2_pext_<mode>3"
12124 [(set (match_operand:SWI48 0 "register_operand" "=r")
12125 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12126 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12129 "pext\t{%2, %1, %0|%0, %1, %2}"
12130 [(set_attr "type" "bitmanip")
12131 (set_attr "prefix" "vex")
12132 (set_attr "mode" "<MODE>")])
12134 ;; TBM instructions.
12135 (define_insn "tbm_bextri_<mode>"
12136 [(set (match_operand:SWI48 0 "register_operand" "=r")
12137 (zero_extract:SWI48
12138 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12139 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12140 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12141 (clobber (reg:CC FLAGS_REG))]
12144 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12145 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12147 [(set_attr "type" "bitmanip")
12148 (set_attr "mode" "<MODE>")])
12150 (define_insn "*tbm_blcfill_<mode>"
12151 [(set (match_operand:SWI48 0 "register_operand" "=r")
12154 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12157 (clobber (reg:CC FLAGS_REG))]
12159 "blcfill\t{%1, %0|%0, %1}"
12160 [(set_attr "type" "bitmanip")
12161 (set_attr "mode" "<MODE>")])
12163 (define_insn "*tbm_blci_<mode>"
12164 [(set (match_operand:SWI48 0 "register_operand" "=r")
12168 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12171 (clobber (reg:CC FLAGS_REG))]
12173 "blci\t{%1, %0|%0, %1}"
12174 [(set_attr "type" "bitmanip")
12175 (set_attr "mode" "<MODE>")])
12177 (define_insn "*tbm_blcic_<mode>"
12178 [(set (match_operand:SWI48 0 "register_operand" "=r")
12181 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12185 (clobber (reg:CC FLAGS_REG))]
12187 "blcic\t{%1, %0|%0, %1}"
12188 [(set_attr "type" "bitmanip")
12189 (set_attr "mode" "<MODE>")])
12191 (define_insn "*tbm_blcmsk_<mode>"
12192 [(set (match_operand:SWI48 0 "register_operand" "=r")
12195 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12198 (clobber (reg:CC FLAGS_REG))]
12200 "blcmsk\t{%1, %0|%0, %1}"
12201 [(set_attr "type" "bitmanip")
12202 (set_attr "mode" "<MODE>")])
12204 (define_insn "*tbm_blcs_<mode>"
12205 [(set (match_operand:SWI48 0 "register_operand" "=r")
12208 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12211 (clobber (reg:CC FLAGS_REG))]
12213 "blcs\t{%1, %0|%0, %1}"
12214 [(set_attr "type" "bitmanip")
12215 (set_attr "mode" "<MODE>")])
12217 (define_insn "*tbm_blsfill_<mode>"
12218 [(set (match_operand:SWI48 0 "register_operand" "=r")
12221 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12224 (clobber (reg:CC FLAGS_REG))]
12226 "blsfill\t{%1, %0|%0, %1}"
12227 [(set_attr "type" "bitmanip")
12228 (set_attr "mode" "<MODE>")])
12230 (define_insn "*tbm_blsic_<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 "blsic\t{%1, %0|%0, %1}"
12241 [(set_attr "type" "bitmanip")
12242 (set_attr "mode" "<MODE>")])
12244 (define_insn "*tbm_t1mskc_<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 "t1mskc\t{%1, %0|%0, %1}"
12255 [(set_attr "type" "bitmanip")
12256 (set_attr "mode" "<MODE>")])
12258 (define_insn "*tbm_tzmsk_<mode>"
12259 [(set (match_operand:SWI48 0 "register_operand" "=r")
12262 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12266 (clobber (reg:CC FLAGS_REG))]
12268 "tzmsk\t{%1, %0|%0, %1}"
12269 [(set_attr "type" "bitmanip")
12270 (set_attr "mode" "<MODE>")])
12272 (define_insn "bsr_rex64"
12273 [(set (match_operand:DI 0 "register_operand" "=r")
12274 (minus:DI (const_int 63)
12275 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12276 (clobber (reg:CC FLAGS_REG))]
12278 "bsr{q}\t{%1, %0|%0, %1}"
12279 [(set_attr "type" "alu1")
12280 (set_attr "prefix_0f" "1")
12281 (set_attr "mode" "DI")])
12284 [(set (match_operand:SI 0 "register_operand" "=r")
12285 (minus:SI (const_int 31)
12286 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12287 (clobber (reg:CC FLAGS_REG))]
12289 "bsr{l}\t{%1, %0|%0, %1}"
12290 [(set_attr "type" "alu1")
12291 (set_attr "prefix_0f" "1")
12292 (set_attr "mode" "SI")])
12294 (define_insn "*bsrhi"
12295 [(set (match_operand:HI 0 "register_operand" "=r")
12296 (minus:HI (const_int 15)
12297 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12298 (clobber (reg:CC FLAGS_REG))]
12300 "bsr{w}\t{%1, %0|%0, %1}"
12301 [(set_attr "type" "alu1")
12302 (set_attr "prefix_0f" "1")
12303 (set_attr "mode" "HI")])
12305 (define_insn "popcount<mode>2"
12306 [(set (match_operand:SWI248 0 "register_operand" "=r")
12308 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12309 (clobber (reg:CC FLAGS_REG))]
12313 return "popcnt\t{%1, %0|%0, %1}";
12315 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12318 [(set_attr "prefix_rep" "1")
12319 (set_attr "type" "bitmanip")
12320 (set_attr "mode" "<MODE>")])
12322 (define_insn "*popcount<mode>2_cmp"
12323 [(set (reg FLAGS_REG)
12326 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12328 (set (match_operand:SWI248 0 "register_operand" "=r")
12329 (popcount:SWI248 (match_dup 1)))]
12330 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12333 return "popcnt\t{%1, %0|%0, %1}";
12335 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12338 [(set_attr "prefix_rep" "1")
12339 (set_attr "type" "bitmanip")
12340 (set_attr "mode" "<MODE>")])
12342 (define_insn "*popcountsi2_cmp_zext"
12343 [(set (reg FLAGS_REG)
12345 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12347 (set (match_operand:DI 0 "register_operand" "=r")
12348 (zero_extend:DI(popcount:SI (match_dup 1))))]
12349 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12352 return "popcnt\t{%1, %0|%0, %1}";
12354 return "popcnt{l}\t{%1, %0|%0, %1}";
12357 [(set_attr "prefix_rep" "1")
12358 (set_attr "type" "bitmanip")
12359 (set_attr "mode" "SI")])
12361 (define_expand "bswap<mode>2"
12362 [(set (match_operand:SWI48 0 "register_operand" "")
12363 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12366 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12368 rtx x = operands[0];
12370 emit_move_insn (x, operands[1]);
12371 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12372 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12373 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12378 (define_insn "*bswap<mode>2_movbe"
12379 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12380 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12382 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12385 movbe\t{%1, %0|%0, %1}
12386 movbe\t{%1, %0|%0, %1}"
12387 [(set_attr "type" "bitmanip,imov,imov")
12388 (set_attr "modrm" "0,1,1")
12389 (set_attr "prefix_0f" "*,1,1")
12390 (set_attr "prefix_extra" "*,1,1")
12391 (set_attr "mode" "<MODE>")])
12393 (define_insn "*bswap<mode>2_1"
12394 [(set (match_operand:SWI48 0 "register_operand" "=r")
12395 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12398 [(set_attr "type" "bitmanip")
12399 (set_attr "modrm" "0")
12400 (set_attr "mode" "<MODE>")])
12402 (define_insn "*bswaphi_lowpart_1"
12403 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12404 (bswap:HI (match_dup 0)))
12405 (clobber (reg:CC FLAGS_REG))]
12406 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12408 xchg{b}\t{%h0, %b0|%b0, %h0}
12409 rol{w}\t{$8, %0|%0, 8}"
12410 [(set_attr "length" "2,4")
12411 (set_attr "mode" "QI,HI")])
12413 (define_insn "bswaphi_lowpart"
12414 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12415 (bswap:HI (match_dup 0)))
12416 (clobber (reg:CC FLAGS_REG))]
12418 "rol{w}\t{$8, %0|%0, 8}"
12419 [(set_attr "length" "4")
12420 (set_attr "mode" "HI")])
12422 (define_expand "paritydi2"
12423 [(set (match_operand:DI 0 "register_operand" "")
12424 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12427 rtx scratch = gen_reg_rtx (QImode);
12430 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12431 NULL_RTX, operands[1]));
12433 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12434 gen_rtx_REG (CCmode, FLAGS_REG),
12436 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12439 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12442 rtx tmp = gen_reg_rtx (SImode);
12444 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12445 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12450 (define_expand "paritysi2"
12451 [(set (match_operand:SI 0 "register_operand" "")
12452 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12455 rtx scratch = gen_reg_rtx (QImode);
12458 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12460 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12461 gen_rtx_REG (CCmode, FLAGS_REG),
12463 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12465 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12469 (define_insn_and_split "paritydi2_cmp"
12470 [(set (reg:CC FLAGS_REG)
12471 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12473 (clobber (match_scratch:DI 0 "=r"))
12474 (clobber (match_scratch:SI 1 "=&r"))
12475 (clobber (match_scratch:HI 2 "=Q"))]
12478 "&& reload_completed"
12480 [(set (match_dup 1)
12481 (xor:SI (match_dup 1) (match_dup 4)))
12482 (clobber (reg:CC FLAGS_REG))])
12484 [(set (reg:CC FLAGS_REG)
12485 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12486 (clobber (match_dup 1))
12487 (clobber (match_dup 2))])]
12489 operands[4] = gen_lowpart (SImode, operands[3]);
12493 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12494 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12497 operands[1] = gen_highpart (SImode, operands[3]);
12500 (define_insn_and_split "paritysi2_cmp"
12501 [(set (reg:CC FLAGS_REG)
12502 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12504 (clobber (match_scratch:SI 0 "=r"))
12505 (clobber (match_scratch:HI 1 "=&Q"))]
12508 "&& reload_completed"
12510 [(set (match_dup 1)
12511 (xor:HI (match_dup 1) (match_dup 3)))
12512 (clobber (reg:CC FLAGS_REG))])
12514 [(set (reg:CC FLAGS_REG)
12515 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12516 (clobber (match_dup 1))])]
12518 operands[3] = gen_lowpart (HImode, operands[2]);
12520 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12521 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12524 (define_insn "*parityhi2_cmp"
12525 [(set (reg:CC FLAGS_REG)
12526 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12528 (clobber (match_scratch:HI 0 "=Q"))]
12530 "xor{b}\t{%h0, %b0|%b0, %h0}"
12531 [(set_attr "length" "2")
12532 (set_attr "mode" "HI")])
12535 ;; Thread-local storage patterns for ELF.
12537 ;; Note that these code sequences must appear exactly as shown
12538 ;; in order to allow linker relaxation.
12540 (define_insn "*tls_global_dynamic_32_gnu"
12541 [(set (match_operand:SI 0 "register_operand" "=a")
12543 [(match_operand:SI 1 "register_operand" "b")
12544 (match_operand:SI 2 "tls_symbolic_operand" "")
12545 (match_operand:SI 3 "constant_call_address_operand" "z")]
12547 (clobber (match_scratch:SI 4 "=d"))
12548 (clobber (match_scratch:SI 5 "=c"))
12549 (clobber (reg:CC FLAGS_REG))]
12550 "!TARGET_64BIT && TARGET_GNU_TLS"
12553 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12554 if (TARGET_SUN_TLS)
12555 #ifdef HAVE_AS_IX86_TLSGDPLT
12556 return "call\t%a2@tlsgdplt";
12558 return "call\t%p3@plt";
12560 return "call\t%P3";
12562 [(set_attr "type" "multi")
12563 (set_attr "length" "12")])
12565 (define_expand "tls_global_dynamic_32"
12567 [(set (match_operand:SI 0 "register_operand" "")
12568 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12569 (match_operand:SI 1 "tls_symbolic_operand" "")
12570 (match_operand:SI 3 "constant_call_address_operand" "")]
12572 (clobber (match_scratch:SI 4 ""))
12573 (clobber (match_scratch:SI 5 ""))
12574 (clobber (reg:CC FLAGS_REG))])])
12576 (define_insn "*tls_global_dynamic_64"
12577 [(set (match_operand:DI 0 "register_operand" "=a")
12579 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12580 (match_operand:DI 3 "" "")))
12581 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12586 fputs (ASM_BYTE "0x66\n", asm_out_file);
12588 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12589 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12590 fputs ("\trex64\n", asm_out_file);
12591 if (TARGET_SUN_TLS)
12592 return "call\t%p2@plt";
12593 return "call\t%P2";
12595 [(set_attr "type" "multi")
12596 (set (attr "length")
12597 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12599 (define_expand "tls_global_dynamic_64"
12601 [(set (match_operand:DI 0 "register_operand" "")
12603 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12605 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12608 (define_insn "*tls_local_dynamic_base_32_gnu"
12609 [(set (match_operand:SI 0 "register_operand" "=a")
12611 [(match_operand:SI 1 "register_operand" "b")
12612 (match_operand:SI 2 "constant_call_address_operand" "z")]
12613 UNSPEC_TLS_LD_BASE))
12614 (clobber (match_scratch:SI 3 "=d"))
12615 (clobber (match_scratch:SI 4 "=c"))
12616 (clobber (reg:CC FLAGS_REG))]
12617 "!TARGET_64BIT && TARGET_GNU_TLS"
12620 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12621 if (TARGET_SUN_TLS)
12622 #ifdef HAVE_AS_IX86_TLSLDMPLT
12623 return "call\t%&@tlsldmplt";
12625 return "call\t%p2@plt";
12627 return "call\t%P2";
12629 [(set_attr "type" "multi")
12630 (set_attr "length" "11")])
12632 (define_expand "tls_local_dynamic_base_32"
12634 [(set (match_operand:SI 0 "register_operand" "")
12636 [(match_operand:SI 1 "register_operand" "")
12637 (match_operand:SI 2 "constant_call_address_operand" "")]
12638 UNSPEC_TLS_LD_BASE))
12639 (clobber (match_scratch:SI 3 ""))
12640 (clobber (match_scratch:SI 4 ""))
12641 (clobber (reg:CC FLAGS_REG))])])
12643 (define_insn "*tls_local_dynamic_base_64"
12644 [(set (match_operand:DI 0 "register_operand" "=a")
12646 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12647 (match_operand:DI 2 "" "")))
12648 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12652 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12653 if (TARGET_SUN_TLS)
12654 return "call\t%p1@plt";
12655 return "call\t%P1";
12657 [(set_attr "type" "multi")
12658 (set_attr "length" "12")])
12660 (define_expand "tls_local_dynamic_base_64"
12662 [(set (match_operand:DI 0 "register_operand" "")
12664 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12666 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12668 ;; Local dynamic of a single variable is a lose. Show combine how
12669 ;; to convert that back to global dynamic.
12671 (define_insn_and_split "*tls_local_dynamic_32_once"
12672 [(set (match_operand:SI 0 "register_operand" "=a")
12674 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12675 (match_operand:SI 2 "constant_call_address_operand" "z")]
12676 UNSPEC_TLS_LD_BASE)
12677 (const:SI (unspec:SI
12678 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12680 (clobber (match_scratch:SI 4 "=d"))
12681 (clobber (match_scratch:SI 5 "=c"))
12682 (clobber (reg:CC FLAGS_REG))]
12687 [(set (match_dup 0)
12688 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12690 (clobber (match_dup 4))
12691 (clobber (match_dup 5))
12692 (clobber (reg:CC FLAGS_REG))])])
12694 ;; Segment register for the thread base ptr load
12695 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12697 ;; Load and add the thread base pointer from %<tp_seg>:0.
12698 (define_insn "*load_tp_x32"
12699 [(set (match_operand:SI 0 "register_operand" "=r")
12700 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12702 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12703 [(set_attr "type" "imov")
12704 (set_attr "modrm" "0")
12705 (set_attr "length" "7")
12706 (set_attr "memory" "load")
12707 (set_attr "imm_disp" "false")])
12709 (define_insn "*load_tp_x32_zext"
12710 [(set (match_operand:DI 0 "register_operand" "=r")
12711 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12713 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12714 [(set_attr "type" "imov")
12715 (set_attr "modrm" "0")
12716 (set_attr "length" "7")
12717 (set_attr "memory" "load")
12718 (set_attr "imm_disp" "false")])
12720 (define_insn "*load_tp_<mode>"
12721 [(set (match_operand:P 0 "register_operand" "=r")
12722 (unspec:P [(const_int 0)] UNSPEC_TP))]
12724 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12725 [(set_attr "type" "imov")
12726 (set_attr "modrm" "0")
12727 (set_attr "length" "7")
12728 (set_attr "memory" "load")
12729 (set_attr "imm_disp" "false")])
12731 (define_insn "*add_tp_x32"
12732 [(set (match_operand:SI 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, %0|%0, 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_x32_zext"
12745 [(set (match_operand:DI 0 "register_operand" "=r")
12747 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12748 (match_operand:SI 1 "register_operand" "0"))))
12749 (clobber (reg:CC FLAGS_REG))]
12751 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12752 [(set_attr "type" "alu")
12753 (set_attr "modrm" "0")
12754 (set_attr "length" "7")
12755 (set_attr "memory" "load")
12756 (set_attr "imm_disp" "false")])
12758 (define_insn "*add_tp_<mode>"
12759 [(set (match_operand:P 0 "register_operand" "=r")
12760 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12761 (match_operand:P 1 "register_operand" "0")))
12762 (clobber (reg:CC FLAGS_REG))]
12764 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12765 [(set_attr "type" "alu")
12766 (set_attr "modrm" "0")
12767 (set_attr "length" "7")
12768 (set_attr "memory" "load")
12769 (set_attr "imm_disp" "false")])
12771 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12772 ;; %rax as destination of the initial executable code sequence.
12773 (define_insn "tls_initial_exec_64_sun"
12774 [(set (match_operand:DI 0 "register_operand" "=a")
12776 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12777 UNSPEC_TLS_IE_SUN))
12778 (clobber (reg:CC FLAGS_REG))]
12779 "TARGET_64BIT && TARGET_SUN_TLS"
12782 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12783 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12785 [(set_attr "type" "multi")])
12787 ;; When Pmode == SImode, there may be no REX prefix for ADD. Avoid
12788 ;; any instructions between MOV and ADD, which may interfere linker
12789 ;; IE->LE optimization, since the last byte of the previous instruction
12790 ;; before ADD may look like a REX prefix. This also avoids
12791 ;; movl x@gottpoff(%rip), %reg32
12792 ;; movl $fs:(%reg32), %reg32
12793 ;; Since address override works only on the (reg32) part in fs:(reg32),
12794 ;; we can't use it as memory operand.
12795 (define_insn "tls_initial_exec_x32"
12796 [(set (match_operand:SI 0 "register_operand" "=r")
12798 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12799 UNSPEC_TLS_IE_X32))
12800 (clobber (reg:CC FLAGS_REG))]
12804 ("mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}", operands);
12805 return "add{l}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12807 [(set_attr "type" "multi")])
12809 ;; GNU2 TLS patterns can be split.
12811 (define_expand "tls_dynamic_gnu2_32"
12812 [(set (match_dup 3)
12813 (plus:SI (match_operand:SI 2 "register_operand" "")
12815 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12818 [(set (match_operand:SI 0 "register_operand" "")
12819 (unspec:SI [(match_dup 1) (match_dup 3)
12820 (match_dup 2) (reg:SI SP_REG)]
12822 (clobber (reg:CC FLAGS_REG))])]
12823 "!TARGET_64BIT && TARGET_GNU2_TLS"
12825 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12826 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12829 (define_insn "*tls_dynamic_gnu2_lea_32"
12830 [(set (match_operand:SI 0 "register_operand" "=r")
12831 (plus:SI (match_operand:SI 1 "register_operand" "b")
12833 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12834 UNSPEC_TLSDESC))))]
12835 "!TARGET_64BIT && TARGET_GNU2_TLS"
12836 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12837 [(set_attr "type" "lea")
12838 (set_attr "mode" "SI")
12839 (set_attr "length" "6")
12840 (set_attr "length_address" "4")])
12842 (define_insn "*tls_dynamic_gnu2_call_32"
12843 [(set (match_operand:SI 0 "register_operand" "=a")
12844 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12845 (match_operand:SI 2 "register_operand" "0")
12846 ;; we have to make sure %ebx still points to the GOT
12847 (match_operand:SI 3 "register_operand" "b")
12850 (clobber (reg:CC FLAGS_REG))]
12851 "!TARGET_64BIT && TARGET_GNU2_TLS"
12852 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12853 [(set_attr "type" "call")
12854 (set_attr "length" "2")
12855 (set_attr "length_address" "0")])
12857 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12858 [(set (match_operand:SI 0 "register_operand" "=&a")
12860 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12861 (match_operand:SI 4 "" "")
12862 (match_operand:SI 2 "register_operand" "b")
12865 (const:SI (unspec:SI
12866 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12868 (clobber (reg:CC FLAGS_REG))]
12869 "!TARGET_64BIT && TARGET_GNU2_TLS"
12872 [(set (match_dup 0) (match_dup 5))]
12874 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12875 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12878 (define_expand "tls_dynamic_gnu2_64"
12879 [(set (match_dup 2)
12880 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12883 [(set (match_operand:DI 0 "register_operand" "")
12884 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12886 (clobber (reg:CC FLAGS_REG))])]
12887 "TARGET_64BIT && TARGET_GNU2_TLS"
12889 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12890 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12893 (define_insn "*tls_dynamic_gnu2_lea_64"
12894 [(set (match_operand:DI 0 "register_operand" "=r")
12895 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12897 "TARGET_64BIT && TARGET_GNU2_TLS"
12898 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12899 [(set_attr "type" "lea")
12900 (set_attr "mode" "DI")
12901 (set_attr "length" "7")
12902 (set_attr "length_address" "4")])
12904 (define_insn "*tls_dynamic_gnu2_call_64"
12905 [(set (match_operand:DI 0 "register_operand" "=a")
12906 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12907 (match_operand:DI 2 "register_operand" "0")
12910 (clobber (reg:CC FLAGS_REG))]
12911 "TARGET_64BIT && TARGET_GNU2_TLS"
12912 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12913 [(set_attr "type" "call")
12914 (set_attr "length" "2")
12915 (set_attr "length_address" "0")])
12917 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12918 [(set (match_operand:DI 0 "register_operand" "=&a")
12920 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12921 (match_operand:DI 3 "" "")
12924 (const:DI (unspec:DI
12925 [(match_operand 1 "tls_symbolic_operand" "")]
12927 (clobber (reg:CC FLAGS_REG))]
12928 "TARGET_64BIT && TARGET_GNU2_TLS"
12931 [(set (match_dup 0) (match_dup 4))]
12933 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12934 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12937 ;; These patterns match the binary 387 instructions for addM3, subM3,
12938 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12939 ;; SFmode. The first is the normal insn, the second the same insn but
12940 ;; with one operand a conversion, and the third the same insn but with
12941 ;; the other operand a conversion. The conversion may be SFmode or
12942 ;; SImode if the target mode DFmode, but only SImode if the target mode
12945 ;; Gcc is slightly more smart about handling normal two address instructions
12946 ;; so use special patterns for add and mull.
12948 (define_insn "*fop_<mode>_comm_mixed"
12949 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12950 (match_operator:MODEF 3 "binary_fp_operator"
12951 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12952 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12953 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12954 && COMMUTATIVE_ARITH_P (operands[3])
12955 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12956 "* return output_387_binary_op (insn, operands);"
12957 [(set (attr "type")
12958 (if_then_else (eq_attr "alternative" "1,2")
12959 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12960 (const_string "ssemul")
12961 (const_string "sseadd"))
12962 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12963 (const_string "fmul")
12964 (const_string "fop"))))
12965 (set_attr "isa" "*,noavx,avx")
12966 (set_attr "prefix" "orig,orig,vex")
12967 (set_attr "mode" "<MODE>")])
12969 (define_insn "*fop_<mode>_comm_sse"
12970 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12971 (match_operator:MODEF 3 "binary_fp_operator"
12972 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12973 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12974 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12975 && COMMUTATIVE_ARITH_P (operands[3])
12976 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12977 "* return output_387_binary_op (insn, operands);"
12978 [(set (attr "type")
12979 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12980 (const_string "ssemul")
12981 (const_string "sseadd")))
12982 (set_attr "isa" "noavx,avx")
12983 (set_attr "prefix" "orig,vex")
12984 (set_attr "mode" "<MODE>")])
12986 (define_insn "*fop_<mode>_comm_i387"
12987 [(set (match_operand:MODEF 0 "register_operand" "=f")
12988 (match_operator:MODEF 3 "binary_fp_operator"
12989 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12990 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12991 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12992 && COMMUTATIVE_ARITH_P (operands[3])
12993 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12994 "* return output_387_binary_op (insn, operands);"
12995 [(set (attr "type")
12996 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12997 (const_string "fmul")
12998 (const_string "fop")))
12999 (set_attr "mode" "<MODE>")])
13001 (define_insn "*fop_<mode>_1_mixed"
13002 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13003 (match_operator:MODEF 3 "binary_fp_operator"
13004 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13005 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13006 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13007 && !COMMUTATIVE_ARITH_P (operands[3])
13008 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13009 "* return output_387_binary_op (insn, operands);"
13010 [(set (attr "type")
13011 (cond [(and (eq_attr "alternative" "2,3")
13012 (match_operand:MODEF 3 "mult_operator" ""))
13013 (const_string "ssemul")
13014 (and (eq_attr "alternative" "2,3")
13015 (match_operand:MODEF 3 "div_operator" ""))
13016 (const_string "ssediv")
13017 (eq_attr "alternative" "2,3")
13018 (const_string "sseadd")
13019 (match_operand:MODEF 3 "mult_operator" "")
13020 (const_string "fmul")
13021 (match_operand:MODEF 3 "div_operator" "")
13022 (const_string "fdiv")
13024 (const_string "fop")))
13025 (set_attr "isa" "*,*,noavx,avx")
13026 (set_attr "prefix" "orig,orig,orig,vex")
13027 (set_attr "mode" "<MODE>")])
13029 (define_insn "*rcpsf2_sse"
13030 [(set (match_operand:SF 0 "register_operand" "=x")
13031 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13034 "%vrcpss\t{%1, %d0|%d0, %1}"
13035 [(set_attr "type" "sse")
13036 (set_attr "atom_sse_attr" "rcp")
13037 (set_attr "prefix" "maybe_vex")
13038 (set_attr "mode" "SF")])
13040 (define_insn "*fop_<mode>_1_sse"
13041 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13042 (match_operator:MODEF 3 "binary_fp_operator"
13043 [(match_operand:MODEF 1 "register_operand" "0,x")
13044 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13045 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13046 && !COMMUTATIVE_ARITH_P (operands[3])"
13047 "* return output_387_binary_op (insn, operands);"
13048 [(set (attr "type")
13049 (cond [(match_operand:MODEF 3 "mult_operator" "")
13050 (const_string "ssemul")
13051 (match_operand:MODEF 3 "div_operator" "")
13052 (const_string "ssediv")
13054 (const_string "sseadd")))
13055 (set_attr "isa" "noavx,avx")
13056 (set_attr "prefix" "orig,vex")
13057 (set_attr "mode" "<MODE>")])
13059 ;; This pattern is not fully shadowed by the pattern above.
13060 (define_insn "*fop_<mode>_1_i387"
13061 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13062 (match_operator:MODEF 3 "binary_fp_operator"
13063 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13064 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13065 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13066 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13067 && !COMMUTATIVE_ARITH_P (operands[3])
13068 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13069 "* return output_387_binary_op (insn, operands);"
13070 [(set (attr "type")
13071 (cond [(match_operand:MODEF 3 "mult_operator" "")
13072 (const_string "fmul")
13073 (match_operand:MODEF 3 "div_operator" "")
13074 (const_string "fdiv")
13076 (const_string "fop")))
13077 (set_attr "mode" "<MODE>")])
13079 ;; ??? Add SSE splitters for these!
13080 (define_insn "*fop_<MODEF:mode>_2_i387"
13081 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13082 (match_operator:MODEF 3 "binary_fp_operator"
13084 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13085 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13086 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13087 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13088 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13089 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13090 [(set (attr "type")
13091 (cond [(match_operand:MODEF 3 "mult_operator" "")
13092 (const_string "fmul")
13093 (match_operand:MODEF 3 "div_operator" "")
13094 (const_string "fdiv")
13096 (const_string "fop")))
13097 (set_attr "fp_int_src" "true")
13098 (set_attr "mode" "<SWI24:MODE>")])
13100 (define_insn "*fop_<MODEF:mode>_3_i387"
13101 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13102 (match_operator:MODEF 3 "binary_fp_operator"
13103 [(match_operand:MODEF 1 "register_operand" "0,0")
13105 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13106 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13107 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13108 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13109 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13110 [(set (attr "type")
13111 (cond [(match_operand:MODEF 3 "mult_operator" "")
13112 (const_string "fmul")
13113 (match_operand:MODEF 3 "div_operator" "")
13114 (const_string "fdiv")
13116 (const_string "fop")))
13117 (set_attr "fp_int_src" "true")
13118 (set_attr "mode" "<MODE>")])
13120 (define_insn "*fop_df_4_i387"
13121 [(set (match_operand:DF 0 "register_operand" "=f,f")
13122 (match_operator:DF 3 "binary_fp_operator"
13124 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13125 (match_operand:DF 2 "register_operand" "0,f")]))]
13126 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13127 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13128 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13129 "* return output_387_binary_op (insn, operands);"
13130 [(set (attr "type")
13131 (cond [(match_operand:DF 3 "mult_operator" "")
13132 (const_string "fmul")
13133 (match_operand:DF 3 "div_operator" "")
13134 (const_string "fdiv")
13136 (const_string "fop")))
13137 (set_attr "mode" "SF")])
13139 (define_insn "*fop_df_5_i387"
13140 [(set (match_operand:DF 0 "register_operand" "=f,f")
13141 (match_operator:DF 3 "binary_fp_operator"
13142 [(match_operand:DF 1 "register_operand" "0,f")
13144 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13145 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13146 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13147 "* return output_387_binary_op (insn, operands);"
13148 [(set (attr "type")
13149 (cond [(match_operand:DF 3 "mult_operator" "")
13150 (const_string "fmul")
13151 (match_operand:DF 3 "div_operator" "")
13152 (const_string "fdiv")
13154 (const_string "fop")))
13155 (set_attr "mode" "SF")])
13157 (define_insn "*fop_df_6_i387"
13158 [(set (match_operand:DF 0 "register_operand" "=f,f")
13159 (match_operator:DF 3 "binary_fp_operator"
13161 (match_operand:SF 1 "register_operand" "0,f"))
13163 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13164 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13165 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13166 "* return output_387_binary_op (insn, operands);"
13167 [(set (attr "type")
13168 (cond [(match_operand:DF 3 "mult_operator" "")
13169 (const_string "fmul")
13170 (match_operand:DF 3 "div_operator" "")
13171 (const_string "fdiv")
13173 (const_string "fop")))
13174 (set_attr "mode" "SF")])
13176 (define_insn "*fop_xf_comm_i387"
13177 [(set (match_operand:XF 0 "register_operand" "=f")
13178 (match_operator:XF 3 "binary_fp_operator"
13179 [(match_operand:XF 1 "register_operand" "%0")
13180 (match_operand:XF 2 "register_operand" "f")]))]
13182 && COMMUTATIVE_ARITH_P (operands[3])"
13183 "* return output_387_binary_op (insn, operands);"
13184 [(set (attr "type")
13185 (if_then_else (match_operand:XF 3 "mult_operator" "")
13186 (const_string "fmul")
13187 (const_string "fop")))
13188 (set_attr "mode" "XF")])
13190 (define_insn "*fop_xf_1_i387"
13191 [(set (match_operand:XF 0 "register_operand" "=f,f")
13192 (match_operator:XF 3 "binary_fp_operator"
13193 [(match_operand:XF 1 "register_operand" "0,f")
13194 (match_operand:XF 2 "register_operand" "f,0")]))]
13196 && !COMMUTATIVE_ARITH_P (operands[3])"
13197 "* return output_387_binary_op (insn, operands);"
13198 [(set (attr "type")
13199 (cond [(match_operand:XF 3 "mult_operator" "")
13200 (const_string "fmul")
13201 (match_operand:XF 3 "div_operator" "")
13202 (const_string "fdiv")
13204 (const_string "fop")))
13205 (set_attr "mode" "XF")])
13207 (define_insn "*fop_xf_2_i387"
13208 [(set (match_operand:XF 0 "register_operand" "=f,f")
13209 (match_operator:XF 3 "binary_fp_operator"
13211 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13212 (match_operand:XF 2 "register_operand" "0,0")]))]
13213 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13214 "* return which_alternative ? \"#\" : 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 "fp_int_src" "true")
13223 (set_attr "mode" "<MODE>")])
13225 (define_insn "*fop_xf_3_i387"
13226 [(set (match_operand:XF 0 "register_operand" "=f,f")
13227 (match_operator:XF 3 "binary_fp_operator"
13228 [(match_operand:XF 1 "register_operand" "0,0")
13230 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13231 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13232 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13233 [(set (attr "type")
13234 (cond [(match_operand:XF 3 "mult_operator" "")
13235 (const_string "fmul")
13236 (match_operand:XF 3 "div_operator" "")
13237 (const_string "fdiv")
13239 (const_string "fop")))
13240 (set_attr "fp_int_src" "true")
13241 (set_attr "mode" "<MODE>")])
13243 (define_insn "*fop_xf_4_i387"
13244 [(set (match_operand:XF 0 "register_operand" "=f,f")
13245 (match_operator:XF 3 "binary_fp_operator"
13247 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13248 (match_operand:XF 2 "register_operand" "0,f")]))]
13250 "* return output_387_binary_op (insn, operands);"
13251 [(set (attr "type")
13252 (cond [(match_operand:XF 3 "mult_operator" "")
13253 (const_string "fmul")
13254 (match_operand:XF 3 "div_operator" "")
13255 (const_string "fdiv")
13257 (const_string "fop")))
13258 (set_attr "mode" "<MODE>")])
13260 (define_insn "*fop_xf_5_i387"
13261 [(set (match_operand:XF 0 "register_operand" "=f,f")
13262 (match_operator:XF 3 "binary_fp_operator"
13263 [(match_operand:XF 1 "register_operand" "0,f")
13265 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13267 "* return output_387_binary_op (insn, operands);"
13268 [(set (attr "type")
13269 (cond [(match_operand:XF 3 "mult_operator" "")
13270 (const_string "fmul")
13271 (match_operand:XF 3 "div_operator" "")
13272 (const_string "fdiv")
13274 (const_string "fop")))
13275 (set_attr "mode" "<MODE>")])
13277 (define_insn "*fop_xf_6_i387"
13278 [(set (match_operand:XF 0 "register_operand" "=f,f")
13279 (match_operator:XF 3 "binary_fp_operator"
13281 (match_operand:MODEF 1 "register_operand" "0,f"))
13283 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13285 "* return output_387_binary_op (insn, operands);"
13286 [(set (attr "type")
13287 (cond [(match_operand:XF 3 "mult_operator" "")
13288 (const_string "fmul")
13289 (match_operand:XF 3 "div_operator" "")
13290 (const_string "fdiv")
13292 (const_string "fop")))
13293 (set_attr "mode" "<MODE>")])
13296 [(set (match_operand 0 "register_operand" "")
13297 (match_operator 3 "binary_fp_operator"
13298 [(float (match_operand:SWI24 1 "register_operand" ""))
13299 (match_operand 2 "register_operand" "")]))]
13301 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13302 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13305 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13306 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13307 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13308 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13309 GET_MODE (operands[3]),
13312 ix86_free_from_memory (GET_MODE (operands[1]));
13317 [(set (match_operand 0 "register_operand" "")
13318 (match_operator 3 "binary_fp_operator"
13319 [(match_operand 1 "register_operand" "")
13320 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13322 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13323 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13326 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13327 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13328 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13329 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13330 GET_MODE (operands[3]),
13333 ix86_free_from_memory (GET_MODE (operands[2]));
13337 ;; FPU special functions.
13339 ;; This pattern implements a no-op XFmode truncation for
13340 ;; all fancy i386 XFmode math functions.
13342 (define_insn "truncxf<mode>2_i387_noop_unspec"
13343 [(set (match_operand:MODEF 0 "register_operand" "=f")
13344 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13345 UNSPEC_TRUNC_NOOP))]
13346 "TARGET_USE_FANCY_MATH_387"
13347 "* return output_387_reg_move (insn, operands);"
13348 [(set_attr "type" "fmov")
13349 (set_attr "mode" "<MODE>")])
13351 (define_insn "sqrtxf2"
13352 [(set (match_operand:XF 0 "register_operand" "=f")
13353 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13354 "TARGET_USE_FANCY_MATH_387"
13356 [(set_attr "type" "fpspc")
13357 (set_attr "mode" "XF")
13358 (set_attr "athlon_decode" "direct")
13359 (set_attr "amdfam10_decode" "direct")
13360 (set_attr "bdver1_decode" "direct")])
13362 (define_insn "sqrt_extend<mode>xf2_i387"
13363 [(set (match_operand:XF 0 "register_operand" "=f")
13366 (match_operand:MODEF 1 "register_operand" "0"))))]
13367 "TARGET_USE_FANCY_MATH_387"
13369 [(set_attr "type" "fpspc")
13370 (set_attr "mode" "XF")
13371 (set_attr "athlon_decode" "direct")
13372 (set_attr "amdfam10_decode" "direct")
13373 (set_attr "bdver1_decode" "direct")])
13375 (define_insn "*rsqrtsf2_sse"
13376 [(set (match_operand:SF 0 "register_operand" "=x")
13377 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13380 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13381 [(set_attr "type" "sse")
13382 (set_attr "atom_sse_attr" "rcp")
13383 (set_attr "prefix" "maybe_vex")
13384 (set_attr "mode" "SF")])
13386 (define_expand "rsqrtsf2"
13387 [(set (match_operand:SF 0 "register_operand" "")
13388 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13392 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13396 (define_insn "*sqrt<mode>2_sse"
13397 [(set (match_operand:MODEF 0 "register_operand" "=x")
13399 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13400 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13401 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13402 [(set_attr "type" "sse")
13403 (set_attr "atom_sse_attr" "sqrt")
13404 (set_attr "prefix" "maybe_vex")
13405 (set_attr "mode" "<MODE>")
13406 (set_attr "athlon_decode" "*")
13407 (set_attr "amdfam10_decode" "*")
13408 (set_attr "bdver1_decode" "*")])
13410 (define_expand "sqrt<mode>2"
13411 [(set (match_operand:MODEF 0 "register_operand" "")
13413 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13414 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13415 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13417 if (<MODE>mode == SFmode
13419 && TARGET_RECIP_SQRT
13420 && !optimize_function_for_size_p (cfun)
13421 && flag_finite_math_only && !flag_trapping_math
13422 && flag_unsafe_math_optimizations)
13424 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13428 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13430 rtx op0 = gen_reg_rtx (XFmode);
13431 rtx op1 = force_reg (<MODE>mode, operands[1]);
13433 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13434 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13439 (define_insn "fpremxf4_i387"
13440 [(set (match_operand:XF 0 "register_operand" "=f")
13441 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13442 (match_operand:XF 3 "register_operand" "1")]
13444 (set (match_operand:XF 1 "register_operand" "=u")
13445 (unspec:XF [(match_dup 2) (match_dup 3)]
13447 (set (reg:CCFP FPSR_REG)
13448 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13450 "TARGET_USE_FANCY_MATH_387"
13452 [(set_attr "type" "fpspc")
13453 (set_attr "mode" "XF")])
13455 (define_expand "fmodxf3"
13456 [(use (match_operand:XF 0 "register_operand" ""))
13457 (use (match_operand:XF 1 "general_operand" ""))
13458 (use (match_operand:XF 2 "general_operand" ""))]
13459 "TARGET_USE_FANCY_MATH_387"
13461 rtx label = gen_label_rtx ();
13463 rtx op1 = gen_reg_rtx (XFmode);
13464 rtx op2 = gen_reg_rtx (XFmode);
13466 emit_move_insn (op2, operands[2]);
13467 emit_move_insn (op1, operands[1]);
13469 emit_label (label);
13470 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13471 ix86_emit_fp_unordered_jump (label);
13472 LABEL_NUSES (label) = 1;
13474 emit_move_insn (operands[0], op1);
13478 (define_expand "fmod<mode>3"
13479 [(use (match_operand:MODEF 0 "register_operand" ""))
13480 (use (match_operand:MODEF 1 "general_operand" ""))
13481 (use (match_operand:MODEF 2 "general_operand" ""))]
13482 "TARGET_USE_FANCY_MATH_387"
13484 rtx (*gen_truncxf) (rtx, rtx);
13486 rtx label = gen_label_rtx ();
13488 rtx op1 = gen_reg_rtx (XFmode);
13489 rtx op2 = gen_reg_rtx (XFmode);
13491 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13492 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13494 emit_label (label);
13495 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13496 ix86_emit_fp_unordered_jump (label);
13497 LABEL_NUSES (label) = 1;
13499 /* Truncate the result properly for strict SSE math. */
13500 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13501 && !TARGET_MIX_SSE_I387)
13502 gen_truncxf = gen_truncxf<mode>2;
13504 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13506 emit_insn (gen_truncxf (operands[0], op1));
13510 (define_insn "fprem1xf4_i387"
13511 [(set (match_operand:XF 0 "register_operand" "=f")
13512 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13513 (match_operand:XF 3 "register_operand" "1")]
13515 (set (match_operand:XF 1 "register_operand" "=u")
13516 (unspec:XF [(match_dup 2) (match_dup 3)]
13518 (set (reg:CCFP FPSR_REG)
13519 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13521 "TARGET_USE_FANCY_MATH_387"
13523 [(set_attr "type" "fpspc")
13524 (set_attr "mode" "XF")])
13526 (define_expand "remainderxf3"
13527 [(use (match_operand:XF 0 "register_operand" ""))
13528 (use (match_operand:XF 1 "general_operand" ""))
13529 (use (match_operand:XF 2 "general_operand" ""))]
13530 "TARGET_USE_FANCY_MATH_387"
13532 rtx label = gen_label_rtx ();
13534 rtx op1 = gen_reg_rtx (XFmode);
13535 rtx op2 = gen_reg_rtx (XFmode);
13537 emit_move_insn (op2, operands[2]);
13538 emit_move_insn (op1, operands[1]);
13540 emit_label (label);
13541 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13542 ix86_emit_fp_unordered_jump (label);
13543 LABEL_NUSES (label) = 1;
13545 emit_move_insn (operands[0], op1);
13549 (define_expand "remainder<mode>3"
13550 [(use (match_operand:MODEF 0 "register_operand" ""))
13551 (use (match_operand:MODEF 1 "general_operand" ""))
13552 (use (match_operand:MODEF 2 "general_operand" ""))]
13553 "TARGET_USE_FANCY_MATH_387"
13555 rtx (*gen_truncxf) (rtx, rtx);
13557 rtx label = gen_label_rtx ();
13559 rtx op1 = gen_reg_rtx (XFmode);
13560 rtx op2 = gen_reg_rtx (XFmode);
13562 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13563 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13565 emit_label (label);
13567 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13568 ix86_emit_fp_unordered_jump (label);
13569 LABEL_NUSES (label) = 1;
13571 /* Truncate the result properly for strict SSE math. */
13572 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13573 && !TARGET_MIX_SSE_I387)
13574 gen_truncxf = gen_truncxf<mode>2;
13576 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13578 emit_insn (gen_truncxf (operands[0], op1));
13582 (define_insn "*sinxf2_i387"
13583 [(set (match_operand:XF 0 "register_operand" "=f")
13584 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13585 "TARGET_USE_FANCY_MATH_387
13586 && flag_unsafe_math_optimizations"
13588 [(set_attr "type" "fpspc")
13589 (set_attr "mode" "XF")])
13591 (define_insn "*sin_extend<mode>xf2_i387"
13592 [(set (match_operand:XF 0 "register_operand" "=f")
13593 (unspec:XF [(float_extend:XF
13594 (match_operand:MODEF 1 "register_operand" "0"))]
13596 "TARGET_USE_FANCY_MATH_387
13597 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13598 || TARGET_MIX_SSE_I387)
13599 && flag_unsafe_math_optimizations"
13601 [(set_attr "type" "fpspc")
13602 (set_attr "mode" "XF")])
13604 (define_insn "*cosxf2_i387"
13605 [(set (match_operand:XF 0 "register_operand" "=f")
13606 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13607 "TARGET_USE_FANCY_MATH_387
13608 && flag_unsafe_math_optimizations"
13610 [(set_attr "type" "fpspc")
13611 (set_attr "mode" "XF")])
13613 (define_insn "*cos_extend<mode>xf2_i387"
13614 [(set (match_operand:XF 0 "register_operand" "=f")
13615 (unspec:XF [(float_extend:XF
13616 (match_operand:MODEF 1 "register_operand" "0"))]
13618 "TARGET_USE_FANCY_MATH_387
13619 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13620 || TARGET_MIX_SSE_I387)
13621 && flag_unsafe_math_optimizations"
13623 [(set_attr "type" "fpspc")
13624 (set_attr "mode" "XF")])
13626 ;; When sincos pattern is defined, sin and cos builtin functions will be
13627 ;; expanded to sincos pattern with one of its outputs left unused.
13628 ;; CSE pass will figure out if two sincos patterns can be combined,
13629 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13630 ;; depending on the unused output.
13632 (define_insn "sincosxf3"
13633 [(set (match_operand:XF 0 "register_operand" "=f")
13634 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13635 UNSPEC_SINCOS_COS))
13636 (set (match_operand:XF 1 "register_operand" "=u")
13637 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13638 "TARGET_USE_FANCY_MATH_387
13639 && flag_unsafe_math_optimizations"
13641 [(set_attr "type" "fpspc")
13642 (set_attr "mode" "XF")])
13645 [(set (match_operand:XF 0 "register_operand" "")
13646 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13647 UNSPEC_SINCOS_COS))
13648 (set (match_operand:XF 1 "register_operand" "")
13649 (unspec: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) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13655 [(set (match_operand:XF 0 "register_operand" "")
13656 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13657 UNSPEC_SINCOS_COS))
13658 (set (match_operand:XF 1 "register_operand" "")
13659 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13660 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13661 && can_create_pseudo_p ()"
13662 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13664 (define_insn "sincos_extend<mode>xf3_i387"
13665 [(set (match_operand:XF 0 "register_operand" "=f")
13666 (unspec:XF [(float_extend:XF
13667 (match_operand:MODEF 2 "register_operand" "0"))]
13668 UNSPEC_SINCOS_COS))
13669 (set (match_operand:XF 1 "register_operand" "=u")
13670 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
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 [(set_attr "type" "fpspc")
13677 (set_attr "mode" "XF")])
13680 [(set (match_operand:XF 0 "register_operand" "")
13681 (unspec:XF [(float_extend:XF
13682 (match_operand:MODEF 2 "register_operand" ""))]
13683 UNSPEC_SINCOS_COS))
13684 (set (match_operand:XF 1 "register_operand" "")
13685 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13686 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13687 && can_create_pseudo_p ()"
13688 [(set (match_dup 1)
13689 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13692 [(set (match_operand:XF 0 "register_operand" "")
13693 (unspec:XF [(float_extend:XF
13694 (match_operand:MODEF 2 "register_operand" ""))]
13695 UNSPEC_SINCOS_COS))
13696 (set (match_operand:XF 1 "register_operand" "")
13697 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13698 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13699 && can_create_pseudo_p ()"
13700 [(set (match_dup 0)
13701 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13703 (define_expand "sincos<mode>3"
13704 [(use (match_operand:MODEF 0 "register_operand" ""))
13705 (use (match_operand:MODEF 1 "register_operand" ""))
13706 (use (match_operand:MODEF 2 "register_operand" ""))]
13707 "TARGET_USE_FANCY_MATH_387
13708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13709 || TARGET_MIX_SSE_I387)
13710 && flag_unsafe_math_optimizations"
13712 rtx op0 = gen_reg_rtx (XFmode);
13713 rtx op1 = gen_reg_rtx (XFmode);
13715 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13716 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13717 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13721 (define_insn "fptanxf4_i387"
13722 [(set (match_operand:XF 0 "register_operand" "=f")
13723 (match_operand:XF 3 "const_double_operand" "F"))
13724 (set (match_operand:XF 1 "register_operand" "=u")
13725 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13727 "TARGET_USE_FANCY_MATH_387
13728 && flag_unsafe_math_optimizations
13729 && standard_80387_constant_p (operands[3]) == 2"
13731 [(set_attr "type" "fpspc")
13732 (set_attr "mode" "XF")])
13734 (define_insn "fptan_extend<mode>xf4_i387"
13735 [(set (match_operand:MODEF 0 "register_operand" "=f")
13736 (match_operand:MODEF 3 "const_double_operand" "F"))
13737 (set (match_operand:XF 1 "register_operand" "=u")
13738 (unspec:XF [(float_extend:XF
13739 (match_operand:MODEF 2 "register_operand" "0"))]
13741 "TARGET_USE_FANCY_MATH_387
13742 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13743 || TARGET_MIX_SSE_I387)
13744 && flag_unsafe_math_optimizations
13745 && standard_80387_constant_p (operands[3]) == 2"
13747 [(set_attr "type" "fpspc")
13748 (set_attr "mode" "XF")])
13750 (define_expand "tanxf2"
13751 [(use (match_operand:XF 0 "register_operand" ""))
13752 (use (match_operand:XF 1 "register_operand" ""))]
13753 "TARGET_USE_FANCY_MATH_387
13754 && flag_unsafe_math_optimizations"
13756 rtx one = gen_reg_rtx (XFmode);
13757 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13759 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13763 (define_expand "tan<mode>2"
13764 [(use (match_operand:MODEF 0 "register_operand" ""))
13765 (use (match_operand:MODEF 1 "register_operand" ""))]
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 rtx op0 = gen_reg_rtx (XFmode);
13773 rtx one = gen_reg_rtx (<MODE>mode);
13774 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13776 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13777 operands[1], op2));
13778 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13782 (define_insn "*fpatanxf3_i387"
13783 [(set (match_operand:XF 0 "register_operand" "=f")
13784 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13785 (match_operand:XF 2 "register_operand" "u")]
13787 (clobber (match_scratch:XF 3 "=2"))]
13788 "TARGET_USE_FANCY_MATH_387
13789 && flag_unsafe_math_optimizations"
13791 [(set_attr "type" "fpspc")
13792 (set_attr "mode" "XF")])
13794 (define_insn "fpatan_extend<mode>xf3_i387"
13795 [(set (match_operand:XF 0 "register_operand" "=f")
13796 (unspec:XF [(float_extend:XF
13797 (match_operand:MODEF 1 "register_operand" "0"))
13799 (match_operand:MODEF 2 "register_operand" "u"))]
13801 (clobber (match_scratch:XF 3 "=2"))]
13802 "TARGET_USE_FANCY_MATH_387
13803 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13804 || TARGET_MIX_SSE_I387)
13805 && flag_unsafe_math_optimizations"
13807 [(set_attr "type" "fpspc")
13808 (set_attr "mode" "XF")])
13810 (define_expand "atan2xf3"
13811 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13812 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13813 (match_operand:XF 1 "register_operand" "")]
13815 (clobber (match_scratch:XF 3 ""))])]
13816 "TARGET_USE_FANCY_MATH_387
13817 && flag_unsafe_math_optimizations")
13819 (define_expand "atan2<mode>3"
13820 [(use (match_operand:MODEF 0 "register_operand" ""))
13821 (use (match_operand:MODEF 1 "register_operand" ""))
13822 (use (match_operand:MODEF 2 "register_operand" ""))]
13823 "TARGET_USE_FANCY_MATH_387
13824 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13825 || TARGET_MIX_SSE_I387)
13826 && flag_unsafe_math_optimizations"
13828 rtx op0 = gen_reg_rtx (XFmode);
13830 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13835 (define_expand "atanxf2"
13836 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13837 (unspec:XF [(match_dup 2)
13838 (match_operand:XF 1 "register_operand" "")]
13840 (clobber (match_scratch:XF 3 ""))])]
13841 "TARGET_USE_FANCY_MATH_387
13842 && flag_unsafe_math_optimizations"
13844 operands[2] = gen_reg_rtx (XFmode);
13845 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13848 (define_expand "atan<mode>2"
13849 [(use (match_operand:MODEF 0 "register_operand" ""))
13850 (use (match_operand:MODEF 1 "register_operand" ""))]
13851 "TARGET_USE_FANCY_MATH_387
13852 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13853 || TARGET_MIX_SSE_I387)
13854 && flag_unsafe_math_optimizations"
13856 rtx op0 = gen_reg_rtx (XFmode);
13858 rtx op2 = gen_reg_rtx (<MODE>mode);
13859 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13861 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13862 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13866 (define_expand "asinxf2"
13867 [(set (match_dup 2)
13868 (mult:XF (match_operand:XF 1 "register_operand" "")
13870 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13871 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13872 (parallel [(set (match_operand:XF 0 "register_operand" "")
13873 (unspec:XF [(match_dup 5) (match_dup 1)]
13875 (clobber (match_scratch:XF 6 ""))])]
13876 "TARGET_USE_FANCY_MATH_387
13877 && flag_unsafe_math_optimizations"
13881 if (optimize_insn_for_size_p ())
13884 for (i = 2; i < 6; i++)
13885 operands[i] = gen_reg_rtx (XFmode);
13887 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13890 (define_expand "asin<mode>2"
13891 [(use (match_operand:MODEF 0 "register_operand" ""))
13892 (use (match_operand:MODEF 1 "general_operand" ""))]
13893 "TARGET_USE_FANCY_MATH_387
13894 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13895 || TARGET_MIX_SSE_I387)
13896 && flag_unsafe_math_optimizations"
13898 rtx op0 = gen_reg_rtx (XFmode);
13899 rtx op1 = gen_reg_rtx (XFmode);
13901 if (optimize_insn_for_size_p ())
13904 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13905 emit_insn (gen_asinxf2 (op0, op1));
13906 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13910 (define_expand "acosxf2"
13911 [(set (match_dup 2)
13912 (mult:XF (match_operand:XF 1 "register_operand" "")
13914 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13915 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13916 (parallel [(set (match_operand:XF 0 "register_operand" "")
13917 (unspec:XF [(match_dup 1) (match_dup 5)]
13919 (clobber (match_scratch:XF 6 ""))])]
13920 "TARGET_USE_FANCY_MATH_387
13921 && flag_unsafe_math_optimizations"
13925 if (optimize_insn_for_size_p ())
13928 for (i = 2; i < 6; i++)
13929 operands[i] = gen_reg_rtx (XFmode);
13931 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13934 (define_expand "acos<mode>2"
13935 [(use (match_operand:MODEF 0 "register_operand" ""))
13936 (use (match_operand:MODEF 1 "general_operand" ""))]
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 rtx op0 = gen_reg_rtx (XFmode);
13943 rtx op1 = gen_reg_rtx (XFmode);
13945 if (optimize_insn_for_size_p ())
13948 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13949 emit_insn (gen_acosxf2 (op0, op1));
13950 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13954 (define_insn "fyl2xxf3_i387"
13955 [(set (match_operand:XF 0 "register_operand" "=f")
13956 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13957 (match_operand:XF 2 "register_operand" "u")]
13959 (clobber (match_scratch:XF 3 "=2"))]
13960 "TARGET_USE_FANCY_MATH_387
13961 && flag_unsafe_math_optimizations"
13963 [(set_attr "type" "fpspc")
13964 (set_attr "mode" "XF")])
13966 (define_insn "fyl2x_extend<mode>xf3_i387"
13967 [(set (match_operand:XF 0 "register_operand" "=f")
13968 (unspec:XF [(float_extend:XF
13969 (match_operand:MODEF 1 "register_operand" "0"))
13970 (match_operand:XF 2 "register_operand" "u")]
13972 (clobber (match_scratch:XF 3 "=2"))]
13973 "TARGET_USE_FANCY_MATH_387
13974 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13975 || TARGET_MIX_SSE_I387)
13976 && flag_unsafe_math_optimizations"
13978 [(set_attr "type" "fpspc")
13979 (set_attr "mode" "XF")])
13981 (define_expand "logxf2"
13982 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13983 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13984 (match_dup 2)] UNSPEC_FYL2X))
13985 (clobber (match_scratch:XF 3 ""))])]
13986 "TARGET_USE_FANCY_MATH_387
13987 && flag_unsafe_math_optimizations"
13989 operands[2] = gen_reg_rtx (XFmode);
13990 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13993 (define_expand "log<mode>2"
13994 [(use (match_operand:MODEF 0 "register_operand" ""))
13995 (use (match_operand:MODEF 1 "register_operand" ""))]
13996 "TARGET_USE_FANCY_MATH_387
13997 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13998 || TARGET_MIX_SSE_I387)
13999 && flag_unsafe_math_optimizations"
14001 rtx op0 = gen_reg_rtx (XFmode);
14003 rtx op2 = gen_reg_rtx (XFmode);
14004 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14006 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14007 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14011 (define_expand "log10xf2"
14012 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14013 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14014 (match_dup 2)] UNSPEC_FYL2X))
14015 (clobber (match_scratch:XF 3 ""))])]
14016 "TARGET_USE_FANCY_MATH_387
14017 && flag_unsafe_math_optimizations"
14019 operands[2] = gen_reg_rtx (XFmode);
14020 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14023 (define_expand "log10<mode>2"
14024 [(use (match_operand:MODEF 0 "register_operand" ""))
14025 (use (match_operand:MODEF 1 "register_operand" ""))]
14026 "TARGET_USE_FANCY_MATH_387
14027 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14028 || TARGET_MIX_SSE_I387)
14029 && flag_unsafe_math_optimizations"
14031 rtx op0 = gen_reg_rtx (XFmode);
14033 rtx op2 = gen_reg_rtx (XFmode);
14034 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14036 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14037 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14041 (define_expand "log2xf2"
14042 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14043 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14044 (match_dup 2)] UNSPEC_FYL2X))
14045 (clobber (match_scratch:XF 3 ""))])]
14046 "TARGET_USE_FANCY_MATH_387
14047 && flag_unsafe_math_optimizations"
14049 operands[2] = gen_reg_rtx (XFmode);
14050 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14053 (define_expand "log2<mode>2"
14054 [(use (match_operand:MODEF 0 "register_operand" ""))
14055 (use (match_operand:MODEF 1 "register_operand" ""))]
14056 "TARGET_USE_FANCY_MATH_387
14057 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14058 || TARGET_MIX_SSE_I387)
14059 && flag_unsafe_math_optimizations"
14061 rtx op0 = gen_reg_rtx (XFmode);
14063 rtx op2 = gen_reg_rtx (XFmode);
14064 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14066 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14067 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14071 (define_insn "fyl2xp1xf3_i387"
14072 [(set (match_operand:XF 0 "register_operand" "=f")
14073 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14074 (match_operand:XF 2 "register_operand" "u")]
14076 (clobber (match_scratch:XF 3 "=2"))]
14077 "TARGET_USE_FANCY_MATH_387
14078 && flag_unsafe_math_optimizations"
14080 [(set_attr "type" "fpspc")
14081 (set_attr "mode" "XF")])
14083 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14084 [(set (match_operand:XF 0 "register_operand" "=f")
14085 (unspec:XF [(float_extend:XF
14086 (match_operand:MODEF 1 "register_operand" "0"))
14087 (match_operand:XF 2 "register_operand" "u")]
14089 (clobber (match_scratch:XF 3 "=2"))]
14090 "TARGET_USE_FANCY_MATH_387
14091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14092 || TARGET_MIX_SSE_I387)
14093 && flag_unsafe_math_optimizations"
14095 [(set_attr "type" "fpspc")
14096 (set_attr "mode" "XF")])
14098 (define_expand "log1pxf2"
14099 [(use (match_operand:XF 0 "register_operand" ""))
14100 (use (match_operand:XF 1 "register_operand" ""))]
14101 "TARGET_USE_FANCY_MATH_387
14102 && flag_unsafe_math_optimizations"
14104 if (optimize_insn_for_size_p ())
14107 ix86_emit_i387_log1p (operands[0], operands[1]);
14111 (define_expand "log1p<mode>2"
14112 [(use (match_operand:MODEF 0 "register_operand" ""))
14113 (use (match_operand:MODEF 1 "register_operand" ""))]
14114 "TARGET_USE_FANCY_MATH_387
14115 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14116 || TARGET_MIX_SSE_I387)
14117 && flag_unsafe_math_optimizations"
14121 if (optimize_insn_for_size_p ())
14124 op0 = gen_reg_rtx (XFmode);
14126 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14128 ix86_emit_i387_log1p (op0, operands[1]);
14129 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14133 (define_insn "fxtractxf3_i387"
14134 [(set (match_operand:XF 0 "register_operand" "=f")
14135 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14136 UNSPEC_XTRACT_FRACT))
14137 (set (match_operand:XF 1 "register_operand" "=u")
14138 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14139 "TARGET_USE_FANCY_MATH_387
14140 && flag_unsafe_math_optimizations"
14142 [(set_attr "type" "fpspc")
14143 (set_attr "mode" "XF")])
14145 (define_insn "fxtract_extend<mode>xf3_i387"
14146 [(set (match_operand:XF 0 "register_operand" "=f")
14147 (unspec:XF [(float_extend:XF
14148 (match_operand:MODEF 2 "register_operand" "0"))]
14149 UNSPEC_XTRACT_FRACT))
14150 (set (match_operand:XF 1 "register_operand" "=u")
14151 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14152 "TARGET_USE_FANCY_MATH_387
14153 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14154 || TARGET_MIX_SSE_I387)
14155 && flag_unsafe_math_optimizations"
14157 [(set_attr "type" "fpspc")
14158 (set_attr "mode" "XF")])
14160 (define_expand "logbxf2"
14161 [(parallel [(set (match_dup 2)
14162 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14163 UNSPEC_XTRACT_FRACT))
14164 (set (match_operand:XF 0 "register_operand" "")
14165 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14166 "TARGET_USE_FANCY_MATH_387
14167 && flag_unsafe_math_optimizations"
14168 "operands[2] = gen_reg_rtx (XFmode);")
14170 (define_expand "logb<mode>2"
14171 [(use (match_operand:MODEF 0 "register_operand" ""))
14172 (use (match_operand:MODEF 1 "register_operand" ""))]
14173 "TARGET_USE_FANCY_MATH_387
14174 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14175 || TARGET_MIX_SSE_I387)
14176 && flag_unsafe_math_optimizations"
14178 rtx op0 = gen_reg_rtx (XFmode);
14179 rtx op1 = gen_reg_rtx (XFmode);
14181 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14182 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14186 (define_expand "ilogbxf2"
14187 [(use (match_operand:SI 0 "register_operand" ""))
14188 (use (match_operand:XF 1 "register_operand" ""))]
14189 "TARGET_USE_FANCY_MATH_387
14190 && flag_unsafe_math_optimizations"
14194 if (optimize_insn_for_size_p ())
14197 op0 = gen_reg_rtx (XFmode);
14198 op1 = gen_reg_rtx (XFmode);
14200 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14201 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14205 (define_expand "ilogb<mode>2"
14206 [(use (match_operand:SI 0 "register_operand" ""))
14207 (use (match_operand:MODEF 1 "register_operand" ""))]
14208 "TARGET_USE_FANCY_MATH_387
14209 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14210 || TARGET_MIX_SSE_I387)
14211 && flag_unsafe_math_optimizations"
14215 if (optimize_insn_for_size_p ())
14218 op0 = gen_reg_rtx (XFmode);
14219 op1 = gen_reg_rtx (XFmode);
14221 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14222 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14226 (define_insn "*f2xm1xf2_i387"
14227 [(set (match_operand:XF 0 "register_operand" "=f")
14228 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14230 "TARGET_USE_FANCY_MATH_387
14231 && flag_unsafe_math_optimizations"
14233 [(set_attr "type" "fpspc")
14234 (set_attr "mode" "XF")])
14236 (define_insn "*fscalexf4_i387"
14237 [(set (match_operand:XF 0 "register_operand" "=f")
14238 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14239 (match_operand:XF 3 "register_operand" "1")]
14240 UNSPEC_FSCALE_FRACT))
14241 (set (match_operand:XF 1 "register_operand" "=u")
14242 (unspec:XF [(match_dup 2) (match_dup 3)]
14243 UNSPEC_FSCALE_EXP))]
14244 "TARGET_USE_FANCY_MATH_387
14245 && flag_unsafe_math_optimizations"
14247 [(set_attr "type" "fpspc")
14248 (set_attr "mode" "XF")])
14250 (define_expand "expNcorexf3"
14251 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14252 (match_operand:XF 2 "register_operand" "")))
14253 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14254 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14255 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14256 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14257 (parallel [(set (match_operand:XF 0 "register_operand" "")
14258 (unspec:XF [(match_dup 8) (match_dup 4)]
14259 UNSPEC_FSCALE_FRACT))
14261 (unspec:XF [(match_dup 8) (match_dup 4)]
14262 UNSPEC_FSCALE_EXP))])]
14263 "TARGET_USE_FANCY_MATH_387
14264 && flag_unsafe_math_optimizations"
14268 if (optimize_insn_for_size_p ())
14271 for (i = 3; i < 10; i++)
14272 operands[i] = gen_reg_rtx (XFmode);
14274 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14277 (define_expand "expxf2"
14278 [(use (match_operand:XF 0 "register_operand" ""))
14279 (use (match_operand:XF 1 "register_operand" ""))]
14280 "TARGET_USE_FANCY_MATH_387
14281 && flag_unsafe_math_optimizations"
14285 if (optimize_insn_for_size_p ())
14288 op2 = gen_reg_rtx (XFmode);
14289 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14291 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14295 (define_expand "exp<mode>2"
14296 [(use (match_operand:MODEF 0 "register_operand" ""))
14297 (use (match_operand:MODEF 1 "general_operand" ""))]
14298 "TARGET_USE_FANCY_MATH_387
14299 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14300 || TARGET_MIX_SSE_I387)
14301 && flag_unsafe_math_optimizations"
14305 if (optimize_insn_for_size_p ())
14308 op0 = gen_reg_rtx (XFmode);
14309 op1 = gen_reg_rtx (XFmode);
14311 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14312 emit_insn (gen_expxf2 (op0, op1));
14313 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14317 (define_expand "exp10xf2"
14318 [(use (match_operand:XF 0 "register_operand" ""))
14319 (use (match_operand:XF 1 "register_operand" ""))]
14320 "TARGET_USE_FANCY_MATH_387
14321 && flag_unsafe_math_optimizations"
14325 if (optimize_insn_for_size_p ())
14328 op2 = gen_reg_rtx (XFmode);
14329 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14331 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14335 (define_expand "exp10<mode>2"
14336 [(use (match_operand:MODEF 0 "register_operand" ""))
14337 (use (match_operand:MODEF 1 "general_operand" ""))]
14338 "TARGET_USE_FANCY_MATH_387
14339 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14340 || TARGET_MIX_SSE_I387)
14341 && flag_unsafe_math_optimizations"
14345 if (optimize_insn_for_size_p ())
14348 op0 = gen_reg_rtx (XFmode);
14349 op1 = gen_reg_rtx (XFmode);
14351 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14352 emit_insn (gen_exp10xf2 (op0, op1));
14353 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14357 (define_expand "exp2xf2"
14358 [(use (match_operand:XF 0 "register_operand" ""))
14359 (use (match_operand:XF 1 "register_operand" ""))]
14360 "TARGET_USE_FANCY_MATH_387
14361 && flag_unsafe_math_optimizations"
14365 if (optimize_insn_for_size_p ())
14368 op2 = gen_reg_rtx (XFmode);
14369 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14371 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14375 (define_expand "exp2<mode>2"
14376 [(use (match_operand:MODEF 0 "register_operand" ""))
14377 (use (match_operand:MODEF 1 "general_operand" ""))]
14378 "TARGET_USE_FANCY_MATH_387
14379 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14380 || TARGET_MIX_SSE_I387)
14381 && flag_unsafe_math_optimizations"
14385 if (optimize_insn_for_size_p ())
14388 op0 = gen_reg_rtx (XFmode);
14389 op1 = gen_reg_rtx (XFmode);
14391 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14392 emit_insn (gen_exp2xf2 (op0, op1));
14393 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14397 (define_expand "expm1xf2"
14398 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14400 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14401 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14402 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14403 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14404 (parallel [(set (match_dup 7)
14405 (unspec:XF [(match_dup 6) (match_dup 4)]
14406 UNSPEC_FSCALE_FRACT))
14408 (unspec:XF [(match_dup 6) (match_dup 4)]
14409 UNSPEC_FSCALE_EXP))])
14410 (parallel [(set (match_dup 10)
14411 (unspec:XF [(match_dup 9) (match_dup 8)]
14412 UNSPEC_FSCALE_FRACT))
14413 (set (match_dup 11)
14414 (unspec:XF [(match_dup 9) (match_dup 8)]
14415 UNSPEC_FSCALE_EXP))])
14416 (set (match_dup 12) (minus:XF (match_dup 10)
14417 (float_extend:XF (match_dup 13))))
14418 (set (match_operand:XF 0 "register_operand" "")
14419 (plus:XF (match_dup 12) (match_dup 7)))]
14420 "TARGET_USE_FANCY_MATH_387
14421 && flag_unsafe_math_optimizations"
14425 if (optimize_insn_for_size_p ())
14428 for (i = 2; i < 13; i++)
14429 operands[i] = gen_reg_rtx (XFmode);
14432 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14434 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14437 (define_expand "expm1<mode>2"
14438 [(use (match_operand:MODEF 0 "register_operand" ""))
14439 (use (match_operand:MODEF 1 "general_operand" ""))]
14440 "TARGET_USE_FANCY_MATH_387
14441 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14442 || TARGET_MIX_SSE_I387)
14443 && flag_unsafe_math_optimizations"
14447 if (optimize_insn_for_size_p ())
14450 op0 = gen_reg_rtx (XFmode);
14451 op1 = gen_reg_rtx (XFmode);
14453 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14454 emit_insn (gen_expm1xf2 (op0, op1));
14455 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14459 (define_expand "ldexpxf3"
14460 [(set (match_dup 3)
14461 (float:XF (match_operand:SI 2 "register_operand" "")))
14462 (parallel [(set (match_operand:XF 0 " register_operand" "")
14463 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14465 UNSPEC_FSCALE_FRACT))
14467 (unspec:XF [(match_dup 1) (match_dup 3)]
14468 UNSPEC_FSCALE_EXP))])]
14469 "TARGET_USE_FANCY_MATH_387
14470 && flag_unsafe_math_optimizations"
14472 if (optimize_insn_for_size_p ())
14475 operands[3] = gen_reg_rtx (XFmode);
14476 operands[4] = gen_reg_rtx (XFmode);
14479 (define_expand "ldexp<mode>3"
14480 [(use (match_operand:MODEF 0 "register_operand" ""))
14481 (use (match_operand:MODEF 1 "general_operand" ""))
14482 (use (match_operand:SI 2 "register_operand" ""))]
14483 "TARGET_USE_FANCY_MATH_387
14484 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14485 || TARGET_MIX_SSE_I387)
14486 && flag_unsafe_math_optimizations"
14490 if (optimize_insn_for_size_p ())
14493 op0 = gen_reg_rtx (XFmode);
14494 op1 = gen_reg_rtx (XFmode);
14496 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14497 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14498 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14502 (define_expand "scalbxf3"
14503 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14504 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14505 (match_operand:XF 2 "register_operand" "")]
14506 UNSPEC_FSCALE_FRACT))
14508 (unspec:XF [(match_dup 1) (match_dup 2)]
14509 UNSPEC_FSCALE_EXP))])]
14510 "TARGET_USE_FANCY_MATH_387
14511 && flag_unsafe_math_optimizations"
14513 if (optimize_insn_for_size_p ())
14516 operands[3] = gen_reg_rtx (XFmode);
14519 (define_expand "scalb<mode>3"
14520 [(use (match_operand:MODEF 0 "register_operand" ""))
14521 (use (match_operand:MODEF 1 "general_operand" ""))
14522 (use (match_operand:MODEF 2 "general_operand" ""))]
14523 "TARGET_USE_FANCY_MATH_387
14524 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14525 || TARGET_MIX_SSE_I387)
14526 && flag_unsafe_math_optimizations"
14530 if (optimize_insn_for_size_p ())
14533 op0 = gen_reg_rtx (XFmode);
14534 op1 = gen_reg_rtx (XFmode);
14535 op2 = gen_reg_rtx (XFmode);
14537 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14538 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14539 emit_insn (gen_scalbxf3 (op0, op1, op2));
14540 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14544 (define_expand "significandxf2"
14545 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14546 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14547 UNSPEC_XTRACT_FRACT))
14549 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14550 "TARGET_USE_FANCY_MATH_387
14551 && flag_unsafe_math_optimizations"
14552 "operands[2] = gen_reg_rtx (XFmode);")
14554 (define_expand "significand<mode>2"
14555 [(use (match_operand:MODEF 0 "register_operand" ""))
14556 (use (match_operand:MODEF 1 "register_operand" ""))]
14557 "TARGET_USE_FANCY_MATH_387
14558 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14559 || TARGET_MIX_SSE_I387)
14560 && flag_unsafe_math_optimizations"
14562 rtx op0 = gen_reg_rtx (XFmode);
14563 rtx op1 = gen_reg_rtx (XFmode);
14565 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14566 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14571 (define_insn "sse4_1_round<mode>2"
14572 [(set (match_operand:MODEF 0 "register_operand" "=x")
14573 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14574 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14577 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14578 [(set_attr "type" "ssecvt")
14579 (set_attr "prefix_extra" "1")
14580 (set_attr "prefix" "maybe_vex")
14581 (set_attr "mode" "<MODE>")])
14583 (define_insn "rintxf2"
14584 [(set (match_operand:XF 0 "register_operand" "=f")
14585 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14587 "TARGET_USE_FANCY_MATH_387
14588 && flag_unsafe_math_optimizations"
14590 [(set_attr "type" "fpspc")
14591 (set_attr "mode" "XF")])
14593 (define_expand "rint<mode>2"
14594 [(use (match_operand:MODEF 0 "register_operand" ""))
14595 (use (match_operand:MODEF 1 "register_operand" ""))]
14596 "(TARGET_USE_FANCY_MATH_387
14597 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14598 || TARGET_MIX_SSE_I387)
14599 && flag_unsafe_math_optimizations)
14600 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14601 && !flag_trapping_math)"
14603 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14604 && !flag_trapping_math)
14607 emit_insn (gen_sse4_1_round<mode>2
14608 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14609 else if (optimize_insn_for_size_p ())
14612 ix86_expand_rint (operands[0], operands[1]);
14616 rtx op0 = gen_reg_rtx (XFmode);
14617 rtx op1 = gen_reg_rtx (XFmode);
14619 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14620 emit_insn (gen_rintxf2 (op0, op1));
14622 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14627 (define_expand "round<mode>2"
14628 [(match_operand:X87MODEF 0 "register_operand" "")
14629 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14630 "(TARGET_USE_FANCY_MATH_387
14631 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14632 || TARGET_MIX_SSE_I387)
14633 && flag_unsafe_math_optimizations)
14634 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14635 && !flag_trapping_math && !flag_rounding_math)"
14637 if (optimize_insn_for_size_p ())
14640 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14641 && !flag_trapping_math && !flag_rounding_math)
14645 operands[1] = force_reg (<MODE>mode, operands[1]);
14646 ix86_expand_round_sse4 (operands[0], operands[1]);
14648 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14649 ix86_expand_round (operands[0], operands[1]);
14651 ix86_expand_rounddf_32 (operands[0], operands[1]);
14655 operands[1] = force_reg (<MODE>mode, operands[1]);
14656 ix86_emit_i387_round (operands[0], operands[1]);
14661 (define_insn_and_split "*fistdi2_1"
14662 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14663 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14665 "TARGET_USE_FANCY_MATH_387
14666 && can_create_pseudo_p ()"
14671 if (memory_operand (operands[0], VOIDmode))
14672 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14675 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14676 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14681 [(set_attr "type" "fpspc")
14682 (set_attr "mode" "DI")])
14684 (define_insn "fistdi2"
14685 [(set (match_operand:DI 0 "memory_operand" "=m")
14686 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14688 (clobber (match_scratch:XF 2 "=&1f"))]
14689 "TARGET_USE_FANCY_MATH_387"
14690 "* return output_fix_trunc (insn, operands, false);"
14691 [(set_attr "type" "fpspc")
14692 (set_attr "mode" "DI")])
14694 (define_insn "fistdi2_with_temp"
14695 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14696 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14698 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14699 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14700 "TARGET_USE_FANCY_MATH_387"
14702 [(set_attr "type" "fpspc")
14703 (set_attr "mode" "DI")])
14706 [(set (match_operand:DI 0 "register_operand" "")
14707 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14709 (clobber (match_operand:DI 2 "memory_operand" ""))
14710 (clobber (match_scratch 3 ""))]
14712 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14713 (clobber (match_dup 3))])
14714 (set (match_dup 0) (match_dup 2))])
14717 [(set (match_operand:DI 0 "memory_operand" "")
14718 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14720 (clobber (match_operand:DI 2 "memory_operand" ""))
14721 (clobber (match_scratch 3 ""))]
14723 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14724 (clobber (match_dup 3))])])
14726 (define_insn_and_split "*fist<mode>2_1"
14727 [(set (match_operand:SWI24 0 "register_operand" "")
14728 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14730 "TARGET_USE_FANCY_MATH_387
14731 && can_create_pseudo_p ()"
14736 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14737 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14741 [(set_attr "type" "fpspc")
14742 (set_attr "mode" "<MODE>")])
14744 (define_insn "fist<mode>2"
14745 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14746 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14748 "TARGET_USE_FANCY_MATH_387"
14749 "* return output_fix_trunc (insn, operands, false);"
14750 [(set_attr "type" "fpspc")
14751 (set_attr "mode" "<MODE>")])
14753 (define_insn "fist<mode>2_with_temp"
14754 [(set (match_operand:SWI24 0 "register_operand" "=r")
14755 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14757 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14758 "TARGET_USE_FANCY_MATH_387"
14760 [(set_attr "type" "fpspc")
14761 (set_attr "mode" "<MODE>")])
14764 [(set (match_operand:SWI24 0 "register_operand" "")
14765 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14767 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14769 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14770 (set (match_dup 0) (match_dup 2))])
14773 [(set (match_operand:SWI24 0 "memory_operand" "")
14774 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14776 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14778 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14780 (define_expand "lrintxf<mode>2"
14781 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14782 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14784 "TARGET_USE_FANCY_MATH_387")
14786 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14787 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14788 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14789 UNSPEC_FIX_NOTRUNC))]
14790 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14791 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14793 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14794 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14795 (match_operand:X87MODEF 1 "register_operand" "")]
14796 "(TARGET_USE_FANCY_MATH_387
14797 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14798 || TARGET_MIX_SSE_I387)
14799 && flag_unsafe_math_optimizations)
14800 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14801 && <SWI248x:MODE>mode != HImode
14802 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14803 && !flag_trapping_math && !flag_rounding_math)"
14805 if (optimize_insn_for_size_p ())
14808 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14809 && <SWI248x:MODE>mode != HImode
14810 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14811 && !flag_trapping_math && !flag_rounding_math)
14812 ix86_expand_lround (operands[0], operands[1]);
14814 ix86_emit_i387_round (operands[0], operands[1]);
14818 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14819 (define_insn_and_split "frndintxf2_floor"
14820 [(set (match_operand:XF 0 "register_operand" "")
14821 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14822 UNSPEC_FRNDINT_FLOOR))
14823 (clobber (reg:CC FLAGS_REG))]
14824 "TARGET_USE_FANCY_MATH_387
14825 && flag_unsafe_math_optimizations
14826 && can_create_pseudo_p ()"
14831 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14833 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14834 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14836 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14837 operands[2], operands[3]));
14840 [(set_attr "type" "frndint")
14841 (set_attr "i387_cw" "floor")
14842 (set_attr "mode" "XF")])
14844 (define_insn "frndintxf2_floor_i387"
14845 [(set (match_operand:XF 0 "register_operand" "=f")
14846 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14847 UNSPEC_FRNDINT_FLOOR))
14848 (use (match_operand:HI 2 "memory_operand" "m"))
14849 (use (match_operand:HI 3 "memory_operand" "m"))]
14850 "TARGET_USE_FANCY_MATH_387
14851 && flag_unsafe_math_optimizations"
14852 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14853 [(set_attr "type" "frndint")
14854 (set_attr "i387_cw" "floor")
14855 (set_attr "mode" "XF")])
14857 (define_expand "floorxf2"
14858 [(use (match_operand:XF 0 "register_operand" ""))
14859 (use (match_operand:XF 1 "register_operand" ""))]
14860 "TARGET_USE_FANCY_MATH_387
14861 && flag_unsafe_math_optimizations"
14863 if (optimize_insn_for_size_p ())
14865 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14869 (define_expand "floor<mode>2"
14870 [(use (match_operand:MODEF 0 "register_operand" ""))
14871 (use (match_operand:MODEF 1 "register_operand" ""))]
14872 "(TARGET_USE_FANCY_MATH_387
14873 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14874 || TARGET_MIX_SSE_I387)
14875 && flag_unsafe_math_optimizations)
14876 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14877 && !flag_trapping_math)"
14879 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14880 && !flag_trapping_math)
14883 emit_insn (gen_sse4_1_round<mode>2
14884 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14885 else if (optimize_insn_for_size_p ())
14887 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14888 ix86_expand_floorceil (operands[0], operands[1], true);
14890 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14896 if (optimize_insn_for_size_p ())
14899 op0 = gen_reg_rtx (XFmode);
14900 op1 = gen_reg_rtx (XFmode);
14901 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14902 emit_insn (gen_frndintxf2_floor (op0, op1));
14904 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14909 (define_insn_and_split "*fist<mode>2_floor_1"
14910 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14911 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14912 UNSPEC_FIST_FLOOR))
14913 (clobber (reg:CC FLAGS_REG))]
14914 "TARGET_USE_FANCY_MATH_387
14915 && flag_unsafe_math_optimizations
14916 && can_create_pseudo_p ()"
14921 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14923 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14924 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14925 if (memory_operand (operands[0], VOIDmode))
14926 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14927 operands[2], operands[3]));
14930 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14931 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14932 operands[2], operands[3],
14937 [(set_attr "type" "fistp")
14938 (set_attr "i387_cw" "floor")
14939 (set_attr "mode" "<MODE>")])
14941 (define_insn "fistdi2_floor"
14942 [(set (match_operand:DI 0 "memory_operand" "=m")
14943 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14944 UNSPEC_FIST_FLOOR))
14945 (use (match_operand:HI 2 "memory_operand" "m"))
14946 (use (match_operand:HI 3 "memory_operand" "m"))
14947 (clobber (match_scratch:XF 4 "=&1f"))]
14948 "TARGET_USE_FANCY_MATH_387
14949 && flag_unsafe_math_optimizations"
14950 "* return output_fix_trunc (insn, operands, false);"
14951 [(set_attr "type" "fistp")
14952 (set_attr "i387_cw" "floor")
14953 (set_attr "mode" "DI")])
14955 (define_insn "fistdi2_floor_with_temp"
14956 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14957 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14958 UNSPEC_FIST_FLOOR))
14959 (use (match_operand:HI 2 "memory_operand" "m,m"))
14960 (use (match_operand:HI 3 "memory_operand" "m,m"))
14961 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14962 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14963 "TARGET_USE_FANCY_MATH_387
14964 && flag_unsafe_math_optimizations"
14966 [(set_attr "type" "fistp")
14967 (set_attr "i387_cw" "floor")
14968 (set_attr "mode" "DI")])
14971 [(set (match_operand:DI 0 "register_operand" "")
14972 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14973 UNSPEC_FIST_FLOOR))
14974 (use (match_operand:HI 2 "memory_operand" ""))
14975 (use (match_operand:HI 3 "memory_operand" ""))
14976 (clobber (match_operand:DI 4 "memory_operand" ""))
14977 (clobber (match_scratch 5 ""))]
14979 [(parallel [(set (match_dup 4)
14980 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14981 (use (match_dup 2))
14982 (use (match_dup 3))
14983 (clobber (match_dup 5))])
14984 (set (match_dup 0) (match_dup 4))])
14987 [(set (match_operand:DI 0 "memory_operand" "")
14988 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14989 UNSPEC_FIST_FLOOR))
14990 (use (match_operand:HI 2 "memory_operand" ""))
14991 (use (match_operand:HI 3 "memory_operand" ""))
14992 (clobber (match_operand:DI 4 "memory_operand" ""))
14993 (clobber (match_scratch 5 ""))]
14995 [(parallel [(set (match_dup 0)
14996 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14997 (use (match_dup 2))
14998 (use (match_dup 3))
14999 (clobber (match_dup 5))])])
15001 (define_insn "fist<mode>2_floor"
15002 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15003 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15004 UNSPEC_FIST_FLOOR))
15005 (use (match_operand:HI 2 "memory_operand" "m"))
15006 (use (match_operand:HI 3 "memory_operand" "m"))]
15007 "TARGET_USE_FANCY_MATH_387
15008 && flag_unsafe_math_optimizations"
15009 "* return output_fix_trunc (insn, operands, false);"
15010 [(set_attr "type" "fistp")
15011 (set_attr "i387_cw" "floor")
15012 (set_attr "mode" "<MODE>")])
15014 (define_insn "fist<mode>2_floor_with_temp"
15015 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15016 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15017 UNSPEC_FIST_FLOOR))
15018 (use (match_operand:HI 2 "memory_operand" "m,m"))
15019 (use (match_operand:HI 3 "memory_operand" "m,m"))
15020 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15021 "TARGET_USE_FANCY_MATH_387
15022 && flag_unsafe_math_optimizations"
15024 [(set_attr "type" "fistp")
15025 (set_attr "i387_cw" "floor")
15026 (set_attr "mode" "<MODE>")])
15029 [(set (match_operand:SWI24 0 "register_operand" "")
15030 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15031 UNSPEC_FIST_FLOOR))
15032 (use (match_operand:HI 2 "memory_operand" ""))
15033 (use (match_operand:HI 3 "memory_operand" ""))
15034 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15036 [(parallel [(set (match_dup 4)
15037 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15038 (use (match_dup 2))
15039 (use (match_dup 3))])
15040 (set (match_dup 0) (match_dup 4))])
15043 [(set (match_operand:SWI24 0 "memory_operand" "")
15044 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15045 UNSPEC_FIST_FLOOR))
15046 (use (match_operand:HI 2 "memory_operand" ""))
15047 (use (match_operand:HI 3 "memory_operand" ""))
15048 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15050 [(parallel [(set (match_dup 0)
15051 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15052 (use (match_dup 2))
15053 (use (match_dup 3))])])
15055 (define_expand "lfloorxf<mode>2"
15056 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15057 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15058 UNSPEC_FIST_FLOOR))
15059 (clobber (reg:CC FLAGS_REG))])]
15060 "TARGET_USE_FANCY_MATH_387
15061 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15062 && flag_unsafe_math_optimizations")
15064 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15065 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15066 (match_operand:MODEF 1 "register_operand" "")]
15067 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15068 && !flag_trapping_math"
15070 if (TARGET_64BIT && optimize_insn_for_size_p ())
15072 ix86_expand_lfloorceil (operands[0], operands[1], true);
15076 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15077 (define_insn_and_split "frndintxf2_ceil"
15078 [(set (match_operand:XF 0 "register_operand" "")
15079 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15080 UNSPEC_FRNDINT_CEIL))
15081 (clobber (reg:CC FLAGS_REG))]
15082 "TARGET_USE_FANCY_MATH_387
15083 && flag_unsafe_math_optimizations
15084 && can_create_pseudo_p ()"
15089 ix86_optimize_mode_switching[I387_CEIL] = 1;
15091 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15092 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15094 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15095 operands[2], operands[3]));
15098 [(set_attr "type" "frndint")
15099 (set_attr "i387_cw" "ceil")
15100 (set_attr "mode" "XF")])
15102 (define_insn "frndintxf2_ceil_i387"
15103 [(set (match_operand:XF 0 "register_operand" "=f")
15104 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15105 UNSPEC_FRNDINT_CEIL))
15106 (use (match_operand:HI 2 "memory_operand" "m"))
15107 (use (match_operand:HI 3 "memory_operand" "m"))]
15108 "TARGET_USE_FANCY_MATH_387
15109 && flag_unsafe_math_optimizations"
15110 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15111 [(set_attr "type" "frndint")
15112 (set_attr "i387_cw" "ceil")
15113 (set_attr "mode" "XF")])
15115 (define_expand "ceilxf2"
15116 [(use (match_operand:XF 0 "register_operand" ""))
15117 (use (match_operand:XF 1 "register_operand" ""))]
15118 "TARGET_USE_FANCY_MATH_387
15119 && flag_unsafe_math_optimizations"
15121 if (optimize_insn_for_size_p ())
15123 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15127 (define_expand "ceil<mode>2"
15128 [(use (match_operand:MODEF 0 "register_operand" ""))
15129 (use (match_operand:MODEF 1 "register_operand" ""))]
15130 "(TARGET_USE_FANCY_MATH_387
15131 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15132 || TARGET_MIX_SSE_I387)
15133 && flag_unsafe_math_optimizations)
15134 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15135 && !flag_trapping_math)"
15137 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15138 && !flag_trapping_math)
15141 emit_insn (gen_sse4_1_round<mode>2
15142 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15143 else if (optimize_insn_for_size_p ())
15145 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15146 ix86_expand_floorceil (operands[0], operands[1], false);
15148 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15154 if (optimize_insn_for_size_p ())
15157 op0 = gen_reg_rtx (XFmode);
15158 op1 = gen_reg_rtx (XFmode);
15159 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15160 emit_insn (gen_frndintxf2_ceil (op0, op1));
15162 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15167 (define_insn_and_split "*fist<mode>2_ceil_1"
15168 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15169 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15171 (clobber (reg:CC FLAGS_REG))]
15172 "TARGET_USE_FANCY_MATH_387
15173 && flag_unsafe_math_optimizations
15174 && can_create_pseudo_p ()"
15179 ix86_optimize_mode_switching[I387_CEIL] = 1;
15181 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15182 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15183 if (memory_operand (operands[0], VOIDmode))
15184 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15185 operands[2], operands[3]));
15188 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15189 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15190 operands[2], operands[3],
15195 [(set_attr "type" "fistp")
15196 (set_attr "i387_cw" "ceil")
15197 (set_attr "mode" "<MODE>")])
15199 (define_insn "fistdi2_ceil"
15200 [(set (match_operand:DI 0 "memory_operand" "=m")
15201 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15203 (use (match_operand:HI 2 "memory_operand" "m"))
15204 (use (match_operand:HI 3 "memory_operand" "m"))
15205 (clobber (match_scratch:XF 4 "=&1f"))]
15206 "TARGET_USE_FANCY_MATH_387
15207 && flag_unsafe_math_optimizations"
15208 "* return output_fix_trunc (insn, operands, false);"
15209 [(set_attr "type" "fistp")
15210 (set_attr "i387_cw" "ceil")
15211 (set_attr "mode" "DI")])
15213 (define_insn "fistdi2_ceil_with_temp"
15214 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15215 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15217 (use (match_operand:HI 2 "memory_operand" "m,m"))
15218 (use (match_operand:HI 3 "memory_operand" "m,m"))
15219 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15220 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15221 "TARGET_USE_FANCY_MATH_387
15222 && flag_unsafe_math_optimizations"
15224 [(set_attr "type" "fistp")
15225 (set_attr "i387_cw" "ceil")
15226 (set_attr "mode" "DI")])
15229 [(set (match_operand:DI 0 "register_operand" "")
15230 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15232 (use (match_operand:HI 2 "memory_operand" ""))
15233 (use (match_operand:HI 3 "memory_operand" ""))
15234 (clobber (match_operand:DI 4 "memory_operand" ""))
15235 (clobber (match_scratch 5 ""))]
15237 [(parallel [(set (match_dup 4)
15238 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15239 (use (match_dup 2))
15240 (use (match_dup 3))
15241 (clobber (match_dup 5))])
15242 (set (match_dup 0) (match_dup 4))])
15245 [(set (match_operand:DI 0 "memory_operand" "")
15246 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15248 (use (match_operand:HI 2 "memory_operand" ""))
15249 (use (match_operand:HI 3 "memory_operand" ""))
15250 (clobber (match_operand:DI 4 "memory_operand" ""))
15251 (clobber (match_scratch 5 ""))]
15253 [(parallel [(set (match_dup 0)
15254 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15255 (use (match_dup 2))
15256 (use (match_dup 3))
15257 (clobber (match_dup 5))])])
15259 (define_insn "fist<mode>2_ceil"
15260 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15261 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15263 (use (match_operand:HI 2 "memory_operand" "m"))
15264 (use (match_operand:HI 3 "memory_operand" "m"))]
15265 "TARGET_USE_FANCY_MATH_387
15266 && flag_unsafe_math_optimizations"
15267 "* return output_fix_trunc (insn, operands, false);"
15268 [(set_attr "type" "fistp")
15269 (set_attr "i387_cw" "ceil")
15270 (set_attr "mode" "<MODE>")])
15272 (define_insn "fist<mode>2_ceil_with_temp"
15273 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15274 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15276 (use (match_operand:HI 2 "memory_operand" "m,m"))
15277 (use (match_operand:HI 3 "memory_operand" "m,m"))
15278 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15279 "TARGET_USE_FANCY_MATH_387
15280 && flag_unsafe_math_optimizations"
15282 [(set_attr "type" "fistp")
15283 (set_attr "i387_cw" "ceil")
15284 (set_attr "mode" "<MODE>")])
15287 [(set (match_operand:SWI24 0 "register_operand" "")
15288 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15290 (use (match_operand:HI 2 "memory_operand" ""))
15291 (use (match_operand:HI 3 "memory_operand" ""))
15292 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15294 [(parallel [(set (match_dup 4)
15295 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15296 (use (match_dup 2))
15297 (use (match_dup 3))])
15298 (set (match_dup 0) (match_dup 4))])
15301 [(set (match_operand:SWI24 0 "memory_operand" "")
15302 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15304 (use (match_operand:HI 2 "memory_operand" ""))
15305 (use (match_operand:HI 3 "memory_operand" ""))
15306 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15308 [(parallel [(set (match_dup 0)
15309 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15310 (use (match_dup 2))
15311 (use (match_dup 3))])])
15313 (define_expand "lceilxf<mode>2"
15314 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15315 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15317 (clobber (reg:CC FLAGS_REG))])]
15318 "TARGET_USE_FANCY_MATH_387
15319 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15320 && flag_unsafe_math_optimizations")
15322 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15323 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15324 (match_operand:MODEF 1 "register_operand" "")]
15325 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15326 && !flag_trapping_math"
15328 ix86_expand_lfloorceil (operands[0], operands[1], false);
15332 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15333 (define_insn_and_split "frndintxf2_trunc"
15334 [(set (match_operand:XF 0 "register_operand" "")
15335 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15336 UNSPEC_FRNDINT_TRUNC))
15337 (clobber (reg:CC FLAGS_REG))]
15338 "TARGET_USE_FANCY_MATH_387
15339 && flag_unsafe_math_optimizations
15340 && can_create_pseudo_p ()"
15345 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15347 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15348 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15350 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15351 operands[2], operands[3]));
15354 [(set_attr "type" "frndint")
15355 (set_attr "i387_cw" "trunc")
15356 (set_attr "mode" "XF")])
15358 (define_insn "frndintxf2_trunc_i387"
15359 [(set (match_operand:XF 0 "register_operand" "=f")
15360 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15361 UNSPEC_FRNDINT_TRUNC))
15362 (use (match_operand:HI 2 "memory_operand" "m"))
15363 (use (match_operand:HI 3 "memory_operand" "m"))]
15364 "TARGET_USE_FANCY_MATH_387
15365 && flag_unsafe_math_optimizations"
15366 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15367 [(set_attr "type" "frndint")
15368 (set_attr "i387_cw" "trunc")
15369 (set_attr "mode" "XF")])
15371 (define_expand "btruncxf2"
15372 [(use (match_operand:XF 0 "register_operand" ""))
15373 (use (match_operand:XF 1 "register_operand" ""))]
15374 "TARGET_USE_FANCY_MATH_387
15375 && flag_unsafe_math_optimizations"
15377 if (optimize_insn_for_size_p ())
15379 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15383 (define_expand "btrunc<mode>2"
15384 [(use (match_operand:MODEF 0 "register_operand" ""))
15385 (use (match_operand:MODEF 1 "register_operand" ""))]
15386 "(TARGET_USE_FANCY_MATH_387
15387 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15388 || TARGET_MIX_SSE_I387)
15389 && flag_unsafe_math_optimizations)
15390 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15391 && !flag_trapping_math)"
15393 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15394 && !flag_trapping_math)
15397 emit_insn (gen_sse4_1_round<mode>2
15398 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15399 else if (optimize_insn_for_size_p ())
15401 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15402 ix86_expand_trunc (operands[0], operands[1]);
15404 ix86_expand_truncdf_32 (operands[0], operands[1]);
15410 if (optimize_insn_for_size_p ())
15413 op0 = gen_reg_rtx (XFmode);
15414 op1 = gen_reg_rtx (XFmode);
15415 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15416 emit_insn (gen_frndintxf2_trunc (op0, op1));
15418 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15423 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15424 (define_insn_and_split "frndintxf2_mask_pm"
15425 [(set (match_operand:XF 0 "register_operand" "")
15426 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15427 UNSPEC_FRNDINT_MASK_PM))
15428 (clobber (reg:CC FLAGS_REG))]
15429 "TARGET_USE_FANCY_MATH_387
15430 && flag_unsafe_math_optimizations
15431 && can_create_pseudo_p ()"
15436 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15438 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15439 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15441 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15442 operands[2], operands[3]));
15445 [(set_attr "type" "frndint")
15446 (set_attr "i387_cw" "mask_pm")
15447 (set_attr "mode" "XF")])
15449 (define_insn "frndintxf2_mask_pm_i387"
15450 [(set (match_operand:XF 0 "register_operand" "=f")
15451 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15452 UNSPEC_FRNDINT_MASK_PM))
15453 (use (match_operand:HI 2 "memory_operand" "m"))
15454 (use (match_operand:HI 3 "memory_operand" "m"))]
15455 "TARGET_USE_FANCY_MATH_387
15456 && flag_unsafe_math_optimizations"
15457 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15458 [(set_attr "type" "frndint")
15459 (set_attr "i387_cw" "mask_pm")
15460 (set_attr "mode" "XF")])
15462 (define_expand "nearbyintxf2"
15463 [(use (match_operand:XF 0 "register_operand" ""))
15464 (use (match_operand:XF 1 "register_operand" ""))]
15465 "TARGET_USE_FANCY_MATH_387
15466 && flag_unsafe_math_optimizations"
15468 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15472 (define_expand "nearbyint<mode>2"
15473 [(use (match_operand:MODEF 0 "register_operand" ""))
15474 (use (match_operand:MODEF 1 "register_operand" ""))]
15475 "TARGET_USE_FANCY_MATH_387
15476 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15477 || TARGET_MIX_SSE_I387)
15478 && flag_unsafe_math_optimizations"
15480 rtx op0 = gen_reg_rtx (XFmode);
15481 rtx op1 = gen_reg_rtx (XFmode);
15483 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15484 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15486 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15490 (define_insn "fxam<mode>2_i387"
15491 [(set (match_operand:HI 0 "register_operand" "=a")
15493 [(match_operand:X87MODEF 1 "register_operand" "f")]
15495 "TARGET_USE_FANCY_MATH_387"
15496 "fxam\n\tfnstsw\t%0"
15497 [(set_attr "type" "multi")
15498 (set_attr "length" "4")
15499 (set_attr "unit" "i387")
15500 (set_attr "mode" "<MODE>")])
15502 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15503 [(set (match_operand:HI 0 "register_operand" "")
15505 [(match_operand:MODEF 1 "memory_operand" "")]
15507 "TARGET_USE_FANCY_MATH_387
15508 && can_create_pseudo_p ()"
15511 [(set (match_dup 2)(match_dup 1))
15513 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15515 operands[2] = gen_reg_rtx (<MODE>mode);
15517 MEM_VOLATILE_P (operands[1]) = 1;
15519 [(set_attr "type" "multi")
15520 (set_attr "unit" "i387")
15521 (set_attr "mode" "<MODE>")])
15523 (define_expand "isinfxf2"
15524 [(use (match_operand:SI 0 "register_operand" ""))
15525 (use (match_operand:XF 1 "register_operand" ""))]
15526 "TARGET_USE_FANCY_MATH_387
15527 && TARGET_C99_FUNCTIONS"
15529 rtx mask = GEN_INT (0x45);
15530 rtx val = GEN_INT (0x05);
15534 rtx scratch = gen_reg_rtx (HImode);
15535 rtx res = gen_reg_rtx (QImode);
15537 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15539 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15540 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15541 cond = gen_rtx_fmt_ee (EQ, QImode,
15542 gen_rtx_REG (CCmode, FLAGS_REG),
15544 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15545 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15549 (define_expand "isinf<mode>2"
15550 [(use (match_operand:SI 0 "register_operand" ""))
15551 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15552 "TARGET_USE_FANCY_MATH_387
15553 && TARGET_C99_FUNCTIONS
15554 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15556 rtx mask = GEN_INT (0x45);
15557 rtx val = GEN_INT (0x05);
15561 rtx scratch = gen_reg_rtx (HImode);
15562 rtx res = gen_reg_rtx (QImode);
15564 /* Remove excess precision by forcing value through memory. */
15565 if (memory_operand (operands[1], VOIDmode))
15566 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15569 enum ix86_stack_slot slot = (virtuals_instantiated
15572 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15574 emit_move_insn (temp, operands[1]);
15575 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15578 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15579 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15580 cond = gen_rtx_fmt_ee (EQ, QImode,
15581 gen_rtx_REG (CCmode, FLAGS_REG),
15583 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15584 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15588 (define_expand "signbitxf2"
15589 [(use (match_operand:SI 0 "register_operand" ""))
15590 (use (match_operand:XF 1 "register_operand" ""))]
15591 "TARGET_USE_FANCY_MATH_387"
15593 rtx scratch = gen_reg_rtx (HImode);
15595 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15596 emit_insn (gen_andsi3 (operands[0],
15597 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15601 (define_insn "movmsk_df"
15602 [(set (match_operand:SI 0 "register_operand" "=r")
15604 [(match_operand:DF 1 "register_operand" "x")]
15606 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15607 "%vmovmskpd\t{%1, %0|%0, %1}"
15608 [(set_attr "type" "ssemov")
15609 (set_attr "prefix" "maybe_vex")
15610 (set_attr "mode" "DF")])
15612 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15613 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15614 (define_expand "signbitdf2"
15615 [(use (match_operand:SI 0 "register_operand" ""))
15616 (use (match_operand:DF 1 "register_operand" ""))]
15617 "TARGET_USE_FANCY_MATH_387
15618 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15620 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15622 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15623 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15627 rtx scratch = gen_reg_rtx (HImode);
15629 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15630 emit_insn (gen_andsi3 (operands[0],
15631 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15636 (define_expand "signbitsf2"
15637 [(use (match_operand:SI 0 "register_operand" ""))
15638 (use (match_operand:SF 1 "register_operand" ""))]
15639 "TARGET_USE_FANCY_MATH_387
15640 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15642 rtx scratch = gen_reg_rtx (HImode);
15644 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15645 emit_insn (gen_andsi3 (operands[0],
15646 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15650 ;; Block operation instructions
15653 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15656 [(set_attr "length" "1")
15657 (set_attr "length_immediate" "0")
15658 (set_attr "modrm" "0")])
15660 (define_expand "movmem<mode>"
15661 [(use (match_operand:BLK 0 "memory_operand" ""))
15662 (use (match_operand:BLK 1 "memory_operand" ""))
15663 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15664 (use (match_operand:SWI48 3 "const_int_operand" ""))
15665 (use (match_operand:SI 4 "const_int_operand" ""))
15666 (use (match_operand:SI 5 "const_int_operand" ""))]
15669 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15670 operands[4], operands[5]))
15676 ;; Most CPUs don't like single string operations
15677 ;; Handle this case here to simplify previous expander.
15679 (define_expand "strmov"
15680 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15681 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15682 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15683 (clobber (reg:CC FLAGS_REG))])
15684 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15685 (clobber (reg:CC FLAGS_REG))])]
15688 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15690 /* If .md ever supports :P for Pmode, these can be directly
15691 in the pattern above. */
15692 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15693 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15695 /* Can't use this if the user has appropriated esi or edi. */
15696 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15697 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15699 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15700 operands[2], operands[3],
15701 operands[5], operands[6]));
15705 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15708 (define_expand "strmov_singleop"
15709 [(parallel [(set (match_operand 1 "memory_operand" "")
15710 (match_operand 3 "memory_operand" ""))
15711 (set (match_operand 0 "register_operand" "")
15712 (match_operand 4 "" ""))
15713 (set (match_operand 2 "register_operand" "")
15714 (match_operand 5 "" ""))])]
15716 "ix86_current_function_needs_cld = 1;")
15718 (define_insn "*strmovdi_rex_1"
15719 [(set (mem:DI (match_operand:P 2 "register_operand" "0"))
15720 (mem:DI (match_operand:P 3 "register_operand" "1")))
15721 (set (match_operand:P 0 "register_operand" "=D")
15722 (plus:P (match_dup 2)
15724 (set (match_operand:P 1 "register_operand" "=S")
15725 (plus:P (match_dup 3)
15728 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15730 [(set_attr "type" "str")
15731 (set_attr "memory" "both")
15732 (set_attr "mode" "DI")])
15734 (define_insn "*strmovsi_1"
15735 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15736 (mem:SI (match_operand:P 3 "register_operand" "1")))
15737 (set (match_operand:P 0 "register_operand" "=D")
15738 (plus:P (match_dup 2)
15740 (set (match_operand:P 1 "register_operand" "=S")
15741 (plus:P (match_dup 3)
15743 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15745 [(set_attr "type" "str")
15746 (set_attr "memory" "both")
15747 (set_attr "mode" "SI")])
15749 (define_insn "*strmovhi_1"
15750 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15751 (mem:HI (match_operand:P 3 "register_operand" "1")))
15752 (set (match_operand:P 0 "register_operand" "=D")
15753 (plus:P (match_dup 2)
15755 (set (match_operand:P 1 "register_operand" "=S")
15756 (plus:P (match_dup 3)
15758 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15760 [(set_attr "type" "str")
15761 (set_attr "memory" "both")
15762 (set_attr "mode" "HI")])
15764 (define_insn "*strmovqi_1"
15765 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15766 (mem:QI (match_operand:P 3 "register_operand" "1")))
15767 (set (match_operand:P 0 "register_operand" "=D")
15768 (plus:P (match_dup 2)
15770 (set (match_operand:P 1 "register_operand" "=S")
15771 (plus:P (match_dup 3)
15773 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15775 [(set_attr "type" "str")
15776 (set_attr "memory" "both")
15777 (set (attr "prefix_rex")
15779 (match_test "<P:MODE>mode == DImode")
15781 (const_string "*")))
15782 (set_attr "mode" "QI")])
15784 (define_expand "rep_mov"
15785 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15786 (set (match_operand 0 "register_operand" "")
15787 (match_operand 5 "" ""))
15788 (set (match_operand 2 "register_operand" "")
15789 (match_operand 6 "" ""))
15790 (set (match_operand 1 "memory_operand" "")
15791 (match_operand 3 "memory_operand" ""))
15792 (use (match_dup 4))])]
15794 "ix86_current_function_needs_cld = 1;")
15796 (define_insn "*rep_movdi_rex64"
15797 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15798 (set (match_operand:P 0 "register_operand" "=D")
15799 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15801 (match_operand:P 3 "register_operand" "0")))
15802 (set (match_operand:P 1 "register_operand" "=S")
15803 (plus:P (ashift:P (match_dup 5) (const_int 3))
15804 (match_operand:P 4 "register_operand" "1")))
15805 (set (mem:BLK (match_dup 3))
15806 (mem:BLK (match_dup 4)))
15807 (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" "DI")])
15816 (define_insn "*rep_movsi"
15817 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15818 (set (match_operand:P 0 "register_operand" "=D")
15819 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15821 (match_operand:P 3 "register_operand" "0")))
15822 (set (match_operand:P 1 "register_operand" "=S")
15823 (plus:P (ashift:P (match_dup 5) (const_int 2))
15824 (match_operand:P 4 "register_operand" "1")))
15825 (set (mem:BLK (match_dup 3))
15826 (mem:BLK (match_dup 4)))
15827 (use (match_dup 5))]
15828 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15829 "%^rep{%;} movs{l|d}"
15830 [(set_attr "type" "str")
15831 (set_attr "prefix_rep" "1")
15832 (set_attr "memory" "both")
15833 (set_attr "mode" "SI")])
15835 (define_insn "*rep_movqi"
15836 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15837 (set (match_operand:P 0 "register_operand" "=D")
15838 (plus:P (match_operand:P 3 "register_operand" "0")
15839 (match_operand:P 5 "register_operand" "2")))
15840 (set (match_operand:P 1 "register_operand" "=S")
15841 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15842 (set (mem:BLK (match_dup 3))
15843 (mem:BLK (match_dup 4)))
15844 (use (match_dup 5))]
15845 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15847 [(set_attr "type" "str")
15848 (set_attr "prefix_rep" "1")
15849 (set_attr "memory" "both")
15850 (set_attr "mode" "QI")])
15852 (define_expand "setmem<mode>"
15853 [(use (match_operand:BLK 0 "memory_operand" ""))
15854 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15855 (use (match_operand:QI 2 "nonmemory_operand" ""))
15856 (use (match_operand 3 "const_int_operand" ""))
15857 (use (match_operand:SI 4 "const_int_operand" ""))
15858 (use (match_operand:SI 5 "const_int_operand" ""))]
15861 if (ix86_expand_setmem (operands[0], operands[1],
15862 operands[2], operands[3],
15863 operands[4], operands[5]))
15869 ;; Most CPUs don't like single string operations
15870 ;; Handle this case here to simplify previous expander.
15872 (define_expand "strset"
15873 [(set (match_operand 1 "memory_operand" "")
15874 (match_operand 2 "register_operand" ""))
15875 (parallel [(set (match_operand 0 "register_operand" "")
15877 (clobber (reg:CC FLAGS_REG))])]
15880 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15881 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15883 /* If .md ever supports :P for Pmode, this can be directly
15884 in the pattern above. */
15885 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15886 GEN_INT (GET_MODE_SIZE (GET_MODE
15888 /* Can't use this if the user has appropriated eax or edi. */
15889 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15890 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15892 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15898 (define_expand "strset_singleop"
15899 [(parallel [(set (match_operand 1 "memory_operand" "")
15900 (match_operand 2 "register_operand" ""))
15901 (set (match_operand 0 "register_operand" "")
15902 (match_operand 3 "" ""))])]
15904 "ix86_current_function_needs_cld = 1;")
15906 (define_insn "*strsetdi_rex_1"
15907 [(set (mem:DI (match_operand:P 1 "register_operand" "0"))
15908 (match_operand:DI 2 "register_operand" "a"))
15909 (set (match_operand:P 0 "register_operand" "=D")
15910 (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 "mode" "DI")])
15919 (define_insn "*strsetsi_1"
15920 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15921 (match_operand:SI 2 "register_operand" "a"))
15922 (set (match_operand:P 0 "register_operand" "=D")
15923 (plus:P (match_dup 1)
15925 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15927 [(set_attr "type" "str")
15928 (set_attr "memory" "store")
15929 (set_attr "mode" "SI")])
15931 (define_insn "*strsethi_1"
15932 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15933 (match_operand:HI 2 "register_operand" "a"))
15934 (set (match_operand:P 0 "register_operand" "=D")
15935 (plus:P (match_dup 1)
15937 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15939 [(set_attr "type" "str")
15940 (set_attr "memory" "store")
15941 (set_attr "mode" "HI")])
15943 (define_insn "*strsetqi_1"
15944 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15945 (match_operand:QI 2 "register_operand" "a"))
15946 (set (match_operand:P 0 "register_operand" "=D")
15947 (plus:P (match_dup 1)
15949 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15951 [(set_attr "type" "str")
15952 (set_attr "memory" "store")
15953 (set (attr "prefix_rex")
15955 (match_test "<P:MODE>mode == DImode")
15957 (const_string "*")))
15958 (set_attr "mode" "QI")])
15960 (define_expand "rep_stos"
15961 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15962 (set (match_operand 0 "register_operand" "")
15963 (match_operand 4 "" ""))
15964 (set (match_operand 2 "memory_operand" "") (const_int 0))
15965 (use (match_operand 3 "register_operand" ""))
15966 (use (match_dup 1))])]
15968 "ix86_current_function_needs_cld = 1;")
15970 (define_insn "*rep_stosdi_rex64"
15971 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15972 (set (match_operand:P 0 "register_operand" "=D")
15973 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15975 (match_operand:P 3 "register_operand" "0")))
15976 (set (mem:BLK (match_dup 3))
15978 (use (match_operand:DI 2 "register_operand" "a"))
15979 (use (match_dup 4))]
15981 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15983 [(set_attr "type" "str")
15984 (set_attr "prefix_rep" "1")
15985 (set_attr "memory" "store")
15986 (set_attr "mode" "DI")])
15988 (define_insn "*rep_stossi"
15989 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15990 (set (match_operand:P 0 "register_operand" "=D")
15991 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15993 (match_operand:P 3 "register_operand" "0")))
15994 (set (mem:BLK (match_dup 3))
15996 (use (match_operand:SI 2 "register_operand" "a"))
15997 (use (match_dup 4))]
15998 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15999 "%^rep{%;} stos{l|d}"
16000 [(set_attr "type" "str")
16001 (set_attr "prefix_rep" "1")
16002 (set_attr "memory" "store")
16003 (set_attr "mode" "SI")])
16005 (define_insn "*rep_stosqi"
16006 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16007 (set (match_operand:P 0 "register_operand" "=D")
16008 (plus:P (match_operand:P 3 "register_operand" "0")
16009 (match_operand:P 4 "register_operand" "1")))
16010 (set (mem:BLK (match_dup 3))
16012 (use (match_operand:QI 2 "register_operand" "a"))
16013 (use (match_dup 4))]
16014 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16016 [(set_attr "type" "str")
16017 (set_attr "prefix_rep" "1")
16018 (set_attr "memory" "store")
16019 (set (attr "prefix_rex")
16021 (match_test "<P:MODE>mode == DImode")
16023 (const_string "*")))
16024 (set_attr "mode" "QI")])
16026 (define_expand "cmpstrnsi"
16027 [(set (match_operand:SI 0 "register_operand" "")
16028 (compare:SI (match_operand:BLK 1 "general_operand" "")
16029 (match_operand:BLK 2 "general_operand" "")))
16030 (use (match_operand 3 "general_operand" ""))
16031 (use (match_operand 4 "immediate_operand" ""))]
16034 rtx addr1, addr2, out, outlow, count, countreg, align;
16036 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16039 /* Can't use this if the user has appropriated ecx, esi or edi. */
16040 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16045 out = gen_reg_rtx (SImode);
16047 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16048 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16049 if (addr1 != XEXP (operands[1], 0))
16050 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16051 if (addr2 != XEXP (operands[2], 0))
16052 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16054 count = operands[3];
16055 countreg = ix86_zero_extend_to_Pmode (count);
16057 /* %%% Iff we are testing strict equality, we can use known alignment
16058 to good advantage. This may be possible with combine, particularly
16059 once cc0 is dead. */
16060 align = operands[4];
16062 if (CONST_INT_P (count))
16064 if (INTVAL (count) == 0)
16066 emit_move_insn (operands[0], const0_rtx);
16069 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16070 operands[1], operands[2]));
16074 rtx (*gen_cmp) (rtx, rtx);
16076 gen_cmp = (TARGET_64BIT
16077 ? gen_cmpdi_1 : gen_cmpsi_1);
16079 emit_insn (gen_cmp (countreg, countreg));
16080 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16081 operands[1], operands[2]));
16084 outlow = gen_lowpart (QImode, out);
16085 emit_insn (gen_cmpintqi (outlow));
16086 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16088 if (operands[0] != out)
16089 emit_move_insn (operands[0], out);
16094 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16096 (define_expand "cmpintqi"
16097 [(set (match_dup 1)
16098 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16100 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16101 (parallel [(set (match_operand:QI 0 "register_operand" "")
16102 (minus:QI (match_dup 1)
16104 (clobber (reg:CC FLAGS_REG))])]
16107 operands[1] = gen_reg_rtx (QImode);
16108 operands[2] = gen_reg_rtx (QImode);
16111 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16112 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16114 (define_expand "cmpstrnqi_nz_1"
16115 [(parallel [(set (reg:CC FLAGS_REG)
16116 (compare:CC (match_operand 4 "memory_operand" "")
16117 (match_operand 5 "memory_operand" "")))
16118 (use (match_operand 2 "register_operand" ""))
16119 (use (match_operand:SI 3 "immediate_operand" ""))
16120 (clobber (match_operand 0 "register_operand" ""))
16121 (clobber (match_operand 1 "register_operand" ""))
16122 (clobber (match_dup 2))])]
16124 "ix86_current_function_needs_cld = 1;")
16126 (define_insn "*cmpstrnqi_nz_1"
16127 [(set (reg:CC FLAGS_REG)
16128 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16129 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16130 (use (match_operand:P 6 "register_operand" "2"))
16131 (use (match_operand:SI 3 "immediate_operand" "i"))
16132 (clobber (match_operand:P 0 "register_operand" "=S"))
16133 (clobber (match_operand:P 1 "register_operand" "=D"))
16134 (clobber (match_operand:P 2 "register_operand" "=c"))]
16135 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16137 [(set_attr "type" "str")
16138 (set_attr "mode" "QI")
16139 (set (attr "prefix_rex")
16141 (match_test "<P:MODE>mode == DImode")
16143 (const_string "*")))
16144 (set_attr "prefix_rep" "1")])
16146 ;; The same, but the count is not known to not be zero.
16148 (define_expand "cmpstrnqi_1"
16149 [(parallel [(set (reg:CC FLAGS_REG)
16150 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16152 (compare:CC (match_operand 4 "memory_operand" "")
16153 (match_operand 5 "memory_operand" ""))
16155 (use (match_operand:SI 3 "immediate_operand" ""))
16156 (use (reg:CC FLAGS_REG))
16157 (clobber (match_operand 0 "register_operand" ""))
16158 (clobber (match_operand 1 "register_operand" ""))
16159 (clobber (match_dup 2))])]
16161 "ix86_current_function_needs_cld = 1;")
16163 (define_insn "*cmpstrnqi_1"
16164 [(set (reg:CC FLAGS_REG)
16165 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16167 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16168 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16170 (use (match_operand:SI 3 "immediate_operand" "i"))
16171 (use (reg:CC FLAGS_REG))
16172 (clobber (match_operand:P 0 "register_operand" "=S"))
16173 (clobber (match_operand:P 1 "register_operand" "=D"))
16174 (clobber (match_operand:P 2 "register_operand" "=c"))]
16175 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16177 [(set_attr "type" "str")
16178 (set_attr "mode" "QI")
16179 (set (attr "prefix_rex")
16181 (match_test "<P:MODE>mode == DImode")
16183 (const_string "*")))
16184 (set_attr "prefix_rep" "1")])
16186 (define_expand "strlen<mode>"
16187 [(set (match_operand:P 0 "register_operand" "")
16188 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16189 (match_operand:QI 2 "immediate_operand" "")
16190 (match_operand 3 "immediate_operand" "")]
16194 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16200 (define_expand "strlenqi_1"
16201 [(parallel [(set (match_operand 0 "register_operand" "")
16202 (match_operand 2 "" ""))
16203 (clobber (match_operand 1 "register_operand" ""))
16204 (clobber (reg:CC FLAGS_REG))])]
16206 "ix86_current_function_needs_cld = 1;")
16208 (define_insn "*strlenqi_1"
16209 [(set (match_operand:P 0 "register_operand" "=&c")
16210 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16211 (match_operand:QI 2 "register_operand" "a")
16212 (match_operand:P 3 "immediate_operand" "i")
16213 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16214 (clobber (match_operand:P 1 "register_operand" "=D"))
16215 (clobber (reg:CC FLAGS_REG))]
16216 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16217 "%^repnz{%;} scasb"
16218 [(set_attr "type" "str")
16219 (set_attr "mode" "QI")
16220 (set (attr "prefix_rex")
16222 (match_test "<P:MODE>mode == DImode")
16224 (const_string "*")))
16225 (set_attr "prefix_rep" "1")])
16227 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16228 ;; handled in combine, but it is not currently up to the task.
16229 ;; When used for their truth value, the cmpstrn* expanders generate
16238 ;; The intermediate three instructions are unnecessary.
16240 ;; This one handles cmpstrn*_nz_1...
16243 (set (reg:CC FLAGS_REG)
16244 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16245 (mem:BLK (match_operand 5 "register_operand" ""))))
16246 (use (match_operand 6 "register_operand" ""))
16247 (use (match_operand:SI 3 "immediate_operand" ""))
16248 (clobber (match_operand 0 "register_operand" ""))
16249 (clobber (match_operand 1 "register_operand" ""))
16250 (clobber (match_operand 2 "register_operand" ""))])
16251 (set (match_operand:QI 7 "register_operand" "")
16252 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16253 (set (match_operand:QI 8 "register_operand" "")
16254 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16255 (set (reg FLAGS_REG)
16256 (compare (match_dup 7) (match_dup 8)))
16258 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16260 (set (reg:CC FLAGS_REG)
16261 (compare:CC (mem:BLK (match_dup 4))
16262 (mem:BLK (match_dup 5))))
16263 (use (match_dup 6))
16264 (use (match_dup 3))
16265 (clobber (match_dup 0))
16266 (clobber (match_dup 1))
16267 (clobber (match_dup 2))])])
16269 ;; ...and this one handles cmpstrn*_1.
16272 (set (reg:CC FLAGS_REG)
16273 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16275 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16276 (mem:BLK (match_operand 5 "register_operand" "")))
16278 (use (match_operand:SI 3 "immediate_operand" ""))
16279 (use (reg:CC FLAGS_REG))
16280 (clobber (match_operand 0 "register_operand" ""))
16281 (clobber (match_operand 1 "register_operand" ""))
16282 (clobber (match_operand 2 "register_operand" ""))])
16283 (set (match_operand:QI 7 "register_operand" "")
16284 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16285 (set (match_operand:QI 8 "register_operand" "")
16286 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16287 (set (reg FLAGS_REG)
16288 (compare (match_dup 7) (match_dup 8)))
16290 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16292 (set (reg:CC FLAGS_REG)
16293 (if_then_else:CC (ne (match_dup 6)
16295 (compare:CC (mem:BLK (match_dup 4))
16296 (mem:BLK (match_dup 5)))
16298 (use (match_dup 3))
16299 (use (reg:CC FLAGS_REG))
16300 (clobber (match_dup 0))
16301 (clobber (match_dup 1))
16302 (clobber (match_dup 2))])])
16304 ;; Conditional move instructions.
16306 (define_expand "mov<mode>cc"
16307 [(set (match_operand:SWIM 0 "register_operand" "")
16308 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16309 (match_operand:SWIM 2 "<general_operand>" "")
16310 (match_operand:SWIM 3 "<general_operand>" "")))]
16312 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16314 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16315 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16316 ;; So just document what we're doing explicitly.
16318 (define_expand "x86_mov<mode>cc_0_m1"
16320 [(set (match_operand:SWI48 0 "register_operand" "")
16321 (if_then_else:SWI48
16322 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16323 [(match_operand 1 "flags_reg_operand" "")
16327 (clobber (reg:CC FLAGS_REG))])])
16329 (define_insn "*x86_mov<mode>cc_0_m1"
16330 [(set (match_operand:SWI48 0 "register_operand" "=r")
16331 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16332 [(reg FLAGS_REG) (const_int 0)])
16335 (clobber (reg:CC FLAGS_REG))]
16337 "sbb{<imodesuffix>}\t%0, %0"
16338 ; Since we don't have the proper number of operands for an alu insn,
16339 ; fill in all the blanks.
16340 [(set_attr "type" "alu")
16341 (set_attr "use_carry" "1")
16342 (set_attr "pent_pair" "pu")
16343 (set_attr "memory" "none")
16344 (set_attr "imm_disp" "false")
16345 (set_attr "mode" "<MODE>")
16346 (set_attr "length_immediate" "0")])
16348 (define_insn "*x86_mov<mode>cc_0_m1_se"
16349 [(set (match_operand:SWI48 0 "register_operand" "=r")
16350 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16351 [(reg FLAGS_REG) (const_int 0)])
16354 (clobber (reg:CC FLAGS_REG))]
16356 "sbb{<imodesuffix>}\t%0, %0"
16357 [(set_attr "type" "alu")
16358 (set_attr "use_carry" "1")
16359 (set_attr "pent_pair" "pu")
16360 (set_attr "memory" "none")
16361 (set_attr "imm_disp" "false")
16362 (set_attr "mode" "<MODE>")
16363 (set_attr "length_immediate" "0")])
16365 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16366 [(set (match_operand:SWI48 0 "register_operand" "=r")
16367 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16368 [(reg FLAGS_REG) (const_int 0)])))]
16370 "sbb{<imodesuffix>}\t%0, %0"
16371 [(set_attr "type" "alu")
16372 (set_attr "use_carry" "1")
16373 (set_attr "pent_pair" "pu")
16374 (set_attr "memory" "none")
16375 (set_attr "imm_disp" "false")
16376 (set_attr "mode" "<MODE>")
16377 (set_attr "length_immediate" "0")])
16379 (define_insn "*mov<mode>cc_noc"
16380 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16381 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16382 [(reg FLAGS_REG) (const_int 0)])
16383 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16384 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16385 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16387 cmov%O2%C1\t{%2, %0|%0, %2}
16388 cmov%O2%c1\t{%3, %0|%0, %3}"
16389 [(set_attr "type" "icmov")
16390 (set_attr "mode" "<MODE>")])
16392 (define_insn_and_split "*movqicc_noc"
16393 [(set (match_operand:QI 0 "register_operand" "=r,r")
16394 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16395 [(match_operand 4 "flags_reg_operand" "")
16397 (match_operand:QI 2 "register_operand" "r,0")
16398 (match_operand:QI 3 "register_operand" "0,r")))]
16399 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16401 "&& reload_completed"
16402 [(set (match_dup 0)
16403 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16406 "operands[0] = gen_lowpart (SImode, operands[0]);
16407 operands[2] = gen_lowpart (SImode, operands[2]);
16408 operands[3] = gen_lowpart (SImode, operands[3]);"
16409 [(set_attr "type" "icmov")
16410 (set_attr "mode" "SI")])
16412 (define_expand "mov<mode>cc"
16413 [(set (match_operand:X87MODEF 0 "register_operand" "")
16414 (if_then_else:X87MODEF
16415 (match_operand 1 "ix86_fp_comparison_operator" "")
16416 (match_operand:X87MODEF 2 "register_operand" "")
16417 (match_operand:X87MODEF 3 "register_operand" "")))]
16418 "(TARGET_80387 && TARGET_CMOVE)
16419 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16420 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16422 (define_insn "*movxfcc_1"
16423 [(set (match_operand:XF 0 "register_operand" "=f,f")
16424 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16425 [(reg FLAGS_REG) (const_int 0)])
16426 (match_operand:XF 2 "register_operand" "f,0")
16427 (match_operand:XF 3 "register_operand" "0,f")))]
16428 "TARGET_80387 && TARGET_CMOVE"
16430 fcmov%F1\t{%2, %0|%0, %2}
16431 fcmov%f1\t{%3, %0|%0, %3}"
16432 [(set_attr "type" "fcmov")
16433 (set_attr "mode" "XF")])
16435 (define_insn "*movdfcc_1_rex64"
16436 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16437 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16438 [(reg FLAGS_REG) (const_int 0)])
16439 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16440 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16441 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16442 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16444 fcmov%F1\t{%2, %0|%0, %2}
16445 fcmov%f1\t{%3, %0|%0, %3}
16446 cmov%O2%C1\t{%2, %0|%0, %2}
16447 cmov%O2%c1\t{%3, %0|%0, %3}"
16448 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16449 (set_attr "mode" "DF,DF,DI,DI")])
16451 (define_insn "*movdfcc_1"
16452 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16453 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16454 [(reg FLAGS_REG) (const_int 0)])
16455 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16456 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16457 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16458 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16460 fcmov%F1\t{%2, %0|%0, %2}
16461 fcmov%f1\t{%3, %0|%0, %3}
16464 [(set_attr "type" "fcmov,fcmov,multi,multi")
16465 (set_attr "mode" "DF,DF,DI,DI")])
16468 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
16469 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16470 [(match_operand 4 "flags_reg_operand" "")
16472 (match_operand:DF 2 "nonimmediate_operand" "")
16473 (match_operand:DF 3 "nonimmediate_operand" "")))]
16474 "!TARGET_64BIT && reload_completed"
16475 [(set (match_dup 2)
16476 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16480 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
16484 split_double_mode (DImode, &operands[2], 2, &operands[5], &operands[7]);
16485 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16488 (define_insn "*movsfcc_1_387"
16489 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16490 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16491 [(reg FLAGS_REG) (const_int 0)])
16492 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16493 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16494 "TARGET_80387 && TARGET_CMOVE
16495 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16497 fcmov%F1\t{%2, %0|%0, %2}
16498 fcmov%f1\t{%3, %0|%0, %3}
16499 cmov%O2%C1\t{%2, %0|%0, %2}
16500 cmov%O2%c1\t{%3, %0|%0, %3}"
16501 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16502 (set_attr "mode" "SF,SF,SI,SI")])
16504 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16505 ;; the scalar versions to have only XMM registers as operands.
16507 ;; XOP conditional move
16508 (define_insn "*xop_pcmov_<mode>"
16509 [(set (match_operand:MODEF 0 "register_operand" "=x")
16510 (if_then_else:MODEF
16511 (match_operand:MODEF 1 "register_operand" "x")
16512 (match_operand:MODEF 2 "register_operand" "x")
16513 (match_operand:MODEF 3 "register_operand" "x")))]
16515 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16516 [(set_attr "type" "sse4arg")])
16518 ;; These versions of the min/max patterns are intentionally ignorant of
16519 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16520 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16521 ;; are undefined in this condition, we're certain this is correct.
16523 (define_insn "<code><mode>3"
16524 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16526 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16527 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16528 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16530 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16531 v<maxmin_float><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 ;; These versions of the min/max patterns implement exactly the operations
16538 ;; min = (op1 < op2 ? op1 : op2)
16539 ;; max = (!(op1 < op2) ? op1 : op2)
16540 ;; Their operands are not commutative, and thus they may be used in the
16541 ;; presence of -0.0 and NaN.
16543 (define_insn "*ieee_smin<mode>3"
16544 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16546 [(match_operand:MODEF 1 "register_operand" "0,x")
16547 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16549 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16551 min<ssemodesuffix>\t{%2, %0|%0, %2}
16552 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16553 [(set_attr "isa" "noavx,avx")
16554 (set_attr "prefix" "orig,vex")
16555 (set_attr "type" "sseadd")
16556 (set_attr "mode" "<MODE>")])
16558 (define_insn "*ieee_smax<mode>3"
16559 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16561 [(match_operand:MODEF 1 "register_operand" "0,x")
16562 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16564 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16566 max<ssemodesuffix>\t{%2, %0|%0, %2}
16567 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16568 [(set_attr "isa" "noavx,avx")
16569 (set_attr "prefix" "orig,vex")
16570 (set_attr "type" "sseadd")
16571 (set_attr "mode" "<MODE>")])
16573 ;; Make two stack loads independent:
16575 ;; fld %st(0) -> fld bb
16576 ;; fmul bb fmul %st(1), %st
16578 ;; Actually we only match the last two instructions for simplicity.
16580 [(set (match_operand 0 "fp_register_operand" "")
16581 (match_operand 1 "fp_register_operand" ""))
16583 (match_operator 2 "binary_fp_operator"
16585 (match_operand 3 "memory_operand" "")]))]
16586 "REGNO (operands[0]) != REGNO (operands[1])"
16587 [(set (match_dup 0) (match_dup 3))
16588 (set (match_dup 0) (match_dup 4))]
16590 ;; The % modifier is not operational anymore in peephole2's, so we have to
16591 ;; swap the operands manually in the case of addition and multiplication.
16595 if (COMMUTATIVE_ARITH_P (operands[2]))
16596 op0 = operands[0], op1 = operands[1];
16598 op0 = operands[1], op1 = operands[0];
16600 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16601 GET_MODE (operands[2]),
16605 ;; Conditional addition patterns
16606 (define_expand "add<mode>cc"
16607 [(match_operand:SWI 0 "register_operand" "")
16608 (match_operand 1 "ordered_comparison_operator" "")
16609 (match_operand:SWI 2 "register_operand" "")
16610 (match_operand:SWI 3 "const_int_operand" "")]
16612 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16614 ;; Misc patterns (?)
16616 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16617 ;; Otherwise there will be nothing to keep
16619 ;; [(set (reg ebp) (reg esp))]
16620 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16621 ;; (clobber (eflags)]
16622 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16624 ;; in proper program order.
16626 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16627 [(set (match_operand:P 0 "register_operand" "=r,r")
16628 (plus:P (match_operand:P 1 "register_operand" "0,r")
16629 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16630 (clobber (reg:CC FLAGS_REG))
16631 (clobber (mem:BLK (scratch)))]
16634 switch (get_attr_type (insn))
16637 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16641 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16642 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16644 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16647 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16648 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16651 [(set (attr "type")
16652 (cond [(and (eq_attr "alternative" "0")
16653 (not (match_test "TARGET_OPT_AGU")))
16654 (const_string "alu")
16655 (match_operand:<MODE> 2 "const0_operand" "")
16656 (const_string "imov")
16658 (const_string "lea")))
16659 (set (attr "length_immediate")
16660 (cond [(eq_attr "type" "imov")
16662 (and (eq_attr "type" "alu")
16663 (match_operand 2 "const128_operand" ""))
16666 (const_string "*")))
16667 (set_attr "mode" "<MODE>")])
16669 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16670 [(set (match_operand:P 0 "register_operand" "=r")
16671 (minus:P (match_operand:P 1 "register_operand" "0")
16672 (match_operand:P 2 "register_operand" "r")))
16673 (clobber (reg:CC FLAGS_REG))
16674 (clobber (mem:BLK (scratch)))]
16676 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16677 [(set_attr "type" "alu")
16678 (set_attr "mode" "<MODE>")])
16680 (define_insn "allocate_stack_worker_probe_<mode>"
16681 [(set (match_operand:P 0 "register_operand" "=a")
16682 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16683 UNSPECV_STACK_PROBE))
16684 (clobber (reg:CC FLAGS_REG))]
16685 "ix86_target_stack_probe ()"
16686 "call\t___chkstk_ms"
16687 [(set_attr "type" "multi")
16688 (set_attr "length" "5")])
16690 (define_expand "allocate_stack"
16691 [(match_operand 0 "register_operand" "")
16692 (match_operand 1 "general_operand" "")]
16693 "ix86_target_stack_probe ()"
16697 #ifndef CHECK_STACK_LIMIT
16698 #define CHECK_STACK_LIMIT 0
16701 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16702 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16704 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16705 stack_pointer_rtx, 0, OPTAB_DIRECT);
16706 if (x != stack_pointer_rtx)
16707 emit_move_insn (stack_pointer_rtx, x);
16711 x = copy_to_mode_reg (Pmode, operands[1]);
16713 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16715 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16716 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16717 stack_pointer_rtx, 0, OPTAB_DIRECT);
16718 if (x != stack_pointer_rtx)
16719 emit_move_insn (stack_pointer_rtx, x);
16722 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16726 ;; Use IOR for stack probes, this is shorter.
16727 (define_expand "probe_stack"
16728 [(match_operand 0 "memory_operand" "")]
16731 rtx (*gen_ior3) (rtx, rtx, rtx);
16733 gen_ior3 = (GET_MODE (operands[0]) == DImode
16734 ? gen_iordi3 : gen_iorsi3);
16736 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16740 (define_insn "adjust_stack_and_probe<mode>"
16741 [(set (match_operand:P 0 "register_operand" "=r")
16742 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16743 UNSPECV_PROBE_STACK_RANGE))
16744 (set (reg:P SP_REG)
16745 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16746 (clobber (reg:CC FLAGS_REG))
16747 (clobber (mem:BLK (scratch)))]
16749 "* return output_adjust_stack_and_probe (operands[0]);"
16750 [(set_attr "type" "multi")])
16752 (define_insn "probe_stack_range<mode>"
16753 [(set (match_operand:P 0 "register_operand" "=r")
16754 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16755 (match_operand:P 2 "const_int_operand" "n")]
16756 UNSPECV_PROBE_STACK_RANGE))
16757 (clobber (reg:CC FLAGS_REG))]
16759 "* return output_probe_stack_range (operands[0], operands[2]);"
16760 [(set_attr "type" "multi")])
16762 (define_expand "builtin_setjmp_receiver"
16763 [(label_ref (match_operand 0 "" ""))]
16764 "!TARGET_64BIT && flag_pic"
16770 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16771 rtx label_rtx = gen_label_rtx ();
16772 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16773 xops[0] = xops[1] = picreg;
16774 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16775 ix86_expand_binary_operator (MINUS, SImode, xops);
16779 emit_insn (gen_set_got (pic_offset_table_rtx));
16783 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16786 [(set (match_operand 0 "register_operand" "")
16787 (match_operator 3 "promotable_binary_operator"
16788 [(match_operand 1 "register_operand" "")
16789 (match_operand 2 "aligned_operand" "")]))
16790 (clobber (reg:CC FLAGS_REG))]
16791 "! TARGET_PARTIAL_REG_STALL && reload_completed
16792 && ((GET_MODE (operands[0]) == HImode
16793 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16794 /* ??? next two lines just !satisfies_constraint_K (...) */
16795 || !CONST_INT_P (operands[2])
16796 || satisfies_constraint_K (operands[2])))
16797 || (GET_MODE (operands[0]) == QImode
16798 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16799 [(parallel [(set (match_dup 0)
16800 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16801 (clobber (reg:CC FLAGS_REG))])]
16803 operands[0] = gen_lowpart (SImode, operands[0]);
16804 operands[1] = gen_lowpart (SImode, operands[1]);
16805 if (GET_CODE (operands[3]) != ASHIFT)
16806 operands[2] = gen_lowpart (SImode, operands[2]);
16807 PUT_MODE (operands[3], SImode);
16810 ; Promote the QImode tests, as i386 has encoding of the AND
16811 ; instruction with 32-bit sign-extended immediate and thus the
16812 ; instruction size is unchanged, except in the %eax case for
16813 ; which it is increased by one byte, hence the ! optimize_size.
16815 [(set (match_operand 0 "flags_reg_operand" "")
16816 (match_operator 2 "compare_operator"
16817 [(and (match_operand 3 "aligned_operand" "")
16818 (match_operand 4 "const_int_operand" ""))
16820 (set (match_operand 1 "register_operand" "")
16821 (and (match_dup 3) (match_dup 4)))]
16822 "! TARGET_PARTIAL_REG_STALL && reload_completed
16823 && optimize_insn_for_speed_p ()
16824 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16825 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16826 /* Ensure that the operand will remain sign-extended immediate. */
16827 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16828 [(parallel [(set (match_dup 0)
16829 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16832 (and:SI (match_dup 3) (match_dup 4)))])]
16835 = gen_int_mode (INTVAL (operands[4])
16836 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16837 operands[1] = gen_lowpart (SImode, operands[1]);
16838 operands[3] = gen_lowpart (SImode, operands[3]);
16841 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16842 ; the TEST instruction with 32-bit sign-extended immediate and thus
16843 ; the instruction size would at least double, which is not what we
16844 ; want even with ! optimize_size.
16846 [(set (match_operand 0 "flags_reg_operand" "")
16847 (match_operator 1 "compare_operator"
16848 [(and (match_operand:HI 2 "aligned_operand" "")
16849 (match_operand:HI 3 "const_int_operand" ""))
16851 "! TARGET_PARTIAL_REG_STALL && reload_completed
16852 && ! TARGET_FAST_PREFIX
16853 && optimize_insn_for_speed_p ()
16854 /* Ensure that the operand will remain sign-extended immediate. */
16855 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16856 [(set (match_dup 0)
16857 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16861 = gen_int_mode (INTVAL (operands[3])
16862 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16863 operands[2] = gen_lowpart (SImode, operands[2]);
16867 [(set (match_operand 0 "register_operand" "")
16868 (neg (match_operand 1 "register_operand" "")))
16869 (clobber (reg:CC FLAGS_REG))]
16870 "! TARGET_PARTIAL_REG_STALL && reload_completed
16871 && (GET_MODE (operands[0]) == HImode
16872 || (GET_MODE (operands[0]) == QImode
16873 && (TARGET_PROMOTE_QImode
16874 || optimize_insn_for_size_p ())))"
16875 [(parallel [(set (match_dup 0)
16876 (neg:SI (match_dup 1)))
16877 (clobber (reg:CC FLAGS_REG))])]
16879 operands[0] = gen_lowpart (SImode, operands[0]);
16880 operands[1] = gen_lowpart (SImode, operands[1]);
16884 [(set (match_operand 0 "register_operand" "")
16885 (not (match_operand 1 "register_operand" "")))]
16886 "! TARGET_PARTIAL_REG_STALL && reload_completed
16887 && (GET_MODE (operands[0]) == HImode
16888 || (GET_MODE (operands[0]) == QImode
16889 && (TARGET_PROMOTE_QImode
16890 || optimize_insn_for_size_p ())))"
16891 [(set (match_dup 0)
16892 (not:SI (match_dup 1)))]
16894 operands[0] = gen_lowpart (SImode, operands[0]);
16895 operands[1] = gen_lowpart (SImode, operands[1]);
16899 [(set (match_operand 0 "register_operand" "")
16900 (if_then_else (match_operator 1 "ordered_comparison_operator"
16901 [(reg FLAGS_REG) (const_int 0)])
16902 (match_operand 2 "register_operand" "")
16903 (match_operand 3 "register_operand" "")))]
16904 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
16905 && (GET_MODE (operands[0]) == HImode
16906 || (GET_MODE (operands[0]) == QImode
16907 && (TARGET_PROMOTE_QImode
16908 || optimize_insn_for_size_p ())))"
16909 [(set (match_dup 0)
16910 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16912 operands[0] = gen_lowpart (SImode, operands[0]);
16913 operands[2] = gen_lowpart (SImode, operands[2]);
16914 operands[3] = gen_lowpart (SImode, operands[3]);
16917 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16918 ;; transform a complex memory operation into two memory to register operations.
16920 ;; Don't push memory operands
16922 [(set (match_operand:SWI 0 "push_operand" "")
16923 (match_operand:SWI 1 "memory_operand" ""))
16924 (match_scratch:SWI 2 "<r>")]
16925 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16926 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16927 [(set (match_dup 2) (match_dup 1))
16928 (set (match_dup 0) (match_dup 2))])
16930 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16933 [(set (match_operand:SF 0 "push_operand" "")
16934 (match_operand:SF 1 "memory_operand" ""))
16935 (match_scratch:SF 2 "r")]
16936 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16937 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16938 [(set (match_dup 2) (match_dup 1))
16939 (set (match_dup 0) (match_dup 2))])
16941 ;; Don't move an immediate directly to memory when the instruction
16944 [(match_scratch:SWI124 1 "<r>")
16945 (set (match_operand:SWI124 0 "memory_operand" "")
16947 "optimize_insn_for_speed_p ()
16948 && !TARGET_USE_MOV0
16949 && TARGET_SPLIT_LONG_MOVES
16950 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16951 && peep2_regno_dead_p (0, FLAGS_REG)"
16952 [(parallel [(set (match_dup 2) (const_int 0))
16953 (clobber (reg:CC FLAGS_REG))])
16954 (set (match_dup 0) (match_dup 1))]
16955 "operands[2] = gen_lowpart (SImode, operands[1]);")
16958 [(match_scratch:SWI124 2 "<r>")
16959 (set (match_operand:SWI124 0 "memory_operand" "")
16960 (match_operand:SWI124 1 "immediate_operand" ""))]
16961 "optimize_insn_for_speed_p ()
16962 && TARGET_SPLIT_LONG_MOVES
16963 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16964 [(set (match_dup 2) (match_dup 1))
16965 (set (match_dup 0) (match_dup 2))])
16967 ;; Don't compare memory with zero, load and use a test instead.
16969 [(set (match_operand 0 "flags_reg_operand" "")
16970 (match_operator 1 "compare_operator"
16971 [(match_operand:SI 2 "memory_operand" "")
16973 (match_scratch:SI 3 "r")]
16974 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16975 [(set (match_dup 3) (match_dup 2))
16976 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16978 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16979 ;; Don't split NOTs with a displacement operand, because resulting XOR
16980 ;; will not be pairable anyway.
16982 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16983 ;; represented using a modRM byte. The XOR replacement is long decoded,
16984 ;; so this split helps here as well.
16986 ;; Note: Can't do this as a regular split because we can't get proper
16987 ;; lifetime information then.
16990 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16991 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16992 "optimize_insn_for_speed_p ()
16993 && ((TARGET_NOT_UNPAIRABLE
16994 && (!MEM_P (operands[0])
16995 || !memory_displacement_operand (operands[0], <MODE>mode)))
16996 || (TARGET_NOT_VECTORMODE
16997 && long_memory_operand (operands[0], <MODE>mode)))
16998 && peep2_regno_dead_p (0, FLAGS_REG)"
16999 [(parallel [(set (match_dup 0)
17000 (xor:SWI124 (match_dup 1) (const_int -1)))
17001 (clobber (reg:CC FLAGS_REG))])])
17003 ;; Non pairable "test imm, reg" instructions can be translated to
17004 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17005 ;; byte opcode instead of two, have a short form for byte operands),
17006 ;; so do it for other CPUs as well. Given that the value was dead,
17007 ;; this should not create any new dependencies. Pass on the sub-word
17008 ;; versions if we're concerned about partial register stalls.
17011 [(set (match_operand 0 "flags_reg_operand" "")
17012 (match_operator 1 "compare_operator"
17013 [(and:SI (match_operand:SI 2 "register_operand" "")
17014 (match_operand:SI 3 "immediate_operand" ""))
17016 "ix86_match_ccmode (insn, CCNOmode)
17017 && (true_regnum (operands[2]) != AX_REG
17018 || satisfies_constraint_K (operands[3]))
17019 && peep2_reg_dead_p (1, operands[2])"
17021 [(set (match_dup 0)
17022 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17025 (and:SI (match_dup 2) (match_dup 3)))])])
17027 ;; We don't need to handle HImode case, because it will be promoted to SImode
17028 ;; on ! TARGET_PARTIAL_REG_STALL
17031 [(set (match_operand 0 "flags_reg_operand" "")
17032 (match_operator 1 "compare_operator"
17033 [(and:QI (match_operand:QI 2 "register_operand" "")
17034 (match_operand:QI 3 "immediate_operand" ""))
17036 "! TARGET_PARTIAL_REG_STALL
17037 && ix86_match_ccmode (insn, CCNOmode)
17038 && true_regnum (operands[2]) != AX_REG
17039 && peep2_reg_dead_p (1, operands[2])"
17041 [(set (match_dup 0)
17042 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17045 (and:QI (match_dup 2) (match_dup 3)))])])
17048 [(set (match_operand 0 "flags_reg_operand" "")
17049 (match_operator 1 "compare_operator"
17052 (match_operand 2 "ext_register_operand" "")
17055 (match_operand 3 "const_int_operand" ""))
17057 "! TARGET_PARTIAL_REG_STALL
17058 && ix86_match_ccmode (insn, CCNOmode)
17059 && true_regnum (operands[2]) != AX_REG
17060 && peep2_reg_dead_p (1, operands[2])"
17061 [(parallel [(set (match_dup 0)
17070 (set (zero_extract:SI (match_dup 2)
17078 (match_dup 3)))])])
17080 ;; Don't do logical operations with memory inputs.
17082 [(match_scratch:SI 2 "r")
17083 (parallel [(set (match_operand:SI 0 "register_operand" "")
17084 (match_operator:SI 3 "arith_or_logical_operator"
17086 (match_operand:SI 1 "memory_operand" "")]))
17087 (clobber (reg:CC FLAGS_REG))])]
17088 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17089 [(set (match_dup 2) (match_dup 1))
17090 (parallel [(set (match_dup 0)
17091 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17092 (clobber (reg:CC FLAGS_REG))])])
17095 [(match_scratch:SI 2 "r")
17096 (parallel [(set (match_operand:SI 0 "register_operand" "")
17097 (match_operator:SI 3 "arith_or_logical_operator"
17098 [(match_operand:SI 1 "memory_operand" "")
17100 (clobber (reg:CC FLAGS_REG))])]
17101 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17102 [(set (match_dup 2) (match_dup 1))
17103 (parallel [(set (match_dup 0)
17104 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17105 (clobber (reg:CC FLAGS_REG))])])
17107 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17108 ;; refers to the destination of the load!
17111 [(set (match_operand:SI 0 "register_operand" "")
17112 (match_operand:SI 1 "register_operand" ""))
17113 (parallel [(set (match_dup 0)
17114 (match_operator:SI 3 "commutative_operator"
17116 (match_operand:SI 2 "memory_operand" "")]))
17117 (clobber (reg:CC FLAGS_REG))])]
17118 "REGNO (operands[0]) != REGNO (operands[1])
17119 && GENERAL_REGNO_P (REGNO (operands[0]))
17120 && GENERAL_REGNO_P (REGNO (operands[1]))"
17121 [(set (match_dup 0) (match_dup 4))
17122 (parallel [(set (match_dup 0)
17123 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17124 (clobber (reg:CC FLAGS_REG))])]
17125 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17128 [(set (match_operand 0 "register_operand" "")
17129 (match_operand 1 "register_operand" ""))
17131 (match_operator 3 "commutative_operator"
17133 (match_operand 2 "memory_operand" "")]))]
17134 "REGNO (operands[0]) != REGNO (operands[1])
17135 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17136 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17137 [(set (match_dup 0) (match_dup 2))
17139 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17141 ; Don't do logical operations with memory outputs
17143 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17144 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17145 ; the same decoder scheduling characteristics as the original.
17148 [(match_scratch:SI 2 "r")
17149 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17150 (match_operator:SI 3 "arith_or_logical_operator"
17152 (match_operand:SI 1 "nonmemory_operand" "")]))
17153 (clobber (reg:CC FLAGS_REG))])]
17154 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17155 /* Do not split stack checking probes. */
17156 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17157 [(set (match_dup 2) (match_dup 0))
17158 (parallel [(set (match_dup 2)
17159 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17160 (clobber (reg:CC FLAGS_REG))])
17161 (set (match_dup 0) (match_dup 2))])
17164 [(match_scratch:SI 2 "r")
17165 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17166 (match_operator:SI 3 "arith_or_logical_operator"
17167 [(match_operand:SI 1 "nonmemory_operand" "")
17169 (clobber (reg:CC FLAGS_REG))])]
17170 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17171 /* Do not split stack checking probes. */
17172 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17173 [(set (match_dup 2) (match_dup 0))
17174 (parallel [(set (match_dup 2)
17175 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17176 (clobber (reg:CC FLAGS_REG))])
17177 (set (match_dup 0) (match_dup 2))])
17179 ;; Attempt to use arith or logical operations with memory outputs with
17180 ;; setting of flags.
17182 [(set (match_operand:SWI 0 "register_operand" "")
17183 (match_operand:SWI 1 "memory_operand" ""))
17184 (parallel [(set (match_dup 0)
17185 (match_operator:SWI 3 "plusminuslogic_operator"
17187 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17188 (clobber (reg:CC FLAGS_REG))])
17189 (set (match_dup 1) (match_dup 0))
17190 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17191 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17192 && peep2_reg_dead_p (4, operands[0])
17193 && !reg_overlap_mentioned_p (operands[0], operands[1])
17194 && ix86_match_ccmode (peep2_next_insn (3),
17195 (GET_CODE (operands[3]) == PLUS
17196 || GET_CODE (operands[3]) == MINUS)
17197 ? CCGOCmode : CCNOmode)"
17198 [(parallel [(set (match_dup 4) (match_dup 5))
17199 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17200 (match_dup 2)]))])]
17202 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17203 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17204 copy_rtx (operands[1]),
17205 copy_rtx (operands[2]));
17206 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17207 operands[5], const0_rtx);
17211 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17212 (match_operator:SWI 2 "plusminuslogic_operator"
17214 (match_operand:SWI 1 "memory_operand" "")]))
17215 (clobber (reg:CC FLAGS_REG))])
17216 (set (match_dup 1) (match_dup 0))
17217 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17218 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17219 && GET_CODE (operands[2]) != MINUS
17220 && peep2_reg_dead_p (3, operands[0])
17221 && !reg_overlap_mentioned_p (operands[0], operands[1])
17222 && ix86_match_ccmode (peep2_next_insn (2),
17223 GET_CODE (operands[2]) == PLUS
17224 ? CCGOCmode : CCNOmode)"
17225 [(parallel [(set (match_dup 3) (match_dup 4))
17226 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17227 (match_dup 0)]))])]
17229 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17230 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17231 copy_rtx (operands[1]),
17232 copy_rtx (operands[0]));
17233 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17234 operands[4], const0_rtx);
17238 [(set (match_operand:SWI12 0 "register_operand" "")
17239 (match_operand:SWI12 1 "memory_operand" ""))
17240 (parallel [(set (match_operand:SI 4 "register_operand" "")
17241 (match_operator:SI 3 "plusminuslogic_operator"
17243 (match_operand:SI 2 "nonmemory_operand" "")]))
17244 (clobber (reg:CC FLAGS_REG))])
17245 (set (match_dup 1) (match_dup 0))
17246 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17247 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17248 && REG_P (operands[0]) && REG_P (operands[4])
17249 && REGNO (operands[0]) == REGNO (operands[4])
17250 && peep2_reg_dead_p (4, operands[0])
17251 && (<MODE>mode != QImode
17252 || immediate_operand (operands[2], SImode)
17253 || q_regs_operand (operands[2], SImode))
17254 && !reg_overlap_mentioned_p (operands[0], operands[1])
17255 && ix86_match_ccmode (peep2_next_insn (3),
17256 (GET_CODE (operands[3]) == PLUS
17257 || GET_CODE (operands[3]) == MINUS)
17258 ? CCGOCmode : CCNOmode)"
17259 [(parallel [(set (match_dup 4) (match_dup 5))
17260 (set (match_dup 1) (match_dup 6))])]
17262 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17263 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17264 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17265 copy_rtx (operands[1]), operands[2]);
17266 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17267 operands[5], const0_rtx);
17268 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17269 copy_rtx (operands[1]),
17270 copy_rtx (operands[2]));
17273 ;; Attempt to always use XOR for zeroing registers.
17275 [(set (match_operand 0 "register_operand" "")
17276 (match_operand 1 "const0_operand" ""))]
17277 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17278 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17279 && GENERAL_REG_P (operands[0])
17280 && peep2_regno_dead_p (0, FLAGS_REG)"
17281 [(parallel [(set (match_dup 0) (const_int 0))
17282 (clobber (reg:CC FLAGS_REG))])]
17283 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17286 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17288 "(GET_MODE (operands[0]) == QImode
17289 || GET_MODE (operands[0]) == HImode)
17290 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17291 && peep2_regno_dead_p (0, FLAGS_REG)"
17292 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17293 (clobber (reg:CC FLAGS_REG))])])
17295 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17297 [(set (match_operand:SWI248 0 "register_operand" "")
17299 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17300 && peep2_regno_dead_p (0, FLAGS_REG)"
17301 [(parallel [(set (match_dup 0) (const_int -1))
17302 (clobber (reg:CC FLAGS_REG))])]
17304 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17305 operands[0] = gen_lowpart (SImode, operands[0]);
17308 ;; Attempt to convert simple lea to add/shift.
17309 ;; These can be created by move expanders.
17312 [(set (match_operand:SWI48 0 "register_operand" "")
17313 (plus:SWI48 (match_dup 0)
17314 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17315 "peep2_regno_dead_p (0, FLAGS_REG)"
17316 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17317 (clobber (reg:CC FLAGS_REG))])])
17320 [(set (match_operand:SI 0 "register_operand" "")
17321 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17322 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17324 && peep2_regno_dead_p (0, FLAGS_REG)
17325 && REGNO (operands[0]) == REGNO (operands[1])"
17326 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17327 (clobber (reg:CC FLAGS_REG))])]
17328 "operands[2] = gen_lowpart (SImode, operands[2]);")
17331 [(set (match_operand:SWI48 0 "register_operand" "")
17332 (mult:SWI48 (match_dup 0)
17333 (match_operand:SWI48 1 "const_int_operand" "")))]
17334 "exact_log2 (INTVAL (operands[1])) >= 0
17335 && peep2_regno_dead_p (0, FLAGS_REG)"
17336 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17337 (clobber (reg:CC FLAGS_REG))])]
17338 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17341 [(set (match_operand:SI 0 "register_operand" "")
17342 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17343 (match_operand:DI 2 "const_int_operand" "")) 0))]
17345 && exact_log2 (INTVAL (operands[2])) >= 0
17346 && REGNO (operands[0]) == REGNO (operands[1])
17347 && peep2_regno_dead_p (0, FLAGS_REG)"
17348 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17349 (clobber (reg:CC FLAGS_REG))])]
17350 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17352 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17353 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17354 ;; On many CPUs it is also faster, since special hardware to avoid esp
17355 ;; dependencies is present.
17357 ;; While some of these conversions may be done using splitters, we use
17358 ;; peepholes in order to allow combine_stack_adjustments pass to see
17359 ;; nonobfuscated RTL.
17361 ;; Convert prologue esp subtractions to push.
17362 ;; We need register to push. In order to keep verify_flow_info happy we have
17364 ;; - use scratch and clobber it in order to avoid dependencies
17365 ;; - use already live register
17366 ;; We can't use the second way right now, since there is no reliable way how to
17367 ;; verify that given register is live. First choice will also most likely in
17368 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17369 ;; call clobbered registers are dead. We may want to use base pointer as an
17370 ;; alternative when no register is available later.
17373 [(match_scratch:W 1 "r")
17374 (parallel [(set (reg:P SP_REG)
17375 (plus:P (reg:P SP_REG)
17376 (match_operand:P 0 "const_int_operand" "")))
17377 (clobber (reg:CC FLAGS_REG))
17378 (clobber (mem:BLK (scratch)))])]
17379 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17380 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17381 [(clobber (match_dup 1))
17382 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17383 (clobber (mem:BLK (scratch)))])])
17386 [(match_scratch:W 1 "r")
17387 (parallel [(set (reg:P SP_REG)
17388 (plus:P (reg:P SP_REG)
17389 (match_operand:P 0 "const_int_operand" "")))
17390 (clobber (reg:CC FLAGS_REG))
17391 (clobber (mem:BLK (scratch)))])]
17392 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17393 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17394 [(clobber (match_dup 1))
17395 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17396 (parallel [(set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17397 (clobber (mem:BLK (scratch)))])])
17399 ;; Convert esp subtractions to push.
17401 [(match_scratch:W 1 "r")
17402 (parallel [(set (reg:P SP_REG)
17403 (plus:P (reg:P SP_REG)
17404 (match_operand:P 0 "const_int_operand" "")))
17405 (clobber (reg:CC FLAGS_REG))])]
17406 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17407 && INTVAL (operands[0]) == -GET_MODE_SIZE (word_mode)"
17408 [(clobber (match_dup 1))
17409 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17412 [(match_scratch:W 1 "r")
17413 (parallel [(set (reg:P SP_REG)
17414 (plus:P (reg:P SP_REG)
17415 (match_operand:P 0 "const_int_operand" "")))
17416 (clobber (reg:CC FLAGS_REG))])]
17417 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17418 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (word_mode)"
17419 [(clobber (match_dup 1))
17420 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17421 (set (mem:W (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17423 ;; Convert epilogue deallocator to pop.
17425 [(match_scratch:W 1 "r")
17426 (parallel [(set (reg:P SP_REG)
17427 (plus:P (reg:P SP_REG)
17428 (match_operand:P 0 "const_int_operand" "")))
17429 (clobber (reg:CC FLAGS_REG))
17430 (clobber (mem:BLK (scratch)))])]
17431 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17432 && INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17433 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17434 (clobber (mem:BLK (scratch)))])])
17436 ;; Two pops case is tricky, since pop causes dependency
17437 ;; on destination register. We use two registers if available.
17439 [(match_scratch:W 1 "r")
17440 (match_scratch:W 2 "r")
17441 (parallel [(set (reg:P SP_REG)
17442 (plus:P (reg:P SP_REG)
17443 (match_operand:P 0 "const_int_operand" "")))
17444 (clobber (reg:CC FLAGS_REG))
17445 (clobber (mem:BLK (scratch)))])]
17446 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17447 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17448 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17449 (clobber (mem:BLK (scratch)))])
17450 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17453 [(match_scratch:W 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 (clobber (mem:BLK (scratch)))])]
17459 "optimize_insn_for_size_p ()
17460 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17461 [(parallel [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17462 (clobber (mem:BLK (scratch)))])
17463 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17465 ;; Convert esp additions to pop.
17467 [(match_scratch:W 1 "r")
17468 (parallel [(set (reg:P SP_REG)
17469 (plus:P (reg:P SP_REG)
17470 (match_operand:P 0 "const_int_operand" "")))
17471 (clobber (reg:CC FLAGS_REG))])]
17472 "INTVAL (operands[0]) == GET_MODE_SIZE (word_mode)"
17473 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17475 ;; Two pops case is tricky, since pop causes dependency
17476 ;; on destination register. We use two registers if available.
17478 [(match_scratch:W 1 "r")
17479 (match_scratch:W 2 "r")
17480 (parallel [(set (reg:P SP_REG)
17481 (plus:P (reg:P SP_REG)
17482 (match_operand:P 0 "const_int_operand" "")))
17483 (clobber (reg:CC FLAGS_REG))])]
17484 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17485 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17486 (set (match_dup 2) (mem:W (post_inc:P (reg:P SP_REG))))])
17489 [(match_scratch:W 1 "r")
17490 (parallel [(set (reg:P SP_REG)
17491 (plus:P (reg:P SP_REG)
17492 (match_operand:P 0 "const_int_operand" "")))
17493 (clobber (reg:CC FLAGS_REG))])]
17494 "optimize_insn_for_size_p ()
17495 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (word_mode)"
17496 [(set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))
17497 (set (match_dup 1) (mem:W (post_inc:P (reg:P SP_REG))))])
17499 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17500 ;; required and register dies. Similarly for 128 to -128.
17502 [(set (match_operand 0 "flags_reg_operand" "")
17503 (match_operator 1 "compare_operator"
17504 [(match_operand 2 "register_operand" "")
17505 (match_operand 3 "const_int_operand" "")]))]
17506 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17507 && incdec_operand (operands[3], GET_MODE (operands[3])))
17508 || (!TARGET_FUSE_CMP_AND_BRANCH
17509 && INTVAL (operands[3]) == 128))
17510 && ix86_match_ccmode (insn, CCGCmode)
17511 && peep2_reg_dead_p (1, operands[2])"
17512 [(parallel [(set (match_dup 0)
17513 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17514 (clobber (match_dup 2))])])
17516 ;; Convert imul by three, five and nine into lea
17519 [(set (match_operand:SWI48 0 "register_operand" "")
17520 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17521 (match_operand:SWI48 2 "const359_operand" "")))
17522 (clobber (reg:CC FLAGS_REG))])]
17523 "!TARGET_PARTIAL_REG_STALL
17524 || <MODE>mode == SImode
17525 || optimize_function_for_size_p (cfun)"
17526 [(set (match_dup 0)
17527 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17529 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17533 [(set (match_operand:SWI48 0 "register_operand" "")
17534 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17535 (match_operand:SWI48 2 "const359_operand" "")))
17536 (clobber (reg:CC FLAGS_REG))])]
17537 "optimize_insn_for_speed_p ()
17538 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17539 [(set (match_dup 0) (match_dup 1))
17541 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17543 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17545 ;; imul $32bit_imm, mem, reg is vector decoded, while
17546 ;; imul $32bit_imm, reg, reg is direct decoded.
17548 [(match_scratch:SWI48 3 "r")
17549 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17550 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17551 (match_operand:SWI48 2 "immediate_operand" "")))
17552 (clobber (reg:CC FLAGS_REG))])]
17553 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17554 && !satisfies_constraint_K (operands[2])"
17555 [(set (match_dup 3) (match_dup 1))
17556 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17557 (clobber (reg:CC FLAGS_REG))])])
17560 [(match_scratch:SI 3 "r")
17561 (parallel [(set (match_operand:DI 0 "register_operand" "")
17563 (mult:SI (match_operand:SI 1 "memory_operand" "")
17564 (match_operand:SI 2 "immediate_operand" ""))))
17565 (clobber (reg:CC FLAGS_REG))])]
17567 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17568 && !satisfies_constraint_K (operands[2])"
17569 [(set (match_dup 3) (match_dup 1))
17570 (parallel [(set (match_dup 0)
17571 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17572 (clobber (reg:CC FLAGS_REG))])])
17574 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17575 ;; Convert it into imul reg, reg
17576 ;; It would be better to force assembler to encode instruction using long
17577 ;; immediate, but there is apparently no way to do so.
17579 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17581 (match_operand:SWI248 1 "nonimmediate_operand" "")
17582 (match_operand:SWI248 2 "const_int_operand" "")))
17583 (clobber (reg:CC FLAGS_REG))])
17584 (match_scratch:SWI248 3 "r")]
17585 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17586 && satisfies_constraint_K (operands[2])"
17587 [(set (match_dup 3) (match_dup 2))
17588 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17589 (clobber (reg:CC FLAGS_REG))])]
17591 if (!rtx_equal_p (operands[0], operands[1]))
17592 emit_move_insn (operands[0], operands[1]);
17595 ;; After splitting up read-modify operations, array accesses with memory
17596 ;; operands might end up in form:
17598 ;; movl 4(%esp), %edx
17600 ;; instead of pre-splitting:
17602 ;; addl 4(%esp), %eax
17604 ;; movl 4(%esp), %edx
17605 ;; leal (%edx,%eax,4), %eax
17608 [(match_scratch:W 5 "r")
17609 (parallel [(set (match_operand 0 "register_operand" "")
17610 (ashift (match_operand 1 "register_operand" "")
17611 (match_operand 2 "const_int_operand" "")))
17612 (clobber (reg:CC FLAGS_REG))])
17613 (parallel [(set (match_operand 3 "register_operand" "")
17614 (plus (match_dup 0)
17615 (match_operand 4 "x86_64_general_operand" "")))
17616 (clobber (reg:CC FLAGS_REG))])]
17617 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17618 /* Validate MODE for lea. */
17619 && ((!TARGET_PARTIAL_REG_STALL
17620 && (GET_MODE (operands[0]) == QImode
17621 || GET_MODE (operands[0]) == HImode))
17622 || GET_MODE (operands[0]) == SImode
17623 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17624 && (rtx_equal_p (operands[0], operands[3])
17625 || peep2_reg_dead_p (2, operands[0]))
17626 /* We reorder load and the shift. */
17627 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17628 [(set (match_dup 5) (match_dup 4))
17629 (set (match_dup 0) (match_dup 1))]
17631 enum machine_mode op1mode = GET_MODE (operands[1]);
17632 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17633 int scale = 1 << INTVAL (operands[2]);
17634 rtx index = gen_lowpart (word_mode, operands[1]);
17635 rtx base = gen_lowpart (word_mode, operands[5]);
17636 rtx dest = gen_lowpart (mode, operands[3]);
17638 operands[1] = gen_rtx_PLUS (word_mode, base,
17639 gen_rtx_MULT (word_mode, index, GEN_INT (scale)));
17640 operands[5] = base;
17641 if (mode != word_mode)
17642 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17643 if (op1mode != word_mode)
17644 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17645 operands[0] = dest;
17648 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17649 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17650 ;; caught for use by garbage collectors and the like. Using an insn that
17651 ;; maps to SIGILL makes it more likely the program will rightfully die.
17652 ;; Keeping with tradition, "6" is in honor of #UD.
17653 (define_insn "trap"
17654 [(trap_if (const_int 1) (const_int 6))]
17656 { return ASM_SHORT "0x0b0f"; }
17657 [(set_attr "length" "2")])
17659 (define_expand "prefetch"
17660 [(prefetch (match_operand 0 "address_operand" "")
17661 (match_operand:SI 1 "const_int_operand" "")
17662 (match_operand:SI 2 "const_int_operand" ""))]
17663 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17665 int rw = INTVAL (operands[1]);
17666 int locality = INTVAL (operands[2]);
17668 gcc_assert (rw == 0 || rw == 1);
17669 gcc_assert (locality >= 0 && locality <= 3);
17670 gcc_assert (GET_MODE (operands[0]) == Pmode
17671 || GET_MODE (operands[0]) == VOIDmode);
17673 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17674 supported by SSE counterpart or the SSE prefetch is not available
17675 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17677 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17678 operands[2] = GEN_INT (3);
17680 operands[1] = const0_rtx;
17683 (define_insn "*prefetch_sse_<mode>"
17684 [(prefetch (match_operand:P 0 "address_operand" "p")
17686 (match_operand:SI 1 "const_int_operand" ""))]
17687 "TARGET_PREFETCH_SSE"
17689 static const char * const patterns[4] = {
17690 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17693 int locality = INTVAL (operands[1]);
17694 gcc_assert (locality >= 0 && locality <= 3);
17696 return patterns[locality];
17698 [(set_attr "type" "sse")
17699 (set_attr "atom_sse_attr" "prefetch")
17700 (set (attr "length_address")
17701 (symbol_ref "memory_address_length (operands[0])"))
17702 (set_attr "memory" "none")])
17704 (define_insn "*prefetch_3dnow_<mode>"
17705 [(prefetch (match_operand:P 0 "address_operand" "p")
17706 (match_operand:SI 1 "const_int_operand" "n")
17710 if (INTVAL (operands[1]) == 0)
17711 return "prefetch\t%a0";
17713 return "prefetchw\t%a0";
17715 [(set_attr "type" "mmx")
17716 (set (attr "length_address")
17717 (symbol_ref "memory_address_length (operands[0])"))
17718 (set_attr "memory" "none")])
17720 (define_expand "stack_protect_set"
17721 [(match_operand 0 "memory_operand" "")
17722 (match_operand 1 "memory_operand" "")]
17725 rtx (*insn)(rtx, rtx);
17727 #ifdef TARGET_THREAD_SSP_OFFSET
17728 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17729 insn = (TARGET_LP64
17730 ? gen_stack_tls_protect_set_di
17731 : gen_stack_tls_protect_set_si);
17733 insn = (TARGET_LP64
17734 ? gen_stack_protect_set_di
17735 : gen_stack_protect_set_si);
17738 emit_insn (insn (operands[0], operands[1]));
17742 (define_insn "stack_protect_set_<mode>"
17743 [(set (match_operand:PTR 0 "memory_operand" "=m")
17744 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17746 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17747 (clobber (reg:CC FLAGS_REG))]
17749 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17750 [(set_attr "type" "multi")])
17752 (define_insn "stack_tls_protect_set_<mode>"
17753 [(set (match_operand:PTR 0 "memory_operand" "=m")
17754 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17755 UNSPEC_SP_TLS_SET))
17756 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17757 (clobber (reg:CC FLAGS_REG))]
17759 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17760 [(set_attr "type" "multi")])
17762 (define_expand "stack_protect_test"
17763 [(match_operand 0 "memory_operand" "")
17764 (match_operand 1 "memory_operand" "")
17765 (match_operand 2 "" "")]
17768 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17770 rtx (*insn)(rtx, rtx, rtx);
17772 #ifdef TARGET_THREAD_SSP_OFFSET
17773 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17774 insn = (TARGET_LP64
17775 ? gen_stack_tls_protect_test_di
17776 : gen_stack_tls_protect_test_si);
17778 insn = (TARGET_LP64
17779 ? gen_stack_protect_test_di
17780 : gen_stack_protect_test_si);
17783 emit_insn (insn (flags, operands[0], operands[1]));
17785 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17786 flags, const0_rtx, operands[2]));
17790 (define_insn "stack_protect_test_<mode>"
17791 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17792 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17793 (match_operand:PTR 2 "memory_operand" "m")]
17795 (clobber (match_scratch:PTR 3 "=&r"))]
17797 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17798 [(set_attr "type" "multi")])
17800 (define_insn "stack_tls_protect_test_<mode>"
17801 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17802 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17803 (match_operand:PTR 2 "const_int_operand" "i")]
17804 UNSPEC_SP_TLS_TEST))
17805 (clobber (match_scratch:PTR 3 "=r"))]
17807 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17808 [(set_attr "type" "multi")])
17810 (define_insn "sse4_2_crc32<mode>"
17811 [(set (match_operand:SI 0 "register_operand" "=r")
17813 [(match_operand:SI 1 "register_operand" "0")
17814 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17816 "TARGET_SSE4_2 || TARGET_CRC32"
17817 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17818 [(set_attr "type" "sselog1")
17819 (set_attr "prefix_rep" "1")
17820 (set_attr "prefix_extra" "1")
17821 (set (attr "prefix_data16")
17822 (if_then_else (match_operand:HI 2 "" "")
17824 (const_string "*")))
17825 (set (attr "prefix_rex")
17826 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17828 (const_string "*")))
17829 (set_attr "mode" "SI")])
17831 (define_insn "sse4_2_crc32di"
17832 [(set (match_operand:DI 0 "register_operand" "=r")
17834 [(match_operand:DI 1 "register_operand" "0")
17835 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17837 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17838 "crc32{q}\t{%2, %0|%0, %2}"
17839 [(set_attr "type" "sselog1")
17840 (set_attr "prefix_rep" "1")
17841 (set_attr "prefix_extra" "1")
17842 (set_attr "mode" "DI")])
17844 (define_expand "rdpmc"
17845 [(match_operand:DI 0 "register_operand" "")
17846 (match_operand:SI 1 "register_operand" "")]
17849 rtx reg = gen_reg_rtx (DImode);
17852 /* Force operand 1 into ECX. */
17853 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17854 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17855 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17860 rtvec vec = rtvec_alloc (2);
17861 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17862 rtx upper = gen_reg_rtx (DImode);
17863 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17864 gen_rtvec (1, const0_rtx),
17866 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17867 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17869 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17870 NULL, 1, OPTAB_DIRECT);
17871 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17875 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17876 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17880 (define_insn "*rdpmc"
17881 [(set (match_operand:DI 0 "register_operand" "=A")
17882 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17886 [(set_attr "type" "other")
17887 (set_attr "length" "2")])
17889 (define_insn "*rdpmc_rex64"
17890 [(set (match_operand:DI 0 "register_operand" "=a")
17891 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17893 (set (match_operand:DI 1 "register_operand" "=d")
17894 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17897 [(set_attr "type" "other")
17898 (set_attr "length" "2")])
17900 (define_expand "rdtsc"
17901 [(set (match_operand:DI 0 "register_operand" "")
17902 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17907 rtvec vec = rtvec_alloc (2);
17908 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17909 rtx upper = gen_reg_rtx (DImode);
17910 rtx lower = gen_reg_rtx (DImode);
17911 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17912 gen_rtvec (1, const0_rtx),
17914 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17915 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17917 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17918 NULL, 1, OPTAB_DIRECT);
17919 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17921 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17926 (define_insn "*rdtsc"
17927 [(set (match_operand:DI 0 "register_operand" "=A")
17928 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17931 [(set_attr "type" "other")
17932 (set_attr "length" "2")])
17934 (define_insn "*rdtsc_rex64"
17935 [(set (match_operand:DI 0 "register_operand" "=a")
17936 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17937 (set (match_operand:DI 1 "register_operand" "=d")
17938 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17941 [(set_attr "type" "other")
17942 (set_attr "length" "2")])
17944 (define_expand "rdtscp"
17945 [(match_operand:DI 0 "register_operand" "")
17946 (match_operand:SI 1 "memory_operand" "")]
17949 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17950 gen_rtvec (1, const0_rtx),
17952 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17953 gen_rtvec (1, const0_rtx),
17955 rtx reg = gen_reg_rtx (DImode);
17956 rtx tmp = gen_reg_rtx (SImode);
17960 rtvec vec = rtvec_alloc (3);
17961 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17962 rtx upper = gen_reg_rtx (DImode);
17963 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17964 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17965 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17967 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17968 NULL, 1, OPTAB_DIRECT);
17969 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17974 rtvec vec = rtvec_alloc (2);
17975 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17976 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17977 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17980 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17981 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17985 (define_insn "*rdtscp"
17986 [(set (match_operand:DI 0 "register_operand" "=A")
17987 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17988 (set (match_operand:SI 1 "register_operand" "=c")
17989 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17992 [(set_attr "type" "other")
17993 (set_attr "length" "3")])
17995 (define_insn "*rdtscp_rex64"
17996 [(set (match_operand:DI 0 "register_operand" "=a")
17997 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17998 (set (match_operand:DI 1 "register_operand" "=d")
17999 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18000 (set (match_operand:SI 2 "register_operand" "=c")
18001 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18004 [(set_attr "type" "other")
18005 (set_attr "length" "3")])
18007 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18009 ;; LWP instructions
18011 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18013 (define_expand "lwp_llwpcb"
18014 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18015 UNSPECV_LLWP_INTRINSIC)]
18018 (define_insn "*lwp_llwpcb<mode>1"
18019 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18020 UNSPECV_LLWP_INTRINSIC)]
18023 [(set_attr "type" "lwp")
18024 (set_attr "mode" "<MODE>")
18025 (set_attr "length" "5")])
18027 (define_expand "lwp_slwpcb"
18028 [(set (match_operand 0 "register_operand" "=r")
18029 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18034 insn = (TARGET_64BIT
18036 : gen_lwp_slwpcbsi);
18038 emit_insn (insn (operands[0]));
18042 (define_insn "lwp_slwpcb<mode>"
18043 [(set (match_operand:P 0 "register_operand" "=r")
18044 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18047 [(set_attr "type" "lwp")
18048 (set_attr "mode" "<MODE>")
18049 (set_attr "length" "5")])
18051 (define_expand "lwp_lwpval<mode>3"
18052 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18053 (match_operand:SI 2 "nonimmediate_operand" "rm")
18054 (match_operand:SI 3 "const_int_operand" "i")]
18055 UNSPECV_LWPVAL_INTRINSIC)]
18057 ;; Avoid unused variable warning.
18058 "(void) operands[0];")
18060 (define_insn "*lwp_lwpval<mode>3_1"
18061 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18062 (match_operand:SI 1 "nonimmediate_operand" "rm")
18063 (match_operand:SI 2 "const_int_operand" "i")]
18064 UNSPECV_LWPVAL_INTRINSIC)]
18066 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18067 [(set_attr "type" "lwp")
18068 (set_attr "mode" "<MODE>")
18069 (set (attr "length")
18070 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18072 (define_expand "lwp_lwpins<mode>3"
18073 [(set (reg:CCC FLAGS_REG)
18074 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18075 (match_operand:SI 2 "nonimmediate_operand" "rm")
18076 (match_operand:SI 3 "const_int_operand" "i")]
18077 UNSPECV_LWPINS_INTRINSIC))
18078 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18079 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18082 (define_insn "*lwp_lwpins<mode>3_1"
18083 [(set (reg:CCC FLAGS_REG)
18084 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18085 (match_operand:SI 1 "nonimmediate_operand" "rm")
18086 (match_operand:SI 2 "const_int_operand" "i")]
18087 UNSPECV_LWPINS_INTRINSIC))]
18089 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18090 [(set_attr "type" "lwp")
18091 (set_attr "mode" "<MODE>")
18092 (set (attr "length")
18093 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18095 (define_insn "rdfsbase<mode>"
18096 [(set (match_operand:SWI48 0 "register_operand" "=r")
18097 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18098 "TARGET_64BIT && TARGET_FSGSBASE"
18100 [(set_attr "type" "other")
18101 (set_attr "prefix_extra" "2")])
18103 (define_insn "rdgsbase<mode>"
18104 [(set (match_operand:SWI48 0 "register_operand" "=r")
18105 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18106 "TARGET_64BIT && TARGET_FSGSBASE"
18108 [(set_attr "type" "other")
18109 (set_attr "prefix_extra" "2")])
18111 (define_insn "wrfsbase<mode>"
18112 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18114 "TARGET_64BIT && TARGET_FSGSBASE"
18116 [(set_attr "type" "other")
18117 (set_attr "prefix_extra" "2")])
18119 (define_insn "wrgsbase<mode>"
18120 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18122 "TARGET_64BIT && TARGET_FSGSBASE"
18124 [(set_attr "type" "other")
18125 (set_attr "prefix_extra" "2")])
18127 (define_insn "rdrand<mode>_1"
18128 [(set (match_operand:SWI248 0 "register_operand" "=r")
18129 (unspec:SWI248 [(const_int 0)] UNSPEC_RDRAND))
18130 (set (reg:CCC FLAGS_REG)
18131 (unspec:CCC [(const_int 0)] UNSPEC_RDRAND))]
18134 [(set_attr "type" "other")
18135 (set_attr "prefix_extra" "1")])
18137 (define_expand "pause"
18138 [(set (match_dup 0)
18139 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18142 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18143 MEM_VOLATILE_P (operands[0]) = 1;
18146 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18147 ;; They have the same encoding.
18148 (define_insn "*pause"
18149 [(set (match_operand:BLK 0 "" "")
18150 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18153 [(set_attr "length" "2")
18154 (set_attr "memory" "unknown")])
18158 (include "sync.md")