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 a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
86 UNSPEC_MEMORY_BLOCKAGE
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_DIV_ALREADY_SPLIT
108 UNSPEC_MS_TO_SYSV_CALL
109 UNSPEC_CALL_NEEDS_VZEROUPPER
114 ;; For SSE/MMX support:
122 ;; Generic math support
124 UNSPEC_IEEE_MIN ; not commutative
125 UNSPEC_IEEE_MAX ; not commutative
127 ;; x87 Floating point
143 UNSPEC_FRNDINT_MASK_PM
147 ;; x87 Double output FP
182 (define_c_enum "unspecv" [
185 UNSPECV_PROBE_STACK_RANGE
188 UNSPECV_SPLIT_STACK_RETURN
194 UNSPECV_LLWP_INTRINSIC
195 UNSPECV_SLWP_INTRINSIC
196 UNSPECV_LWPVAL_INTRINSIC
197 UNSPECV_LWPINS_INTRINSIC
203 ;; For RDRAND support
210 ;; Constants to represent rounding modes in the ROUND instruction
219 ;; Constants to represent pcomtrue/pcomfalse variants
229 ;; Constants used in the XOP pperm instruction
231 [(PPERM_SRC 0x00) /* copy source */
232 (PPERM_INVERT 0x20) /* invert source */
233 (PPERM_REVERSE 0x40) /* bit reverse source */
234 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
235 (PPERM_ZERO 0x80) /* all 0's */
236 (PPERM_ONES 0xa0) /* all 1's */
237 (PPERM_SIGN 0xc0) /* propagate sign bit */
238 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
239 (PPERM_SRC1 0x00) /* use first source byte */
240 (PPERM_SRC2 0x10) /* use second source byte */
243 ;; Registers by name.
296 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
299 ;; In C guard expressions, put expressions which may be compile-time
300 ;; constants first. This allows for better optimization. For
301 ;; example, write "TARGET_64BIT && reload_completed", not
302 ;; "reload_completed && TARGET_64BIT".
306 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
307 atom,generic64,amdfam10,bdver1,bdver2,btver1"
308 (const (symbol_ref "ix86_schedule")))
310 ;; A basic instruction type. Refinements due to arguments to be
311 ;; provided in other attributes.
314 alu,alu1,negnot,imov,imovx,lea,
315 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
316 icmp,test,ibr,setcc,icmov,
317 push,pop,call,callv,leave,
319 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
320 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
321 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
322 ssemuladd,sse4arg,lwp,
323 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
324 (const_string "other"))
326 ;; Main data type used by the insn
328 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
329 (const_string "unknown"))
331 ;; The CPU unit operations uses.
332 (define_attr "unit" "integer,i387,sse,mmx,unknown"
333 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
334 (const_string "i387")
335 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
336 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
337 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
339 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
341 (eq_attr "type" "other")
342 (const_string "unknown")]
343 (const_string "integer")))
345 ;; The (bounding maximum) length of an instruction immediate.
346 (define_attr "length_immediate" ""
347 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
350 (eq_attr "unit" "i387,sse,mmx")
352 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
353 rotate,rotatex,rotate1,imul,icmp,push,pop")
354 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
355 (eq_attr "type" "imov,test")
356 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
357 (eq_attr "type" "call")
358 (if_then_else (match_operand 0 "constant_call_address_operand" "")
361 (eq_attr "type" "callv")
362 (if_then_else (match_operand 1 "constant_call_address_operand" "")
365 ;; We don't know the size before shorten_branches. Expect
366 ;; the instruction to fit for better scheduling.
367 (eq_attr "type" "ibr")
370 (symbol_ref "/* Update immediate_length and other attributes! */
371 gcc_unreachable (),1")))
373 ;; The (bounding maximum) length of an instruction address.
374 (define_attr "length_address" ""
375 (cond [(eq_attr "type" "str,other,multi,fxch")
377 (and (eq_attr "type" "call")
378 (match_operand 0 "constant_call_address_operand" ""))
380 (and (eq_attr "type" "callv")
381 (match_operand 1 "constant_call_address_operand" ""))
384 (symbol_ref "ix86_attr_length_address_default (insn)")))
386 ;; Set when length prefix is used.
387 (define_attr "prefix_data16" ""
388 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
390 (eq_attr "mode" "HI")
392 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
397 ;; Set when string REP prefix is used.
398 (define_attr "prefix_rep" ""
399 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
401 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
406 ;; Set when 0f opcode prefix is used.
407 (define_attr "prefix_0f" ""
409 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
410 (eq_attr "unit" "sse,mmx"))
414 ;; Set when REX opcode prefix is used.
415 (define_attr "prefix_rex" ""
416 (cond [(not (match_test "TARGET_64BIT"))
418 (and (eq_attr "mode" "DI")
419 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
420 (eq_attr "unit" "!mmx")))
422 (and (eq_attr "mode" "QI")
423 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
425 (match_test "x86_extended_reg_mentioned_p (insn)")
427 (and (eq_attr "type" "imovx")
428 (match_operand:QI 1 "ext_QIreg_operand" ""))
433 ;; There are also additional prefixes in 3DNOW, SSSE3.
434 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
435 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
436 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
437 (define_attr "prefix_extra" ""
438 (cond [(eq_attr "type" "ssemuladd,sse4arg")
440 (eq_attr "type" "sseiadd1,ssecvt1")
445 ;; Prefix used: original, VEX or maybe VEX.
446 (define_attr "prefix" "orig,vex,maybe_vex"
447 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
449 (const_string "orig")))
451 ;; VEX W bit is used.
452 (define_attr "prefix_vex_w" "" (const_int 0))
454 ;; The length of VEX prefix
455 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
456 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
457 ;; still prefix_0f 1, with prefix_extra 1.
458 (define_attr "length_vex" ""
459 (if_then_else (and (eq_attr "prefix_0f" "1")
460 (eq_attr "prefix_extra" "0"))
461 (if_then_else (eq_attr "prefix_vex_w" "1")
462 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
463 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
464 (if_then_else (eq_attr "prefix_vex_w" "1")
465 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
466 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
468 ;; Set when modrm byte is used.
469 (define_attr "modrm" ""
470 (cond [(eq_attr "type" "str,leave")
472 (eq_attr "unit" "i387")
474 (and (eq_attr "type" "incdec")
475 (and (not (match_test "TARGET_64BIT"))
476 (ior (match_operand:SI 1 "register_operand" "")
477 (match_operand:HI 1 "register_operand" ""))))
479 (and (eq_attr "type" "push")
480 (not (match_operand 1 "memory_operand" "")))
482 (and (eq_attr "type" "pop")
483 (not (match_operand 0 "memory_operand" "")))
485 (and (eq_attr "type" "imov")
486 (and (not (eq_attr "mode" "DI"))
487 (ior (and (match_operand 0 "register_operand" "")
488 (match_operand 1 "immediate_operand" ""))
489 (ior (and (match_operand 0 "ax_reg_operand" "")
490 (match_operand 1 "memory_displacement_only_operand" ""))
491 (and (match_operand 0 "memory_displacement_only_operand" "")
492 (match_operand 1 "ax_reg_operand" ""))))))
494 (and (eq_attr "type" "call")
495 (match_operand 0 "constant_call_address_operand" ""))
497 (and (eq_attr "type" "callv")
498 (match_operand 1 "constant_call_address_operand" ""))
500 (and (eq_attr "type" "alu,alu1,icmp,test")
501 (match_operand 0 "ax_reg_operand" ""))
502 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
506 ;; The (bounding maximum) length of an instruction in bytes.
507 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
508 ;; Later we may want to split them and compute proper length as for
510 (define_attr "length" ""
511 (cond [(eq_attr "type" "other,multi,fistp,frndint")
513 (eq_attr "type" "fcmp")
515 (eq_attr "unit" "i387")
517 (plus (attr "prefix_data16")
518 (attr "length_address")))
519 (ior (eq_attr "prefix" "vex")
520 (and (eq_attr "prefix" "maybe_vex")
521 (match_test "TARGET_AVX")))
522 (plus (attr "length_vex")
523 (plus (attr "length_immediate")
525 (attr "length_address"))))]
526 (plus (plus (attr "modrm")
527 (plus (attr "prefix_0f")
528 (plus (attr "prefix_rex")
529 (plus (attr "prefix_extra")
531 (plus (attr "prefix_rep")
532 (plus (attr "prefix_data16")
533 (plus (attr "length_immediate")
534 (attr "length_address")))))))
536 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
537 ;; `store' if there is a simple memory reference therein, or `unknown'
538 ;; if the instruction is complex.
540 (define_attr "memory" "none,load,store,both,unknown"
541 (cond [(eq_attr "type" "other,multi,str,lwp")
542 (const_string "unknown")
543 (eq_attr "type" "lea,fcmov,fpspc")
544 (const_string "none")
545 (eq_attr "type" "fistp,leave")
546 (const_string "both")
547 (eq_attr "type" "frndint")
548 (const_string "load")
549 (eq_attr "type" "push")
550 (if_then_else (match_operand 1 "memory_operand" "")
551 (const_string "both")
552 (const_string "store"))
553 (eq_attr "type" "pop")
554 (if_then_else (match_operand 0 "memory_operand" "")
555 (const_string "both")
556 (const_string "load"))
557 (eq_attr "type" "setcc")
558 (if_then_else (match_operand 0 "memory_operand" "")
559 (const_string "store")
560 (const_string "none"))
561 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
562 (if_then_else (ior (match_operand 0 "memory_operand" "")
563 (match_operand 1 "memory_operand" ""))
564 (const_string "load")
565 (const_string "none"))
566 (eq_attr "type" "ibr")
567 (if_then_else (match_operand 0 "memory_operand" "")
568 (const_string "load")
569 (const_string "none"))
570 (eq_attr "type" "call")
571 (if_then_else (match_operand 0 "constant_call_address_operand" "")
572 (const_string "none")
573 (const_string "load"))
574 (eq_attr "type" "callv")
575 (if_then_else (match_operand 1 "constant_call_address_operand" "")
576 (const_string "none")
577 (const_string "load"))
578 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
579 (match_operand 1 "memory_operand" ""))
580 (const_string "both")
581 (and (match_operand 0 "memory_operand" "")
582 (match_operand 1 "memory_operand" ""))
583 (const_string "both")
584 (match_operand 0 "memory_operand" "")
585 (const_string "store")
586 (match_operand 1 "memory_operand" "")
587 (const_string "load")
589 "!alu1,negnot,ishift1,
590 imov,imovx,icmp,test,bitmanip,
592 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
593 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
594 (match_operand 2 "memory_operand" ""))
595 (const_string "load")
596 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
597 (match_operand 3 "memory_operand" ""))
598 (const_string "load")
600 (const_string "none")))
602 ;; Indicates if an instruction has both an immediate and a displacement.
604 (define_attr "imm_disp" "false,true,unknown"
605 (cond [(eq_attr "type" "other,multi")
606 (const_string "unknown")
607 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
608 (and (match_operand 0 "memory_displacement_operand" "")
609 (match_operand 1 "immediate_operand" "")))
610 (const_string "true")
611 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
612 (and (match_operand 0 "memory_displacement_operand" "")
613 (match_operand 2 "immediate_operand" "")))
614 (const_string "true")
616 (const_string "false")))
618 ;; Indicates if an FP operation has an integer source.
620 (define_attr "fp_int_src" "false,true"
621 (const_string "false"))
623 ;; Defines rounding mode of an FP operation.
625 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
626 (const_string "any"))
628 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
629 (define_attr "use_carry" "0,1" (const_string "0"))
631 ;; Define attribute to indicate unaligned ssemov insns
632 (define_attr "movu" "0,1" (const_string "0"))
634 ;; Used to control the "enabled" attribute on a per-instruction basis.
635 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
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")
650 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
651 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
655 ;; Describe a user's asm statement.
656 (define_asm_attributes
657 [(set_attr "length" "128")
658 (set_attr "type" "multi")])
660 (define_code_iterator plusminus [plus minus])
662 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
664 ;; Base name for define_insn
665 (define_code_attr plusminus_insn
666 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
667 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
669 ;; Base name for insn mnemonic.
670 (define_code_attr plusminus_mnemonic
671 [(plus "add") (ss_plus "adds") (us_plus "addus")
672 (minus "sub") (ss_minus "subs") (us_minus "subus")])
673 (define_code_attr plusminus_carry_mnemonic
674 [(plus "adc") (minus "sbb")])
676 ;; Mark commutative operators as such in constraints.
677 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
678 (minus "") (ss_minus "") (us_minus "")])
680 ;; Mapping of max and min
681 (define_code_iterator maxmin [smax smin umax umin])
683 ;; Mapping of signed max and min
684 (define_code_iterator smaxmin [smax smin])
686 ;; Mapping of unsigned max and min
687 (define_code_iterator umaxmin [umax umin])
689 ;; Base name for integer and FP insn mnemonic
690 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
691 (umax "maxu") (umin "minu")])
692 (define_code_attr maxmin_float [(smax "max") (smin "min")])
694 ;; Mapping of logic operators
695 (define_code_iterator any_logic [and ior xor])
696 (define_code_iterator any_or [ior xor])
698 ;; Base name for insn mnemonic.
699 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
701 ;; Mapping of logic-shift operators
702 (define_code_iterator any_lshift [ashift lshiftrt])
704 ;; Mapping of shift-right operators
705 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
707 ;; Base name for define_insn
708 (define_code_attr shift_insn
709 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
711 ;; Base name for insn mnemonic.
712 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
713 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
715 ;; Mapping of rotate operators
716 (define_code_iterator any_rotate [rotate rotatert])
718 ;; Base name for define_insn
719 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
721 ;; Base name for insn mnemonic.
722 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
724 ;; Mapping of abs neg operators
725 (define_code_iterator absneg [abs neg])
727 ;; Base name for x87 insn mnemonic.
728 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
730 ;; Used in signed and unsigned widening multiplications.
731 (define_code_iterator any_extend [sign_extend zero_extend])
733 ;; Prefix for insn menmonic.
734 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
736 ;; Prefix for define_insn
737 (define_code_attr u [(sign_extend "") (zero_extend "u")])
738 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
740 ;; All integer modes.
741 (define_mode_iterator SWI1248x [QI HI SI DI])
743 ;; All integer modes without QImode.
744 (define_mode_iterator SWI248x [HI SI DI])
746 ;; All integer modes without QImode and HImode.
747 (define_mode_iterator SWI48x [SI DI])
749 ;; All integer modes without SImode and DImode.
750 (define_mode_iterator SWI12 [QI HI])
752 ;; All integer modes without DImode.
753 (define_mode_iterator SWI124 [QI HI SI])
755 ;; All integer modes without QImode and DImode.
756 (define_mode_iterator SWI24 [HI SI])
758 ;; Single word integer modes.
759 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
761 ;; Single word integer modes without QImode.
762 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
764 ;; Single word integer modes without QImode and HImode.
765 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
767 ;; All math-dependant single and double word integer modes.
768 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
769 (HI "TARGET_HIMODE_MATH")
770 SI DI (TI "TARGET_64BIT")])
772 ;; Math-dependant single word integer modes.
773 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
774 (HI "TARGET_HIMODE_MATH")
775 SI (DI "TARGET_64BIT")])
777 ;; Math-dependant integer modes without DImode.
778 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
779 (HI "TARGET_HIMODE_MATH")
782 ;; Math-dependant single word integer modes without QImode.
783 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
784 SI (DI "TARGET_64BIT")])
786 ;; Double word integer modes.
787 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
788 (TI "TARGET_64BIT")])
790 ;; Double word integer modes as mode attribute.
791 (define_mode_attr DWI [(SI "DI") (DI "TI")])
792 (define_mode_attr dwi [(SI "di") (DI "ti")])
794 ;; Half mode for double word integer modes.
795 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
796 (DI "TARGET_64BIT")])
798 ;; Instruction suffix for integer modes.
799 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
801 ;; Pointer size prefix for integer modes (Intel asm dialect)
802 (define_mode_attr iptrsize [(QI "BYTE")
807 ;; Register class for integer modes.
808 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
810 ;; Immediate operand constraint for integer modes.
811 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
813 ;; General operand constraint for word modes.
814 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
816 ;; Immediate operand constraint for double integer modes.
817 (define_mode_attr di [(SI "nF") (DI "e")])
819 ;; Immediate operand constraint for shifts.
820 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
822 ;; General operand predicate for integer modes.
823 (define_mode_attr general_operand
824 [(QI "general_operand")
825 (HI "general_operand")
826 (SI "x86_64_general_operand")
827 (DI "x86_64_general_operand")
828 (TI "x86_64_general_operand")])
830 ;; General sign/zero extend operand predicate for integer modes.
831 (define_mode_attr general_szext_operand
832 [(QI "general_operand")
833 (HI "general_operand")
834 (SI "x86_64_szext_general_operand")
835 (DI "x86_64_szext_general_operand")])
837 ;; Immediate operand predicate for integer modes.
838 (define_mode_attr immediate_operand
839 [(QI "immediate_operand")
840 (HI "immediate_operand")
841 (SI "x86_64_immediate_operand")
842 (DI "x86_64_immediate_operand")])
844 ;; Nonmemory operand predicate for integer modes.
845 (define_mode_attr nonmemory_operand
846 [(QI "nonmemory_operand")
847 (HI "nonmemory_operand")
848 (SI "x86_64_nonmemory_operand")
849 (DI "x86_64_nonmemory_operand")])
851 ;; Operand predicate for shifts.
852 (define_mode_attr shift_operand
853 [(QI "nonimmediate_operand")
854 (HI "nonimmediate_operand")
855 (SI "nonimmediate_operand")
856 (DI "shiftdi_operand")
857 (TI "register_operand")])
859 ;; Operand predicate for shift argument.
860 (define_mode_attr shift_immediate_operand
861 [(QI "const_1_to_31_operand")
862 (HI "const_1_to_31_operand")
863 (SI "const_1_to_31_operand")
864 (DI "const_1_to_63_operand")])
866 ;; Input operand predicate for arithmetic left shifts.
867 (define_mode_attr ashl_input_operand
868 [(QI "nonimmediate_operand")
869 (HI "nonimmediate_operand")
870 (SI "nonimmediate_operand")
871 (DI "ashldi_input_operand")
872 (TI "reg_or_pm1_operand")])
874 ;; SSE and x87 SFmode and DFmode floating point modes
875 (define_mode_iterator MODEF [SF DF])
877 ;; All x87 floating point modes
878 (define_mode_iterator X87MODEF [SF DF XF])
880 ;; SSE instruction suffix for various modes
881 (define_mode_attr ssemodesuffix
883 (V8SF "ps") (V4DF "pd")
884 (V4SF "ps") (V2DF "pd")
885 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
886 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
888 ;; SSE vector suffix for floating point modes
889 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
891 ;; SSE vector mode corresponding to a scalar mode
892 (define_mode_attr ssevecmode
893 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
895 ;; Instruction suffix for REX 64bit operators.
896 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
898 ;; This mode iterator allows :P to be used for patterns that operate on
899 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
900 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
902 ;; This mode iterator allows :PTR to be used for patterns that operate on
903 ;; ptr_mode sized quantities.
904 (define_mode_iterator PTR
905 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
907 ;; Scheduling descriptions
909 (include "pentium.md")
912 (include "athlon.md")
913 (include "bdver1.md")
919 ;; Operand and operator predicates and constraints
921 (include "predicates.md")
922 (include "constraints.md")
925 ;; Compare and branch/compare and store instructions.
927 (define_expand "cbranch<mode>4"
928 [(set (reg:CC FLAGS_REG)
929 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
930 (match_operand:SDWIM 2 "<general_operand>" "")))
931 (set (pc) (if_then_else
932 (match_operator 0 "ordered_comparison_operator"
933 [(reg:CC FLAGS_REG) (const_int 0)])
934 (label_ref (match_operand 3 "" ""))
938 if (MEM_P (operands[1]) && MEM_P (operands[2]))
939 operands[1] = force_reg (<MODE>mode, operands[1]);
940 ix86_expand_branch (GET_CODE (operands[0]),
941 operands[1], operands[2], operands[3]);
945 (define_expand "cstore<mode>4"
946 [(set (reg:CC FLAGS_REG)
947 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
948 (match_operand:SWIM 3 "<general_operand>" "")))
949 (set (match_operand:QI 0 "register_operand" "")
950 (match_operator 1 "ordered_comparison_operator"
951 [(reg:CC FLAGS_REG) (const_int 0)]))]
954 if (MEM_P (operands[2]) && MEM_P (operands[3]))
955 operands[2] = force_reg (<MODE>mode, operands[2]);
956 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
957 operands[2], operands[3]);
961 (define_expand "cmp<mode>_1"
962 [(set (reg:CC FLAGS_REG)
963 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
964 (match_operand:SWI48 1 "<general_operand>" "")))])
966 (define_insn "*cmp<mode>_ccno_1"
967 [(set (reg FLAGS_REG)
968 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
969 (match_operand:SWI 1 "const0_operand" "")))]
970 "ix86_match_ccmode (insn, CCNOmode)"
972 test{<imodesuffix>}\t%0, %0
973 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
974 [(set_attr "type" "test,icmp")
975 (set_attr "length_immediate" "0,1")
976 (set_attr "mode" "<MODE>")])
978 (define_insn "*cmp<mode>_1"
979 [(set (reg FLAGS_REG)
980 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
981 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
982 "ix86_match_ccmode (insn, CCmode)"
983 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
984 [(set_attr "type" "icmp")
985 (set_attr "mode" "<MODE>")])
987 (define_insn "*cmp<mode>_minus_1"
988 [(set (reg FLAGS_REG)
990 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
991 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
993 "ix86_match_ccmode (insn, CCGOCmode)"
994 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
995 [(set_attr "type" "icmp")
996 (set_attr "mode" "<MODE>")])
998 (define_insn "*cmpqi_ext_1"
999 [(set (reg FLAGS_REG)
1001 (match_operand:QI 0 "general_operand" "Qm")
1004 (match_operand 1 "ext_register_operand" "Q")
1006 (const_int 8)) 0)))]
1007 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1008 "cmp{b}\t{%h1, %0|%0, %h1}"
1009 [(set_attr "type" "icmp")
1010 (set_attr "mode" "QI")])
1012 (define_insn "*cmpqi_ext_1_rex64"
1013 [(set (reg FLAGS_REG)
1015 (match_operand:QI 0 "register_operand" "Q")
1018 (match_operand 1 "ext_register_operand" "Q")
1020 (const_int 8)) 0)))]
1021 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1022 "cmp{b}\t{%h1, %0|%0, %h1}"
1023 [(set_attr "type" "icmp")
1024 (set_attr "mode" "QI")])
1026 (define_insn "*cmpqi_ext_2"
1027 [(set (reg FLAGS_REG)
1031 (match_operand 0 "ext_register_operand" "Q")
1034 (match_operand:QI 1 "const0_operand" "")))]
1035 "ix86_match_ccmode (insn, CCNOmode)"
1037 [(set_attr "type" "test")
1038 (set_attr "length_immediate" "0")
1039 (set_attr "mode" "QI")])
1041 (define_expand "cmpqi_ext_3"
1042 [(set (reg:CC FLAGS_REG)
1046 (match_operand 0 "ext_register_operand" "")
1049 (match_operand:QI 1 "immediate_operand" "")))])
1051 (define_insn "*cmpqi_ext_3_insn"
1052 [(set (reg FLAGS_REG)
1056 (match_operand 0 "ext_register_operand" "Q")
1059 (match_operand:QI 1 "general_operand" "Qmn")))]
1060 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1061 "cmp{b}\t{%1, %h0|%h0, %1}"
1062 [(set_attr "type" "icmp")
1063 (set_attr "modrm" "1")
1064 (set_attr "mode" "QI")])
1066 (define_insn "*cmpqi_ext_3_insn_rex64"
1067 [(set (reg FLAGS_REG)
1071 (match_operand 0 "ext_register_operand" "Q")
1074 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1075 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1076 "cmp{b}\t{%1, %h0|%h0, %1}"
1077 [(set_attr "type" "icmp")
1078 (set_attr "modrm" "1")
1079 (set_attr "mode" "QI")])
1081 (define_insn "*cmpqi_ext_4"
1082 [(set (reg FLAGS_REG)
1086 (match_operand 0 "ext_register_operand" "Q")
1091 (match_operand 1 "ext_register_operand" "Q")
1093 (const_int 8)) 0)))]
1094 "ix86_match_ccmode (insn, CCmode)"
1095 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1096 [(set_attr "type" "icmp")
1097 (set_attr "mode" "QI")])
1099 ;; These implement float point compares.
1100 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1101 ;; which would allow mix and match FP modes on the compares. Which is what
1102 ;; the old patterns did, but with many more of them.
1104 (define_expand "cbranchxf4"
1105 [(set (reg:CC FLAGS_REG)
1106 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1107 (match_operand:XF 2 "nonmemory_operand" "")))
1108 (set (pc) (if_then_else
1109 (match_operator 0 "ix86_fp_comparison_operator"
1112 (label_ref (match_operand 3 "" ""))
1116 ix86_expand_branch (GET_CODE (operands[0]),
1117 operands[1], operands[2], operands[3]);
1121 (define_expand "cstorexf4"
1122 [(set (reg:CC FLAGS_REG)
1123 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1124 (match_operand:XF 3 "nonmemory_operand" "")))
1125 (set (match_operand:QI 0 "register_operand" "")
1126 (match_operator 1 "ix86_fp_comparison_operator"
1131 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1132 operands[2], operands[3]);
1136 (define_expand "cbranch<mode>4"
1137 [(set (reg:CC FLAGS_REG)
1138 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1139 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1140 (set (pc) (if_then_else
1141 (match_operator 0 "ix86_fp_comparison_operator"
1144 (label_ref (match_operand 3 "" ""))
1146 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1148 ix86_expand_branch (GET_CODE (operands[0]),
1149 operands[1], operands[2], operands[3]);
1153 (define_expand "cstore<mode>4"
1154 [(set (reg:CC FLAGS_REG)
1155 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1156 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1157 (set (match_operand:QI 0 "register_operand" "")
1158 (match_operator 1 "ix86_fp_comparison_operator"
1161 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1163 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1164 operands[2], operands[3]);
1168 (define_expand "cbranchcc4"
1169 [(set (pc) (if_then_else
1170 (match_operator 0 "comparison_operator"
1171 [(match_operand 1 "flags_reg_operand" "")
1172 (match_operand 2 "const0_operand" "")])
1173 (label_ref (match_operand 3 "" ""))
1177 ix86_expand_branch (GET_CODE (operands[0]),
1178 operands[1], operands[2], operands[3]);
1182 (define_expand "cstorecc4"
1183 [(set (match_operand:QI 0 "register_operand" "")
1184 (match_operator 1 "comparison_operator"
1185 [(match_operand 2 "flags_reg_operand" "")
1186 (match_operand 3 "const0_operand" "")]))]
1189 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1190 operands[2], operands[3]);
1195 ;; FP compares, step 1:
1196 ;; Set the FP condition codes.
1198 ;; CCFPmode compare with exceptions
1199 ;; CCFPUmode compare with no exceptions
1201 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1202 ;; used to manage the reg stack popping would not be preserved.
1204 (define_insn "*cmpfp_0"
1205 [(set (match_operand:HI 0 "register_operand" "=a")
1208 (match_operand 1 "register_operand" "f")
1209 (match_operand 2 "const0_operand" ""))]
1211 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1212 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1213 "* return output_fp_compare (insn, operands, false, false);"
1214 [(set_attr "type" "multi")
1215 (set_attr "unit" "i387")
1217 (cond [(match_operand:SF 1 "" "")
1219 (match_operand:DF 1 "" "")
1222 (const_string "XF")))])
1224 (define_insn_and_split "*cmpfp_0_cc"
1225 [(set (reg:CCFP FLAGS_REG)
1227 (match_operand 1 "register_operand" "f")
1228 (match_operand 2 "const0_operand" "")))
1229 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1230 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1231 && TARGET_SAHF && !TARGET_CMOVE
1232 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1234 "&& reload_completed"
1237 [(compare:CCFP (match_dup 1)(match_dup 2))]
1239 (set (reg:CC FLAGS_REG)
1240 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1242 [(set_attr "type" "multi")
1243 (set_attr "unit" "i387")
1245 (cond [(match_operand:SF 1 "" "")
1247 (match_operand:DF 1 "" "")
1250 (const_string "XF")))])
1252 (define_insn "*cmpfp_xf"
1253 [(set (match_operand:HI 0 "register_operand" "=a")
1256 (match_operand:XF 1 "register_operand" "f")
1257 (match_operand:XF 2 "register_operand" "f"))]
1260 "* return output_fp_compare (insn, operands, false, false);"
1261 [(set_attr "type" "multi")
1262 (set_attr "unit" "i387")
1263 (set_attr "mode" "XF")])
1265 (define_insn_and_split "*cmpfp_xf_cc"
1266 [(set (reg:CCFP FLAGS_REG)
1268 (match_operand:XF 1 "register_operand" "f")
1269 (match_operand:XF 2 "register_operand" "f")))
1270 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1272 && TARGET_SAHF && !TARGET_CMOVE"
1274 "&& reload_completed"
1277 [(compare:CCFP (match_dup 1)(match_dup 2))]
1279 (set (reg:CC FLAGS_REG)
1280 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1282 [(set_attr "type" "multi")
1283 (set_attr "unit" "i387")
1284 (set_attr "mode" "XF")])
1286 (define_insn "*cmpfp_<mode>"
1287 [(set (match_operand:HI 0 "register_operand" "=a")
1290 (match_operand:MODEF 1 "register_operand" "f")
1291 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1294 "* return output_fp_compare (insn, operands, false, false);"
1295 [(set_attr "type" "multi")
1296 (set_attr "unit" "i387")
1297 (set_attr "mode" "<MODE>")])
1299 (define_insn_and_split "*cmpfp_<mode>_cc"
1300 [(set (reg:CCFP FLAGS_REG)
1302 (match_operand:MODEF 1 "register_operand" "f")
1303 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1304 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1306 && TARGET_SAHF && !TARGET_CMOVE"
1308 "&& reload_completed"
1311 [(compare:CCFP (match_dup 1)(match_dup 2))]
1313 (set (reg:CC FLAGS_REG)
1314 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1316 [(set_attr "type" "multi")
1317 (set_attr "unit" "i387")
1318 (set_attr "mode" "<MODE>")])
1320 (define_insn "*cmpfp_u"
1321 [(set (match_operand:HI 0 "register_operand" "=a")
1324 (match_operand 1 "register_operand" "f")
1325 (match_operand 2 "register_operand" "f"))]
1327 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1328 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1329 "* return output_fp_compare (insn, operands, false, true);"
1330 [(set_attr "type" "multi")
1331 (set_attr "unit" "i387")
1333 (cond [(match_operand:SF 1 "" "")
1335 (match_operand:DF 1 "" "")
1338 (const_string "XF")))])
1340 (define_insn_and_split "*cmpfp_u_cc"
1341 [(set (reg:CCFPU FLAGS_REG)
1343 (match_operand 1 "register_operand" "f")
1344 (match_operand 2 "register_operand" "f")))
1345 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1346 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1347 && TARGET_SAHF && !TARGET_CMOVE
1348 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1350 "&& reload_completed"
1353 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1355 (set (reg:CC FLAGS_REG)
1356 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1358 [(set_attr "type" "multi")
1359 (set_attr "unit" "i387")
1361 (cond [(match_operand:SF 1 "" "")
1363 (match_operand:DF 1 "" "")
1366 (const_string "XF")))])
1368 (define_insn "*cmpfp_<mode>"
1369 [(set (match_operand:HI 0 "register_operand" "=a")
1372 (match_operand 1 "register_operand" "f")
1373 (match_operator 3 "float_operator"
1374 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1376 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1377 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1378 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1379 "* return output_fp_compare (insn, operands, false, false);"
1380 [(set_attr "type" "multi")
1381 (set_attr "unit" "i387")
1382 (set_attr "fp_int_src" "true")
1383 (set_attr "mode" "<MODE>")])
1385 (define_insn_and_split "*cmpfp_<mode>_cc"
1386 [(set (reg:CCFP FLAGS_REG)
1388 (match_operand 1 "register_operand" "f")
1389 (match_operator 3 "float_operator"
1390 [(match_operand:SWI24 2 "memory_operand" "m")])))
1391 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1392 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1393 && TARGET_SAHF && !TARGET_CMOVE
1394 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1395 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1397 "&& reload_completed"
1402 (match_op_dup 3 [(match_dup 2)]))]
1404 (set (reg:CC FLAGS_REG)
1405 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1407 [(set_attr "type" "multi")
1408 (set_attr "unit" "i387")
1409 (set_attr "fp_int_src" "true")
1410 (set_attr "mode" "<MODE>")])
1412 ;; FP compares, step 2
1413 ;; Move the fpsw to ax.
1415 (define_insn "x86_fnstsw_1"
1416 [(set (match_operand:HI 0 "register_operand" "=a")
1417 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1420 [(set (attr "length")
1421 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1422 (set_attr "mode" "SI")
1423 (set_attr "unit" "i387")])
1425 ;; FP compares, step 3
1426 ;; Get ax into flags, general case.
1428 (define_insn "x86_sahf_1"
1429 [(set (reg:CC FLAGS_REG)
1430 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1434 #ifndef HAVE_AS_IX86_SAHF
1436 return ASM_BYTE "0x9e";
1441 [(set_attr "length" "1")
1442 (set_attr "athlon_decode" "vector")
1443 (set_attr "amdfam10_decode" "direct")
1444 (set_attr "bdver1_decode" "direct")
1445 (set_attr "mode" "SI")])
1447 ;; Pentium Pro can do steps 1 through 3 in one go.
1448 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1449 ;; (these i387 instructions set flags directly)
1450 (define_insn "*cmpfp_i_mixed"
1451 [(set (reg:CCFP FLAGS_REG)
1452 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1453 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1454 "TARGET_MIX_SSE_I387
1455 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1456 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1457 "* return output_fp_compare (insn, operands, true, false);"
1458 [(set_attr "type" "fcmp,ssecomi")
1459 (set_attr "prefix" "orig,maybe_vex")
1461 (if_then_else (match_operand:SF 1 "" "")
1463 (const_string "DF")))
1464 (set (attr "prefix_rep")
1465 (if_then_else (eq_attr "type" "ssecomi")
1467 (const_string "*")))
1468 (set (attr "prefix_data16")
1469 (cond [(eq_attr "type" "fcmp")
1471 (eq_attr "mode" "DF")
1474 (const_string "0")))
1475 (set_attr "athlon_decode" "vector")
1476 (set_attr "amdfam10_decode" "direct")
1477 (set_attr "bdver1_decode" "double")])
1479 (define_insn "*cmpfp_i_sse"
1480 [(set (reg:CCFP FLAGS_REG)
1481 (compare:CCFP (match_operand 0 "register_operand" "x")
1482 (match_operand 1 "nonimmediate_operand" "xm")))]
1484 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1485 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1486 "* return output_fp_compare (insn, operands, true, false);"
1487 [(set_attr "type" "ssecomi")
1488 (set_attr "prefix" "maybe_vex")
1490 (if_then_else (match_operand:SF 1 "" "")
1492 (const_string "DF")))
1493 (set_attr "prefix_rep" "0")
1494 (set (attr "prefix_data16")
1495 (if_then_else (eq_attr "mode" "DF")
1497 (const_string "0")))
1498 (set_attr "athlon_decode" "vector")
1499 (set_attr "amdfam10_decode" "direct")
1500 (set_attr "bdver1_decode" "double")])
1502 (define_insn "*cmpfp_i_i387"
1503 [(set (reg:CCFP FLAGS_REG)
1504 (compare:CCFP (match_operand 0 "register_operand" "f")
1505 (match_operand 1 "register_operand" "f")))]
1506 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1508 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1509 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510 "* return output_fp_compare (insn, operands, true, false);"
1511 [(set_attr "type" "fcmp")
1513 (cond [(match_operand:SF 1 "" "")
1515 (match_operand:DF 1 "" "")
1518 (const_string "XF")))
1519 (set_attr "athlon_decode" "vector")
1520 (set_attr "amdfam10_decode" "direct")
1521 (set_attr "bdver1_decode" "double")])
1523 (define_insn "*cmpfp_iu_mixed"
1524 [(set (reg:CCFPU FLAGS_REG)
1525 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1526 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1527 "TARGET_MIX_SSE_I387
1528 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1529 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1530 "* return output_fp_compare (insn, operands, true, true);"
1531 [(set_attr "type" "fcmp,ssecomi")
1532 (set_attr "prefix" "orig,maybe_vex")
1534 (if_then_else (match_operand:SF 1 "" "")
1536 (const_string "DF")))
1537 (set (attr "prefix_rep")
1538 (if_then_else (eq_attr "type" "ssecomi")
1540 (const_string "*")))
1541 (set (attr "prefix_data16")
1542 (cond [(eq_attr "type" "fcmp")
1544 (eq_attr "mode" "DF")
1547 (const_string "0")))
1548 (set_attr "athlon_decode" "vector")
1549 (set_attr "amdfam10_decode" "direct")
1550 (set_attr "bdver1_decode" "double")])
1552 (define_insn "*cmpfp_iu_sse"
1553 [(set (reg:CCFPU FLAGS_REG)
1554 (compare:CCFPU (match_operand 0 "register_operand" "x")
1555 (match_operand 1 "nonimmediate_operand" "xm")))]
1557 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1558 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1559 "* return output_fp_compare (insn, operands, true, true);"
1560 [(set_attr "type" "ssecomi")
1561 (set_attr "prefix" "maybe_vex")
1563 (if_then_else (match_operand:SF 1 "" "")
1565 (const_string "DF")))
1566 (set_attr "prefix_rep" "0")
1567 (set (attr "prefix_data16")
1568 (if_then_else (eq_attr "mode" "DF")
1570 (const_string "0")))
1571 (set_attr "athlon_decode" "vector")
1572 (set_attr "amdfam10_decode" "direct")
1573 (set_attr "bdver1_decode" "double")])
1575 (define_insn "*cmpfp_iu_387"
1576 [(set (reg:CCFPU FLAGS_REG)
1577 (compare:CCFPU (match_operand 0 "register_operand" "f")
1578 (match_operand 1 "register_operand" "f")))]
1579 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1581 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1582 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1583 "* return output_fp_compare (insn, operands, true, true);"
1584 [(set_attr "type" "fcmp")
1586 (cond [(match_operand:SF 1 "" "")
1588 (match_operand:DF 1 "" "")
1591 (const_string "XF")))
1592 (set_attr "athlon_decode" "vector")
1593 (set_attr "amdfam10_decode" "direct")
1594 (set_attr "bdver1_decode" "direct")])
1596 ;; Push/pop instructions.
1598 (define_insn "*push<mode>2"
1599 [(set (match_operand:DWI 0 "push_operand" "=<")
1600 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1603 [(set_attr "type" "multi")
1604 (set_attr "mode" "<MODE>")])
1607 [(set (match_operand:TI 0 "push_operand" "")
1608 (match_operand:TI 1 "general_operand" ""))]
1609 "TARGET_64BIT && reload_completed
1610 && !SSE_REG_P (operands[1])"
1612 "ix86_split_long_move (operands); DONE;")
1614 (define_insn "*pushdi2_rex64"
1615 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1616 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1621 [(set_attr "type" "push,multi")
1622 (set_attr "mode" "DI")])
1624 ;; Convert impossible pushes of immediate to existing instructions.
1625 ;; First try to get scratch register and go through it. In case this
1626 ;; fails, push sign extended lower part first and then overwrite
1627 ;; upper part by 32bit move.
1629 [(match_scratch:DI 2 "r")
1630 (set (match_operand:DI 0 "push_operand" "")
1631 (match_operand:DI 1 "immediate_operand" ""))]
1632 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1633 && !x86_64_immediate_operand (operands[1], DImode)"
1634 [(set (match_dup 2) (match_dup 1))
1635 (set (match_dup 0) (match_dup 2))])
1637 ;; We need to define this as both peepholer and splitter for case
1638 ;; peephole2 pass is not run.
1639 ;; "&& 1" is needed to keep it from matching the previous pattern.
1641 [(set (match_operand:DI 0 "push_operand" "")
1642 (match_operand:DI 1 "immediate_operand" ""))]
1643 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1644 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1645 [(set (match_dup 0) (match_dup 1))
1646 (set (match_dup 2) (match_dup 3))]
1648 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1650 operands[1] = gen_lowpart (DImode, operands[2]);
1651 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1656 [(set (match_operand:DI 0 "push_operand" "")
1657 (match_operand:DI 1 "immediate_operand" ""))]
1658 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1659 ? epilogue_completed : reload_completed)
1660 && !symbolic_operand (operands[1], DImode)
1661 && !x86_64_immediate_operand (operands[1], DImode)"
1662 [(set (match_dup 0) (match_dup 1))
1663 (set (match_dup 2) (match_dup 3))]
1665 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1667 operands[1] = gen_lowpart (DImode, operands[2]);
1668 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (Pmode, stack_pointer_rtx,
1673 [(set (match_operand:DI 0 "push_operand" "")
1674 (match_operand:DI 1 "general_operand" ""))]
1675 "!TARGET_64BIT && reload_completed
1676 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1678 "ix86_split_long_move (operands); DONE;")
1680 (define_insn "*pushsi2"
1681 [(set (match_operand:SI 0 "push_operand" "=<")
1682 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1685 [(set_attr "type" "push")
1686 (set_attr "mode" "SI")])
1688 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1689 ;; "push a byte/word". But actually we use pushl, which has the effect
1690 ;; of rounding the amount pushed up to a word.
1692 ;; For TARGET_64BIT we always round up to 8 bytes.
1693 (define_insn "*push<mode>2_rex64"
1694 [(set (match_operand:SWI124 0 "push_operand" "=X")
1695 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1698 [(set_attr "type" "push")
1699 (set_attr "mode" "DI")])
1701 (define_insn "*push<mode>2"
1702 [(set (match_operand:SWI12 0 "push_operand" "=X")
1703 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1706 [(set_attr "type" "push")
1707 (set_attr "mode" "SI")])
1709 (define_insn "*push<mode>2_prologue"
1710 [(set (match_operand:P 0 "push_operand" "=<")
1711 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1712 (clobber (mem:BLK (scratch)))]
1714 "push{<imodesuffix>}\t%1"
1715 [(set_attr "type" "push")
1716 (set_attr "mode" "<MODE>")])
1718 (define_insn "*pop<mode>1"
1719 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1720 (match_operand:P 1 "pop_operand" ">"))]
1722 "pop{<imodesuffix>}\t%0"
1723 [(set_attr "type" "pop")
1724 (set_attr "mode" "<MODE>")])
1726 (define_insn "*pop<mode>1_epilogue"
1727 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1728 (match_operand:P 1 "pop_operand" ">"))
1729 (clobber (mem:BLK (scratch)))]
1731 "pop{<imodesuffix>}\t%0"
1732 [(set_attr "type" "pop")
1733 (set_attr "mode" "<MODE>")])
1735 ;; Move instructions.
1737 (define_expand "movoi"
1738 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1739 (match_operand:OI 1 "general_operand" ""))]
1741 "ix86_expand_move (OImode, operands); DONE;")
1743 (define_expand "movti"
1744 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1745 (match_operand:TI 1 "nonimmediate_operand" ""))]
1746 "TARGET_64BIT || TARGET_SSE"
1749 ix86_expand_move (TImode, operands);
1750 else if (push_operand (operands[0], TImode))
1751 ix86_expand_push (TImode, operands[1]);
1753 ix86_expand_vector_move (TImode, operands);
1757 ;; This expands to what emit_move_complex would generate if we didn't
1758 ;; have a movti pattern. Having this avoids problems with reload on
1759 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1760 ;; to have around all the time.
1761 (define_expand "movcdi"
1762 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1763 (match_operand:CDI 1 "general_operand" ""))]
1766 if (push_operand (operands[0], CDImode))
1767 emit_move_complex_push (CDImode, operands[0], operands[1]);
1769 emit_move_complex_parts (operands[0], operands[1]);
1773 (define_expand "mov<mode>"
1774 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1775 (match_operand:SWI1248x 1 "general_operand" ""))]
1777 "ix86_expand_move (<MODE>mode, operands); DONE;")
1779 (define_insn "*mov<mode>_xor"
1780 [(set (match_operand:SWI48 0 "register_operand" "=r")
1781 (match_operand:SWI48 1 "const0_operand" ""))
1782 (clobber (reg:CC FLAGS_REG))]
1785 [(set_attr "type" "alu1")
1786 (set_attr "mode" "SI")
1787 (set_attr "length_immediate" "0")])
1789 (define_insn "*mov<mode>_or"
1790 [(set (match_operand:SWI48 0 "register_operand" "=r")
1791 (match_operand:SWI48 1 "const_int_operand" ""))
1792 (clobber (reg:CC FLAGS_REG))]
1794 && operands[1] == constm1_rtx"
1795 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1796 [(set_attr "type" "alu1")
1797 (set_attr "mode" "<MODE>")
1798 (set_attr "length_immediate" "1")])
1800 (define_insn "*movoi_internal_avx"
1801 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1802 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1803 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1805 switch (which_alternative)
1808 return standard_sse_constant_opcode (insn, operands[1]);
1811 if (misaligned_operand (operands[0], OImode)
1812 || misaligned_operand (operands[1], OImode))
1813 return "vmovdqu\t{%1, %0|%0, %1}";
1815 return "vmovdqa\t{%1, %0|%0, %1}";
1820 [(set_attr "type" "sselog1,ssemov,ssemov")
1821 (set_attr "prefix" "vex")
1822 (set_attr "mode" "OI")])
1824 (define_insn "*movti_internal_rex64"
1825 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m")
1826 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1827 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1829 switch (which_alternative)
1835 return standard_sse_constant_opcode (insn, operands[1]);
1838 /* TDmode values are passed as TImode on the stack. Moving them
1839 to stack may result in unaligned memory access. */
1840 if (misaligned_operand (operands[0], TImode)
1841 || misaligned_operand (operands[1], TImode))
1843 if (get_attr_mode (insn) == MODE_V4SF)
1844 return "%vmovups\t{%1, %0|%0, %1}";
1846 return "%vmovdqu\t{%1, %0|%0, %1}";
1850 if (get_attr_mode (insn) == MODE_V4SF)
1851 return "%vmovaps\t{%1, %0|%0, %1}";
1853 return "%vmovdqa\t{%1, %0|%0, %1}";
1859 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1860 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1862 (cond [(eq_attr "alternative" "0,1")
1864 (ior (not (match_test "TARGET_SSE2"))
1865 (match_test "optimize_function_for_size_p (cfun)"))
1866 (const_string "V4SF")
1867 (and (eq_attr "alternative" "4")
1868 (match_test "TARGET_SSE_TYPELESS_STORES"))
1869 (const_string "V4SF")
1871 (const_string "TI")))])
1874 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1875 (match_operand:TI 1 "general_operand" ""))]
1877 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1879 "ix86_split_long_move (operands); DONE;")
1881 (define_insn "*movti_internal_sse"
1882 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1883 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1884 "TARGET_SSE && !TARGET_64BIT
1885 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1887 switch (which_alternative)
1890 return standard_sse_constant_opcode (insn, operands[1]);
1893 /* TDmode values are passed as TImode on the stack. Moving them
1894 to stack may result in unaligned memory access. */
1895 if (misaligned_operand (operands[0], TImode)
1896 || misaligned_operand (operands[1], TImode))
1898 if (get_attr_mode (insn) == MODE_V4SF)
1899 return "%vmovups\t{%1, %0|%0, %1}";
1901 return "%vmovdqu\t{%1, %0|%0, %1}";
1905 if (get_attr_mode (insn) == MODE_V4SF)
1906 return "%vmovaps\t{%1, %0|%0, %1}";
1908 return "%vmovdqa\t{%1, %0|%0, %1}";
1914 [(set_attr "type" "sselog1,ssemov,ssemov")
1915 (set_attr "prefix" "maybe_vex")
1917 (cond [(ior (not (match_test "TARGET_SSE2"))
1918 (match_test "optimize_function_for_size_p (cfun)"))
1919 (const_string "V4SF")
1920 (and (eq_attr "alternative" "2")
1921 (match_test "TARGET_SSE_TYPELESS_STORES"))
1922 (const_string "V4SF")]
1923 (const_string "TI")))])
1925 (define_insn "*movdi_internal_rex64"
1926 [(set (match_operand:DI 0 "nonimmediate_operand"
1927 "=r,r ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1928 (match_operand:DI 1 "general_operand"
1929 "Z ,rem,i,re,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1930 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1932 switch (get_attr_type (insn))
1935 if (SSE_REG_P (operands[0]))
1936 return "movq2dq\t{%1, %0|%0, %1}";
1938 return "movdq2q\t{%1, %0|%0, %1}";
1941 if (get_attr_mode (insn) == MODE_TI)
1942 return "%vmovdqa\t{%1, %0|%0, %1}";
1943 /* Handle broken assemblers that require movd instead of movq. */
1944 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1945 return "%vmovd\t{%1, %0|%0, %1}";
1947 return "%vmovq\t{%1, %0|%0, %1}";
1950 /* Handle broken assemblers that require movd instead of movq. */
1951 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1952 return "movd\t{%1, %0|%0, %1}";
1954 return "movq\t{%1, %0|%0, %1}";
1957 return standard_sse_constant_opcode (insn, operands[1]);
1960 return "pxor\t%0, %0";
1963 return "lea{q}\t{%E1, %0|%0, %E1}";
1966 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1967 if (get_attr_mode (insn) == MODE_SI)
1968 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1969 else if (which_alternative == 2)
1970 return "movabs{q}\t{%1, %0|%0, %1}";
1971 else if (ix86_use_lea_for_mov (insn, operands))
1972 return "lea{q}\t{%E1, %0|%0, %E1}";
1974 return "mov{q}\t{%1, %0|%0, %1}";
1978 (cond [(eq_attr "alternative" "4")
1979 (const_string "mmx")
1980 (eq_attr "alternative" "5,6,7,8")
1981 (const_string "mmxmov")
1982 (eq_attr "alternative" "9")
1983 (const_string "sselog1")
1984 (eq_attr "alternative" "10,11,12,13,14")
1985 (const_string "ssemov")
1986 (eq_attr "alternative" "15,16")
1987 (const_string "ssecvt")
1988 (match_operand 1 "pic_32bit_operand" "")
1989 (const_string "lea")
1991 (const_string "imov")))
1994 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1996 (const_string "*")))
1997 (set (attr "length_immediate")
1999 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2001 (const_string "*")))
2002 (set (attr "prefix_rex")
2003 (if_then_else (eq_attr "alternative" "7,8")
2005 (const_string "*")))
2006 (set (attr "prefix_data16")
2007 (if_then_else (eq_attr "alternative" "10")
2009 (const_string "*")))
2010 (set (attr "prefix")
2011 (if_then_else (eq_attr "alternative" "11,12,13,14,15")
2012 (const_string "maybe_vex")
2013 (const_string "orig")))
2014 (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2016 ;; Reload patterns to support multi-word load/store
2017 ;; with non-offsetable address.
2018 (define_expand "reload_noff_store"
2019 [(parallel [(match_operand 0 "memory_operand" "=m")
2020 (match_operand 1 "register_operand" "r")
2021 (match_operand:DI 2 "register_operand" "=&r")])]
2024 rtx mem = operands[0];
2025 rtx addr = XEXP (mem, 0);
2027 emit_move_insn (operands[2], addr);
2028 mem = replace_equiv_address_nv (mem, operands[2]);
2030 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2034 (define_expand "reload_noff_load"
2035 [(parallel [(match_operand 0 "register_operand" "=r")
2036 (match_operand 1 "memory_operand" "m")
2037 (match_operand:DI 2 "register_operand" "=r")])]
2040 rtx mem = operands[1];
2041 rtx addr = XEXP (mem, 0);
2043 emit_move_insn (operands[2], addr);
2044 mem = replace_equiv_address_nv (mem, operands[2]);
2046 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2050 (define_insn "*movdi_internal"
2051 [(set (match_operand:DI 0 "nonimmediate_operand"
2052 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2053 (match_operand:DI 1 "general_operand"
2054 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2055 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2057 switch (get_attr_type (insn))
2060 if (SSE_REG_P (operands[0]))
2061 return "movq2dq\t{%1, %0|%0, %1}";
2063 return "movdq2q\t{%1, %0|%0, %1}";
2066 switch (get_attr_mode (insn))
2069 return "%vmovdqa\t{%1, %0|%0, %1}";
2071 return "%vmovq\t{%1, %0|%0, %1}";
2073 return "movaps\t{%1, %0|%0, %1}";
2075 return "movlps\t{%1, %0|%0, %1}";
2081 return "movq\t{%1, %0|%0, %1}";
2084 return standard_sse_constant_opcode (insn, operands[1]);
2087 return "pxor\t%0, %0";
2097 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2098 (const_string "sse2")
2099 (eq_attr "alternative" "9,10,11,12")
2100 (const_string "noavx")
2102 (const_string "*")))
2104 (cond [(eq_attr "alternative" "0,1")
2105 (const_string "multi")
2106 (eq_attr "alternative" "2")
2107 (const_string "mmx")
2108 (eq_attr "alternative" "3,4")
2109 (const_string "mmxmov")
2110 (eq_attr "alternative" "5,9")
2111 (const_string "sselog1")
2112 (eq_attr "alternative" "13,14")
2113 (const_string "ssecvt")
2115 (const_string "ssemov")))
2116 (set (attr "prefix")
2117 (if_then_else (eq_attr "alternative" "5,6,7,8")
2118 (const_string "maybe_vex")
2119 (const_string "orig")))
2120 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2123 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2124 (match_operand:DI 1 "general_operand" ""))]
2125 "!TARGET_64BIT && reload_completed
2126 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2127 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2129 "ix86_split_long_move (operands); DONE;")
2131 (define_insn "*movsi_internal"
2132 [(set (match_operand:SI 0 "nonimmediate_operand"
2133 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2134 (match_operand:SI 1 "general_operand"
2135 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2136 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2138 switch (get_attr_type (insn))
2141 return standard_sse_constant_opcode (insn, operands[1]);
2144 switch (get_attr_mode (insn))
2147 return "%vmovdqa\t{%1, %0|%0, %1}";
2149 return "%vmovaps\t{%1, %0|%0, %1}";
2151 return "%vmovd\t{%1, %0|%0, %1}";
2153 return "%vmovss\t{%1, %0|%0, %1}";
2159 return "pxor\t%0, %0";
2162 if (get_attr_mode (insn) == MODE_DI)
2163 return "movq\t{%1, %0|%0, %1}";
2164 return "movd\t{%1, %0|%0, %1}";
2167 return "lea{l}\t{%E1, %0|%0, %E1}";
2170 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2171 if (ix86_use_lea_for_mov (insn, operands))
2172 return "lea{l}\t{%E1, %0|%0, %E1}";
2174 return "mov{l}\t{%1, %0|%0, %1}";
2178 (cond [(eq_attr "alternative" "2")
2179 (const_string "mmx")
2180 (eq_attr "alternative" "3,4,5")
2181 (const_string "mmxmov")
2182 (eq_attr "alternative" "6")
2183 (const_string "sselog1")
2184 (eq_attr "alternative" "7,8,9,10,11")
2185 (const_string "ssemov")
2186 (match_operand 1 "pic_32bit_operand" "")
2187 (const_string "lea")
2189 (const_string "imov")))
2190 (set (attr "prefix")
2191 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2192 (const_string "orig")
2193 (const_string "maybe_vex")))
2194 (set (attr "prefix_data16")
2195 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2197 (const_string "*")))
2199 (cond [(eq_attr "alternative" "2,3")
2201 (eq_attr "alternative" "6,7")
2203 (not (match_test "TARGET_SSE2"))
2204 (const_string "V4SF")
2205 (const_string "TI"))
2206 (and (eq_attr "alternative" "8,9,10,11")
2207 (not (match_test "TARGET_SSE2")))
2210 (const_string "SI")))])
2212 (define_insn "*movhi_internal"
2213 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2214 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2215 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2217 switch (get_attr_type (insn))
2220 /* movzwl is faster than movw on p2 due to partial word stalls,
2221 though not as fast as an aligned movl. */
2222 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2224 if (get_attr_mode (insn) == MODE_SI)
2225 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2227 return "mov{w}\t{%1, %0|%0, %1}";
2231 (cond [(match_test "optimize_function_for_size_p (cfun)")
2232 (const_string "imov")
2233 (and (eq_attr "alternative" "0")
2234 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2235 (not (match_test "TARGET_HIMODE_MATH"))))
2236 (const_string "imov")
2237 (and (eq_attr "alternative" "1,2")
2238 (match_operand:HI 1 "aligned_operand" ""))
2239 (const_string "imov")
2240 (and (match_test "TARGET_MOVX")
2241 (eq_attr "alternative" "0,2"))
2242 (const_string "imovx")
2244 (const_string "imov")))
2246 (cond [(eq_attr "type" "imovx")
2248 (and (eq_attr "alternative" "1,2")
2249 (match_operand:HI 1 "aligned_operand" ""))
2251 (and (eq_attr "alternative" "0")
2252 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2253 (not (match_test "TARGET_HIMODE_MATH"))))
2256 (const_string "HI")))])
2258 ;; Situation is quite tricky about when to choose full sized (SImode) move
2259 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2260 ;; partial register dependency machines (such as AMD Athlon), where QImode
2261 ;; moves issue extra dependency and for partial register stalls machines
2262 ;; that don't use QImode patterns (and QImode move cause stall on the next
2265 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2266 ;; register stall machines with, where we use QImode instructions, since
2267 ;; partial register stall can be caused there. Then we use movzx.
2268 (define_insn "*movqi_internal"
2269 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2270 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2271 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2273 switch (get_attr_type (insn))
2276 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2277 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2279 if (get_attr_mode (insn) == MODE_SI)
2280 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2282 return "mov{b}\t{%1, %0|%0, %1}";
2286 (cond [(and (eq_attr "alternative" "5")
2287 (not (match_operand:QI 1 "aligned_operand" "")))
2288 (const_string "imovx")
2289 (match_test "optimize_function_for_size_p (cfun)")
2290 (const_string "imov")
2291 (and (eq_attr "alternative" "3")
2292 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2293 (not (match_test "TARGET_QIMODE_MATH"))))
2294 (const_string "imov")
2295 (eq_attr "alternative" "3,5")
2296 (const_string "imovx")
2297 (and (match_test "TARGET_MOVX")
2298 (eq_attr "alternative" "2"))
2299 (const_string "imovx")
2301 (const_string "imov")))
2303 (cond [(eq_attr "alternative" "3,4,5")
2305 (eq_attr "alternative" "6")
2307 (eq_attr "type" "imovx")
2309 (and (eq_attr "type" "imov")
2310 (and (eq_attr "alternative" "0,1")
2311 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2312 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2313 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2315 ;; Avoid partial register stalls when not using QImode arithmetic
2316 (and (eq_attr "type" "imov")
2317 (and (eq_attr "alternative" "0,1")
2318 (and (match_test "TARGET_PARTIAL_REG_STALL")
2319 (not (match_test "TARGET_QIMODE_MATH")))))
2322 (const_string "QI")))])
2324 ;; Stores and loads of ax to arbitrary constant address.
2325 ;; We fake an second form of instruction to force reload to load address
2326 ;; into register when rax is not available
2327 (define_insn "*movabs<mode>_1"
2328 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2329 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2330 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2332 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2333 mov{<imodesuffix>}\t{%1, %a0|<iptrsize> PTR %a0, %1}"
2334 [(set_attr "type" "imov")
2335 (set_attr "modrm" "0,*")
2336 (set_attr "length_address" "8,0")
2337 (set_attr "length_immediate" "0,*")
2338 (set_attr "memory" "store")
2339 (set_attr "mode" "<MODE>")])
2341 (define_insn "*movabs<mode>_2"
2342 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2343 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2344 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2346 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2347 mov{<imodesuffix>}\t{%a1, %0|%0, <iptrsize> PTR %a1}"
2348 [(set_attr "type" "imov")
2349 (set_attr "modrm" "0,*")
2350 (set_attr "length_address" "8,0")
2351 (set_attr "length_immediate" "0")
2352 (set_attr "memory" "load")
2353 (set_attr "mode" "<MODE>")])
2355 (define_insn "*swap<mode>"
2356 [(set (match_operand:SWI48 0 "register_operand" "+r")
2357 (match_operand:SWI48 1 "register_operand" "+r"))
2361 "xchg{<imodesuffix>}\t%1, %0"
2362 [(set_attr "type" "imov")
2363 (set_attr "mode" "<MODE>")
2364 (set_attr "pent_pair" "np")
2365 (set_attr "athlon_decode" "vector")
2366 (set_attr "amdfam10_decode" "double")
2367 (set_attr "bdver1_decode" "double")])
2369 (define_insn "*swap<mode>_1"
2370 [(set (match_operand:SWI12 0 "register_operand" "+r")
2371 (match_operand:SWI12 1 "register_operand" "+r"))
2374 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2376 [(set_attr "type" "imov")
2377 (set_attr "mode" "SI")
2378 (set_attr "pent_pair" "np")
2379 (set_attr "athlon_decode" "vector")
2380 (set_attr "amdfam10_decode" "double")
2381 (set_attr "bdver1_decode" "double")])
2383 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2384 ;; is disabled for AMDFAM10
2385 (define_insn "*swap<mode>_2"
2386 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2387 (match_operand:SWI12 1 "register_operand" "+<r>"))
2390 "TARGET_PARTIAL_REG_STALL"
2391 "xchg{<imodesuffix>}\t%1, %0"
2392 [(set_attr "type" "imov")
2393 (set_attr "mode" "<MODE>")
2394 (set_attr "pent_pair" "np")
2395 (set_attr "athlon_decode" "vector")])
2397 (define_expand "movstrict<mode>"
2398 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2399 (match_operand:SWI12 1 "general_operand" ""))]
2402 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2404 if (GET_CODE (operands[0]) == SUBREG
2405 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2407 /* Don't generate memory->memory moves, go through a register */
2408 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2409 operands[1] = force_reg (<MODE>mode, operands[1]);
2412 (define_insn "*movstrict<mode>_1"
2413 [(set (strict_low_part
2414 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2415 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2416 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2417 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2418 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2419 [(set_attr "type" "imov")
2420 (set_attr "mode" "<MODE>")])
2422 (define_insn "*movstrict<mode>_xor"
2423 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2424 (match_operand:SWI12 1 "const0_operand" ""))
2425 (clobber (reg:CC FLAGS_REG))]
2427 "xor{<imodesuffix>}\t%0, %0"
2428 [(set_attr "type" "alu1")
2429 (set_attr "mode" "<MODE>")
2430 (set_attr "length_immediate" "0")])
2432 (define_insn "*mov<mode>_extv_1"
2433 [(set (match_operand:SWI24 0 "register_operand" "=R")
2434 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2438 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2439 [(set_attr "type" "imovx")
2440 (set_attr "mode" "SI")])
2442 (define_insn "*movqi_extv_1_rex64"
2443 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2444 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2449 switch (get_attr_type (insn))
2452 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2454 return "mov{b}\t{%h1, %0|%0, %h1}";
2458 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2459 (match_test "TARGET_MOVX"))
2460 (const_string "imovx")
2461 (const_string "imov")))
2463 (if_then_else (eq_attr "type" "imovx")
2465 (const_string "QI")))])
2467 (define_insn "*movqi_extv_1"
2468 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2469 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2474 switch (get_attr_type (insn))
2477 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2479 return "mov{b}\t{%h1, %0|%0, %h1}";
2483 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2484 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2485 (match_test "TARGET_MOVX")))
2486 (const_string "imovx")
2487 (const_string "imov")))
2489 (if_then_else (eq_attr "type" "imovx")
2491 (const_string "QI")))])
2493 (define_insn "*mov<mode>_extzv_1"
2494 [(set (match_operand:SWI48 0 "register_operand" "=R")
2495 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2499 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2500 [(set_attr "type" "imovx")
2501 (set_attr "mode" "SI")])
2503 (define_insn "*movqi_extzv_2_rex64"
2504 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2506 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2511 switch (get_attr_type (insn))
2514 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2516 return "mov{b}\t{%h1, %0|%0, %h1}";
2520 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2521 (match_test "TARGET_MOVX"))
2522 (const_string "imovx")
2523 (const_string "imov")))
2525 (if_then_else (eq_attr "type" "imovx")
2527 (const_string "QI")))])
2529 (define_insn "*movqi_extzv_2"
2530 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2532 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2537 switch (get_attr_type (insn))
2540 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2542 return "mov{b}\t{%h1, %0|%0, %h1}";
2546 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2547 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2548 (match_test "TARGET_MOVX")))
2549 (const_string "imovx")
2550 (const_string "imov")))
2552 (if_then_else (eq_attr "type" "imovx")
2554 (const_string "QI")))])
2556 (define_expand "mov<mode>_insv_1"
2557 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2560 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2562 (define_insn "*mov<mode>_insv_1_rex64"
2563 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2566 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2569 if (CONST_INT_P (operands[1]))
2570 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2571 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2573 [(set_attr "type" "imov")
2574 (set_attr "mode" "QI")])
2576 (define_insn "*movsi_insv_1"
2577 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2580 (match_operand:SI 1 "general_operand" "Qmn"))]
2583 if (CONST_INT_P (operands[1]))
2584 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2585 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2587 [(set_attr "type" "imov")
2588 (set_attr "mode" "QI")])
2590 (define_insn "*movqi_insv_2"
2591 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2594 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2597 "mov{b}\t{%h1, %h0|%h0, %h1}"
2598 [(set_attr "type" "imov")
2599 (set_attr "mode" "QI")])
2601 ;; Floating point push instructions.
2603 (define_insn "*pushtf"
2604 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2605 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2608 /* This insn should be already split before reg-stack. */
2611 [(set_attr "type" "multi")
2612 (set_attr "unit" "sse,*,*")
2613 (set_attr "mode" "TF,SI,SI")])
2615 ;; %%% Kill this when call knows how to work this out.
2617 [(set (match_operand:TF 0 "push_operand" "")
2618 (match_operand:TF 1 "sse_reg_operand" ""))]
2619 "TARGET_SSE2 && reload_completed"
2620 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2621 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2623 (define_insn "*pushxf"
2624 [(set (match_operand:XF 0 "push_operand" "=<,<")
2625 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2626 "optimize_function_for_speed_p (cfun)"
2628 /* This insn should be already split before reg-stack. */
2631 [(set_attr "type" "multi")
2632 (set_attr "unit" "i387,*")
2633 (set_attr "mode" "XF,SI")])
2635 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2636 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2637 ;; Pushing using integer instructions is longer except for constants
2638 ;; and direct memory references (assuming that any given constant is pushed
2639 ;; only once, but this ought to be handled elsewhere).
2641 (define_insn "*pushxf_nointeger"
2642 [(set (match_operand:XF 0 "push_operand" "=<,<")
2643 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2644 "optimize_function_for_size_p (cfun)"
2646 /* This insn should be already split before reg-stack. */
2649 [(set_attr "type" "multi")
2650 (set_attr "unit" "i387,*")
2651 (set_attr "mode" "XF,SI")])
2653 ;; %%% Kill this when call knows how to work this out.
2655 [(set (match_operand:XF 0 "push_operand" "")
2656 (match_operand:XF 1 "fp_register_operand" ""))]
2658 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2659 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2660 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2662 (define_insn "*pushdf_rex64"
2663 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2664 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2667 /* This insn should be already split before reg-stack. */
2670 [(set_attr "type" "multi")
2671 (set_attr "unit" "i387,*,*")
2672 (set_attr "mode" "DF,DI,DF")])
2674 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2675 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2676 ;; On the average, pushdf using integers can be still shorter.
2678 (define_insn "*pushdf"
2679 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2680 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2683 /* This insn should be already split before reg-stack. */
2686 [(set_attr "isa" "*,*,sse2")
2687 (set_attr "type" "multi")
2688 (set_attr "unit" "i387,*,*")
2689 (set_attr "mode" "DF,DI,DF")])
2691 ;; %%% Kill this when call knows how to work this out.
2693 [(set (match_operand:DF 0 "push_operand" "")
2694 (match_operand:DF 1 "any_fp_register_operand" ""))]
2696 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2697 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2699 (define_insn "*pushsf_rex64"
2700 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2701 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2704 /* Anything else should be already split before reg-stack. */
2705 gcc_assert (which_alternative == 1);
2706 return "push{q}\t%q1";
2708 [(set_attr "type" "multi,push,multi")
2709 (set_attr "unit" "i387,*,*")
2710 (set_attr "mode" "SF,DI,SF")])
2712 (define_insn "*pushsf"
2713 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2714 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2717 /* Anything else should be already split before reg-stack. */
2718 gcc_assert (which_alternative == 1);
2719 return "push{l}\t%1";
2721 [(set_attr "type" "multi,push,multi")
2722 (set_attr "unit" "i387,*,*")
2723 (set_attr "mode" "SF,SI,SF")])
2725 ;; %%% Kill this when call knows how to work this out.
2727 [(set (match_operand:SF 0 "push_operand" "")
2728 (match_operand:SF 1 "any_fp_register_operand" ""))]
2730 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2731 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2732 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2735 [(set (match_operand:SF 0 "push_operand" "")
2736 (match_operand:SF 1 "memory_operand" ""))]
2738 && (operands[2] = find_constant_src (insn))"
2739 [(set (match_dup 0) (match_dup 2))])
2742 [(set (match_operand 0 "push_operand" "")
2743 (match_operand 1 "general_operand" ""))]
2745 && (GET_MODE (operands[0]) == TFmode
2746 || GET_MODE (operands[0]) == XFmode
2747 || GET_MODE (operands[0]) == DFmode)
2748 && !ANY_FP_REG_P (operands[1])"
2750 "ix86_split_long_move (operands); DONE;")
2752 ;; Floating point move instructions.
2754 (define_expand "movtf"
2755 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2756 (match_operand:TF 1 "nonimmediate_operand" ""))]
2757 "TARGET_64BIT || TARGET_SSE2"
2759 ix86_expand_move (TFmode, operands);
2763 (define_expand "mov<mode>"
2764 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2765 (match_operand:X87MODEF 1 "general_operand" ""))]
2767 "ix86_expand_move (<MODE>mode, operands); DONE;")
2769 (define_insn "*movtf_internal_rex64"
2770 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2771 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,*r"))]
2772 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2773 && (!can_create_pseudo_p ()
2774 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2775 || GET_CODE (operands[1]) != CONST_DOUBLE
2776 || (optimize_function_for_size_p (cfun)
2777 && standard_sse_constant_p (operands[1])
2778 && !memory_operand (operands[0], TFmode))
2779 || (!TARGET_MEMORY_MISMATCH_STALL
2780 && memory_operand (operands[0], TFmode)))"
2782 switch (which_alternative)
2786 /* Handle misaligned load/store since we
2787 don't have movmisaligntf pattern. */
2788 if (misaligned_operand (operands[0], TFmode)
2789 || misaligned_operand (operands[1], TFmode))
2791 if (get_attr_mode (insn) == MODE_V4SF)
2792 return "%vmovups\t{%1, %0|%0, %1}";
2794 return "%vmovdqu\t{%1, %0|%0, %1}";
2798 if (get_attr_mode (insn) == MODE_V4SF)
2799 return "%vmovaps\t{%1, %0|%0, %1}";
2801 return "%vmovdqa\t{%1, %0|%0, %1}";
2805 return standard_sse_constant_opcode (insn, operands[1]);
2815 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2816 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2818 (cond [(eq_attr "alternative" "0,2")
2820 (match_test "optimize_function_for_size_p (cfun)")
2821 (const_string "V4SF")
2822 (const_string "TI"))
2823 (eq_attr "alternative" "1")
2825 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2826 (match_test "optimize_function_for_size_p (cfun)"))
2827 (const_string "V4SF")
2828 (const_string "TI"))]
2829 (const_string "DI")))])
2831 (define_insn "*movtf_internal_sse2"
2832 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x")
2833 (match_operand:TF 1 "general_operand" "xm,x,C"))]
2834 "TARGET_SSE2 && !TARGET_64BIT
2835 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2836 && (!can_create_pseudo_p ()
2837 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2838 || GET_CODE (operands[1]) != CONST_DOUBLE
2839 || (optimize_function_for_size_p (cfun)
2840 && standard_sse_constant_p (operands[1])
2841 && !memory_operand (operands[0], TFmode))
2842 || (!TARGET_MEMORY_MISMATCH_STALL
2843 && memory_operand (operands[0], TFmode)))"
2845 switch (which_alternative)
2849 /* Handle misaligned load/store since we
2850 don't have movmisaligntf pattern. */
2851 if (misaligned_operand (operands[0], TFmode)
2852 || misaligned_operand (operands[1], TFmode))
2854 if (get_attr_mode (insn) == MODE_V4SF)
2855 return "%vmovups\t{%1, %0|%0, %1}";
2857 return "%vmovdqu\t{%1, %0|%0, %1}";
2861 if (get_attr_mode (insn) == MODE_V4SF)
2862 return "%vmovaps\t{%1, %0|%0, %1}";
2864 return "%vmovdqa\t{%1, %0|%0, %1}";
2868 return standard_sse_constant_opcode (insn, operands[1]);
2874 [(set_attr "type" "ssemov,ssemov,sselog1")
2875 (set_attr "prefix" "maybe_vex")
2877 (cond [(eq_attr "alternative" "0,2")
2879 (match_test "optimize_function_for_size_p (cfun)")
2880 (const_string "V4SF")
2881 (const_string "TI"))
2882 (eq_attr "alternative" "1")
2884 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2885 (match_test "optimize_function_for_size_p (cfun)"))
2886 (const_string "V4SF")
2887 (const_string "TI"))]
2888 (const_string "DI")))])
2890 (define_insn "*movxf_internal_rex64"
2891 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2892 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rC"))]
2893 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2894 && (!can_create_pseudo_p ()
2895 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2896 || GET_CODE (operands[1]) != CONST_DOUBLE
2897 || (optimize_function_for_size_p (cfun)
2898 && standard_80387_constant_p (operands[1]) > 0
2899 && !memory_operand (operands[0], XFmode))
2900 || (!TARGET_MEMORY_MISMATCH_STALL
2901 && memory_operand (operands[0], XFmode)))"
2903 switch (which_alternative)
2907 return output_387_reg_move (insn, operands);
2910 return standard_80387_constant_opcode (operands[1]);
2920 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2921 (set_attr "mode" "XF,XF,XF,SI,SI")])
2923 ;; Possible store forwarding (partial memory) stall in alternative 4.
2924 (define_insn "*movxf_internal"
2925 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2926 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rF"))]
2927 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2928 && (!can_create_pseudo_p ()
2929 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2930 || GET_CODE (operands[1]) != CONST_DOUBLE
2931 || (optimize_function_for_size_p (cfun)
2932 && standard_80387_constant_p (operands[1]) > 0
2933 && !memory_operand (operands[0], XFmode))
2934 || (!TARGET_MEMORY_MISMATCH_STALL
2935 && memory_operand (operands[0], XFmode)))"
2937 switch (which_alternative)
2941 return output_387_reg_move (insn, operands);
2944 return standard_80387_constant_opcode (operands[1]);
2954 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2955 (set_attr "mode" "XF,XF,XF,SI,SI")])
2957 (define_insn "*movdf_internal_rex64"
2958 [(set (match_operand:DF 0 "nonimmediate_operand"
2959 "=?Yf*f,?m ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ")
2960 (match_operand:DF 1 "general_operand"
2961 "Yf*fm ,Yf*f ,G ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2962 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2963 && (!can_create_pseudo_p ()
2964 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2965 || GET_CODE (operands[1]) != CONST_DOUBLE
2966 || (optimize_function_for_size_p (cfun)
2967 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2968 && standard_80387_constant_p (operands[1]) > 0)
2969 || (TARGET_SSE2 && TARGET_SSE_MATH
2970 && standard_sse_constant_p (operands[1]))))
2971 || memory_operand (operands[0], DFmode))"
2973 switch (which_alternative)
2977 return output_387_reg_move (insn, operands);
2980 return standard_80387_constant_opcode (operands[1]);
2984 return "mov{q}\t{%1, %0|%0, %1}";
2987 return "mov{l}\t{%1, %k0|%k0, %1}";
2990 return "movabs{q}\t{%1, %0|%0, %1}";
2993 return standard_sse_constant_opcode (insn, operands[1]);
2998 switch (get_attr_mode (insn))
3001 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3002 return "%vmovapd\t{%1, %0|%0, %1}";
3004 return "%vmovaps\t{%1, %0|%0, %1}";
3007 return "%vmovq\t{%1, %0|%0, %1}";
3009 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3010 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3011 return "%vmovsd\t{%1, %0|%0, %1}";
3013 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3015 return "%vmovlps\t{%1, %d0|%d0, %1}";
3022 /* Handle broken assemblers that require movd instead of movq. */
3023 return "%vmovd\t{%1, %0|%0, %1}";
3030 (cond [(eq_attr "alternative" "0,1,2")
3031 (const_string "fmov")
3032 (eq_attr "alternative" "3,4,5,6")
3033 (const_string "imov")
3034 (eq_attr "alternative" "7")
3035 (const_string "sselog1")
3037 (const_string "ssemov")))
3040 (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3042 (const_string "*")))
3043 (set (attr "length_immediate")
3045 (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3047 (const_string "*")))
3048 (set (attr "prefix")
3049 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3050 (const_string "orig")
3051 (const_string "maybe_vex")))
3052 (set (attr "prefix_data16")
3053 (if_then_else (eq_attr "mode" "V1DF")
3055 (const_string "*")))
3057 (cond [(eq_attr "alternative" "0,1,2")
3059 (eq_attr "alternative" "3,4,6,11,12")
3061 (eq_attr "alternative" "5")
3064 /* xorps is one byte shorter. */
3065 (eq_attr "alternative" "7")
3066 (cond [(match_test "optimize_function_for_size_p (cfun)")
3067 (const_string "V4SF")
3068 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3071 (const_string "V2DF"))
3073 /* For architectures resolving dependencies on
3074 whole SSE registers use APD move to break dependency
3075 chains, otherwise use short move to avoid extra work.
3077 movaps encodes one byte shorter. */
3078 (eq_attr "alternative" "8")
3080 [(match_test "optimize_function_for_size_p (cfun)")
3081 (const_string "V4SF")
3082 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3083 (const_string "V2DF")
3085 (const_string "DF"))
3086 /* For architectures resolving dependencies on register
3087 parts we may avoid extra work to zero out upper part
3089 (eq_attr "alternative" "9")
3091 (match_test "TARGET_SSE_SPLIT_REGS")
3092 (const_string "V1DF")
3093 (const_string "DF"))
3095 (const_string "DF")))])
3097 ;; Possible store forwarding (partial memory) stall in alternative 4.
3098 (define_insn "*movdf_internal"
3099 [(set (match_operand:DF 0 "nonimmediate_operand"
3100 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3101 (match_operand:DF 1 "general_operand"
3102 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3103 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3104 && (!can_create_pseudo_p ()
3105 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3106 || GET_CODE (operands[1]) != CONST_DOUBLE
3107 || (optimize_function_for_size_p (cfun)
3108 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3109 && standard_80387_constant_p (operands[1]) > 0)
3110 || (TARGET_SSE2 && TARGET_SSE_MATH
3111 && standard_sse_constant_p (operands[1])))
3112 && !memory_operand (operands[0], DFmode))
3113 || (!TARGET_MEMORY_MISMATCH_STALL
3114 && memory_operand (operands[0], DFmode)))"
3116 switch (which_alternative)
3120 return output_387_reg_move (insn, operands);
3123 return standard_80387_constant_opcode (operands[1]);
3131 return standard_sse_constant_opcode (insn, operands[1]);
3139 switch (get_attr_mode (insn))
3142 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3143 return "%vmovapd\t{%1, %0|%0, %1}";
3145 return "%vmovaps\t{%1, %0|%0, %1}";
3148 return "%vmovq\t{%1, %0|%0, %1}";
3150 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3151 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3152 return "%vmovsd\t{%1, %0|%0, %1}";
3154 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3156 return "%vmovlps\t{%1, %d0|%d0, %1}";
3166 (if_then_else (eq_attr "alternative" "5,6,7,8")
3167 (const_string "sse2")
3168 (const_string "*")))
3170 (cond [(eq_attr "alternative" "0,1,2")
3171 (const_string "fmov")
3172 (eq_attr "alternative" "3,4")
3173 (const_string "multi")
3174 (eq_attr "alternative" "5,9")
3175 (const_string "sselog1")
3177 (const_string "ssemov")))
3178 (set (attr "prefix")
3179 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3180 (const_string "orig")
3181 (const_string "maybe_vex")))
3182 (set (attr "prefix_data16")
3183 (if_then_else (eq_attr "mode" "V1DF")
3185 (const_string "*")))
3187 (cond [(eq_attr "alternative" "0,1,2")
3189 (eq_attr "alternative" "3,4")
3192 /* For SSE1, we have many fewer alternatives. */
3193 (not (match_test "TARGET_SSE2"))
3195 (eq_attr "alternative" "5,6,9,10")
3196 (const_string "V4SF")
3197 (const_string "V2SF"))
3199 /* xorps is one byte shorter. */
3200 (eq_attr "alternative" "5,9")
3201 (cond [(match_test "optimize_function_for_size_p (cfun)")
3202 (const_string "V4SF")
3203 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3206 (const_string "V2DF"))
3208 /* For architectures resolving dependencies on
3209 whole SSE registers use APD move to break dependency
3210 chains, otherwise use short move to avoid extra work.
3212 movaps encodes one byte shorter. */
3213 (eq_attr "alternative" "6,10")
3215 [(match_test "optimize_function_for_size_p (cfun)")
3216 (const_string "V4SF")
3217 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3218 (const_string "V2DF")
3220 (const_string "DF"))
3221 /* For architectures resolving dependencies on register
3222 parts we may avoid extra work to zero out upper part
3224 (eq_attr "alternative" "7,11")
3226 (match_test "TARGET_SSE_SPLIT_REGS")
3227 (const_string "V1DF")
3228 (const_string "DF"))
3230 (const_string "DF")))])
3232 (define_insn "*movsf_internal"
3233 [(set (match_operand:SF 0 "nonimmediate_operand"
3234 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3235 (match_operand:SF 1 "general_operand"
3236 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3237 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3238 && (!can_create_pseudo_p ()
3239 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3240 || GET_CODE (operands[1]) != CONST_DOUBLE
3241 || (optimize_function_for_size_p (cfun)
3242 && ((!TARGET_SSE_MATH
3243 && standard_80387_constant_p (operands[1]) > 0)
3245 && standard_sse_constant_p (operands[1]))))
3246 || memory_operand (operands[0], SFmode))"
3248 switch (which_alternative)
3252 return output_387_reg_move (insn, operands);
3255 return standard_80387_constant_opcode (operands[1]);
3259 return "mov{l}\t{%1, %0|%0, %1}";
3262 return standard_sse_constant_opcode (insn, operands[1]);
3265 if (get_attr_mode (insn) == MODE_V4SF)
3266 return "%vmovaps\t{%1, %0|%0, %1}";
3268 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3272 return "%vmovss\t{%1, %0|%0, %1}";
3278 return "movd\t{%1, %0|%0, %1}";
3281 return "movq\t{%1, %0|%0, %1}";
3285 return "%vmovd\t{%1, %0|%0, %1}";
3292 (cond [(eq_attr "alternative" "0,1,2")
3293 (const_string "fmov")
3294 (eq_attr "alternative" "3,4")
3295 (const_string "imov")
3296 (eq_attr "alternative" "5")
3297 (const_string "sselog1")
3298 (eq_attr "alternative" "9,10,11,14,15")
3299 (const_string "mmxmov")
3301 (const_string "ssemov")))
3302 (set (attr "prefix")
3303 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3304 (const_string "maybe_vex")
3305 (const_string "orig")))
3307 (cond [(eq_attr "alternative" "3,4,9,10")
3309 (eq_attr "alternative" "5")
3311 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3312 (match_test "TARGET_SSE2"))
3313 (not (match_test "optimize_function_for_size_p (cfun)")))
3315 (const_string "V4SF"))
3316 /* For architectures resolving dependencies on
3317 whole SSE registers use APS move to break dependency
3318 chains, otherwise use short move to avoid extra work.
3320 Do the same for architectures resolving dependencies on
3321 the parts. While in DF mode it is better to always handle
3322 just register parts, the SF mode is different due to lack
3323 of instructions to load just part of the register. It is
3324 better to maintain the whole registers in single format
3325 to avoid problems on using packed logical operations. */
3326 (eq_attr "alternative" "6")
3328 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3329 (match_test "TARGET_SSE_SPLIT_REGS"))
3330 (const_string "V4SF")
3331 (const_string "SF"))
3332 (eq_attr "alternative" "11")
3333 (const_string "DI")]
3334 (const_string "SF")))])
3337 [(set (match_operand 0 "any_fp_register_operand" "")
3338 (match_operand 1 "memory_operand" ""))]
3340 && (GET_MODE (operands[0]) == TFmode
3341 || GET_MODE (operands[0]) == XFmode
3342 || GET_MODE (operands[0]) == DFmode
3343 || GET_MODE (operands[0]) == SFmode)
3344 && (operands[2] = find_constant_src (insn))"
3345 [(set (match_dup 0) (match_dup 2))]
3347 rtx c = operands[2];
3348 int r = REGNO (operands[0]);
3350 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3351 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3356 [(set (match_operand 0 "any_fp_register_operand" "")
3357 (float_extend (match_operand 1 "memory_operand" "")))]
3359 && (GET_MODE (operands[0]) == TFmode
3360 || GET_MODE (operands[0]) == XFmode
3361 || GET_MODE (operands[0]) == DFmode)
3362 && (operands[2] = find_constant_src (insn))"
3363 [(set (match_dup 0) (match_dup 2))]
3365 rtx c = operands[2];
3366 int r = REGNO (operands[0]);
3368 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3369 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3373 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3375 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3376 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3378 && (standard_80387_constant_p (operands[1]) == 8
3379 || standard_80387_constant_p (operands[1]) == 9)"
3380 [(set (match_dup 0)(match_dup 1))
3382 (neg:X87MODEF (match_dup 0)))]
3386 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3387 if (real_isnegzero (&r))
3388 operands[1] = CONST0_RTX (<MODE>mode);
3390 operands[1] = CONST1_RTX (<MODE>mode);
3394 [(set (match_operand 0 "nonimmediate_operand" "")
3395 (match_operand 1 "general_operand" ""))]
3397 && (GET_MODE (operands[0]) == TFmode
3398 || GET_MODE (operands[0]) == XFmode
3399 || GET_MODE (operands[0]) == DFmode)
3400 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3402 "ix86_split_long_move (operands); DONE;")
3404 (define_insn "swapxf"
3405 [(set (match_operand:XF 0 "register_operand" "+f")
3406 (match_operand:XF 1 "register_operand" "+f"))
3411 if (STACK_TOP_P (operands[0]))
3416 [(set_attr "type" "fxch")
3417 (set_attr "mode" "XF")])
3419 (define_insn "*swap<mode>"
3420 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3421 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3424 "TARGET_80387 || reload_completed"
3426 if (STACK_TOP_P (operands[0]))
3431 [(set_attr "type" "fxch")
3432 (set_attr "mode" "<MODE>")])
3434 ;; Zero extension instructions
3436 (define_expand "zero_extendsidi2"
3437 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3438 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3443 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3448 (define_insn "*zero_extendsidi2_rex64"
3449 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?!*y,?*Yi,*x")
3451 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3454 mov{l}\t{%1, %k0|%k0, %1}
3456 movd\t{%1, %0|%0, %1}
3457 movd\t{%1, %0|%0, %1}
3458 %vmovd\t{%1, %0|%0, %1}
3459 %vmovd\t{%1, %0|%0, %1}"
3460 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3461 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3462 (set_attr "prefix_0f" "0,*,*,*,*,*")
3463 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3466 [(set (match_operand:DI 0 "memory_operand" "")
3467 (zero_extend:DI (match_dup 0)))]
3469 [(set (match_dup 4) (const_int 0))]
3470 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3472 ;; %%% Kill me once multi-word ops are sane.
3473 (define_insn "zero_extendsidi2_1"
3474 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?!*y,?*Yi,*x")
3476 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3477 (clobber (reg:CC FLAGS_REG))]
3483 movd\t{%1, %0|%0, %1}
3484 movd\t{%1, %0|%0, %1}
3485 %vmovd\t{%1, %0|%0, %1}
3486 %vmovd\t{%1, %0|%0, %1}"
3487 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3488 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3489 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3490 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3493 [(set (match_operand:DI 0 "register_operand" "")
3494 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3495 (clobber (reg:CC FLAGS_REG))]
3496 "!TARGET_64BIT && reload_completed
3497 && true_regnum (operands[0]) == true_regnum (operands[1])"
3498 [(set (match_dup 4) (const_int 0))]
3499 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3502 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3503 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3504 (clobber (reg:CC FLAGS_REG))]
3505 "!TARGET_64BIT && reload_completed
3506 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3507 [(set (match_dup 3) (match_dup 1))
3508 (set (match_dup 4) (const_int 0))]
3509 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3511 (define_insn "zero_extend<mode>di2"
3512 [(set (match_operand:DI 0 "register_operand" "=r")
3514 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3516 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3517 [(set_attr "type" "imovx")
3518 (set_attr "mode" "SI")])
3520 (define_expand "zero_extendhisi2"
3521 [(set (match_operand:SI 0 "register_operand" "")
3522 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3525 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3527 operands[1] = force_reg (HImode, operands[1]);
3528 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3533 (define_insn_and_split "zero_extendhisi2_and"
3534 [(set (match_operand:SI 0 "register_operand" "=r")
3535 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3536 (clobber (reg:CC FLAGS_REG))]
3537 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3539 "&& reload_completed"
3540 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3541 (clobber (reg:CC FLAGS_REG))])]
3543 [(set_attr "type" "alu1")
3544 (set_attr "mode" "SI")])
3546 (define_insn "*zero_extendhisi2_movzwl"
3547 [(set (match_operand:SI 0 "register_operand" "=r")
3548 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3549 "!TARGET_ZERO_EXTEND_WITH_AND
3550 || optimize_function_for_size_p (cfun)"
3551 "movz{wl|x}\t{%1, %0|%0, %1}"
3552 [(set_attr "type" "imovx")
3553 (set_attr "mode" "SI")])
3555 (define_expand "zero_extendqi<mode>2"
3557 [(set (match_operand:SWI24 0 "register_operand" "")
3558 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3559 (clobber (reg:CC FLAGS_REG))])])
3561 (define_insn "*zero_extendqi<mode>2_and"
3562 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3563 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3564 (clobber (reg:CC FLAGS_REG))]
3565 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3567 [(set_attr "type" "alu1")
3568 (set_attr "mode" "<MODE>")])
3570 ;; When source and destination does not overlap, clear destination
3571 ;; first and then do the movb
3573 [(set (match_operand:SWI24 0 "register_operand" "")
3574 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3575 (clobber (reg:CC FLAGS_REG))]
3577 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3578 && ANY_QI_REG_P (operands[0])
3579 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3580 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3581 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3583 operands[2] = gen_lowpart (QImode, operands[0]);
3584 ix86_expand_clear (operands[0]);
3587 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3588 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3589 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3590 (clobber (reg:CC FLAGS_REG))]
3591 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3593 [(set_attr "type" "imovx,alu1")
3594 (set_attr "mode" "<MODE>")])
3596 ;; For the movzbl case strip only the clobber
3598 [(set (match_operand:SWI24 0 "register_operand" "")
3599 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3600 (clobber (reg:CC FLAGS_REG))]
3602 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3603 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3605 (zero_extend:SWI24 (match_dup 1)))])
3607 ; zero extend to SImode to avoid partial register stalls
3608 (define_insn "*zero_extendqi<mode>2_movzbl"
3609 [(set (match_operand:SWI24 0 "register_operand" "=r")
3610 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3612 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3613 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3614 [(set_attr "type" "imovx")
3615 (set_attr "mode" "SI")])
3617 ;; Rest is handled by single and.
3619 [(set (match_operand:SWI24 0 "register_operand" "")
3620 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3621 (clobber (reg:CC FLAGS_REG))]
3623 && true_regnum (operands[0]) == true_regnum (operands[1])"
3624 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3625 (clobber (reg:CC FLAGS_REG))])])
3627 ;; Sign extension instructions
3629 (define_expand "extendsidi2"
3630 [(set (match_operand:DI 0 "register_operand" "")
3631 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3636 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3641 (define_insn "*extendsidi2_rex64"
3642 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3643 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3647 movs{lq|x}\t{%1, %0|%0, %1}"
3648 [(set_attr "type" "imovx")
3649 (set_attr "mode" "DI")
3650 (set_attr "prefix_0f" "0")
3651 (set_attr "modrm" "0,1")])
3653 (define_insn "extendsidi2_1"
3654 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3655 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3656 (clobber (reg:CC FLAGS_REG))
3657 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3661 ;; Extend to memory case when source register does die.
3663 [(set (match_operand:DI 0 "memory_operand" "")
3664 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3665 (clobber (reg:CC FLAGS_REG))
3666 (clobber (match_operand:SI 2 "register_operand" ""))]
3668 && dead_or_set_p (insn, operands[1])
3669 && !reg_mentioned_p (operands[1], operands[0]))"
3670 [(set (match_dup 3) (match_dup 1))
3671 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3672 (clobber (reg:CC FLAGS_REG))])
3673 (set (match_dup 4) (match_dup 1))]
3674 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3676 ;; Extend to memory case when source register does not die.
3678 [(set (match_operand:DI 0 "memory_operand" "")
3679 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3680 (clobber (reg:CC FLAGS_REG))
3681 (clobber (match_operand:SI 2 "register_operand" ""))]
3685 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3687 emit_move_insn (operands[3], operands[1]);
3689 /* Generate a cltd if possible and doing so it profitable. */
3690 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3691 && true_regnum (operands[1]) == AX_REG
3692 && true_regnum (operands[2]) == DX_REG)
3694 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3698 emit_move_insn (operands[2], operands[1]);
3699 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3701 emit_move_insn (operands[4], operands[2]);
3705 ;; Extend to register case. Optimize case where source and destination
3706 ;; registers match and cases where we can use cltd.
3708 [(set (match_operand:DI 0 "register_operand" "")
3709 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3710 (clobber (reg:CC FLAGS_REG))
3711 (clobber (match_scratch:SI 2 ""))]
3715 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3717 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3718 emit_move_insn (operands[3], operands[1]);
3720 /* Generate a cltd if possible and doing so it profitable. */
3721 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3722 && true_regnum (operands[3]) == AX_REG
3723 && true_regnum (operands[4]) == DX_REG)
3725 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3729 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3730 emit_move_insn (operands[4], operands[1]);
3732 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3736 (define_insn "extend<mode>di2"
3737 [(set (match_operand:DI 0 "register_operand" "=r")
3739 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3741 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3742 [(set_attr "type" "imovx")
3743 (set_attr "mode" "DI")])
3745 (define_insn "extendhisi2"
3746 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3747 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3750 switch (get_attr_prefix_0f (insn))
3753 return "{cwtl|cwde}";
3755 return "movs{wl|x}\t{%1, %0|%0, %1}";
3758 [(set_attr "type" "imovx")
3759 (set_attr "mode" "SI")
3760 (set (attr "prefix_0f")
3761 ;; movsx is short decodable while cwtl is vector decoded.
3762 (if_then_else (and (eq_attr "cpu" "!k6")
3763 (eq_attr "alternative" "0"))
3765 (const_string "1")))
3767 (if_then_else (eq_attr "prefix_0f" "0")
3769 (const_string "1")))])
3771 (define_insn "*extendhisi2_zext"
3772 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3775 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3778 switch (get_attr_prefix_0f (insn))
3781 return "{cwtl|cwde}";
3783 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3786 [(set_attr "type" "imovx")
3787 (set_attr "mode" "SI")
3788 (set (attr "prefix_0f")
3789 ;; movsx is short decodable while cwtl is vector decoded.
3790 (if_then_else (and (eq_attr "cpu" "!k6")
3791 (eq_attr "alternative" "0"))
3793 (const_string "1")))
3795 (if_then_else (eq_attr "prefix_0f" "0")
3797 (const_string "1")))])
3799 (define_insn "extendqisi2"
3800 [(set (match_operand:SI 0 "register_operand" "=r")
3801 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3803 "movs{bl|x}\t{%1, %0|%0, %1}"
3804 [(set_attr "type" "imovx")
3805 (set_attr "mode" "SI")])
3807 (define_insn "*extendqisi2_zext"
3808 [(set (match_operand:DI 0 "register_operand" "=r")
3810 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3812 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3813 [(set_attr "type" "imovx")
3814 (set_attr "mode" "SI")])
3816 (define_insn "extendqihi2"
3817 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3818 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3821 switch (get_attr_prefix_0f (insn))
3824 return "{cbtw|cbw}";
3826 return "movs{bw|x}\t{%1, %0|%0, %1}";
3829 [(set_attr "type" "imovx")
3830 (set_attr "mode" "HI")
3831 (set (attr "prefix_0f")
3832 ;; movsx is short decodable while cwtl is vector decoded.
3833 (if_then_else (and (eq_attr "cpu" "!k6")
3834 (eq_attr "alternative" "0"))
3836 (const_string "1")))
3838 (if_then_else (eq_attr "prefix_0f" "0")
3840 (const_string "1")))])
3842 ;; Conversions between float and double.
3844 ;; These are all no-ops in the model used for the 80387.
3845 ;; So just emit moves.
3847 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3849 [(set (match_operand:DF 0 "push_operand" "")
3850 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3852 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3853 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3856 [(set (match_operand:XF 0 "push_operand" "")
3857 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3859 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3860 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3861 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3863 (define_expand "extendsfdf2"
3864 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3865 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3866 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3868 /* ??? Needed for compress_float_constant since all fp constants
3869 are TARGET_LEGITIMATE_CONSTANT_P. */
3870 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3872 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3873 && standard_80387_constant_p (operands[1]) > 0)
3875 operands[1] = simplify_const_unary_operation
3876 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3877 emit_move_insn_1 (operands[0], operands[1]);
3880 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3884 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3886 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3888 We do the conversion post reload to avoid producing of 128bit spills
3889 that might lead to ICE on 32bit target. The sequence unlikely combine
3892 [(set (match_operand:DF 0 "register_operand" "")
3894 (match_operand:SF 1 "nonimmediate_operand" "")))]
3895 "TARGET_USE_VECTOR_FP_CONVERTS
3896 && optimize_insn_for_speed_p ()
3897 && reload_completed && SSE_REG_P (operands[0])"
3902 (parallel [(const_int 0) (const_int 1)]))))]
3904 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3905 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3906 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3907 Try to avoid move when unpacking can be done in source. */
3908 if (REG_P (operands[1]))
3910 /* If it is unsafe to overwrite upper half of source, we need
3911 to move to destination and unpack there. */
3912 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3913 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3914 && true_regnum (operands[0]) != true_regnum (operands[1]))
3916 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3917 emit_move_insn (tmp, operands[1]);
3920 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3921 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3925 emit_insn (gen_vec_setv4sf_0 (operands[3],
3926 CONST0_RTX (V4SFmode), operands[1]));
3929 (define_insn "*extendsfdf2_mixed"
3930 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3932 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3933 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3935 switch (which_alternative)
3939 return output_387_reg_move (insn, operands);
3942 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3948 [(set_attr "type" "fmov,fmov,ssecvt")
3949 (set_attr "prefix" "orig,orig,maybe_vex")
3950 (set_attr "mode" "SF,XF,DF")])
3952 (define_insn "*extendsfdf2_sse"
3953 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3954 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3955 "TARGET_SSE2 && TARGET_SSE_MATH"
3956 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3957 [(set_attr "type" "ssecvt")
3958 (set_attr "prefix" "maybe_vex")
3959 (set_attr "mode" "DF")])
3961 (define_insn "*extendsfdf2_i387"
3962 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3963 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3965 "* return output_387_reg_move (insn, operands);"
3966 [(set_attr "type" "fmov")
3967 (set_attr "mode" "SF,XF")])
3969 (define_expand "extend<mode>xf2"
3970 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3971 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3974 /* ??? Needed for compress_float_constant since all fp constants
3975 are TARGET_LEGITIMATE_CONSTANT_P. */
3976 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3978 if (standard_80387_constant_p (operands[1]) > 0)
3980 operands[1] = simplify_const_unary_operation
3981 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3982 emit_move_insn_1 (operands[0], operands[1]);
3985 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3989 (define_insn "*extend<mode>xf2_i387"
3990 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3992 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3994 "* return output_387_reg_move (insn, operands);"
3995 [(set_attr "type" "fmov")
3996 (set_attr "mode" "<MODE>,XF")])
3998 ;; %%% This seems bad bad news.
3999 ;; This cannot output into an f-reg because there is no way to be sure
4000 ;; of truncating in that case. Otherwise this is just like a simple move
4001 ;; insn. So we pretend we can output to a reg in order to get better
4002 ;; register preferencing, but we really use a stack slot.
4004 ;; Conversion from DFmode to SFmode.
4006 (define_expand "truncdfsf2"
4007 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4009 (match_operand:DF 1 "nonimmediate_operand" "")))]
4010 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4012 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4014 else if (flag_unsafe_math_optimizations)
4018 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4019 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4024 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4026 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4028 We do the conversion post reload to avoid producing of 128bit spills
4029 that might lead to ICE on 32bit target. The sequence unlikely combine
4032 [(set (match_operand:SF 0 "register_operand" "")
4034 (match_operand:DF 1 "nonimmediate_operand" "")))]
4035 "TARGET_USE_VECTOR_FP_CONVERTS
4036 && optimize_insn_for_speed_p ()
4037 && reload_completed && SSE_REG_P (operands[0])"
4040 (float_truncate:V2SF
4044 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4045 operands[3] = CONST0_RTX (V2SFmode);
4046 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4047 /* Use movsd for loading from memory, unpcklpd for registers.
4048 Try to avoid move when unpacking can be done in source, or SSE3
4049 movddup is available. */
4050 if (REG_P (operands[1]))
4053 && true_regnum (operands[0]) != true_regnum (operands[1])
4054 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4055 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4057 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4058 emit_move_insn (tmp, operands[1]);
4061 else if (!TARGET_SSE3)
4062 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4063 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4066 emit_insn (gen_sse2_loadlpd (operands[4],
4067 CONST0_RTX (V2DFmode), operands[1]));
4070 (define_expand "truncdfsf2_with_temp"
4071 [(parallel [(set (match_operand:SF 0 "" "")
4072 (float_truncate:SF (match_operand:DF 1 "" "")))
4073 (clobber (match_operand:SF 2 "" ""))])])
4075 (define_insn "*truncdfsf_fast_mixed"
4076 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4078 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4079 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4081 switch (which_alternative)
4084 return output_387_reg_move (insn, operands);
4086 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4091 [(set_attr "type" "fmov,ssecvt")
4092 (set_attr "prefix" "orig,maybe_vex")
4093 (set_attr "mode" "SF")])
4095 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4096 ;; because nothing we do here is unsafe.
4097 (define_insn "*truncdfsf_fast_sse"
4098 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4100 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4101 "TARGET_SSE2 && TARGET_SSE_MATH"
4102 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4103 [(set_attr "type" "ssecvt")
4104 (set_attr "prefix" "maybe_vex")
4105 (set_attr "mode" "SF")])
4107 (define_insn "*truncdfsf_fast_i387"
4108 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4110 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4111 "TARGET_80387 && flag_unsafe_math_optimizations"
4112 "* return output_387_reg_move (insn, operands);"
4113 [(set_attr "type" "fmov")
4114 (set_attr "mode" "SF")])
4116 (define_insn "*truncdfsf_mixed"
4117 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4119 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4120 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4121 "TARGET_MIX_SSE_I387"
4123 switch (which_alternative)
4126 return output_387_reg_move (insn, operands);
4128 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4134 [(set_attr "isa" "*,sse2,*,*,*")
4135 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4136 (set_attr "unit" "*,*,i387,i387,i387")
4137 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4138 (set_attr "mode" "SF")])
4140 (define_insn "*truncdfsf_i387"
4141 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4143 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4144 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4147 switch (which_alternative)
4150 return output_387_reg_move (insn, operands);
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4160 (define_insn "*truncdfsf2_i387_1"
4161 [(set (match_operand:SF 0 "memory_operand" "=m")
4163 (match_operand:DF 1 "register_operand" "f")))]
4165 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4166 && !TARGET_MIX_SSE_I387"
4167 "* return output_387_reg_move (insn, operands);"
4168 [(set_attr "type" "fmov")
4169 (set_attr "mode" "SF")])
4172 [(set (match_operand:SF 0 "register_operand" "")
4174 (match_operand:DF 1 "fp_register_operand" "")))
4175 (clobber (match_operand 2 "" ""))]
4177 [(set (match_dup 2) (match_dup 1))
4178 (set (match_dup 0) (match_dup 2))]
4179 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4181 ;; Conversion from XFmode to {SF,DF}mode
4183 (define_expand "truncxf<mode>2"
4184 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4185 (float_truncate:MODEF
4186 (match_operand:XF 1 "register_operand" "")))
4187 (clobber (match_dup 2))])]
4190 if (flag_unsafe_math_optimizations)
4192 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4193 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4194 if (reg != operands[0])
4195 emit_move_insn (operands[0], reg);
4199 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4202 (define_insn "*truncxfsf2_mixed"
4203 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4205 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4206 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4209 gcc_assert (!which_alternative);
4210 return output_387_reg_move (insn, operands);
4212 [(set_attr "type" "fmov,multi,multi,multi")
4213 (set_attr "unit" "*,i387,i387,i387")
4214 (set_attr "mode" "SF")])
4216 (define_insn "*truncxfdf2_mixed"
4217 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4219 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4220 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4223 gcc_assert (!which_alternative);
4224 return output_387_reg_move (insn, operands);
4226 [(set_attr "isa" "*,*,sse2,*")
4227 (set_attr "type" "fmov,multi,multi,multi")
4228 (set_attr "unit" "*,i387,i387,i387")
4229 (set_attr "mode" "DF")])
4231 (define_insn "truncxf<mode>2_i387_noop"
4232 [(set (match_operand:MODEF 0 "register_operand" "=f")
4233 (float_truncate:MODEF
4234 (match_operand:XF 1 "register_operand" "f")))]
4235 "TARGET_80387 && flag_unsafe_math_optimizations"
4236 "* return output_387_reg_move (insn, operands);"
4237 [(set_attr "type" "fmov")
4238 (set_attr "mode" "<MODE>")])
4240 (define_insn "*truncxf<mode>2_i387"
4241 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4242 (float_truncate:MODEF
4243 (match_operand:XF 1 "register_operand" "f")))]
4245 "* return output_387_reg_move (insn, operands);"
4246 [(set_attr "type" "fmov")
4247 (set_attr "mode" "<MODE>")])
4250 [(set (match_operand:MODEF 0 "register_operand" "")
4251 (float_truncate:MODEF
4252 (match_operand:XF 1 "register_operand" "")))
4253 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4254 "TARGET_80387 && reload_completed"
4255 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4256 (set (match_dup 0) (match_dup 2))])
4259 [(set (match_operand:MODEF 0 "memory_operand" "")
4260 (float_truncate:MODEF
4261 (match_operand:XF 1 "register_operand" "")))
4262 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4264 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4266 ;; Signed conversion to DImode.
4268 (define_expand "fix_truncxfdi2"
4269 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4270 (fix:DI (match_operand:XF 1 "register_operand" "")))
4271 (clobber (reg:CC FLAGS_REG))])]
4276 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4281 (define_expand "fix_trunc<mode>di2"
4282 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4283 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4284 (clobber (reg:CC FLAGS_REG))])]
4285 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4288 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4290 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4293 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4295 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4296 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4297 if (out != operands[0])
4298 emit_move_insn (operands[0], out);
4303 ;; Signed conversion to SImode.
4305 (define_expand "fix_truncxfsi2"
4306 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4307 (fix:SI (match_operand:XF 1 "register_operand" "")))
4308 (clobber (reg:CC FLAGS_REG))])]
4313 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4318 (define_expand "fix_trunc<mode>si2"
4319 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4320 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4321 (clobber (reg:CC FLAGS_REG))])]
4322 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4325 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4327 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4330 if (SSE_FLOAT_MODE_P (<MODE>mode))
4332 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4333 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4334 if (out != operands[0])
4335 emit_move_insn (operands[0], out);
4340 ;; Signed conversion to HImode.
4342 (define_expand "fix_trunc<mode>hi2"
4343 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4344 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4345 (clobber (reg:CC FLAGS_REG))])]
4347 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4351 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4356 ;; Unsigned conversion to SImode.
4358 (define_expand "fixuns_trunc<mode>si2"
4360 [(set (match_operand:SI 0 "register_operand" "")
4362 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4364 (clobber (match_scratch:<ssevecmode> 3 ""))
4365 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4366 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4368 enum machine_mode mode = <MODE>mode;
4369 enum machine_mode vecmode = <ssevecmode>mode;
4370 REAL_VALUE_TYPE TWO31r;
4373 if (optimize_insn_for_size_p ())
4376 real_ldexp (&TWO31r, &dconst1, 31);
4377 two31 = const_double_from_real_value (TWO31r, mode);
4378 two31 = ix86_build_const_vector (vecmode, true, two31);
4379 operands[2] = force_reg (vecmode, two31);
4382 (define_insn_and_split "*fixuns_trunc<mode>_1"
4383 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4385 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4386 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4387 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4388 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4389 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4390 && optimize_function_for_speed_p (cfun)"
4392 "&& reload_completed"
4395 ix86_split_convert_uns_si_sse (operands);
4399 ;; Unsigned conversion to HImode.
4400 ;; Without these patterns, we'll try the unsigned SI conversion which
4401 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4403 (define_expand "fixuns_trunc<mode>hi2"
4405 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4406 (set (match_operand:HI 0 "nonimmediate_operand" "")
4407 (subreg:HI (match_dup 2) 0))]
4408 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4409 "operands[2] = gen_reg_rtx (SImode);")
4411 ;; When SSE is available, it is always faster to use it!
4412 (define_insn "fix_trunc<mode>di_sse"
4413 [(set (match_operand:DI 0 "register_operand" "=r,r")
4414 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4415 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4416 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4417 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4418 [(set_attr "type" "sseicvt")
4419 (set_attr "prefix" "maybe_vex")
4420 (set_attr "prefix_rex" "1")
4421 (set_attr "mode" "<MODE>")
4422 (set_attr "athlon_decode" "double,vector")
4423 (set_attr "amdfam10_decode" "double,double")
4424 (set_attr "bdver1_decode" "double,double")])
4426 (define_insn "fix_trunc<mode>si_sse"
4427 [(set (match_operand:SI 0 "register_operand" "=r,r")
4428 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4429 "SSE_FLOAT_MODE_P (<MODE>mode)
4430 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4431 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4432 [(set_attr "type" "sseicvt")
4433 (set_attr "prefix" "maybe_vex")
4434 (set_attr "mode" "<MODE>")
4435 (set_attr "athlon_decode" "double,vector")
4436 (set_attr "amdfam10_decode" "double,double")
4437 (set_attr "bdver1_decode" "double,double")])
4439 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4441 [(set (match_operand:MODEF 0 "register_operand" "")
4442 (match_operand:MODEF 1 "memory_operand" ""))
4443 (set (match_operand:SWI48x 2 "register_operand" "")
4444 (fix:SWI48x (match_dup 0)))]
4445 "TARGET_SHORTEN_X87_SSE
4446 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4447 && peep2_reg_dead_p (2, operands[0])"
4448 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4450 ;; Avoid vector decoded forms of the instruction.
4452 [(match_scratch:DF 2 "x")
4453 (set (match_operand:SWI48x 0 "register_operand" "")
4454 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4455 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4456 [(set (match_dup 2) (match_dup 1))
4457 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4460 [(match_scratch:SF 2 "x")
4461 (set (match_operand:SWI48x 0 "register_operand" "")
4462 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4463 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4464 [(set (match_dup 2) (match_dup 1))
4465 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4467 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4468 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4469 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4470 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4472 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4473 && (TARGET_64BIT || <MODE>mode != DImode))
4475 && can_create_pseudo_p ()"
4480 if (memory_operand (operands[0], VOIDmode))
4481 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4484 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4485 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4491 [(set_attr "type" "fisttp")
4492 (set_attr "mode" "<MODE>")])
4494 (define_insn "fix_trunc<mode>_i387_fisttp"
4495 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4496 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4497 (clobber (match_scratch:XF 2 "=&1f"))]
4498 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4500 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4501 && (TARGET_64BIT || <MODE>mode != DImode))
4502 && TARGET_SSE_MATH)"
4503 "* return output_fix_trunc (insn, operands, true);"
4504 [(set_attr "type" "fisttp")
4505 (set_attr "mode" "<MODE>")])
4507 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4508 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4509 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4510 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4511 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4512 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4514 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4515 && (TARGET_64BIT || <MODE>mode != DImode))
4516 && TARGET_SSE_MATH)"
4518 [(set_attr "type" "fisttp")
4519 (set_attr "mode" "<MODE>")])
4522 [(set (match_operand:SWI248x 0 "register_operand" "")
4523 (fix:SWI248x (match_operand 1 "register_operand" "")))
4524 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4525 (clobber (match_scratch 3 ""))]
4527 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4528 (clobber (match_dup 3))])
4529 (set (match_dup 0) (match_dup 2))])
4532 [(set (match_operand:SWI248x 0 "memory_operand" "")
4533 (fix:SWI248x (match_operand 1 "register_operand" "")))
4534 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4535 (clobber (match_scratch 3 ""))]
4537 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4538 (clobber (match_dup 3))])])
4540 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4541 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4542 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4543 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4544 ;; function in i386.c.
4545 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4546 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4547 (fix:SWI248x (match_operand 1 "register_operand" "")))
4548 (clobber (reg:CC FLAGS_REG))]
4549 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4551 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4552 && (TARGET_64BIT || <MODE>mode != DImode))
4553 && can_create_pseudo_p ()"
4558 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4560 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4561 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4562 if (memory_operand (operands[0], VOIDmode))
4563 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4564 operands[2], operands[3]));
4567 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4568 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4569 operands[2], operands[3],
4574 [(set_attr "type" "fistp")
4575 (set_attr "i387_cw" "trunc")
4576 (set_attr "mode" "<MODE>")])
4578 (define_insn "fix_truncdi_i387"
4579 [(set (match_operand:DI 0 "memory_operand" "=m")
4580 (fix:DI (match_operand 1 "register_operand" "f")))
4581 (use (match_operand:HI 2 "memory_operand" "m"))
4582 (use (match_operand:HI 3 "memory_operand" "m"))
4583 (clobber (match_scratch:XF 4 "=&1f"))]
4584 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4586 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4587 "* return output_fix_trunc (insn, operands, false);"
4588 [(set_attr "type" "fistp")
4589 (set_attr "i387_cw" "trunc")
4590 (set_attr "mode" "DI")])
4592 (define_insn "fix_truncdi_i387_with_temp"
4593 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4594 (fix:DI (match_operand 1 "register_operand" "f,f")))
4595 (use (match_operand:HI 2 "memory_operand" "m,m"))
4596 (use (match_operand:HI 3 "memory_operand" "m,m"))
4597 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4598 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4599 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4601 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4603 [(set_attr "type" "fistp")
4604 (set_attr "i387_cw" "trunc")
4605 (set_attr "mode" "DI")])
4608 [(set (match_operand:DI 0 "register_operand" "")
4609 (fix:DI (match_operand 1 "register_operand" "")))
4610 (use (match_operand:HI 2 "memory_operand" ""))
4611 (use (match_operand:HI 3 "memory_operand" ""))
4612 (clobber (match_operand:DI 4 "memory_operand" ""))
4613 (clobber (match_scratch 5 ""))]
4615 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4618 (clobber (match_dup 5))])
4619 (set (match_dup 0) (match_dup 4))])
4622 [(set (match_operand:DI 0 "memory_operand" "")
4623 (fix:DI (match_operand 1 "register_operand" "")))
4624 (use (match_operand:HI 2 "memory_operand" ""))
4625 (use (match_operand:HI 3 "memory_operand" ""))
4626 (clobber (match_operand:DI 4 "memory_operand" ""))
4627 (clobber (match_scratch 5 ""))]
4629 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4632 (clobber (match_dup 5))])])
4634 (define_insn "fix_trunc<mode>_i387"
4635 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4636 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4637 (use (match_operand:HI 2 "memory_operand" "m"))
4638 (use (match_operand:HI 3 "memory_operand" "m"))]
4639 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4641 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4642 "* return output_fix_trunc (insn, operands, false);"
4643 [(set_attr "type" "fistp")
4644 (set_attr "i387_cw" "trunc")
4645 (set_attr "mode" "<MODE>")])
4647 (define_insn "fix_trunc<mode>_i387_with_temp"
4648 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4649 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4650 (use (match_operand:HI 2 "memory_operand" "m,m"))
4651 (use (match_operand:HI 3 "memory_operand" "m,m"))
4652 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4653 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4655 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4657 [(set_attr "type" "fistp")
4658 (set_attr "i387_cw" "trunc")
4659 (set_attr "mode" "<MODE>")])
4662 [(set (match_operand:SWI24 0 "register_operand" "")
4663 (fix:SWI24 (match_operand 1 "register_operand" "")))
4664 (use (match_operand:HI 2 "memory_operand" ""))
4665 (use (match_operand:HI 3 "memory_operand" ""))
4666 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4668 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4670 (use (match_dup 3))])
4671 (set (match_dup 0) (match_dup 4))])
4674 [(set (match_operand:SWI24 0 "memory_operand" "")
4675 (fix:SWI24 (match_operand 1 "register_operand" "")))
4676 (use (match_operand:HI 2 "memory_operand" ""))
4677 (use (match_operand:HI 3 "memory_operand" ""))
4678 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4680 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4682 (use (match_dup 3))])])
4684 (define_insn "x86_fnstcw_1"
4685 [(set (match_operand:HI 0 "memory_operand" "=m")
4686 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4689 [(set (attr "length")
4690 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4691 (set_attr "mode" "HI")
4692 (set_attr "unit" "i387")
4693 (set_attr "bdver1_decode" "vector")])
4695 (define_insn "x86_fldcw_1"
4696 [(set (reg:HI FPCR_REG)
4697 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4700 [(set (attr "length")
4701 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4702 (set_attr "mode" "HI")
4703 (set_attr "unit" "i387")
4704 (set_attr "athlon_decode" "vector")
4705 (set_attr "amdfam10_decode" "vector")
4706 (set_attr "bdver1_decode" "vector")])
4708 ;; Conversion between fixed point and floating point.
4710 ;; Even though we only accept memory inputs, the backend _really_
4711 ;; wants to be able to do this between registers.
4713 (define_expand "floathi<mode>2"
4714 [(set (match_operand:X87MODEF 0 "register_operand" "")
4715 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4717 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4718 || TARGET_MIX_SSE_I387)")
4720 ;; Pre-reload splitter to add memory clobber to the pattern.
4721 (define_insn_and_split "*floathi<mode>2_1"
4722 [(set (match_operand:X87MODEF 0 "register_operand" "")
4723 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4726 || TARGET_MIX_SSE_I387)
4727 && can_create_pseudo_p ()"
4730 [(parallel [(set (match_dup 0)
4731 (float:X87MODEF (match_dup 1)))
4732 (clobber (match_dup 2))])]
4733 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4735 (define_insn "*floathi<mode>2_i387_with_temp"
4736 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4737 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4738 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4740 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4741 || TARGET_MIX_SSE_I387)"
4743 [(set_attr "type" "fmov,multi")
4744 (set_attr "mode" "<MODE>")
4745 (set_attr "unit" "*,i387")
4746 (set_attr "fp_int_src" "true")])
4748 (define_insn "*floathi<mode>2_i387"
4749 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4750 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4753 || TARGET_MIX_SSE_I387)"
4755 [(set_attr "type" "fmov")
4756 (set_attr "mode" "<MODE>")
4757 (set_attr "fp_int_src" "true")])
4760 [(set (match_operand:X87MODEF 0 "register_operand" "")
4761 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4762 (clobber (match_operand:HI 2 "memory_operand" ""))]
4764 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4765 || TARGET_MIX_SSE_I387)
4766 && reload_completed"
4767 [(set (match_dup 2) (match_dup 1))
4768 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4771 [(set (match_operand:X87MODEF 0 "register_operand" "")
4772 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4773 (clobber (match_operand:HI 2 "memory_operand" ""))]
4775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4776 || TARGET_MIX_SSE_I387)
4777 && reload_completed"
4778 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4780 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4781 [(set (match_operand:X87MODEF 0 "register_operand" "")
4783 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4785 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4786 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4788 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4789 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4790 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4792 rtx reg = gen_reg_rtx (XFmode);
4793 rtx (*insn)(rtx, rtx);
4795 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4797 if (<X87MODEF:MODE>mode == SFmode)
4798 insn = gen_truncxfsf2;
4799 else if (<X87MODEF:MODE>mode == DFmode)
4800 insn = gen_truncxfdf2;
4804 emit_insn (insn (operands[0], reg));
4809 ;; Pre-reload splitter to add memory clobber to the pattern.
4810 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4811 [(set (match_operand:X87MODEF 0 "register_operand" "")
4812 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4814 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4815 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4816 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4817 || TARGET_MIX_SSE_I387))
4818 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4819 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4820 && ((<SWI48x:MODE>mode == SImode
4821 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4822 && optimize_function_for_speed_p (cfun)
4823 && flag_trapping_math)
4824 || !(TARGET_INTER_UNIT_CONVERSIONS
4825 || optimize_function_for_size_p (cfun)))))
4826 && can_create_pseudo_p ()"
4829 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4830 (clobber (match_dup 2))])]
4832 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4834 /* Avoid store forwarding (partial memory) stall penalty
4835 by passing DImode value through XMM registers. */
4836 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4837 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4838 && optimize_function_for_speed_p (cfun))
4840 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4847 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4848 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4850 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4851 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4852 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4853 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4855 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4856 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4857 (set_attr "unit" "*,i387,*,*,*")
4858 (set_attr "athlon_decode" "*,*,double,direct,double")
4859 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4860 (set_attr "bdver1_decode" "*,*,double,direct,double")
4861 (set_attr "fp_int_src" "true")])
4863 (define_insn "*floatsi<mode>2_vector_mixed"
4864 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4865 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4866 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4867 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4871 [(set_attr "type" "fmov,sseicvt")
4872 (set_attr "mode" "<MODE>,<ssevecmode>")
4873 (set_attr "unit" "i387,*")
4874 (set_attr "athlon_decode" "*,direct")
4875 (set_attr "amdfam10_decode" "*,double")
4876 (set_attr "bdver1_decode" "*,direct")
4877 (set_attr "fp_int_src" "true")])
4879 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4880 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4882 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4883 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4884 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4885 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4887 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4888 (set_attr "mode" "<MODEF:MODE>")
4889 (set_attr "unit" "*,i387,*,*")
4890 (set_attr "athlon_decode" "*,*,double,direct")
4891 (set_attr "amdfam10_decode" "*,*,vector,double")
4892 (set_attr "bdver1_decode" "*,*,double,direct")
4893 (set_attr "fp_int_src" "true")])
4896 [(set (match_operand:MODEF 0 "register_operand" "")
4897 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4898 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4899 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4900 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4901 && TARGET_INTER_UNIT_CONVERSIONS
4903 && (SSE_REG_P (operands[0])
4904 || (GET_CODE (operands[0]) == SUBREG
4905 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4906 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4909 [(set (match_operand:MODEF 0 "register_operand" "")
4910 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4911 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4912 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4913 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4914 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4916 && (SSE_REG_P (operands[0])
4917 || (GET_CODE (operands[0]) == SUBREG
4918 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4919 [(set (match_dup 2) (match_dup 1))
4920 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4922 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4923 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4925 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4926 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4927 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4928 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4931 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4932 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4933 [(set_attr "type" "fmov,sseicvt,sseicvt")
4934 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4935 (set_attr "mode" "<MODEF:MODE>")
4936 (set (attr "prefix_rex")
4938 (and (eq_attr "prefix" "maybe_vex")
4939 (match_test "<SWI48x:MODE>mode == DImode"))
4941 (const_string "*")))
4942 (set_attr "unit" "i387,*,*")
4943 (set_attr "athlon_decode" "*,double,direct")
4944 (set_attr "amdfam10_decode" "*,vector,double")
4945 (set_attr "bdver1_decode" "*,double,direct")
4946 (set_attr "fp_int_src" "true")])
4948 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4949 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4951 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4952 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4953 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4954 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4957 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4958 [(set_attr "type" "fmov,sseicvt")
4959 (set_attr "prefix" "orig,maybe_vex")
4960 (set_attr "mode" "<MODEF:MODE>")
4961 (set (attr "prefix_rex")
4963 (and (eq_attr "prefix" "maybe_vex")
4964 (match_test "<SWI48x:MODE>mode == DImode"))
4966 (const_string "*")))
4967 (set_attr "athlon_decode" "*,direct")
4968 (set_attr "amdfam10_decode" "*,double")
4969 (set_attr "bdver1_decode" "*,direct")
4970 (set_attr "fp_int_src" "true")])
4972 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4973 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4975 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4976 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4977 "TARGET_SSE2 && TARGET_SSE_MATH
4978 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4980 [(set_attr "type" "sseicvt")
4981 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4982 (set_attr "athlon_decode" "double,direct,double")
4983 (set_attr "amdfam10_decode" "vector,double,double")
4984 (set_attr "bdver1_decode" "double,direct,double")
4985 (set_attr "fp_int_src" "true")])
4987 (define_insn "*floatsi<mode>2_vector_sse"
4988 [(set (match_operand:MODEF 0 "register_operand" "=x")
4989 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4990 "TARGET_SSE2 && TARGET_SSE_MATH
4991 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4993 [(set_attr "type" "sseicvt")
4994 (set_attr "mode" "<MODE>")
4995 (set_attr "athlon_decode" "direct")
4996 (set_attr "amdfam10_decode" "double")
4997 (set_attr "bdver1_decode" "direct")
4998 (set_attr "fp_int_src" "true")])
5001 [(set (match_operand:MODEF 0 "register_operand" "")
5002 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5003 (clobber (match_operand:SI 2 "memory_operand" ""))]
5004 "TARGET_SSE2 && TARGET_SSE_MATH
5005 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5007 && (SSE_REG_P (operands[0])
5008 || (GET_CODE (operands[0]) == SUBREG
5009 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5012 rtx op1 = operands[1];
5014 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5016 if (GET_CODE (op1) == SUBREG)
5017 op1 = SUBREG_REG (op1);
5019 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5021 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5022 emit_insn (gen_sse2_loadld (operands[4],
5023 CONST0_RTX (V4SImode), operands[1]));
5025 /* We can ignore possible trapping value in the
5026 high part of SSE register for non-trapping math. */
5027 else if (SSE_REG_P (op1) && !flag_trapping_math)
5028 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5031 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5032 emit_move_insn (operands[2], operands[1]);
5033 emit_insn (gen_sse2_loadld (operands[4],
5034 CONST0_RTX (V4SImode), operands[2]));
5036 if (<ssevecmode>mode == V4SFmode)
5037 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5039 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5044 [(set (match_operand:MODEF 0 "register_operand" "")
5045 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5046 (clobber (match_operand:SI 2 "memory_operand" ""))]
5047 "TARGET_SSE2 && TARGET_SSE_MATH
5048 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5050 && (SSE_REG_P (operands[0])
5051 || (GET_CODE (operands[0]) == SUBREG
5052 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5055 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5057 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5059 emit_insn (gen_sse2_loadld (operands[4],
5060 CONST0_RTX (V4SImode), operands[1]));
5061 if (<ssevecmode>mode == V4SFmode)
5062 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5064 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5069 [(set (match_operand:MODEF 0 "register_operand" "")
5070 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5071 "TARGET_SSE2 && TARGET_SSE_MATH
5072 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5074 && (SSE_REG_P (operands[0])
5075 || (GET_CODE (operands[0]) == SUBREG
5076 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5079 rtx op1 = operands[1];
5081 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5083 if (GET_CODE (op1) == SUBREG)
5084 op1 = SUBREG_REG (op1);
5086 if (GENERAL_REG_P (op1))
5088 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5089 if (TARGET_INTER_UNIT_MOVES)
5090 emit_insn (gen_sse2_loadld (operands[4],
5091 CONST0_RTX (V4SImode), operands[1]));
5094 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5096 emit_insn (gen_sse2_loadld (operands[4],
5097 CONST0_RTX (V4SImode), operands[5]));
5098 ix86_free_from_memory (GET_MODE (operands[1]));
5101 /* We can ignore possible trapping value in the
5102 high part of SSE register for non-trapping math. */
5103 else if (SSE_REG_P (op1) && !flag_trapping_math)
5104 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5107 if (<ssevecmode>mode == V4SFmode)
5108 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5110 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5115 [(set (match_operand:MODEF 0 "register_operand" "")
5116 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5117 "TARGET_SSE2 && TARGET_SSE_MATH
5118 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5120 && (SSE_REG_P (operands[0])
5121 || (GET_CODE (operands[0]) == SUBREG
5122 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5125 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5127 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5129 emit_insn (gen_sse2_loadld (operands[4],
5130 CONST0_RTX (V4SImode), operands[1]));
5131 if (<ssevecmode>mode == V4SFmode)
5132 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5134 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5138 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5139 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5141 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5142 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5143 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5144 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5146 [(set_attr "type" "sseicvt")
5147 (set_attr "mode" "<MODEF:MODE>")
5148 (set_attr "athlon_decode" "double,direct")
5149 (set_attr "amdfam10_decode" "vector,double")
5150 (set_attr "bdver1_decode" "double,direct")
5151 (set_attr "fp_int_src" "true")])
5153 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5154 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5156 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5157 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5158 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5159 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5160 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5161 [(set_attr "type" "sseicvt")
5162 (set_attr "prefix" "maybe_vex")
5163 (set_attr "mode" "<MODEF:MODE>")
5164 (set (attr "prefix_rex")
5166 (and (eq_attr "prefix" "maybe_vex")
5167 (match_test "<SWI48x:MODE>mode == DImode"))
5169 (const_string "*")))
5170 (set_attr "athlon_decode" "double,direct")
5171 (set_attr "amdfam10_decode" "vector,double")
5172 (set_attr "bdver1_decode" "double,direct")
5173 (set_attr "fp_int_src" "true")])
5176 [(set (match_operand:MODEF 0 "register_operand" "")
5177 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5178 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5179 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5180 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5181 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5183 && (SSE_REG_P (operands[0])
5184 || (GET_CODE (operands[0]) == SUBREG
5185 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5186 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5188 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5189 [(set (match_operand:MODEF 0 "register_operand" "=x")
5191 (match_operand:SWI48x 1 "memory_operand" "m")))]
5192 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5193 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5194 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5195 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5196 [(set_attr "type" "sseicvt")
5197 (set_attr "prefix" "maybe_vex")
5198 (set_attr "mode" "<MODEF:MODE>")
5199 (set (attr "prefix_rex")
5201 (and (eq_attr "prefix" "maybe_vex")
5202 (match_test "<SWI48x:MODE>mode == DImode"))
5204 (const_string "*")))
5205 (set_attr "athlon_decode" "direct")
5206 (set_attr "amdfam10_decode" "double")
5207 (set_attr "bdver1_decode" "direct")
5208 (set_attr "fp_int_src" "true")])
5211 [(set (match_operand:MODEF 0 "register_operand" "")
5212 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5213 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5214 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5215 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5216 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5218 && (SSE_REG_P (operands[0])
5219 || (GET_CODE (operands[0]) == SUBREG
5220 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5221 [(set (match_dup 2) (match_dup 1))
5222 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5225 [(set (match_operand:MODEF 0 "register_operand" "")
5226 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5227 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5228 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5229 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5231 && (SSE_REG_P (operands[0])
5232 || (GET_CODE (operands[0]) == SUBREG
5233 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5234 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5236 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5237 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5239 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5240 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5242 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5246 [(set_attr "type" "fmov,multi")
5247 (set_attr "mode" "<X87MODEF:MODE>")
5248 (set_attr "unit" "*,i387")
5249 (set_attr "fp_int_src" "true")])
5251 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5252 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5254 (match_operand:SWI48x 1 "memory_operand" "m")))]
5256 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5258 [(set_attr "type" "fmov")
5259 (set_attr "mode" "<X87MODEF:MODE>")
5260 (set_attr "fp_int_src" "true")])
5263 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5264 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5265 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5267 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5268 && reload_completed"
5269 [(set (match_dup 2) (match_dup 1))
5270 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5273 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5274 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5275 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5277 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5278 && reload_completed"
5279 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5281 ;; Avoid store forwarding (partial memory) stall penalty
5282 ;; by passing DImode value through XMM registers. */
5284 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5285 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5287 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5288 (clobber (match_scratch:V4SI 3 "=X,x"))
5289 (clobber (match_scratch:V4SI 4 "=X,x"))
5290 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5291 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5292 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5293 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5295 [(set_attr "type" "multi")
5296 (set_attr "mode" "<X87MODEF:MODE>")
5297 (set_attr "unit" "i387")
5298 (set_attr "fp_int_src" "true")])
5301 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5302 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5303 (clobber (match_scratch:V4SI 3 ""))
5304 (clobber (match_scratch:V4SI 4 ""))
5305 (clobber (match_operand:DI 2 "memory_operand" ""))]
5306 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5307 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5308 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5309 && reload_completed"
5310 [(set (match_dup 2) (match_dup 3))
5311 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5313 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5314 Assemble the 64-bit DImode value in an xmm register. */
5315 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5316 gen_rtx_SUBREG (SImode, operands[1], 0)));
5317 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5318 gen_rtx_SUBREG (SImode, operands[1], 4)));
5319 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5322 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5326 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5327 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5328 (clobber (match_scratch:V4SI 3 ""))
5329 (clobber (match_scratch:V4SI 4 ""))
5330 (clobber (match_operand:DI 2 "memory_operand" ""))]
5331 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5332 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5333 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5334 && reload_completed"
5335 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5337 ;; Avoid store forwarding (partial memory) stall penalty by extending
5338 ;; SImode value to DImode through XMM register instead of pushing two
5339 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5340 ;; targets benefit from this optimization. Also note that fild
5341 ;; loads from memory only.
5343 (define_insn "*floatunssi<mode>2_1"
5344 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5345 (unsigned_float:X87MODEF
5346 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5347 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5348 (clobber (match_scratch:SI 3 "=X,x"))]
5350 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5353 [(set_attr "type" "multi")
5354 (set_attr "mode" "<MODE>")])
5357 [(set (match_operand:X87MODEF 0 "register_operand" "")
5358 (unsigned_float:X87MODEF
5359 (match_operand:SI 1 "register_operand" "")))
5360 (clobber (match_operand:DI 2 "memory_operand" ""))
5361 (clobber (match_scratch:SI 3 ""))]
5363 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5365 && reload_completed"
5366 [(set (match_dup 2) (match_dup 1))
5368 (float:X87MODEF (match_dup 2)))]
5369 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5372 [(set (match_operand:X87MODEF 0 "register_operand" "")
5373 (unsigned_float:X87MODEF
5374 (match_operand:SI 1 "memory_operand" "")))
5375 (clobber (match_operand:DI 2 "memory_operand" ""))
5376 (clobber (match_scratch:SI 3 ""))]
5378 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5380 && reload_completed"
5381 [(set (match_dup 2) (match_dup 3))
5383 (float:X87MODEF (match_dup 2)))]
5385 emit_move_insn (operands[3], operands[1]);
5386 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5389 (define_expand "floatunssi<mode>2"
5391 [(set (match_operand:X87MODEF 0 "register_operand" "")
5392 (unsigned_float:X87MODEF
5393 (match_operand:SI 1 "nonimmediate_operand" "")))
5394 (clobber (match_dup 2))
5395 (clobber (match_scratch:SI 3 ""))])]
5397 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5399 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5401 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5403 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5407 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5410 (define_expand "floatunsdisf2"
5411 [(use (match_operand:SF 0 "register_operand" ""))
5412 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5413 "TARGET_64BIT && TARGET_SSE_MATH"
5414 "x86_emit_floatuns (operands); DONE;")
5416 (define_expand "floatunsdidf2"
5417 [(use (match_operand:DF 0 "register_operand" ""))
5418 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5419 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5420 && TARGET_SSE2 && TARGET_SSE_MATH"
5423 x86_emit_floatuns (operands);
5425 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5429 ;; Load effective address instructions
5431 (define_insn_and_split "*lea<mode>"
5432 [(set (match_operand:SWI48 0 "register_operand" "=r")
5433 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5436 rtx addr = operands[1];
5438 if (SImode_address_operand (addr, VOIDmode))
5440 gcc_assert (TARGET_64BIT);
5441 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5444 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5446 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5449 ix86_split_lea_for_addr (operands, <MODE>mode);
5452 [(set_attr "type" "lea")
5455 (match_operand 1 "SImode_address_operand")
5457 (const_string "<MODE>")))])
5461 (define_expand "add<mode>3"
5462 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5463 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5464 (match_operand:SDWIM 2 "<general_operand>" "")))]
5466 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5468 (define_insn_and_split "*add<dwi>3_doubleword"
5469 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5471 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5472 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5473 (clobber (reg:CC FLAGS_REG))]
5474 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5477 [(parallel [(set (reg:CC FLAGS_REG)
5478 (unspec:CC [(match_dup 1) (match_dup 2)]
5481 (plus:DWIH (match_dup 1) (match_dup 2)))])
5482 (parallel [(set (match_dup 3)
5486 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5488 (clobber (reg:CC FLAGS_REG))])]
5489 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5491 (define_insn "*add<mode>3_cc"
5492 [(set (reg:CC FLAGS_REG)
5494 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5495 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5497 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5498 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5499 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5500 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5501 [(set_attr "type" "alu")
5502 (set_attr "mode" "<MODE>")])
5504 (define_insn "addqi3_cc"
5505 [(set (reg:CC FLAGS_REG)
5507 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5508 (match_operand:QI 2 "general_operand" "qn,qm")]
5510 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5511 (plus:QI (match_dup 1) (match_dup 2)))]
5512 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5513 "add{b}\t{%2, %0|%0, %2}"
5514 [(set_attr "type" "alu")
5515 (set_attr "mode" "QI")])
5517 (define_insn "*add<mode>_1"
5518 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5520 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5521 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5522 (clobber (reg:CC FLAGS_REG))]
5523 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5525 switch (get_attr_type (insn))
5531 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5532 if (operands[2] == const1_rtx)
5533 return "inc{<imodesuffix>}\t%0";
5536 gcc_assert (operands[2] == constm1_rtx);
5537 return "dec{<imodesuffix>}\t%0";
5541 /* For most processors, ADD is faster than LEA. This alternative
5542 was added to use ADD as much as possible. */
5543 if (which_alternative == 2)
5546 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5549 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5550 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5551 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5553 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5557 (cond [(eq_attr "alternative" "3")
5558 (const_string "lea")
5559 (match_operand:SWI48 2 "incdec_operand" "")
5560 (const_string "incdec")
5562 (const_string "alu")))
5563 (set (attr "length_immediate")
5565 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5567 (const_string "*")))
5568 (set_attr "mode" "<MODE>")])
5570 ;; It may seem that nonimmediate operand is proper one for operand 1.
5571 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5572 ;; we take care in ix86_binary_operator_ok to not allow two memory
5573 ;; operands so proper swapping will be done in reload. This allow
5574 ;; patterns constructed from addsi_1 to match.
5576 (define_insn "addsi_1_zext"
5577 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5579 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5580 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5581 (clobber (reg:CC FLAGS_REG))]
5582 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5584 switch (get_attr_type (insn))
5590 if (operands[2] == const1_rtx)
5591 return "inc{l}\t%k0";
5594 gcc_assert (operands[2] == constm1_rtx);
5595 return "dec{l}\t%k0";
5599 /* For most processors, ADD is faster than LEA. This alternative
5600 was added to use ADD as much as possible. */
5601 if (which_alternative == 1)
5604 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5607 if (x86_maybe_negate_const_int (&operands[2], SImode))
5608 return "sub{l}\t{%2, %k0|%k0, %2}";
5610 return "add{l}\t{%2, %k0|%k0, %2}";
5614 (cond [(eq_attr "alternative" "2")
5615 (const_string "lea")
5616 (match_operand:SI 2 "incdec_operand" "")
5617 (const_string "incdec")
5619 (const_string "alu")))
5620 (set (attr "length_immediate")
5622 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5624 (const_string "*")))
5625 (set_attr "mode" "SI")])
5627 (define_insn "*addhi_1"
5628 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5629 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5630 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5631 (clobber (reg:CC FLAGS_REG))]
5632 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5634 switch (get_attr_type (insn))
5640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5641 if (operands[2] == const1_rtx)
5642 return "inc{w}\t%0";
5645 gcc_assert (operands[2] == constm1_rtx);
5646 return "dec{w}\t%0";
5650 /* For most processors, ADD is faster than LEA. This alternative
5651 was added to use ADD as much as possible. */
5652 if (which_alternative == 2)
5655 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5658 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5659 if (x86_maybe_negate_const_int (&operands[2], HImode))
5660 return "sub{w}\t{%2, %0|%0, %2}";
5662 return "add{w}\t{%2, %0|%0, %2}";
5666 (cond [(eq_attr "alternative" "3")
5667 (const_string "lea")
5668 (match_operand:HI 2 "incdec_operand" "")
5669 (const_string "incdec")
5671 (const_string "alu")))
5672 (set (attr "length_immediate")
5674 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5676 (const_string "*")))
5677 (set_attr "mode" "HI,HI,HI,SI")])
5679 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5680 (define_insn "*addqi_1"
5681 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5682 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5683 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5684 (clobber (reg:CC FLAGS_REG))]
5685 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5687 bool widen = (which_alternative == 3 || which_alternative == 4);
5689 switch (get_attr_type (insn))
5695 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5696 if (operands[2] == const1_rtx)
5697 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5700 gcc_assert (operands[2] == constm1_rtx);
5701 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5705 /* For most processors, ADD is faster than LEA. These alternatives
5706 were added to use ADD as much as possible. */
5707 if (which_alternative == 2 || which_alternative == 4)
5710 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5713 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5714 if (x86_maybe_negate_const_int (&operands[2], QImode))
5717 return "sub{l}\t{%2, %k0|%k0, %2}";
5719 return "sub{b}\t{%2, %0|%0, %2}";
5722 return "add{l}\t{%k2, %k0|%k0, %k2}";
5724 return "add{b}\t{%2, %0|%0, %2}";
5728 (cond [(eq_attr "alternative" "5")
5729 (const_string "lea")
5730 (match_operand:QI 2 "incdec_operand" "")
5731 (const_string "incdec")
5733 (const_string "alu")))
5734 (set (attr "length_immediate")
5736 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5738 (const_string "*")))
5739 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5741 (define_insn "*addqi_1_slp"
5742 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5743 (plus:QI (match_dup 0)
5744 (match_operand:QI 1 "general_operand" "qn,qm")))
5745 (clobber (reg:CC FLAGS_REG))]
5746 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5747 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5749 switch (get_attr_type (insn))
5752 if (operands[1] == const1_rtx)
5753 return "inc{b}\t%0";
5756 gcc_assert (operands[1] == constm1_rtx);
5757 return "dec{b}\t%0";
5761 if (x86_maybe_negate_const_int (&operands[1], QImode))
5762 return "sub{b}\t{%1, %0|%0, %1}";
5764 return "add{b}\t{%1, %0|%0, %1}";
5768 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5769 (const_string "incdec")
5770 (const_string "alu1")))
5771 (set (attr "memory")
5772 (if_then_else (match_operand 1 "memory_operand" "")
5773 (const_string "load")
5774 (const_string "none")))
5775 (set_attr "mode" "QI")])
5777 ;; Split non destructive adds if we cannot use lea.
5779 [(set (match_operand:SWI48 0 "register_operand" "")
5780 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5781 (match_operand:SWI48 2 "nonmemory_operand" "")))
5782 (clobber (reg:CC FLAGS_REG))]
5783 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5784 [(set (match_dup 0) (match_dup 1))
5785 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5786 (clobber (reg:CC FLAGS_REG))])])
5788 ;; Convert add to the lea pattern to avoid flags dependency.
5790 [(set (match_operand:SWI 0 "register_operand" "")
5791 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5792 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5793 (clobber (reg:CC FLAGS_REG))]
5794 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5797 enum machine_mode mode = <MODE>mode;
5800 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5803 operands[0] = gen_lowpart (mode, operands[0]);
5804 operands[1] = gen_lowpart (mode, operands[1]);
5805 operands[2] = gen_lowpart (mode, operands[2]);
5808 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5810 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5814 ;; Convert add to the lea pattern to avoid flags dependency.
5816 [(set (match_operand:DI 0 "register_operand" "")
5818 (plus:SI (match_operand:SI 1 "register_operand" "")
5819 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5820 (clobber (reg:CC FLAGS_REG))]
5821 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5823 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5825 (define_insn "*add<mode>_2"
5826 [(set (reg FLAGS_REG)
5829 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5830 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5832 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5833 (plus:SWI (match_dup 1) (match_dup 2)))]
5834 "ix86_match_ccmode (insn, CCGOCmode)
5835 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5837 switch (get_attr_type (insn))
5840 if (operands[2] == const1_rtx)
5841 return "inc{<imodesuffix>}\t%0";
5844 gcc_assert (operands[2] == constm1_rtx);
5845 return "dec{<imodesuffix>}\t%0";
5849 if (which_alternative == 2)
5852 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5855 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5856 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5857 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5859 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5863 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5864 (const_string "incdec")
5865 (const_string "alu")))
5866 (set (attr "length_immediate")
5868 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5870 (const_string "*")))
5871 (set_attr "mode" "<MODE>")])
5873 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5874 (define_insn "*addsi_2_zext"
5875 [(set (reg FLAGS_REG)
5877 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5878 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5880 (set (match_operand:DI 0 "register_operand" "=r,r")
5881 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5882 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5883 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5885 switch (get_attr_type (insn))
5888 if (operands[2] == const1_rtx)
5889 return "inc{l}\t%k0";
5892 gcc_assert (operands[2] == constm1_rtx);
5893 return "dec{l}\t%k0";
5897 if (which_alternative == 1)
5900 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5903 if (x86_maybe_negate_const_int (&operands[2], SImode))
5904 return "sub{l}\t{%2, %k0|%k0, %2}";
5906 return "add{l}\t{%2, %k0|%k0, %2}";
5910 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5911 (const_string "incdec")
5912 (const_string "alu")))
5913 (set (attr "length_immediate")
5915 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5917 (const_string "*")))
5918 (set_attr "mode" "SI")])
5920 (define_insn "*add<mode>_3"
5921 [(set (reg FLAGS_REG)
5923 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5924 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5925 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5926 "ix86_match_ccmode (insn, CCZmode)
5927 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5929 switch (get_attr_type (insn))
5932 if (operands[2] == const1_rtx)
5933 return "inc{<imodesuffix>}\t%0";
5936 gcc_assert (operands[2] == constm1_rtx);
5937 return "dec{<imodesuffix>}\t%0";
5941 if (which_alternative == 1)
5944 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5947 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5948 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5949 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5951 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5955 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5956 (const_string "incdec")
5957 (const_string "alu")))
5958 (set (attr "length_immediate")
5960 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5962 (const_string "*")))
5963 (set_attr "mode" "<MODE>")])
5965 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5966 (define_insn "*addsi_3_zext"
5967 [(set (reg FLAGS_REG)
5969 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5970 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5971 (set (match_operand:DI 0 "register_operand" "=r,r")
5972 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5973 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5974 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5976 switch (get_attr_type (insn))
5979 if (operands[2] == const1_rtx)
5980 return "inc{l}\t%k0";
5983 gcc_assert (operands[2] == constm1_rtx);
5984 return "dec{l}\t%k0";
5988 if (which_alternative == 1)
5991 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5994 if (x86_maybe_negate_const_int (&operands[2], SImode))
5995 return "sub{l}\t{%2, %k0|%k0, %2}";
5997 return "add{l}\t{%2, %k0|%k0, %2}";
6001 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6002 (const_string "incdec")
6003 (const_string "alu")))
6004 (set (attr "length_immediate")
6006 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6008 (const_string "*")))
6009 (set_attr "mode" "SI")])
6011 ; For comparisons against 1, -1 and 128, we may generate better code
6012 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6013 ; is matched then. We can't accept general immediate, because for
6014 ; case of overflows, the result is messed up.
6015 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6016 ; only for comparisons not depending on it.
6018 (define_insn "*adddi_4"
6019 [(set (reg FLAGS_REG)
6021 (match_operand:DI 1 "nonimmediate_operand" "0")
6022 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6023 (clobber (match_scratch:DI 0 "=rm"))]
6025 && ix86_match_ccmode (insn, CCGCmode)"
6027 switch (get_attr_type (insn))
6030 if (operands[2] == constm1_rtx)
6031 return "inc{q}\t%0";
6034 gcc_assert (operands[2] == const1_rtx);
6035 return "dec{q}\t%0";
6039 if (x86_maybe_negate_const_int (&operands[2], DImode))
6040 return "add{q}\t{%2, %0|%0, %2}";
6042 return "sub{q}\t{%2, %0|%0, %2}";
6046 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6047 (const_string "incdec")
6048 (const_string "alu")))
6049 (set (attr "length_immediate")
6051 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6053 (const_string "*")))
6054 (set_attr "mode" "DI")])
6056 ; For comparisons against 1, -1 and 128, we may generate better code
6057 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6058 ; is matched then. We can't accept general immediate, because for
6059 ; case of overflows, the result is messed up.
6060 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6061 ; only for comparisons not depending on it.
6063 (define_insn "*add<mode>_4"
6064 [(set (reg FLAGS_REG)
6066 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6067 (match_operand:SWI124 2 "const_int_operand" "n")))
6068 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6069 "ix86_match_ccmode (insn, CCGCmode)"
6071 switch (get_attr_type (insn))
6074 if (operands[2] == constm1_rtx)
6075 return "inc{<imodesuffix>}\t%0";
6078 gcc_assert (operands[2] == const1_rtx);
6079 return "dec{<imodesuffix>}\t%0";
6083 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6084 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6086 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6090 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6091 (const_string "incdec")
6092 (const_string "alu")))
6093 (set (attr "length_immediate")
6095 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6097 (const_string "*")))
6098 (set_attr "mode" "<MODE>")])
6100 (define_insn "*add<mode>_5"
6101 [(set (reg FLAGS_REG)
6104 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6105 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6107 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6108 "ix86_match_ccmode (insn, CCGOCmode)
6109 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6111 switch (get_attr_type (insn))
6114 if (operands[2] == const1_rtx)
6115 return "inc{<imodesuffix>}\t%0";
6118 gcc_assert (operands[2] == constm1_rtx);
6119 return "dec{<imodesuffix>}\t%0";
6123 if (which_alternative == 1)
6126 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6129 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6130 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6131 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6133 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6137 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6138 (const_string "incdec")
6139 (const_string "alu")))
6140 (set (attr "length_immediate")
6142 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6144 (const_string "*")))
6145 (set_attr "mode" "<MODE>")])
6147 (define_insn "*addqi_ext_1_rex64"
6148 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6153 (match_operand 1 "ext_register_operand" "0")
6156 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6157 (clobber (reg:CC FLAGS_REG))]
6160 switch (get_attr_type (insn))
6163 if (operands[2] == const1_rtx)
6164 return "inc{b}\t%h0";
6167 gcc_assert (operands[2] == constm1_rtx);
6168 return "dec{b}\t%h0";
6172 return "add{b}\t{%2, %h0|%h0, %2}";
6176 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6177 (const_string "incdec")
6178 (const_string "alu")))
6179 (set_attr "modrm" "1")
6180 (set_attr "mode" "QI")])
6182 (define_insn "addqi_ext_1"
6183 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6188 (match_operand 1 "ext_register_operand" "0")
6191 (match_operand:QI 2 "general_operand" "Qmn")))
6192 (clobber (reg:CC FLAGS_REG))]
6195 switch (get_attr_type (insn))
6198 if (operands[2] == const1_rtx)
6199 return "inc{b}\t%h0";
6202 gcc_assert (operands[2] == constm1_rtx);
6203 return "dec{b}\t%h0";
6207 return "add{b}\t{%2, %h0|%h0, %2}";
6211 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6212 (const_string "incdec")
6213 (const_string "alu")))
6214 (set_attr "modrm" "1")
6215 (set_attr "mode" "QI")])
6217 (define_insn "*addqi_ext_2"
6218 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6223 (match_operand 1 "ext_register_operand" "%0")
6227 (match_operand 2 "ext_register_operand" "Q")
6230 (clobber (reg:CC FLAGS_REG))]
6232 "add{b}\t{%h2, %h0|%h0, %h2}"
6233 [(set_attr "type" "alu")
6234 (set_attr "mode" "QI")])
6236 ;; The lea patterns for modes less than 32 bits need to be matched by
6237 ;; several insns converted to real lea by splitters.
6239 (define_insn_and_split "*lea_general_1"
6240 [(set (match_operand 0 "register_operand" "=r")
6241 (plus (plus (match_operand 1 "index_register_operand" "l")
6242 (match_operand 2 "register_operand" "r"))
6243 (match_operand 3 "immediate_operand" "i")))]
6244 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6245 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6246 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6247 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6248 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6249 || GET_MODE (operands[3]) == VOIDmode)"
6251 "&& reload_completed"
6254 enum machine_mode mode = SImode;
6257 operands[0] = gen_lowpart (mode, operands[0]);
6258 operands[1] = gen_lowpart (mode, operands[1]);
6259 operands[2] = gen_lowpart (mode, operands[2]);
6260 operands[3] = gen_lowpart (mode, operands[3]);
6262 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6265 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6268 [(set_attr "type" "lea")
6269 (set_attr "mode" "SI")])
6271 (define_insn_and_split "*lea_general_2"
6272 [(set (match_operand 0 "register_operand" "=r")
6273 (plus (mult (match_operand 1 "index_register_operand" "l")
6274 (match_operand 2 "const248_operand" "n"))
6275 (match_operand 3 "nonmemory_operand" "ri")))]
6276 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6277 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6278 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6279 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6280 || GET_MODE (operands[3]) == VOIDmode)"
6282 "&& reload_completed"
6285 enum machine_mode mode = SImode;
6288 operands[0] = gen_lowpart (mode, operands[0]);
6289 operands[1] = gen_lowpart (mode, operands[1]);
6290 operands[3] = gen_lowpart (mode, operands[3]);
6292 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6295 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6298 [(set_attr "type" "lea")
6299 (set_attr "mode" "SI")])
6301 (define_insn_and_split "*lea_general_3"
6302 [(set (match_operand 0 "register_operand" "=r")
6303 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6304 (match_operand 2 "const248_operand" "n"))
6305 (match_operand 3 "register_operand" "r"))
6306 (match_operand 4 "immediate_operand" "i")))]
6307 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6308 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6309 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6310 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6312 "&& reload_completed"
6315 enum machine_mode mode = SImode;
6318 operands[0] = gen_lowpart (mode, operands[0]);
6319 operands[1] = gen_lowpart (mode, operands[1]);
6320 operands[3] = gen_lowpart (mode, operands[3]);
6321 operands[4] = gen_lowpart (mode, operands[4]);
6323 pat = gen_rtx_PLUS (mode,
6325 gen_rtx_MULT (mode, operands[1],
6330 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6333 [(set_attr "type" "lea")
6334 (set_attr "mode" "SI")])
6336 (define_insn_and_split "*lea_general_4"
6337 [(set (match_operand 0 "register_operand" "=r")
6339 (match_operand 1 "index_register_operand" "l")
6340 (match_operand 2 "const_int_operand" "n"))
6341 (match_operand 3 "const_int_operand" "n")))]
6342 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6343 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6344 || GET_MODE (operands[0]) == SImode
6345 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6346 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6347 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6348 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6349 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6351 "&& reload_completed"
6354 enum machine_mode mode = GET_MODE (operands[0]);
6357 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6360 operands[0] = gen_lowpart (mode, operands[0]);
6361 operands[1] = gen_lowpart (mode, operands[1]);
6364 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6366 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6367 INTVAL (operands[3]));
6369 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6372 [(set_attr "type" "lea")
6374 (if_then_else (match_operand:DI 0 "" "")
6376 (const_string "SI")))])
6378 ;; Subtract instructions
6380 (define_expand "sub<mode>3"
6381 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6382 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6383 (match_operand:SDWIM 2 "<general_operand>" "")))]
6385 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6387 (define_insn_and_split "*sub<dwi>3_doubleword"
6388 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6390 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6391 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6392 (clobber (reg:CC FLAGS_REG))]
6393 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6396 [(parallel [(set (reg:CC FLAGS_REG)
6397 (compare:CC (match_dup 1) (match_dup 2)))
6399 (minus:DWIH (match_dup 1) (match_dup 2)))])
6400 (parallel [(set (match_dup 3)
6404 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6406 (clobber (reg:CC FLAGS_REG))])]
6407 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6409 (define_insn "*sub<mode>_1"
6410 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6412 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6413 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6414 (clobber (reg:CC FLAGS_REG))]
6415 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6416 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6417 [(set_attr "type" "alu")
6418 (set_attr "mode" "<MODE>")])
6420 (define_insn "*subsi_1_zext"
6421 [(set (match_operand:DI 0 "register_operand" "=r")
6423 (minus:SI (match_operand:SI 1 "register_operand" "0")
6424 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6425 (clobber (reg:CC FLAGS_REG))]
6426 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6427 "sub{l}\t{%2, %k0|%k0, %2}"
6428 [(set_attr "type" "alu")
6429 (set_attr "mode" "SI")])
6431 (define_insn "*subqi_1_slp"
6432 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6433 (minus:QI (match_dup 0)
6434 (match_operand:QI 1 "general_operand" "qn,qm")))
6435 (clobber (reg:CC FLAGS_REG))]
6436 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6438 "sub{b}\t{%1, %0|%0, %1}"
6439 [(set_attr "type" "alu1")
6440 (set_attr "mode" "QI")])
6442 (define_insn "*sub<mode>_2"
6443 [(set (reg FLAGS_REG)
6446 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6447 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6449 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6450 (minus:SWI (match_dup 1) (match_dup 2)))]
6451 "ix86_match_ccmode (insn, CCGOCmode)
6452 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6453 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6454 [(set_attr "type" "alu")
6455 (set_attr "mode" "<MODE>")])
6457 (define_insn "*subsi_2_zext"
6458 [(set (reg FLAGS_REG)
6460 (minus:SI (match_operand:SI 1 "register_operand" "0")
6461 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6463 (set (match_operand:DI 0 "register_operand" "=r")
6465 (minus:SI (match_dup 1)
6467 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6468 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6469 "sub{l}\t{%2, %k0|%k0, %2}"
6470 [(set_attr "type" "alu")
6471 (set_attr "mode" "SI")])
6473 (define_insn "*sub<mode>_3"
6474 [(set (reg FLAGS_REG)
6475 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6476 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6477 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6478 (minus:SWI (match_dup 1) (match_dup 2)))]
6479 "ix86_match_ccmode (insn, CCmode)
6480 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6481 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6482 [(set_attr "type" "alu")
6483 (set_attr "mode" "<MODE>")])
6485 (define_insn "*subsi_3_zext"
6486 [(set (reg FLAGS_REG)
6487 (compare (match_operand:SI 1 "register_operand" "0")
6488 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6489 (set (match_operand:DI 0 "register_operand" "=r")
6491 (minus:SI (match_dup 1)
6493 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6494 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6495 "sub{l}\t{%2, %1|%1, %2}"
6496 [(set_attr "type" "alu")
6497 (set_attr "mode" "SI")])
6499 ;; Add with carry and subtract with borrow
6501 (define_expand "<plusminus_insn><mode>3_carry"
6503 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6505 (match_operand:SWI 1 "nonimmediate_operand" "")
6506 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6507 [(match_operand 3 "flags_reg_operand" "")
6509 (match_operand:SWI 2 "<general_operand>" ""))))
6510 (clobber (reg:CC FLAGS_REG))])]
6511 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6513 (define_insn "*<plusminus_insn><mode>3_carry"
6514 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6516 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6518 (match_operator 3 "ix86_carry_flag_operator"
6519 [(reg FLAGS_REG) (const_int 0)])
6520 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6521 (clobber (reg:CC FLAGS_REG))]
6522 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6523 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6524 [(set_attr "type" "alu")
6525 (set_attr "use_carry" "1")
6526 (set_attr "pent_pair" "pu")
6527 (set_attr "mode" "<MODE>")])
6529 (define_insn "*addsi3_carry_zext"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6533 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6534 [(reg FLAGS_REG) (const_int 0)])
6535 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6536 (clobber (reg:CC FLAGS_REG))]
6537 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6538 "adc{l}\t{%2, %k0|%k0, %2}"
6539 [(set_attr "type" "alu")
6540 (set_attr "use_carry" "1")
6541 (set_attr "pent_pair" "pu")
6542 (set_attr "mode" "SI")])
6544 (define_insn "*subsi3_carry_zext"
6545 [(set (match_operand:DI 0 "register_operand" "=r")
6547 (minus:SI (match_operand:SI 1 "register_operand" "0")
6548 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6549 [(reg FLAGS_REG) (const_int 0)])
6550 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6551 (clobber (reg:CC FLAGS_REG))]
6552 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6553 "sbb{l}\t{%2, %k0|%k0, %2}"
6554 [(set_attr "type" "alu")
6555 (set_attr "pent_pair" "pu")
6556 (set_attr "mode" "SI")])
6558 ;; Overflow setting add instructions
6560 (define_insn "*add<mode>3_cconly_overflow"
6561 [(set (reg:CCC FLAGS_REG)
6564 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6565 (match_operand:SWI 2 "<general_operand>" "<g>"))
6567 (clobber (match_scratch:SWI 0 "=<r>"))]
6568 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6569 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6570 [(set_attr "type" "alu")
6571 (set_attr "mode" "<MODE>")])
6573 (define_insn "*add<mode>3_cc_overflow"
6574 [(set (reg:CCC FLAGS_REG)
6577 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
6578 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6580 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6581 (plus:SWI (match_dup 1) (match_dup 2)))]
6582 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6583 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6584 [(set_attr "type" "alu")
6585 (set_attr "mode" "<MODE>")])
6587 (define_insn "*addsi3_zext_cc_overflow"
6588 [(set (reg:CCC FLAGS_REG)
6591 (match_operand:SI 1 "nonimmediate_operand" "%0")
6592 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6594 (set (match_operand:DI 0 "register_operand" "=r")
6595 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6596 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6597 "add{l}\t{%2, %k0|%k0, %2}"
6598 [(set_attr "type" "alu")
6599 (set_attr "mode" "SI")])
6601 ;; The patterns that match these are at the end of this file.
6603 (define_expand "<plusminus_insn>xf3"
6604 [(set (match_operand:XF 0 "register_operand" "")
6606 (match_operand:XF 1 "register_operand" "")
6607 (match_operand:XF 2 "register_operand" "")))]
6610 (define_expand "<plusminus_insn><mode>3"
6611 [(set (match_operand:MODEF 0 "register_operand" "")
6613 (match_operand:MODEF 1 "register_operand" "")
6614 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6615 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6616 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6618 ;; Multiply instructions
6620 (define_expand "mul<mode>3"
6621 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6623 (match_operand:SWIM248 1 "register_operand" "")
6624 (match_operand:SWIM248 2 "<general_operand>" "")))
6625 (clobber (reg:CC FLAGS_REG))])])
6627 (define_expand "mulqi3"
6628 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6630 (match_operand:QI 1 "register_operand" "")
6631 (match_operand:QI 2 "nonimmediate_operand" "")))
6632 (clobber (reg:CC FLAGS_REG))])]
6633 "TARGET_QIMODE_MATH")
6636 ;; IMUL reg32/64, reg32/64, imm8 Direct
6637 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6638 ;; IMUL reg32/64, reg32/64, imm32 Direct
6639 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6640 ;; IMUL reg32/64, reg32/64 Direct
6641 ;; IMUL reg32/64, mem32/64 Direct
6643 ;; On BDVER1, all above IMULs use DirectPath
6645 (define_insn "*mul<mode>3_1"
6646 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6648 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6649 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6650 (clobber (reg:CC FLAGS_REG))]
6651 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6653 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6654 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6655 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6656 [(set_attr "type" "imul")
6657 (set_attr "prefix_0f" "0,0,1")
6658 (set (attr "athlon_decode")
6659 (cond [(eq_attr "cpu" "athlon")
6660 (const_string "vector")
6661 (eq_attr "alternative" "1")
6662 (const_string "vector")
6663 (and (eq_attr "alternative" "2")
6664 (match_operand 1 "memory_operand" ""))
6665 (const_string "vector")]
6666 (const_string "direct")))
6667 (set (attr "amdfam10_decode")
6668 (cond [(and (eq_attr "alternative" "0,1")
6669 (match_operand 1 "memory_operand" ""))
6670 (const_string "vector")]
6671 (const_string "direct")))
6672 (set_attr "bdver1_decode" "direct")
6673 (set_attr "mode" "<MODE>")])
6675 (define_insn "*mulsi3_1_zext"
6676 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6678 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6679 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6680 (clobber (reg:CC FLAGS_REG))]
6682 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6684 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6685 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6686 imul{l}\t{%2, %k0|%k0, %2}"
6687 [(set_attr "type" "imul")
6688 (set_attr "prefix_0f" "0,0,1")
6689 (set (attr "athlon_decode")
6690 (cond [(eq_attr "cpu" "athlon")
6691 (const_string "vector")
6692 (eq_attr "alternative" "1")
6693 (const_string "vector")
6694 (and (eq_attr "alternative" "2")
6695 (match_operand 1 "memory_operand" ""))
6696 (const_string "vector")]
6697 (const_string "direct")))
6698 (set (attr "amdfam10_decode")
6699 (cond [(and (eq_attr "alternative" "0,1")
6700 (match_operand 1 "memory_operand" ""))
6701 (const_string "vector")]
6702 (const_string "direct")))
6703 (set_attr "bdver1_decode" "direct")
6704 (set_attr "mode" "SI")])
6707 ;; IMUL reg16, reg16, imm8 VectorPath
6708 ;; IMUL reg16, mem16, imm8 VectorPath
6709 ;; IMUL reg16, reg16, imm16 VectorPath
6710 ;; IMUL reg16, mem16, imm16 VectorPath
6711 ;; IMUL reg16, reg16 Direct
6712 ;; IMUL reg16, mem16 Direct
6714 ;; On BDVER1, all HI MULs use DoublePath
6716 (define_insn "*mulhi3_1"
6717 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6718 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6719 (match_operand:HI 2 "general_operand" "K,n,mr")))
6720 (clobber (reg:CC FLAGS_REG))]
6722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6724 imul{w}\t{%2, %1, %0|%0, %1, %2}
6725 imul{w}\t{%2, %1, %0|%0, %1, %2}
6726 imul{w}\t{%2, %0|%0, %2}"
6727 [(set_attr "type" "imul")
6728 (set_attr "prefix_0f" "0,0,1")
6729 (set (attr "athlon_decode")
6730 (cond [(eq_attr "cpu" "athlon")
6731 (const_string "vector")
6732 (eq_attr "alternative" "1,2")
6733 (const_string "vector")]
6734 (const_string "direct")))
6735 (set (attr "amdfam10_decode")
6736 (cond [(eq_attr "alternative" "0,1")
6737 (const_string "vector")]
6738 (const_string "direct")))
6739 (set_attr "bdver1_decode" "double")
6740 (set_attr "mode" "HI")])
6742 ;;On AMDFAM10 and BDVER1
6746 (define_insn "*mulqi3_1"
6747 [(set (match_operand:QI 0 "register_operand" "=a")
6748 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6749 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6750 (clobber (reg:CC FLAGS_REG))]
6752 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6754 [(set_attr "type" "imul")
6755 (set_attr "length_immediate" "0")
6756 (set (attr "athlon_decode")
6757 (if_then_else (eq_attr "cpu" "athlon")
6758 (const_string "vector")
6759 (const_string "direct")))
6760 (set_attr "amdfam10_decode" "direct")
6761 (set_attr "bdver1_decode" "direct")
6762 (set_attr "mode" "QI")])
6764 (define_expand "<u>mul<mode><dwi>3"
6765 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6768 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6770 (match_operand:DWIH 2 "register_operand" ""))))
6771 (clobber (reg:CC FLAGS_REG))])])
6773 (define_expand "<u>mulqihi3"
6774 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6777 (match_operand:QI 1 "nonimmediate_operand" ""))
6779 (match_operand:QI 2 "register_operand" ""))))
6780 (clobber (reg:CC FLAGS_REG))])]
6781 "TARGET_QIMODE_MATH")
6783 (define_insn "*bmi2_umulditi3_1"
6784 [(set (match_operand:DI 0 "register_operand" "=r")
6786 (match_operand:DI 2 "nonimmediate_operand" "%d")
6787 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6788 (set (match_operand:DI 1 "register_operand" "=r")
6791 (mult:TI (zero_extend:TI (match_dup 2))
6792 (zero_extend:TI (match_dup 3)))
6794 "TARGET_64BIT && TARGET_BMI2
6795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6796 "mulx\t{%3, %0, %1|%1, %0, %3}"
6797 [(set_attr "type" "imulx")
6798 (set_attr "prefix" "vex")
6799 (set_attr "mode" "DI")])
6801 (define_insn "*bmi2_umulsidi3_1"
6802 [(set (match_operand:SI 0 "register_operand" "=r")
6804 (match_operand:SI 2 "nonimmediate_operand" "%d")
6805 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6806 (set (match_operand:SI 1 "register_operand" "=r")
6809 (mult:DI (zero_extend:DI (match_dup 2))
6810 (zero_extend:DI (match_dup 3)))
6812 "!TARGET_64BIT && TARGET_BMI2
6813 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6814 "mulx\t{%3, %0, %1|%1, %0, %3}"
6815 [(set_attr "type" "imulx")
6816 (set_attr "prefix" "vex")
6817 (set_attr "mode" "SI")])
6819 (define_insn "*umul<mode><dwi>3_1"
6820 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6823 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6825 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6826 (clobber (reg:CC FLAGS_REG))]
6827 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6829 mul{<imodesuffix>}\t%2
6831 [(set_attr "isa" "*,bmi2")
6832 (set_attr "type" "imul,imulx")
6833 (set_attr "length_immediate" "0,*")
6834 (set (attr "athlon_decode")
6835 (cond [(eq_attr "alternative" "0")
6836 (if_then_else (eq_attr "cpu" "athlon")
6837 (const_string "vector")
6838 (const_string "double"))]
6839 (const_string "*")))
6840 (set_attr "amdfam10_decode" "double,*")
6841 (set_attr "bdver1_decode" "direct,*")
6842 (set_attr "prefix" "orig,vex")
6843 (set_attr "mode" "<MODE>")])
6845 ;; Convert mul to the mulx pattern to avoid flags dependency.
6847 [(set (match_operand:<DWI> 0 "register_operand" "")
6850 (match_operand:DWIH 1 "register_operand" ""))
6852 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6853 (clobber (reg:CC FLAGS_REG))]
6854 "TARGET_BMI2 && reload_completed
6855 && true_regnum (operands[1]) == DX_REG"
6856 [(parallel [(set (match_dup 3)
6857 (mult:DWIH (match_dup 1) (match_dup 2)))
6861 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6862 (zero_extend:<DWI> (match_dup 2)))
6865 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6867 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6870 (define_insn "*mul<mode><dwi>3_1"
6871 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6874 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6876 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6877 (clobber (reg:CC FLAGS_REG))]
6878 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6879 "imul{<imodesuffix>}\t%2"
6880 [(set_attr "type" "imul")
6881 (set_attr "length_immediate" "0")
6882 (set (attr "athlon_decode")
6883 (if_then_else (eq_attr "cpu" "athlon")
6884 (const_string "vector")
6885 (const_string "double")))
6886 (set_attr "amdfam10_decode" "double")
6887 (set_attr "bdver1_decode" "direct")
6888 (set_attr "mode" "<MODE>")])
6890 (define_insn "*<u>mulqihi3_1"
6891 [(set (match_operand:HI 0 "register_operand" "=a")
6894 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6896 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6897 (clobber (reg:CC FLAGS_REG))]
6899 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6900 "<sgnprefix>mul{b}\t%2"
6901 [(set_attr "type" "imul")
6902 (set_attr "length_immediate" "0")
6903 (set (attr "athlon_decode")
6904 (if_then_else (eq_attr "cpu" "athlon")
6905 (const_string "vector")
6906 (const_string "direct")))
6907 (set_attr "amdfam10_decode" "direct")
6908 (set_attr "bdver1_decode" "direct")
6909 (set_attr "mode" "QI")])
6911 (define_expand "<s>mul<mode>3_highpart"
6912 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6917 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6919 (match_operand:SWI48 2 "register_operand" "")))
6921 (clobber (match_scratch:SWI48 3 ""))
6922 (clobber (reg:CC FLAGS_REG))])]
6924 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6926 (define_insn "*<s>muldi3_highpart_1"
6927 [(set (match_operand:DI 0 "register_operand" "=d")
6932 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6934 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6936 (clobber (match_scratch:DI 3 "=1"))
6937 (clobber (reg:CC FLAGS_REG))]
6939 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6940 "<sgnprefix>mul{q}\t%2"
6941 [(set_attr "type" "imul")
6942 (set_attr "length_immediate" "0")
6943 (set (attr "athlon_decode")
6944 (if_then_else (eq_attr "cpu" "athlon")
6945 (const_string "vector")
6946 (const_string "double")))
6947 (set_attr "amdfam10_decode" "double")
6948 (set_attr "bdver1_decode" "direct")
6949 (set_attr "mode" "DI")])
6951 (define_insn "*<s>mulsi3_highpart_1"
6952 [(set (match_operand:SI 0 "register_operand" "=d")
6957 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6959 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6961 (clobber (match_scratch:SI 3 "=1"))
6962 (clobber (reg:CC FLAGS_REG))]
6963 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6964 "<sgnprefix>mul{l}\t%2"
6965 [(set_attr "type" "imul")
6966 (set_attr "length_immediate" "0")
6967 (set (attr "athlon_decode")
6968 (if_then_else (eq_attr "cpu" "athlon")
6969 (const_string "vector")
6970 (const_string "double")))
6971 (set_attr "amdfam10_decode" "double")
6972 (set_attr "bdver1_decode" "direct")
6973 (set_attr "mode" "SI")])
6975 (define_insn "*<s>mulsi3_highpart_zext"
6976 [(set (match_operand:DI 0 "register_operand" "=d")
6977 (zero_extend:DI (truncate:SI
6979 (mult:DI (any_extend:DI
6980 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6982 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6984 (clobber (match_scratch:SI 3 "=1"))
6985 (clobber (reg:CC FLAGS_REG))]
6987 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6988 "<sgnprefix>mul{l}\t%2"
6989 [(set_attr "type" "imul")
6990 (set_attr "length_immediate" "0")
6991 (set (attr "athlon_decode")
6992 (if_then_else (eq_attr "cpu" "athlon")
6993 (const_string "vector")
6994 (const_string "double")))
6995 (set_attr "amdfam10_decode" "double")
6996 (set_attr "bdver1_decode" "direct")
6997 (set_attr "mode" "SI")])
6999 ;; The patterns that match these are at the end of this file.
7001 (define_expand "mulxf3"
7002 [(set (match_operand:XF 0 "register_operand" "")
7003 (mult:XF (match_operand:XF 1 "register_operand" "")
7004 (match_operand:XF 2 "register_operand" "")))]
7007 (define_expand "mul<mode>3"
7008 [(set (match_operand:MODEF 0 "register_operand" "")
7009 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7010 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7011 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7012 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7014 ;; Divide instructions
7016 ;; The patterns that match these are at the end of this file.
7018 (define_expand "divxf3"
7019 [(set (match_operand:XF 0 "register_operand" "")
7020 (div:XF (match_operand:XF 1 "register_operand" "")
7021 (match_operand:XF 2 "register_operand" "")))]
7024 (define_expand "divdf3"
7025 [(set (match_operand:DF 0 "register_operand" "")
7026 (div:DF (match_operand:DF 1 "register_operand" "")
7027 (match_operand:DF 2 "nonimmediate_operand" "")))]
7028 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7029 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7031 (define_expand "divsf3"
7032 [(set (match_operand:SF 0 "register_operand" "")
7033 (div:SF (match_operand:SF 1 "register_operand" "")
7034 (match_operand:SF 2 "nonimmediate_operand" "")))]
7035 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7040 && optimize_insn_for_speed_p ()
7041 && flag_finite_math_only && !flag_trapping_math
7042 && flag_unsafe_math_optimizations)
7044 ix86_emit_swdivsf (operands[0], operands[1],
7045 operands[2], SFmode);
7050 ;; Divmod instructions.
7052 (define_expand "divmod<mode>4"
7053 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7055 (match_operand:SWIM248 1 "register_operand" "")
7056 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7057 (set (match_operand:SWIM248 3 "register_operand" "")
7058 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7059 (clobber (reg:CC FLAGS_REG))])])
7061 ;; Split with 8bit unsigned divide:
7062 ;; if (dividend an divisor are in [0-255])
7063 ;; use 8bit unsigned integer divide
7065 ;; use original integer divide
7067 [(set (match_operand:SWI48 0 "register_operand" "")
7068 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7069 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7070 (set (match_operand:SWI48 1 "register_operand" "")
7071 (mod:SWI48 (match_dup 2) (match_dup 3)))
7072 (clobber (reg:CC FLAGS_REG))]
7073 "TARGET_USE_8BIT_IDIV
7074 && TARGET_QIMODE_MATH
7075 && can_create_pseudo_p ()
7076 && !optimize_insn_for_size_p ()"
7078 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7080 (define_insn_and_split "divmod<mode>4_1"
7081 [(set (match_operand:SWI48 0 "register_operand" "=a")
7082 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7083 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7084 (set (match_operand:SWI48 1 "register_operand" "=&d")
7085 (mod:SWI48 (match_dup 2) (match_dup 3)))
7086 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7087 (clobber (reg:CC FLAGS_REG))]
7091 [(parallel [(set (match_dup 1)
7092 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7093 (clobber (reg:CC FLAGS_REG))])
7094 (parallel [(set (match_dup 0)
7095 (div:SWI48 (match_dup 2) (match_dup 3)))
7097 (mod:SWI48 (match_dup 2) (match_dup 3)))
7099 (clobber (reg:CC FLAGS_REG))])]
7101 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7103 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7104 operands[4] = operands[2];
7107 /* Avoid use of cltd in favor of a mov+shift. */
7108 emit_move_insn (operands[1], operands[2]);
7109 operands[4] = operands[1];
7112 [(set_attr "type" "multi")
7113 (set_attr "mode" "<MODE>")])
7115 (define_insn_and_split "*divmod<mode>4"
7116 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7117 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7118 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7119 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7120 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7121 (clobber (reg:CC FLAGS_REG))]
7125 [(parallel [(set (match_dup 1)
7126 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7127 (clobber (reg:CC FLAGS_REG))])
7128 (parallel [(set (match_dup 0)
7129 (div:SWIM248 (match_dup 2) (match_dup 3)))
7131 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7133 (clobber (reg:CC FLAGS_REG))])]
7135 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7137 if (<MODE>mode != HImode
7138 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7139 operands[4] = operands[2];
7142 /* Avoid use of cltd in favor of a mov+shift. */
7143 emit_move_insn (operands[1], operands[2]);
7144 operands[4] = operands[1];
7147 [(set_attr "type" "multi")
7148 (set_attr "mode" "<MODE>")])
7150 (define_insn "*divmod<mode>4_noext"
7151 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7152 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7153 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7154 (set (match_operand:SWIM248 1 "register_operand" "=d")
7155 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7156 (use (match_operand:SWIM248 4 "register_operand" "1"))
7157 (clobber (reg:CC FLAGS_REG))]
7159 "idiv{<imodesuffix>}\t%3"
7160 [(set_attr "type" "idiv")
7161 (set_attr "mode" "<MODE>")])
7163 (define_expand "divmodqi4"
7164 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7166 (match_operand:QI 1 "register_operand" "")
7167 (match_operand:QI 2 "nonimmediate_operand" "")))
7168 (set (match_operand:QI 3 "register_operand" "")
7169 (mod:QI (match_dup 1) (match_dup 2)))
7170 (clobber (reg:CC FLAGS_REG))])]
7171 "TARGET_QIMODE_MATH"
7176 tmp0 = gen_reg_rtx (HImode);
7177 tmp1 = gen_reg_rtx (HImode);
7179 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7181 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7182 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7184 /* Extract remainder from AH. */
7185 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7186 insn = emit_move_insn (operands[3], tmp1);
7188 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7189 set_unique_reg_note (insn, REG_EQUAL, mod);
7191 /* Extract quotient from AL. */
7192 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7194 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7195 set_unique_reg_note (insn, REG_EQUAL, div);
7200 ;; Divide AX by r/m8, with result stored in
7203 ;; Change div/mod to HImode and extend the second argument to HImode
7204 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7205 ;; combine may fail.
7206 (define_insn "divmodhiqi3"
7207 [(set (match_operand:HI 0 "register_operand" "=a")
7212 (mod:HI (match_operand:HI 1 "register_operand" "0")
7214 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7218 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7219 (clobber (reg:CC FLAGS_REG))]
7220 "TARGET_QIMODE_MATH"
7222 [(set_attr "type" "idiv")
7223 (set_attr "mode" "QI")])
7225 (define_expand "udivmod<mode>4"
7226 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7228 (match_operand:SWIM248 1 "register_operand" "")
7229 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7230 (set (match_operand:SWIM248 3 "register_operand" "")
7231 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7232 (clobber (reg:CC FLAGS_REG))])])
7234 ;; Split with 8bit unsigned divide:
7235 ;; if (dividend an divisor are in [0-255])
7236 ;; use 8bit unsigned integer divide
7238 ;; use original integer divide
7240 [(set (match_operand:SWI48 0 "register_operand" "")
7241 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7242 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7243 (set (match_operand:SWI48 1 "register_operand" "")
7244 (umod:SWI48 (match_dup 2) (match_dup 3)))
7245 (clobber (reg:CC FLAGS_REG))]
7246 "TARGET_USE_8BIT_IDIV
7247 && TARGET_QIMODE_MATH
7248 && can_create_pseudo_p ()
7249 && !optimize_insn_for_size_p ()"
7251 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7253 (define_insn_and_split "udivmod<mode>4_1"
7254 [(set (match_operand:SWI48 0 "register_operand" "=a")
7255 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7256 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7257 (set (match_operand:SWI48 1 "register_operand" "=&d")
7258 (umod:SWI48 (match_dup 2) (match_dup 3)))
7259 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7260 (clobber (reg:CC FLAGS_REG))]
7264 [(set (match_dup 1) (const_int 0))
7265 (parallel [(set (match_dup 0)
7266 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7268 (umod:SWI48 (match_dup 2) (match_dup 3)))
7270 (clobber (reg:CC FLAGS_REG))])]
7272 [(set_attr "type" "multi")
7273 (set_attr "mode" "<MODE>")])
7275 (define_insn_and_split "*udivmod<mode>4"
7276 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7277 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7278 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7279 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7280 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7281 (clobber (reg:CC FLAGS_REG))]
7285 [(set (match_dup 1) (const_int 0))
7286 (parallel [(set (match_dup 0)
7287 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7289 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7291 (clobber (reg:CC FLAGS_REG))])]
7293 [(set_attr "type" "multi")
7294 (set_attr "mode" "<MODE>")])
7296 (define_insn "*udivmod<mode>4_noext"
7297 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7298 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7299 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7300 (set (match_operand:SWIM248 1 "register_operand" "=d")
7301 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7302 (use (match_operand:SWIM248 4 "register_operand" "1"))
7303 (clobber (reg:CC FLAGS_REG))]
7305 "div{<imodesuffix>}\t%3"
7306 [(set_attr "type" "idiv")
7307 (set_attr "mode" "<MODE>")])
7309 (define_expand "udivmodqi4"
7310 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7312 (match_operand:QI 1 "register_operand" "")
7313 (match_operand:QI 2 "nonimmediate_operand" "")))
7314 (set (match_operand:QI 3 "register_operand" "")
7315 (umod:QI (match_dup 1) (match_dup 2)))
7316 (clobber (reg:CC FLAGS_REG))])]
7317 "TARGET_QIMODE_MATH"
7322 tmp0 = gen_reg_rtx (HImode);
7323 tmp1 = gen_reg_rtx (HImode);
7325 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7327 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7328 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7330 /* Extract remainder from AH. */
7331 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7332 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7333 insn = emit_move_insn (operands[3], tmp1);
7335 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7336 set_unique_reg_note (insn, REG_EQUAL, mod);
7338 /* Extract quotient from AL. */
7339 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7341 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7342 set_unique_reg_note (insn, REG_EQUAL, div);
7347 (define_insn "udivmodhiqi3"
7348 [(set (match_operand:HI 0 "register_operand" "=a")
7353 (mod:HI (match_operand:HI 1 "register_operand" "0")
7355 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7359 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7360 (clobber (reg:CC FLAGS_REG))]
7361 "TARGET_QIMODE_MATH"
7363 [(set_attr "type" "idiv")
7364 (set_attr "mode" "QI")])
7366 ;; We cannot use div/idiv for double division, because it causes
7367 ;; "division by zero" on the overflow and that's not what we expect
7368 ;; from truncate. Because true (non truncating) double division is
7369 ;; never generated, we can't create this insn anyway.
7372 ; [(set (match_operand:SI 0 "register_operand" "=a")
7374 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7376 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7377 ; (set (match_operand:SI 3 "register_operand" "=d")
7379 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7380 ; (clobber (reg:CC FLAGS_REG))]
7382 ; "div{l}\t{%2, %0|%0, %2}"
7383 ; [(set_attr "type" "idiv")])
7385 ;;- Logical AND instructions
7387 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7388 ;; Note that this excludes ah.
7390 (define_expand "testsi_ccno_1"
7391 [(set (reg:CCNO FLAGS_REG)
7393 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7394 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7397 (define_expand "testqi_ccz_1"
7398 [(set (reg:CCZ FLAGS_REG)
7399 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7400 (match_operand:QI 1 "nonmemory_operand" ""))
7403 (define_expand "testdi_ccno_1"
7404 [(set (reg:CCNO FLAGS_REG)
7406 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7407 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7409 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7411 (define_insn "*testdi_1"
7412 [(set (reg FLAGS_REG)
7415 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7416 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7418 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7419 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7421 test{l}\t{%k1, %k0|%k0, %k1}
7422 test{l}\t{%k1, %k0|%k0, %k1}
7423 test{q}\t{%1, %0|%0, %1}
7424 test{q}\t{%1, %0|%0, %1}
7425 test{q}\t{%1, %0|%0, %1}"
7426 [(set_attr "type" "test")
7427 (set_attr "modrm" "0,1,0,1,1")
7428 (set_attr "mode" "SI,SI,DI,DI,DI")])
7430 (define_insn "*testqi_1_maybe_si"
7431 [(set (reg FLAGS_REG)
7434 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7435 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7437 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7438 && ix86_match_ccmode (insn,
7439 CONST_INT_P (operands[1])
7440 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7442 if (which_alternative == 3)
7444 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7445 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7446 return "test{l}\t{%1, %k0|%k0, %1}";
7448 return "test{b}\t{%1, %0|%0, %1}";
7450 [(set_attr "type" "test")
7451 (set_attr "modrm" "0,1,1,1")
7452 (set_attr "mode" "QI,QI,QI,SI")
7453 (set_attr "pent_pair" "uv,np,uv,np")])
7455 (define_insn "*test<mode>_1"
7456 [(set (reg FLAGS_REG)
7459 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7460 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7462 "ix86_match_ccmode (insn, CCNOmode)
7463 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7464 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7465 [(set_attr "type" "test")
7466 (set_attr "modrm" "0,1,1")
7467 (set_attr "mode" "<MODE>")
7468 (set_attr "pent_pair" "uv,np,uv")])
7470 (define_expand "testqi_ext_ccno_0"
7471 [(set (reg:CCNO FLAGS_REG)
7475 (match_operand 0 "ext_register_operand" "")
7478 (match_operand 1 "const_int_operand" ""))
7481 (define_insn "*testqi_ext_0"
7482 [(set (reg FLAGS_REG)
7486 (match_operand 0 "ext_register_operand" "Q")
7489 (match_operand 1 "const_int_operand" "n"))
7491 "ix86_match_ccmode (insn, CCNOmode)"
7492 "test{b}\t{%1, %h0|%h0, %1}"
7493 [(set_attr "type" "test")
7494 (set_attr "mode" "QI")
7495 (set_attr "length_immediate" "1")
7496 (set_attr "modrm" "1")
7497 (set_attr "pent_pair" "np")])
7499 (define_insn "*testqi_ext_1_rex64"
7500 [(set (reg FLAGS_REG)
7504 (match_operand 0 "ext_register_operand" "Q")
7508 (match_operand:QI 1 "register_operand" "Q")))
7510 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7511 "test{b}\t{%1, %h0|%h0, %1}"
7512 [(set_attr "type" "test")
7513 (set_attr "mode" "QI")])
7515 (define_insn "*testqi_ext_1"
7516 [(set (reg FLAGS_REG)
7520 (match_operand 0 "ext_register_operand" "Q")
7524 (match_operand:QI 1 "general_operand" "Qm")))
7526 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7527 "test{b}\t{%1, %h0|%h0, %1}"
7528 [(set_attr "type" "test")
7529 (set_attr "mode" "QI")])
7531 (define_insn "*testqi_ext_2"
7532 [(set (reg FLAGS_REG)
7536 (match_operand 0 "ext_register_operand" "Q")
7540 (match_operand 1 "ext_register_operand" "Q")
7544 "ix86_match_ccmode (insn, CCNOmode)"
7545 "test{b}\t{%h1, %h0|%h0, %h1}"
7546 [(set_attr "type" "test")
7547 (set_attr "mode" "QI")])
7549 (define_insn "*testqi_ext_3_rex64"
7550 [(set (reg FLAGS_REG)
7551 (compare (zero_extract:DI
7552 (match_operand 0 "nonimmediate_operand" "rm")
7553 (match_operand:DI 1 "const_int_operand" "")
7554 (match_operand:DI 2 "const_int_operand" ""))
7557 && ix86_match_ccmode (insn, CCNOmode)
7558 && INTVAL (operands[1]) > 0
7559 && INTVAL (operands[2]) >= 0
7560 /* Ensure that resulting mask is zero or sign extended operand. */
7561 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7562 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7563 && INTVAL (operands[1]) > 32))
7564 && (GET_MODE (operands[0]) == SImode
7565 || GET_MODE (operands[0]) == DImode
7566 || GET_MODE (operands[0]) == HImode
7567 || GET_MODE (operands[0]) == QImode)"
7570 ;; Combine likes to form bit extractions for some tests. Humor it.
7571 (define_insn "*testqi_ext_3"
7572 [(set (reg FLAGS_REG)
7573 (compare (zero_extract:SI
7574 (match_operand 0 "nonimmediate_operand" "rm")
7575 (match_operand:SI 1 "const_int_operand" "")
7576 (match_operand:SI 2 "const_int_operand" ""))
7578 "ix86_match_ccmode (insn, CCNOmode)
7579 && INTVAL (operands[1]) > 0
7580 && INTVAL (operands[2]) >= 0
7581 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7582 && (GET_MODE (operands[0]) == SImode
7583 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7584 || GET_MODE (operands[0]) == HImode
7585 || GET_MODE (operands[0]) == QImode)"
7589 [(set (match_operand 0 "flags_reg_operand" "")
7590 (match_operator 1 "compare_operator"
7592 (match_operand 2 "nonimmediate_operand" "")
7593 (match_operand 3 "const_int_operand" "")
7594 (match_operand 4 "const_int_operand" ""))
7596 "ix86_match_ccmode (insn, CCNOmode)"
7597 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7599 rtx val = operands[2];
7600 HOST_WIDE_INT len = INTVAL (operands[3]);
7601 HOST_WIDE_INT pos = INTVAL (operands[4]);
7603 enum machine_mode mode, submode;
7605 mode = GET_MODE (val);
7608 /* ??? Combine likes to put non-volatile mem extractions in QImode
7609 no matter the size of the test. So find a mode that works. */
7610 if (! MEM_VOLATILE_P (val))
7612 mode = smallest_mode_for_size (pos + len, MODE_INT);
7613 val = adjust_address (val, mode, 0);
7616 else if (GET_CODE (val) == SUBREG
7617 && (submode = GET_MODE (SUBREG_REG (val)),
7618 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7619 && pos + len <= GET_MODE_BITSIZE (submode)
7620 && GET_MODE_CLASS (submode) == MODE_INT)
7622 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7624 val = SUBREG_REG (val);
7626 else if (mode == HImode && pos + len <= 8)
7628 /* Small HImode tests can be converted to QImode. */
7630 val = gen_lowpart (QImode, val);
7633 if (len == HOST_BITS_PER_WIDE_INT)
7636 mask = ((HOST_WIDE_INT)1 << len) - 1;
7639 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7642 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7643 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7644 ;; this is relatively important trick.
7645 ;; Do the conversion only post-reload to avoid limiting of the register class
7648 [(set (match_operand 0 "flags_reg_operand" "")
7649 (match_operator 1 "compare_operator"
7650 [(and (match_operand 2 "register_operand" "")
7651 (match_operand 3 "const_int_operand" ""))
7654 && QI_REG_P (operands[2])
7655 && GET_MODE (operands[2]) != QImode
7656 && ((ix86_match_ccmode (insn, CCZmode)
7657 && !(INTVAL (operands[3]) & ~(255 << 8)))
7658 || (ix86_match_ccmode (insn, CCNOmode)
7659 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7662 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7666 operands[2] = gen_lowpart (SImode, operands[2]);
7667 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7671 [(set (match_operand 0 "flags_reg_operand" "")
7672 (match_operator 1 "compare_operator"
7673 [(and (match_operand 2 "nonimmediate_operand" "")
7674 (match_operand 3 "const_int_operand" ""))
7677 && GET_MODE (operands[2]) != QImode
7678 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7679 && ((ix86_match_ccmode (insn, CCZmode)
7680 && !(INTVAL (operands[3]) & ~255))
7681 || (ix86_match_ccmode (insn, CCNOmode)
7682 && !(INTVAL (operands[3]) & ~127)))"
7684 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7687 operands[2] = gen_lowpart (QImode, operands[2]);
7688 operands[3] = gen_lowpart (QImode, operands[3]);
7691 ;; %%% This used to optimize known byte-wide and operations to memory,
7692 ;; and sometimes to QImode registers. If this is considered useful,
7693 ;; it should be done with splitters.
7695 (define_expand "and<mode>3"
7696 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7697 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7698 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7701 if (<MODE>mode == DImode
7702 && GET_CODE (operands[2]) == CONST_INT
7703 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7704 && REG_P (operands[1]))
7705 emit_insn (gen_zero_extendsidi2 (operands[0],
7706 gen_lowpart (SImode, operands[1])));
7708 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7712 (define_insn "*anddi_1"
7713 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7715 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7716 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7717 (clobber (reg:CC FLAGS_REG))]
7718 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7720 switch (get_attr_type (insn))
7724 enum machine_mode mode;
7726 gcc_assert (CONST_INT_P (operands[2]));
7727 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7729 else if (INTVAL (operands[2]) == 0xffff)
7733 gcc_assert (INTVAL (operands[2]) == 0xff);
7737 operands[1] = gen_lowpart (mode, operands[1]);
7739 return "mov{l}\t{%1, %k0|%k0, %1}";
7740 else if (mode == HImode)
7741 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7743 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7747 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7748 if (get_attr_mode (insn) == MODE_SI)
7749 return "and{l}\t{%k2, %k0|%k0, %k2}";
7751 return "and{q}\t{%2, %0|%0, %2}";
7754 [(set_attr "type" "alu,alu,alu,imovx")
7755 (set_attr "length_immediate" "*,*,*,0")
7756 (set (attr "prefix_rex")
7758 (and (eq_attr "type" "imovx")
7759 (and (match_test "INTVAL (operands[2]) == 0xff")
7760 (match_operand 1 "ext_QIreg_operand" "")))
7762 (const_string "*")))
7763 (set_attr "mode" "SI,DI,DI,SI")])
7765 (define_insn "*andsi_1"
7766 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7767 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7768 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7769 (clobber (reg:CC FLAGS_REG))]
7770 "ix86_binary_operator_ok (AND, SImode, operands)"
7772 switch (get_attr_type (insn))
7776 enum machine_mode mode;
7778 gcc_assert (CONST_INT_P (operands[2]));
7779 if (INTVAL (operands[2]) == 0xffff)
7783 gcc_assert (INTVAL (operands[2]) == 0xff);
7787 operands[1] = gen_lowpart (mode, operands[1]);
7789 return "movz{wl|x}\t{%1, %0|%0, %1}";
7791 return "movz{bl|x}\t{%1, %0|%0, %1}";
7795 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7796 return "and{l}\t{%2, %0|%0, %2}";
7799 [(set_attr "type" "alu,alu,imovx")
7800 (set (attr "prefix_rex")
7802 (and (eq_attr "type" "imovx")
7803 (and (match_test "INTVAL (operands[2]) == 0xff")
7804 (match_operand 1 "ext_QIreg_operand" "")))
7806 (const_string "*")))
7807 (set_attr "length_immediate" "*,*,0")
7808 (set_attr "mode" "SI")])
7810 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7811 (define_insn "*andsi_1_zext"
7812 [(set (match_operand:DI 0 "register_operand" "=r")
7814 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7815 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7816 (clobber (reg:CC FLAGS_REG))]
7817 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7818 "and{l}\t{%2, %k0|%k0, %2}"
7819 [(set_attr "type" "alu")
7820 (set_attr "mode" "SI")])
7822 (define_insn "*andhi_1"
7823 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7824 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7825 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7826 (clobber (reg:CC FLAGS_REG))]
7827 "ix86_binary_operator_ok (AND, HImode, operands)"
7829 switch (get_attr_type (insn))
7832 gcc_assert (CONST_INT_P (operands[2]));
7833 gcc_assert (INTVAL (operands[2]) == 0xff);
7834 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7837 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7839 return "and{w}\t{%2, %0|%0, %2}";
7842 [(set_attr "type" "alu,alu,imovx")
7843 (set_attr "length_immediate" "*,*,0")
7844 (set (attr "prefix_rex")
7846 (and (eq_attr "type" "imovx")
7847 (match_operand 1 "ext_QIreg_operand" ""))
7849 (const_string "*")))
7850 (set_attr "mode" "HI,HI,SI")])
7852 ;; %%% Potential partial reg stall on alternative 2. What to do?
7853 (define_insn "*andqi_1"
7854 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7855 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7856 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7857 (clobber (reg:CC FLAGS_REG))]
7858 "ix86_binary_operator_ok (AND, QImode, operands)"
7860 and{b}\t{%2, %0|%0, %2}
7861 and{b}\t{%2, %0|%0, %2}
7862 and{l}\t{%k2, %k0|%k0, %k2}"
7863 [(set_attr "type" "alu")
7864 (set_attr "mode" "QI,QI,SI")])
7866 (define_insn "*andqi_1_slp"
7867 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7868 (and:QI (match_dup 0)
7869 (match_operand:QI 1 "general_operand" "qn,qmn")))
7870 (clobber (reg:CC FLAGS_REG))]
7871 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7872 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7873 "and{b}\t{%1, %0|%0, %1}"
7874 [(set_attr "type" "alu1")
7875 (set_attr "mode" "QI")])
7878 [(set (match_operand 0 "register_operand" "")
7880 (const_int -65536)))
7881 (clobber (reg:CC FLAGS_REG))]
7882 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7883 || optimize_function_for_size_p (cfun)"
7884 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7885 "operands[1] = gen_lowpart (HImode, operands[0]);")
7888 [(set (match_operand 0 "ext_register_operand" "")
7891 (clobber (reg:CC FLAGS_REG))]
7892 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7893 && reload_completed"
7894 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7895 "operands[1] = gen_lowpart (QImode, operands[0]);")
7898 [(set (match_operand 0 "ext_register_operand" "")
7900 (const_int -65281)))
7901 (clobber (reg:CC FLAGS_REG))]
7902 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7903 && reload_completed"
7904 [(parallel [(set (zero_extract:SI (match_dup 0)
7908 (zero_extract:SI (match_dup 0)
7911 (zero_extract:SI (match_dup 0)
7914 (clobber (reg:CC FLAGS_REG))])]
7915 "operands[0] = gen_lowpart (SImode, operands[0]);")
7917 (define_insn "*anddi_2"
7918 [(set (reg FLAGS_REG)
7921 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7922 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7924 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7925 (and:DI (match_dup 1) (match_dup 2)))]
7927 && ix86_match_ccmode
7929 /* If we are going to emit andl instead of andq, and the operands[2]
7930 constant might have the SImode sign bit set, make sure the sign
7931 flag isn't tested, because the instruction will set the sign flag
7932 based on bit 31 rather than bit 63. If it isn't CONST_INT,
7933 conservatively assume it might have bit 31 set. */
7934 (satisfies_constraint_Z (operands[2])
7935 && (!CONST_INT_P (operands[2])
7936 || val_signbit_known_set_p (SImode, INTVAL (operands[2]))))
7937 ? CCZmode : CCNOmode)
7938 && ix86_binary_operator_ok (AND, DImode, operands)"
7940 and{l}\t{%k2, %k0|%k0, %k2}
7941 and{q}\t{%2, %0|%0, %2}
7942 and{q}\t{%2, %0|%0, %2}"
7943 [(set_attr "type" "alu")
7944 (set_attr "mode" "SI,DI,DI")])
7946 (define_insn "*andqi_2_maybe_si"
7947 [(set (reg FLAGS_REG)
7949 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7950 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7952 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7953 (and:QI (match_dup 1) (match_dup 2)))]
7954 "ix86_binary_operator_ok (AND, QImode, operands)
7955 && ix86_match_ccmode (insn,
7956 CONST_INT_P (operands[2])
7957 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7959 if (which_alternative == 2)
7961 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7962 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7963 return "and{l}\t{%2, %k0|%k0, %2}";
7965 return "and{b}\t{%2, %0|%0, %2}";
7967 [(set_attr "type" "alu")
7968 (set_attr "mode" "QI,QI,SI")])
7970 (define_insn "*and<mode>_2"
7971 [(set (reg FLAGS_REG)
7972 (compare (and:SWI124
7973 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7974 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7976 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7977 (and:SWI124 (match_dup 1) (match_dup 2)))]
7978 "ix86_match_ccmode (insn, CCNOmode)
7979 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7980 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7981 [(set_attr "type" "alu")
7982 (set_attr "mode" "<MODE>")])
7984 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7985 (define_insn "*andsi_2_zext"
7986 [(set (reg FLAGS_REG)
7988 (match_operand:SI 1 "nonimmediate_operand" "%0")
7989 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7991 (set (match_operand:DI 0 "register_operand" "=r")
7992 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7993 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7994 && ix86_binary_operator_ok (AND, SImode, operands)"
7995 "and{l}\t{%2, %k0|%k0, %2}"
7996 [(set_attr "type" "alu")
7997 (set_attr "mode" "SI")])
7999 (define_insn "*andqi_2_slp"
8000 [(set (reg FLAGS_REG)
8002 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8003 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8005 (set (strict_low_part (match_dup 0))
8006 (and:QI (match_dup 0) (match_dup 1)))]
8007 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8008 && ix86_match_ccmode (insn, CCNOmode)
8009 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8010 "and{b}\t{%1, %0|%0, %1}"
8011 [(set_attr "type" "alu1")
8012 (set_attr "mode" "QI")])
8014 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8015 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8016 ;; for a QImode operand, which of course failed.
8017 (define_insn "andqi_ext_0"
8018 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8023 (match_operand 1 "ext_register_operand" "0")
8026 (match_operand 2 "const_int_operand" "n")))
8027 (clobber (reg:CC FLAGS_REG))]
8029 "and{b}\t{%2, %h0|%h0, %2}"
8030 [(set_attr "type" "alu")
8031 (set_attr "length_immediate" "1")
8032 (set_attr "modrm" "1")
8033 (set_attr "mode" "QI")])
8035 ;; Generated by peephole translating test to and. This shows up
8036 ;; often in fp comparisons.
8037 (define_insn "*andqi_ext_0_cc"
8038 [(set (reg FLAGS_REG)
8042 (match_operand 1 "ext_register_operand" "0")
8045 (match_operand 2 "const_int_operand" "n"))
8047 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8056 "ix86_match_ccmode (insn, CCNOmode)"
8057 "and{b}\t{%2, %h0|%h0, %2}"
8058 [(set_attr "type" "alu")
8059 (set_attr "length_immediate" "1")
8060 (set_attr "modrm" "1")
8061 (set_attr "mode" "QI")])
8063 (define_insn "*andqi_ext_1_rex64"
8064 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8069 (match_operand 1 "ext_register_operand" "0")
8073 (match_operand 2 "ext_register_operand" "Q"))))
8074 (clobber (reg:CC FLAGS_REG))]
8076 "and{b}\t{%2, %h0|%h0, %2}"
8077 [(set_attr "type" "alu")
8078 (set_attr "length_immediate" "0")
8079 (set_attr "mode" "QI")])
8081 (define_insn "*andqi_ext_1"
8082 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8087 (match_operand 1 "ext_register_operand" "0")
8091 (match_operand:QI 2 "general_operand" "Qm"))))
8092 (clobber (reg:CC FLAGS_REG))]
8094 "and{b}\t{%2, %h0|%h0, %2}"
8095 [(set_attr "type" "alu")
8096 (set_attr "length_immediate" "0")
8097 (set_attr "mode" "QI")])
8099 (define_insn "*andqi_ext_2"
8100 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8105 (match_operand 1 "ext_register_operand" "%0")
8109 (match_operand 2 "ext_register_operand" "Q")
8112 (clobber (reg:CC FLAGS_REG))]
8114 "and{b}\t{%h2, %h0|%h0, %h2}"
8115 [(set_attr "type" "alu")
8116 (set_attr "length_immediate" "0")
8117 (set_attr "mode" "QI")])
8119 ;; Convert wide AND instructions with immediate operand to shorter QImode
8120 ;; equivalents when possible.
8121 ;; Don't do the splitting with memory operands, since it introduces risk
8122 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8123 ;; for size, but that can (should?) be handled by generic code instead.
8125 [(set (match_operand 0 "register_operand" "")
8126 (and (match_operand 1 "register_operand" "")
8127 (match_operand 2 "const_int_operand" "")))
8128 (clobber (reg:CC FLAGS_REG))]
8130 && QI_REG_P (operands[0])
8131 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8132 && !(~INTVAL (operands[2]) & ~(255 << 8))
8133 && GET_MODE (operands[0]) != QImode"
8134 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8135 (and:SI (zero_extract:SI (match_dup 1)
8136 (const_int 8) (const_int 8))
8138 (clobber (reg:CC FLAGS_REG))])]
8140 operands[0] = gen_lowpart (SImode, operands[0]);
8141 operands[1] = gen_lowpart (SImode, operands[1]);
8142 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8145 ;; Since AND can be encoded with sign extended immediate, this is only
8146 ;; profitable when 7th bit is not set.
8148 [(set (match_operand 0 "register_operand" "")
8149 (and (match_operand 1 "general_operand" "")
8150 (match_operand 2 "const_int_operand" "")))
8151 (clobber (reg:CC FLAGS_REG))]
8153 && ANY_QI_REG_P (operands[0])
8154 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8155 && !(~INTVAL (operands[2]) & ~255)
8156 && !(INTVAL (operands[2]) & 128)
8157 && GET_MODE (operands[0]) != QImode"
8158 [(parallel [(set (strict_low_part (match_dup 0))
8159 (and:QI (match_dup 1)
8161 (clobber (reg:CC FLAGS_REG))])]
8163 operands[0] = gen_lowpart (QImode, operands[0]);
8164 operands[1] = gen_lowpart (QImode, operands[1]);
8165 operands[2] = gen_lowpart (QImode, operands[2]);
8168 ;; Logical inclusive and exclusive OR instructions
8170 ;; %%% This used to optimize known byte-wide and operations to memory.
8171 ;; If this is considered useful, it should be done with splitters.
8173 (define_expand "<code><mode>3"
8174 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8175 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8176 (match_operand:SWIM 2 "<general_operand>" "")))]
8178 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8180 (define_insn "*<code><mode>_1"
8181 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8183 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8184 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8185 (clobber (reg:CC FLAGS_REG))]
8186 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8187 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8188 [(set_attr "type" "alu")
8189 (set_attr "mode" "<MODE>")])
8191 ;; %%% Potential partial reg stall on alternative 2. What to do?
8192 (define_insn "*<code>qi_1"
8193 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8194 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8195 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8196 (clobber (reg:CC FLAGS_REG))]
8197 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8199 <logic>{b}\t{%2, %0|%0, %2}
8200 <logic>{b}\t{%2, %0|%0, %2}
8201 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8202 [(set_attr "type" "alu")
8203 (set_attr "mode" "QI,QI,SI")])
8205 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8206 (define_insn "*<code>si_1_zext"
8207 [(set (match_operand:DI 0 "register_operand" "=r")
8209 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8210 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8211 (clobber (reg:CC FLAGS_REG))]
8212 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8213 "<logic>{l}\t{%2, %k0|%k0, %2}"
8214 [(set_attr "type" "alu")
8215 (set_attr "mode" "SI")])
8217 (define_insn "*<code>si_1_zext_imm"
8218 [(set (match_operand:DI 0 "register_operand" "=r")
8220 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8221 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8222 (clobber (reg:CC FLAGS_REG))]
8223 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8224 "<logic>{l}\t{%2, %k0|%k0, %2}"
8225 [(set_attr "type" "alu")
8226 (set_attr "mode" "SI")])
8228 (define_insn "*<code>qi_1_slp"
8229 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8230 (any_or:QI (match_dup 0)
8231 (match_operand:QI 1 "general_operand" "qmn,qn")))
8232 (clobber (reg:CC FLAGS_REG))]
8233 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8234 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8235 "<logic>{b}\t{%1, %0|%0, %1}"
8236 [(set_attr "type" "alu1")
8237 (set_attr "mode" "QI")])
8239 (define_insn "*<code><mode>_2"
8240 [(set (reg FLAGS_REG)
8241 (compare (any_or:SWI
8242 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8243 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8245 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8246 (any_or:SWI (match_dup 1) (match_dup 2)))]
8247 "ix86_match_ccmode (insn, CCNOmode)
8248 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8249 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8250 [(set_attr "type" "alu")
8251 (set_attr "mode" "<MODE>")])
8253 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8254 ;; ??? Special case for immediate operand is missing - it is tricky.
8255 (define_insn "*<code>si_2_zext"
8256 [(set (reg FLAGS_REG)
8257 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8258 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8260 (set (match_operand:DI 0 "register_operand" "=r")
8261 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8262 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8263 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8264 "<logic>{l}\t{%2, %k0|%k0, %2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "mode" "SI")])
8268 (define_insn "*<code>si_2_zext_imm"
8269 [(set (reg FLAGS_REG)
8271 (match_operand:SI 1 "nonimmediate_operand" "%0")
8272 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8274 (set (match_operand:DI 0 "register_operand" "=r")
8275 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8276 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8277 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8278 "<logic>{l}\t{%2, %k0|%k0, %2}"
8279 [(set_attr "type" "alu")
8280 (set_attr "mode" "SI")])
8282 (define_insn "*<code>qi_2_slp"
8283 [(set (reg FLAGS_REG)
8284 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8285 (match_operand:QI 1 "general_operand" "qmn,qn"))
8287 (set (strict_low_part (match_dup 0))
8288 (any_or:QI (match_dup 0) (match_dup 1)))]
8289 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8290 && ix86_match_ccmode (insn, CCNOmode)
8291 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8292 "<logic>{b}\t{%1, %0|%0, %1}"
8293 [(set_attr "type" "alu1")
8294 (set_attr "mode" "QI")])
8296 (define_insn "*<code><mode>_3"
8297 [(set (reg FLAGS_REG)
8298 (compare (any_or:SWI
8299 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8300 (match_operand:SWI 2 "<general_operand>" "<g>"))
8302 (clobber (match_scratch:SWI 0 "=<r>"))]
8303 "ix86_match_ccmode (insn, CCNOmode)
8304 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8305 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8306 [(set_attr "type" "alu")
8307 (set_attr "mode" "<MODE>")])
8309 (define_insn "*<code>qi_ext_0"
8310 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8315 (match_operand 1 "ext_register_operand" "0")
8318 (match_operand 2 "const_int_operand" "n")))
8319 (clobber (reg:CC FLAGS_REG))]
8320 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8321 "<logic>{b}\t{%2, %h0|%h0, %2}"
8322 [(set_attr "type" "alu")
8323 (set_attr "length_immediate" "1")
8324 (set_attr "modrm" "1")
8325 (set_attr "mode" "QI")])
8327 (define_insn "*<code>qi_ext_1_rex64"
8328 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8333 (match_operand 1 "ext_register_operand" "0")
8337 (match_operand 2 "ext_register_operand" "Q"))))
8338 (clobber (reg:CC FLAGS_REG))]
8340 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8341 "<logic>{b}\t{%2, %h0|%h0, %2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "length_immediate" "0")
8344 (set_attr "mode" "QI")])
8346 (define_insn "*<code>qi_ext_1"
8347 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8352 (match_operand 1 "ext_register_operand" "0")
8356 (match_operand:QI 2 "general_operand" "Qm"))))
8357 (clobber (reg:CC FLAGS_REG))]
8359 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8360 "<logic>{b}\t{%2, %h0|%h0, %2}"
8361 [(set_attr "type" "alu")
8362 (set_attr "length_immediate" "0")
8363 (set_attr "mode" "QI")])
8365 (define_insn "*<code>qi_ext_2"
8366 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8370 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8373 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8376 (clobber (reg:CC FLAGS_REG))]
8377 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8378 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8379 [(set_attr "type" "alu")
8380 (set_attr "length_immediate" "0")
8381 (set_attr "mode" "QI")])
8384 [(set (match_operand 0 "register_operand" "")
8385 (any_or (match_operand 1 "register_operand" "")
8386 (match_operand 2 "const_int_operand" "")))
8387 (clobber (reg:CC FLAGS_REG))]
8389 && QI_REG_P (operands[0])
8390 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8391 && !(INTVAL (operands[2]) & ~(255 << 8))
8392 && GET_MODE (operands[0]) != QImode"
8393 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8394 (any_or:SI (zero_extract:SI (match_dup 1)
8395 (const_int 8) (const_int 8))
8397 (clobber (reg:CC FLAGS_REG))])]
8399 operands[0] = gen_lowpart (SImode, operands[0]);
8400 operands[1] = gen_lowpart (SImode, operands[1]);
8401 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8404 ;; Since OR can be encoded with sign extended immediate, this is only
8405 ;; profitable when 7th bit is set.
8407 [(set (match_operand 0 "register_operand" "")
8408 (any_or (match_operand 1 "general_operand" "")
8409 (match_operand 2 "const_int_operand" "")))
8410 (clobber (reg:CC FLAGS_REG))]
8412 && ANY_QI_REG_P (operands[0])
8413 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8414 && !(INTVAL (operands[2]) & ~255)
8415 && (INTVAL (operands[2]) & 128)
8416 && GET_MODE (operands[0]) != QImode"
8417 [(parallel [(set (strict_low_part (match_dup 0))
8418 (any_or:QI (match_dup 1)
8420 (clobber (reg:CC FLAGS_REG))])]
8422 operands[0] = gen_lowpart (QImode, operands[0]);
8423 operands[1] = gen_lowpart (QImode, operands[1]);
8424 operands[2] = gen_lowpart (QImode, operands[2]);
8427 (define_expand "xorqi_cc_ext_1"
8429 (set (reg:CCNO FLAGS_REG)
8433 (match_operand 1 "ext_register_operand" "")
8436 (match_operand:QI 2 "general_operand" ""))
8438 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8448 (define_insn "*xorqi_cc_ext_1_rex64"
8449 [(set (reg FLAGS_REG)
8453 (match_operand 1 "ext_register_operand" "0")
8456 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8458 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8467 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8468 "xor{b}\t{%2, %h0|%h0, %2}"
8469 [(set_attr "type" "alu")
8470 (set_attr "modrm" "1")
8471 (set_attr "mode" "QI")])
8473 (define_insn "*xorqi_cc_ext_1"
8474 [(set (reg FLAGS_REG)
8478 (match_operand 1 "ext_register_operand" "0")
8481 (match_operand:QI 2 "general_operand" "qmn"))
8483 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8492 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8493 "xor{b}\t{%2, %h0|%h0, %2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "modrm" "1")
8496 (set_attr "mode" "QI")])
8498 ;; Negation instructions
8500 (define_expand "neg<mode>2"
8501 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8502 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8504 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8506 (define_insn_and_split "*neg<dwi>2_doubleword"
8507 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8508 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8509 (clobber (reg:CC FLAGS_REG))]
8510 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8514 [(set (reg:CCZ FLAGS_REG)
8515 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8516 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8519 (plus:DWIH (match_dup 3)
8520 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8522 (clobber (reg:CC FLAGS_REG))])
8525 (neg:DWIH (match_dup 2)))
8526 (clobber (reg:CC FLAGS_REG))])]
8527 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8529 (define_insn "*neg<mode>2_1"
8530 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8531 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8532 (clobber (reg:CC FLAGS_REG))]
8533 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8534 "neg{<imodesuffix>}\t%0"
8535 [(set_attr "type" "negnot")
8536 (set_attr "mode" "<MODE>")])
8538 ;; Combine is quite creative about this pattern.
8539 (define_insn "*negsi2_1_zext"
8540 [(set (match_operand:DI 0 "register_operand" "=r")
8542 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8545 (clobber (reg:CC FLAGS_REG))]
8546 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8548 [(set_attr "type" "negnot")
8549 (set_attr "mode" "SI")])
8551 ;; The problem with neg is that it does not perform (compare x 0),
8552 ;; it really performs (compare 0 x), which leaves us with the zero
8553 ;; flag being the only useful item.
8555 (define_insn "*neg<mode>2_cmpz"
8556 [(set (reg:CCZ FLAGS_REG)
8558 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8560 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8561 (neg:SWI (match_dup 1)))]
8562 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8563 "neg{<imodesuffix>}\t%0"
8564 [(set_attr "type" "negnot")
8565 (set_attr "mode" "<MODE>")])
8567 (define_insn "*negsi2_cmpz_zext"
8568 [(set (reg:CCZ FLAGS_REG)
8572 (match_operand:DI 1 "register_operand" "0")
8576 (set (match_operand:DI 0 "register_operand" "=r")
8577 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8580 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8582 [(set_attr "type" "negnot")
8583 (set_attr "mode" "SI")])
8585 ;; Changing of sign for FP values is doable using integer unit too.
8587 (define_expand "<code><mode>2"
8588 [(set (match_operand:X87MODEF 0 "register_operand" "")
8589 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8590 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8591 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8593 (define_insn "*absneg<mode>2_mixed"
8594 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8595 (match_operator:MODEF 3 "absneg_operator"
8596 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8597 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8598 (clobber (reg:CC FLAGS_REG))]
8599 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8602 (define_insn "*absneg<mode>2_sse"
8603 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8604 (match_operator:MODEF 3 "absneg_operator"
8605 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8606 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8607 (clobber (reg:CC FLAGS_REG))]
8608 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8611 (define_insn "*absneg<mode>2_i387"
8612 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8613 (match_operator:X87MODEF 3 "absneg_operator"
8614 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8615 (use (match_operand 2 "" ""))
8616 (clobber (reg:CC FLAGS_REG))]
8617 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8620 (define_expand "<code>tf2"
8621 [(set (match_operand:TF 0 "register_operand" "")
8622 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8624 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8626 (define_insn "*absnegtf2_sse"
8627 [(set (match_operand:TF 0 "register_operand" "=x,x")
8628 (match_operator:TF 3 "absneg_operator"
8629 [(match_operand:TF 1 "register_operand" "0,x")]))
8630 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8631 (clobber (reg:CC FLAGS_REG))]
8635 ;; Splitters for fp abs and neg.
8638 [(set (match_operand 0 "fp_register_operand" "")
8639 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8640 (use (match_operand 2 "" ""))
8641 (clobber (reg:CC FLAGS_REG))]
8643 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8646 [(set (match_operand 0 "register_operand" "")
8647 (match_operator 3 "absneg_operator"
8648 [(match_operand 1 "register_operand" "")]))
8649 (use (match_operand 2 "nonimmediate_operand" ""))
8650 (clobber (reg:CC FLAGS_REG))]
8651 "reload_completed && SSE_REG_P (operands[0])"
8652 [(set (match_dup 0) (match_dup 3))]
8654 enum machine_mode mode = GET_MODE (operands[0]);
8655 enum machine_mode vmode = GET_MODE (operands[2]);
8658 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8659 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8660 if (operands_match_p (operands[0], operands[2]))
8663 operands[1] = operands[2];
8666 if (GET_CODE (operands[3]) == ABS)
8667 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8669 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8674 [(set (match_operand:SF 0 "register_operand" "")
8675 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8676 (use (match_operand:V4SF 2 "" ""))
8677 (clobber (reg:CC FLAGS_REG))]
8679 [(parallel [(set (match_dup 0) (match_dup 1))
8680 (clobber (reg:CC FLAGS_REG))])]
8683 operands[0] = gen_lowpart (SImode, operands[0]);
8684 if (GET_CODE (operands[1]) == ABS)
8686 tmp = gen_int_mode (0x7fffffff, SImode);
8687 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8691 tmp = gen_int_mode (0x80000000, SImode);
8692 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8698 [(set (match_operand:DF 0 "register_operand" "")
8699 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8700 (use (match_operand 2 "" ""))
8701 (clobber (reg:CC FLAGS_REG))]
8703 [(parallel [(set (match_dup 0) (match_dup 1))
8704 (clobber (reg:CC FLAGS_REG))])]
8709 tmp = gen_lowpart (DImode, operands[0]);
8710 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8713 if (GET_CODE (operands[1]) == ABS)
8716 tmp = gen_rtx_NOT (DImode, tmp);
8720 operands[0] = gen_highpart (SImode, operands[0]);
8721 if (GET_CODE (operands[1]) == ABS)
8723 tmp = gen_int_mode (0x7fffffff, SImode);
8724 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8728 tmp = gen_int_mode (0x80000000, SImode);
8729 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8736 [(set (match_operand:XF 0 "register_operand" "")
8737 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8738 (use (match_operand 2 "" ""))
8739 (clobber (reg:CC FLAGS_REG))]
8741 [(parallel [(set (match_dup 0) (match_dup 1))
8742 (clobber (reg:CC FLAGS_REG))])]
8745 operands[0] = gen_rtx_REG (SImode,
8746 true_regnum (operands[0])
8747 + (TARGET_64BIT ? 1 : 2));
8748 if (GET_CODE (operands[1]) == ABS)
8750 tmp = GEN_INT (0x7fff);
8751 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8755 tmp = GEN_INT (0x8000);
8756 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8761 ;; Conditionalize these after reload. If they match before reload, we
8762 ;; lose the clobber and ability to use integer instructions.
8764 (define_insn "*<code><mode>2_1"
8765 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8766 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8768 && (reload_completed
8769 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8770 "f<absneg_mnemonic>"
8771 [(set_attr "type" "fsgn")
8772 (set_attr "mode" "<MODE>")])
8774 (define_insn "*<code>extendsfdf2"
8775 [(set (match_operand:DF 0 "register_operand" "=f")
8776 (absneg:DF (float_extend:DF
8777 (match_operand:SF 1 "register_operand" "0"))))]
8778 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8779 "f<absneg_mnemonic>"
8780 [(set_attr "type" "fsgn")
8781 (set_attr "mode" "DF")])
8783 (define_insn "*<code>extendsfxf2"
8784 [(set (match_operand:XF 0 "register_operand" "=f")
8785 (absneg:XF (float_extend:XF
8786 (match_operand:SF 1 "register_operand" "0"))))]
8788 "f<absneg_mnemonic>"
8789 [(set_attr "type" "fsgn")
8790 (set_attr "mode" "XF")])
8792 (define_insn "*<code>extenddfxf2"
8793 [(set (match_operand:XF 0 "register_operand" "=f")
8794 (absneg:XF (float_extend:XF
8795 (match_operand:DF 1 "register_operand" "0"))))]
8797 "f<absneg_mnemonic>"
8798 [(set_attr "type" "fsgn")
8799 (set_attr "mode" "XF")])
8801 ;; Copysign instructions
8803 (define_mode_iterator CSGNMODE [SF DF TF])
8804 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8806 (define_expand "copysign<mode>3"
8807 [(match_operand:CSGNMODE 0 "register_operand" "")
8808 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8809 (match_operand:CSGNMODE 2 "register_operand" "")]
8810 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8811 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8812 "ix86_expand_copysign (operands); DONE;")
8814 (define_insn_and_split "copysign<mode>3_const"
8815 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8817 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8818 (match_operand:CSGNMODE 2 "register_operand" "0")
8819 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8821 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8822 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8824 "&& reload_completed"
8826 "ix86_split_copysign_const (operands); DONE;")
8828 (define_insn "copysign<mode>3_var"
8829 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8831 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8832 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8833 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8834 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8836 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8837 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8838 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8842 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8844 [(match_operand:CSGNMODE 2 "register_operand" "")
8845 (match_operand:CSGNMODE 3 "register_operand" "")
8846 (match_operand:<CSGNVMODE> 4 "" "")
8847 (match_operand:<CSGNVMODE> 5 "" "")]
8849 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8850 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8851 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8852 && reload_completed"
8854 "ix86_split_copysign_var (operands); DONE;")
8856 ;; One complement instructions
8858 (define_expand "one_cmpl<mode>2"
8859 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8860 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8862 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8864 (define_insn "*one_cmpl<mode>2_1"
8865 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8866 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8867 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8868 "not{<imodesuffix>}\t%0"
8869 [(set_attr "type" "negnot")
8870 (set_attr "mode" "<MODE>")])
8872 ;; %%% Potential partial reg stall on alternative 1. What to do?
8873 (define_insn "*one_cmplqi2_1"
8874 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8875 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8876 "ix86_unary_operator_ok (NOT, QImode, operands)"
8880 [(set_attr "type" "negnot")
8881 (set_attr "mode" "QI,SI")])
8883 ;; ??? Currently never generated - xor is used instead.
8884 (define_insn "*one_cmplsi2_1_zext"
8885 [(set (match_operand:DI 0 "register_operand" "=r")
8887 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8888 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8890 [(set_attr "type" "negnot")
8891 (set_attr "mode" "SI")])
8893 (define_insn "*one_cmpl<mode>2_2"
8894 [(set (reg FLAGS_REG)
8895 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8897 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8898 (not:SWI (match_dup 1)))]
8899 "ix86_match_ccmode (insn, CCNOmode)
8900 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8902 [(set_attr "type" "alu1")
8903 (set_attr "mode" "<MODE>")])
8906 [(set (match_operand 0 "flags_reg_operand" "")
8907 (match_operator 2 "compare_operator"
8908 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8910 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8911 (not:SWI (match_dup 3)))]
8912 "ix86_match_ccmode (insn, CCNOmode)"
8913 [(parallel [(set (match_dup 0)
8914 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8917 (xor:SWI (match_dup 3) (const_int -1)))])])
8919 ;; ??? Currently never generated - xor is used instead.
8920 (define_insn "*one_cmplsi2_2_zext"
8921 [(set (reg FLAGS_REG)
8922 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8924 (set (match_operand:DI 0 "register_operand" "=r")
8925 (zero_extend:DI (not:SI (match_dup 1))))]
8926 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8927 && ix86_unary_operator_ok (NOT, SImode, operands)"
8929 [(set_attr "type" "alu1")
8930 (set_attr "mode" "SI")])
8933 [(set (match_operand 0 "flags_reg_operand" "")
8934 (match_operator 2 "compare_operator"
8935 [(not:SI (match_operand:SI 3 "register_operand" ""))
8937 (set (match_operand:DI 1 "register_operand" "")
8938 (zero_extend:DI (not:SI (match_dup 3))))]
8939 "ix86_match_ccmode (insn, CCNOmode)"
8940 [(parallel [(set (match_dup 0)
8941 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8944 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8946 ;; Shift instructions
8948 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8949 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8950 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8951 ;; from the assembler input.
8953 ;; This instruction shifts the target reg/mem as usual, but instead of
8954 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8955 ;; is a left shift double, bits are taken from the high order bits of
8956 ;; reg, else if the insn is a shift right double, bits are taken from the
8957 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8958 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8960 ;; Since sh[lr]d does not change the `reg' operand, that is done
8961 ;; separately, making all shifts emit pairs of shift double and normal
8962 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8963 ;; support a 63 bit shift, each shift where the count is in a reg expands
8964 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8966 ;; If the shift count is a constant, we need never emit more than one
8967 ;; shift pair, instead using moves and sign extension for counts greater
8970 (define_expand "ashl<mode>3"
8971 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8972 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8973 (match_operand:QI 2 "nonmemory_operand" "")))]
8975 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8977 (define_insn "*ashl<mode>3_doubleword"
8978 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8979 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8980 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8981 (clobber (reg:CC FLAGS_REG))]
8984 [(set_attr "type" "multi")])
8987 [(set (match_operand:DWI 0 "register_operand" "")
8988 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8989 (match_operand:QI 2 "nonmemory_operand" "")))
8990 (clobber (reg:CC FLAGS_REG))]
8991 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8993 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8995 ;; By default we don't ask for a scratch register, because when DWImode
8996 ;; values are manipulated, registers are already at a premium. But if
8997 ;; we have one handy, we won't turn it away.
9000 [(match_scratch:DWIH 3 "r")
9001 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9003 (match_operand:<DWI> 1 "nonmemory_operand" "")
9004 (match_operand:QI 2 "nonmemory_operand" "")))
9005 (clobber (reg:CC FLAGS_REG))])
9009 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9011 (define_insn "x86_64_shld"
9012 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9013 (ior:DI (ashift:DI (match_dup 0)
9014 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9015 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9016 (minus:QI (const_int 64) (match_dup 2)))))
9017 (clobber (reg:CC FLAGS_REG))]
9019 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9020 [(set_attr "type" "ishift")
9021 (set_attr "prefix_0f" "1")
9022 (set_attr "mode" "DI")
9023 (set_attr "athlon_decode" "vector")
9024 (set_attr "amdfam10_decode" "vector")
9025 (set_attr "bdver1_decode" "vector")])
9027 (define_insn "x86_shld"
9028 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9029 (ior:SI (ashift:SI (match_dup 0)
9030 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9031 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9032 (minus:QI (const_int 32) (match_dup 2)))))
9033 (clobber (reg:CC FLAGS_REG))]
9035 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9036 [(set_attr "type" "ishift")
9037 (set_attr "prefix_0f" "1")
9038 (set_attr "mode" "SI")
9039 (set_attr "pent_pair" "np")
9040 (set_attr "athlon_decode" "vector")
9041 (set_attr "amdfam10_decode" "vector")
9042 (set_attr "bdver1_decode" "vector")])
9044 (define_expand "x86_shift<mode>_adj_1"
9045 [(set (reg:CCZ FLAGS_REG)
9046 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9049 (set (match_operand:SWI48 0 "register_operand" "")
9050 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9051 (match_operand:SWI48 1 "register_operand" "")
9054 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9055 (match_operand:SWI48 3 "register_operand" "")
9058 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9060 (define_expand "x86_shift<mode>_adj_2"
9061 [(use (match_operand:SWI48 0 "register_operand" ""))
9062 (use (match_operand:SWI48 1 "register_operand" ""))
9063 (use (match_operand:QI 2 "register_operand" ""))]
9066 rtx label = gen_label_rtx ();
9069 emit_insn (gen_testqi_ccz_1 (operands[2],
9070 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9072 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9073 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9074 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9075 gen_rtx_LABEL_REF (VOIDmode, label),
9077 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9078 JUMP_LABEL (tmp) = label;
9080 emit_move_insn (operands[0], operands[1]);
9081 ix86_expand_clear (operands[1]);
9084 LABEL_NUSES (label) = 1;
9089 ;; Avoid useless masking of count operand.
9090 (define_insn "*ashl<mode>3_mask"
9091 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9093 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9096 (match_operand:SI 2 "register_operand" "c")
9097 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9098 (clobber (reg:CC FLAGS_REG))]
9099 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9100 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9101 == GET_MODE_BITSIZE (<MODE>mode)-1"
9103 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9105 [(set_attr "type" "ishift")
9106 (set_attr "mode" "<MODE>")])
9108 (define_insn "*bmi2_ashl<mode>3_1"
9109 [(set (match_operand:SWI48 0 "register_operand" "=r")
9110 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9111 (match_operand:SWI48 2 "register_operand" "r")))]
9113 "shlx\t{%2, %1, %0|%0, %1, %2}"
9114 [(set_attr "type" "ishiftx")
9115 (set_attr "mode" "<MODE>")])
9117 (define_insn "*ashl<mode>3_1"
9118 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9119 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9120 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9121 (clobber (reg:CC FLAGS_REG))]
9122 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9124 switch (get_attr_type (insn))
9131 gcc_assert (operands[2] == const1_rtx);
9132 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9133 return "add{<imodesuffix>}\t%0, %0";
9136 if (operands[2] == const1_rtx
9137 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9138 return "sal{<imodesuffix>}\t%0";
9140 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9143 [(set_attr "isa" "*,*,bmi2")
9145 (cond [(eq_attr "alternative" "1")
9146 (const_string "lea")
9147 (eq_attr "alternative" "2")
9148 (const_string "ishiftx")
9149 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9150 (match_operand 0 "register_operand" ""))
9151 (match_operand 2 "const1_operand" ""))
9152 (const_string "alu")
9154 (const_string "ishift")))
9155 (set (attr "length_immediate")
9157 (ior (eq_attr "type" "alu")
9158 (and (eq_attr "type" "ishift")
9159 (and (match_operand 2 "const1_operand" "")
9160 (ior (match_test "TARGET_SHIFT1")
9161 (match_test "optimize_function_for_size_p (cfun)")))))
9163 (const_string "*")))
9164 (set_attr "mode" "<MODE>")])
9166 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9168 [(set (match_operand:SWI48 0 "register_operand" "")
9169 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9170 (match_operand:QI 2 "register_operand" "")))
9171 (clobber (reg:CC FLAGS_REG))]
9172 "TARGET_BMI2 && reload_completed"
9174 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9175 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9177 (define_insn "*bmi2_ashlsi3_1_zext"
9178 [(set (match_operand:DI 0 "register_operand" "=r")
9180 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9181 (match_operand:SI 2 "register_operand" "r"))))]
9182 "TARGET_64BIT && TARGET_BMI2"
9183 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9184 [(set_attr "type" "ishiftx")
9185 (set_attr "mode" "SI")])
9187 (define_insn "*ashlsi3_1_zext"
9188 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9190 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9191 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9192 (clobber (reg:CC FLAGS_REG))]
9193 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9195 switch (get_attr_type (insn))
9202 gcc_assert (operands[2] == const1_rtx);
9203 return "add{l}\t%k0, %k0";
9206 if (operands[2] == const1_rtx
9207 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9208 return "sal{l}\t%k0";
9210 return "sal{l}\t{%2, %k0|%k0, %2}";
9213 [(set_attr "isa" "*,*,bmi2")
9215 (cond [(eq_attr "alternative" "1")
9216 (const_string "lea")
9217 (eq_attr "alternative" "2")
9218 (const_string "ishiftx")
9219 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9220 (match_operand 2 "const1_operand" ""))
9221 (const_string "alu")
9223 (const_string "ishift")))
9224 (set (attr "length_immediate")
9226 (ior (eq_attr "type" "alu")
9227 (and (eq_attr "type" "ishift")
9228 (and (match_operand 2 "const1_operand" "")
9229 (ior (match_test "TARGET_SHIFT1")
9230 (match_test "optimize_function_for_size_p (cfun)")))))
9232 (const_string "*")))
9233 (set_attr "mode" "SI")])
9235 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9237 [(set (match_operand:DI 0 "register_operand" "")
9239 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9240 (match_operand:QI 2 "register_operand" ""))))
9241 (clobber (reg:CC FLAGS_REG))]
9242 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9244 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9245 "operands[2] = gen_lowpart (SImode, operands[2]);")
9247 (define_insn "*ashlhi3_1"
9248 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9249 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9250 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9251 (clobber (reg:CC FLAGS_REG))]
9252 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9254 switch (get_attr_type (insn))
9260 gcc_assert (operands[2] == const1_rtx);
9261 return "add{w}\t%0, %0";
9264 if (operands[2] == const1_rtx
9265 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9266 return "sal{w}\t%0";
9268 return "sal{w}\t{%2, %0|%0, %2}";
9272 (cond [(eq_attr "alternative" "1")
9273 (const_string "lea")
9274 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9275 (match_operand 0 "register_operand" ""))
9276 (match_operand 2 "const1_operand" ""))
9277 (const_string "alu")
9279 (const_string "ishift")))
9280 (set (attr "length_immediate")
9282 (ior (eq_attr "type" "alu")
9283 (and (eq_attr "type" "ishift")
9284 (and (match_operand 2 "const1_operand" "")
9285 (ior (match_test "TARGET_SHIFT1")
9286 (match_test "optimize_function_for_size_p (cfun)")))))
9288 (const_string "*")))
9289 (set_attr "mode" "HI,SI")])
9291 ;; %%% Potential partial reg stall on alternative 1. What to do?
9292 (define_insn "*ashlqi3_1"
9293 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9294 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9295 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9296 (clobber (reg:CC FLAGS_REG))]
9297 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9299 switch (get_attr_type (insn))
9305 gcc_assert (operands[2] == const1_rtx);
9306 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9307 return "add{l}\t%k0, %k0";
9309 return "add{b}\t%0, %0";
9312 if (operands[2] == const1_rtx
9313 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9315 if (get_attr_mode (insn) == MODE_SI)
9316 return "sal{l}\t%k0";
9318 return "sal{b}\t%0";
9322 if (get_attr_mode (insn) == MODE_SI)
9323 return "sal{l}\t{%2, %k0|%k0, %2}";
9325 return "sal{b}\t{%2, %0|%0, %2}";
9330 (cond [(eq_attr "alternative" "2")
9331 (const_string "lea")
9332 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9333 (match_operand 0 "register_operand" ""))
9334 (match_operand 2 "const1_operand" ""))
9335 (const_string "alu")
9337 (const_string "ishift")))
9338 (set (attr "length_immediate")
9340 (ior (eq_attr "type" "alu")
9341 (and (eq_attr "type" "ishift")
9342 (and (match_operand 2 "const1_operand" "")
9343 (ior (match_test "TARGET_SHIFT1")
9344 (match_test "optimize_function_for_size_p (cfun)")))))
9346 (const_string "*")))
9347 (set_attr "mode" "QI,SI,SI")])
9349 (define_insn "*ashlqi3_1_slp"
9350 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9351 (ashift:QI (match_dup 0)
9352 (match_operand:QI 1 "nonmemory_operand" "cI")))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "(optimize_function_for_size_p (cfun)
9355 || !TARGET_PARTIAL_FLAG_REG_STALL
9356 || (operands[1] == const1_rtx
9358 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9360 switch (get_attr_type (insn))
9363 gcc_assert (operands[1] == const1_rtx);
9364 return "add{b}\t%0, %0";
9367 if (operands[1] == const1_rtx
9368 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9369 return "sal{b}\t%0";
9371 return "sal{b}\t{%1, %0|%0, %1}";
9375 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9376 (match_operand 0 "register_operand" ""))
9377 (match_operand 1 "const1_operand" ""))
9378 (const_string "alu")
9380 (const_string "ishift1")))
9381 (set (attr "length_immediate")
9383 (ior (eq_attr "type" "alu")
9384 (and (eq_attr "type" "ishift1")
9385 (and (match_operand 1 "const1_operand" "")
9386 (ior (match_test "TARGET_SHIFT1")
9387 (match_test "optimize_function_for_size_p (cfun)")))))
9389 (const_string "*")))
9390 (set_attr "mode" "QI")])
9392 ;; Convert ashift to the lea pattern to avoid flags dependency.
9394 [(set (match_operand 0 "register_operand" "")
9395 (ashift (match_operand 1 "index_register_operand" "")
9396 (match_operand:QI 2 "const_int_operand" "")))
9397 (clobber (reg:CC FLAGS_REG))]
9398 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9400 && true_regnum (operands[0]) != true_regnum (operands[1])"
9403 enum machine_mode mode = GET_MODE (operands[0]);
9406 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9409 operands[0] = gen_lowpart (mode, operands[0]);
9410 operands[1] = gen_lowpart (mode, operands[1]);
9413 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9415 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9417 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9421 ;; Convert ashift to the lea pattern to avoid flags dependency.
9423 [(set (match_operand:DI 0 "register_operand" "")
9425 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9426 (match_operand:QI 2 "const_int_operand" ""))))
9427 (clobber (reg:CC FLAGS_REG))]
9428 "TARGET_64BIT && reload_completed
9429 && true_regnum (operands[0]) != true_regnum (operands[1])"
9431 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9433 operands[1] = gen_lowpart (DImode, operands[1]);
9434 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9437 ;; This pattern can't accept a variable shift count, since shifts by
9438 ;; zero don't affect the flags. We assume that shifts by constant
9439 ;; zero are optimized away.
9440 (define_insn "*ashl<mode>3_cmp"
9441 [(set (reg FLAGS_REG)
9443 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9444 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9446 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9447 (ashift:SWI (match_dup 1) (match_dup 2)))]
9448 "(optimize_function_for_size_p (cfun)
9449 || !TARGET_PARTIAL_FLAG_REG_STALL
9450 || (operands[2] == const1_rtx
9452 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9453 && ix86_match_ccmode (insn, CCGOCmode)
9454 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9456 switch (get_attr_type (insn))
9459 gcc_assert (operands[2] == const1_rtx);
9460 return "add{<imodesuffix>}\t%0, %0";
9463 if (operands[2] == const1_rtx
9464 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9465 return "sal{<imodesuffix>}\t%0";
9467 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9471 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9472 (match_operand 0 "register_operand" ""))
9473 (match_operand 2 "const1_operand" ""))
9474 (const_string "alu")
9476 (const_string "ishift")))
9477 (set (attr "length_immediate")
9479 (ior (eq_attr "type" "alu")
9480 (and (eq_attr "type" "ishift")
9481 (and (match_operand 2 "const1_operand" "")
9482 (ior (match_test "TARGET_SHIFT1")
9483 (match_test "optimize_function_for_size_p (cfun)")))))
9485 (const_string "*")))
9486 (set_attr "mode" "<MODE>")])
9488 (define_insn "*ashlsi3_cmp_zext"
9489 [(set (reg FLAGS_REG)
9491 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9492 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9494 (set (match_operand:DI 0 "register_operand" "=r")
9495 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9497 && (optimize_function_for_size_p (cfun)
9498 || !TARGET_PARTIAL_FLAG_REG_STALL
9499 || (operands[2] == const1_rtx
9501 || TARGET_DOUBLE_WITH_ADD)))
9502 && ix86_match_ccmode (insn, CCGOCmode)
9503 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9505 switch (get_attr_type (insn))
9508 gcc_assert (operands[2] == const1_rtx);
9509 return "add{l}\t%k0, %k0";
9512 if (operands[2] == const1_rtx
9513 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9514 return "sal{l}\t%k0";
9516 return "sal{l}\t{%2, %k0|%k0, %2}";
9520 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9521 (match_operand 2 "const1_operand" ""))
9522 (const_string "alu")
9524 (const_string "ishift")))
9525 (set (attr "length_immediate")
9527 (ior (eq_attr "type" "alu")
9528 (and (eq_attr "type" "ishift")
9529 (and (match_operand 2 "const1_operand" "")
9530 (ior (match_test "TARGET_SHIFT1")
9531 (match_test "optimize_function_for_size_p (cfun)")))))
9533 (const_string "*")))
9534 (set_attr "mode" "SI")])
9536 (define_insn "*ashl<mode>3_cconly"
9537 [(set (reg FLAGS_REG)
9539 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9540 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9542 (clobber (match_scratch:SWI 0 "=<r>"))]
9543 "(optimize_function_for_size_p (cfun)
9544 || !TARGET_PARTIAL_FLAG_REG_STALL
9545 || (operands[2] == const1_rtx
9547 || TARGET_DOUBLE_WITH_ADD)))
9548 && ix86_match_ccmode (insn, CCGOCmode)"
9550 switch (get_attr_type (insn))
9553 gcc_assert (operands[2] == const1_rtx);
9554 return "add{<imodesuffix>}\t%0, %0";
9557 if (operands[2] == const1_rtx
9558 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9559 return "sal{<imodesuffix>}\t%0";
9561 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9565 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9566 (match_operand 0 "register_operand" ""))
9567 (match_operand 2 "const1_operand" ""))
9568 (const_string "alu")
9570 (const_string "ishift")))
9571 (set (attr "length_immediate")
9573 (ior (eq_attr "type" "alu")
9574 (and (eq_attr "type" "ishift")
9575 (and (match_operand 2 "const1_operand" "")
9576 (ior (match_test "TARGET_SHIFT1")
9577 (match_test "optimize_function_for_size_p (cfun)")))))
9579 (const_string "*")))
9580 (set_attr "mode" "<MODE>")])
9582 ;; See comment above `ashl<mode>3' about how this works.
9584 (define_expand "<shift_insn><mode>3"
9585 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9586 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9587 (match_operand:QI 2 "nonmemory_operand" "")))]
9589 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9591 ;; Avoid useless masking of count operand.
9592 (define_insn "*<shift_insn><mode>3_mask"
9593 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9595 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9598 (match_operand:SI 2 "register_operand" "c")
9599 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9600 (clobber (reg:CC FLAGS_REG))]
9601 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9602 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9603 == GET_MODE_BITSIZE (<MODE>mode)-1"
9605 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9607 [(set_attr "type" "ishift")
9608 (set_attr "mode" "<MODE>")])
9610 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9611 [(set (match_operand:DWI 0 "register_operand" "=r")
9612 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9613 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9614 (clobber (reg:CC FLAGS_REG))]
9617 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9619 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9620 [(set_attr "type" "multi")])
9622 ;; By default we don't ask for a scratch register, because when DWImode
9623 ;; values are manipulated, registers are already at a premium. But if
9624 ;; we have one handy, we won't turn it away.
9627 [(match_scratch:DWIH 3 "r")
9628 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9630 (match_operand:<DWI> 1 "register_operand" "")
9631 (match_operand:QI 2 "nonmemory_operand" "")))
9632 (clobber (reg:CC FLAGS_REG))])
9636 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9638 (define_insn "x86_64_shrd"
9639 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9640 (ior:DI (ashiftrt:DI (match_dup 0)
9641 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9642 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9643 (minus:QI (const_int 64) (match_dup 2)))))
9644 (clobber (reg:CC FLAGS_REG))]
9646 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9647 [(set_attr "type" "ishift")
9648 (set_attr "prefix_0f" "1")
9649 (set_attr "mode" "DI")
9650 (set_attr "athlon_decode" "vector")
9651 (set_attr "amdfam10_decode" "vector")
9652 (set_attr "bdver1_decode" "vector")])
9654 (define_insn "x86_shrd"
9655 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9656 (ior:SI (ashiftrt:SI (match_dup 0)
9657 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9658 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9659 (minus:QI (const_int 32) (match_dup 2)))))
9660 (clobber (reg:CC FLAGS_REG))]
9662 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9663 [(set_attr "type" "ishift")
9664 (set_attr "prefix_0f" "1")
9665 (set_attr "mode" "SI")
9666 (set_attr "pent_pair" "np")
9667 (set_attr "athlon_decode" "vector")
9668 (set_attr "amdfam10_decode" "vector")
9669 (set_attr "bdver1_decode" "vector")])
9671 (define_insn "ashrdi3_cvt"
9672 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9673 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9674 (match_operand:QI 2 "const_int_operand" "")))
9675 (clobber (reg:CC FLAGS_REG))]
9676 "TARGET_64BIT && INTVAL (operands[2]) == 63
9677 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9678 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9681 sar{q}\t{%2, %0|%0, %2}"
9682 [(set_attr "type" "imovx,ishift")
9683 (set_attr "prefix_0f" "0,*")
9684 (set_attr "length_immediate" "0,*")
9685 (set_attr "modrm" "0,1")
9686 (set_attr "mode" "DI")])
9688 (define_insn "ashrsi3_cvt"
9689 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9690 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9691 (match_operand:QI 2 "const_int_operand" "")))
9692 (clobber (reg:CC FLAGS_REG))]
9693 "INTVAL (operands[2]) == 31
9694 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9695 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9698 sar{l}\t{%2, %0|%0, %2}"
9699 [(set_attr "type" "imovx,ishift")
9700 (set_attr "prefix_0f" "0,*")
9701 (set_attr "length_immediate" "0,*")
9702 (set_attr "modrm" "0,1")
9703 (set_attr "mode" "SI")])
9705 (define_insn "*ashrsi3_cvt_zext"
9706 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9708 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9709 (match_operand:QI 2 "const_int_operand" ""))))
9710 (clobber (reg:CC FLAGS_REG))]
9711 "TARGET_64BIT && INTVAL (operands[2]) == 31
9712 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9713 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9716 sar{l}\t{%2, %k0|%k0, %2}"
9717 [(set_attr "type" "imovx,ishift")
9718 (set_attr "prefix_0f" "0,*")
9719 (set_attr "length_immediate" "0,*")
9720 (set_attr "modrm" "0,1")
9721 (set_attr "mode" "SI")])
9723 (define_expand "x86_shift<mode>_adj_3"
9724 [(use (match_operand:SWI48 0 "register_operand" ""))
9725 (use (match_operand:SWI48 1 "register_operand" ""))
9726 (use (match_operand:QI 2 "register_operand" ""))]
9729 rtx label = gen_label_rtx ();
9732 emit_insn (gen_testqi_ccz_1 (operands[2],
9733 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9735 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9736 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9737 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9738 gen_rtx_LABEL_REF (VOIDmode, label),
9740 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9741 JUMP_LABEL (tmp) = label;
9743 emit_move_insn (operands[0], operands[1]);
9744 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9745 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9747 LABEL_NUSES (label) = 1;
9752 (define_insn "*bmi2_<shift_insn><mode>3_1"
9753 [(set (match_operand:SWI48 0 "register_operand" "=r")
9754 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9755 (match_operand:SWI48 2 "register_operand" "r")))]
9757 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9758 [(set_attr "type" "ishiftx")
9759 (set_attr "mode" "<MODE>")])
9761 (define_insn "*<shift_insn><mode>3_1"
9762 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9764 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9765 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9766 (clobber (reg:CC FLAGS_REG))]
9767 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9769 switch (get_attr_type (insn))
9775 if (operands[2] == const1_rtx
9776 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9777 return "<shift>{<imodesuffix>}\t%0";
9779 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9782 [(set_attr "isa" "*,bmi2")
9783 (set_attr "type" "ishift,ishiftx")
9784 (set (attr "length_immediate")
9786 (and (match_operand 2 "const1_operand" "")
9787 (ior (match_test "TARGET_SHIFT1")
9788 (match_test "optimize_function_for_size_p (cfun)")))
9790 (const_string "*")))
9791 (set_attr "mode" "<MODE>")])
9793 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9795 [(set (match_operand:SWI48 0 "register_operand" "")
9796 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9797 (match_operand:QI 2 "register_operand" "")))
9798 (clobber (reg:CC FLAGS_REG))]
9799 "TARGET_BMI2 && reload_completed"
9801 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9802 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9804 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9805 [(set (match_operand:DI 0 "register_operand" "=r")
9807 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9808 (match_operand:SI 2 "register_operand" "r"))))]
9809 "TARGET_64BIT && TARGET_BMI2"
9810 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9811 [(set_attr "type" "ishiftx")
9812 (set_attr "mode" "SI")])
9814 (define_insn "*<shift_insn>si3_1_zext"
9815 [(set (match_operand:DI 0 "register_operand" "=r,r")
9817 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9818 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9819 (clobber (reg:CC FLAGS_REG))]
9820 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9822 switch (get_attr_type (insn))
9828 if (operands[2] == const1_rtx
9829 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9830 return "<shift>{l}\t%k0";
9832 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9835 [(set_attr "isa" "*,bmi2")
9836 (set_attr "type" "ishift,ishiftx")
9837 (set (attr "length_immediate")
9839 (and (match_operand 2 "const1_operand" "")
9840 (ior (match_test "TARGET_SHIFT1")
9841 (match_test "optimize_function_for_size_p (cfun)")))
9843 (const_string "*")))
9844 (set_attr "mode" "SI")])
9846 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9848 [(set (match_operand:DI 0 "register_operand" "")
9850 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9851 (match_operand:QI 2 "register_operand" ""))))
9852 (clobber (reg:CC FLAGS_REG))]
9853 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9855 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9856 "operands[2] = gen_lowpart (SImode, operands[2]);")
9858 (define_insn "*<shift_insn><mode>3_1"
9859 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9861 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9862 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9863 (clobber (reg:CC FLAGS_REG))]
9864 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9866 if (operands[2] == const1_rtx
9867 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9868 return "<shift>{<imodesuffix>}\t%0";
9870 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9872 [(set_attr "type" "ishift")
9873 (set (attr "length_immediate")
9875 (and (match_operand 2 "const1_operand" "")
9876 (ior (match_test "TARGET_SHIFT1")
9877 (match_test "optimize_function_for_size_p (cfun)")))
9879 (const_string "*")))
9880 (set_attr "mode" "<MODE>")])
9882 (define_insn "*<shift_insn>qi3_1_slp"
9883 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9884 (any_shiftrt:QI (match_dup 0)
9885 (match_operand:QI 1 "nonmemory_operand" "cI")))
9886 (clobber (reg:CC FLAGS_REG))]
9887 "(optimize_function_for_size_p (cfun)
9888 || !TARGET_PARTIAL_REG_STALL
9889 || (operands[1] == const1_rtx
9892 if (operands[1] == const1_rtx
9893 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9894 return "<shift>{b}\t%0";
9896 return "<shift>{b}\t{%1, %0|%0, %1}";
9898 [(set_attr "type" "ishift1")
9899 (set (attr "length_immediate")
9901 (and (match_operand 1 "const1_operand" "")
9902 (ior (match_test "TARGET_SHIFT1")
9903 (match_test "optimize_function_for_size_p (cfun)")))
9905 (const_string "*")))
9906 (set_attr "mode" "QI")])
9908 ;; This pattern can't accept a variable shift count, since shifts by
9909 ;; zero don't affect the flags. We assume that shifts by constant
9910 ;; zero are optimized away.
9911 (define_insn "*<shift_insn><mode>3_cmp"
9912 [(set (reg FLAGS_REG)
9915 (match_operand:SWI 1 "nonimmediate_operand" "0")
9916 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9918 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9919 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9920 "(optimize_function_for_size_p (cfun)
9921 || !TARGET_PARTIAL_FLAG_REG_STALL
9922 || (operands[2] == const1_rtx
9924 && ix86_match_ccmode (insn, CCGOCmode)
9925 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9927 if (operands[2] == const1_rtx
9928 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9929 return "<shift>{<imodesuffix>}\t%0";
9931 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9933 [(set_attr "type" "ishift")
9934 (set (attr "length_immediate")
9936 (and (match_operand 2 "const1_operand" "")
9937 (ior (match_test "TARGET_SHIFT1")
9938 (match_test "optimize_function_for_size_p (cfun)")))
9940 (const_string "*")))
9941 (set_attr "mode" "<MODE>")])
9943 (define_insn "*<shift_insn>si3_cmp_zext"
9944 [(set (reg FLAGS_REG)
9946 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9947 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9949 (set (match_operand:DI 0 "register_operand" "=r")
9950 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9952 && (optimize_function_for_size_p (cfun)
9953 || !TARGET_PARTIAL_FLAG_REG_STALL
9954 || (operands[2] == const1_rtx
9956 && ix86_match_ccmode (insn, CCGOCmode)
9957 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9959 if (operands[2] == const1_rtx
9960 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9961 return "<shift>{l}\t%k0";
9963 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9965 [(set_attr "type" "ishift")
9966 (set (attr "length_immediate")
9968 (and (match_operand 2 "const1_operand" "")
9969 (ior (match_test "TARGET_SHIFT1")
9970 (match_test "optimize_function_for_size_p (cfun)")))
9972 (const_string "*")))
9973 (set_attr "mode" "SI")])
9975 (define_insn "*<shift_insn><mode>3_cconly"
9976 [(set (reg FLAGS_REG)
9979 (match_operand:SWI 1 "register_operand" "0")
9980 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9982 (clobber (match_scratch:SWI 0 "=<r>"))]
9983 "(optimize_function_for_size_p (cfun)
9984 || !TARGET_PARTIAL_FLAG_REG_STALL
9985 || (operands[2] == const1_rtx
9987 && ix86_match_ccmode (insn, CCGOCmode)"
9989 if (operands[2] == const1_rtx
9990 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9991 return "<shift>{<imodesuffix>}\t%0";
9993 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9995 [(set_attr "type" "ishift")
9996 (set (attr "length_immediate")
9998 (and (match_operand 2 "const1_operand" "")
9999 (ior (match_test "TARGET_SHIFT1")
10000 (match_test "optimize_function_for_size_p (cfun)")))
10002 (const_string "*")))
10003 (set_attr "mode" "<MODE>")])
10005 ;; Rotate instructions
10007 (define_expand "<rotate_insn>ti3"
10008 [(set (match_operand:TI 0 "register_operand" "")
10009 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10010 (match_operand:QI 2 "nonmemory_operand" "")))]
10013 if (const_1_to_63_operand (operands[2], VOIDmode))
10014 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10015 (operands[0], operands[1], operands[2]));
10022 (define_expand "<rotate_insn>di3"
10023 [(set (match_operand:DI 0 "shiftdi_operand" "")
10024 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10025 (match_operand:QI 2 "nonmemory_operand" "")))]
10029 ix86_expand_binary_operator (<CODE>, DImode, operands);
10030 else if (const_1_to_31_operand (operands[2], VOIDmode))
10031 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10032 (operands[0], operands[1], operands[2]));
10039 (define_expand "<rotate_insn><mode>3"
10040 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10041 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10042 (match_operand:QI 2 "nonmemory_operand" "")))]
10044 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10046 ;; Avoid useless masking of count operand.
10047 (define_insn "*<rotate_insn><mode>3_mask"
10048 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10050 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10053 (match_operand:SI 2 "register_operand" "c")
10054 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10055 (clobber (reg:CC FLAGS_REG))]
10056 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10057 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10058 == GET_MODE_BITSIZE (<MODE>mode)-1"
10060 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10062 [(set_attr "type" "rotate")
10063 (set_attr "mode" "<MODE>")])
10065 ;; Implement rotation using two double-precision
10066 ;; shift instructions and a scratch register.
10068 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10069 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10070 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10071 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10072 (clobber (reg:CC FLAGS_REG))
10073 (clobber (match_scratch:DWIH 3 "=&r"))]
10077 [(set (match_dup 3) (match_dup 4))
10079 [(set (match_dup 4)
10080 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10081 (lshiftrt:DWIH (match_dup 5)
10082 (minus:QI (match_dup 6) (match_dup 2)))))
10083 (clobber (reg:CC FLAGS_REG))])
10085 [(set (match_dup 5)
10086 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10087 (lshiftrt:DWIH (match_dup 3)
10088 (minus:QI (match_dup 6) (match_dup 2)))))
10089 (clobber (reg:CC FLAGS_REG))])]
10091 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10093 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10096 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10097 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10098 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10099 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10100 (clobber (reg:CC FLAGS_REG))
10101 (clobber (match_scratch:DWIH 3 "=&r"))]
10105 [(set (match_dup 3) (match_dup 4))
10107 [(set (match_dup 4)
10108 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10109 (ashift:DWIH (match_dup 5)
10110 (minus:QI (match_dup 6) (match_dup 2)))))
10111 (clobber (reg:CC FLAGS_REG))])
10113 [(set (match_dup 5)
10114 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10115 (ashift:DWIH (match_dup 3)
10116 (minus:QI (match_dup 6) (match_dup 2)))))
10117 (clobber (reg:CC FLAGS_REG))])]
10119 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10121 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10124 (define_insn "*bmi2_rorx<mode>3_1"
10125 [(set (match_operand:SWI48 0 "register_operand" "=r")
10126 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10127 (match_operand:QI 2 "immediate_operand" "<S>")))]
10129 "rorx\t{%2, %1, %0|%0, %1, %2}"
10130 [(set_attr "type" "rotatex")
10131 (set_attr "mode" "<MODE>")])
10133 (define_insn "*<rotate_insn><mode>3_1"
10134 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10136 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10137 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10138 (clobber (reg:CC FLAGS_REG))]
10139 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10141 switch (get_attr_type (insn))
10147 if (operands[2] == const1_rtx
10148 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10149 return "<rotate>{<imodesuffix>}\t%0";
10151 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10154 [(set_attr "isa" "*,bmi2")
10155 (set_attr "type" "rotate,rotatex")
10156 (set (attr "length_immediate")
10158 (and (eq_attr "type" "rotate")
10159 (and (match_operand 2 "const1_operand" "")
10160 (ior (match_test "TARGET_SHIFT1")
10161 (match_test "optimize_function_for_size_p (cfun)"))))
10163 (const_string "*")))
10164 (set_attr "mode" "<MODE>")])
10166 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10168 [(set (match_operand:SWI48 0 "register_operand" "")
10169 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10170 (match_operand:QI 2 "immediate_operand" "")))
10171 (clobber (reg:CC FLAGS_REG))]
10172 "TARGET_BMI2 && reload_completed"
10173 [(set (match_dup 0)
10174 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10177 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10181 [(set (match_operand:SWI48 0 "register_operand" "")
10182 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10183 (match_operand:QI 2 "immediate_operand" "")))
10184 (clobber (reg:CC FLAGS_REG))]
10185 "TARGET_BMI2 && reload_completed"
10186 [(set (match_dup 0)
10187 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10189 (define_insn "*bmi2_rorxsi3_1_zext"
10190 [(set (match_operand:DI 0 "register_operand" "=r")
10192 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10193 (match_operand:QI 2 "immediate_operand" "I"))))]
10194 "TARGET_64BIT && TARGET_BMI2"
10195 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10196 [(set_attr "type" "rotatex")
10197 (set_attr "mode" "SI")])
10199 (define_insn "*<rotate_insn>si3_1_zext"
10200 [(set (match_operand:DI 0 "register_operand" "=r,r")
10202 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10203 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10204 (clobber (reg:CC FLAGS_REG))]
10205 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10207 switch (get_attr_type (insn))
10213 if (operands[2] == const1_rtx
10214 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10215 return "<rotate>{l}\t%k0";
10217 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10220 [(set_attr "isa" "*,bmi2")
10221 (set_attr "type" "rotate,rotatex")
10222 (set (attr "length_immediate")
10224 (and (eq_attr "type" "rotate")
10225 (and (match_operand 2 "const1_operand" "")
10226 (ior (match_test "TARGET_SHIFT1")
10227 (match_test "optimize_function_for_size_p (cfun)"))))
10229 (const_string "*")))
10230 (set_attr "mode" "SI")])
10232 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10234 [(set (match_operand:DI 0 "register_operand" "")
10236 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10237 (match_operand:QI 2 "immediate_operand" ""))))
10238 (clobber (reg:CC FLAGS_REG))]
10239 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10240 [(set (match_dup 0)
10241 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10244 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10248 [(set (match_operand:DI 0 "register_operand" "")
10250 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10251 (match_operand:QI 2 "immediate_operand" ""))))
10252 (clobber (reg:CC FLAGS_REG))]
10253 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10254 [(set (match_dup 0)
10255 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10257 (define_insn "*<rotate_insn><mode>3_1"
10258 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10259 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10260 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10261 (clobber (reg:CC FLAGS_REG))]
10262 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10264 if (operands[2] == const1_rtx
10265 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10266 return "<rotate>{<imodesuffix>}\t%0";
10268 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10270 [(set_attr "type" "rotate")
10271 (set (attr "length_immediate")
10273 (and (match_operand 2 "const1_operand" "")
10274 (ior (match_test "TARGET_SHIFT1")
10275 (match_test "optimize_function_for_size_p (cfun)")))
10277 (const_string "*")))
10278 (set_attr "mode" "<MODE>")])
10280 (define_insn "*<rotate_insn>qi3_1_slp"
10281 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10282 (any_rotate:QI (match_dup 0)
10283 (match_operand:QI 1 "nonmemory_operand" "cI")))
10284 (clobber (reg:CC FLAGS_REG))]
10285 "(optimize_function_for_size_p (cfun)
10286 || !TARGET_PARTIAL_REG_STALL
10287 || (operands[1] == const1_rtx
10288 && TARGET_SHIFT1))"
10290 if (operands[1] == const1_rtx
10291 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10292 return "<rotate>{b}\t%0";
10294 return "<rotate>{b}\t{%1, %0|%0, %1}";
10296 [(set_attr "type" "rotate1")
10297 (set (attr "length_immediate")
10299 (and (match_operand 1 "const1_operand" "")
10300 (ior (match_test "TARGET_SHIFT1")
10301 (match_test "optimize_function_for_size_p (cfun)")))
10303 (const_string "*")))
10304 (set_attr "mode" "QI")])
10307 [(set (match_operand:HI 0 "register_operand" "")
10308 (any_rotate:HI (match_dup 0) (const_int 8)))
10309 (clobber (reg:CC FLAGS_REG))]
10311 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10312 [(parallel [(set (strict_low_part (match_dup 0))
10313 (bswap:HI (match_dup 0)))
10314 (clobber (reg:CC FLAGS_REG))])])
10316 ;; Bit set / bit test instructions
10318 (define_expand "extv"
10319 [(set (match_operand:SI 0 "register_operand" "")
10320 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10321 (match_operand:SI 2 "const8_operand" "")
10322 (match_operand:SI 3 "const8_operand" "")))]
10325 /* Handle extractions from %ah et al. */
10326 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10329 /* From mips.md: extract_bit_field doesn't verify that our source
10330 matches the predicate, so check it again here. */
10331 if (! ext_register_operand (operands[1], VOIDmode))
10335 (define_expand "extzv"
10336 [(set (match_operand:SI 0 "register_operand" "")
10337 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10338 (match_operand:SI 2 "const8_operand" "")
10339 (match_operand:SI 3 "const8_operand" "")))]
10342 /* Handle extractions from %ah et al. */
10343 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10346 /* From mips.md: extract_bit_field doesn't verify that our source
10347 matches the predicate, so check it again here. */
10348 if (! ext_register_operand (operands[1], VOIDmode))
10352 (define_expand "insv"
10353 [(set (zero_extract (match_operand 0 "register_operand" "")
10354 (match_operand 1 "const_int_operand" "")
10355 (match_operand 2 "const_int_operand" ""))
10356 (match_operand 3 "register_operand" ""))]
10359 rtx (*gen_mov_insv_1) (rtx, rtx);
10361 if (ix86_expand_pinsr (operands))
10364 /* Handle insertions to %ah et al. */
10365 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10368 /* From mips.md: insert_bit_field doesn't verify that our source
10369 matches the predicate, so check it again here. */
10370 if (! ext_register_operand (operands[0], VOIDmode))
10373 gen_mov_insv_1 = (TARGET_64BIT
10374 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10376 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10380 ;; %%% bts, btr, btc, bt.
10381 ;; In general these instructions are *slow* when applied to memory,
10382 ;; since they enforce atomic operation. When applied to registers,
10383 ;; it depends on the cpu implementation. They're never faster than
10384 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10385 ;; no point. But in 64-bit, we can't hold the relevant immediates
10386 ;; within the instruction itself, so operating on bits in the high
10387 ;; 32-bits of a register becomes easier.
10389 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10390 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10391 ;; negdf respectively, so they can never be disabled entirely.
10393 (define_insn "*btsq"
10394 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10396 (match_operand:DI 1 "const_0_to_63_operand" ""))
10398 (clobber (reg:CC FLAGS_REG))]
10399 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10400 "bts{q}\t{%1, %0|%0, %1}"
10401 [(set_attr "type" "alu1")
10402 (set_attr "prefix_0f" "1")
10403 (set_attr "mode" "DI")])
10405 (define_insn "*btrq"
10406 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10408 (match_operand:DI 1 "const_0_to_63_operand" ""))
10410 (clobber (reg:CC FLAGS_REG))]
10411 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10412 "btr{q}\t{%1, %0|%0, %1}"
10413 [(set_attr "type" "alu1")
10414 (set_attr "prefix_0f" "1")
10415 (set_attr "mode" "DI")])
10417 (define_insn "*btcq"
10418 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10420 (match_operand:DI 1 "const_0_to_63_operand" ""))
10421 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10422 (clobber (reg:CC FLAGS_REG))]
10423 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10424 "btc{q}\t{%1, %0|%0, %1}"
10425 [(set_attr "type" "alu1")
10426 (set_attr "prefix_0f" "1")
10427 (set_attr "mode" "DI")])
10429 ;; Allow Nocona to avoid these instructions if a register is available.
10432 [(match_scratch:DI 2 "r")
10433 (parallel [(set (zero_extract:DI
10434 (match_operand:DI 0 "register_operand" "")
10436 (match_operand:DI 1 "const_0_to_63_operand" ""))
10438 (clobber (reg:CC FLAGS_REG))])]
10439 "TARGET_64BIT && !TARGET_USE_BT"
10442 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10445 if (HOST_BITS_PER_WIDE_INT >= 64)
10446 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10447 else if (i < HOST_BITS_PER_WIDE_INT)
10448 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10450 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10452 op1 = immed_double_const (lo, hi, DImode);
10455 emit_move_insn (operands[2], op1);
10459 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10464 [(match_scratch:DI 2 "r")
10465 (parallel [(set (zero_extract:DI
10466 (match_operand:DI 0 "register_operand" "")
10468 (match_operand:DI 1 "const_0_to_63_operand" ""))
10470 (clobber (reg:CC FLAGS_REG))])]
10471 "TARGET_64BIT && !TARGET_USE_BT"
10474 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10477 if (HOST_BITS_PER_WIDE_INT >= 64)
10478 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10479 else if (i < HOST_BITS_PER_WIDE_INT)
10480 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10482 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10484 op1 = immed_double_const (~lo, ~hi, DImode);
10487 emit_move_insn (operands[2], op1);
10491 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10496 [(match_scratch:DI 2 "r")
10497 (parallel [(set (zero_extract:DI
10498 (match_operand:DI 0 "register_operand" "")
10500 (match_operand:DI 1 "const_0_to_63_operand" ""))
10501 (not:DI (zero_extract:DI
10502 (match_dup 0) (const_int 1) (match_dup 1))))
10503 (clobber (reg:CC FLAGS_REG))])]
10504 "TARGET_64BIT && !TARGET_USE_BT"
10507 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10510 if (HOST_BITS_PER_WIDE_INT >= 64)
10511 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10512 else if (i < HOST_BITS_PER_WIDE_INT)
10513 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10515 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10517 op1 = immed_double_const (lo, hi, DImode);
10520 emit_move_insn (operands[2], op1);
10524 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10528 (define_insn "*bt<mode>"
10529 [(set (reg:CCC FLAGS_REG)
10531 (zero_extract:SWI48
10532 (match_operand:SWI48 0 "register_operand" "r")
10534 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10536 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10537 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10538 [(set_attr "type" "alu1")
10539 (set_attr "prefix_0f" "1")
10540 (set_attr "mode" "<MODE>")])
10542 ;; Store-flag instructions.
10544 ;; For all sCOND expanders, also expand the compare or test insn that
10545 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10547 (define_insn_and_split "*setcc_di_1"
10548 [(set (match_operand:DI 0 "register_operand" "=q")
10549 (match_operator:DI 1 "ix86_comparison_operator"
10550 [(reg FLAGS_REG) (const_int 0)]))]
10551 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10553 "&& reload_completed"
10554 [(set (match_dup 2) (match_dup 1))
10555 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10557 PUT_MODE (operands[1], QImode);
10558 operands[2] = gen_lowpart (QImode, operands[0]);
10561 (define_insn_and_split "*setcc_si_1_and"
10562 [(set (match_operand:SI 0 "register_operand" "=q")
10563 (match_operator:SI 1 "ix86_comparison_operator"
10564 [(reg FLAGS_REG) (const_int 0)]))
10565 (clobber (reg:CC FLAGS_REG))]
10566 "!TARGET_PARTIAL_REG_STALL
10567 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10569 "&& reload_completed"
10570 [(set (match_dup 2) (match_dup 1))
10571 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10572 (clobber (reg:CC FLAGS_REG))])]
10574 PUT_MODE (operands[1], QImode);
10575 operands[2] = gen_lowpart (QImode, operands[0]);
10578 (define_insn_and_split "*setcc_si_1_movzbl"
10579 [(set (match_operand:SI 0 "register_operand" "=q")
10580 (match_operator:SI 1 "ix86_comparison_operator"
10581 [(reg FLAGS_REG) (const_int 0)]))]
10582 "!TARGET_PARTIAL_REG_STALL
10583 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10585 "&& reload_completed"
10586 [(set (match_dup 2) (match_dup 1))
10587 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10589 PUT_MODE (operands[1], QImode);
10590 operands[2] = gen_lowpart (QImode, operands[0]);
10593 (define_insn "*setcc_qi"
10594 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10595 (match_operator:QI 1 "ix86_comparison_operator"
10596 [(reg FLAGS_REG) (const_int 0)]))]
10599 [(set_attr "type" "setcc")
10600 (set_attr "mode" "QI")])
10602 (define_insn "*setcc_qi_slp"
10603 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10604 (match_operator:QI 1 "ix86_comparison_operator"
10605 [(reg FLAGS_REG) (const_int 0)]))]
10608 [(set_attr "type" "setcc")
10609 (set_attr "mode" "QI")])
10611 ;; In general it is not safe to assume too much about CCmode registers,
10612 ;; so simplify-rtx stops when it sees a second one. Under certain
10613 ;; conditions this is safe on x86, so help combine not create
10620 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10621 (ne:QI (match_operator 1 "ix86_comparison_operator"
10622 [(reg FLAGS_REG) (const_int 0)])
10625 [(set (match_dup 0) (match_dup 1))]
10626 "PUT_MODE (operands[1], QImode);")
10629 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10630 (ne:QI (match_operator 1 "ix86_comparison_operator"
10631 [(reg FLAGS_REG) (const_int 0)])
10634 [(set (match_dup 0) (match_dup 1))]
10635 "PUT_MODE (operands[1], QImode);")
10638 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10639 (eq:QI (match_operator 1 "ix86_comparison_operator"
10640 [(reg FLAGS_REG) (const_int 0)])
10643 [(set (match_dup 0) (match_dup 1))]
10645 rtx new_op1 = copy_rtx (operands[1]);
10646 operands[1] = new_op1;
10647 PUT_MODE (new_op1, QImode);
10648 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10649 GET_MODE (XEXP (new_op1, 0))));
10651 /* Make sure that (a) the CCmode we have for the flags is strong
10652 enough for the reversed compare or (b) we have a valid FP compare. */
10653 if (! ix86_comparison_operator (new_op1, VOIDmode))
10658 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10659 (eq:QI (match_operator 1 "ix86_comparison_operator"
10660 [(reg FLAGS_REG) (const_int 0)])
10663 [(set (match_dup 0) (match_dup 1))]
10665 rtx new_op1 = copy_rtx (operands[1]);
10666 operands[1] = new_op1;
10667 PUT_MODE (new_op1, QImode);
10668 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10669 GET_MODE (XEXP (new_op1, 0))));
10671 /* Make sure that (a) the CCmode we have for the flags is strong
10672 enough for the reversed compare or (b) we have a valid FP compare. */
10673 if (! ix86_comparison_operator (new_op1, VOIDmode))
10677 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10678 ;; subsequent logical operations are used to imitate conditional moves.
10679 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10682 (define_insn "setcc_<mode>_sse"
10683 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10684 (match_operator:MODEF 3 "sse_comparison_operator"
10685 [(match_operand:MODEF 1 "register_operand" "0,x")
10686 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10687 "SSE_FLOAT_MODE_P (<MODE>mode)"
10689 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10690 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10691 [(set_attr "isa" "noavx,avx")
10692 (set_attr "type" "ssecmp")
10693 (set_attr "length_immediate" "1")
10694 (set_attr "prefix" "orig,vex")
10695 (set_attr "mode" "<MODE>")])
10697 ;; Basic conditional jump instructions.
10698 ;; We ignore the overflow flag for signed branch instructions.
10700 (define_insn "*jcc_1"
10702 (if_then_else (match_operator 1 "ix86_comparison_operator"
10703 [(reg FLAGS_REG) (const_int 0)])
10704 (label_ref (match_operand 0 "" ""))
10708 [(set_attr "type" "ibr")
10709 (set_attr "modrm" "0")
10710 (set (attr "length")
10711 (if_then_else (and (ge (minus (match_dup 0) (pc))
10713 (lt (minus (match_dup 0) (pc))
10718 (define_insn "*jcc_2"
10720 (if_then_else (match_operator 1 "ix86_comparison_operator"
10721 [(reg FLAGS_REG) (const_int 0)])
10723 (label_ref (match_operand 0 "" ""))))]
10726 [(set_attr "type" "ibr")
10727 (set_attr "modrm" "0")
10728 (set (attr "length")
10729 (if_then_else (and (ge (minus (match_dup 0) (pc))
10731 (lt (minus (match_dup 0) (pc))
10736 ;; In general it is not safe to assume too much about CCmode registers,
10737 ;; so simplify-rtx stops when it sees a second one. Under certain
10738 ;; conditions this is safe on x86, so help combine not create
10746 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10747 [(reg FLAGS_REG) (const_int 0)])
10749 (label_ref (match_operand 1 "" ""))
10753 (if_then_else (match_dup 0)
10754 (label_ref (match_dup 1))
10756 "PUT_MODE (operands[0], VOIDmode);")
10760 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10761 [(reg FLAGS_REG) (const_int 0)])
10763 (label_ref (match_operand 1 "" ""))
10767 (if_then_else (match_dup 0)
10768 (label_ref (match_dup 1))
10771 rtx new_op0 = copy_rtx (operands[0]);
10772 operands[0] = new_op0;
10773 PUT_MODE (new_op0, VOIDmode);
10774 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10775 GET_MODE (XEXP (new_op0, 0))));
10777 /* Make sure that (a) the CCmode we have for the flags is strong
10778 enough for the reversed compare or (b) we have a valid FP compare. */
10779 if (! ix86_comparison_operator (new_op0, VOIDmode))
10783 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10784 ;; pass generates from shift insn with QImode operand. Actually, the mode
10785 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10786 ;; appropriate modulo of the bit offset value.
10788 (define_insn_and_split "*jcc_bt<mode>"
10790 (if_then_else (match_operator 0 "bt_comparison_operator"
10791 [(zero_extract:SWI48
10792 (match_operand:SWI48 1 "register_operand" "r")
10795 (match_operand:QI 2 "register_operand" "r")))
10797 (label_ref (match_operand 3 "" ""))
10799 (clobber (reg:CC FLAGS_REG))]
10800 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10803 [(set (reg:CCC FLAGS_REG)
10805 (zero_extract:SWI48
10811 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10812 (label_ref (match_dup 3))
10815 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10817 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10820 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10821 ;; also for DImode, this is what combine produces.
10822 (define_insn_and_split "*jcc_bt<mode>_mask"
10824 (if_then_else (match_operator 0 "bt_comparison_operator"
10825 [(zero_extract:SWI48
10826 (match_operand:SWI48 1 "register_operand" "r")
10829 (match_operand:SI 2 "register_operand" "r")
10830 (match_operand:SI 3 "const_int_operand" "n")))])
10831 (label_ref (match_operand 4 "" ""))
10833 (clobber (reg:CC FLAGS_REG))]
10834 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10835 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10836 == GET_MODE_BITSIZE (<MODE>mode)-1"
10839 [(set (reg:CCC FLAGS_REG)
10841 (zero_extract:SWI48
10847 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10848 (label_ref (match_dup 4))
10851 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10853 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10856 (define_insn_and_split "*jcc_btsi_1"
10858 (if_then_else (match_operator 0 "bt_comparison_operator"
10861 (match_operand:SI 1 "register_operand" "r")
10862 (match_operand:QI 2 "register_operand" "r"))
10865 (label_ref (match_operand 3 "" ""))
10867 (clobber (reg:CC FLAGS_REG))]
10868 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10871 [(set (reg:CCC FLAGS_REG)
10879 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10880 (label_ref (match_dup 3))
10883 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10885 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10888 ;; avoid useless masking of bit offset operand
10889 (define_insn_and_split "*jcc_btsi_mask_1"
10892 (match_operator 0 "bt_comparison_operator"
10895 (match_operand:SI 1 "register_operand" "r")
10898 (match_operand:SI 2 "register_operand" "r")
10899 (match_operand:SI 3 "const_int_operand" "n")) 0))
10902 (label_ref (match_operand 4 "" ""))
10904 (clobber (reg:CC FLAGS_REG))]
10905 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10906 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10909 [(set (reg:CCC FLAGS_REG)
10917 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10918 (label_ref (match_dup 4))
10920 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10922 ;; Define combination compare-and-branch fp compare instructions to help
10925 (define_insn "*fp_jcc_1_387"
10927 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10928 [(match_operand 1 "register_operand" "f")
10929 (match_operand 2 "nonimmediate_operand" "fm")])
10930 (label_ref (match_operand 3 "" ""))
10932 (clobber (reg:CCFP FPSR_REG))
10933 (clobber (reg:CCFP FLAGS_REG))
10934 (clobber (match_scratch:HI 4 "=a"))]
10936 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10937 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10938 && SELECT_CC_MODE (GET_CODE (operands[0]),
10939 operands[1], operands[2]) == CCFPmode
10943 (define_insn "*fp_jcc_1r_387"
10945 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10946 [(match_operand 1 "register_operand" "f")
10947 (match_operand 2 "nonimmediate_operand" "fm")])
10949 (label_ref (match_operand 3 "" ""))))
10950 (clobber (reg:CCFP FPSR_REG))
10951 (clobber (reg:CCFP FLAGS_REG))
10952 (clobber (match_scratch:HI 4 "=a"))]
10954 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10955 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10956 && SELECT_CC_MODE (GET_CODE (operands[0]),
10957 operands[1], operands[2]) == CCFPmode
10961 (define_insn "*fp_jcc_2_387"
10963 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10964 [(match_operand 1 "register_operand" "f")
10965 (match_operand 2 "register_operand" "f")])
10966 (label_ref (match_operand 3 "" ""))
10968 (clobber (reg:CCFP FPSR_REG))
10969 (clobber (reg:CCFP FLAGS_REG))
10970 (clobber (match_scratch:HI 4 "=a"))]
10971 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10972 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10976 (define_insn "*fp_jcc_2r_387"
10978 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10979 [(match_operand 1 "register_operand" "f")
10980 (match_operand 2 "register_operand" "f")])
10982 (label_ref (match_operand 3 "" ""))))
10983 (clobber (reg:CCFP FPSR_REG))
10984 (clobber (reg:CCFP FLAGS_REG))
10985 (clobber (match_scratch:HI 4 "=a"))]
10986 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10987 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10991 (define_insn "*fp_jcc_3_387"
10993 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10994 [(match_operand 1 "register_operand" "f")
10995 (match_operand 2 "const0_operand" "")])
10996 (label_ref (match_operand 3 "" ""))
10998 (clobber (reg:CCFP FPSR_REG))
10999 (clobber (reg:CCFP FLAGS_REG))
11000 (clobber (match_scratch:HI 4 "=a"))]
11001 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11002 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11003 && SELECT_CC_MODE (GET_CODE (operands[0]),
11004 operands[1], operands[2]) == CCFPmode
11010 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11011 [(match_operand 1 "register_operand" "")
11012 (match_operand 2 "nonimmediate_operand" "")])
11013 (match_operand 3 "" "")
11014 (match_operand 4 "" "")))
11015 (clobber (reg:CCFP FPSR_REG))
11016 (clobber (reg:CCFP FLAGS_REG))]
11020 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11021 operands[3], operands[4], NULL_RTX, NULL_RTX);
11027 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11028 [(match_operand 1 "register_operand" "")
11029 (match_operand 2 "general_operand" "")])
11030 (match_operand 3 "" "")
11031 (match_operand 4 "" "")))
11032 (clobber (reg:CCFP FPSR_REG))
11033 (clobber (reg:CCFP FLAGS_REG))
11034 (clobber (match_scratch:HI 5 "=a"))]
11038 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11039 operands[3], operands[4], operands[5], NULL_RTX);
11043 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11044 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11045 ;; with a precedence over other operators and is always put in the first
11046 ;; place. Swap condition and operands to match ficom instruction.
11048 (define_insn "*fp_jcc_4_<mode>_387"
11051 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11052 [(match_operator 1 "float_operator"
11053 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11054 (match_operand 3 "register_operand" "f,f")])
11055 (label_ref (match_operand 4 "" ""))
11057 (clobber (reg:CCFP FPSR_REG))
11058 (clobber (reg:CCFP FLAGS_REG))
11059 (clobber (match_scratch:HI 5 "=a,a"))]
11060 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11061 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11062 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11063 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11070 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11071 [(match_operator 1 "float_operator"
11072 [(match_operand:SWI24 2 "memory_operand" "")])
11073 (match_operand 3 "register_operand" "")])
11074 (match_operand 4 "" "")
11075 (match_operand 5 "" "")))
11076 (clobber (reg:CCFP FPSR_REG))
11077 (clobber (reg:CCFP FLAGS_REG))
11078 (clobber (match_scratch:HI 6 "=a"))]
11082 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11084 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11085 operands[3], operands[7],
11086 operands[4], operands[5], operands[6], NULL_RTX);
11090 ;; %%% Kill this when reload knows how to do it.
11094 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11095 [(match_operator 1 "float_operator"
11096 [(match_operand:SWI24 2 "register_operand" "")])
11097 (match_operand 3 "register_operand" "")])
11098 (match_operand 4 "" "")
11099 (match_operand 5 "" "")))
11100 (clobber (reg:CCFP FPSR_REG))
11101 (clobber (reg:CCFP FLAGS_REG))
11102 (clobber (match_scratch:HI 6 "=a"))]
11106 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11107 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11109 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11110 operands[3], operands[7],
11111 operands[4], operands[5], operands[6], operands[2]);
11115 ;; Unconditional and other jump instructions
11117 (define_insn "jump"
11119 (label_ref (match_operand 0 "" "")))]
11122 [(set_attr "type" "ibr")
11123 (set (attr "length")
11124 (if_then_else (and (ge (minus (match_dup 0) (pc))
11126 (lt (minus (match_dup 0) (pc))
11130 (set_attr "modrm" "0")])
11132 (define_expand "indirect_jump"
11133 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11135 (define_insn "*indirect_jump"
11136 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11139 [(set_attr "type" "ibr")
11140 (set_attr "length_immediate" "0")])
11142 (define_expand "tablejump"
11143 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11144 (use (label_ref (match_operand 1 "" "")))])]
11147 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11148 relative. Convert the relative address to an absolute address. */
11152 enum rtx_code code;
11154 /* We can't use @GOTOFF for text labels on VxWorks;
11155 see gotoff_operand. */
11156 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11160 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11162 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11166 op1 = pic_offset_table_rtx;
11171 op0 = pic_offset_table_rtx;
11175 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11178 else if (TARGET_X32)
11179 operands[0] = convert_memory_address (Pmode, operands[0]);
11182 (define_insn "*tablejump_1"
11183 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11184 (use (label_ref (match_operand 1 "" "")))]
11187 [(set_attr "type" "ibr")
11188 (set_attr "length_immediate" "0")])
11190 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11193 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11194 (set (match_operand:QI 1 "register_operand" "")
11195 (match_operator:QI 2 "ix86_comparison_operator"
11196 [(reg FLAGS_REG) (const_int 0)]))
11197 (set (match_operand 3 "q_regs_operand" "")
11198 (zero_extend (match_dup 1)))]
11199 "(peep2_reg_dead_p (3, operands[1])
11200 || operands_match_p (operands[1], operands[3]))
11201 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11202 [(set (match_dup 4) (match_dup 0))
11203 (set (strict_low_part (match_dup 5))
11206 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11207 operands[5] = gen_lowpart (QImode, operands[3]);
11208 ix86_expand_clear (operands[3]);
11211 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11214 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11215 (set (match_operand:QI 1 "register_operand" "")
11216 (match_operator:QI 2 "ix86_comparison_operator"
11217 [(reg FLAGS_REG) (const_int 0)]))
11218 (parallel [(set (match_operand 3 "q_regs_operand" "")
11219 (zero_extend (match_dup 1)))
11220 (clobber (reg:CC FLAGS_REG))])]
11221 "(peep2_reg_dead_p (3, operands[1])
11222 || operands_match_p (operands[1], operands[3]))
11223 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11224 [(set (match_dup 4) (match_dup 0))
11225 (set (strict_low_part (match_dup 5))
11228 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11229 operands[5] = gen_lowpart (QImode, operands[3]);
11230 ix86_expand_clear (operands[3]);
11233 ;; Call instructions.
11235 ;; The predicates normally associated with named expanders are not properly
11236 ;; checked for calls. This is a bug in the generic code, but it isn't that
11237 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11239 ;; P6 processors will jump to the address after the decrement when %esp
11240 ;; is used as a call operand, so they will execute return address as a code.
11241 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11243 ;; Register constraint for call instruction.
11244 (define_mode_attr c [(SI "l") (DI "r")])
11246 ;; Call subroutine returning no value.
11248 (define_expand "call"
11249 [(call (match_operand:QI 0 "" "")
11250 (match_operand 1 "" ""))
11251 (use (match_operand 2 "" ""))]
11254 ix86_expand_call (NULL, operands[0], operands[1],
11255 operands[2], NULL, false);
11259 (define_expand "sibcall"
11260 [(call (match_operand:QI 0 "" "")
11261 (match_operand 1 "" ""))
11262 (use (match_operand 2 "" ""))]
11265 ix86_expand_call (NULL, operands[0], operands[1],
11266 operands[2], NULL, true);
11270 (define_insn_and_split "*call_vzeroupper"
11271 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11272 (match_operand 1 "" ""))
11273 (unspec [(match_operand 2 "const_int_operand" "")]
11274 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11275 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11277 "&& reload_completed"
11279 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11280 [(set_attr "type" "call")])
11282 (define_insn "*call"
11283 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11284 (match_operand 1 "" ""))]
11285 "!SIBLING_CALL_P (insn)"
11286 "* return ix86_output_call_insn (insn, operands[0]);"
11287 [(set_attr "type" "call")])
11289 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11290 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11291 (match_operand 1 "" ""))
11292 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11293 (clobber (reg:TI XMM6_REG))
11294 (clobber (reg:TI XMM7_REG))
11295 (clobber (reg:TI XMM8_REG))
11296 (clobber (reg:TI XMM9_REG))
11297 (clobber (reg:TI XMM10_REG))
11298 (clobber (reg:TI XMM11_REG))
11299 (clobber (reg:TI XMM12_REG))
11300 (clobber (reg:TI XMM13_REG))
11301 (clobber (reg:TI XMM14_REG))
11302 (clobber (reg:TI XMM15_REG))
11303 (clobber (reg:DI SI_REG))
11304 (clobber (reg:DI DI_REG))
11305 (unspec [(match_operand 2 "const_int_operand" "")]
11306 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11307 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11309 "&& reload_completed"
11311 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11312 [(set_attr "type" "call")])
11314 (define_insn "*call_rex64_ms_sysv"
11315 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11316 (match_operand 1 "" ""))
11317 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11318 (clobber (reg:TI XMM6_REG))
11319 (clobber (reg:TI XMM7_REG))
11320 (clobber (reg:TI XMM8_REG))
11321 (clobber (reg:TI XMM9_REG))
11322 (clobber (reg:TI XMM10_REG))
11323 (clobber (reg:TI XMM11_REG))
11324 (clobber (reg:TI XMM12_REG))
11325 (clobber (reg:TI XMM13_REG))
11326 (clobber (reg:TI XMM14_REG))
11327 (clobber (reg:TI XMM15_REG))
11328 (clobber (reg:DI SI_REG))
11329 (clobber (reg:DI DI_REG))]
11330 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11331 "* return ix86_output_call_insn (insn, operands[0]);"
11332 [(set_attr "type" "call")])
11334 (define_insn_and_split "*sibcall_vzeroupper"
11335 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11336 (match_operand 1 "" ""))
11337 (unspec [(match_operand 2 "const_int_operand" "")]
11338 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11339 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11341 "&& reload_completed"
11343 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11344 [(set_attr "type" "call")])
11346 (define_insn "*sibcall"
11347 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11348 (match_operand 1 "" ""))]
11349 "SIBLING_CALL_P (insn)"
11350 "* return ix86_output_call_insn (insn, operands[0]);"
11351 [(set_attr "type" "call")])
11353 (define_expand "call_pop"
11354 [(parallel [(call (match_operand:QI 0 "" "")
11355 (match_operand:SI 1 "" ""))
11356 (set (reg:SI SP_REG)
11357 (plus:SI (reg:SI SP_REG)
11358 (match_operand:SI 3 "" "")))])]
11361 ix86_expand_call (NULL, operands[0], operands[1],
11362 operands[2], operands[3], false);
11366 (define_insn_and_split "*call_pop_vzeroupper"
11367 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11368 (match_operand:SI 1 "" ""))
11369 (set (reg:SI SP_REG)
11370 (plus:SI (reg:SI SP_REG)
11371 (match_operand:SI 2 "immediate_operand" "i")))
11372 (unspec [(match_operand 3 "const_int_operand" "")]
11373 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11374 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11376 "&& reload_completed"
11378 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11379 [(set_attr "type" "call")])
11381 (define_insn "*call_pop"
11382 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11383 (match_operand 1 "" ""))
11384 (set (reg:SI SP_REG)
11385 (plus:SI (reg:SI SP_REG)
11386 (match_operand:SI 2 "immediate_operand" "i")))]
11387 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11388 "* return ix86_output_call_insn (insn, operands[0]);"
11389 [(set_attr "type" "call")])
11391 (define_insn_and_split "*sibcall_pop_vzeroupper"
11392 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11393 (match_operand 1 "" ""))
11394 (set (reg:SI SP_REG)
11395 (plus:SI (reg:SI SP_REG)
11396 (match_operand:SI 2 "immediate_operand" "i")))
11397 (unspec [(match_operand 3 "const_int_operand" "")]
11398 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11399 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11401 "&& reload_completed"
11403 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11404 [(set_attr "type" "call")])
11406 (define_insn "*sibcall_pop"
11407 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11408 (match_operand 1 "" ""))
11409 (set (reg:SI SP_REG)
11410 (plus:SI (reg:SI SP_REG)
11411 (match_operand:SI 2 "immediate_operand" "i")))]
11412 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11413 "* return ix86_output_call_insn (insn, operands[0]);"
11414 [(set_attr "type" "call")])
11416 ;; Call subroutine, returning value in operand 0
11418 (define_expand "call_value"
11419 [(set (match_operand 0 "" "")
11420 (call (match_operand:QI 1 "" "")
11421 (match_operand 2 "" "")))
11422 (use (match_operand 3 "" ""))]
11425 ix86_expand_call (operands[0], operands[1], operands[2],
11426 operands[3], NULL, false);
11430 (define_expand "sibcall_value"
11431 [(set (match_operand 0 "" "")
11432 (call (match_operand:QI 1 "" "")
11433 (match_operand 2 "" "")))
11434 (use (match_operand 3 "" ""))]
11437 ix86_expand_call (operands[0], operands[1], operands[2],
11438 operands[3], NULL, true);
11442 (define_insn_and_split "*call_value_vzeroupper"
11443 [(set (match_operand 0 "" "")
11444 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11445 (match_operand 2 "" "")))
11446 (unspec [(match_operand 3 "const_int_operand" "")]
11447 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11448 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11450 "&& reload_completed"
11452 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11453 [(set_attr "type" "callv")])
11455 (define_insn "*call_value"
11456 [(set (match_operand 0 "" "")
11457 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11458 (match_operand 2 "" "")))]
11459 "!SIBLING_CALL_P (insn)"
11460 "* return ix86_output_call_insn (insn, operands[1]);"
11461 [(set_attr "type" "callv")])
11463 (define_insn_and_split "*sibcall_value_vzeroupper"
11464 [(set (match_operand 0 "" "")
11465 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11466 (match_operand 2 "" "")))
11467 (unspec [(match_operand 3 "const_int_operand" "")]
11468 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11469 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11471 "&& reload_completed"
11473 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11474 [(set_attr "type" "callv")])
11476 (define_insn "*sibcall_value"
11477 [(set (match_operand 0 "" "")
11478 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11479 (match_operand 2 "" "")))]
11480 "SIBLING_CALL_P (insn)"
11481 "* return ix86_output_call_insn (insn, operands[1]);"
11482 [(set_attr "type" "callv")])
11484 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11485 [(set (match_operand 0 "" "")
11486 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11487 (match_operand 2 "" "")))
11488 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11489 (clobber (reg:TI XMM6_REG))
11490 (clobber (reg:TI XMM7_REG))
11491 (clobber (reg:TI XMM8_REG))
11492 (clobber (reg:TI XMM9_REG))
11493 (clobber (reg:TI XMM10_REG))
11494 (clobber (reg:TI XMM11_REG))
11495 (clobber (reg:TI XMM12_REG))
11496 (clobber (reg:TI XMM13_REG))
11497 (clobber (reg:TI XMM14_REG))
11498 (clobber (reg:TI XMM15_REG))
11499 (clobber (reg:DI SI_REG))
11500 (clobber (reg:DI DI_REG))
11501 (unspec [(match_operand 3 "const_int_operand" "")]
11502 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11503 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11505 "&& reload_completed"
11507 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11508 [(set_attr "type" "callv")])
11510 (define_insn "*call_value_rex64_ms_sysv"
11511 [(set (match_operand 0 "" "")
11512 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11513 (match_operand 2 "" "")))
11514 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11515 (clobber (reg:TI XMM6_REG))
11516 (clobber (reg:TI XMM7_REG))
11517 (clobber (reg:TI XMM8_REG))
11518 (clobber (reg:TI XMM9_REG))
11519 (clobber (reg:TI XMM10_REG))
11520 (clobber (reg:TI XMM11_REG))
11521 (clobber (reg:TI XMM12_REG))
11522 (clobber (reg:TI XMM13_REG))
11523 (clobber (reg:TI XMM14_REG))
11524 (clobber (reg:TI XMM15_REG))
11525 (clobber (reg:DI SI_REG))
11526 (clobber (reg:DI DI_REG))]
11527 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11528 "* return ix86_output_call_insn (insn, operands[1]);"
11529 [(set_attr "type" "callv")])
11531 (define_expand "call_value_pop"
11532 [(parallel [(set (match_operand 0 "" "")
11533 (call (match_operand:QI 1 "" "")
11534 (match_operand:SI 2 "" "")))
11535 (set (reg:SI SP_REG)
11536 (plus:SI (reg:SI SP_REG)
11537 (match_operand:SI 4 "" "")))])]
11540 ix86_expand_call (operands[0], operands[1], operands[2],
11541 operands[3], operands[4], false);
11545 (define_insn_and_split "*call_value_pop_vzeroupper"
11546 [(set (match_operand 0 "" "")
11547 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11548 (match_operand 2 "" "")))
11549 (set (reg:SI SP_REG)
11550 (plus:SI (reg:SI SP_REG)
11551 (match_operand:SI 3 "immediate_operand" "i")))
11552 (unspec [(match_operand 4 "const_int_operand" "")]
11553 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11554 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11556 "&& reload_completed"
11558 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11559 [(set_attr "type" "callv")])
11561 (define_insn "*call_value_pop"
11562 [(set (match_operand 0 "" "")
11563 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11564 (match_operand 2 "" "")))
11565 (set (reg:SI SP_REG)
11566 (plus:SI (reg:SI SP_REG)
11567 (match_operand:SI 3 "immediate_operand" "i")))]
11568 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11569 "* return ix86_output_call_insn (insn, operands[1]);"
11570 [(set_attr "type" "callv")])
11572 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11573 [(set (match_operand 0 "" "")
11574 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11575 (match_operand 2 "" "")))
11576 (set (reg:SI SP_REG)
11577 (plus:SI (reg:SI SP_REG)
11578 (match_operand:SI 3 "immediate_operand" "i")))
11579 (unspec [(match_operand 4 "const_int_operand" "")]
11580 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11581 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11583 "&& reload_completed"
11585 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11586 [(set_attr "type" "callv")])
11588 (define_insn "*sibcall_value_pop"
11589 [(set (match_operand 0 "" "")
11590 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11591 (match_operand 2 "" "")))
11592 (set (reg:SI SP_REG)
11593 (plus:SI (reg:SI SP_REG)
11594 (match_operand:SI 3 "immediate_operand" "i")))]
11595 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11596 "* return ix86_output_call_insn (insn, operands[1]);"
11597 [(set_attr "type" "callv")])
11599 ;; Call subroutine returning any type.
11601 (define_expand "untyped_call"
11602 [(parallel [(call (match_operand 0 "" "")
11604 (match_operand 1 "" "")
11605 (match_operand 2 "" "")])]
11610 /* In order to give reg-stack an easier job in validating two
11611 coprocessor registers as containing a possible return value,
11612 simply pretend the untyped call returns a complex long double
11615 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11616 and should have the default ABI. */
11618 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11619 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11620 operands[0], const0_rtx,
11621 GEN_INT ((TARGET_64BIT
11622 ? (ix86_abi == SYSV_ABI
11623 ? X86_64_SSE_REGPARM_MAX
11624 : X86_64_MS_SSE_REGPARM_MAX)
11625 : X86_32_SSE_REGPARM_MAX)
11629 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11631 rtx set = XVECEXP (operands[2], 0, i);
11632 emit_move_insn (SET_DEST (set), SET_SRC (set));
11635 /* The optimizer does not know that the call sets the function value
11636 registers we stored in the result block. We avoid problems by
11637 claiming that all hard registers are used and clobbered at this
11639 emit_insn (gen_blockage ());
11644 ;; Prologue and epilogue instructions
11646 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11647 ;; all of memory. This blocks insns from being moved across this point.
11649 (define_insn "blockage"
11650 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11653 [(set_attr "length" "0")])
11655 ;; Do not schedule instructions accessing memory across this point.
11657 (define_expand "memory_blockage"
11658 [(set (match_dup 0)
11659 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11662 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11663 MEM_VOLATILE_P (operands[0]) = 1;
11666 (define_insn "*memory_blockage"
11667 [(set (match_operand:BLK 0 "" "")
11668 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11671 [(set_attr "length" "0")])
11673 ;; As USE insns aren't meaningful after reload, this is used instead
11674 ;; to prevent deleting instructions setting registers for PIC code
11675 (define_insn "prologue_use"
11676 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11679 [(set_attr "length" "0")])
11681 ;; Insn emitted into the body of a function to return from a function.
11682 ;; This is only done if the function's epilogue is known to be simple.
11683 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11685 (define_expand "return"
11687 "ix86_can_use_return_insn_p ()"
11689 ix86_maybe_emit_epilogue_vzeroupper ();
11690 if (crtl->args.pops_args)
11692 rtx popc = GEN_INT (crtl->args.pops_args);
11693 emit_jump_insn (gen_simple_return_pop_internal (popc));
11698 ;; We need to disable this for TARGET_SEH, as otherwise
11699 ;; shrink-wrapped prologue gets enabled too. This might exceed
11700 ;; the maximum size of prologue in unwind information.
11702 (define_expand "simple_return"
11706 ix86_maybe_emit_epilogue_vzeroupper ();
11707 if (crtl->args.pops_args)
11709 rtx popc = GEN_INT (crtl->args.pops_args);
11710 emit_jump_insn (gen_simple_return_pop_internal (popc));
11715 (define_insn "simple_return_internal"
11719 [(set_attr "length" "1")
11720 (set_attr "atom_unit" "jeu")
11721 (set_attr "length_immediate" "0")
11722 (set_attr "modrm" "0")])
11724 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11725 ;; instruction Athlon and K8 have.
11727 (define_insn "simple_return_internal_long"
11729 (unspec [(const_int 0)] UNSPEC_REP)]
11732 [(set_attr "length" "2")
11733 (set_attr "atom_unit" "jeu")
11734 (set_attr "length_immediate" "0")
11735 (set_attr "prefix_rep" "1")
11736 (set_attr "modrm" "0")])
11738 (define_insn "simple_return_pop_internal"
11740 (use (match_operand:SI 0 "const_int_operand" ""))]
11743 [(set_attr "length" "3")
11744 (set_attr "atom_unit" "jeu")
11745 (set_attr "length_immediate" "2")
11746 (set_attr "modrm" "0")])
11748 (define_insn "simple_return_indirect_internal"
11750 (use (match_operand:SI 0 "register_operand" "r"))]
11753 [(set_attr "type" "ibr")
11754 (set_attr "length_immediate" "0")])
11760 [(set_attr "length" "1")
11761 (set_attr "length_immediate" "0")
11762 (set_attr "modrm" "0")])
11764 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11765 (define_insn "nops"
11766 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11770 int num = INTVAL (operands[0]);
11772 gcc_assert (num >= 1 && num <= 8);
11775 fputs ("\tnop\n", asm_out_file);
11779 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11780 (set_attr "length_immediate" "0")
11781 (set_attr "modrm" "0")])
11783 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11784 ;; branch prediction penalty for the third jump in a 16-byte
11788 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11791 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11792 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11794 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11795 The align insn is used to avoid 3 jump instructions in the row to improve
11796 branch prediction and the benefits hardly outweigh the cost of extra 8
11797 nops on the average inserted by full alignment pseudo operation. */
11801 [(set_attr "length" "16")])
11803 (define_expand "prologue"
11806 "ix86_expand_prologue (); DONE;")
11808 (define_insn "set_got"
11809 [(set (match_operand:SI 0 "register_operand" "=r")
11810 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11811 (clobber (reg:CC FLAGS_REG))]
11813 "* return output_set_got (operands[0], NULL_RTX);"
11814 [(set_attr "type" "multi")
11815 (set_attr "length" "12")])
11817 (define_insn "set_got_labelled"
11818 [(set (match_operand:SI 0 "register_operand" "=r")
11819 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11821 (clobber (reg:CC FLAGS_REG))]
11823 "* return output_set_got (operands[0], operands[1]);"
11824 [(set_attr "type" "multi")
11825 (set_attr "length" "12")])
11827 (define_insn "set_got_rex64"
11828 [(set (match_operand:DI 0 "register_operand" "=r")
11829 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11831 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11832 [(set_attr "type" "lea")
11833 (set_attr "length_address" "4")
11834 (set_attr "mode" "DI")])
11836 (define_insn "set_rip_rex64"
11837 [(set (match_operand:DI 0 "register_operand" "=r")
11838 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11840 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11841 [(set_attr "type" "lea")
11842 (set_attr "length_address" "4")
11843 (set_attr "mode" "DI")])
11845 (define_insn "set_got_offset_rex64"
11846 [(set (match_operand:DI 0 "register_operand" "=r")
11848 [(label_ref (match_operand 1 "" ""))]
11849 UNSPEC_SET_GOT_OFFSET))]
11851 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11852 [(set_attr "type" "imov")
11853 (set_attr "length_immediate" "0")
11854 (set_attr "length_address" "8")
11855 (set_attr "mode" "DI")])
11857 (define_expand "epilogue"
11860 "ix86_expand_epilogue (1); DONE;")
11862 (define_expand "sibcall_epilogue"
11865 "ix86_expand_epilogue (0); DONE;")
11867 (define_expand "eh_return"
11868 [(use (match_operand 0 "register_operand" ""))]
11871 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11873 /* Tricky bit: we write the address of the handler to which we will
11874 be returning into someone else's stack frame, one word below the
11875 stack address we wish to restore. */
11876 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11877 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11878 tmp = gen_rtx_MEM (Pmode, tmp);
11879 emit_move_insn (tmp, ra);
11881 emit_jump_insn (gen_eh_return_internal ());
11886 (define_insn_and_split "eh_return_internal"
11890 "epilogue_completed"
11892 "ix86_expand_epilogue (2); DONE;")
11894 (define_insn "leave"
11895 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11896 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11897 (clobber (mem:BLK (scratch)))]
11900 [(set_attr "type" "leave")])
11902 (define_insn "leave_rex64"
11903 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11904 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11905 (clobber (mem:BLK (scratch)))]
11908 [(set_attr "type" "leave")])
11910 ;; Handle -fsplit-stack.
11912 (define_expand "split_stack_prologue"
11916 ix86_expand_split_stack_prologue ();
11920 ;; In order to support the call/return predictor, we use a return
11921 ;; instruction which the middle-end doesn't see.
11922 (define_insn "split_stack_return"
11923 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11924 UNSPECV_SPLIT_STACK_RETURN)]
11927 if (operands[0] == const0_rtx)
11932 [(set_attr "atom_unit" "jeu")
11933 (set_attr "modrm" "0")
11934 (set (attr "length")
11935 (if_then_else (match_operand:SI 0 "const0_operand" "")
11938 (set (attr "length_immediate")
11939 (if_then_else (match_operand:SI 0 "const0_operand" "")
11943 ;; If there are operand 0 bytes available on the stack, jump to
11946 (define_expand "split_stack_space_check"
11947 [(set (pc) (if_then_else
11948 (ltu (minus (reg SP_REG)
11949 (match_operand 0 "register_operand" ""))
11950 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11951 (label_ref (match_operand 1 "" ""))
11955 rtx reg, size, limit;
11957 reg = gen_reg_rtx (Pmode);
11958 size = force_reg (Pmode, operands[0]);
11959 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11960 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11961 UNSPEC_STACK_CHECK);
11962 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11963 ix86_expand_branch (GEU, reg, limit, operands[1]);
11968 ;; Bit manipulation instructions.
11970 (define_expand "ffs<mode>2"
11971 [(set (match_dup 2) (const_int -1))
11972 (parallel [(set (reg:CCZ FLAGS_REG)
11974 (match_operand:SWI48 1 "nonimmediate_operand" "")
11976 (set (match_operand:SWI48 0 "register_operand" "")
11977 (ctz:SWI48 (match_dup 1)))])
11978 (set (match_dup 0) (if_then_else:SWI48
11979 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11982 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11983 (clobber (reg:CC FLAGS_REG))])]
11986 if (<MODE>mode == SImode && !TARGET_CMOVE)
11988 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11991 operands[2] = gen_reg_rtx (<MODE>mode);
11994 (define_insn_and_split "ffssi2_no_cmove"
11995 [(set (match_operand:SI 0 "register_operand" "=r")
11996 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11997 (clobber (match_scratch:SI 2 "=&q"))
11998 (clobber (reg:CC FLAGS_REG))]
12001 "&& reload_completed"
12002 [(parallel [(set (reg:CCZ FLAGS_REG)
12003 (compare:CCZ (match_dup 1) (const_int 0)))
12004 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12005 (set (strict_low_part (match_dup 3))
12006 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12007 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12008 (clobber (reg:CC FLAGS_REG))])
12009 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12010 (clobber (reg:CC FLAGS_REG))])
12011 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12012 (clobber (reg:CC FLAGS_REG))])]
12014 operands[3] = gen_lowpart (QImode, operands[2]);
12015 ix86_expand_clear (operands[2]);
12018 (define_insn "*ffs<mode>_1"
12019 [(set (reg:CCZ FLAGS_REG)
12020 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12022 (set (match_operand:SWI48 0 "register_operand" "=r")
12023 (ctz:SWI48 (match_dup 1)))]
12025 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12026 [(set_attr "type" "alu1")
12027 (set_attr "prefix_0f" "1")
12028 (set_attr "mode" "<MODE>")])
12030 (define_insn "ctz<mode>2"
12031 [(set (match_operand:SWI248 0 "register_operand" "=r")
12032 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12033 (clobber (reg:CC FLAGS_REG))]
12037 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12039 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12041 [(set_attr "type" "alu1")
12042 (set_attr "prefix_0f" "1")
12043 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12044 (set_attr "mode" "<MODE>")])
12046 (define_expand "clz<mode>2"
12048 [(set (match_operand:SWI248 0 "register_operand" "")
12051 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12052 (clobber (reg:CC FLAGS_REG))])
12054 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12055 (clobber (reg:CC FLAGS_REG))])]
12060 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12063 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12066 (define_insn "clz<mode>2_lzcnt"
12067 [(set (match_operand:SWI248 0 "register_operand" "=r")
12068 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12069 (clobber (reg:CC FLAGS_REG))]
12071 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12072 [(set_attr "prefix_rep" "1")
12073 (set_attr "type" "bitmanip")
12074 (set_attr "mode" "<MODE>")])
12076 ;; BMI instructions.
12077 (define_insn "*bmi_andn_<mode>"
12078 [(set (match_operand:SWI48 0 "register_operand" "=r")
12081 (match_operand:SWI48 1 "register_operand" "r"))
12082 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12083 (clobber (reg:CC FLAGS_REG))]
12085 "andn\t{%2, %1, %0|%0, %1, %2}"
12086 [(set_attr "type" "bitmanip")
12087 (set_attr "mode" "<MODE>")])
12089 (define_insn "bmi_bextr_<mode>"
12090 [(set (match_operand:SWI48 0 "register_operand" "=r")
12091 (unspec:SWI48 [(match_operand:SWI48 1 "nonimmediate_operand" "rm")
12092 (match_operand:SWI48 2 "register_operand" "r")]
12094 (clobber (reg:CC FLAGS_REG))]
12096 "bextr\t{%2, %1, %0|%0, %1, %2}"
12097 [(set_attr "type" "bitmanip")
12098 (set_attr "mode" "<MODE>")])
12100 (define_insn "*bmi_blsi_<mode>"
12101 [(set (match_operand:SWI48 0 "register_operand" "=r")
12104 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12106 (clobber (reg:CC FLAGS_REG))]
12108 "blsi\t{%1, %0|%0, %1}"
12109 [(set_attr "type" "bitmanip")
12110 (set_attr "mode" "<MODE>")])
12112 (define_insn "*bmi_blsmsk_<mode>"
12113 [(set (match_operand:SWI48 0 "register_operand" "=r")
12116 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12119 (clobber (reg:CC FLAGS_REG))]
12121 "blsmsk\t{%1, %0|%0, %1}"
12122 [(set_attr "type" "bitmanip")
12123 (set_attr "mode" "<MODE>")])
12125 (define_insn "*bmi_blsr_<mode>"
12126 [(set (match_operand:SWI48 0 "register_operand" "=r")
12129 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12132 (clobber (reg:CC FLAGS_REG))]
12134 "blsr\t{%1, %0|%0, %1}"
12135 [(set_attr "type" "bitmanip")
12136 (set_attr "mode" "<MODE>")])
12138 ;; BMI2 instructions.
12139 (define_insn "bmi2_bzhi_<mode>3"
12140 [(set (match_operand:SWI48 0 "register_operand" "=r")
12141 (and:SWI48 (lshiftrt:SWI48 (const_int -1)
12142 (match_operand:SWI48 2 "register_operand" "r"))
12143 (match_operand:SWI48 1 "nonimmediate_operand" "rm")))
12144 (clobber (reg:CC FLAGS_REG))]
12146 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12147 [(set_attr "type" "bitmanip")
12148 (set_attr "prefix" "vex")
12149 (set_attr "mode" "<MODE>")])
12151 (define_insn "bmi2_pdep_<mode>3"
12152 [(set (match_operand:SWI48 0 "register_operand" "=r")
12153 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12154 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12157 "pdep\t{%2, %1, %0|%0, %1, %2}"
12158 [(set_attr "type" "bitmanip")
12159 (set_attr "prefix" "vex")
12160 (set_attr "mode" "<MODE>")])
12162 (define_insn "bmi2_pext_<mode>3"
12163 [(set (match_operand:SWI48 0 "register_operand" "=r")
12164 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12165 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12168 "pext\t{%2, %1, %0|%0, %1, %2}"
12169 [(set_attr "type" "bitmanip")
12170 (set_attr "prefix" "vex")
12171 (set_attr "mode" "<MODE>")])
12173 ;; TBM instructions.
12174 (define_insn "tbm_bextri_<mode>"
12175 [(set (match_operand:SWI48 0 "register_operand" "=r")
12176 (zero_extract:SWI48
12177 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12178 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12179 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12180 (clobber (reg:CC FLAGS_REG))]
12183 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12184 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12186 [(set_attr "type" "bitmanip")
12187 (set_attr "mode" "<MODE>")])
12189 (define_insn "*tbm_blcfill_<mode>"
12190 [(set (match_operand:SWI48 0 "register_operand" "=r")
12193 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12196 (clobber (reg:CC FLAGS_REG))]
12198 "blcfill\t{%1, %0|%0, %1}"
12199 [(set_attr "type" "bitmanip")
12200 (set_attr "mode" "<MODE>")])
12202 (define_insn "*tbm_blci_<mode>"
12203 [(set (match_operand:SWI48 0 "register_operand" "=r")
12207 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12210 (clobber (reg:CC FLAGS_REG))]
12212 "blci\t{%1, %0|%0, %1}"
12213 [(set_attr "type" "bitmanip")
12214 (set_attr "mode" "<MODE>")])
12216 (define_insn "*tbm_blcic_<mode>"
12217 [(set (match_operand:SWI48 0 "register_operand" "=r")
12220 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12224 (clobber (reg:CC FLAGS_REG))]
12226 "blcic\t{%1, %0|%0, %1}"
12227 [(set_attr "type" "bitmanip")
12228 (set_attr "mode" "<MODE>")])
12230 (define_insn "*tbm_blcmsk_<mode>"
12231 [(set (match_operand:SWI48 0 "register_operand" "=r")
12234 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12237 (clobber (reg:CC FLAGS_REG))]
12239 "blcmsk\t{%1, %0|%0, %1}"
12240 [(set_attr "type" "bitmanip")
12241 (set_attr "mode" "<MODE>")])
12243 (define_insn "*tbm_blcs_<mode>"
12244 [(set (match_operand:SWI48 0 "register_operand" "=r")
12247 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12250 (clobber (reg:CC FLAGS_REG))]
12252 "blcs\t{%1, %0|%0, %1}"
12253 [(set_attr "type" "bitmanip")
12254 (set_attr "mode" "<MODE>")])
12256 (define_insn "*tbm_blsfill_<mode>"
12257 [(set (match_operand:SWI48 0 "register_operand" "=r")
12260 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12263 (clobber (reg:CC FLAGS_REG))]
12265 "blsfill\t{%1, %0|%0, %1}"
12266 [(set_attr "type" "bitmanip")
12267 (set_attr "mode" "<MODE>")])
12269 (define_insn "*tbm_blsic_<mode>"
12270 [(set (match_operand:SWI48 0 "register_operand" "=r")
12273 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12277 (clobber (reg:CC FLAGS_REG))]
12279 "blsic\t{%1, %0|%0, %1}"
12280 [(set_attr "type" "bitmanip")
12281 (set_attr "mode" "<MODE>")])
12283 (define_insn "*tbm_t1mskc_<mode>"
12284 [(set (match_operand:SWI48 0 "register_operand" "=r")
12287 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12291 (clobber (reg:CC FLAGS_REG))]
12293 "t1mskc\t{%1, %0|%0, %1}"
12294 [(set_attr "type" "bitmanip")
12295 (set_attr "mode" "<MODE>")])
12297 (define_insn "*tbm_tzmsk_<mode>"
12298 [(set (match_operand:SWI48 0 "register_operand" "=r")
12301 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12305 (clobber (reg:CC FLAGS_REG))]
12307 "tzmsk\t{%1, %0|%0, %1}"
12308 [(set_attr "type" "bitmanip")
12309 (set_attr "mode" "<MODE>")])
12311 (define_insn "bsr_rex64"
12312 [(set (match_operand:DI 0 "register_operand" "=r")
12313 (minus:DI (const_int 63)
12314 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12315 (clobber (reg:CC FLAGS_REG))]
12317 "bsr{q}\t{%1, %0|%0, %1}"
12318 [(set_attr "type" "alu1")
12319 (set_attr "prefix_0f" "1")
12320 (set_attr "mode" "DI")])
12323 [(set (match_operand:SI 0 "register_operand" "=r")
12324 (minus:SI (const_int 31)
12325 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12326 (clobber (reg:CC FLAGS_REG))]
12328 "bsr{l}\t{%1, %0|%0, %1}"
12329 [(set_attr "type" "alu1")
12330 (set_attr "prefix_0f" "1")
12331 (set_attr "mode" "SI")])
12333 (define_insn "*bsrhi"
12334 [(set (match_operand:HI 0 "register_operand" "=r")
12335 (minus:HI (const_int 15)
12336 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12337 (clobber (reg:CC FLAGS_REG))]
12339 "bsr{w}\t{%1, %0|%0, %1}"
12340 [(set_attr "type" "alu1")
12341 (set_attr "prefix_0f" "1")
12342 (set_attr "mode" "HI")])
12344 (define_insn "popcount<mode>2"
12345 [(set (match_operand:SWI248 0 "register_operand" "=r")
12347 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12348 (clobber (reg:CC FLAGS_REG))]
12352 return "popcnt\t{%1, %0|%0, %1}";
12354 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12357 [(set_attr "prefix_rep" "1")
12358 (set_attr "type" "bitmanip")
12359 (set_attr "mode" "<MODE>")])
12361 (define_insn "*popcount<mode>2_cmp"
12362 [(set (reg FLAGS_REG)
12365 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12367 (set (match_operand:SWI248 0 "register_operand" "=r")
12368 (popcount:SWI248 (match_dup 1)))]
12369 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12372 return "popcnt\t{%1, %0|%0, %1}";
12374 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12377 [(set_attr "prefix_rep" "1")
12378 (set_attr "type" "bitmanip")
12379 (set_attr "mode" "<MODE>")])
12381 (define_insn "*popcountsi2_cmp_zext"
12382 [(set (reg FLAGS_REG)
12384 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12386 (set (match_operand:DI 0 "register_operand" "=r")
12387 (zero_extend:DI(popcount:SI (match_dup 1))))]
12388 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12391 return "popcnt\t{%1, %0|%0, %1}";
12393 return "popcnt{l}\t{%1, %0|%0, %1}";
12396 [(set_attr "prefix_rep" "1")
12397 (set_attr "type" "bitmanip")
12398 (set_attr "mode" "SI")])
12400 (define_expand "bswap<mode>2"
12401 [(set (match_operand:SWI48 0 "register_operand" "")
12402 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12405 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12407 rtx x = operands[0];
12409 emit_move_insn (x, operands[1]);
12410 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12411 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12412 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12417 (define_insn "*bswap<mode>2_movbe"
12418 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12419 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12421 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12424 movbe\t{%1, %0|%0, %1}
12425 movbe\t{%1, %0|%0, %1}"
12426 [(set_attr "type" "bitmanip,imov,imov")
12427 (set_attr "modrm" "0,1,1")
12428 (set_attr "prefix_0f" "*,1,1")
12429 (set_attr "prefix_extra" "*,1,1")
12430 (set_attr "mode" "<MODE>")])
12432 (define_insn "*bswap<mode>2_1"
12433 [(set (match_operand:SWI48 0 "register_operand" "=r")
12434 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12437 [(set_attr "type" "bitmanip")
12438 (set_attr "modrm" "0")
12439 (set_attr "mode" "<MODE>")])
12441 (define_insn "*bswaphi_lowpart_1"
12442 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12443 (bswap:HI (match_dup 0)))
12444 (clobber (reg:CC FLAGS_REG))]
12445 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12447 xchg{b}\t{%h0, %b0|%b0, %h0}
12448 rol{w}\t{$8, %0|%0, 8}"
12449 [(set_attr "length" "2,4")
12450 (set_attr "mode" "QI,HI")])
12452 (define_insn "bswaphi_lowpart"
12453 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12454 (bswap:HI (match_dup 0)))
12455 (clobber (reg:CC FLAGS_REG))]
12457 "rol{w}\t{$8, %0|%0, 8}"
12458 [(set_attr "length" "4")
12459 (set_attr "mode" "HI")])
12461 (define_expand "paritydi2"
12462 [(set (match_operand:DI 0 "register_operand" "")
12463 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12466 rtx scratch = gen_reg_rtx (QImode);
12469 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12470 NULL_RTX, operands[1]));
12472 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12473 gen_rtx_REG (CCmode, FLAGS_REG),
12475 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12478 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12481 rtx tmp = gen_reg_rtx (SImode);
12483 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12484 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12489 (define_expand "paritysi2"
12490 [(set (match_operand:SI 0 "register_operand" "")
12491 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12494 rtx scratch = gen_reg_rtx (QImode);
12497 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12499 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12500 gen_rtx_REG (CCmode, FLAGS_REG),
12502 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12504 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12508 (define_insn_and_split "paritydi2_cmp"
12509 [(set (reg:CC FLAGS_REG)
12510 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12512 (clobber (match_scratch:DI 0 "=r"))
12513 (clobber (match_scratch:SI 1 "=&r"))
12514 (clobber (match_scratch:HI 2 "=Q"))]
12517 "&& reload_completed"
12519 [(set (match_dup 1)
12520 (xor:SI (match_dup 1) (match_dup 4)))
12521 (clobber (reg:CC FLAGS_REG))])
12523 [(set (reg:CC FLAGS_REG)
12524 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12525 (clobber (match_dup 1))
12526 (clobber (match_dup 2))])]
12528 operands[4] = gen_lowpart (SImode, operands[3]);
12532 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12533 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12536 operands[1] = gen_highpart (SImode, operands[3]);
12539 (define_insn_and_split "paritysi2_cmp"
12540 [(set (reg:CC FLAGS_REG)
12541 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12543 (clobber (match_scratch:SI 0 "=r"))
12544 (clobber (match_scratch:HI 1 "=&Q"))]
12547 "&& reload_completed"
12549 [(set (match_dup 1)
12550 (xor:HI (match_dup 1) (match_dup 3)))
12551 (clobber (reg:CC FLAGS_REG))])
12553 [(set (reg:CC FLAGS_REG)
12554 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12555 (clobber (match_dup 1))])]
12557 operands[3] = gen_lowpart (HImode, operands[2]);
12559 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12560 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12563 (define_insn "*parityhi2_cmp"
12564 [(set (reg:CC FLAGS_REG)
12565 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12567 (clobber (match_scratch:HI 0 "=Q"))]
12569 "xor{b}\t{%h0, %b0|%b0, %h0}"
12570 [(set_attr "length" "2")
12571 (set_attr "mode" "HI")])
12574 ;; Thread-local storage patterns for ELF.
12576 ;; Note that these code sequences must appear exactly as shown
12577 ;; in order to allow linker relaxation.
12579 (define_insn "*tls_global_dynamic_32_gnu"
12580 [(set (match_operand:SI 0 "register_operand" "=a")
12582 [(match_operand:SI 1 "register_operand" "b")
12583 (match_operand:SI 2 "tls_symbolic_operand" "")
12584 (match_operand:SI 3 "constant_call_address_operand" "z")]
12586 (clobber (match_scratch:SI 4 "=d"))
12587 (clobber (match_scratch:SI 5 "=c"))
12588 (clobber (reg:CC FLAGS_REG))]
12589 "!TARGET_64BIT && TARGET_GNU_TLS"
12592 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12593 if (TARGET_SUN_TLS)
12594 #ifdef HAVE_AS_IX86_TLSGDPLT
12595 return "call\t%a2@tlsgdplt";
12597 return "call\t%p3@plt";
12599 return "call\t%P3";
12601 [(set_attr "type" "multi")
12602 (set_attr "length" "12")])
12604 (define_expand "tls_global_dynamic_32"
12606 [(set (match_operand:SI 0 "register_operand" "")
12607 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12608 (match_operand:SI 1 "tls_symbolic_operand" "")
12609 (match_operand:SI 3 "constant_call_address_operand" "")]
12611 (clobber (match_scratch:SI 4 ""))
12612 (clobber (match_scratch:SI 5 ""))
12613 (clobber (reg:CC FLAGS_REG))])])
12615 (define_insn "*tls_global_dynamic_64"
12616 [(set (match_operand:DI 0 "register_operand" "=a")
12618 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12619 (match_operand:DI 3 "" "")))
12620 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12625 fputs (ASM_BYTE "0x66\n", asm_out_file);
12627 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12628 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12629 fputs ("\trex64\n", asm_out_file);
12630 if (TARGET_SUN_TLS)
12631 return "call\t%p2@plt";
12632 return "call\t%P2";
12634 [(set_attr "type" "multi")
12635 (set (attr "length")
12636 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12638 (define_expand "tls_global_dynamic_64"
12640 [(set (match_operand:DI 0 "register_operand" "")
12642 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12644 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12647 (define_insn "*tls_local_dynamic_base_32_gnu"
12648 [(set (match_operand:SI 0 "register_operand" "=a")
12650 [(match_operand:SI 1 "register_operand" "b")
12651 (match_operand:SI 2 "constant_call_address_operand" "z")]
12652 UNSPEC_TLS_LD_BASE))
12653 (clobber (match_scratch:SI 3 "=d"))
12654 (clobber (match_scratch:SI 4 "=c"))
12655 (clobber (reg:CC FLAGS_REG))]
12656 "!TARGET_64BIT && TARGET_GNU_TLS"
12659 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12660 if (TARGET_SUN_TLS)
12661 #ifdef HAVE_AS_IX86_TLSLDMPLT
12662 return "call\t%&@tlsldmplt";
12664 return "call\t%p2@plt";
12666 return "call\t%P2";
12668 [(set_attr "type" "multi")
12669 (set_attr "length" "11")])
12671 (define_expand "tls_local_dynamic_base_32"
12673 [(set (match_operand:SI 0 "register_operand" "")
12675 [(match_operand:SI 1 "register_operand" "")
12676 (match_operand:SI 2 "constant_call_address_operand" "")]
12677 UNSPEC_TLS_LD_BASE))
12678 (clobber (match_scratch:SI 3 ""))
12679 (clobber (match_scratch:SI 4 ""))
12680 (clobber (reg:CC FLAGS_REG))])])
12682 (define_insn "*tls_local_dynamic_base_64"
12683 [(set (match_operand:DI 0 "register_operand" "=a")
12685 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12686 (match_operand:DI 2 "" "")))
12687 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12691 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12692 if (TARGET_SUN_TLS)
12693 return "call\t%p1@plt";
12694 return "call\t%P1";
12696 [(set_attr "type" "multi")
12697 (set_attr "length" "12")])
12699 (define_expand "tls_local_dynamic_base_64"
12701 [(set (match_operand:DI 0 "register_operand" "")
12703 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12705 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12707 ;; Local dynamic of a single variable is a lose. Show combine how
12708 ;; to convert that back to global dynamic.
12710 (define_insn_and_split "*tls_local_dynamic_32_once"
12711 [(set (match_operand:SI 0 "register_operand" "=a")
12713 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12714 (match_operand:SI 2 "constant_call_address_operand" "z")]
12715 UNSPEC_TLS_LD_BASE)
12716 (const:SI (unspec:SI
12717 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12719 (clobber (match_scratch:SI 4 "=d"))
12720 (clobber (match_scratch:SI 5 "=c"))
12721 (clobber (reg:CC FLAGS_REG))]
12726 [(set (match_dup 0)
12727 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12729 (clobber (match_dup 4))
12730 (clobber (match_dup 5))
12731 (clobber (reg:CC FLAGS_REG))])])
12733 ;; Segment register for the thread base ptr load
12734 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12736 ;; Load and add the thread base pointer from %<tp_seg>:0.
12737 (define_insn "*load_tp_x32"
12738 [(set (match_operand:SI 0 "register_operand" "=r")
12739 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12741 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12742 [(set_attr "type" "imov")
12743 (set_attr "modrm" "0")
12744 (set_attr "length" "7")
12745 (set_attr "memory" "load")
12746 (set_attr "imm_disp" "false")])
12748 (define_insn "*load_tp_x32_zext"
12749 [(set (match_operand:DI 0 "register_operand" "=r")
12750 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12752 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12753 [(set_attr "type" "imov")
12754 (set_attr "modrm" "0")
12755 (set_attr "length" "7")
12756 (set_attr "memory" "load")
12757 (set_attr "imm_disp" "false")])
12759 (define_insn "*load_tp_<mode>"
12760 [(set (match_operand:P 0 "register_operand" "=r")
12761 (unspec:P [(const_int 0)] UNSPEC_TP))]
12763 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12764 [(set_attr "type" "imov")
12765 (set_attr "modrm" "0")
12766 (set_attr "length" "7")
12767 (set_attr "memory" "load")
12768 (set_attr "imm_disp" "false")])
12770 (define_insn "*add_tp_x32"
12771 [(set (match_operand:SI 0 "register_operand" "=r")
12772 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12773 (match_operand:SI 1 "register_operand" "0")))
12774 (clobber (reg:CC FLAGS_REG))]
12776 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12777 [(set_attr "type" "alu")
12778 (set_attr "modrm" "0")
12779 (set_attr "length" "7")
12780 (set_attr "memory" "load")
12781 (set_attr "imm_disp" "false")])
12783 (define_insn "*add_tp_x32_zext"
12784 [(set (match_operand:DI 0 "register_operand" "=r")
12786 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12787 (match_operand:SI 1 "register_operand" "0"))))
12788 (clobber (reg:CC FLAGS_REG))]
12790 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12791 [(set_attr "type" "alu")
12792 (set_attr "modrm" "0")
12793 (set_attr "length" "7")
12794 (set_attr "memory" "load")
12795 (set_attr "imm_disp" "false")])
12797 (define_insn "*add_tp_<mode>"
12798 [(set (match_operand:P 0 "register_operand" "=r")
12799 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12800 (match_operand:P 1 "register_operand" "0")))
12801 (clobber (reg:CC FLAGS_REG))]
12803 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12804 [(set_attr "type" "alu")
12805 (set_attr "modrm" "0")
12806 (set_attr "length" "7")
12807 (set_attr "memory" "load")
12808 (set_attr "imm_disp" "false")])
12810 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12811 ;; %rax as destination of the initial executable code sequence.
12812 (define_insn "tls_initial_exec_64_sun"
12813 [(set (match_operand:DI 0 "register_operand" "=a")
12815 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12816 UNSPEC_TLS_IE_SUN))
12817 (clobber (reg:CC FLAGS_REG))]
12818 "TARGET_64BIT && TARGET_SUN_TLS"
12821 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12822 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12824 [(set_attr "type" "multi")])
12826 ;; GNU2 TLS patterns can be split.
12828 (define_expand "tls_dynamic_gnu2_32"
12829 [(set (match_dup 3)
12830 (plus:SI (match_operand:SI 2 "register_operand" "")
12832 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12835 [(set (match_operand:SI 0 "register_operand" "")
12836 (unspec:SI [(match_dup 1) (match_dup 3)
12837 (match_dup 2) (reg:SI SP_REG)]
12839 (clobber (reg:CC FLAGS_REG))])]
12840 "!TARGET_64BIT && TARGET_GNU2_TLS"
12842 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12843 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12846 (define_insn "*tls_dynamic_gnu2_lea_32"
12847 [(set (match_operand:SI 0 "register_operand" "=r")
12848 (plus:SI (match_operand:SI 1 "register_operand" "b")
12850 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12851 UNSPEC_TLSDESC))))]
12852 "!TARGET_64BIT && TARGET_GNU2_TLS"
12853 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12854 [(set_attr "type" "lea")
12855 (set_attr "mode" "SI")
12856 (set_attr "length" "6")
12857 (set_attr "length_address" "4")])
12859 (define_insn "*tls_dynamic_gnu2_call_32"
12860 [(set (match_operand:SI 0 "register_operand" "=a")
12861 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12862 (match_operand:SI 2 "register_operand" "0")
12863 ;; we have to make sure %ebx still points to the GOT
12864 (match_operand:SI 3 "register_operand" "b")
12867 (clobber (reg:CC FLAGS_REG))]
12868 "!TARGET_64BIT && TARGET_GNU2_TLS"
12869 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12870 [(set_attr "type" "call")
12871 (set_attr "length" "2")
12872 (set_attr "length_address" "0")])
12874 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12875 [(set (match_operand:SI 0 "register_operand" "=&a")
12877 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12878 (match_operand:SI 4 "" "")
12879 (match_operand:SI 2 "register_operand" "b")
12882 (const:SI (unspec:SI
12883 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12885 (clobber (reg:CC FLAGS_REG))]
12886 "!TARGET_64BIT && TARGET_GNU2_TLS"
12889 [(set (match_dup 0) (match_dup 5))]
12891 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12892 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12895 (define_expand "tls_dynamic_gnu2_64"
12896 [(set (match_dup 2)
12897 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12900 [(set (match_operand:DI 0 "register_operand" "")
12901 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12903 (clobber (reg:CC FLAGS_REG))])]
12904 "TARGET_64BIT && TARGET_GNU2_TLS"
12906 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12907 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12910 (define_insn "*tls_dynamic_gnu2_lea_64"
12911 [(set (match_operand:DI 0 "register_operand" "=r")
12912 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12914 "TARGET_64BIT && TARGET_GNU2_TLS"
12915 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12916 [(set_attr "type" "lea")
12917 (set_attr "mode" "DI")
12918 (set_attr "length" "7")
12919 (set_attr "length_address" "4")])
12921 (define_insn "*tls_dynamic_gnu2_call_64"
12922 [(set (match_operand:DI 0 "register_operand" "=a")
12923 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12924 (match_operand:DI 2 "register_operand" "0")
12927 (clobber (reg:CC FLAGS_REG))]
12928 "TARGET_64BIT && TARGET_GNU2_TLS"
12929 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12930 [(set_attr "type" "call")
12931 (set_attr "length" "2")
12932 (set_attr "length_address" "0")])
12934 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12935 [(set (match_operand:DI 0 "register_operand" "=&a")
12937 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12938 (match_operand:DI 3 "" "")
12941 (const:DI (unspec:DI
12942 [(match_operand 1 "tls_symbolic_operand" "")]
12944 (clobber (reg:CC FLAGS_REG))]
12945 "TARGET_64BIT && TARGET_GNU2_TLS"
12948 [(set (match_dup 0) (match_dup 4))]
12950 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12951 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12954 ;; These patterns match the binary 387 instructions for addM3, subM3,
12955 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12956 ;; SFmode. The first is the normal insn, the second the same insn but
12957 ;; with one operand a conversion, and the third the same insn but with
12958 ;; the other operand a conversion. The conversion may be SFmode or
12959 ;; SImode if the target mode DFmode, but only SImode if the target mode
12962 ;; Gcc is slightly more smart about handling normal two address instructions
12963 ;; so use special patterns for add and mull.
12965 (define_insn "*fop_<mode>_comm_mixed"
12966 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12967 (match_operator:MODEF 3 "binary_fp_operator"
12968 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12969 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12970 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12971 && COMMUTATIVE_ARITH_P (operands[3])
12972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12973 "* return output_387_binary_op (insn, operands);"
12974 [(set (attr "type")
12975 (if_then_else (eq_attr "alternative" "1,2")
12976 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12977 (const_string "ssemul")
12978 (const_string "sseadd"))
12979 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12980 (const_string "fmul")
12981 (const_string "fop"))))
12982 (set_attr "isa" "*,noavx,avx")
12983 (set_attr "prefix" "orig,orig,vex")
12984 (set_attr "mode" "<MODE>")])
12986 (define_insn "*fop_<mode>_comm_sse"
12987 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12988 (match_operator:MODEF 3 "binary_fp_operator"
12989 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12990 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12991 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
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 "ssemul")
12998 (const_string "sseadd")))
12999 (set_attr "isa" "noavx,avx")
13000 (set_attr "prefix" "orig,vex")
13001 (set_attr "mode" "<MODE>")])
13003 (define_insn "*fop_<mode>_comm_i387"
13004 [(set (match_operand:MODEF 0 "register_operand" "=f")
13005 (match_operator:MODEF 3 "binary_fp_operator"
13006 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13007 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13008 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13009 && COMMUTATIVE_ARITH_P (operands[3])
13010 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13011 "* return output_387_binary_op (insn, operands);"
13012 [(set (attr "type")
13013 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13014 (const_string "fmul")
13015 (const_string "fop")))
13016 (set_attr "mode" "<MODE>")])
13018 (define_insn "*fop_<mode>_1_mixed"
13019 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13020 (match_operator:MODEF 3 "binary_fp_operator"
13021 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13022 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13023 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13024 && !COMMUTATIVE_ARITH_P (operands[3])
13025 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13026 "* return output_387_binary_op (insn, operands);"
13027 [(set (attr "type")
13028 (cond [(and (eq_attr "alternative" "2,3")
13029 (match_operand:MODEF 3 "mult_operator" ""))
13030 (const_string "ssemul")
13031 (and (eq_attr "alternative" "2,3")
13032 (match_operand:MODEF 3 "div_operator" ""))
13033 (const_string "ssediv")
13034 (eq_attr "alternative" "2,3")
13035 (const_string "sseadd")
13036 (match_operand:MODEF 3 "mult_operator" "")
13037 (const_string "fmul")
13038 (match_operand:MODEF 3 "div_operator" "")
13039 (const_string "fdiv")
13041 (const_string "fop")))
13042 (set_attr "isa" "*,*,noavx,avx")
13043 (set_attr "prefix" "orig,orig,orig,vex")
13044 (set_attr "mode" "<MODE>")])
13046 (define_insn "*rcpsf2_sse"
13047 [(set (match_operand:SF 0 "register_operand" "=x")
13048 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13051 "%vrcpss\t{%1, %d0|%d0, %1}"
13052 [(set_attr "type" "sse")
13053 (set_attr "atom_sse_attr" "rcp")
13054 (set_attr "prefix" "maybe_vex")
13055 (set_attr "mode" "SF")])
13057 (define_insn "*fop_<mode>_1_sse"
13058 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13059 (match_operator:MODEF 3 "binary_fp_operator"
13060 [(match_operand:MODEF 1 "register_operand" "0,x")
13061 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13062 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13063 && !COMMUTATIVE_ARITH_P (operands[3])"
13064 "* return output_387_binary_op (insn, operands);"
13065 [(set (attr "type")
13066 (cond [(match_operand:MODEF 3 "mult_operator" "")
13067 (const_string "ssemul")
13068 (match_operand:MODEF 3 "div_operator" "")
13069 (const_string "ssediv")
13071 (const_string "sseadd")))
13072 (set_attr "isa" "noavx,avx")
13073 (set_attr "prefix" "orig,vex")
13074 (set_attr "mode" "<MODE>")])
13076 ;; This pattern is not fully shadowed by the pattern above.
13077 (define_insn "*fop_<mode>_1_i387"
13078 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13079 (match_operator:MODEF 3 "binary_fp_operator"
13080 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13081 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13082 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13083 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13084 && !COMMUTATIVE_ARITH_P (operands[3])
13085 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13086 "* return output_387_binary_op (insn, operands);"
13087 [(set (attr "type")
13088 (cond [(match_operand:MODEF 3 "mult_operator" "")
13089 (const_string "fmul")
13090 (match_operand:MODEF 3 "div_operator" "")
13091 (const_string "fdiv")
13093 (const_string "fop")))
13094 (set_attr "mode" "<MODE>")])
13096 ;; ??? Add SSE splitters for these!
13097 (define_insn "*fop_<MODEF:mode>_2_i387"
13098 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13099 (match_operator:MODEF 3 "binary_fp_operator"
13101 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13102 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13103 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13104 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13105 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13106 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13107 [(set (attr "type")
13108 (cond [(match_operand:MODEF 3 "mult_operator" "")
13109 (const_string "fmul")
13110 (match_operand:MODEF 3 "div_operator" "")
13111 (const_string "fdiv")
13113 (const_string "fop")))
13114 (set_attr "fp_int_src" "true")
13115 (set_attr "mode" "<SWI24:MODE>")])
13117 (define_insn "*fop_<MODEF:mode>_3_i387"
13118 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13119 (match_operator:MODEF 3 "binary_fp_operator"
13120 [(match_operand:MODEF 1 "register_operand" "0,0")
13122 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13123 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13124 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13125 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13126 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13127 [(set (attr "type")
13128 (cond [(match_operand:MODEF 3 "mult_operator" "")
13129 (const_string "fmul")
13130 (match_operand:MODEF 3 "div_operator" "")
13131 (const_string "fdiv")
13133 (const_string "fop")))
13134 (set_attr "fp_int_src" "true")
13135 (set_attr "mode" "<MODE>")])
13137 (define_insn "*fop_df_4_i387"
13138 [(set (match_operand:DF 0 "register_operand" "=f,f")
13139 (match_operator:DF 3 "binary_fp_operator"
13141 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13142 (match_operand:DF 2 "register_operand" "0,f")]))]
13143 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13144 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13145 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13146 "* return output_387_binary_op (insn, operands);"
13147 [(set (attr "type")
13148 (cond [(match_operand:DF 3 "mult_operator" "")
13149 (const_string "fmul")
13150 (match_operand:DF 3 "div_operator" "")
13151 (const_string "fdiv")
13153 (const_string "fop")))
13154 (set_attr "mode" "SF")])
13156 (define_insn "*fop_df_5_i387"
13157 [(set (match_operand:DF 0 "register_operand" "=f,f")
13158 (match_operator:DF 3 "binary_fp_operator"
13159 [(match_operand:DF 1 "register_operand" "0,f")
13161 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13162 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13163 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13164 "* return output_387_binary_op (insn, operands);"
13165 [(set (attr "type")
13166 (cond [(match_operand:DF 3 "mult_operator" "")
13167 (const_string "fmul")
13168 (match_operand:DF 3 "div_operator" "")
13169 (const_string "fdiv")
13171 (const_string "fop")))
13172 (set_attr "mode" "SF")])
13174 (define_insn "*fop_df_6_i387"
13175 [(set (match_operand:DF 0 "register_operand" "=f,f")
13176 (match_operator:DF 3 "binary_fp_operator"
13178 (match_operand:SF 1 "register_operand" "0,f"))
13180 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13181 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13182 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13183 "* return output_387_binary_op (insn, operands);"
13184 [(set (attr "type")
13185 (cond [(match_operand:DF 3 "mult_operator" "")
13186 (const_string "fmul")
13187 (match_operand:DF 3 "div_operator" "")
13188 (const_string "fdiv")
13190 (const_string "fop")))
13191 (set_attr "mode" "SF")])
13193 (define_insn "*fop_xf_comm_i387"
13194 [(set (match_operand:XF 0 "register_operand" "=f")
13195 (match_operator:XF 3 "binary_fp_operator"
13196 [(match_operand:XF 1 "register_operand" "%0")
13197 (match_operand:XF 2 "register_operand" "f")]))]
13199 && COMMUTATIVE_ARITH_P (operands[3])"
13200 "* return output_387_binary_op (insn, operands);"
13201 [(set (attr "type")
13202 (if_then_else (match_operand:XF 3 "mult_operator" "")
13203 (const_string "fmul")
13204 (const_string "fop")))
13205 (set_attr "mode" "XF")])
13207 (define_insn "*fop_xf_1_i387"
13208 [(set (match_operand:XF 0 "register_operand" "=f,f")
13209 (match_operator:XF 3 "binary_fp_operator"
13210 [(match_operand:XF 1 "register_operand" "0,f")
13211 (match_operand:XF 2 "register_operand" "f,0")]))]
13213 && !COMMUTATIVE_ARITH_P (operands[3])"
13214 "* return output_387_binary_op (insn, operands);"
13215 [(set (attr "type")
13216 (cond [(match_operand:XF 3 "mult_operator" "")
13217 (const_string "fmul")
13218 (match_operand:XF 3 "div_operator" "")
13219 (const_string "fdiv")
13221 (const_string "fop")))
13222 (set_attr "mode" "XF")])
13224 (define_insn "*fop_xf_2_i387"
13225 [(set (match_operand:XF 0 "register_operand" "=f,f")
13226 (match_operator:XF 3 "binary_fp_operator"
13228 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13229 (match_operand:XF 2 "register_operand" "0,0")]))]
13230 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13231 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13232 [(set (attr "type")
13233 (cond [(match_operand:XF 3 "mult_operator" "")
13234 (const_string "fmul")
13235 (match_operand:XF 3 "div_operator" "")
13236 (const_string "fdiv")
13238 (const_string "fop")))
13239 (set_attr "fp_int_src" "true")
13240 (set_attr "mode" "<MODE>")])
13242 (define_insn "*fop_xf_3_i387"
13243 [(set (match_operand:XF 0 "register_operand" "=f,f")
13244 (match_operator:XF 3 "binary_fp_operator"
13245 [(match_operand:XF 1 "register_operand" "0,0")
13247 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13248 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13249 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13250 [(set (attr "type")
13251 (cond [(match_operand:XF 3 "mult_operator" "")
13252 (const_string "fmul")
13253 (match_operand:XF 3 "div_operator" "")
13254 (const_string "fdiv")
13256 (const_string "fop")))
13257 (set_attr "fp_int_src" "true")
13258 (set_attr "mode" "<MODE>")])
13260 (define_insn "*fop_xf_4_i387"
13261 [(set (match_operand:XF 0 "register_operand" "=f,f")
13262 (match_operator:XF 3 "binary_fp_operator"
13264 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13265 (match_operand:XF 2 "register_operand" "0,f")]))]
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_5_i387"
13278 [(set (match_operand:XF 0 "register_operand" "=f,f")
13279 (match_operator:XF 3 "binary_fp_operator"
13280 [(match_operand:XF 1 "register_operand" "0,f")
13282 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13284 "* return output_387_binary_op (insn, operands);"
13285 [(set (attr "type")
13286 (cond [(match_operand:XF 3 "mult_operator" "")
13287 (const_string "fmul")
13288 (match_operand:XF 3 "div_operator" "")
13289 (const_string "fdiv")
13291 (const_string "fop")))
13292 (set_attr "mode" "<MODE>")])
13294 (define_insn "*fop_xf_6_i387"
13295 [(set (match_operand:XF 0 "register_operand" "=f,f")
13296 (match_operator:XF 3 "binary_fp_operator"
13298 (match_operand:MODEF 1 "register_operand" "0,f"))
13300 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13302 "* return output_387_binary_op (insn, operands);"
13303 [(set (attr "type")
13304 (cond [(match_operand:XF 3 "mult_operator" "")
13305 (const_string "fmul")
13306 (match_operand:XF 3 "div_operator" "")
13307 (const_string "fdiv")
13309 (const_string "fop")))
13310 (set_attr "mode" "<MODE>")])
13313 [(set (match_operand 0 "register_operand" "")
13314 (match_operator 3 "binary_fp_operator"
13315 [(float (match_operand:SWI24 1 "register_operand" ""))
13316 (match_operand 2 "register_operand" "")]))]
13318 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13319 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13322 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13323 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13324 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13325 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13326 GET_MODE (operands[3]),
13329 ix86_free_from_memory (GET_MODE (operands[1]));
13334 [(set (match_operand 0 "register_operand" "")
13335 (match_operator 3 "binary_fp_operator"
13336 [(match_operand 1 "register_operand" "")
13337 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13339 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13340 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13343 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13344 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13345 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13346 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13347 GET_MODE (operands[3]),
13350 ix86_free_from_memory (GET_MODE (operands[2]));
13354 ;; FPU special functions.
13356 ;; This pattern implements a no-op XFmode truncation for
13357 ;; all fancy i386 XFmode math functions.
13359 (define_insn "truncxf<mode>2_i387_noop_unspec"
13360 [(set (match_operand:MODEF 0 "register_operand" "=f")
13361 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13362 UNSPEC_TRUNC_NOOP))]
13363 "TARGET_USE_FANCY_MATH_387"
13364 "* return output_387_reg_move (insn, operands);"
13365 [(set_attr "type" "fmov")
13366 (set_attr "mode" "<MODE>")])
13368 (define_insn "sqrtxf2"
13369 [(set (match_operand:XF 0 "register_operand" "=f")
13370 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13371 "TARGET_USE_FANCY_MATH_387"
13373 [(set_attr "type" "fpspc")
13374 (set_attr "mode" "XF")
13375 (set_attr "athlon_decode" "direct")
13376 (set_attr "amdfam10_decode" "direct")
13377 (set_attr "bdver1_decode" "direct")])
13379 (define_insn "sqrt_extend<mode>xf2_i387"
13380 [(set (match_operand:XF 0 "register_operand" "=f")
13383 (match_operand:MODEF 1 "register_operand" "0"))))]
13384 "TARGET_USE_FANCY_MATH_387"
13386 [(set_attr "type" "fpspc")
13387 (set_attr "mode" "XF")
13388 (set_attr "athlon_decode" "direct")
13389 (set_attr "amdfam10_decode" "direct")
13390 (set_attr "bdver1_decode" "direct")])
13392 (define_insn "*rsqrtsf2_sse"
13393 [(set (match_operand:SF 0 "register_operand" "=x")
13394 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13397 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13398 [(set_attr "type" "sse")
13399 (set_attr "atom_sse_attr" "rcp")
13400 (set_attr "prefix" "maybe_vex")
13401 (set_attr "mode" "SF")])
13403 (define_expand "rsqrtsf2"
13404 [(set (match_operand:SF 0 "register_operand" "")
13405 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13409 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13413 (define_insn "*sqrt<mode>2_sse"
13414 [(set (match_operand:MODEF 0 "register_operand" "=x")
13416 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13417 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13418 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13419 [(set_attr "type" "sse")
13420 (set_attr "atom_sse_attr" "sqrt")
13421 (set_attr "prefix" "maybe_vex")
13422 (set_attr "mode" "<MODE>")
13423 (set_attr "athlon_decode" "*")
13424 (set_attr "amdfam10_decode" "*")
13425 (set_attr "bdver1_decode" "*")])
13427 (define_expand "sqrt<mode>2"
13428 [(set (match_operand:MODEF 0 "register_operand" "")
13430 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13431 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13432 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13434 if (<MODE>mode == SFmode
13436 && TARGET_RECIP_SQRT
13437 && !optimize_function_for_size_p (cfun)
13438 && flag_finite_math_only && !flag_trapping_math
13439 && flag_unsafe_math_optimizations)
13441 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13445 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13447 rtx op0 = gen_reg_rtx (XFmode);
13448 rtx op1 = force_reg (<MODE>mode, operands[1]);
13450 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13451 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13456 (define_insn "fpremxf4_i387"
13457 [(set (match_operand:XF 0 "register_operand" "=f")
13458 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13459 (match_operand:XF 3 "register_operand" "1")]
13461 (set (match_operand:XF 1 "register_operand" "=u")
13462 (unspec:XF [(match_dup 2) (match_dup 3)]
13464 (set (reg:CCFP FPSR_REG)
13465 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13467 "TARGET_USE_FANCY_MATH_387"
13469 [(set_attr "type" "fpspc")
13470 (set_attr "mode" "XF")])
13472 (define_expand "fmodxf3"
13473 [(use (match_operand:XF 0 "register_operand" ""))
13474 (use (match_operand:XF 1 "general_operand" ""))
13475 (use (match_operand:XF 2 "general_operand" ""))]
13476 "TARGET_USE_FANCY_MATH_387"
13478 rtx label = gen_label_rtx ();
13480 rtx op1 = gen_reg_rtx (XFmode);
13481 rtx op2 = gen_reg_rtx (XFmode);
13483 emit_move_insn (op2, operands[2]);
13484 emit_move_insn (op1, operands[1]);
13486 emit_label (label);
13487 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13488 ix86_emit_fp_unordered_jump (label);
13489 LABEL_NUSES (label) = 1;
13491 emit_move_insn (operands[0], op1);
13495 (define_expand "fmod<mode>3"
13496 [(use (match_operand:MODEF 0 "register_operand" ""))
13497 (use (match_operand:MODEF 1 "general_operand" ""))
13498 (use (match_operand:MODEF 2 "general_operand" ""))]
13499 "TARGET_USE_FANCY_MATH_387"
13501 rtx (*gen_truncxf) (rtx, rtx);
13503 rtx label = gen_label_rtx ();
13505 rtx op1 = gen_reg_rtx (XFmode);
13506 rtx op2 = gen_reg_rtx (XFmode);
13508 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13509 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13511 emit_label (label);
13512 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13513 ix86_emit_fp_unordered_jump (label);
13514 LABEL_NUSES (label) = 1;
13516 /* Truncate the result properly for strict SSE math. */
13517 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13518 && !TARGET_MIX_SSE_I387)
13519 gen_truncxf = gen_truncxf<mode>2;
13521 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13523 emit_insn (gen_truncxf (operands[0], op1));
13527 (define_insn "fprem1xf4_i387"
13528 [(set (match_operand:XF 0 "register_operand" "=f")
13529 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13530 (match_operand:XF 3 "register_operand" "1")]
13532 (set (match_operand:XF 1 "register_operand" "=u")
13533 (unspec:XF [(match_dup 2) (match_dup 3)]
13535 (set (reg:CCFP FPSR_REG)
13536 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13538 "TARGET_USE_FANCY_MATH_387"
13540 [(set_attr "type" "fpspc")
13541 (set_attr "mode" "XF")])
13543 (define_expand "remainderxf3"
13544 [(use (match_operand:XF 0 "register_operand" ""))
13545 (use (match_operand:XF 1 "general_operand" ""))
13546 (use (match_operand:XF 2 "general_operand" ""))]
13547 "TARGET_USE_FANCY_MATH_387"
13549 rtx label = gen_label_rtx ();
13551 rtx op1 = gen_reg_rtx (XFmode);
13552 rtx op2 = gen_reg_rtx (XFmode);
13554 emit_move_insn (op2, operands[2]);
13555 emit_move_insn (op1, operands[1]);
13557 emit_label (label);
13558 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13559 ix86_emit_fp_unordered_jump (label);
13560 LABEL_NUSES (label) = 1;
13562 emit_move_insn (operands[0], op1);
13566 (define_expand "remainder<mode>3"
13567 [(use (match_operand:MODEF 0 "register_operand" ""))
13568 (use (match_operand:MODEF 1 "general_operand" ""))
13569 (use (match_operand:MODEF 2 "general_operand" ""))]
13570 "TARGET_USE_FANCY_MATH_387"
13572 rtx (*gen_truncxf) (rtx, rtx);
13574 rtx label = gen_label_rtx ();
13576 rtx op1 = gen_reg_rtx (XFmode);
13577 rtx op2 = gen_reg_rtx (XFmode);
13579 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13580 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13582 emit_label (label);
13584 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13585 ix86_emit_fp_unordered_jump (label);
13586 LABEL_NUSES (label) = 1;
13588 /* Truncate the result properly for strict SSE math. */
13589 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13590 && !TARGET_MIX_SSE_I387)
13591 gen_truncxf = gen_truncxf<mode>2;
13593 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13595 emit_insn (gen_truncxf (operands[0], op1));
13599 (define_insn "*sinxf2_i387"
13600 [(set (match_operand:XF 0 "register_operand" "=f")
13601 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13602 "TARGET_USE_FANCY_MATH_387
13603 && flag_unsafe_math_optimizations"
13605 [(set_attr "type" "fpspc")
13606 (set_attr "mode" "XF")])
13608 (define_insn "*sin_extend<mode>xf2_i387"
13609 [(set (match_operand:XF 0 "register_operand" "=f")
13610 (unspec:XF [(float_extend:XF
13611 (match_operand:MODEF 1 "register_operand" "0"))]
13613 "TARGET_USE_FANCY_MATH_387
13614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13615 || TARGET_MIX_SSE_I387)
13616 && flag_unsafe_math_optimizations"
13618 [(set_attr "type" "fpspc")
13619 (set_attr "mode" "XF")])
13621 (define_insn "*cosxf2_i387"
13622 [(set (match_operand:XF 0 "register_operand" "=f")
13623 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13624 "TARGET_USE_FANCY_MATH_387
13625 && flag_unsafe_math_optimizations"
13627 [(set_attr "type" "fpspc")
13628 (set_attr "mode" "XF")])
13630 (define_insn "*cos_extend<mode>xf2_i387"
13631 [(set (match_operand:XF 0 "register_operand" "=f")
13632 (unspec:XF [(float_extend:XF
13633 (match_operand:MODEF 1 "register_operand" "0"))]
13635 "TARGET_USE_FANCY_MATH_387
13636 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13637 || TARGET_MIX_SSE_I387)
13638 && flag_unsafe_math_optimizations"
13640 [(set_attr "type" "fpspc")
13641 (set_attr "mode" "XF")])
13643 ;; When sincos pattern is defined, sin and cos builtin functions will be
13644 ;; expanded to sincos pattern with one of its outputs left unused.
13645 ;; CSE pass will figure out if two sincos patterns can be combined,
13646 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13647 ;; depending on the unused output.
13649 (define_insn "sincosxf3"
13650 [(set (match_operand:XF 0 "register_operand" "=f")
13651 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13652 UNSPEC_SINCOS_COS))
13653 (set (match_operand:XF 1 "register_operand" "=u")
13654 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13655 "TARGET_USE_FANCY_MATH_387
13656 && flag_unsafe_math_optimizations"
13658 [(set_attr "type" "fpspc")
13659 (set_attr "mode" "XF")])
13662 [(set (match_operand:XF 0 "register_operand" "")
13663 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13664 UNSPEC_SINCOS_COS))
13665 (set (match_operand:XF 1 "register_operand" "")
13666 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13667 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13668 && can_create_pseudo_p ()"
13669 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13672 [(set (match_operand:XF 0 "register_operand" "")
13673 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13674 UNSPEC_SINCOS_COS))
13675 (set (match_operand:XF 1 "register_operand" "")
13676 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13677 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13678 && can_create_pseudo_p ()"
13679 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13681 (define_insn "sincos_extend<mode>xf3_i387"
13682 [(set (match_operand:XF 0 "register_operand" "=f")
13683 (unspec:XF [(float_extend:XF
13684 (match_operand:MODEF 2 "register_operand" "0"))]
13685 UNSPEC_SINCOS_COS))
13686 (set (match_operand:XF 1 "register_operand" "=u")
13687 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13688 "TARGET_USE_FANCY_MATH_387
13689 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13690 || TARGET_MIX_SSE_I387)
13691 && flag_unsafe_math_optimizations"
13693 [(set_attr "type" "fpspc")
13694 (set_attr "mode" "XF")])
13697 [(set (match_operand:XF 0 "register_operand" "")
13698 (unspec:XF [(float_extend:XF
13699 (match_operand:MODEF 2 "register_operand" ""))]
13700 UNSPEC_SINCOS_COS))
13701 (set (match_operand:XF 1 "register_operand" "")
13702 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13703 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13704 && can_create_pseudo_p ()"
13705 [(set (match_dup 1)
13706 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13709 [(set (match_operand:XF 0 "register_operand" "")
13710 (unspec:XF [(float_extend:XF
13711 (match_operand:MODEF 2 "register_operand" ""))]
13712 UNSPEC_SINCOS_COS))
13713 (set (match_operand:XF 1 "register_operand" "")
13714 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13715 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13716 && can_create_pseudo_p ()"
13717 [(set (match_dup 0)
13718 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13720 (define_expand "sincos<mode>3"
13721 [(use (match_operand:MODEF 0 "register_operand" ""))
13722 (use (match_operand:MODEF 1 "register_operand" ""))
13723 (use (match_operand:MODEF 2 "register_operand" ""))]
13724 "TARGET_USE_FANCY_MATH_387
13725 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13726 || TARGET_MIX_SSE_I387)
13727 && flag_unsafe_math_optimizations"
13729 rtx op0 = gen_reg_rtx (XFmode);
13730 rtx op1 = gen_reg_rtx (XFmode);
13732 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13733 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13734 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13738 (define_insn "fptanxf4_i387"
13739 [(set (match_operand:XF 0 "register_operand" "=f")
13740 (match_operand:XF 3 "const_double_operand" "F"))
13741 (set (match_operand:XF 1 "register_operand" "=u")
13742 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13744 "TARGET_USE_FANCY_MATH_387
13745 && flag_unsafe_math_optimizations
13746 && standard_80387_constant_p (operands[3]) == 2"
13748 [(set_attr "type" "fpspc")
13749 (set_attr "mode" "XF")])
13751 (define_insn "fptan_extend<mode>xf4_i387"
13752 [(set (match_operand:MODEF 0 "register_operand" "=f")
13753 (match_operand:MODEF 3 "const_double_operand" "F"))
13754 (set (match_operand:XF 1 "register_operand" "=u")
13755 (unspec:XF [(float_extend:XF
13756 (match_operand:MODEF 2 "register_operand" "0"))]
13758 "TARGET_USE_FANCY_MATH_387
13759 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13760 || TARGET_MIX_SSE_I387)
13761 && flag_unsafe_math_optimizations
13762 && standard_80387_constant_p (operands[3]) == 2"
13764 [(set_attr "type" "fpspc")
13765 (set_attr "mode" "XF")])
13767 (define_expand "tanxf2"
13768 [(use (match_operand:XF 0 "register_operand" ""))
13769 (use (match_operand:XF 1 "register_operand" ""))]
13770 "TARGET_USE_FANCY_MATH_387
13771 && flag_unsafe_math_optimizations"
13773 rtx one = gen_reg_rtx (XFmode);
13774 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13776 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13780 (define_expand "tan<mode>2"
13781 [(use (match_operand:MODEF 0 "register_operand" ""))
13782 (use (match_operand:MODEF 1 "register_operand" ""))]
13783 "TARGET_USE_FANCY_MATH_387
13784 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13785 || TARGET_MIX_SSE_I387)
13786 && flag_unsafe_math_optimizations"
13788 rtx op0 = gen_reg_rtx (XFmode);
13790 rtx one = gen_reg_rtx (<MODE>mode);
13791 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13793 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13794 operands[1], op2));
13795 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13799 (define_insn "*fpatanxf3_i387"
13800 [(set (match_operand:XF 0 "register_operand" "=f")
13801 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13802 (match_operand:XF 2 "register_operand" "u")]
13804 (clobber (match_scratch:XF 3 "=2"))]
13805 "TARGET_USE_FANCY_MATH_387
13806 && flag_unsafe_math_optimizations"
13808 [(set_attr "type" "fpspc")
13809 (set_attr "mode" "XF")])
13811 (define_insn "fpatan_extend<mode>xf3_i387"
13812 [(set (match_operand:XF 0 "register_operand" "=f")
13813 (unspec:XF [(float_extend:XF
13814 (match_operand:MODEF 1 "register_operand" "0"))
13816 (match_operand:MODEF 2 "register_operand" "u"))]
13818 (clobber (match_scratch:XF 3 "=2"))]
13819 "TARGET_USE_FANCY_MATH_387
13820 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13821 || TARGET_MIX_SSE_I387)
13822 && flag_unsafe_math_optimizations"
13824 [(set_attr "type" "fpspc")
13825 (set_attr "mode" "XF")])
13827 (define_expand "atan2xf3"
13828 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13829 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13830 (match_operand:XF 1 "register_operand" "")]
13832 (clobber (match_scratch:XF 3 ""))])]
13833 "TARGET_USE_FANCY_MATH_387
13834 && flag_unsafe_math_optimizations")
13836 (define_expand "atan2<mode>3"
13837 [(use (match_operand:MODEF 0 "register_operand" ""))
13838 (use (match_operand:MODEF 1 "register_operand" ""))
13839 (use (match_operand:MODEF 2 "register_operand" ""))]
13840 "TARGET_USE_FANCY_MATH_387
13841 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13842 || TARGET_MIX_SSE_I387)
13843 && flag_unsafe_math_optimizations"
13845 rtx op0 = gen_reg_rtx (XFmode);
13847 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13848 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13852 (define_expand "atanxf2"
13853 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13854 (unspec:XF [(match_dup 2)
13855 (match_operand:XF 1 "register_operand" "")]
13857 (clobber (match_scratch:XF 3 ""))])]
13858 "TARGET_USE_FANCY_MATH_387
13859 && flag_unsafe_math_optimizations"
13861 operands[2] = gen_reg_rtx (XFmode);
13862 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13865 (define_expand "atan<mode>2"
13866 [(use (match_operand:MODEF 0 "register_operand" ""))
13867 (use (match_operand:MODEF 1 "register_operand" ""))]
13868 "TARGET_USE_FANCY_MATH_387
13869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13870 || TARGET_MIX_SSE_I387)
13871 && flag_unsafe_math_optimizations"
13873 rtx op0 = gen_reg_rtx (XFmode);
13875 rtx op2 = gen_reg_rtx (<MODE>mode);
13876 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13878 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13879 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13883 (define_expand "asinxf2"
13884 [(set (match_dup 2)
13885 (mult:XF (match_operand:XF 1 "register_operand" "")
13887 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13888 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13889 (parallel [(set (match_operand:XF 0 "register_operand" "")
13890 (unspec:XF [(match_dup 5) (match_dup 1)]
13892 (clobber (match_scratch:XF 6 ""))])]
13893 "TARGET_USE_FANCY_MATH_387
13894 && flag_unsafe_math_optimizations"
13898 if (optimize_insn_for_size_p ())
13901 for (i = 2; i < 6; i++)
13902 operands[i] = gen_reg_rtx (XFmode);
13904 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13907 (define_expand "asin<mode>2"
13908 [(use (match_operand:MODEF 0 "register_operand" ""))
13909 (use (match_operand:MODEF 1 "general_operand" ""))]
13910 "TARGET_USE_FANCY_MATH_387
13911 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13912 || TARGET_MIX_SSE_I387)
13913 && flag_unsafe_math_optimizations"
13915 rtx op0 = gen_reg_rtx (XFmode);
13916 rtx op1 = gen_reg_rtx (XFmode);
13918 if (optimize_insn_for_size_p ())
13921 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13922 emit_insn (gen_asinxf2 (op0, op1));
13923 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13927 (define_expand "acosxf2"
13928 [(set (match_dup 2)
13929 (mult:XF (match_operand:XF 1 "register_operand" "")
13931 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13932 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13933 (parallel [(set (match_operand:XF 0 "register_operand" "")
13934 (unspec:XF [(match_dup 1) (match_dup 5)]
13936 (clobber (match_scratch:XF 6 ""))])]
13937 "TARGET_USE_FANCY_MATH_387
13938 && flag_unsafe_math_optimizations"
13942 if (optimize_insn_for_size_p ())
13945 for (i = 2; i < 6; i++)
13946 operands[i] = gen_reg_rtx (XFmode);
13948 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13951 (define_expand "acos<mode>2"
13952 [(use (match_operand:MODEF 0 "register_operand" ""))
13953 (use (match_operand:MODEF 1 "general_operand" ""))]
13954 "TARGET_USE_FANCY_MATH_387
13955 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13956 || TARGET_MIX_SSE_I387)
13957 && flag_unsafe_math_optimizations"
13959 rtx op0 = gen_reg_rtx (XFmode);
13960 rtx op1 = gen_reg_rtx (XFmode);
13962 if (optimize_insn_for_size_p ())
13965 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13966 emit_insn (gen_acosxf2 (op0, op1));
13967 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13971 (define_insn "fyl2xxf3_i387"
13972 [(set (match_operand:XF 0 "register_operand" "=f")
13973 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13974 (match_operand:XF 2 "register_operand" "u")]
13976 (clobber (match_scratch:XF 3 "=2"))]
13977 "TARGET_USE_FANCY_MATH_387
13978 && flag_unsafe_math_optimizations"
13980 [(set_attr "type" "fpspc")
13981 (set_attr "mode" "XF")])
13983 (define_insn "fyl2x_extend<mode>xf3_i387"
13984 [(set (match_operand:XF 0 "register_operand" "=f")
13985 (unspec:XF [(float_extend:XF
13986 (match_operand:MODEF 1 "register_operand" "0"))
13987 (match_operand:XF 2 "register_operand" "u")]
13989 (clobber (match_scratch:XF 3 "=2"))]
13990 "TARGET_USE_FANCY_MATH_387
13991 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13992 || TARGET_MIX_SSE_I387)
13993 && flag_unsafe_math_optimizations"
13995 [(set_attr "type" "fpspc")
13996 (set_attr "mode" "XF")])
13998 (define_expand "logxf2"
13999 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14000 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14001 (match_dup 2)] UNSPEC_FYL2X))
14002 (clobber (match_scratch:XF 3 ""))])]
14003 "TARGET_USE_FANCY_MATH_387
14004 && flag_unsafe_math_optimizations"
14006 operands[2] = gen_reg_rtx (XFmode);
14007 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14010 (define_expand "log<mode>2"
14011 [(use (match_operand:MODEF 0 "register_operand" ""))
14012 (use (match_operand:MODEF 1 "register_operand" ""))]
14013 "TARGET_USE_FANCY_MATH_387
14014 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14015 || TARGET_MIX_SSE_I387)
14016 && flag_unsafe_math_optimizations"
14018 rtx op0 = gen_reg_rtx (XFmode);
14020 rtx op2 = gen_reg_rtx (XFmode);
14021 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14023 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14024 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14028 (define_expand "log10xf2"
14029 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14030 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14031 (match_dup 2)] UNSPEC_FYL2X))
14032 (clobber (match_scratch:XF 3 ""))])]
14033 "TARGET_USE_FANCY_MATH_387
14034 && flag_unsafe_math_optimizations"
14036 operands[2] = gen_reg_rtx (XFmode);
14037 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14040 (define_expand "log10<mode>2"
14041 [(use (match_operand:MODEF 0 "register_operand" ""))
14042 (use (match_operand:MODEF 1 "register_operand" ""))]
14043 "TARGET_USE_FANCY_MATH_387
14044 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14045 || TARGET_MIX_SSE_I387)
14046 && flag_unsafe_math_optimizations"
14048 rtx op0 = gen_reg_rtx (XFmode);
14050 rtx op2 = gen_reg_rtx (XFmode);
14051 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14053 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14054 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14058 (define_expand "log2xf2"
14059 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14060 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14061 (match_dup 2)] UNSPEC_FYL2X))
14062 (clobber (match_scratch:XF 3 ""))])]
14063 "TARGET_USE_FANCY_MATH_387
14064 && flag_unsafe_math_optimizations"
14066 operands[2] = gen_reg_rtx (XFmode);
14067 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14070 (define_expand "log2<mode>2"
14071 [(use (match_operand:MODEF 0 "register_operand" ""))
14072 (use (match_operand:MODEF 1 "register_operand" ""))]
14073 "TARGET_USE_FANCY_MATH_387
14074 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14075 || TARGET_MIX_SSE_I387)
14076 && flag_unsafe_math_optimizations"
14078 rtx op0 = gen_reg_rtx (XFmode);
14080 rtx op2 = gen_reg_rtx (XFmode);
14081 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14083 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14084 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14088 (define_insn "fyl2xp1xf3_i387"
14089 [(set (match_operand:XF 0 "register_operand" "=f")
14090 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14091 (match_operand:XF 2 "register_operand" "u")]
14093 (clobber (match_scratch:XF 3 "=2"))]
14094 "TARGET_USE_FANCY_MATH_387
14095 && flag_unsafe_math_optimizations"
14097 [(set_attr "type" "fpspc")
14098 (set_attr "mode" "XF")])
14100 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14101 [(set (match_operand:XF 0 "register_operand" "=f")
14102 (unspec:XF [(float_extend:XF
14103 (match_operand:MODEF 1 "register_operand" "0"))
14104 (match_operand:XF 2 "register_operand" "u")]
14106 (clobber (match_scratch:XF 3 "=2"))]
14107 "TARGET_USE_FANCY_MATH_387
14108 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14109 || TARGET_MIX_SSE_I387)
14110 && flag_unsafe_math_optimizations"
14112 [(set_attr "type" "fpspc")
14113 (set_attr "mode" "XF")])
14115 (define_expand "log1pxf2"
14116 [(use (match_operand:XF 0 "register_operand" ""))
14117 (use (match_operand:XF 1 "register_operand" ""))]
14118 "TARGET_USE_FANCY_MATH_387
14119 && flag_unsafe_math_optimizations"
14121 if (optimize_insn_for_size_p ())
14124 ix86_emit_i387_log1p (operands[0], operands[1]);
14128 (define_expand "log1p<mode>2"
14129 [(use (match_operand:MODEF 0 "register_operand" ""))
14130 (use (match_operand:MODEF 1 "register_operand" ""))]
14131 "TARGET_USE_FANCY_MATH_387
14132 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14133 || TARGET_MIX_SSE_I387)
14134 && flag_unsafe_math_optimizations"
14138 if (optimize_insn_for_size_p ())
14141 op0 = gen_reg_rtx (XFmode);
14143 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14145 ix86_emit_i387_log1p (op0, operands[1]);
14146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14150 (define_insn "fxtractxf3_i387"
14151 [(set (match_operand:XF 0 "register_operand" "=f")
14152 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14153 UNSPEC_XTRACT_FRACT))
14154 (set (match_operand:XF 1 "register_operand" "=u")
14155 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && flag_unsafe_math_optimizations"
14159 [(set_attr "type" "fpspc")
14160 (set_attr "mode" "XF")])
14162 (define_insn "fxtract_extend<mode>xf3_i387"
14163 [(set (match_operand:XF 0 "register_operand" "=f")
14164 (unspec:XF [(float_extend:XF
14165 (match_operand:MODEF 2 "register_operand" "0"))]
14166 UNSPEC_XTRACT_FRACT))
14167 (set (match_operand:XF 1 "register_operand" "=u")
14168 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14169 "TARGET_USE_FANCY_MATH_387
14170 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14171 || TARGET_MIX_SSE_I387)
14172 && flag_unsafe_math_optimizations"
14174 [(set_attr "type" "fpspc")
14175 (set_attr "mode" "XF")])
14177 (define_expand "logbxf2"
14178 [(parallel [(set (match_dup 2)
14179 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14180 UNSPEC_XTRACT_FRACT))
14181 (set (match_operand:XF 0 "register_operand" "")
14182 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14183 "TARGET_USE_FANCY_MATH_387
14184 && flag_unsafe_math_optimizations"
14185 "operands[2] = gen_reg_rtx (XFmode);")
14187 (define_expand "logb<mode>2"
14188 [(use (match_operand:MODEF 0 "register_operand" ""))
14189 (use (match_operand:MODEF 1 "register_operand" ""))]
14190 "TARGET_USE_FANCY_MATH_387
14191 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14192 || TARGET_MIX_SSE_I387)
14193 && flag_unsafe_math_optimizations"
14195 rtx op0 = gen_reg_rtx (XFmode);
14196 rtx op1 = gen_reg_rtx (XFmode);
14198 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14199 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14203 (define_expand "ilogbxf2"
14204 [(use (match_operand:SI 0 "register_operand" ""))
14205 (use (match_operand:XF 1 "register_operand" ""))]
14206 "TARGET_USE_FANCY_MATH_387
14207 && flag_unsafe_math_optimizations"
14211 if (optimize_insn_for_size_p ())
14214 op0 = gen_reg_rtx (XFmode);
14215 op1 = gen_reg_rtx (XFmode);
14217 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14218 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14222 (define_expand "ilogb<mode>2"
14223 [(use (match_operand:SI 0 "register_operand" ""))
14224 (use (match_operand:MODEF 1 "register_operand" ""))]
14225 "TARGET_USE_FANCY_MATH_387
14226 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14227 || TARGET_MIX_SSE_I387)
14228 && flag_unsafe_math_optimizations"
14232 if (optimize_insn_for_size_p ())
14235 op0 = gen_reg_rtx (XFmode);
14236 op1 = gen_reg_rtx (XFmode);
14238 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14239 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14243 (define_insn "*f2xm1xf2_i387"
14244 [(set (match_operand:XF 0 "register_operand" "=f")
14245 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14247 "TARGET_USE_FANCY_MATH_387
14248 && flag_unsafe_math_optimizations"
14250 [(set_attr "type" "fpspc")
14251 (set_attr "mode" "XF")])
14253 (define_insn "*fscalexf4_i387"
14254 [(set (match_operand:XF 0 "register_operand" "=f")
14255 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14256 (match_operand:XF 3 "register_operand" "1")]
14257 UNSPEC_FSCALE_FRACT))
14258 (set (match_operand:XF 1 "register_operand" "=u")
14259 (unspec:XF [(match_dup 2) (match_dup 3)]
14260 UNSPEC_FSCALE_EXP))]
14261 "TARGET_USE_FANCY_MATH_387
14262 && flag_unsafe_math_optimizations"
14264 [(set_attr "type" "fpspc")
14265 (set_attr "mode" "XF")])
14267 (define_expand "expNcorexf3"
14268 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14269 (match_operand:XF 2 "register_operand" "")))
14270 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14271 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14272 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14273 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14274 (parallel [(set (match_operand:XF 0 "register_operand" "")
14275 (unspec:XF [(match_dup 8) (match_dup 4)]
14276 UNSPEC_FSCALE_FRACT))
14278 (unspec:XF [(match_dup 8) (match_dup 4)]
14279 UNSPEC_FSCALE_EXP))])]
14280 "TARGET_USE_FANCY_MATH_387
14281 && flag_unsafe_math_optimizations"
14285 if (optimize_insn_for_size_p ())
14288 for (i = 3; i < 10; i++)
14289 operands[i] = gen_reg_rtx (XFmode);
14291 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14294 (define_expand "expxf2"
14295 [(use (match_operand:XF 0 "register_operand" ""))
14296 (use (match_operand:XF 1 "register_operand" ""))]
14297 "TARGET_USE_FANCY_MATH_387
14298 && flag_unsafe_math_optimizations"
14302 if (optimize_insn_for_size_p ())
14305 op2 = gen_reg_rtx (XFmode);
14306 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14308 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14312 (define_expand "exp<mode>2"
14313 [(use (match_operand:MODEF 0 "register_operand" ""))
14314 (use (match_operand:MODEF 1 "general_operand" ""))]
14315 "TARGET_USE_FANCY_MATH_387
14316 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14317 || TARGET_MIX_SSE_I387)
14318 && flag_unsafe_math_optimizations"
14322 if (optimize_insn_for_size_p ())
14325 op0 = gen_reg_rtx (XFmode);
14326 op1 = gen_reg_rtx (XFmode);
14328 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14329 emit_insn (gen_expxf2 (op0, op1));
14330 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14334 (define_expand "exp10xf2"
14335 [(use (match_operand:XF 0 "register_operand" ""))
14336 (use (match_operand:XF 1 "register_operand" ""))]
14337 "TARGET_USE_FANCY_MATH_387
14338 && flag_unsafe_math_optimizations"
14342 if (optimize_insn_for_size_p ())
14345 op2 = gen_reg_rtx (XFmode);
14346 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14348 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14352 (define_expand "exp10<mode>2"
14353 [(use (match_operand:MODEF 0 "register_operand" ""))
14354 (use (match_operand:MODEF 1 "general_operand" ""))]
14355 "TARGET_USE_FANCY_MATH_387
14356 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14357 || TARGET_MIX_SSE_I387)
14358 && flag_unsafe_math_optimizations"
14362 if (optimize_insn_for_size_p ())
14365 op0 = gen_reg_rtx (XFmode);
14366 op1 = gen_reg_rtx (XFmode);
14368 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14369 emit_insn (gen_exp10xf2 (op0, op1));
14370 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14374 (define_expand "exp2xf2"
14375 [(use (match_operand:XF 0 "register_operand" ""))
14376 (use (match_operand:XF 1 "register_operand" ""))]
14377 "TARGET_USE_FANCY_MATH_387
14378 && flag_unsafe_math_optimizations"
14382 if (optimize_insn_for_size_p ())
14385 op2 = gen_reg_rtx (XFmode);
14386 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14388 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14392 (define_expand "exp2<mode>2"
14393 [(use (match_operand:MODEF 0 "register_operand" ""))
14394 (use (match_operand:MODEF 1 "general_operand" ""))]
14395 "TARGET_USE_FANCY_MATH_387
14396 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14397 || TARGET_MIX_SSE_I387)
14398 && flag_unsafe_math_optimizations"
14402 if (optimize_insn_for_size_p ())
14405 op0 = gen_reg_rtx (XFmode);
14406 op1 = gen_reg_rtx (XFmode);
14408 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14409 emit_insn (gen_exp2xf2 (op0, op1));
14410 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14414 (define_expand "expm1xf2"
14415 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14417 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14418 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14419 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14420 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14421 (parallel [(set (match_dup 7)
14422 (unspec:XF [(match_dup 6) (match_dup 4)]
14423 UNSPEC_FSCALE_FRACT))
14425 (unspec:XF [(match_dup 6) (match_dup 4)]
14426 UNSPEC_FSCALE_EXP))])
14427 (parallel [(set (match_dup 10)
14428 (unspec:XF [(match_dup 9) (match_dup 8)]
14429 UNSPEC_FSCALE_FRACT))
14430 (set (match_dup 11)
14431 (unspec:XF [(match_dup 9) (match_dup 8)]
14432 UNSPEC_FSCALE_EXP))])
14433 (set (match_dup 12) (minus:XF (match_dup 10)
14434 (float_extend:XF (match_dup 13))))
14435 (set (match_operand:XF 0 "register_operand" "")
14436 (plus:XF (match_dup 12) (match_dup 7)))]
14437 "TARGET_USE_FANCY_MATH_387
14438 && flag_unsafe_math_optimizations"
14442 if (optimize_insn_for_size_p ())
14445 for (i = 2; i < 13; i++)
14446 operands[i] = gen_reg_rtx (XFmode);
14449 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14451 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14454 (define_expand "expm1<mode>2"
14455 [(use (match_operand:MODEF 0 "register_operand" ""))
14456 (use (match_operand:MODEF 1 "general_operand" ""))]
14457 "TARGET_USE_FANCY_MATH_387
14458 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14459 || TARGET_MIX_SSE_I387)
14460 && flag_unsafe_math_optimizations"
14464 if (optimize_insn_for_size_p ())
14467 op0 = gen_reg_rtx (XFmode);
14468 op1 = gen_reg_rtx (XFmode);
14470 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14471 emit_insn (gen_expm1xf2 (op0, op1));
14472 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14476 (define_expand "ldexpxf3"
14477 [(set (match_dup 3)
14478 (float:XF (match_operand:SI 2 "register_operand" "")))
14479 (parallel [(set (match_operand:XF 0 " register_operand" "")
14480 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14482 UNSPEC_FSCALE_FRACT))
14484 (unspec:XF [(match_dup 1) (match_dup 3)]
14485 UNSPEC_FSCALE_EXP))])]
14486 "TARGET_USE_FANCY_MATH_387
14487 && flag_unsafe_math_optimizations"
14489 if (optimize_insn_for_size_p ())
14492 operands[3] = gen_reg_rtx (XFmode);
14493 operands[4] = gen_reg_rtx (XFmode);
14496 (define_expand "ldexp<mode>3"
14497 [(use (match_operand:MODEF 0 "register_operand" ""))
14498 (use (match_operand:MODEF 1 "general_operand" ""))
14499 (use (match_operand:SI 2 "register_operand" ""))]
14500 "TARGET_USE_FANCY_MATH_387
14501 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14502 || TARGET_MIX_SSE_I387)
14503 && flag_unsafe_math_optimizations"
14507 if (optimize_insn_for_size_p ())
14510 op0 = gen_reg_rtx (XFmode);
14511 op1 = gen_reg_rtx (XFmode);
14513 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14514 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14519 (define_expand "scalbxf3"
14520 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14521 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14522 (match_operand:XF 2 "register_operand" "")]
14523 UNSPEC_FSCALE_FRACT))
14525 (unspec:XF [(match_dup 1) (match_dup 2)]
14526 UNSPEC_FSCALE_EXP))])]
14527 "TARGET_USE_FANCY_MATH_387
14528 && flag_unsafe_math_optimizations"
14530 if (optimize_insn_for_size_p ())
14533 operands[3] = gen_reg_rtx (XFmode);
14536 (define_expand "scalb<mode>3"
14537 [(use (match_operand:MODEF 0 "register_operand" ""))
14538 (use (match_operand:MODEF 1 "general_operand" ""))
14539 (use (match_operand:MODEF 2 "general_operand" ""))]
14540 "TARGET_USE_FANCY_MATH_387
14541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14542 || TARGET_MIX_SSE_I387)
14543 && flag_unsafe_math_optimizations"
14547 if (optimize_insn_for_size_p ())
14550 op0 = gen_reg_rtx (XFmode);
14551 op1 = gen_reg_rtx (XFmode);
14552 op2 = gen_reg_rtx (XFmode);
14554 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14555 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14556 emit_insn (gen_scalbxf3 (op0, op1, op2));
14557 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14561 (define_expand "significandxf2"
14562 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14563 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14564 UNSPEC_XTRACT_FRACT))
14566 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14567 "TARGET_USE_FANCY_MATH_387
14568 && flag_unsafe_math_optimizations"
14569 "operands[2] = gen_reg_rtx (XFmode);")
14571 (define_expand "significand<mode>2"
14572 [(use (match_operand:MODEF 0 "register_operand" ""))
14573 (use (match_operand:MODEF 1 "register_operand" ""))]
14574 "TARGET_USE_FANCY_MATH_387
14575 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14576 || TARGET_MIX_SSE_I387)
14577 && flag_unsafe_math_optimizations"
14579 rtx op0 = gen_reg_rtx (XFmode);
14580 rtx op1 = gen_reg_rtx (XFmode);
14582 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14583 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14588 (define_insn "sse4_1_round<mode>2"
14589 [(set (match_operand:MODEF 0 "register_operand" "=x")
14590 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14591 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14594 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14595 [(set_attr "type" "ssecvt")
14596 (set_attr "prefix_extra" "1")
14597 (set_attr "prefix" "maybe_vex")
14598 (set_attr "mode" "<MODE>")])
14600 (define_insn "rintxf2"
14601 [(set (match_operand:XF 0 "register_operand" "=f")
14602 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14604 "TARGET_USE_FANCY_MATH_387
14605 && flag_unsafe_math_optimizations"
14607 [(set_attr "type" "fpspc")
14608 (set_attr "mode" "XF")])
14610 (define_expand "rint<mode>2"
14611 [(use (match_operand:MODEF 0 "register_operand" ""))
14612 (use (match_operand:MODEF 1 "register_operand" ""))]
14613 "(TARGET_USE_FANCY_MATH_387
14614 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14615 || TARGET_MIX_SSE_I387)
14616 && flag_unsafe_math_optimizations)
14617 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14618 && !flag_trapping_math)"
14620 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14621 && !flag_trapping_math)
14624 emit_insn (gen_sse4_1_round<mode>2
14625 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14626 else if (optimize_insn_for_size_p ())
14629 ix86_expand_rint (operands[0], operands[1]);
14633 rtx op0 = gen_reg_rtx (XFmode);
14634 rtx op1 = gen_reg_rtx (XFmode);
14636 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14637 emit_insn (gen_rintxf2 (op0, op1));
14639 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14644 (define_expand "round<mode>2"
14645 [(match_operand:X87MODEF 0 "register_operand" "")
14646 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14647 "(TARGET_USE_FANCY_MATH_387
14648 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14649 || TARGET_MIX_SSE_I387)
14650 && flag_unsafe_math_optimizations)
14651 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14652 && !flag_trapping_math && !flag_rounding_math)"
14654 if (optimize_insn_for_size_p ())
14657 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14658 && !flag_trapping_math && !flag_rounding_math)
14662 operands[1] = force_reg (<MODE>mode, operands[1]);
14663 ix86_expand_round_sse4 (operands[0], operands[1]);
14665 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14666 ix86_expand_round (operands[0], operands[1]);
14668 ix86_expand_rounddf_32 (operands[0], operands[1]);
14672 operands[1] = force_reg (<MODE>mode, operands[1]);
14673 ix86_emit_i387_round (operands[0], operands[1]);
14678 (define_insn_and_split "*fistdi2_1"
14679 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14680 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14682 "TARGET_USE_FANCY_MATH_387
14683 && can_create_pseudo_p ()"
14688 if (memory_operand (operands[0], VOIDmode))
14689 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14692 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14693 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14698 [(set_attr "type" "fpspc")
14699 (set_attr "mode" "DI")])
14701 (define_insn "fistdi2"
14702 [(set (match_operand:DI 0 "memory_operand" "=m")
14703 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14705 (clobber (match_scratch:XF 2 "=&1f"))]
14706 "TARGET_USE_FANCY_MATH_387"
14707 "* return output_fix_trunc (insn, operands, false);"
14708 [(set_attr "type" "fpspc")
14709 (set_attr "mode" "DI")])
14711 (define_insn "fistdi2_with_temp"
14712 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14713 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14715 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14716 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14717 "TARGET_USE_FANCY_MATH_387"
14719 [(set_attr "type" "fpspc")
14720 (set_attr "mode" "DI")])
14723 [(set (match_operand:DI 0 "register_operand" "")
14724 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14726 (clobber (match_operand:DI 2 "memory_operand" ""))
14727 (clobber (match_scratch 3 ""))]
14729 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14730 (clobber (match_dup 3))])
14731 (set (match_dup 0) (match_dup 2))])
14734 [(set (match_operand:DI 0 "memory_operand" "")
14735 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14737 (clobber (match_operand:DI 2 "memory_operand" ""))
14738 (clobber (match_scratch 3 ""))]
14740 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14741 (clobber (match_dup 3))])])
14743 (define_insn_and_split "*fist<mode>2_1"
14744 [(set (match_operand:SWI24 0 "register_operand" "")
14745 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14747 "TARGET_USE_FANCY_MATH_387
14748 && can_create_pseudo_p ()"
14753 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14754 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14758 [(set_attr "type" "fpspc")
14759 (set_attr "mode" "<MODE>")])
14761 (define_insn "fist<mode>2"
14762 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14763 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14765 "TARGET_USE_FANCY_MATH_387"
14766 "* return output_fix_trunc (insn, operands, false);"
14767 [(set_attr "type" "fpspc")
14768 (set_attr "mode" "<MODE>")])
14770 (define_insn "fist<mode>2_with_temp"
14771 [(set (match_operand:SWI24 0 "register_operand" "=r")
14772 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14774 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14775 "TARGET_USE_FANCY_MATH_387"
14777 [(set_attr "type" "fpspc")
14778 (set_attr "mode" "<MODE>")])
14781 [(set (match_operand:SWI24 0 "register_operand" "")
14782 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14784 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14786 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14787 (set (match_dup 0) (match_dup 2))])
14790 [(set (match_operand:SWI24 0 "memory_operand" "")
14791 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14793 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14795 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14797 (define_expand "lrintxf<mode>2"
14798 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14799 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14801 "TARGET_USE_FANCY_MATH_387")
14803 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14804 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14805 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14806 UNSPEC_FIX_NOTRUNC))]
14807 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14808 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14810 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14811 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14812 (match_operand:X87MODEF 1 "register_operand" "")]
14813 "(TARGET_USE_FANCY_MATH_387
14814 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14815 || TARGET_MIX_SSE_I387)
14816 && flag_unsafe_math_optimizations)
14817 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14818 && <SWI248x:MODE>mode != HImode
14819 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14820 && !flag_trapping_math && !flag_rounding_math)"
14822 if (optimize_insn_for_size_p ())
14825 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14826 && <SWI248x:MODE>mode != HImode
14827 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14828 && !flag_trapping_math && !flag_rounding_math)
14829 ix86_expand_lround (operands[0], operands[1]);
14831 ix86_emit_i387_round (operands[0], operands[1]);
14835 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14836 (define_insn_and_split "frndintxf2_floor"
14837 [(set (match_operand:XF 0 "register_operand" "")
14838 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14839 UNSPEC_FRNDINT_FLOOR))
14840 (clobber (reg:CC FLAGS_REG))]
14841 "TARGET_USE_FANCY_MATH_387
14842 && flag_unsafe_math_optimizations
14843 && can_create_pseudo_p ()"
14848 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14850 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14851 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14853 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14854 operands[2], operands[3]));
14857 [(set_attr "type" "frndint")
14858 (set_attr "i387_cw" "floor")
14859 (set_attr "mode" "XF")])
14861 (define_insn "frndintxf2_floor_i387"
14862 [(set (match_operand:XF 0 "register_operand" "=f")
14863 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14864 UNSPEC_FRNDINT_FLOOR))
14865 (use (match_operand:HI 2 "memory_operand" "m"))
14866 (use (match_operand:HI 3 "memory_operand" "m"))]
14867 "TARGET_USE_FANCY_MATH_387
14868 && flag_unsafe_math_optimizations"
14869 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14870 [(set_attr "type" "frndint")
14871 (set_attr "i387_cw" "floor")
14872 (set_attr "mode" "XF")])
14874 (define_expand "floorxf2"
14875 [(use (match_operand:XF 0 "register_operand" ""))
14876 (use (match_operand:XF 1 "register_operand" ""))]
14877 "TARGET_USE_FANCY_MATH_387
14878 && flag_unsafe_math_optimizations"
14880 if (optimize_insn_for_size_p ())
14882 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14886 (define_expand "floor<mode>2"
14887 [(use (match_operand:MODEF 0 "register_operand" ""))
14888 (use (match_operand:MODEF 1 "register_operand" ""))]
14889 "(TARGET_USE_FANCY_MATH_387
14890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14891 || TARGET_MIX_SSE_I387)
14892 && flag_unsafe_math_optimizations)
14893 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14894 && !flag_trapping_math)"
14896 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14897 && !flag_trapping_math)
14900 emit_insn (gen_sse4_1_round<mode>2
14901 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14902 else if (optimize_insn_for_size_p ())
14904 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14905 ix86_expand_floorceil (operands[0], operands[1], true);
14907 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14913 if (optimize_insn_for_size_p ())
14916 op0 = gen_reg_rtx (XFmode);
14917 op1 = gen_reg_rtx (XFmode);
14918 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14919 emit_insn (gen_frndintxf2_floor (op0, op1));
14921 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14926 (define_insn_and_split "*fist<mode>2_floor_1"
14927 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14928 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14929 UNSPEC_FIST_FLOOR))
14930 (clobber (reg:CC FLAGS_REG))]
14931 "TARGET_USE_FANCY_MATH_387
14932 && flag_unsafe_math_optimizations
14933 && can_create_pseudo_p ()"
14938 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14940 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14941 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14942 if (memory_operand (operands[0], VOIDmode))
14943 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14944 operands[2], operands[3]));
14947 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14948 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14949 operands[2], operands[3],
14954 [(set_attr "type" "fistp")
14955 (set_attr "i387_cw" "floor")
14956 (set_attr "mode" "<MODE>")])
14958 (define_insn "fistdi2_floor"
14959 [(set (match_operand:DI 0 "memory_operand" "=m")
14960 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14961 UNSPEC_FIST_FLOOR))
14962 (use (match_operand:HI 2 "memory_operand" "m"))
14963 (use (match_operand:HI 3 "memory_operand" "m"))
14964 (clobber (match_scratch:XF 4 "=&1f"))]
14965 "TARGET_USE_FANCY_MATH_387
14966 && flag_unsafe_math_optimizations"
14967 "* return output_fix_trunc (insn, operands, false);"
14968 [(set_attr "type" "fistp")
14969 (set_attr "i387_cw" "floor")
14970 (set_attr "mode" "DI")])
14972 (define_insn "fistdi2_floor_with_temp"
14973 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14974 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14975 UNSPEC_FIST_FLOOR))
14976 (use (match_operand:HI 2 "memory_operand" "m,m"))
14977 (use (match_operand:HI 3 "memory_operand" "m,m"))
14978 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14979 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14980 "TARGET_USE_FANCY_MATH_387
14981 && flag_unsafe_math_optimizations"
14983 [(set_attr "type" "fistp")
14984 (set_attr "i387_cw" "floor")
14985 (set_attr "mode" "DI")])
14988 [(set (match_operand:DI 0 "register_operand" "")
14989 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14990 UNSPEC_FIST_FLOOR))
14991 (use (match_operand:HI 2 "memory_operand" ""))
14992 (use (match_operand:HI 3 "memory_operand" ""))
14993 (clobber (match_operand:DI 4 "memory_operand" ""))
14994 (clobber (match_scratch 5 ""))]
14996 [(parallel [(set (match_dup 4)
14997 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14998 (use (match_dup 2))
14999 (use (match_dup 3))
15000 (clobber (match_dup 5))])
15001 (set (match_dup 0) (match_dup 4))])
15004 [(set (match_operand:DI 0 "memory_operand" "")
15005 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15006 UNSPEC_FIST_FLOOR))
15007 (use (match_operand:HI 2 "memory_operand" ""))
15008 (use (match_operand:HI 3 "memory_operand" ""))
15009 (clobber (match_operand:DI 4 "memory_operand" ""))
15010 (clobber (match_scratch 5 ""))]
15012 [(parallel [(set (match_dup 0)
15013 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15014 (use (match_dup 2))
15015 (use (match_dup 3))
15016 (clobber (match_dup 5))])])
15018 (define_insn "fist<mode>2_floor"
15019 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15020 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15021 UNSPEC_FIST_FLOOR))
15022 (use (match_operand:HI 2 "memory_operand" "m"))
15023 (use (match_operand:HI 3 "memory_operand" "m"))]
15024 "TARGET_USE_FANCY_MATH_387
15025 && flag_unsafe_math_optimizations"
15026 "* return output_fix_trunc (insn, operands, false);"
15027 [(set_attr "type" "fistp")
15028 (set_attr "i387_cw" "floor")
15029 (set_attr "mode" "<MODE>")])
15031 (define_insn "fist<mode>2_floor_with_temp"
15032 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15033 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15034 UNSPEC_FIST_FLOOR))
15035 (use (match_operand:HI 2 "memory_operand" "m,m"))
15036 (use (match_operand:HI 3 "memory_operand" "m,m"))
15037 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15038 "TARGET_USE_FANCY_MATH_387
15039 && flag_unsafe_math_optimizations"
15041 [(set_attr "type" "fistp")
15042 (set_attr "i387_cw" "floor")
15043 (set_attr "mode" "<MODE>")])
15046 [(set (match_operand:SWI24 0 "register_operand" "")
15047 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15048 UNSPEC_FIST_FLOOR))
15049 (use (match_operand:HI 2 "memory_operand" ""))
15050 (use (match_operand:HI 3 "memory_operand" ""))
15051 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15053 [(parallel [(set (match_dup 4)
15054 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15055 (use (match_dup 2))
15056 (use (match_dup 3))])
15057 (set (match_dup 0) (match_dup 4))])
15060 [(set (match_operand:SWI24 0 "memory_operand" "")
15061 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15062 UNSPEC_FIST_FLOOR))
15063 (use (match_operand:HI 2 "memory_operand" ""))
15064 (use (match_operand:HI 3 "memory_operand" ""))
15065 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15067 [(parallel [(set (match_dup 0)
15068 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15069 (use (match_dup 2))
15070 (use (match_dup 3))])])
15072 (define_expand "lfloorxf<mode>2"
15073 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15074 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15075 UNSPEC_FIST_FLOOR))
15076 (clobber (reg:CC FLAGS_REG))])]
15077 "TARGET_USE_FANCY_MATH_387
15078 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15079 && flag_unsafe_math_optimizations")
15081 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15082 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15083 (match_operand:MODEF 1 "register_operand" "")]
15084 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15085 && !flag_trapping_math"
15087 if (TARGET_64BIT && optimize_insn_for_size_p ())
15089 ix86_expand_lfloorceil (operands[0], operands[1], true);
15093 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15094 (define_insn_and_split "frndintxf2_ceil"
15095 [(set (match_operand:XF 0 "register_operand" "")
15096 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15097 UNSPEC_FRNDINT_CEIL))
15098 (clobber (reg:CC FLAGS_REG))]
15099 "TARGET_USE_FANCY_MATH_387
15100 && flag_unsafe_math_optimizations
15101 && can_create_pseudo_p ()"
15106 ix86_optimize_mode_switching[I387_CEIL] = 1;
15108 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15109 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15111 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15112 operands[2], operands[3]));
15115 [(set_attr "type" "frndint")
15116 (set_attr "i387_cw" "ceil")
15117 (set_attr "mode" "XF")])
15119 (define_insn "frndintxf2_ceil_i387"
15120 [(set (match_operand:XF 0 "register_operand" "=f")
15121 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15122 UNSPEC_FRNDINT_CEIL))
15123 (use (match_operand:HI 2 "memory_operand" "m"))
15124 (use (match_operand:HI 3 "memory_operand" "m"))]
15125 "TARGET_USE_FANCY_MATH_387
15126 && flag_unsafe_math_optimizations"
15127 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15128 [(set_attr "type" "frndint")
15129 (set_attr "i387_cw" "ceil")
15130 (set_attr "mode" "XF")])
15132 (define_expand "ceilxf2"
15133 [(use (match_operand:XF 0 "register_operand" ""))
15134 (use (match_operand:XF 1 "register_operand" ""))]
15135 "TARGET_USE_FANCY_MATH_387
15136 && flag_unsafe_math_optimizations"
15138 if (optimize_insn_for_size_p ())
15140 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15144 (define_expand "ceil<mode>2"
15145 [(use (match_operand:MODEF 0 "register_operand" ""))
15146 (use (match_operand:MODEF 1 "register_operand" ""))]
15147 "(TARGET_USE_FANCY_MATH_387
15148 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15149 || TARGET_MIX_SSE_I387)
15150 && flag_unsafe_math_optimizations)
15151 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15152 && !flag_trapping_math)"
15154 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15155 && !flag_trapping_math)
15158 emit_insn (gen_sse4_1_round<mode>2
15159 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15160 else if (optimize_insn_for_size_p ())
15162 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15163 ix86_expand_floorceil (operands[0], operands[1], false);
15165 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15171 if (optimize_insn_for_size_p ())
15174 op0 = gen_reg_rtx (XFmode);
15175 op1 = gen_reg_rtx (XFmode);
15176 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15177 emit_insn (gen_frndintxf2_ceil (op0, op1));
15179 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15184 (define_insn_and_split "*fist<mode>2_ceil_1"
15185 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15186 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15188 (clobber (reg:CC FLAGS_REG))]
15189 "TARGET_USE_FANCY_MATH_387
15190 && flag_unsafe_math_optimizations
15191 && can_create_pseudo_p ()"
15196 ix86_optimize_mode_switching[I387_CEIL] = 1;
15198 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15199 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15200 if (memory_operand (operands[0], VOIDmode))
15201 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15202 operands[2], operands[3]));
15205 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15206 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15207 operands[2], operands[3],
15212 [(set_attr "type" "fistp")
15213 (set_attr "i387_cw" "ceil")
15214 (set_attr "mode" "<MODE>")])
15216 (define_insn "fistdi2_ceil"
15217 [(set (match_operand:DI 0 "memory_operand" "=m")
15218 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15220 (use (match_operand:HI 2 "memory_operand" "m"))
15221 (use (match_operand:HI 3 "memory_operand" "m"))
15222 (clobber (match_scratch:XF 4 "=&1f"))]
15223 "TARGET_USE_FANCY_MATH_387
15224 && flag_unsafe_math_optimizations"
15225 "* return output_fix_trunc (insn, operands, false);"
15226 [(set_attr "type" "fistp")
15227 (set_attr "i387_cw" "ceil")
15228 (set_attr "mode" "DI")])
15230 (define_insn "fistdi2_ceil_with_temp"
15231 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15232 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15234 (use (match_operand:HI 2 "memory_operand" "m,m"))
15235 (use (match_operand:HI 3 "memory_operand" "m,m"))
15236 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15237 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15238 "TARGET_USE_FANCY_MATH_387
15239 && flag_unsafe_math_optimizations"
15241 [(set_attr "type" "fistp")
15242 (set_attr "i387_cw" "ceil")
15243 (set_attr "mode" "DI")])
15246 [(set (match_operand:DI 0 "register_operand" "")
15247 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15249 (use (match_operand:HI 2 "memory_operand" ""))
15250 (use (match_operand:HI 3 "memory_operand" ""))
15251 (clobber (match_operand:DI 4 "memory_operand" ""))
15252 (clobber (match_scratch 5 ""))]
15254 [(parallel [(set (match_dup 4)
15255 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15256 (use (match_dup 2))
15257 (use (match_dup 3))
15258 (clobber (match_dup 5))])
15259 (set (match_dup 0) (match_dup 4))])
15262 [(set (match_operand:DI 0 "memory_operand" "")
15263 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15265 (use (match_operand:HI 2 "memory_operand" ""))
15266 (use (match_operand:HI 3 "memory_operand" ""))
15267 (clobber (match_operand:DI 4 "memory_operand" ""))
15268 (clobber (match_scratch 5 ""))]
15270 [(parallel [(set (match_dup 0)
15271 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15272 (use (match_dup 2))
15273 (use (match_dup 3))
15274 (clobber (match_dup 5))])])
15276 (define_insn "fist<mode>2_ceil"
15277 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15278 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15280 (use (match_operand:HI 2 "memory_operand" "m"))
15281 (use (match_operand:HI 3 "memory_operand" "m"))]
15282 "TARGET_USE_FANCY_MATH_387
15283 && flag_unsafe_math_optimizations"
15284 "* return output_fix_trunc (insn, operands, false);"
15285 [(set_attr "type" "fistp")
15286 (set_attr "i387_cw" "ceil")
15287 (set_attr "mode" "<MODE>")])
15289 (define_insn "fist<mode>2_ceil_with_temp"
15290 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15291 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15293 (use (match_operand:HI 2 "memory_operand" "m,m"))
15294 (use (match_operand:HI 3 "memory_operand" "m,m"))
15295 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15296 "TARGET_USE_FANCY_MATH_387
15297 && flag_unsafe_math_optimizations"
15299 [(set_attr "type" "fistp")
15300 (set_attr "i387_cw" "ceil")
15301 (set_attr "mode" "<MODE>")])
15304 [(set (match_operand:SWI24 0 "register_operand" "")
15305 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15307 (use (match_operand:HI 2 "memory_operand" ""))
15308 (use (match_operand:HI 3 "memory_operand" ""))
15309 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15311 [(parallel [(set (match_dup 4)
15312 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15313 (use (match_dup 2))
15314 (use (match_dup 3))])
15315 (set (match_dup 0) (match_dup 4))])
15318 [(set (match_operand:SWI24 0 "memory_operand" "")
15319 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15321 (use (match_operand:HI 2 "memory_operand" ""))
15322 (use (match_operand:HI 3 "memory_operand" ""))
15323 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15325 [(parallel [(set (match_dup 0)
15326 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15327 (use (match_dup 2))
15328 (use (match_dup 3))])])
15330 (define_expand "lceilxf<mode>2"
15331 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15332 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15334 (clobber (reg:CC FLAGS_REG))])]
15335 "TARGET_USE_FANCY_MATH_387
15336 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15337 && flag_unsafe_math_optimizations")
15339 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15340 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15341 (match_operand:MODEF 1 "register_operand" "")]
15342 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15343 && !flag_trapping_math"
15345 ix86_expand_lfloorceil (operands[0], operands[1], false);
15349 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15350 (define_insn_and_split "frndintxf2_trunc"
15351 [(set (match_operand:XF 0 "register_operand" "")
15352 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15353 UNSPEC_FRNDINT_TRUNC))
15354 (clobber (reg:CC FLAGS_REG))]
15355 "TARGET_USE_FANCY_MATH_387
15356 && flag_unsafe_math_optimizations
15357 && can_create_pseudo_p ()"
15362 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15364 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15365 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15367 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15368 operands[2], operands[3]));
15371 [(set_attr "type" "frndint")
15372 (set_attr "i387_cw" "trunc")
15373 (set_attr "mode" "XF")])
15375 (define_insn "frndintxf2_trunc_i387"
15376 [(set (match_operand:XF 0 "register_operand" "=f")
15377 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15378 UNSPEC_FRNDINT_TRUNC))
15379 (use (match_operand:HI 2 "memory_operand" "m"))
15380 (use (match_operand:HI 3 "memory_operand" "m"))]
15381 "TARGET_USE_FANCY_MATH_387
15382 && flag_unsafe_math_optimizations"
15383 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15384 [(set_attr "type" "frndint")
15385 (set_attr "i387_cw" "trunc")
15386 (set_attr "mode" "XF")])
15388 (define_expand "btruncxf2"
15389 [(use (match_operand:XF 0 "register_operand" ""))
15390 (use (match_operand:XF 1 "register_operand" ""))]
15391 "TARGET_USE_FANCY_MATH_387
15392 && flag_unsafe_math_optimizations"
15394 if (optimize_insn_for_size_p ())
15396 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15400 (define_expand "btrunc<mode>2"
15401 [(use (match_operand:MODEF 0 "register_operand" ""))
15402 (use (match_operand:MODEF 1 "register_operand" ""))]
15403 "(TARGET_USE_FANCY_MATH_387
15404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15405 || TARGET_MIX_SSE_I387)
15406 && flag_unsafe_math_optimizations)
15407 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15408 && !flag_trapping_math)"
15410 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15411 && !flag_trapping_math)
15414 emit_insn (gen_sse4_1_round<mode>2
15415 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15416 else if (optimize_insn_for_size_p ())
15418 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15419 ix86_expand_trunc (operands[0], operands[1]);
15421 ix86_expand_truncdf_32 (operands[0], operands[1]);
15427 if (optimize_insn_for_size_p ())
15430 op0 = gen_reg_rtx (XFmode);
15431 op1 = gen_reg_rtx (XFmode);
15432 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15433 emit_insn (gen_frndintxf2_trunc (op0, op1));
15435 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15440 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15441 (define_insn_and_split "frndintxf2_mask_pm"
15442 [(set (match_operand:XF 0 "register_operand" "")
15443 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15444 UNSPEC_FRNDINT_MASK_PM))
15445 (clobber (reg:CC FLAGS_REG))]
15446 "TARGET_USE_FANCY_MATH_387
15447 && flag_unsafe_math_optimizations
15448 && can_create_pseudo_p ()"
15453 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15455 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15456 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15458 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15459 operands[2], operands[3]));
15462 [(set_attr "type" "frndint")
15463 (set_attr "i387_cw" "mask_pm")
15464 (set_attr "mode" "XF")])
15466 (define_insn "frndintxf2_mask_pm_i387"
15467 [(set (match_operand:XF 0 "register_operand" "=f")
15468 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15469 UNSPEC_FRNDINT_MASK_PM))
15470 (use (match_operand:HI 2 "memory_operand" "m"))
15471 (use (match_operand:HI 3 "memory_operand" "m"))]
15472 "TARGET_USE_FANCY_MATH_387
15473 && flag_unsafe_math_optimizations"
15474 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15475 [(set_attr "type" "frndint")
15476 (set_attr "i387_cw" "mask_pm")
15477 (set_attr "mode" "XF")])
15479 (define_expand "nearbyintxf2"
15480 [(use (match_operand:XF 0 "register_operand" ""))
15481 (use (match_operand:XF 1 "register_operand" ""))]
15482 "TARGET_USE_FANCY_MATH_387
15483 && flag_unsafe_math_optimizations"
15485 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15489 (define_expand "nearbyint<mode>2"
15490 [(use (match_operand:MODEF 0 "register_operand" ""))
15491 (use (match_operand:MODEF 1 "register_operand" ""))]
15492 "TARGET_USE_FANCY_MATH_387
15493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15494 || TARGET_MIX_SSE_I387)
15495 && flag_unsafe_math_optimizations"
15497 rtx op0 = gen_reg_rtx (XFmode);
15498 rtx op1 = gen_reg_rtx (XFmode);
15500 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15501 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15503 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15507 (define_insn "fxam<mode>2_i387"
15508 [(set (match_operand:HI 0 "register_operand" "=a")
15510 [(match_operand:X87MODEF 1 "register_operand" "f")]
15512 "TARGET_USE_FANCY_MATH_387"
15513 "fxam\n\tfnstsw\t%0"
15514 [(set_attr "type" "multi")
15515 (set_attr "length" "4")
15516 (set_attr "unit" "i387")
15517 (set_attr "mode" "<MODE>")])
15519 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15520 [(set (match_operand:HI 0 "register_operand" "")
15522 [(match_operand:MODEF 1 "memory_operand" "")]
15524 "TARGET_USE_FANCY_MATH_387
15525 && can_create_pseudo_p ()"
15528 [(set (match_dup 2)(match_dup 1))
15530 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15532 operands[2] = gen_reg_rtx (<MODE>mode);
15534 MEM_VOLATILE_P (operands[1]) = 1;
15536 [(set_attr "type" "multi")
15537 (set_attr "unit" "i387")
15538 (set_attr "mode" "<MODE>")])
15540 (define_expand "isinfxf2"
15541 [(use (match_operand:SI 0 "register_operand" ""))
15542 (use (match_operand:XF 1 "register_operand" ""))]
15543 "TARGET_USE_FANCY_MATH_387
15544 && TARGET_C99_FUNCTIONS"
15546 rtx mask = GEN_INT (0x45);
15547 rtx val = GEN_INT (0x05);
15551 rtx scratch = gen_reg_rtx (HImode);
15552 rtx res = gen_reg_rtx (QImode);
15554 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15556 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15557 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15558 cond = gen_rtx_fmt_ee (EQ, QImode,
15559 gen_rtx_REG (CCmode, FLAGS_REG),
15561 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15562 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15566 (define_expand "isinf<mode>2"
15567 [(use (match_operand:SI 0 "register_operand" ""))
15568 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15569 "TARGET_USE_FANCY_MATH_387
15570 && TARGET_C99_FUNCTIONS
15571 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15573 rtx mask = GEN_INT (0x45);
15574 rtx val = GEN_INT (0x05);
15578 rtx scratch = gen_reg_rtx (HImode);
15579 rtx res = gen_reg_rtx (QImode);
15581 /* Remove excess precision by forcing value through memory. */
15582 if (memory_operand (operands[1], VOIDmode))
15583 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15586 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15588 emit_move_insn (temp, operands[1]);
15589 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15592 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15593 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15594 cond = gen_rtx_fmt_ee (EQ, QImode,
15595 gen_rtx_REG (CCmode, FLAGS_REG),
15597 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15598 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15602 (define_expand "signbitxf2"
15603 [(use (match_operand:SI 0 "register_operand" ""))
15604 (use (match_operand:XF 1 "register_operand" ""))]
15605 "TARGET_USE_FANCY_MATH_387"
15607 rtx scratch = gen_reg_rtx (HImode);
15609 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15610 emit_insn (gen_andsi3 (operands[0],
15611 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15615 (define_insn "movmsk_df"
15616 [(set (match_operand:SI 0 "register_operand" "=r")
15618 [(match_operand:DF 1 "register_operand" "x")]
15620 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15621 "%vmovmskpd\t{%1, %0|%0, %1}"
15622 [(set_attr "type" "ssemov")
15623 (set_attr "prefix" "maybe_vex")
15624 (set_attr "mode" "DF")])
15626 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15627 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15628 (define_expand "signbitdf2"
15629 [(use (match_operand:SI 0 "register_operand" ""))
15630 (use (match_operand:DF 1 "register_operand" ""))]
15631 "TARGET_USE_FANCY_MATH_387
15632 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15634 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15636 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15637 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15641 rtx scratch = gen_reg_rtx (HImode);
15643 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15644 emit_insn (gen_andsi3 (operands[0],
15645 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15650 (define_expand "signbitsf2"
15651 [(use (match_operand:SI 0 "register_operand" ""))
15652 (use (match_operand:SF 1 "register_operand" ""))]
15653 "TARGET_USE_FANCY_MATH_387
15654 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15656 rtx scratch = gen_reg_rtx (HImode);
15658 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15659 emit_insn (gen_andsi3 (operands[0],
15660 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15664 ;; Block operation instructions
15667 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15670 [(set_attr "length" "1")
15671 (set_attr "length_immediate" "0")
15672 (set_attr "modrm" "0")])
15674 (define_expand "movmem<mode>"
15675 [(use (match_operand:BLK 0 "memory_operand" ""))
15676 (use (match_operand:BLK 1 "memory_operand" ""))
15677 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15678 (use (match_operand:SWI48 3 "const_int_operand" ""))
15679 (use (match_operand:SI 4 "const_int_operand" ""))
15680 (use (match_operand:SI 5 "const_int_operand" ""))]
15683 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15684 operands[4], operands[5]))
15690 ;; Most CPUs don't like single string operations
15691 ;; Handle this case here to simplify previous expander.
15693 (define_expand "strmov"
15694 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15695 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15696 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15697 (clobber (reg:CC FLAGS_REG))])
15698 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15699 (clobber (reg:CC FLAGS_REG))])]
15702 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15704 /* If .md ever supports :P for Pmode, these can be directly
15705 in the pattern above. */
15706 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15707 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15709 /* Can't use this if the user has appropriated esi or edi. */
15710 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15711 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15713 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15714 operands[2], operands[3],
15715 operands[5], operands[6]));
15719 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15722 (define_expand "strmov_singleop"
15723 [(parallel [(set (match_operand 1 "memory_operand" "")
15724 (match_operand 3 "memory_operand" ""))
15725 (set (match_operand 0 "register_operand" "")
15726 (match_operand 4 "" ""))
15727 (set (match_operand 2 "register_operand" "")
15728 (match_operand 5 "" ""))])]
15730 "ix86_current_function_needs_cld = 1;")
15732 (define_insn "*strmovdi_rex_1"
15733 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15734 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15735 (set (match_operand:DI 0 "register_operand" "=D")
15736 (plus:DI (match_dup 2)
15738 (set (match_operand:DI 1 "register_operand" "=S")
15739 (plus:DI (match_dup 3)
15742 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15744 [(set_attr "type" "str")
15745 (set_attr "memory" "both")
15746 (set_attr "mode" "DI")])
15748 (define_insn "*strmovsi_1"
15749 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15750 (mem:SI (match_operand:P 3 "register_operand" "1")))
15751 (set (match_operand:P 0 "register_operand" "=D")
15752 (plus:P (match_dup 2)
15754 (set (match_operand:P 1 "register_operand" "=S")
15755 (plus:P (match_dup 3)
15757 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15759 [(set_attr "type" "str")
15760 (set_attr "memory" "both")
15761 (set_attr "mode" "SI")])
15763 (define_insn "*strmovhi_1"
15764 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15765 (mem:HI (match_operand:P 3 "register_operand" "1")))
15766 (set (match_operand:P 0 "register_operand" "=D")
15767 (plus:P (match_dup 2)
15769 (set (match_operand:P 1 "register_operand" "=S")
15770 (plus:P (match_dup 3)
15772 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15774 [(set_attr "type" "str")
15775 (set_attr "memory" "both")
15776 (set_attr "mode" "HI")])
15778 (define_insn "*strmovqi_1"
15779 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15780 (mem:QI (match_operand:P 3 "register_operand" "1")))
15781 (set (match_operand:P 0 "register_operand" "=D")
15782 (plus:P (match_dup 2)
15784 (set (match_operand:P 1 "register_operand" "=S")
15785 (plus:P (match_dup 3)
15787 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15789 [(set_attr "type" "str")
15790 (set_attr "memory" "both")
15791 (set (attr "prefix_rex")
15793 (match_test "<P:MODE>mode == DImode")
15795 (const_string "*")))
15796 (set_attr "mode" "QI")])
15798 (define_expand "rep_mov"
15799 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15800 (set (match_operand 0 "register_operand" "")
15801 (match_operand 5 "" ""))
15802 (set (match_operand 2 "register_operand" "")
15803 (match_operand 6 "" ""))
15804 (set (match_operand 1 "memory_operand" "")
15805 (match_operand 3 "memory_operand" ""))
15806 (use (match_dup 4))])]
15808 "ix86_current_function_needs_cld = 1;")
15810 (define_insn "*rep_movdi_rex64"
15811 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15812 (set (match_operand:DI 0 "register_operand" "=D")
15813 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15815 (match_operand:DI 3 "register_operand" "0")))
15816 (set (match_operand:DI 1 "register_operand" "=S")
15817 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15818 (match_operand:DI 4 "register_operand" "1")))
15819 (set (mem:BLK (match_dup 3))
15820 (mem:BLK (match_dup 4)))
15821 (use (match_dup 5))]
15823 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15825 [(set_attr "type" "str")
15826 (set_attr "prefix_rep" "1")
15827 (set_attr "memory" "both")
15828 (set_attr "mode" "DI")])
15830 (define_insn "*rep_movsi"
15831 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15832 (set (match_operand:P 0 "register_operand" "=D")
15833 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15835 (match_operand:P 3 "register_operand" "0")))
15836 (set (match_operand:P 1 "register_operand" "=S")
15837 (plus:P (ashift:P (match_dup 5) (const_int 2))
15838 (match_operand:P 4 "register_operand" "1")))
15839 (set (mem:BLK (match_dup 3))
15840 (mem:BLK (match_dup 4)))
15841 (use (match_dup 5))]
15842 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15843 "rep{%;} movs{l|d}"
15844 [(set_attr "type" "str")
15845 (set_attr "prefix_rep" "1")
15846 (set_attr "memory" "both")
15847 (set_attr "mode" "SI")])
15849 (define_insn "*rep_movqi"
15850 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15851 (set (match_operand:P 0 "register_operand" "=D")
15852 (plus:P (match_operand:P 3 "register_operand" "0")
15853 (match_operand:P 5 "register_operand" "2")))
15854 (set (match_operand:P 1 "register_operand" "=S")
15855 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15856 (set (mem:BLK (match_dup 3))
15857 (mem:BLK (match_dup 4)))
15858 (use (match_dup 5))]
15859 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15861 [(set_attr "type" "str")
15862 (set_attr "prefix_rep" "1")
15863 (set_attr "memory" "both")
15864 (set_attr "mode" "QI")])
15866 (define_expand "setmem<mode>"
15867 [(use (match_operand:BLK 0 "memory_operand" ""))
15868 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15869 (use (match_operand:QI 2 "nonmemory_operand" ""))
15870 (use (match_operand 3 "const_int_operand" ""))
15871 (use (match_operand:SI 4 "const_int_operand" ""))
15872 (use (match_operand:SI 5 "const_int_operand" ""))]
15875 if (ix86_expand_setmem (operands[0], operands[1],
15876 operands[2], operands[3],
15877 operands[4], operands[5]))
15883 ;; Most CPUs don't like single string operations
15884 ;; Handle this case here to simplify previous expander.
15886 (define_expand "strset"
15887 [(set (match_operand 1 "memory_operand" "")
15888 (match_operand 2 "register_operand" ""))
15889 (parallel [(set (match_operand 0 "register_operand" "")
15891 (clobber (reg:CC FLAGS_REG))])]
15894 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15895 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15897 /* If .md ever supports :P for Pmode, this can be directly
15898 in the pattern above. */
15899 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15900 GEN_INT (GET_MODE_SIZE (GET_MODE
15902 /* Can't use this if the user has appropriated eax or edi. */
15903 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15904 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15906 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15912 (define_expand "strset_singleop"
15913 [(parallel [(set (match_operand 1 "memory_operand" "")
15914 (match_operand 2 "register_operand" ""))
15915 (set (match_operand 0 "register_operand" "")
15916 (match_operand 3 "" ""))
15917 (unspec [(const_int 0)] UNSPEC_STOS)])]
15919 "ix86_current_function_needs_cld = 1;")
15921 (define_insn "*strsetdi_rex_1"
15922 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15923 (match_operand:DI 2 "register_operand" "a"))
15924 (set (match_operand:DI 0 "register_operand" "=D")
15925 (plus:DI (match_dup 1)
15927 (unspec [(const_int 0)] UNSPEC_STOS)]
15929 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15931 [(set_attr "type" "str")
15932 (set_attr "memory" "store")
15933 (set_attr "mode" "DI")])
15935 (define_insn "*strsetsi_1"
15936 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15937 (match_operand:SI 2 "register_operand" "a"))
15938 (set (match_operand:P 0 "register_operand" "=D")
15939 (plus:P (match_dup 1)
15941 (unspec [(const_int 0)] UNSPEC_STOS)]
15942 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15944 [(set_attr "type" "str")
15945 (set_attr "memory" "store")
15946 (set_attr "mode" "SI")])
15948 (define_insn "*strsethi_1"
15949 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15950 (match_operand:HI 2 "register_operand" "a"))
15951 (set (match_operand:P 0 "register_operand" "=D")
15952 (plus:P (match_dup 1)
15954 (unspec [(const_int 0)] UNSPEC_STOS)]
15955 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15957 [(set_attr "type" "str")
15958 (set_attr "memory" "store")
15959 (set_attr "mode" "HI")])
15961 (define_insn "*strsetqi_1"
15962 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15963 (match_operand:QI 2 "register_operand" "a"))
15964 (set (match_operand:P 0 "register_operand" "=D")
15965 (plus:P (match_dup 1)
15967 (unspec [(const_int 0)] UNSPEC_STOS)]
15968 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15970 [(set_attr "type" "str")
15971 (set_attr "memory" "store")
15972 (set (attr "prefix_rex")
15974 (match_test "<P:MODE>mode == DImode")
15976 (const_string "*")))
15977 (set_attr "mode" "QI")])
15979 (define_expand "rep_stos"
15980 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15981 (set (match_operand 0 "register_operand" "")
15982 (match_operand 4 "" ""))
15983 (set (match_operand 2 "memory_operand" "") (const_int 0))
15984 (use (match_operand 3 "register_operand" ""))
15985 (use (match_dup 1))])]
15987 "ix86_current_function_needs_cld = 1;")
15989 (define_insn "*rep_stosdi_rex64"
15990 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15991 (set (match_operand:DI 0 "register_operand" "=D")
15992 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15994 (match_operand:DI 3 "register_operand" "0")))
15995 (set (mem:BLK (match_dup 3))
15997 (use (match_operand:DI 2 "register_operand" "a"))
15998 (use (match_dup 4))]
16000 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16002 [(set_attr "type" "str")
16003 (set_attr "prefix_rep" "1")
16004 (set_attr "memory" "store")
16005 (set_attr "mode" "DI")])
16007 (define_insn "*rep_stossi"
16008 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16009 (set (match_operand:P 0 "register_operand" "=D")
16010 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16012 (match_operand:P 3 "register_operand" "0")))
16013 (set (mem:BLK (match_dup 3))
16015 (use (match_operand:SI 2 "register_operand" "a"))
16016 (use (match_dup 4))]
16017 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16018 "rep{%;} stos{l|d}"
16019 [(set_attr "type" "str")
16020 (set_attr "prefix_rep" "1")
16021 (set_attr "memory" "store")
16022 (set_attr "mode" "SI")])
16024 (define_insn "*rep_stosqi"
16025 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16026 (set (match_operand:P 0 "register_operand" "=D")
16027 (plus:P (match_operand:P 3 "register_operand" "0")
16028 (match_operand:P 4 "register_operand" "1")))
16029 (set (mem:BLK (match_dup 3))
16031 (use (match_operand:QI 2 "register_operand" "a"))
16032 (use (match_dup 4))]
16033 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16035 [(set_attr "type" "str")
16036 (set_attr "prefix_rep" "1")
16037 (set_attr "memory" "store")
16038 (set (attr "prefix_rex")
16040 (match_test "<P:MODE>mode == DImode")
16042 (const_string "*")))
16043 (set_attr "mode" "QI")])
16045 (define_expand "cmpstrnsi"
16046 [(set (match_operand:SI 0 "register_operand" "")
16047 (compare:SI (match_operand:BLK 1 "general_operand" "")
16048 (match_operand:BLK 2 "general_operand" "")))
16049 (use (match_operand 3 "general_operand" ""))
16050 (use (match_operand 4 "immediate_operand" ""))]
16053 rtx addr1, addr2, out, outlow, count, countreg, align;
16055 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16058 /* Can't use this if the user has appropriated ecx, esi or edi. */
16059 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16064 out = gen_reg_rtx (SImode);
16066 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16067 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16068 if (addr1 != XEXP (operands[1], 0))
16069 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16070 if (addr2 != XEXP (operands[2], 0))
16071 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16073 count = operands[3];
16074 countreg = ix86_zero_extend_to_Pmode (count);
16076 /* %%% Iff we are testing strict equality, we can use known alignment
16077 to good advantage. This may be possible with combine, particularly
16078 once cc0 is dead. */
16079 align = operands[4];
16081 if (CONST_INT_P (count))
16083 if (INTVAL (count) == 0)
16085 emit_move_insn (operands[0], const0_rtx);
16088 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16089 operands[1], operands[2]));
16093 rtx (*gen_cmp) (rtx, rtx);
16095 gen_cmp = (TARGET_64BIT
16096 ? gen_cmpdi_1 : gen_cmpsi_1);
16098 emit_insn (gen_cmp (countreg, countreg));
16099 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16100 operands[1], operands[2]));
16103 outlow = gen_lowpart (QImode, out);
16104 emit_insn (gen_cmpintqi (outlow));
16105 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16107 if (operands[0] != out)
16108 emit_move_insn (operands[0], out);
16113 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16115 (define_expand "cmpintqi"
16116 [(set (match_dup 1)
16117 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16119 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16120 (parallel [(set (match_operand:QI 0 "register_operand" "")
16121 (minus:QI (match_dup 1)
16123 (clobber (reg:CC FLAGS_REG))])]
16126 operands[1] = gen_reg_rtx (QImode);
16127 operands[2] = gen_reg_rtx (QImode);
16130 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16131 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16133 (define_expand "cmpstrnqi_nz_1"
16134 [(parallel [(set (reg:CC FLAGS_REG)
16135 (compare:CC (match_operand 4 "memory_operand" "")
16136 (match_operand 5 "memory_operand" "")))
16137 (use (match_operand 2 "register_operand" ""))
16138 (use (match_operand:SI 3 "immediate_operand" ""))
16139 (clobber (match_operand 0 "register_operand" ""))
16140 (clobber (match_operand 1 "register_operand" ""))
16141 (clobber (match_dup 2))])]
16143 "ix86_current_function_needs_cld = 1;")
16145 (define_insn "*cmpstrnqi_nz_1"
16146 [(set (reg:CC FLAGS_REG)
16147 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16148 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16149 (use (match_operand:P 6 "register_operand" "2"))
16150 (use (match_operand:SI 3 "immediate_operand" "i"))
16151 (clobber (match_operand:P 0 "register_operand" "=S"))
16152 (clobber (match_operand:P 1 "register_operand" "=D"))
16153 (clobber (match_operand:P 2 "register_operand" "=c"))]
16154 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16156 [(set_attr "type" "str")
16157 (set_attr "mode" "QI")
16158 (set (attr "prefix_rex")
16160 (match_test "<P:MODE>mode == DImode")
16162 (const_string "*")))
16163 (set_attr "prefix_rep" "1")])
16165 ;; The same, but the count is not known to not be zero.
16167 (define_expand "cmpstrnqi_1"
16168 [(parallel [(set (reg:CC FLAGS_REG)
16169 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16171 (compare:CC (match_operand 4 "memory_operand" "")
16172 (match_operand 5 "memory_operand" ""))
16174 (use (match_operand:SI 3 "immediate_operand" ""))
16175 (use (reg:CC FLAGS_REG))
16176 (clobber (match_operand 0 "register_operand" ""))
16177 (clobber (match_operand 1 "register_operand" ""))
16178 (clobber (match_dup 2))])]
16180 "ix86_current_function_needs_cld = 1;")
16182 (define_insn "*cmpstrnqi_1"
16183 [(set (reg:CC FLAGS_REG)
16184 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16186 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16187 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16189 (use (match_operand:SI 3 "immediate_operand" "i"))
16190 (use (reg:CC FLAGS_REG))
16191 (clobber (match_operand:P 0 "register_operand" "=S"))
16192 (clobber (match_operand:P 1 "register_operand" "=D"))
16193 (clobber (match_operand:P 2 "register_operand" "=c"))]
16194 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16196 [(set_attr "type" "str")
16197 (set_attr "mode" "QI")
16198 (set (attr "prefix_rex")
16200 (match_test "<P:MODE>mode == DImode")
16202 (const_string "*")))
16203 (set_attr "prefix_rep" "1")])
16205 (define_expand "strlen<mode>"
16206 [(set (match_operand:P 0 "register_operand" "")
16207 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16208 (match_operand:QI 2 "immediate_operand" "")
16209 (match_operand 3 "immediate_operand" "")]
16213 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16219 (define_expand "strlenqi_1"
16220 [(parallel [(set (match_operand 0 "register_operand" "")
16221 (match_operand 2 "" ""))
16222 (clobber (match_operand 1 "register_operand" ""))
16223 (clobber (reg:CC FLAGS_REG))])]
16225 "ix86_current_function_needs_cld = 1;")
16227 (define_insn "*strlenqi_1"
16228 [(set (match_operand:P 0 "register_operand" "=&c")
16229 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16230 (match_operand:QI 2 "register_operand" "a")
16231 (match_operand:P 3 "immediate_operand" "i")
16232 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16233 (clobber (match_operand:P 1 "register_operand" "=D"))
16234 (clobber (reg:CC FLAGS_REG))]
16235 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16237 [(set_attr "type" "str")
16238 (set_attr "mode" "QI")
16239 (set (attr "prefix_rex")
16241 (match_test "<P:MODE>mode == DImode")
16243 (const_string "*")))
16244 (set_attr "prefix_rep" "1")])
16246 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16247 ;; handled in combine, but it is not currently up to the task.
16248 ;; When used for their truth value, the cmpstrn* expanders generate
16257 ;; The intermediate three instructions are unnecessary.
16259 ;; This one handles cmpstrn*_nz_1...
16262 (set (reg:CC FLAGS_REG)
16263 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16264 (mem:BLK (match_operand 5 "register_operand" ""))))
16265 (use (match_operand 6 "register_operand" ""))
16266 (use (match_operand:SI 3 "immediate_operand" ""))
16267 (clobber (match_operand 0 "register_operand" ""))
16268 (clobber (match_operand 1 "register_operand" ""))
16269 (clobber (match_operand 2 "register_operand" ""))])
16270 (set (match_operand:QI 7 "register_operand" "")
16271 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16272 (set (match_operand:QI 8 "register_operand" "")
16273 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16274 (set (reg FLAGS_REG)
16275 (compare (match_dup 7) (match_dup 8)))
16277 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16279 (set (reg:CC FLAGS_REG)
16280 (compare:CC (mem:BLK (match_dup 4))
16281 (mem:BLK (match_dup 5))))
16282 (use (match_dup 6))
16283 (use (match_dup 3))
16284 (clobber (match_dup 0))
16285 (clobber (match_dup 1))
16286 (clobber (match_dup 2))])])
16288 ;; ...and this one handles cmpstrn*_1.
16291 (set (reg:CC FLAGS_REG)
16292 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16294 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16295 (mem:BLK (match_operand 5 "register_operand" "")))
16297 (use (match_operand:SI 3 "immediate_operand" ""))
16298 (use (reg:CC FLAGS_REG))
16299 (clobber (match_operand 0 "register_operand" ""))
16300 (clobber (match_operand 1 "register_operand" ""))
16301 (clobber (match_operand 2 "register_operand" ""))])
16302 (set (match_operand:QI 7 "register_operand" "")
16303 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16304 (set (match_operand:QI 8 "register_operand" "")
16305 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16306 (set (reg FLAGS_REG)
16307 (compare (match_dup 7) (match_dup 8)))
16309 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16311 (set (reg:CC FLAGS_REG)
16312 (if_then_else:CC (ne (match_dup 6)
16314 (compare:CC (mem:BLK (match_dup 4))
16315 (mem:BLK (match_dup 5)))
16317 (use (match_dup 3))
16318 (use (reg:CC FLAGS_REG))
16319 (clobber (match_dup 0))
16320 (clobber (match_dup 1))
16321 (clobber (match_dup 2))])])
16323 ;; Conditional move instructions.
16325 (define_expand "mov<mode>cc"
16326 [(set (match_operand:SWIM 0 "register_operand" "")
16327 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16328 (match_operand:SWIM 2 "<general_operand>" "")
16329 (match_operand:SWIM 3 "<general_operand>" "")))]
16331 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16333 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16334 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16335 ;; So just document what we're doing explicitly.
16337 (define_expand "x86_mov<mode>cc_0_m1"
16339 [(set (match_operand:SWI48 0 "register_operand" "")
16340 (if_then_else:SWI48
16341 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16342 [(match_operand 1 "flags_reg_operand" "")
16346 (clobber (reg:CC FLAGS_REG))])])
16348 (define_insn "*x86_mov<mode>cc_0_m1"
16349 [(set (match_operand:SWI48 0 "register_operand" "=r")
16350 (if_then_else: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 ; Since we don't have the proper number of operands for an alu insn,
16358 ; fill in all the blanks.
16359 [(set_attr "type" "alu")
16360 (set_attr "use_carry" "1")
16361 (set_attr "pent_pair" "pu")
16362 (set_attr "memory" "none")
16363 (set_attr "imm_disp" "false")
16364 (set_attr "mode" "<MODE>")
16365 (set_attr "length_immediate" "0")])
16367 (define_insn "*x86_mov<mode>cc_0_m1_se"
16368 [(set (match_operand:SWI48 0 "register_operand" "=r")
16369 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16370 [(reg FLAGS_REG) (const_int 0)])
16373 (clobber (reg:CC FLAGS_REG))]
16375 "sbb{<imodesuffix>}\t%0, %0"
16376 [(set_attr "type" "alu")
16377 (set_attr "use_carry" "1")
16378 (set_attr "pent_pair" "pu")
16379 (set_attr "memory" "none")
16380 (set_attr "imm_disp" "false")
16381 (set_attr "mode" "<MODE>")
16382 (set_attr "length_immediate" "0")])
16384 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16385 [(set (match_operand:SWI48 0 "register_operand" "=r")
16386 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16387 [(reg FLAGS_REG) (const_int 0)])))
16388 (clobber (reg:CC FLAGS_REG))]
16390 "sbb{<imodesuffix>}\t%0, %0"
16391 [(set_attr "type" "alu")
16392 (set_attr "use_carry" "1")
16393 (set_attr "pent_pair" "pu")
16394 (set_attr "memory" "none")
16395 (set_attr "imm_disp" "false")
16396 (set_attr "mode" "<MODE>")
16397 (set_attr "length_immediate" "0")])
16399 (define_insn "*mov<mode>cc_noc"
16400 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16401 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16402 [(reg FLAGS_REG) (const_int 0)])
16403 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16404 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16405 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16407 cmov%O2%C1\t{%2, %0|%0, %2}
16408 cmov%O2%c1\t{%3, %0|%0, %3}"
16409 [(set_attr "type" "icmov")
16410 (set_attr "mode" "<MODE>")])
16412 (define_insn "*movqicc_noc"
16413 [(set (match_operand:QI 0 "register_operand" "=r,r")
16414 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16415 [(reg FLAGS_REG) (const_int 0)])
16416 (match_operand:QI 2 "register_operand" "r,0")
16417 (match_operand:QI 3 "register_operand" "0,r")))]
16418 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16420 [(set_attr "type" "icmov")
16421 (set_attr "mode" "QI")])
16424 [(set (match_operand 0 "register_operand")
16425 (if_then_else (match_operator 1 "ix86_comparison_operator"
16426 [(reg FLAGS_REG) (const_int 0)])
16427 (match_operand 2 "register_operand")
16428 (match_operand 3 "register_operand")))]
16429 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16430 && (GET_MODE (operands[0]) == QImode
16431 || GET_MODE (operands[0]) == HImode)
16432 && reload_completed"
16433 [(set (match_dup 0)
16434 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16436 operands[0] = gen_lowpart (SImode, operands[0]);
16437 operands[2] = gen_lowpart (SImode, operands[2]);
16438 operands[3] = gen_lowpart (SImode, operands[3]);
16441 (define_expand "mov<mode>cc"
16442 [(set (match_operand:X87MODEF 0 "register_operand" "")
16443 (if_then_else:X87MODEF
16444 (match_operand 1 "ix86_fp_comparison_operator" "")
16445 (match_operand:X87MODEF 2 "register_operand" "")
16446 (match_operand:X87MODEF 3 "register_operand" "")))]
16447 "(TARGET_80387 && TARGET_CMOVE)
16448 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16449 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16451 (define_insn "*movxfcc_1"
16452 [(set (match_operand:XF 0 "register_operand" "=f,f")
16453 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16454 [(reg FLAGS_REG) (const_int 0)])
16455 (match_operand:XF 2 "register_operand" "f,0")
16456 (match_operand:XF 3 "register_operand" "0,f")))]
16457 "TARGET_80387 && TARGET_CMOVE"
16459 fcmov%F1\t{%2, %0|%0, %2}
16460 fcmov%f1\t{%3, %0|%0, %3}"
16461 [(set_attr "type" "fcmov")
16462 (set_attr "mode" "XF")])
16464 (define_insn "*movdfcc_1_rex64"
16465 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16466 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16467 [(reg FLAGS_REG) (const_int 0)])
16468 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16469 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16470 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16471 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16473 fcmov%F1\t{%2, %0|%0, %2}
16474 fcmov%f1\t{%3, %0|%0, %3}
16475 cmov%O2%C1\t{%2, %0|%0, %2}
16476 cmov%O2%c1\t{%3, %0|%0, %3}"
16477 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16478 (set_attr "mode" "DF,DF,DI,DI")])
16480 (define_insn "*movdfcc_1"
16481 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16482 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16483 [(reg FLAGS_REG) (const_int 0)])
16484 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16485 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16486 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16487 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16489 fcmov%F1\t{%2, %0|%0, %2}
16490 fcmov%f1\t{%3, %0|%0, %3}
16493 [(set_attr "type" "fcmov,fcmov,multi,multi")
16494 (set_attr "mode" "DF,DF,DI,DI")])
16497 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16498 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16499 [(reg FLAGS_REG) (const_int 0)])
16500 (match_operand:DF 2 "nonimmediate_operand")
16501 (match_operand:DF 3 "nonimmediate_operand")))]
16502 "!TARGET_64BIT && reload_completed"
16503 [(set (match_dup 2)
16504 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16506 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16508 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16509 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16512 (define_insn "*movsfcc_1_387"
16513 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16514 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16515 [(reg FLAGS_REG) (const_int 0)])
16516 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16517 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16518 "TARGET_80387 && TARGET_CMOVE
16519 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16521 fcmov%F1\t{%2, %0|%0, %2}
16522 fcmov%f1\t{%3, %0|%0, %3}
16523 cmov%O2%C1\t{%2, %0|%0, %2}
16524 cmov%O2%c1\t{%3, %0|%0, %3}"
16525 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16526 (set_attr "mode" "SF,SF,SI,SI")])
16528 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16529 ;; the scalar versions to have only XMM registers as operands.
16531 ;; XOP conditional move
16532 (define_insn "*xop_pcmov_<mode>"
16533 [(set (match_operand:MODEF 0 "register_operand" "=x")
16534 (if_then_else:MODEF
16535 (match_operand:MODEF 1 "register_operand" "x")
16536 (match_operand:MODEF 2 "register_operand" "x")
16537 (match_operand:MODEF 3 "register_operand" "x")))]
16539 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16540 [(set_attr "type" "sse4arg")])
16542 ;; These versions of the min/max patterns are intentionally ignorant of
16543 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16544 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16545 ;; are undefined in this condition, we're certain this is correct.
16547 (define_insn "<code><mode>3"
16548 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16550 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16551 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16552 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16554 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16555 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16556 [(set_attr "isa" "noavx,avx")
16557 (set_attr "prefix" "orig,vex")
16558 (set_attr "type" "sseadd")
16559 (set_attr "mode" "<MODE>")])
16561 ;; These versions of the min/max patterns implement exactly the operations
16562 ;; min = (op1 < op2 ? op1 : op2)
16563 ;; max = (!(op1 < op2) ? op1 : op2)
16564 ;; Their operands are not commutative, and thus they may be used in the
16565 ;; presence of -0.0 and NaN.
16567 (define_insn "*ieee_smin<mode>3"
16568 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16570 [(match_operand:MODEF 1 "register_operand" "0,x")
16571 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16573 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16575 min<ssemodesuffix>\t{%2, %0|%0, %2}
16576 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16577 [(set_attr "isa" "noavx,avx")
16578 (set_attr "prefix" "orig,vex")
16579 (set_attr "type" "sseadd")
16580 (set_attr "mode" "<MODE>")])
16582 (define_insn "*ieee_smax<mode>3"
16583 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16585 [(match_operand:MODEF 1 "register_operand" "0,x")
16586 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16588 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16590 max<ssemodesuffix>\t{%2, %0|%0, %2}
16591 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16592 [(set_attr "isa" "noavx,avx")
16593 (set_attr "prefix" "orig,vex")
16594 (set_attr "type" "sseadd")
16595 (set_attr "mode" "<MODE>")])
16597 ;; Make two stack loads independent:
16599 ;; fld %st(0) -> fld bb
16600 ;; fmul bb fmul %st(1), %st
16602 ;; Actually we only match the last two instructions for simplicity.
16604 [(set (match_operand 0 "fp_register_operand" "")
16605 (match_operand 1 "fp_register_operand" ""))
16607 (match_operator 2 "binary_fp_operator"
16609 (match_operand 3 "memory_operand" "")]))]
16610 "REGNO (operands[0]) != REGNO (operands[1])"
16611 [(set (match_dup 0) (match_dup 3))
16612 (set (match_dup 0) (match_dup 4))]
16614 ;; The % modifier is not operational anymore in peephole2's, so we have to
16615 ;; swap the operands manually in the case of addition and multiplication.
16619 if (COMMUTATIVE_ARITH_P (operands[2]))
16620 op0 = operands[0], op1 = operands[1];
16622 op0 = operands[1], op1 = operands[0];
16624 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16625 GET_MODE (operands[2]),
16629 ;; Conditional addition patterns
16630 (define_expand "add<mode>cc"
16631 [(match_operand:SWI 0 "register_operand" "")
16632 (match_operand 1 "ordered_comparison_operator" "")
16633 (match_operand:SWI 2 "register_operand" "")
16634 (match_operand:SWI 3 "const_int_operand" "")]
16636 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16638 ;; Misc patterns (?)
16640 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16641 ;; Otherwise there will be nothing to keep
16643 ;; [(set (reg ebp) (reg esp))]
16644 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16645 ;; (clobber (eflags)]
16646 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16648 ;; in proper program order.
16650 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16651 [(set (match_operand:P 0 "register_operand" "=r,r")
16652 (plus:P (match_operand:P 1 "register_operand" "0,r")
16653 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16654 (clobber (reg:CC FLAGS_REG))
16655 (clobber (mem:BLK (scratch)))]
16658 switch (get_attr_type (insn))
16661 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16664 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16665 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16666 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16668 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16671 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16672 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16675 [(set (attr "type")
16676 (cond [(and (eq_attr "alternative" "0")
16677 (not (match_test "TARGET_OPT_AGU")))
16678 (const_string "alu")
16679 (match_operand:<MODE> 2 "const0_operand" "")
16680 (const_string "imov")
16682 (const_string "lea")))
16683 (set (attr "length_immediate")
16684 (cond [(eq_attr "type" "imov")
16686 (and (eq_attr "type" "alu")
16687 (match_operand 2 "const128_operand" ""))
16690 (const_string "*")))
16691 (set_attr "mode" "<MODE>")])
16693 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16694 [(set (match_operand:P 0 "register_operand" "=r")
16695 (minus:P (match_operand:P 1 "register_operand" "0")
16696 (match_operand:P 2 "register_operand" "r")))
16697 (clobber (reg:CC FLAGS_REG))
16698 (clobber (mem:BLK (scratch)))]
16700 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16701 [(set_attr "type" "alu")
16702 (set_attr "mode" "<MODE>")])
16704 (define_insn "allocate_stack_worker_probe_<mode>"
16705 [(set (match_operand:P 0 "register_operand" "=a")
16706 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16707 UNSPECV_STACK_PROBE))
16708 (clobber (reg:CC FLAGS_REG))]
16709 "ix86_target_stack_probe ()"
16710 "call\t___chkstk_ms"
16711 [(set_attr "type" "multi")
16712 (set_attr "length" "5")])
16714 (define_expand "allocate_stack"
16715 [(match_operand 0 "register_operand" "")
16716 (match_operand 1 "general_operand" "")]
16717 "ix86_target_stack_probe ()"
16721 #ifndef CHECK_STACK_LIMIT
16722 #define CHECK_STACK_LIMIT 0
16725 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16726 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16728 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16729 stack_pointer_rtx, 0, OPTAB_DIRECT);
16730 if (x != stack_pointer_rtx)
16731 emit_move_insn (stack_pointer_rtx, x);
16735 x = copy_to_mode_reg (Pmode, operands[1]);
16737 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16739 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16740 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16741 stack_pointer_rtx, 0, OPTAB_DIRECT);
16742 if (x != stack_pointer_rtx)
16743 emit_move_insn (stack_pointer_rtx, x);
16746 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16750 ;; Use IOR for stack probes, this is shorter.
16751 (define_expand "probe_stack"
16752 [(match_operand 0 "memory_operand" "")]
16755 rtx (*gen_ior3) (rtx, rtx, rtx);
16757 gen_ior3 = (GET_MODE (operands[0]) == DImode
16758 ? gen_iordi3 : gen_iorsi3);
16760 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16764 (define_insn "adjust_stack_and_probe<mode>"
16765 [(set (match_operand:P 0 "register_operand" "=r")
16766 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16767 UNSPECV_PROBE_STACK_RANGE))
16768 (set (reg:P SP_REG)
16769 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16770 (clobber (reg:CC FLAGS_REG))
16771 (clobber (mem:BLK (scratch)))]
16773 "* return output_adjust_stack_and_probe (operands[0]);"
16774 [(set_attr "type" "multi")])
16776 (define_insn "probe_stack_range<mode>"
16777 [(set (match_operand:P 0 "register_operand" "=r")
16778 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16779 (match_operand:P 2 "const_int_operand" "n")]
16780 UNSPECV_PROBE_STACK_RANGE))
16781 (clobber (reg:CC FLAGS_REG))]
16783 "* return output_probe_stack_range (operands[0], operands[2]);"
16784 [(set_attr "type" "multi")])
16786 (define_expand "builtin_setjmp_receiver"
16787 [(label_ref (match_operand 0 "" ""))]
16788 "!TARGET_64BIT && flag_pic"
16794 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16795 rtx label_rtx = gen_label_rtx ();
16796 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16797 xops[0] = xops[1] = picreg;
16798 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16799 ix86_expand_binary_operator (MINUS, SImode, xops);
16803 emit_insn (gen_set_got (pic_offset_table_rtx));
16807 (define_insn_and_split "nonlocal_goto_receiver"
16808 [(unspec_volatile [(const_int 0)] UNSPECV_NLGR)]
16809 "TARGET_MACHO && !TARGET_64BIT && flag_pic"
16811 "&& reload_completed"
16814 if (crtl->uses_pic_offset_table)
16817 rtx label_rtx = gen_label_rtx ();
16820 /* Get a new pic base. */
16821 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16822 /* Correct this with the offset from the new to the old. */
16823 xops[0] = xops[1] = pic_offset_table_rtx;
16824 label_rtx = gen_rtx_LABEL_REF (SImode, label_rtx);
16825 tmp = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, label_rtx),
16826 UNSPEC_MACHOPIC_OFFSET);
16827 xops[2] = gen_rtx_CONST (Pmode, tmp);
16828 ix86_expand_binary_operator (MINUS, SImode, xops);
16831 /* No pic reg restore needed. */
16832 emit_note (NOTE_INSN_DELETED);
16837 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16840 [(set (match_operand 0 "register_operand" "")
16841 (match_operator 3 "promotable_binary_operator"
16842 [(match_operand 1 "register_operand" "")
16843 (match_operand 2 "aligned_operand" "")]))
16844 (clobber (reg:CC FLAGS_REG))]
16845 "! TARGET_PARTIAL_REG_STALL && reload_completed
16846 && ((GET_MODE (operands[0]) == HImode
16847 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16848 /* ??? next two lines just !satisfies_constraint_K (...) */
16849 || !CONST_INT_P (operands[2])
16850 || satisfies_constraint_K (operands[2])))
16851 || (GET_MODE (operands[0]) == QImode
16852 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16853 [(parallel [(set (match_dup 0)
16854 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16855 (clobber (reg:CC FLAGS_REG))])]
16857 operands[0] = gen_lowpart (SImode, operands[0]);
16858 operands[1] = gen_lowpart (SImode, operands[1]);
16859 if (GET_CODE (operands[3]) != ASHIFT)
16860 operands[2] = gen_lowpart (SImode, operands[2]);
16861 PUT_MODE (operands[3], SImode);
16864 ; Promote the QImode tests, as i386 has encoding of the AND
16865 ; instruction with 32-bit sign-extended immediate and thus the
16866 ; instruction size is unchanged, except in the %eax case for
16867 ; which it is increased by one byte, hence the ! optimize_size.
16869 [(set (match_operand 0 "flags_reg_operand" "")
16870 (match_operator 2 "compare_operator"
16871 [(and (match_operand 3 "aligned_operand" "")
16872 (match_operand 4 "const_int_operand" ""))
16874 (set (match_operand 1 "register_operand" "")
16875 (and (match_dup 3) (match_dup 4)))]
16876 "! TARGET_PARTIAL_REG_STALL && reload_completed
16877 && optimize_insn_for_speed_p ()
16878 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16879 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16880 /* Ensure that the operand will remain sign-extended immediate. */
16881 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16882 [(parallel [(set (match_dup 0)
16883 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16886 (and:SI (match_dup 3) (match_dup 4)))])]
16889 = gen_int_mode (INTVAL (operands[4])
16890 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16891 operands[1] = gen_lowpart (SImode, operands[1]);
16892 operands[3] = gen_lowpart (SImode, operands[3]);
16895 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16896 ; the TEST instruction with 32-bit sign-extended immediate and thus
16897 ; the instruction size would at least double, which is not what we
16898 ; want even with ! optimize_size.
16900 [(set (match_operand 0 "flags_reg_operand" "")
16901 (match_operator 1 "compare_operator"
16902 [(and (match_operand:HI 2 "aligned_operand" "")
16903 (match_operand:HI 3 "const_int_operand" ""))
16905 "! TARGET_PARTIAL_REG_STALL && reload_completed
16906 && ! TARGET_FAST_PREFIX
16907 && optimize_insn_for_speed_p ()
16908 /* Ensure that the operand will remain sign-extended immediate. */
16909 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16910 [(set (match_dup 0)
16911 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16915 = gen_int_mode (INTVAL (operands[3])
16916 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16917 operands[2] = gen_lowpart (SImode, operands[2]);
16921 [(set (match_operand 0 "register_operand" "")
16922 (neg (match_operand 1 "register_operand" "")))
16923 (clobber (reg:CC FLAGS_REG))]
16924 "! TARGET_PARTIAL_REG_STALL && reload_completed
16925 && (GET_MODE (operands[0]) == HImode
16926 || (GET_MODE (operands[0]) == QImode
16927 && (TARGET_PROMOTE_QImode
16928 || optimize_insn_for_size_p ())))"
16929 [(parallel [(set (match_dup 0)
16930 (neg:SI (match_dup 1)))
16931 (clobber (reg:CC FLAGS_REG))])]
16933 operands[0] = gen_lowpart (SImode, operands[0]);
16934 operands[1] = gen_lowpart (SImode, operands[1]);
16938 [(set (match_operand 0 "register_operand" "")
16939 (not (match_operand 1 "register_operand" "")))]
16940 "! TARGET_PARTIAL_REG_STALL && reload_completed
16941 && (GET_MODE (operands[0]) == HImode
16942 || (GET_MODE (operands[0]) == QImode
16943 && (TARGET_PROMOTE_QImode
16944 || optimize_insn_for_size_p ())))"
16945 [(set (match_dup 0)
16946 (not:SI (match_dup 1)))]
16948 operands[0] = gen_lowpart (SImode, operands[0]);
16949 operands[1] = gen_lowpart (SImode, operands[1]);
16952 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16953 ;; transform a complex memory operation into two memory to register operations.
16955 ;; Don't push memory operands
16957 [(set (match_operand:SWI 0 "push_operand" "")
16958 (match_operand:SWI 1 "memory_operand" ""))
16959 (match_scratch:SWI 2 "<r>")]
16960 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16961 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16962 [(set (match_dup 2) (match_dup 1))
16963 (set (match_dup 0) (match_dup 2))])
16965 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16968 [(set (match_operand:SF 0 "push_operand" "")
16969 (match_operand:SF 1 "memory_operand" ""))
16970 (match_scratch:SF 2 "r")]
16971 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16972 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16973 [(set (match_dup 2) (match_dup 1))
16974 (set (match_dup 0) (match_dup 2))])
16976 ;; Don't move an immediate directly to memory when the instruction
16979 [(match_scratch:SWI124 1 "<r>")
16980 (set (match_operand:SWI124 0 "memory_operand" "")
16982 "optimize_insn_for_speed_p ()
16983 && !TARGET_USE_MOV0
16984 && TARGET_SPLIT_LONG_MOVES
16985 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16986 && peep2_regno_dead_p (0, FLAGS_REG)"
16987 [(parallel [(set (match_dup 2) (const_int 0))
16988 (clobber (reg:CC FLAGS_REG))])
16989 (set (match_dup 0) (match_dup 1))]
16990 "operands[2] = gen_lowpart (SImode, operands[1]);")
16993 [(match_scratch:SWI124 2 "<r>")
16994 (set (match_operand:SWI124 0 "memory_operand" "")
16995 (match_operand:SWI124 1 "immediate_operand" ""))]
16996 "optimize_insn_for_speed_p ()
16997 && TARGET_SPLIT_LONG_MOVES
16998 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16999 [(set (match_dup 2) (match_dup 1))
17000 (set (match_dup 0) (match_dup 2))])
17002 ;; Don't compare memory with zero, load and use a test instead.
17004 [(set (match_operand 0 "flags_reg_operand" "")
17005 (match_operator 1 "compare_operator"
17006 [(match_operand:SI 2 "memory_operand" "")
17008 (match_scratch:SI 3 "r")]
17009 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
17010 [(set (match_dup 3) (match_dup 2))
17011 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
17013 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
17014 ;; Don't split NOTs with a displacement operand, because resulting XOR
17015 ;; will not be pairable anyway.
17017 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
17018 ;; represented using a modRM byte. The XOR replacement is long decoded,
17019 ;; so this split helps here as well.
17021 ;; Note: Can't do this as a regular split because we can't get proper
17022 ;; lifetime information then.
17025 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17026 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17027 "optimize_insn_for_speed_p ()
17028 && ((TARGET_NOT_UNPAIRABLE
17029 && (!MEM_P (operands[0])
17030 || !memory_displacement_operand (operands[0], <MODE>mode)))
17031 || (TARGET_NOT_VECTORMODE
17032 && long_memory_operand (operands[0], <MODE>mode)))
17033 && peep2_regno_dead_p (0, FLAGS_REG)"
17034 [(parallel [(set (match_dup 0)
17035 (xor:SWI124 (match_dup 1) (const_int -1)))
17036 (clobber (reg:CC FLAGS_REG))])])
17038 ;; Non pairable "test imm, reg" instructions can be translated to
17039 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17040 ;; byte opcode instead of two, have a short form for byte operands),
17041 ;; so do it for other CPUs as well. Given that the value was dead,
17042 ;; this should not create any new dependencies. Pass on the sub-word
17043 ;; versions if we're concerned about partial register stalls.
17046 [(set (match_operand 0 "flags_reg_operand" "")
17047 (match_operator 1 "compare_operator"
17048 [(and:SI (match_operand:SI 2 "register_operand" "")
17049 (match_operand:SI 3 "immediate_operand" ""))
17051 "ix86_match_ccmode (insn, CCNOmode)
17052 && (true_regnum (operands[2]) != AX_REG
17053 || satisfies_constraint_K (operands[3]))
17054 && peep2_reg_dead_p (1, operands[2])"
17056 [(set (match_dup 0)
17057 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17060 (and:SI (match_dup 2) (match_dup 3)))])])
17062 ;; We don't need to handle HImode case, because it will be promoted to SImode
17063 ;; on ! TARGET_PARTIAL_REG_STALL
17066 [(set (match_operand 0 "flags_reg_operand" "")
17067 (match_operator 1 "compare_operator"
17068 [(and:QI (match_operand:QI 2 "register_operand" "")
17069 (match_operand:QI 3 "immediate_operand" ""))
17071 "! TARGET_PARTIAL_REG_STALL
17072 && ix86_match_ccmode (insn, CCNOmode)
17073 && true_regnum (operands[2]) != AX_REG
17074 && peep2_reg_dead_p (1, operands[2])"
17076 [(set (match_dup 0)
17077 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17080 (and:QI (match_dup 2) (match_dup 3)))])])
17083 [(set (match_operand 0 "flags_reg_operand" "")
17084 (match_operator 1 "compare_operator"
17087 (match_operand 2 "ext_register_operand" "")
17090 (match_operand 3 "const_int_operand" ""))
17092 "! TARGET_PARTIAL_REG_STALL
17093 && ix86_match_ccmode (insn, CCNOmode)
17094 && true_regnum (operands[2]) != AX_REG
17095 && peep2_reg_dead_p (1, operands[2])"
17096 [(parallel [(set (match_dup 0)
17105 (set (zero_extract:SI (match_dup 2)
17113 (match_dup 3)))])])
17115 ;; Don't do logical operations with memory inputs.
17117 [(match_scratch:SI 2 "r")
17118 (parallel [(set (match_operand:SI 0 "register_operand" "")
17119 (match_operator:SI 3 "arith_or_logical_operator"
17121 (match_operand:SI 1 "memory_operand" "")]))
17122 (clobber (reg:CC FLAGS_REG))])]
17123 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17124 [(set (match_dup 2) (match_dup 1))
17125 (parallel [(set (match_dup 0)
17126 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17127 (clobber (reg:CC FLAGS_REG))])])
17130 [(match_scratch:SI 2 "r")
17131 (parallel [(set (match_operand:SI 0 "register_operand" "")
17132 (match_operator:SI 3 "arith_or_logical_operator"
17133 [(match_operand:SI 1 "memory_operand" "")
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17137 [(set (match_dup 2) (match_dup 1))
17138 (parallel [(set (match_dup 0)
17139 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17140 (clobber (reg:CC FLAGS_REG))])])
17142 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17143 ;; refers to the destination of the load!
17146 [(set (match_operand:SI 0 "register_operand" "")
17147 (match_operand:SI 1 "register_operand" ""))
17148 (parallel [(set (match_dup 0)
17149 (match_operator:SI 3 "commutative_operator"
17151 (match_operand:SI 2 "memory_operand" "")]))
17152 (clobber (reg:CC FLAGS_REG))])]
17153 "REGNO (operands[0]) != REGNO (operands[1])
17154 && GENERAL_REGNO_P (REGNO (operands[0]))
17155 && GENERAL_REGNO_P (REGNO (operands[1]))"
17156 [(set (match_dup 0) (match_dup 4))
17157 (parallel [(set (match_dup 0)
17158 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17159 (clobber (reg:CC FLAGS_REG))])]
17160 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17163 [(set (match_operand 0 "register_operand" "")
17164 (match_operand 1 "register_operand" ""))
17166 (match_operator 3 "commutative_operator"
17168 (match_operand 2 "memory_operand" "")]))]
17169 "REGNO (operands[0]) != REGNO (operands[1])
17170 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17171 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17172 [(set (match_dup 0) (match_dup 2))
17174 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17176 ; Don't do logical operations with memory outputs
17178 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17179 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17180 ; the same decoder scheduling characteristics as the original.
17183 [(match_scratch:SI 2 "r")
17184 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17185 (match_operator:SI 3 "arith_or_logical_operator"
17187 (match_operand:SI 1 "nonmemory_operand" "")]))
17188 (clobber (reg:CC FLAGS_REG))])]
17189 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17190 /* Do not split stack checking probes. */
17191 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17192 [(set (match_dup 2) (match_dup 0))
17193 (parallel [(set (match_dup 2)
17194 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17195 (clobber (reg:CC FLAGS_REG))])
17196 (set (match_dup 0) (match_dup 2))])
17199 [(match_scratch:SI 2 "r")
17200 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17201 (match_operator:SI 3 "arith_or_logical_operator"
17202 [(match_operand:SI 1 "nonmemory_operand" "")
17204 (clobber (reg:CC FLAGS_REG))])]
17205 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17206 /* Do not split stack checking probes. */
17207 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17208 [(set (match_dup 2) (match_dup 0))
17209 (parallel [(set (match_dup 2)
17210 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17211 (clobber (reg:CC FLAGS_REG))])
17212 (set (match_dup 0) (match_dup 2))])
17214 ;; Attempt to use arith or logical operations with memory outputs with
17215 ;; setting of flags.
17217 [(set (match_operand:SWI 0 "register_operand" "")
17218 (match_operand:SWI 1 "memory_operand" ""))
17219 (parallel [(set (match_dup 0)
17220 (match_operator:SWI 3 "plusminuslogic_operator"
17222 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17223 (clobber (reg:CC FLAGS_REG))])
17224 (set (match_dup 1) (match_dup 0))
17225 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17226 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17227 && peep2_reg_dead_p (4, operands[0])
17228 && !reg_overlap_mentioned_p (operands[0], operands[1])
17229 && !reg_overlap_mentioned_p (operands[0], operands[2])
17230 && (<MODE>mode != QImode
17231 || immediate_operand (operands[2], QImode)
17232 || q_regs_operand (operands[2], QImode))
17233 && ix86_match_ccmode (peep2_next_insn (3),
17234 (GET_CODE (operands[3]) == PLUS
17235 || GET_CODE (operands[3]) == MINUS)
17236 ? CCGOCmode : CCNOmode)"
17237 [(parallel [(set (match_dup 4) (match_dup 5))
17238 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17239 (match_dup 2)]))])]
17241 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17242 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17243 copy_rtx (operands[1]),
17244 copy_rtx (operands[2]));
17245 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17246 operands[5], const0_rtx);
17250 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17251 (match_operator:SWI 2 "plusminuslogic_operator"
17253 (match_operand:SWI 1 "memory_operand" "")]))
17254 (clobber (reg:CC FLAGS_REG))])
17255 (set (match_dup 1) (match_dup 0))
17256 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17257 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17258 && GET_CODE (operands[2]) != MINUS
17259 && peep2_reg_dead_p (3, operands[0])
17260 && !reg_overlap_mentioned_p (operands[0], operands[1])
17261 && ix86_match_ccmode (peep2_next_insn (2),
17262 GET_CODE (operands[2]) == PLUS
17263 ? CCGOCmode : CCNOmode)"
17264 [(parallel [(set (match_dup 3) (match_dup 4))
17265 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17266 (match_dup 0)]))])]
17268 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17269 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17270 copy_rtx (operands[1]),
17271 copy_rtx (operands[0]));
17272 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17273 operands[4], const0_rtx);
17277 [(set (match_operand:SWI12 0 "register_operand" "")
17278 (match_operand:SWI12 1 "memory_operand" ""))
17279 (parallel [(set (match_operand:SI 4 "register_operand" "")
17280 (match_operator:SI 3 "plusminuslogic_operator"
17282 (match_operand:SI 2 "nonmemory_operand" "")]))
17283 (clobber (reg:CC FLAGS_REG))])
17284 (set (match_dup 1) (match_dup 0))
17285 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17286 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17287 && REG_P (operands[0]) && REG_P (operands[4])
17288 && REGNO (operands[0]) == REGNO (operands[4])
17289 && peep2_reg_dead_p (4, operands[0])
17290 && (<MODE>mode != QImode
17291 || immediate_operand (operands[2], SImode)
17292 || q_regs_operand (operands[2], SImode))
17293 && !reg_overlap_mentioned_p (operands[0], operands[1])
17294 && !reg_overlap_mentioned_p (operands[0], operands[2])
17295 && ix86_match_ccmode (peep2_next_insn (3),
17296 (GET_CODE (operands[3]) == PLUS
17297 || GET_CODE (operands[3]) == MINUS)
17298 ? CCGOCmode : CCNOmode)"
17299 [(parallel [(set (match_dup 4) (match_dup 5))
17300 (set (match_dup 1) (match_dup 6))])]
17302 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17303 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17304 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17305 copy_rtx (operands[1]), operands[2]);
17306 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17307 operands[5], const0_rtx);
17308 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17309 copy_rtx (operands[1]),
17310 copy_rtx (operands[2]));
17313 ;; Attempt to always use XOR for zeroing registers.
17315 [(set (match_operand 0 "register_operand" "")
17316 (match_operand 1 "const0_operand" ""))]
17317 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17318 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17319 && GENERAL_REG_P (operands[0])
17320 && peep2_regno_dead_p (0, FLAGS_REG)"
17321 [(parallel [(set (match_dup 0) (const_int 0))
17322 (clobber (reg:CC FLAGS_REG))])]
17323 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17326 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17328 "(GET_MODE (operands[0]) == QImode
17329 || GET_MODE (operands[0]) == HImode)
17330 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17331 && peep2_regno_dead_p (0, FLAGS_REG)"
17332 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17333 (clobber (reg:CC FLAGS_REG))])])
17335 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17337 [(set (match_operand:SWI248 0 "register_operand" "")
17339 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17340 && peep2_regno_dead_p (0, FLAGS_REG)"
17341 [(parallel [(set (match_dup 0) (const_int -1))
17342 (clobber (reg:CC FLAGS_REG))])]
17344 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17345 operands[0] = gen_lowpart (SImode, operands[0]);
17348 ;; Attempt to convert simple lea to add/shift.
17349 ;; These can be created by move expanders.
17352 [(set (match_operand:SWI48 0 "register_operand" "")
17353 (plus:SWI48 (match_dup 0)
17354 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17355 "peep2_regno_dead_p (0, FLAGS_REG)"
17356 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17357 (clobber (reg:CC FLAGS_REG))])])
17360 [(set (match_operand:SI 0 "register_operand" "")
17361 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17362 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17364 && peep2_regno_dead_p (0, FLAGS_REG)
17365 && REGNO (operands[0]) == REGNO (operands[1])"
17366 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17367 (clobber (reg:CC FLAGS_REG))])]
17368 "operands[2] = gen_lowpart (SImode, operands[2]);")
17371 [(set (match_operand:SWI48 0 "register_operand" "")
17372 (mult:SWI48 (match_dup 0)
17373 (match_operand:SWI48 1 "const_int_operand" "")))]
17374 "exact_log2 (INTVAL (operands[1])) >= 0
17375 && peep2_regno_dead_p (0, FLAGS_REG)"
17376 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17377 (clobber (reg:CC FLAGS_REG))])]
17378 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17381 [(set (match_operand:SI 0 "register_operand" "")
17382 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17383 (match_operand:DI 2 "const_int_operand" "")) 0))]
17385 && exact_log2 (INTVAL (operands[2])) >= 0
17386 && REGNO (operands[0]) == REGNO (operands[1])
17387 && peep2_regno_dead_p (0, FLAGS_REG)"
17388 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17389 (clobber (reg:CC FLAGS_REG))])]
17390 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17392 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17393 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17394 ;; On many CPUs it is also faster, since special hardware to avoid esp
17395 ;; dependencies is present.
17397 ;; While some of these conversions may be done using splitters, we use
17398 ;; peepholes in order to allow combine_stack_adjustments pass to see
17399 ;; nonobfuscated RTL.
17401 ;; Convert prologue esp subtractions to push.
17402 ;; We need register to push. In order to keep verify_flow_info happy we have
17404 ;; - use scratch and clobber it in order to avoid dependencies
17405 ;; - use already live register
17406 ;; We can't use the second way right now, since there is no reliable way how to
17407 ;; verify that given register is live. First choice will also most likely in
17408 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17409 ;; call clobbered registers are dead. We may want to use base pointer as an
17410 ;; alternative when no register is available later.
17413 [(match_scratch:P 1 "r")
17414 (parallel [(set (reg:P SP_REG)
17415 (plus:P (reg:P SP_REG)
17416 (match_operand:P 0 "const_int_operand" "")))
17417 (clobber (reg:CC FLAGS_REG))
17418 (clobber (mem:BLK (scratch)))])]
17419 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17420 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17421 [(clobber (match_dup 1))
17422 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17423 (clobber (mem:BLK (scratch)))])])
17426 [(match_scratch:P 1 "r")
17427 (parallel [(set (reg:P SP_REG)
17428 (plus:P (reg:P SP_REG)
17429 (match_operand:P 0 "const_int_operand" "")))
17430 (clobber (reg:CC FLAGS_REG))
17431 (clobber (mem:BLK (scratch)))])]
17432 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17433 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17434 [(clobber (match_dup 1))
17435 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17436 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17437 (clobber (mem:BLK (scratch)))])])
17439 ;; Convert esp subtractions to push.
17441 [(match_scratch:P 1 "r")
17442 (parallel [(set (reg:P SP_REG)
17443 (plus:P (reg:P SP_REG)
17444 (match_operand:P 0 "const_int_operand" "")))
17445 (clobber (reg:CC FLAGS_REG))])]
17446 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17447 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17448 [(clobber (match_dup 1))
17449 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17452 [(match_scratch:P 1 "r")
17453 (parallel [(set (reg:P SP_REG)
17454 (plus:P (reg:P SP_REG)
17455 (match_operand:P 0 "const_int_operand" "")))
17456 (clobber (reg:CC FLAGS_REG))])]
17457 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17458 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17459 [(clobber (match_dup 1))
17460 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17461 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17463 ;; Convert epilogue deallocator to pop.
17465 [(match_scratch:P 1 "r")
17466 (parallel [(set (reg:P SP_REG)
17467 (plus:P (reg:P SP_REG)
17468 (match_operand:P 0 "const_int_operand" "")))
17469 (clobber (reg:CC FLAGS_REG))
17470 (clobber (mem:BLK (scratch)))])]
17471 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17472 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17473 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17474 (clobber (mem:BLK (scratch)))])])
17476 ;; Two pops case is tricky, since pop causes dependency
17477 ;; on destination register. We use two registers if available.
17479 [(match_scratch:P 1 "r")
17480 (match_scratch:P 2 "r")
17481 (parallel [(set (reg:P SP_REG)
17482 (plus:P (reg:P SP_REG)
17483 (match_operand:P 0 "const_int_operand" "")))
17484 (clobber (reg:CC FLAGS_REG))
17485 (clobber (mem:BLK (scratch)))])]
17486 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17487 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17488 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17489 (clobber (mem:BLK (scratch)))])
17490 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17493 [(match_scratch:P 1 "r")
17494 (parallel [(set (reg:P SP_REG)
17495 (plus:P (reg:P SP_REG)
17496 (match_operand:P 0 "const_int_operand" "")))
17497 (clobber (reg:CC FLAGS_REG))
17498 (clobber (mem:BLK (scratch)))])]
17499 "optimize_insn_for_size_p ()
17500 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17501 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17502 (clobber (mem:BLK (scratch)))])
17503 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17505 ;; Convert esp additions to pop.
17507 [(match_scratch:P 1 "r")
17508 (parallel [(set (reg:P SP_REG)
17509 (plus:P (reg:P SP_REG)
17510 (match_operand:P 0 "const_int_operand" "")))
17511 (clobber (reg:CC FLAGS_REG))])]
17512 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17513 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17515 ;; Two pops case is tricky, since pop causes dependency
17516 ;; on destination register. We use two registers if available.
17518 [(match_scratch:P 1 "r")
17519 (match_scratch:P 2 "r")
17520 (parallel [(set (reg:P SP_REG)
17521 (plus:P (reg:P SP_REG)
17522 (match_operand:P 0 "const_int_operand" "")))
17523 (clobber (reg:CC FLAGS_REG))])]
17524 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17525 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17526 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17529 [(match_scratch:P 1 "r")
17530 (parallel [(set (reg:P SP_REG)
17531 (plus:P (reg:P SP_REG)
17532 (match_operand:P 0 "const_int_operand" "")))
17533 (clobber (reg:CC FLAGS_REG))])]
17534 "optimize_insn_for_size_p ()
17535 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17536 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17537 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17539 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17540 ;; required and register dies. Similarly for 128 to -128.
17542 [(set (match_operand 0 "flags_reg_operand" "")
17543 (match_operator 1 "compare_operator"
17544 [(match_operand 2 "register_operand" "")
17545 (match_operand 3 "const_int_operand" "")]))]
17546 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17547 && incdec_operand (operands[3], GET_MODE (operands[3])))
17548 || (!TARGET_FUSE_CMP_AND_BRANCH
17549 && INTVAL (operands[3]) == 128))
17550 && ix86_match_ccmode (insn, CCGCmode)
17551 && peep2_reg_dead_p (1, operands[2])"
17552 [(parallel [(set (match_dup 0)
17553 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17554 (clobber (match_dup 2))])])
17556 ;; Convert imul by three, five and nine into lea
17559 [(set (match_operand:SWI48 0 "register_operand" "")
17560 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17561 (match_operand:SWI48 2 "const359_operand" "")))
17562 (clobber (reg:CC FLAGS_REG))])]
17563 "!TARGET_PARTIAL_REG_STALL
17564 || <MODE>mode == SImode
17565 || optimize_function_for_size_p (cfun)"
17566 [(set (match_dup 0)
17567 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17569 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17573 [(set (match_operand:SWI48 0 "register_operand" "")
17574 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17575 (match_operand:SWI48 2 "const359_operand" "")))
17576 (clobber (reg:CC FLAGS_REG))])]
17577 "optimize_insn_for_speed_p ()
17578 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17579 [(set (match_dup 0) (match_dup 1))
17581 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17583 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17585 ;; imul $32bit_imm, mem, reg is vector decoded, while
17586 ;; imul $32bit_imm, reg, reg is direct decoded.
17588 [(match_scratch:SWI48 3 "r")
17589 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17590 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17591 (match_operand:SWI48 2 "immediate_operand" "")))
17592 (clobber (reg:CC FLAGS_REG))])]
17593 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17594 && !satisfies_constraint_K (operands[2])"
17595 [(set (match_dup 3) (match_dup 1))
17596 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17597 (clobber (reg:CC FLAGS_REG))])])
17600 [(match_scratch:SI 3 "r")
17601 (parallel [(set (match_operand:DI 0 "register_operand" "")
17603 (mult:SI (match_operand:SI 1 "memory_operand" "")
17604 (match_operand:SI 2 "immediate_operand" ""))))
17605 (clobber (reg:CC FLAGS_REG))])]
17607 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17608 && !satisfies_constraint_K (operands[2])"
17609 [(set (match_dup 3) (match_dup 1))
17610 (parallel [(set (match_dup 0)
17611 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17612 (clobber (reg:CC FLAGS_REG))])])
17614 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17615 ;; Convert it into imul reg, reg
17616 ;; It would be better to force assembler to encode instruction using long
17617 ;; immediate, but there is apparently no way to do so.
17619 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17621 (match_operand:SWI248 1 "nonimmediate_operand" "")
17622 (match_operand:SWI248 2 "const_int_operand" "")))
17623 (clobber (reg:CC FLAGS_REG))])
17624 (match_scratch:SWI248 3 "r")]
17625 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17626 && satisfies_constraint_K (operands[2])"
17627 [(set (match_dup 3) (match_dup 2))
17628 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17629 (clobber (reg:CC FLAGS_REG))])]
17631 if (!rtx_equal_p (operands[0], operands[1]))
17632 emit_move_insn (operands[0], operands[1]);
17635 ;; After splitting up read-modify operations, array accesses with memory
17636 ;; operands might end up in form:
17638 ;; movl 4(%esp), %edx
17640 ;; instead of pre-splitting:
17642 ;; addl 4(%esp), %eax
17644 ;; movl 4(%esp), %edx
17645 ;; leal (%edx,%eax,4), %eax
17648 [(match_scratch:P 5 "r")
17649 (parallel [(set (match_operand 0 "register_operand" "")
17650 (ashift (match_operand 1 "register_operand" "")
17651 (match_operand 2 "const_int_operand" "")))
17652 (clobber (reg:CC FLAGS_REG))])
17653 (parallel [(set (match_operand 3 "register_operand" "")
17654 (plus (match_dup 0)
17655 (match_operand 4 "x86_64_general_operand" "")))
17656 (clobber (reg:CC FLAGS_REG))])]
17657 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17658 /* Validate MODE for lea. */
17659 && ((!TARGET_PARTIAL_REG_STALL
17660 && (GET_MODE (operands[0]) == QImode
17661 || GET_MODE (operands[0]) == HImode))
17662 || GET_MODE (operands[0]) == SImode
17663 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17664 && (rtx_equal_p (operands[0], operands[3])
17665 || peep2_reg_dead_p (2, operands[0]))
17666 /* We reorder load and the shift. */
17667 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17668 [(set (match_dup 5) (match_dup 4))
17669 (set (match_dup 0) (match_dup 1))]
17671 enum machine_mode op1mode = GET_MODE (operands[1]);
17672 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17673 int scale = 1 << INTVAL (operands[2]);
17674 rtx index = gen_lowpart (Pmode, operands[1]);
17675 rtx base = gen_lowpart (Pmode, operands[5]);
17676 rtx dest = gen_lowpart (mode, operands[3]);
17678 operands[1] = gen_rtx_PLUS (Pmode, base,
17679 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17680 operands[5] = base;
17682 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17683 if (op1mode != Pmode)
17684 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17685 operands[0] = dest;
17688 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17689 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17690 ;; caught for use by garbage collectors and the like. Using an insn that
17691 ;; maps to SIGILL makes it more likely the program will rightfully die.
17692 ;; Keeping with tradition, "6" is in honor of #UD.
17693 (define_insn "trap"
17694 [(trap_if (const_int 1) (const_int 6))]
17696 { return ASM_SHORT "0x0b0f"; }
17697 [(set_attr "length" "2")])
17699 (define_expand "prefetch"
17700 [(prefetch (match_operand 0 "address_operand" "")
17701 (match_operand:SI 1 "const_int_operand" "")
17702 (match_operand:SI 2 "const_int_operand" ""))]
17703 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17705 int rw = INTVAL (operands[1]);
17706 int locality = INTVAL (operands[2]);
17708 gcc_assert (rw == 0 || rw == 1);
17709 gcc_assert (IN_RANGE (locality, 0, 3));
17711 if (TARGET_PREFETCHW && rw)
17712 operands[2] = GEN_INT (3);
17713 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17714 supported by SSE counterpart or the SSE prefetch is not available
17715 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17717 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17718 operands[2] = GEN_INT (3);
17720 operands[1] = const0_rtx;
17723 (define_insn "*prefetch_sse"
17724 [(prefetch (match_operand 0 "address_operand" "p")
17726 (match_operand:SI 1 "const_int_operand" ""))]
17727 "TARGET_PREFETCH_SSE"
17729 static const char * const patterns[4] = {
17730 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17733 int locality = INTVAL (operands[1]);
17734 gcc_assert (IN_RANGE (locality, 0, 3));
17736 return patterns[locality];
17738 [(set_attr "type" "sse")
17739 (set_attr "atom_sse_attr" "prefetch")
17740 (set (attr "length_address")
17741 (symbol_ref "memory_address_length (operands[0], false)"))
17742 (set_attr "memory" "none")])
17744 (define_insn "*prefetch_3dnow"
17745 [(prefetch (match_operand 0 "address_operand" "p")
17746 (match_operand:SI 1 "const_int_operand" "n")
17748 "TARGET_3DNOW || TARGET_PREFETCHW"
17750 if (INTVAL (operands[1]) == 0)
17751 return "prefetch\t%a0";
17753 return "prefetchw\t%a0";
17755 [(set_attr "type" "mmx")
17756 (set (attr "length_address")
17757 (symbol_ref "memory_address_length (operands[0], false)"))
17758 (set_attr "memory" "none")])
17760 (define_expand "stack_protect_set"
17761 [(match_operand 0 "memory_operand" "")
17762 (match_operand 1 "memory_operand" "")]
17763 "!TARGET_HAS_BIONIC"
17765 rtx (*insn)(rtx, rtx);
17767 #ifdef TARGET_THREAD_SSP_OFFSET
17768 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17769 insn = (TARGET_LP64
17770 ? gen_stack_tls_protect_set_di
17771 : gen_stack_tls_protect_set_si);
17773 insn = (TARGET_LP64
17774 ? gen_stack_protect_set_di
17775 : gen_stack_protect_set_si);
17778 emit_insn (insn (operands[0], operands[1]));
17782 (define_insn "stack_protect_set_<mode>"
17783 [(set (match_operand:PTR 0 "memory_operand" "=m")
17784 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17786 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17787 (clobber (reg:CC FLAGS_REG))]
17788 "!TARGET_HAS_BIONIC"
17789 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17790 [(set_attr "type" "multi")])
17792 (define_insn "stack_tls_protect_set_<mode>"
17793 [(set (match_operand:PTR 0 "memory_operand" "=m")
17794 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17795 UNSPEC_SP_TLS_SET))
17796 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17797 (clobber (reg:CC FLAGS_REG))]
17799 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17800 [(set_attr "type" "multi")])
17802 (define_expand "stack_protect_test"
17803 [(match_operand 0 "memory_operand" "")
17804 (match_operand 1 "memory_operand" "")
17805 (match_operand 2 "" "")]
17806 "!TARGET_HAS_BIONIC"
17808 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17810 rtx (*insn)(rtx, rtx, rtx);
17812 #ifdef TARGET_THREAD_SSP_OFFSET
17813 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17814 insn = (TARGET_LP64
17815 ? gen_stack_tls_protect_test_di
17816 : gen_stack_tls_protect_test_si);
17818 insn = (TARGET_LP64
17819 ? gen_stack_protect_test_di
17820 : gen_stack_protect_test_si);
17823 emit_insn (insn (flags, operands[0], operands[1]));
17825 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17826 flags, const0_rtx, operands[2]));
17830 (define_insn "stack_protect_test_<mode>"
17831 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17832 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17833 (match_operand:PTR 2 "memory_operand" "m")]
17835 (clobber (match_scratch:PTR 3 "=&r"))]
17836 "!TARGET_HAS_BIONIC"
17837 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17838 [(set_attr "type" "multi")])
17840 (define_insn "stack_tls_protect_test_<mode>"
17841 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17842 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17843 (match_operand:PTR 2 "const_int_operand" "i")]
17844 UNSPEC_SP_TLS_TEST))
17845 (clobber (match_scratch:PTR 3 "=r"))]
17847 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17848 [(set_attr "type" "multi")])
17850 (define_insn "sse4_2_crc32<mode>"
17851 [(set (match_operand:SI 0 "register_operand" "=r")
17853 [(match_operand:SI 1 "register_operand" "0")
17854 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17856 "TARGET_SSE4_2 || TARGET_CRC32"
17857 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17858 [(set_attr "type" "sselog1")
17859 (set_attr "prefix_rep" "1")
17860 (set_attr "prefix_extra" "1")
17861 (set (attr "prefix_data16")
17862 (if_then_else (match_operand:HI 2 "" "")
17864 (const_string "*")))
17865 (set (attr "prefix_rex")
17866 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17868 (const_string "*")))
17869 (set_attr "mode" "SI")])
17871 (define_insn "sse4_2_crc32di"
17872 [(set (match_operand:DI 0 "register_operand" "=r")
17874 [(match_operand:DI 1 "register_operand" "0")
17875 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17877 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17878 "crc32{q}\t{%2, %0|%0, %2}"
17879 [(set_attr "type" "sselog1")
17880 (set_attr "prefix_rep" "1")
17881 (set_attr "prefix_extra" "1")
17882 (set_attr "mode" "DI")])
17884 (define_expand "rdpmc"
17885 [(match_operand:DI 0 "register_operand" "")
17886 (match_operand:SI 1 "register_operand" "")]
17889 rtx reg = gen_reg_rtx (DImode);
17892 /* Force operand 1 into ECX. */
17893 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17894 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17895 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17900 rtvec vec = rtvec_alloc (2);
17901 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17902 rtx upper = gen_reg_rtx (DImode);
17903 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17904 gen_rtvec (1, const0_rtx),
17906 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17907 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17909 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17910 NULL, 1, OPTAB_DIRECT);
17911 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17915 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17916 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17920 (define_insn "*rdpmc"
17921 [(set (match_operand:DI 0 "register_operand" "=A")
17922 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17926 [(set_attr "type" "other")
17927 (set_attr "length" "2")])
17929 (define_insn "*rdpmc_rex64"
17930 [(set (match_operand:DI 0 "register_operand" "=a")
17931 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17933 (set (match_operand:DI 1 "register_operand" "=d")
17934 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17937 [(set_attr "type" "other")
17938 (set_attr "length" "2")])
17940 (define_expand "rdtsc"
17941 [(set (match_operand:DI 0 "register_operand" "")
17942 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17947 rtvec vec = rtvec_alloc (2);
17948 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17949 rtx upper = gen_reg_rtx (DImode);
17950 rtx lower = gen_reg_rtx (DImode);
17951 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17952 gen_rtvec (1, const0_rtx),
17954 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17955 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17957 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17958 NULL, 1, OPTAB_DIRECT);
17959 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17961 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17966 (define_insn "*rdtsc"
17967 [(set (match_operand:DI 0 "register_operand" "=A")
17968 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17971 [(set_attr "type" "other")
17972 (set_attr "length" "2")])
17974 (define_insn "*rdtsc_rex64"
17975 [(set (match_operand:DI 0 "register_operand" "=a")
17976 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17977 (set (match_operand:DI 1 "register_operand" "=d")
17978 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17981 [(set_attr "type" "other")
17982 (set_attr "length" "2")])
17984 (define_expand "rdtscp"
17985 [(match_operand:DI 0 "register_operand" "")
17986 (match_operand:SI 1 "memory_operand" "")]
17989 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17990 gen_rtvec (1, const0_rtx),
17992 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17993 gen_rtvec (1, const0_rtx),
17995 rtx reg = gen_reg_rtx (DImode);
17996 rtx tmp = gen_reg_rtx (SImode);
18000 rtvec vec = rtvec_alloc (3);
18001 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18002 rtx upper = gen_reg_rtx (DImode);
18003 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18004 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
18005 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
18007 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
18008 NULL, 1, OPTAB_DIRECT);
18009 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
18014 rtvec vec = rtvec_alloc (2);
18015 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
18016 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
18017 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
18020 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
18021 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18025 (define_insn "*rdtscp"
18026 [(set (match_operand:DI 0 "register_operand" "=A")
18027 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18028 (set (match_operand:SI 1 "register_operand" "=c")
18029 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18032 [(set_attr "type" "other")
18033 (set_attr "length" "3")])
18035 (define_insn "*rdtscp_rex64"
18036 [(set (match_operand:DI 0 "register_operand" "=a")
18037 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18038 (set (match_operand:DI 1 "register_operand" "=d")
18039 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18040 (set (match_operand:SI 2 "register_operand" "=c")
18041 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18044 [(set_attr "type" "other")
18045 (set_attr "length" "3")])
18047 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18049 ;; LWP instructions
18051 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18053 (define_expand "lwp_llwpcb"
18054 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18055 UNSPECV_LLWP_INTRINSIC)]
18058 (define_insn "*lwp_llwpcb<mode>1"
18059 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18060 UNSPECV_LLWP_INTRINSIC)]
18063 [(set_attr "type" "lwp")
18064 (set_attr "mode" "<MODE>")
18065 (set_attr "length" "5")])
18067 (define_expand "lwp_slwpcb"
18068 [(set (match_operand 0 "register_operand" "=r")
18069 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18074 insn = (TARGET_64BIT
18076 : gen_lwp_slwpcbsi);
18078 emit_insn (insn (operands[0]));
18082 (define_insn "lwp_slwpcb<mode>"
18083 [(set (match_operand:P 0 "register_operand" "=r")
18084 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18087 [(set_attr "type" "lwp")
18088 (set_attr "mode" "<MODE>")
18089 (set_attr "length" "5")])
18091 (define_expand "lwp_lwpval<mode>3"
18092 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18093 (match_operand:SI 2 "nonimmediate_operand" "rm")
18094 (match_operand:SI 3 "const_int_operand" "i")]
18095 UNSPECV_LWPVAL_INTRINSIC)]
18097 ;; Avoid unused variable warning.
18098 "(void) operands[0];")
18100 (define_insn "*lwp_lwpval<mode>3_1"
18101 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18102 (match_operand:SI 1 "nonimmediate_operand" "rm")
18103 (match_operand:SI 2 "const_int_operand" "i")]
18104 UNSPECV_LWPVAL_INTRINSIC)]
18106 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18107 [(set_attr "type" "lwp")
18108 (set_attr "mode" "<MODE>")
18109 (set (attr "length")
18110 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18112 (define_expand "lwp_lwpins<mode>3"
18113 [(set (reg:CCC FLAGS_REG)
18114 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18115 (match_operand:SI 2 "nonimmediate_operand" "rm")
18116 (match_operand:SI 3 "const_int_operand" "i")]
18117 UNSPECV_LWPINS_INTRINSIC))
18118 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18119 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18122 (define_insn "*lwp_lwpins<mode>3_1"
18123 [(set (reg:CCC FLAGS_REG)
18124 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18125 (match_operand:SI 1 "nonimmediate_operand" "rm")
18126 (match_operand:SI 2 "const_int_operand" "i")]
18127 UNSPECV_LWPINS_INTRINSIC))]
18129 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18130 [(set_attr "type" "lwp")
18131 (set_attr "mode" "<MODE>")
18132 (set (attr "length")
18133 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18135 (define_insn "rdfsbase<mode>"
18136 [(set (match_operand:SWI48 0 "register_operand" "=r")
18137 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18138 "TARGET_64BIT && TARGET_FSGSBASE"
18140 [(set_attr "type" "other")
18141 (set_attr "prefix_extra" "2")])
18143 (define_insn "rdgsbase<mode>"
18144 [(set (match_operand:SWI48 0 "register_operand" "=r")
18145 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18146 "TARGET_64BIT && TARGET_FSGSBASE"
18148 [(set_attr "type" "other")
18149 (set_attr "prefix_extra" "2")])
18151 (define_insn "wrfsbase<mode>"
18152 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18154 "TARGET_64BIT && TARGET_FSGSBASE"
18156 [(set_attr "type" "other")
18157 (set_attr "prefix_extra" "2")])
18159 (define_insn "wrgsbase<mode>"
18160 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18162 "TARGET_64BIT && TARGET_FSGSBASE"
18164 [(set_attr "type" "other")
18165 (set_attr "prefix_extra" "2")])
18167 (define_insn "rdrand<mode>_1"
18168 [(set (match_operand:SWI248 0 "register_operand" "=r")
18169 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18170 (set (reg:CCC FLAGS_REG)
18171 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18174 [(set_attr "type" "other")
18175 (set_attr "prefix_extra" "1")])
18177 (define_expand "pause"
18178 [(set (match_dup 0)
18179 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18182 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18183 MEM_VOLATILE_P (operands[0]) = 1;
18186 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18187 ;; They have the same encoding.
18188 (define_insn "*pause"
18189 [(set (match_operand:BLK 0 "" "")
18190 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18193 [(set_attr "length" "2")
18194 (set_attr "memory" "unknown")])
18198 (include "sync.md")