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
207 ;; Constants to represent rounding modes in the ROUND instruction
216 ;; Constants to represent pcomtrue/pcomfalse variants
226 ;; Constants used in the XOP pperm instruction
228 [(PPERM_SRC 0x00) /* copy source */
229 (PPERM_INVERT 0x20) /* invert source */
230 (PPERM_REVERSE 0x40) /* bit reverse source */
231 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
232 (PPERM_ZERO 0x80) /* all 0's */
233 (PPERM_ONES 0xa0) /* all 1's */
234 (PPERM_SIGN 0xc0) /* propagate sign bit */
235 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
236 (PPERM_SRC1 0x00) /* use first source byte */
237 (PPERM_SRC2 0x10) /* use second source byte */
240 ;; Registers by name.
293 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
296 ;; In C guard expressions, put expressions which may be compile-time
297 ;; constants first. This allows for better optimization. For
298 ;; example, write "TARGET_64BIT && reload_completed", not
299 ;; "reload_completed && TARGET_64BIT".
303 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
304 atom,generic64,amdfam10,bdver1,bdver2,btver1"
305 (const (symbol_ref "ix86_schedule")))
307 ;; A basic instruction type. Refinements due to arguments to be
308 ;; provided in other attributes.
311 alu,alu1,negnot,imov,imovx,lea,
312 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
313 icmp,test,ibr,setcc,icmov,
314 push,pop,call,callv,leave,
316 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
317 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
318 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
319 ssemuladd,sse4arg,lwp,
320 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
321 (const_string "other"))
323 ;; Main data type used by the insn
325 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
326 (const_string "unknown"))
328 ;; The CPU unit operations uses.
329 (define_attr "unit" "integer,i387,sse,mmx,unknown"
330 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
331 (const_string "i387")
332 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
333 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
334 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
336 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
338 (eq_attr "type" "other")
339 (const_string "unknown")]
340 (const_string "integer")))
342 ;; The (bounding maximum) length of an instruction immediate.
343 (define_attr "length_immediate" ""
344 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
347 (eq_attr "unit" "i387,sse,mmx")
349 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
350 rotate,rotatex,rotate1,imul,icmp,push,pop")
351 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
352 (eq_attr "type" "imov,test")
353 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
354 (eq_attr "type" "call")
355 (if_then_else (match_operand 0 "constant_call_address_operand" "")
358 (eq_attr "type" "callv")
359 (if_then_else (match_operand 1 "constant_call_address_operand" "")
362 ;; We don't know the size before shorten_branches. Expect
363 ;; the instruction to fit for better scheduling.
364 (eq_attr "type" "ibr")
367 (symbol_ref "/* Update immediate_length and other attributes! */
368 gcc_unreachable (),1")))
370 ;; The (bounding maximum) length of an instruction address.
371 (define_attr "length_address" ""
372 (cond [(eq_attr "type" "str,other,multi,fxch")
374 (and (eq_attr "type" "call")
375 (match_operand 0 "constant_call_address_operand" ""))
377 (and (eq_attr "type" "callv")
378 (match_operand 1 "constant_call_address_operand" ""))
381 (symbol_ref "ix86_attr_length_address_default (insn)")))
383 ;; Set when length prefix is used.
384 (define_attr "prefix_data16" ""
385 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
387 (eq_attr "mode" "HI")
389 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
394 ;; Set when string REP prefix is used.
395 (define_attr "prefix_rep" ""
396 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
398 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
403 ;; Set when 0f opcode prefix is used.
404 (define_attr "prefix_0f" ""
406 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
407 (eq_attr "unit" "sse,mmx"))
411 ;; Set when REX opcode prefix is used.
412 (define_attr "prefix_rex" ""
413 (cond [(not (match_test "TARGET_64BIT"))
415 (and (eq_attr "mode" "DI")
416 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
417 (eq_attr "unit" "!mmx")))
419 (and (eq_attr "mode" "QI")
420 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
422 (match_test "x86_extended_reg_mentioned_p (insn)")
424 (and (eq_attr "type" "imovx")
425 (match_operand:QI 1 "ext_QIreg_operand" ""))
430 ;; There are also additional prefixes in 3DNOW, SSSE3.
431 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
432 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
433 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
434 (define_attr "prefix_extra" ""
435 (cond [(eq_attr "type" "ssemuladd,sse4arg")
437 (eq_attr "type" "sseiadd1,ssecvt1")
442 ;; Prefix used: original, VEX or maybe VEX.
443 (define_attr "prefix" "orig,vex,maybe_vex"
444 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
446 (const_string "orig")))
448 ;; VEX W bit is used.
449 (define_attr "prefix_vex_w" "" (const_int 0))
451 ;; The length of VEX prefix
452 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
453 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
454 ;; still prefix_0f 1, with prefix_extra 1.
455 (define_attr "length_vex" ""
456 (if_then_else (and (eq_attr "prefix_0f" "1")
457 (eq_attr "prefix_extra" "0"))
458 (if_then_else (eq_attr "prefix_vex_w" "1")
459 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
460 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
461 (if_then_else (eq_attr "prefix_vex_w" "1")
462 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
463 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
465 ;; Set when modrm byte is used.
466 (define_attr "modrm" ""
467 (cond [(eq_attr "type" "str,leave")
469 (eq_attr "unit" "i387")
471 (and (eq_attr "type" "incdec")
472 (and (not (match_test "TARGET_64BIT"))
473 (ior (match_operand:SI 1 "register_operand" "")
474 (match_operand:HI 1 "register_operand" ""))))
476 (and (eq_attr "type" "push")
477 (not (match_operand 1 "memory_operand" "")))
479 (and (eq_attr "type" "pop")
480 (not (match_operand 0 "memory_operand" "")))
482 (and (eq_attr "type" "imov")
483 (and (not (eq_attr "mode" "DI"))
484 (ior (and (match_operand 0 "register_operand" "")
485 (match_operand 1 "immediate_operand" ""))
486 (ior (and (match_operand 0 "ax_reg_operand" "")
487 (match_operand 1 "memory_displacement_only_operand" ""))
488 (and (match_operand 0 "memory_displacement_only_operand" "")
489 (match_operand 1 "ax_reg_operand" ""))))))
491 (and (eq_attr "type" "call")
492 (match_operand 0 "constant_call_address_operand" ""))
494 (and (eq_attr "type" "callv")
495 (match_operand 1 "constant_call_address_operand" ""))
497 (and (eq_attr "type" "alu,alu1,icmp,test")
498 (match_operand 0 "ax_reg_operand" ""))
499 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
503 ;; The (bounding maximum) length of an instruction in bytes.
504 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
505 ;; Later we may want to split them and compute proper length as for
507 (define_attr "length" ""
508 (cond [(eq_attr "type" "other,multi,fistp,frndint")
510 (eq_attr "type" "fcmp")
512 (eq_attr "unit" "i387")
514 (plus (attr "prefix_data16")
515 (attr "length_address")))
516 (ior (eq_attr "prefix" "vex")
517 (and (eq_attr "prefix" "maybe_vex")
518 (match_test "TARGET_AVX")))
519 (plus (attr "length_vex")
520 (plus (attr "length_immediate")
522 (attr "length_address"))))]
523 (plus (plus (attr "modrm")
524 (plus (attr "prefix_0f")
525 (plus (attr "prefix_rex")
526 (plus (attr "prefix_extra")
528 (plus (attr "prefix_rep")
529 (plus (attr "prefix_data16")
530 (plus (attr "length_immediate")
531 (attr "length_address")))))))
533 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
534 ;; `store' if there is a simple memory reference therein, or `unknown'
535 ;; if the instruction is complex.
537 (define_attr "memory" "none,load,store,both,unknown"
538 (cond [(eq_attr "type" "other,multi,str,lwp")
539 (const_string "unknown")
540 (eq_attr "type" "lea,fcmov,fpspc")
541 (const_string "none")
542 (eq_attr "type" "fistp,leave")
543 (const_string "both")
544 (eq_attr "type" "frndint")
545 (const_string "load")
546 (eq_attr "type" "push")
547 (if_then_else (match_operand 1 "memory_operand" "")
548 (const_string "both")
549 (const_string "store"))
550 (eq_attr "type" "pop")
551 (if_then_else (match_operand 0 "memory_operand" "")
552 (const_string "both")
553 (const_string "load"))
554 (eq_attr "type" "setcc")
555 (if_then_else (match_operand 0 "memory_operand" "")
556 (const_string "store")
557 (const_string "none"))
558 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
559 (if_then_else (ior (match_operand 0 "memory_operand" "")
560 (match_operand 1 "memory_operand" ""))
561 (const_string "load")
562 (const_string "none"))
563 (eq_attr "type" "ibr")
564 (if_then_else (match_operand 0 "memory_operand" "")
565 (const_string "load")
566 (const_string "none"))
567 (eq_attr "type" "call")
568 (if_then_else (match_operand 0 "constant_call_address_operand" "")
569 (const_string "none")
570 (const_string "load"))
571 (eq_attr "type" "callv")
572 (if_then_else (match_operand 1 "constant_call_address_operand" "")
573 (const_string "none")
574 (const_string "load"))
575 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
576 (match_operand 1 "memory_operand" ""))
577 (const_string "both")
578 (and (match_operand 0 "memory_operand" "")
579 (match_operand 1 "memory_operand" ""))
580 (const_string "both")
581 (match_operand 0 "memory_operand" "")
582 (const_string "store")
583 (match_operand 1 "memory_operand" "")
584 (const_string "load")
586 "!alu1,negnot,ishift1,
587 imov,imovx,icmp,test,bitmanip,
589 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
590 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
591 (match_operand 2 "memory_operand" ""))
592 (const_string "load")
593 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
594 (match_operand 3 "memory_operand" ""))
595 (const_string "load")
597 (const_string "none")))
599 ;; Indicates if an instruction has both an immediate and a displacement.
601 (define_attr "imm_disp" "false,true,unknown"
602 (cond [(eq_attr "type" "other,multi")
603 (const_string "unknown")
604 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
605 (and (match_operand 0 "memory_displacement_operand" "")
606 (match_operand 1 "immediate_operand" "")))
607 (const_string "true")
608 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
609 (and (match_operand 0 "memory_displacement_operand" "")
610 (match_operand 2 "immediate_operand" "")))
611 (const_string "true")
613 (const_string "false")))
615 ;; Indicates if an FP operation has an integer source.
617 (define_attr "fp_int_src" "false,true"
618 (const_string "false"))
620 ;; Defines rounding mode of an FP operation.
622 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
623 (const_string "any"))
625 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
626 (define_attr "use_carry" "0,1" (const_string "0"))
628 ;; Define attribute to indicate unaligned ssemov insns
629 (define_attr "movu" "0,1" (const_string "0"))
631 ;; Used to control the "enabled" attribute on a per-instruction basis.
632 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,
634 (const_string "base"))
636 (define_attr "enabled" ""
637 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
638 (eq_attr "isa" "sse2_noavx")
639 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
640 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
641 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
642 (eq_attr "isa" "sse4_noavx")
643 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
644 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
645 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
646 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
647 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
648 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
652 ;; Describe a user's asm statement.
653 (define_asm_attributes
654 [(set_attr "length" "128")
655 (set_attr "type" "multi")])
657 (define_code_iterator plusminus [plus minus])
659 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
661 ;; Base name for define_insn
662 (define_code_attr plusminus_insn
663 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
664 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
666 ;; Base name for insn mnemonic.
667 (define_code_attr plusminus_mnemonic
668 [(plus "add") (ss_plus "adds") (us_plus "addus")
669 (minus "sub") (ss_minus "subs") (us_minus "subus")])
670 (define_code_attr plusminus_carry_mnemonic
671 [(plus "adc") (minus "sbb")])
673 ;; Mark commutative operators as such in constraints.
674 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
675 (minus "") (ss_minus "") (us_minus "")])
677 ;; Mapping of max and min
678 (define_code_iterator maxmin [smax smin umax umin])
680 ;; Mapping of signed max and min
681 (define_code_iterator smaxmin [smax smin])
683 ;; Mapping of unsigned max and min
684 (define_code_iterator umaxmin [umax umin])
686 ;; Base name for integer and FP insn mnemonic
687 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
688 (umax "maxu") (umin "minu")])
689 (define_code_attr maxmin_float [(smax "max") (smin "min")])
691 ;; Mapping of logic operators
692 (define_code_iterator any_logic [and ior xor])
693 (define_code_iterator any_or [ior xor])
695 ;; Base name for insn mnemonic.
696 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
698 ;; Mapping of logic-shift operators
699 (define_code_iterator any_lshift [ashift lshiftrt])
701 ;; Mapping of shift-right operators
702 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
704 ;; Base name for define_insn
705 (define_code_attr shift_insn
706 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
708 ;; Base name for insn mnemonic.
709 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
710 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
712 ;; Mapping of rotate operators
713 (define_code_iterator any_rotate [rotate rotatert])
715 ;; Base name for define_insn
716 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
718 ;; Base name for insn mnemonic.
719 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
721 ;; Mapping of abs neg operators
722 (define_code_iterator absneg [abs neg])
724 ;; Base name for x87 insn mnemonic.
725 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
727 ;; Used in signed and unsigned widening multiplications.
728 (define_code_iterator any_extend [sign_extend zero_extend])
730 ;; Prefix for insn menmonic.
731 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
733 ;; Prefix for define_insn
734 (define_code_attr u [(sign_extend "") (zero_extend "u")])
735 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
737 ;; All integer modes.
738 (define_mode_iterator SWI1248x [QI HI SI DI])
740 ;; All integer modes without QImode.
741 (define_mode_iterator SWI248x [HI SI DI])
743 ;; All integer modes without QImode and HImode.
744 (define_mode_iterator SWI48x [SI DI])
746 ;; All integer modes without SImode and DImode.
747 (define_mode_iterator SWI12 [QI HI])
749 ;; All integer modes without DImode.
750 (define_mode_iterator SWI124 [QI HI SI])
752 ;; All integer modes without QImode and DImode.
753 (define_mode_iterator SWI24 [HI SI])
755 ;; Single word integer modes.
756 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
758 ;; Single word integer modes without QImode.
759 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
761 ;; Single word integer modes without QImode and HImode.
762 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
764 ;; All math-dependant single and double word integer modes.
765 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
766 (HI "TARGET_HIMODE_MATH")
767 SI DI (TI "TARGET_64BIT")])
769 ;; Math-dependant single word integer modes.
770 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
771 (HI "TARGET_HIMODE_MATH")
772 SI (DI "TARGET_64BIT")])
774 ;; Math-dependant integer modes without DImode.
775 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
776 (HI "TARGET_HIMODE_MATH")
779 ;; Math-dependant single word integer modes without QImode.
780 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
781 SI (DI "TARGET_64BIT")])
783 ;; Double word integer modes.
784 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
785 (TI "TARGET_64BIT")])
787 ;; Double word integer modes as mode attribute.
788 (define_mode_attr DWI [(SI "DI") (DI "TI")])
789 (define_mode_attr dwi [(SI "di") (DI "ti")])
791 ;; Half mode for double word integer modes.
792 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
793 (DI "TARGET_64BIT")])
795 ;; Instruction suffix for integer modes.
796 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
798 ;; Pointer size prefix for integer modes (Intel asm dialect)
799 (define_mode_attr iptrsize [(QI "BYTE")
804 ;; Register class for integer modes.
805 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
807 ;; Immediate operand constraint for integer modes.
808 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
810 ;; General operand constraint for word modes.
811 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
813 ;; Immediate operand constraint for double integer modes.
814 (define_mode_attr di [(SI "nF") (DI "e")])
816 ;; Immediate operand constraint for shifts.
817 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
819 ;; General operand predicate for integer modes.
820 (define_mode_attr general_operand
821 [(QI "general_operand")
822 (HI "general_operand")
823 (SI "x86_64_general_operand")
824 (DI "x86_64_general_operand")
825 (TI "x86_64_general_operand")])
827 ;; General sign/zero extend operand predicate for integer modes.
828 (define_mode_attr general_szext_operand
829 [(QI "general_operand")
830 (HI "general_operand")
831 (SI "x86_64_szext_general_operand")
832 (DI "x86_64_szext_general_operand")])
834 ;; Immediate operand predicate for integer modes.
835 (define_mode_attr immediate_operand
836 [(QI "immediate_operand")
837 (HI "immediate_operand")
838 (SI "x86_64_immediate_operand")
839 (DI "x86_64_immediate_operand")])
841 ;; Nonmemory operand predicate for integer modes.
842 (define_mode_attr nonmemory_operand
843 [(QI "nonmemory_operand")
844 (HI "nonmemory_operand")
845 (SI "x86_64_nonmemory_operand")
846 (DI "x86_64_nonmemory_operand")])
848 ;; Operand predicate for shifts.
849 (define_mode_attr shift_operand
850 [(QI "nonimmediate_operand")
851 (HI "nonimmediate_operand")
852 (SI "nonimmediate_operand")
853 (DI "shiftdi_operand")
854 (TI "register_operand")])
856 ;; Operand predicate for shift argument.
857 (define_mode_attr shift_immediate_operand
858 [(QI "const_1_to_31_operand")
859 (HI "const_1_to_31_operand")
860 (SI "const_1_to_31_operand")
861 (DI "const_1_to_63_operand")])
863 ;; Input operand predicate for arithmetic left shifts.
864 (define_mode_attr ashl_input_operand
865 [(QI "nonimmediate_operand")
866 (HI "nonimmediate_operand")
867 (SI "nonimmediate_operand")
868 (DI "ashldi_input_operand")
869 (TI "reg_or_pm1_operand")])
871 ;; SSE and x87 SFmode and DFmode floating point modes
872 (define_mode_iterator MODEF [SF DF])
874 ;; All x87 floating point modes
875 (define_mode_iterator X87MODEF [SF DF XF])
877 ;; SSE instruction suffix for various modes
878 (define_mode_attr ssemodesuffix
880 (V8SF "ps") (V4DF "pd")
881 (V4SF "ps") (V2DF "pd")
882 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
883 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
885 ;; SSE vector suffix for floating point modes
886 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
888 ;; SSE vector mode corresponding to a scalar mode
889 (define_mode_attr ssevecmode
890 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
892 ;; Instruction suffix for REX 64bit operators.
893 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
895 ;; This mode iterator allows :P to be used for patterns that operate on
896 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
897 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
899 ;; This mode iterator allows :PTR to be used for patterns that operate on
900 ;; ptr_mode sized quantities.
901 (define_mode_iterator PTR
902 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
904 ;; Scheduling descriptions
906 (include "pentium.md")
909 (include "athlon.md")
910 (include "bdver1.md")
916 ;; Operand and operator predicates and constraints
918 (include "predicates.md")
919 (include "constraints.md")
922 ;; Compare and branch/compare and store instructions.
924 (define_expand "cbranch<mode>4"
925 [(set (reg:CC FLAGS_REG)
926 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
927 (match_operand:SDWIM 2 "<general_operand>" "")))
928 (set (pc) (if_then_else
929 (match_operator 0 "ordered_comparison_operator"
930 [(reg:CC FLAGS_REG) (const_int 0)])
931 (label_ref (match_operand 3 "" ""))
935 if (MEM_P (operands[1]) && MEM_P (operands[2]))
936 operands[1] = force_reg (<MODE>mode, operands[1]);
937 ix86_expand_branch (GET_CODE (operands[0]),
938 operands[1], operands[2], operands[3]);
942 (define_expand "cstore<mode>4"
943 [(set (reg:CC FLAGS_REG)
944 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
945 (match_operand:SWIM 3 "<general_operand>" "")))
946 (set (match_operand:QI 0 "register_operand" "")
947 (match_operator 1 "ordered_comparison_operator"
948 [(reg:CC FLAGS_REG) (const_int 0)]))]
951 if (MEM_P (operands[2]) && MEM_P (operands[3]))
952 operands[2] = force_reg (<MODE>mode, operands[2]);
953 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
954 operands[2], operands[3]);
958 (define_expand "cmp<mode>_1"
959 [(set (reg:CC FLAGS_REG)
960 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
961 (match_operand:SWI48 1 "<general_operand>" "")))])
963 (define_insn "*cmp<mode>_ccno_1"
964 [(set (reg FLAGS_REG)
965 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
966 (match_operand:SWI 1 "const0_operand" "")))]
967 "ix86_match_ccmode (insn, CCNOmode)"
969 test{<imodesuffix>}\t%0, %0
970 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
971 [(set_attr "type" "test,icmp")
972 (set_attr "length_immediate" "0,1")
973 (set_attr "mode" "<MODE>")])
975 (define_insn "*cmp<mode>_1"
976 [(set (reg FLAGS_REG)
977 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
978 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
979 "ix86_match_ccmode (insn, CCmode)"
980 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
981 [(set_attr "type" "icmp")
982 (set_attr "mode" "<MODE>")])
984 (define_insn "*cmp<mode>_minus_1"
985 [(set (reg FLAGS_REG)
987 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
988 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
990 "ix86_match_ccmode (insn, CCGOCmode)"
991 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
992 [(set_attr "type" "icmp")
993 (set_attr "mode" "<MODE>")])
995 (define_insn "*cmpqi_ext_1"
996 [(set (reg FLAGS_REG)
998 (match_operand:QI 0 "general_operand" "Qm")
1001 (match_operand 1 "ext_register_operand" "Q")
1003 (const_int 8)) 0)))]
1004 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1005 "cmp{b}\t{%h1, %0|%0, %h1}"
1006 [(set_attr "type" "icmp")
1007 (set_attr "mode" "QI")])
1009 (define_insn "*cmpqi_ext_1_rex64"
1010 [(set (reg FLAGS_REG)
1012 (match_operand:QI 0 "register_operand" "Q")
1015 (match_operand 1 "ext_register_operand" "Q")
1017 (const_int 8)) 0)))]
1018 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1019 "cmp{b}\t{%h1, %0|%0, %h1}"
1020 [(set_attr "type" "icmp")
1021 (set_attr "mode" "QI")])
1023 (define_insn "*cmpqi_ext_2"
1024 [(set (reg FLAGS_REG)
1028 (match_operand 0 "ext_register_operand" "Q")
1031 (match_operand:QI 1 "const0_operand" "")))]
1032 "ix86_match_ccmode (insn, CCNOmode)"
1034 [(set_attr "type" "test")
1035 (set_attr "length_immediate" "0")
1036 (set_attr "mode" "QI")])
1038 (define_expand "cmpqi_ext_3"
1039 [(set (reg:CC FLAGS_REG)
1043 (match_operand 0 "ext_register_operand" "")
1046 (match_operand:QI 1 "immediate_operand" "")))])
1048 (define_insn "*cmpqi_ext_3_insn"
1049 [(set (reg FLAGS_REG)
1053 (match_operand 0 "ext_register_operand" "Q")
1056 (match_operand:QI 1 "general_operand" "Qmn")))]
1057 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1058 "cmp{b}\t{%1, %h0|%h0, %1}"
1059 [(set_attr "type" "icmp")
1060 (set_attr "modrm" "1")
1061 (set_attr "mode" "QI")])
1063 (define_insn "*cmpqi_ext_3_insn_rex64"
1064 [(set (reg FLAGS_REG)
1068 (match_operand 0 "ext_register_operand" "Q")
1071 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1072 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1073 "cmp{b}\t{%1, %h0|%h0, %1}"
1074 [(set_attr "type" "icmp")
1075 (set_attr "modrm" "1")
1076 (set_attr "mode" "QI")])
1078 (define_insn "*cmpqi_ext_4"
1079 [(set (reg FLAGS_REG)
1083 (match_operand 0 "ext_register_operand" "Q")
1088 (match_operand 1 "ext_register_operand" "Q")
1090 (const_int 8)) 0)))]
1091 "ix86_match_ccmode (insn, CCmode)"
1092 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1093 [(set_attr "type" "icmp")
1094 (set_attr "mode" "QI")])
1096 ;; These implement float point compares.
1097 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1098 ;; which would allow mix and match FP modes on the compares. Which is what
1099 ;; the old patterns did, but with many more of them.
1101 (define_expand "cbranchxf4"
1102 [(set (reg:CC FLAGS_REG)
1103 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1104 (match_operand:XF 2 "nonmemory_operand" "")))
1105 (set (pc) (if_then_else
1106 (match_operator 0 "ix86_fp_comparison_operator"
1109 (label_ref (match_operand 3 "" ""))
1113 ix86_expand_branch (GET_CODE (operands[0]),
1114 operands[1], operands[2], operands[3]);
1118 (define_expand "cstorexf4"
1119 [(set (reg:CC FLAGS_REG)
1120 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1121 (match_operand:XF 3 "nonmemory_operand" "")))
1122 (set (match_operand:QI 0 "register_operand" "")
1123 (match_operator 1 "ix86_fp_comparison_operator"
1128 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1129 operands[2], operands[3]);
1133 (define_expand "cbranch<mode>4"
1134 [(set (reg:CC FLAGS_REG)
1135 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1136 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1137 (set (pc) (if_then_else
1138 (match_operator 0 "ix86_fp_comparison_operator"
1141 (label_ref (match_operand 3 "" ""))
1143 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1145 ix86_expand_branch (GET_CODE (operands[0]),
1146 operands[1], operands[2], operands[3]);
1150 (define_expand "cstore<mode>4"
1151 [(set (reg:CC FLAGS_REG)
1152 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1153 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1154 (set (match_operand:QI 0 "register_operand" "")
1155 (match_operator 1 "ix86_fp_comparison_operator"
1158 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1160 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1161 operands[2], operands[3]);
1165 (define_expand "cbranchcc4"
1166 [(set (pc) (if_then_else
1167 (match_operator 0 "comparison_operator"
1168 [(match_operand 1 "flags_reg_operand" "")
1169 (match_operand 2 "const0_operand" "")])
1170 (label_ref (match_operand 3 "" ""))
1174 ix86_expand_branch (GET_CODE (operands[0]),
1175 operands[1], operands[2], operands[3]);
1179 (define_expand "cstorecc4"
1180 [(set (match_operand:QI 0 "register_operand" "")
1181 (match_operator 1 "comparison_operator"
1182 [(match_operand 2 "flags_reg_operand" "")
1183 (match_operand 3 "const0_operand" "")]))]
1186 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1187 operands[2], operands[3]);
1192 ;; FP compares, step 1:
1193 ;; Set the FP condition codes.
1195 ;; CCFPmode compare with exceptions
1196 ;; CCFPUmode compare with no exceptions
1198 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1199 ;; used to manage the reg stack popping would not be preserved.
1201 (define_insn "*cmpfp_0"
1202 [(set (match_operand:HI 0 "register_operand" "=a")
1205 (match_operand 1 "register_operand" "f")
1206 (match_operand 2 "const0_operand" ""))]
1208 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1209 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1210 "* return output_fp_compare (insn, operands, false, false);"
1211 [(set_attr "type" "multi")
1212 (set_attr "unit" "i387")
1214 (cond [(match_operand:SF 1 "" "")
1216 (match_operand:DF 1 "" "")
1219 (const_string "XF")))])
1221 (define_insn_and_split "*cmpfp_0_cc"
1222 [(set (reg:CCFP FLAGS_REG)
1224 (match_operand 1 "register_operand" "f")
1225 (match_operand 2 "const0_operand" "")))
1226 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1227 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1228 && TARGET_SAHF && !TARGET_CMOVE
1229 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1231 "&& reload_completed"
1234 [(compare:CCFP (match_dup 1)(match_dup 2))]
1236 (set (reg:CC FLAGS_REG)
1237 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1239 [(set_attr "type" "multi")
1240 (set_attr "unit" "i387")
1242 (cond [(match_operand:SF 1 "" "")
1244 (match_operand:DF 1 "" "")
1247 (const_string "XF")))])
1249 (define_insn "*cmpfp_xf"
1250 [(set (match_operand:HI 0 "register_operand" "=a")
1253 (match_operand:XF 1 "register_operand" "f")
1254 (match_operand:XF 2 "register_operand" "f"))]
1257 "* return output_fp_compare (insn, operands, false, false);"
1258 [(set_attr "type" "multi")
1259 (set_attr "unit" "i387")
1260 (set_attr "mode" "XF")])
1262 (define_insn_and_split "*cmpfp_xf_cc"
1263 [(set (reg:CCFP FLAGS_REG)
1265 (match_operand:XF 1 "register_operand" "f")
1266 (match_operand:XF 2 "register_operand" "f")))
1267 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1269 && TARGET_SAHF && !TARGET_CMOVE"
1271 "&& reload_completed"
1274 [(compare:CCFP (match_dup 1)(match_dup 2))]
1276 (set (reg:CC FLAGS_REG)
1277 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1279 [(set_attr "type" "multi")
1280 (set_attr "unit" "i387")
1281 (set_attr "mode" "XF")])
1283 (define_insn "*cmpfp_<mode>"
1284 [(set (match_operand:HI 0 "register_operand" "=a")
1287 (match_operand:MODEF 1 "register_operand" "f")
1288 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1291 "* return output_fp_compare (insn, operands, false, false);"
1292 [(set_attr "type" "multi")
1293 (set_attr "unit" "i387")
1294 (set_attr "mode" "<MODE>")])
1296 (define_insn_and_split "*cmpfp_<mode>_cc"
1297 [(set (reg:CCFP FLAGS_REG)
1299 (match_operand:MODEF 1 "register_operand" "f")
1300 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1301 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1303 && TARGET_SAHF && !TARGET_CMOVE"
1305 "&& reload_completed"
1308 [(compare:CCFP (match_dup 1)(match_dup 2))]
1310 (set (reg:CC FLAGS_REG)
1311 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "mode" "<MODE>")])
1317 (define_insn "*cmpfp_u"
1318 [(set (match_operand:HI 0 "register_operand" "=a")
1321 (match_operand 1 "register_operand" "f")
1322 (match_operand 2 "register_operand" "f"))]
1324 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1325 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1326 "* return output_fp_compare (insn, operands, false, true);"
1327 [(set_attr "type" "multi")
1328 (set_attr "unit" "i387")
1330 (cond [(match_operand:SF 1 "" "")
1332 (match_operand:DF 1 "" "")
1335 (const_string "XF")))])
1337 (define_insn_and_split "*cmpfp_u_cc"
1338 [(set (reg:CCFPU FLAGS_REG)
1340 (match_operand 1 "register_operand" "f")
1341 (match_operand 2 "register_operand" "f")))
1342 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1343 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1344 && TARGET_SAHF && !TARGET_CMOVE
1345 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1347 "&& reload_completed"
1350 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1352 (set (reg:CC FLAGS_REG)
1353 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1355 [(set_attr "type" "multi")
1356 (set_attr "unit" "i387")
1358 (cond [(match_operand:SF 1 "" "")
1360 (match_operand:DF 1 "" "")
1363 (const_string "XF")))])
1365 (define_insn "*cmpfp_<mode>"
1366 [(set (match_operand:HI 0 "register_operand" "=a")
1369 (match_operand 1 "register_operand" "f")
1370 (match_operator 3 "float_operator"
1371 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1373 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1374 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1375 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1376 "* return output_fp_compare (insn, operands, false, false);"
1377 [(set_attr "type" "multi")
1378 (set_attr "unit" "i387")
1379 (set_attr "fp_int_src" "true")
1380 (set_attr "mode" "<MODE>")])
1382 (define_insn_and_split "*cmpfp_<mode>_cc"
1383 [(set (reg:CCFP FLAGS_REG)
1385 (match_operand 1 "register_operand" "f")
1386 (match_operator 3 "float_operator"
1387 [(match_operand:SWI24 2 "memory_operand" "m")])))
1388 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1389 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1390 && TARGET_SAHF && !TARGET_CMOVE
1391 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1392 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1394 "&& reload_completed"
1399 (match_op_dup 3 [(match_dup 2)]))]
1401 (set (reg:CC FLAGS_REG)
1402 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1404 [(set_attr "type" "multi")
1405 (set_attr "unit" "i387")
1406 (set_attr "fp_int_src" "true")
1407 (set_attr "mode" "<MODE>")])
1409 ;; FP compares, step 2
1410 ;; Move the fpsw to ax.
1412 (define_insn "x86_fnstsw_1"
1413 [(set (match_operand:HI 0 "register_operand" "=a")
1414 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1417 [(set (attr "length")
1418 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1419 (set_attr "mode" "SI")
1420 (set_attr "unit" "i387")])
1422 ;; FP compares, step 3
1423 ;; Get ax into flags, general case.
1425 (define_insn "x86_sahf_1"
1426 [(set (reg:CC FLAGS_REG)
1427 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1431 #ifndef HAVE_AS_IX86_SAHF
1433 return ASM_BYTE "0x9e";
1438 [(set_attr "length" "1")
1439 (set_attr "athlon_decode" "vector")
1440 (set_attr "amdfam10_decode" "direct")
1441 (set_attr "bdver1_decode" "direct")
1442 (set_attr "mode" "SI")])
1444 ;; Pentium Pro can do steps 1 through 3 in one go.
1445 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1446 ;; (these i387 instructions set flags directly)
1447 (define_insn "*cmpfp_i_mixed"
1448 [(set (reg:CCFP FLAGS_REG)
1449 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1450 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1451 "TARGET_MIX_SSE_I387
1452 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1453 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1454 "* return output_fp_compare (insn, operands, true, false);"
1455 [(set_attr "type" "fcmp,ssecomi")
1456 (set_attr "prefix" "orig,maybe_vex")
1458 (if_then_else (match_operand:SF 1 "" "")
1460 (const_string "DF")))
1461 (set (attr "prefix_rep")
1462 (if_then_else (eq_attr "type" "ssecomi")
1464 (const_string "*")))
1465 (set (attr "prefix_data16")
1466 (cond [(eq_attr "type" "fcmp")
1468 (eq_attr "mode" "DF")
1471 (const_string "0")))
1472 (set_attr "athlon_decode" "vector")
1473 (set_attr "amdfam10_decode" "direct")
1474 (set_attr "bdver1_decode" "double")])
1476 (define_insn "*cmpfp_i_sse"
1477 [(set (reg:CCFP FLAGS_REG)
1478 (compare:CCFP (match_operand 0 "register_operand" "x")
1479 (match_operand 1 "nonimmediate_operand" "xm")))]
1481 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1482 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1483 "* return output_fp_compare (insn, operands, true, false);"
1484 [(set_attr "type" "ssecomi")
1485 (set_attr "prefix" "maybe_vex")
1487 (if_then_else (match_operand:SF 1 "" "")
1489 (const_string "DF")))
1490 (set_attr "prefix_rep" "0")
1491 (set (attr "prefix_data16")
1492 (if_then_else (eq_attr "mode" "DF")
1494 (const_string "0")))
1495 (set_attr "athlon_decode" "vector")
1496 (set_attr "amdfam10_decode" "direct")
1497 (set_attr "bdver1_decode" "double")])
1499 (define_insn "*cmpfp_i_i387"
1500 [(set (reg:CCFP FLAGS_REG)
1501 (compare:CCFP (match_operand 0 "register_operand" "f")
1502 (match_operand 1 "register_operand" "f")))]
1503 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1505 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1506 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507 "* return output_fp_compare (insn, operands, true, false);"
1508 [(set_attr "type" "fcmp")
1510 (cond [(match_operand:SF 1 "" "")
1512 (match_operand:DF 1 "" "")
1515 (const_string "XF")))
1516 (set_attr "athlon_decode" "vector")
1517 (set_attr "amdfam10_decode" "direct")
1518 (set_attr "bdver1_decode" "double")])
1520 (define_insn "*cmpfp_iu_mixed"
1521 [(set (reg:CCFPU FLAGS_REG)
1522 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1523 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1524 "TARGET_MIX_SSE_I387
1525 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1526 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1527 "* return output_fp_compare (insn, operands, true, true);"
1528 [(set_attr "type" "fcmp,ssecomi")
1529 (set_attr "prefix" "orig,maybe_vex")
1531 (if_then_else (match_operand:SF 1 "" "")
1533 (const_string "DF")))
1534 (set (attr "prefix_rep")
1535 (if_then_else (eq_attr "type" "ssecomi")
1537 (const_string "*")))
1538 (set (attr "prefix_data16")
1539 (cond [(eq_attr "type" "fcmp")
1541 (eq_attr "mode" "DF")
1544 (const_string "0")))
1545 (set_attr "athlon_decode" "vector")
1546 (set_attr "amdfam10_decode" "direct")
1547 (set_attr "bdver1_decode" "double")])
1549 (define_insn "*cmpfp_iu_sse"
1550 [(set (reg:CCFPU FLAGS_REG)
1551 (compare:CCFPU (match_operand 0 "register_operand" "x")
1552 (match_operand 1 "nonimmediate_operand" "xm")))]
1554 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1555 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1556 "* return output_fp_compare (insn, operands, true, true);"
1557 [(set_attr "type" "ssecomi")
1558 (set_attr "prefix" "maybe_vex")
1560 (if_then_else (match_operand:SF 1 "" "")
1562 (const_string "DF")))
1563 (set_attr "prefix_rep" "0")
1564 (set (attr "prefix_data16")
1565 (if_then_else (eq_attr "mode" "DF")
1567 (const_string "0")))
1568 (set_attr "athlon_decode" "vector")
1569 (set_attr "amdfam10_decode" "direct")
1570 (set_attr "bdver1_decode" "double")])
1572 (define_insn "*cmpfp_iu_387"
1573 [(set (reg:CCFPU FLAGS_REG)
1574 (compare:CCFPU (match_operand 0 "register_operand" "f")
1575 (match_operand 1 "register_operand" "f")))]
1576 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1578 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1579 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1580 "* return output_fp_compare (insn, operands, true, true);"
1581 [(set_attr "type" "fcmp")
1583 (cond [(match_operand:SF 1 "" "")
1585 (match_operand:DF 1 "" "")
1588 (const_string "XF")))
1589 (set_attr "athlon_decode" "vector")
1590 (set_attr "amdfam10_decode" "direct")
1591 (set_attr "bdver1_decode" "direct")])
1593 ;; Push/pop instructions.
1595 (define_insn "*push<mode>2"
1596 [(set (match_operand:DWI 0 "push_operand" "=<")
1597 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1600 [(set_attr "type" "multi")
1601 (set_attr "mode" "<MODE>")])
1604 [(set (match_operand:TI 0 "push_operand" "")
1605 (match_operand:TI 1 "general_operand" ""))]
1606 "TARGET_64BIT && reload_completed
1607 && !SSE_REG_P (operands[1])"
1609 "ix86_split_long_move (operands); DONE;")
1611 (define_insn "*pushdi2_rex64"
1612 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1613 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1618 [(set_attr "type" "push,multi")
1619 (set_attr "mode" "DI")])
1621 ;; Convert impossible pushes of immediate to existing instructions.
1622 ;; First try to get scratch register and go through it. In case this
1623 ;; fails, push sign extended lower part first and then overwrite
1624 ;; upper part by 32bit move.
1626 [(match_scratch:DI 2 "r")
1627 (set (match_operand:DI 0 "push_operand" "")
1628 (match_operand:DI 1 "immediate_operand" ""))]
1629 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1630 && !x86_64_immediate_operand (operands[1], DImode)"
1631 [(set (match_dup 2) (match_dup 1))
1632 (set (match_dup 0) (match_dup 2))])
1634 ;; We need to define this as both peepholer and splitter for case
1635 ;; peephole2 pass is not run.
1636 ;; "&& 1" is needed to keep it from matching the previous pattern.
1638 [(set (match_operand:DI 0 "push_operand" "")
1639 (match_operand:DI 1 "immediate_operand" ""))]
1640 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1641 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1642 [(set (match_dup 0) (match_dup 1))
1643 (set (match_dup 2) (match_dup 3))]
1645 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1647 operands[1] = gen_lowpart (DImode, operands[2]);
1648 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1653 [(set (match_operand:DI 0 "push_operand" "")
1654 (match_operand:DI 1 "immediate_operand" ""))]
1655 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1656 ? epilogue_completed : reload_completed)
1657 && !symbolic_operand (operands[1], DImode)
1658 && !x86_64_immediate_operand (operands[1], DImode)"
1659 [(set (match_dup 0) (match_dup 1))
1660 (set (match_dup 2) (match_dup 3))]
1662 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1664 operands[1] = gen_lowpart (DImode, operands[2]);
1665 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1670 [(set (match_operand:DI 0 "push_operand" "")
1671 (match_operand:DI 1 "general_operand" ""))]
1672 "!TARGET_64BIT && reload_completed
1673 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1675 "ix86_split_long_move (operands); DONE;")
1677 (define_insn "*pushsi2"
1678 [(set (match_operand:SI 0 "push_operand" "=<")
1679 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1682 [(set_attr "type" "push")
1683 (set_attr "mode" "SI")])
1685 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1686 ;; "push a byte/word". But actually we use pushl, which has the effect
1687 ;; of rounding the amount pushed up to a word.
1689 ;; For TARGET_64BIT we always round up to 8 bytes.
1690 (define_insn "*push<mode>2_rex64"
1691 [(set (match_operand:SWI124 0 "push_operand" "=X")
1692 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1695 [(set_attr "type" "push")
1696 (set_attr "mode" "DI")])
1698 (define_insn "*push<mode>2"
1699 [(set (match_operand:SWI12 0 "push_operand" "=X")
1700 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1703 [(set_attr "type" "push")
1704 (set_attr "mode" "SI")])
1706 (define_insn "*push<mode>2_prologue"
1707 [(set (match_operand:P 0 "push_operand" "=<")
1708 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1709 (clobber (mem:BLK (scratch)))]
1711 "push{<imodesuffix>}\t%1"
1712 [(set_attr "type" "push")
1713 (set_attr "mode" "<MODE>")])
1715 (define_insn "*pop<mode>1"
1716 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1717 (match_operand:P 1 "pop_operand" ">"))]
1719 "pop{<imodesuffix>}\t%0"
1720 [(set_attr "type" "pop")
1721 (set_attr "mode" "<MODE>")])
1723 (define_insn "*pop<mode>1_epilogue"
1724 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1725 (match_operand:P 1 "pop_operand" ">"))
1726 (clobber (mem:BLK (scratch)))]
1728 "pop{<imodesuffix>}\t%0"
1729 [(set_attr "type" "pop")
1730 (set_attr "mode" "<MODE>")])
1732 ;; Move instructions.
1734 (define_expand "movoi"
1735 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1736 (match_operand:OI 1 "general_operand" ""))]
1738 "ix86_expand_move (OImode, operands); DONE;")
1740 (define_expand "movti"
1741 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1742 (match_operand:TI 1 "nonimmediate_operand" ""))]
1743 "TARGET_64BIT || TARGET_SSE"
1746 ix86_expand_move (TImode, operands);
1747 else if (push_operand (operands[0], TImode))
1748 ix86_expand_push (TImode, operands[1]);
1750 ix86_expand_vector_move (TImode, operands);
1754 ;; This expands to what emit_move_complex would generate if we didn't
1755 ;; have a movti pattern. Having this avoids problems with reload on
1756 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1757 ;; to have around all the time.
1758 (define_expand "movcdi"
1759 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1760 (match_operand:CDI 1 "general_operand" ""))]
1763 if (push_operand (operands[0], CDImode))
1764 emit_move_complex_push (CDImode, operands[0], operands[1]);
1766 emit_move_complex_parts (operands[0], operands[1]);
1770 (define_expand "mov<mode>"
1771 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1772 (match_operand:SWI1248x 1 "general_operand" ""))]
1774 "ix86_expand_move (<MODE>mode, operands); DONE;")
1776 (define_insn "*mov<mode>_xor"
1777 [(set (match_operand:SWI48 0 "register_operand" "=r")
1778 (match_operand:SWI48 1 "const0_operand" ""))
1779 (clobber (reg:CC FLAGS_REG))]
1782 [(set_attr "type" "alu1")
1783 (set_attr "mode" "SI")
1784 (set_attr "length_immediate" "0")])
1786 (define_insn "*mov<mode>_or"
1787 [(set (match_operand:SWI48 0 "register_operand" "=r")
1788 (match_operand:SWI48 1 "const_int_operand" ""))
1789 (clobber (reg:CC FLAGS_REG))]
1791 && operands[1] == constm1_rtx"
1792 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1793 [(set_attr "type" "alu1")
1794 (set_attr "mode" "<MODE>")
1795 (set_attr "length_immediate" "1")])
1797 (define_insn "*movoi_internal_avx"
1798 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1799 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1800 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1802 switch (which_alternative)
1805 return standard_sse_constant_opcode (insn, operands[1]);
1808 if (misaligned_operand (operands[0], OImode)
1809 || misaligned_operand (operands[1], OImode))
1810 return "vmovdqu\t{%1, %0|%0, %1}";
1812 return "vmovdqa\t{%1, %0|%0, %1}";
1817 [(set_attr "type" "sselog1,ssemov,ssemov")
1818 (set_attr "prefix" "vex")
1819 (set_attr "mode" "OI")])
1821 (define_insn "*movti_internal_rex64"
1822 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,m")
1823 (match_operand:TI 1 "general_operand" "riFo,re,C,xm,x"))]
1824 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1826 switch (which_alternative)
1832 return standard_sse_constant_opcode (insn, operands[1]);
1835 /* TDmode values are passed as TImode on the stack. Moving them
1836 to stack may result in unaligned memory access. */
1837 if (misaligned_operand (operands[0], TImode)
1838 || misaligned_operand (operands[1], TImode))
1840 if (get_attr_mode (insn) == MODE_V4SF)
1841 return "%vmovups\t{%1, %0|%0, %1}";
1843 return "%vmovdqu\t{%1, %0|%0, %1}";
1847 if (get_attr_mode (insn) == MODE_V4SF)
1848 return "%vmovaps\t{%1, %0|%0, %1}";
1850 return "%vmovdqa\t{%1, %0|%0, %1}";
1856 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1857 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1859 (cond [(eq_attr "alternative" "0,1")
1861 (ior (not (match_test "TARGET_SSE2"))
1862 (match_test "optimize_function_for_size_p (cfun)"))
1863 (const_string "V4SF")
1864 (and (eq_attr "alternative" "4")
1865 (match_test "TARGET_SSE_TYPELESS_STORES"))
1866 (const_string "V4SF")
1868 (const_string "TI")))])
1871 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1872 (match_operand:TI 1 "general_operand" ""))]
1874 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1876 "ix86_split_long_move (operands); DONE;")
1878 (define_insn "*movti_internal_sse"
1879 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1880 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1881 "TARGET_SSE && !TARGET_64BIT
1882 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1884 switch (which_alternative)
1887 return standard_sse_constant_opcode (insn, operands[1]);
1890 /* TDmode values are passed as TImode on the stack. Moving them
1891 to stack may result in unaligned memory access. */
1892 if (misaligned_operand (operands[0], TImode)
1893 || misaligned_operand (operands[1], TImode))
1895 if (get_attr_mode (insn) == MODE_V4SF)
1896 return "%vmovups\t{%1, %0|%0, %1}";
1898 return "%vmovdqu\t{%1, %0|%0, %1}";
1902 if (get_attr_mode (insn) == MODE_V4SF)
1903 return "%vmovaps\t{%1, %0|%0, %1}";
1905 return "%vmovdqa\t{%1, %0|%0, %1}";
1911 [(set_attr "type" "sselog1,ssemov,ssemov")
1912 (set_attr "prefix" "maybe_vex")
1914 (cond [(ior (not (match_test "TARGET_SSE2"))
1915 (match_test "optimize_function_for_size_p (cfun)"))
1916 (const_string "V4SF")
1917 (and (eq_attr "alternative" "2")
1918 (match_test "TARGET_SSE_TYPELESS_STORES"))
1919 (const_string "V4SF")]
1920 (const_string "TI")))])
1922 (define_insn "*movdi_internal_rex64"
1923 [(set (match_operand:DI 0 "nonimmediate_operand"
1924 "=r,r ,r,m ,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1925 (match_operand:DI 1 "general_operand"
1926 "Z ,rem,i,re,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1927 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1929 switch (get_attr_type (insn))
1932 if (SSE_REG_P (operands[0]))
1933 return "movq2dq\t{%1, %0|%0, %1}";
1935 return "movdq2q\t{%1, %0|%0, %1}";
1938 if (get_attr_mode (insn) == MODE_TI)
1939 return "%vmovdqa\t{%1, %0|%0, %1}";
1940 /* Handle broken assemblers that require movd instead of movq. */
1941 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1942 return "%vmovd\t{%1, %0|%0, %1}";
1944 return "%vmovq\t{%1, %0|%0, %1}";
1947 /* Handle broken assemblers that require movd instead of movq. */
1948 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1949 return "movd\t{%1, %0|%0, %1}";
1951 return "movq\t{%1, %0|%0, %1}";
1954 return standard_sse_constant_opcode (insn, operands[1]);
1957 return "pxor\t%0, %0";
1960 return "lea{q}\t{%E1, %0|%0, %E1}";
1963 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1964 if (get_attr_mode (insn) == MODE_SI)
1965 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1966 else if (which_alternative == 2)
1967 return "movabs{q}\t{%1, %0|%0, %1}";
1968 else if (ix86_use_lea_for_mov (insn, operands))
1969 return "lea{q}\t{%E1, %0|%0, %E1}";
1971 return "mov{q}\t{%1, %0|%0, %1}";
1975 (cond [(eq_attr "alternative" "4")
1976 (const_string "mmx")
1977 (eq_attr "alternative" "5,6,7,8")
1978 (const_string "mmxmov")
1979 (eq_attr "alternative" "9")
1980 (const_string "sselog1")
1981 (eq_attr "alternative" "10,11,12,13,14")
1982 (const_string "ssemov")
1983 (eq_attr "alternative" "15,16")
1984 (const_string "ssecvt")
1985 (match_operand 1 "pic_32bit_operand" "")
1986 (const_string "lea")
1988 (const_string "imov")))
1991 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1993 (const_string "*")))
1994 (set (attr "length_immediate")
1996 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1998 (const_string "*")))
1999 (set (attr "prefix_rex")
2000 (if_then_else (eq_attr "alternative" "7,8")
2002 (const_string "*")))
2003 (set (attr "prefix_data16")
2004 (if_then_else (eq_attr "alternative" "10")
2006 (const_string "*")))
2007 (set (attr "prefix")
2008 (if_then_else (eq_attr "alternative" "11,12,13,14,15")
2009 (const_string "maybe_vex")
2010 (const_string "orig")))
2011 (set_attr "mode" "SI,DI,DI,DI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2013 ;; Reload patterns to support multi-word load/store
2014 ;; with non-offsetable address.
2015 (define_expand "reload_noff_store"
2016 [(parallel [(match_operand 0 "memory_operand" "=m")
2017 (match_operand 1 "register_operand" "r")
2018 (match_operand:DI 2 "register_operand" "=&r")])]
2021 rtx mem = operands[0];
2022 rtx addr = XEXP (mem, 0);
2024 emit_move_insn (operands[2], addr);
2025 mem = replace_equiv_address_nv (mem, operands[2]);
2027 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2031 (define_expand "reload_noff_load"
2032 [(parallel [(match_operand 0 "register_operand" "=r")
2033 (match_operand 1 "memory_operand" "m")
2034 (match_operand:DI 2 "register_operand" "=r")])]
2037 rtx mem = operands[1];
2038 rtx addr = XEXP (mem, 0);
2040 emit_move_insn (operands[2], addr);
2041 mem = replace_equiv_address_nv (mem, operands[2]);
2043 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2047 (define_insn "*movdi_internal"
2048 [(set (match_operand:DI 0 "nonimmediate_operand"
2049 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2050 (match_operand:DI 1 "general_operand"
2051 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2052 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2054 switch (get_attr_type (insn))
2057 if (SSE_REG_P (operands[0]))
2058 return "movq2dq\t{%1, %0|%0, %1}";
2060 return "movdq2q\t{%1, %0|%0, %1}";
2063 switch (get_attr_mode (insn))
2066 return "%vmovdqa\t{%1, %0|%0, %1}";
2068 return "%vmovq\t{%1, %0|%0, %1}";
2070 return "movaps\t{%1, %0|%0, %1}";
2072 return "movlps\t{%1, %0|%0, %1}";
2078 return "movq\t{%1, %0|%0, %1}";
2081 return standard_sse_constant_opcode (insn, operands[1]);
2084 return "pxor\t%0, %0";
2094 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2095 (const_string "sse2")
2096 (eq_attr "alternative" "9,10,11,12")
2097 (const_string "noavx")
2099 (const_string "*")))
2101 (cond [(eq_attr "alternative" "0,1")
2102 (const_string "multi")
2103 (eq_attr "alternative" "2")
2104 (const_string "mmx")
2105 (eq_attr "alternative" "3,4")
2106 (const_string "mmxmov")
2107 (eq_attr "alternative" "5,9")
2108 (const_string "sselog1")
2109 (eq_attr "alternative" "13,14")
2110 (const_string "ssecvt")
2112 (const_string "ssemov")))
2113 (set (attr "prefix")
2114 (if_then_else (eq_attr "alternative" "5,6,7,8")
2115 (const_string "maybe_vex")
2116 (const_string "orig")))
2117 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2120 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2121 (match_operand:DI 1 "general_operand" ""))]
2122 "!TARGET_64BIT && reload_completed
2123 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2124 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2126 "ix86_split_long_move (operands); DONE;")
2128 (define_insn "*movsi_internal"
2129 [(set (match_operand:SI 0 "nonimmediate_operand"
2130 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2131 (match_operand:SI 1 "general_operand"
2132 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2133 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2135 switch (get_attr_type (insn))
2138 return standard_sse_constant_opcode (insn, operands[1]);
2141 switch (get_attr_mode (insn))
2144 return "%vmovdqa\t{%1, %0|%0, %1}";
2146 return "%vmovaps\t{%1, %0|%0, %1}";
2148 return "%vmovd\t{%1, %0|%0, %1}";
2150 return "%vmovss\t{%1, %0|%0, %1}";
2156 return "pxor\t%0, %0";
2159 if (get_attr_mode (insn) == MODE_DI)
2160 return "movq\t{%1, %0|%0, %1}";
2161 return "movd\t{%1, %0|%0, %1}";
2164 return "lea{l}\t{%E1, %0|%0, %E1}";
2167 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2168 if (ix86_use_lea_for_mov (insn, operands))
2169 return "lea{l}\t{%E1, %0|%0, %E1}";
2171 return "mov{l}\t{%1, %0|%0, %1}";
2175 (cond [(eq_attr "alternative" "2")
2176 (const_string "mmx")
2177 (eq_attr "alternative" "3,4,5")
2178 (const_string "mmxmov")
2179 (eq_attr "alternative" "6")
2180 (const_string "sselog1")
2181 (eq_attr "alternative" "7,8,9,10,11")
2182 (const_string "ssemov")
2183 (match_operand 1 "pic_32bit_operand" "")
2184 (const_string "lea")
2186 (const_string "imov")))
2187 (set (attr "prefix")
2188 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2189 (const_string "orig")
2190 (const_string "maybe_vex")))
2191 (set (attr "prefix_data16")
2192 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2194 (const_string "*")))
2196 (cond [(eq_attr "alternative" "2,3")
2198 (eq_attr "alternative" "6,7")
2200 (not (match_test "TARGET_SSE2"))
2201 (const_string "V4SF")
2202 (const_string "TI"))
2203 (and (eq_attr "alternative" "8,9,10,11")
2204 (not (match_test "TARGET_SSE2")))
2207 (const_string "SI")))])
2209 (define_insn "*movhi_internal"
2210 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2211 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2212 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2214 switch (get_attr_type (insn))
2217 /* movzwl is faster than movw on p2 due to partial word stalls,
2218 though not as fast as an aligned movl. */
2219 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2221 if (get_attr_mode (insn) == MODE_SI)
2222 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2224 return "mov{w}\t{%1, %0|%0, %1}";
2228 (cond [(match_test "optimize_function_for_size_p (cfun)")
2229 (const_string "imov")
2230 (and (eq_attr "alternative" "0")
2231 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2232 (not (match_test "TARGET_HIMODE_MATH"))))
2233 (const_string "imov")
2234 (and (eq_attr "alternative" "1,2")
2235 (match_operand:HI 1 "aligned_operand" ""))
2236 (const_string "imov")
2237 (and (match_test "TARGET_MOVX")
2238 (eq_attr "alternative" "0,2"))
2239 (const_string "imovx")
2241 (const_string "imov")))
2243 (cond [(eq_attr "type" "imovx")
2245 (and (eq_attr "alternative" "1,2")
2246 (match_operand:HI 1 "aligned_operand" ""))
2248 (and (eq_attr "alternative" "0")
2249 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2250 (not (match_test "TARGET_HIMODE_MATH"))))
2253 (const_string "HI")))])
2255 ;; Situation is quite tricky about when to choose full sized (SImode) move
2256 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2257 ;; partial register dependency machines (such as AMD Athlon), where QImode
2258 ;; moves issue extra dependency and for partial register stalls machines
2259 ;; that don't use QImode patterns (and QImode move cause stall on the next
2262 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2263 ;; register stall machines with, where we use QImode instructions, since
2264 ;; partial register stall can be caused there. Then we use movzx.
2265 (define_insn "*movqi_internal"
2266 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2267 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2268 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2270 switch (get_attr_type (insn))
2273 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2274 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2276 if (get_attr_mode (insn) == MODE_SI)
2277 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2279 return "mov{b}\t{%1, %0|%0, %1}";
2283 (cond [(and (eq_attr "alternative" "5")
2284 (not (match_operand:QI 1 "aligned_operand" "")))
2285 (const_string "imovx")
2286 (match_test "optimize_function_for_size_p (cfun)")
2287 (const_string "imov")
2288 (and (eq_attr "alternative" "3")
2289 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2290 (not (match_test "TARGET_QIMODE_MATH"))))
2291 (const_string "imov")
2292 (eq_attr "alternative" "3,5")
2293 (const_string "imovx")
2294 (and (match_test "TARGET_MOVX")
2295 (eq_attr "alternative" "2"))
2296 (const_string "imovx")
2298 (const_string "imov")))
2300 (cond [(eq_attr "alternative" "3,4,5")
2302 (eq_attr "alternative" "6")
2304 (eq_attr "type" "imovx")
2306 (and (eq_attr "type" "imov")
2307 (and (eq_attr "alternative" "0,1")
2308 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2309 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2310 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2312 ;; Avoid partial register stalls when not using QImode arithmetic
2313 (and (eq_attr "type" "imov")
2314 (and (eq_attr "alternative" "0,1")
2315 (and (match_test "TARGET_PARTIAL_REG_STALL")
2316 (not (match_test "TARGET_QIMODE_MATH")))))
2319 (const_string "QI")))])
2321 ;; Stores and loads of ax to arbitrary constant address.
2322 ;; We fake an second form of instruction to force reload to load address
2323 ;; into register when rax is not available
2324 (define_insn "*movabs<mode>_1"
2325 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2326 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2327 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2329 movabs{<imodesuffix>}\t{%1, %P0|[%P0], %1}
2330 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2331 [(set_attr "type" "imov")
2332 (set_attr "modrm" "0,*")
2333 (set_attr "length_address" "8,0")
2334 (set_attr "length_immediate" "0,*")
2335 (set_attr "memory" "store")
2336 (set_attr "mode" "<MODE>")])
2338 (define_insn "*movabs<mode>_2"
2339 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2340 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2341 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2343 movabs{<imodesuffix>}\t{%P1, %0|%0, [%P1]}
2344 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2345 [(set_attr "type" "imov")
2346 (set_attr "modrm" "0,*")
2347 (set_attr "length_address" "8,0")
2348 (set_attr "length_immediate" "0")
2349 (set_attr "memory" "load")
2350 (set_attr "mode" "<MODE>")])
2352 (define_insn "*swap<mode>"
2353 [(set (match_operand:SWI48 0 "register_operand" "+r")
2354 (match_operand:SWI48 1 "register_operand" "+r"))
2358 "xchg{<imodesuffix>}\t%1, %0"
2359 [(set_attr "type" "imov")
2360 (set_attr "mode" "<MODE>")
2361 (set_attr "pent_pair" "np")
2362 (set_attr "athlon_decode" "vector")
2363 (set_attr "amdfam10_decode" "double")
2364 (set_attr "bdver1_decode" "double")])
2366 (define_insn "*swap<mode>_1"
2367 [(set (match_operand:SWI12 0 "register_operand" "+r")
2368 (match_operand:SWI12 1 "register_operand" "+r"))
2371 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2373 [(set_attr "type" "imov")
2374 (set_attr "mode" "SI")
2375 (set_attr "pent_pair" "np")
2376 (set_attr "athlon_decode" "vector")
2377 (set_attr "amdfam10_decode" "double")
2378 (set_attr "bdver1_decode" "double")])
2380 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2381 ;; is disabled for AMDFAM10
2382 (define_insn "*swap<mode>_2"
2383 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2384 (match_operand:SWI12 1 "register_operand" "+<r>"))
2387 "TARGET_PARTIAL_REG_STALL"
2388 "xchg{<imodesuffix>}\t%1, %0"
2389 [(set_attr "type" "imov")
2390 (set_attr "mode" "<MODE>")
2391 (set_attr "pent_pair" "np")
2392 (set_attr "athlon_decode" "vector")])
2394 (define_expand "movstrict<mode>"
2395 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2396 (match_operand:SWI12 1 "general_operand" ""))]
2399 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2401 if (GET_CODE (operands[0]) == SUBREG
2402 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2404 /* Don't generate memory->memory moves, go through a register */
2405 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2406 operands[1] = force_reg (<MODE>mode, operands[1]);
2409 (define_insn "*movstrict<mode>_1"
2410 [(set (strict_low_part
2411 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2412 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2413 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2414 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2415 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2416 [(set_attr "type" "imov")
2417 (set_attr "mode" "<MODE>")])
2419 (define_insn "*movstrict<mode>_xor"
2420 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2421 (match_operand:SWI12 1 "const0_operand" ""))
2422 (clobber (reg:CC FLAGS_REG))]
2424 "xor{<imodesuffix>}\t%0, %0"
2425 [(set_attr "type" "alu1")
2426 (set_attr "mode" "<MODE>")
2427 (set_attr "length_immediate" "0")])
2429 (define_insn "*mov<mode>_extv_1"
2430 [(set (match_operand:SWI24 0 "register_operand" "=R")
2431 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2435 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2436 [(set_attr "type" "imovx")
2437 (set_attr "mode" "SI")])
2439 (define_insn "*movqi_extv_1_rex64"
2440 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2441 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2446 switch (get_attr_type (insn))
2449 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2451 return "mov{b}\t{%h1, %0|%0, %h1}";
2455 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2456 (match_test "TARGET_MOVX"))
2457 (const_string "imovx")
2458 (const_string "imov")))
2460 (if_then_else (eq_attr "type" "imovx")
2462 (const_string "QI")))])
2464 (define_insn "*movqi_extv_1"
2465 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2466 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2471 switch (get_attr_type (insn))
2474 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2476 return "mov{b}\t{%h1, %0|%0, %h1}";
2480 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2481 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2482 (match_test "TARGET_MOVX")))
2483 (const_string "imovx")
2484 (const_string "imov")))
2486 (if_then_else (eq_attr "type" "imovx")
2488 (const_string "QI")))])
2490 (define_insn "*mov<mode>_extzv_1"
2491 [(set (match_operand:SWI48 0 "register_operand" "=R")
2492 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2496 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2497 [(set_attr "type" "imovx")
2498 (set_attr "mode" "SI")])
2500 (define_insn "*movqi_extzv_2_rex64"
2501 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2503 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2508 switch (get_attr_type (insn))
2511 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2513 return "mov{b}\t{%h1, %0|%0, %h1}";
2517 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2518 (match_test "TARGET_MOVX"))
2519 (const_string "imovx")
2520 (const_string "imov")))
2522 (if_then_else (eq_attr "type" "imovx")
2524 (const_string "QI")))])
2526 (define_insn "*movqi_extzv_2"
2527 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2529 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2534 switch (get_attr_type (insn))
2537 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2539 return "mov{b}\t{%h1, %0|%0, %h1}";
2543 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2544 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2545 (match_test "TARGET_MOVX")))
2546 (const_string "imovx")
2547 (const_string "imov")))
2549 (if_then_else (eq_attr "type" "imovx")
2551 (const_string "QI")))])
2553 (define_expand "mov<mode>_insv_1"
2554 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2557 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2559 (define_insn "*mov<mode>_insv_1_rex64"
2560 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2563 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2566 if (CONST_INT_P (operands[1]))
2567 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2568 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2570 [(set_attr "type" "imov")
2571 (set_attr "mode" "QI")])
2573 (define_insn "*movsi_insv_1"
2574 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2577 (match_operand:SI 1 "general_operand" "Qmn"))]
2580 if (CONST_INT_P (operands[1]))
2581 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2582 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2584 [(set_attr "type" "imov")
2585 (set_attr "mode" "QI")])
2587 (define_insn "*movqi_insv_2"
2588 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2591 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2594 "mov{b}\t{%h1, %h0|%h0, %h1}"
2595 [(set_attr "type" "imov")
2596 (set_attr "mode" "QI")])
2598 ;; Floating point push instructions.
2600 (define_insn "*pushtf"
2601 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2602 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2605 /* This insn should be already split before reg-stack. */
2608 [(set_attr "type" "multi")
2609 (set_attr "unit" "sse,*,*")
2610 (set_attr "mode" "TF,SI,SI")])
2612 ;; %%% Kill this when call knows how to work this out.
2614 [(set (match_operand:TF 0 "push_operand" "")
2615 (match_operand:TF 1 "sse_reg_operand" ""))]
2616 "TARGET_SSE2 && reload_completed"
2617 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2618 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2620 (define_insn "*pushxf"
2621 [(set (match_operand:XF 0 "push_operand" "=<,<")
2622 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2623 "optimize_function_for_speed_p (cfun)"
2625 /* This insn should be already split before reg-stack. */
2628 [(set_attr "type" "multi")
2629 (set_attr "unit" "i387,*")
2630 (set_attr "mode" "XF,SI")])
2632 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2633 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2634 ;; Pushing using integer instructions is longer except for constants
2635 ;; and direct memory references (assuming that any given constant is pushed
2636 ;; only once, but this ought to be handled elsewhere).
2638 (define_insn "*pushxf_nointeger"
2639 [(set (match_operand:XF 0 "push_operand" "=<,<")
2640 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2641 "optimize_function_for_size_p (cfun)"
2643 /* This insn should be already split before reg-stack. */
2646 [(set_attr "type" "multi")
2647 (set_attr "unit" "i387,*")
2648 (set_attr "mode" "XF,SI")])
2650 ;; %%% Kill this when call knows how to work this out.
2652 [(set (match_operand:XF 0 "push_operand" "")
2653 (match_operand:XF 1 "fp_register_operand" ""))]
2655 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2656 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2657 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2659 (define_insn "*pushdf_rex64"
2660 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2661 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2664 /* This insn should be already split before reg-stack. */
2667 [(set_attr "type" "multi")
2668 (set_attr "unit" "i387,*,*")
2669 (set_attr "mode" "DF,DI,DF")])
2671 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2672 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2673 ;; On the average, pushdf using integers can be still shorter.
2675 (define_insn "*pushdf"
2676 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2677 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2680 /* This insn should be already split before reg-stack. */
2683 [(set_attr "isa" "*,*,sse2")
2684 (set_attr "type" "multi")
2685 (set_attr "unit" "i387,*,*")
2686 (set_attr "mode" "DF,DI,DF")])
2688 ;; %%% Kill this when call knows how to work this out.
2690 [(set (match_operand:DF 0 "push_operand" "")
2691 (match_operand:DF 1 "any_fp_register_operand" ""))]
2693 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2694 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2696 (define_insn "*pushsf_rex64"
2697 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2698 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2701 /* Anything else should be already split before reg-stack. */
2702 gcc_assert (which_alternative == 1);
2703 return "push{q}\t%q1";
2705 [(set_attr "type" "multi,push,multi")
2706 (set_attr "unit" "i387,*,*")
2707 (set_attr "mode" "SF,DI,SF")])
2709 (define_insn "*pushsf"
2710 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2711 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2714 /* Anything else should be already split before reg-stack. */
2715 gcc_assert (which_alternative == 1);
2716 return "push{l}\t%1";
2718 [(set_attr "type" "multi,push,multi")
2719 (set_attr "unit" "i387,*,*")
2720 (set_attr "mode" "SF,SI,SF")])
2722 ;; %%% Kill this when call knows how to work this out.
2724 [(set (match_operand:SF 0 "push_operand" "")
2725 (match_operand:SF 1 "any_fp_register_operand" ""))]
2727 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2728 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2729 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2732 [(set (match_operand:SF 0 "push_operand" "")
2733 (match_operand:SF 1 "memory_operand" ""))]
2735 && (operands[2] = find_constant_src (insn))"
2736 [(set (match_dup 0) (match_dup 2))])
2739 [(set (match_operand 0 "push_operand" "")
2740 (match_operand 1 "general_operand" ""))]
2742 && (GET_MODE (operands[0]) == TFmode
2743 || GET_MODE (operands[0]) == XFmode
2744 || GET_MODE (operands[0]) == DFmode)
2745 && !ANY_FP_REG_P (operands[1])"
2747 "ix86_split_long_move (operands); DONE;")
2749 ;; Floating point move instructions.
2751 (define_expand "movtf"
2752 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2753 (match_operand:TF 1 "nonimmediate_operand" ""))]
2754 "TARGET_64BIT || TARGET_SSE2"
2756 ix86_expand_move (TFmode, operands);
2760 (define_expand "mov<mode>"
2761 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2762 (match_operand:X87MODEF 1 "general_operand" ""))]
2764 "ix86_expand_move (<MODE>mode, operands); DONE;")
2766 (define_insn "*movtf_internal_rex64"
2767 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2768 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,*r"))]
2769 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2770 && (!can_create_pseudo_p ()
2771 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2772 || GET_CODE (operands[1]) != CONST_DOUBLE
2773 || (optimize_function_for_size_p (cfun)
2774 && standard_sse_constant_p (operands[1])
2775 && !memory_operand (operands[0], TFmode))
2776 || (!TARGET_MEMORY_MISMATCH_STALL
2777 && memory_operand (operands[0], TFmode)))"
2779 switch (which_alternative)
2783 /* Handle misaligned load/store since we
2784 don't have movmisaligntf pattern. */
2785 if (misaligned_operand (operands[0], TFmode)
2786 || misaligned_operand (operands[1], TFmode))
2788 if (get_attr_mode (insn) == MODE_V4SF)
2789 return "%vmovups\t{%1, %0|%0, %1}";
2791 return "%vmovdqu\t{%1, %0|%0, %1}";
2795 if (get_attr_mode (insn) == MODE_V4SF)
2796 return "%vmovaps\t{%1, %0|%0, %1}";
2798 return "%vmovdqa\t{%1, %0|%0, %1}";
2802 return standard_sse_constant_opcode (insn, operands[1]);
2812 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2813 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2815 (cond [(eq_attr "alternative" "0,2")
2817 (match_test "optimize_function_for_size_p (cfun)")
2818 (const_string "V4SF")
2819 (const_string "TI"))
2820 (eq_attr "alternative" "1")
2822 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2823 (match_test "optimize_function_for_size_p (cfun)"))
2824 (const_string "V4SF")
2825 (const_string "TI"))]
2826 (const_string "DI")))])
2828 (define_insn "*movtf_internal_sse2"
2829 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x")
2830 (match_operand:TF 1 "general_operand" "xm,x,C"))]
2831 "TARGET_SSE2 && !TARGET_64BIT
2832 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2833 && (!can_create_pseudo_p ()
2834 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2835 || GET_CODE (operands[1]) != CONST_DOUBLE
2836 || (optimize_function_for_size_p (cfun)
2837 && standard_sse_constant_p (operands[1])
2838 && !memory_operand (operands[0], TFmode))
2839 || (!TARGET_MEMORY_MISMATCH_STALL
2840 && memory_operand (operands[0], TFmode)))"
2842 switch (which_alternative)
2846 /* Handle misaligned load/store since we
2847 don't have movmisaligntf pattern. */
2848 if (misaligned_operand (operands[0], TFmode)
2849 || misaligned_operand (operands[1], TFmode))
2851 if (get_attr_mode (insn) == MODE_V4SF)
2852 return "%vmovups\t{%1, %0|%0, %1}";
2854 return "%vmovdqu\t{%1, %0|%0, %1}";
2858 if (get_attr_mode (insn) == MODE_V4SF)
2859 return "%vmovaps\t{%1, %0|%0, %1}";
2861 return "%vmovdqa\t{%1, %0|%0, %1}";
2865 return standard_sse_constant_opcode (insn, operands[1]);
2871 [(set_attr "type" "ssemov,ssemov,sselog1")
2872 (set_attr "prefix" "maybe_vex")
2874 (cond [(eq_attr "alternative" "0,2")
2876 (match_test "optimize_function_for_size_p (cfun)")
2877 (const_string "V4SF")
2878 (const_string "TI"))
2879 (eq_attr "alternative" "1")
2881 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2882 (match_test "optimize_function_for_size_p (cfun)"))
2883 (const_string "V4SF")
2884 (const_string "TI"))]
2885 (const_string "DI")))])
2887 (define_insn "*movxf_internal_rex64"
2888 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2889 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rC"))]
2890 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2891 && (!can_create_pseudo_p ()
2892 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2893 || GET_CODE (operands[1]) != CONST_DOUBLE
2894 || (optimize_function_for_size_p (cfun)
2895 && standard_80387_constant_p (operands[1]) > 0
2896 && !memory_operand (operands[0], XFmode))
2897 || (!TARGET_MEMORY_MISMATCH_STALL
2898 && memory_operand (operands[0], XFmode)))"
2900 switch (which_alternative)
2904 return output_387_reg_move (insn, operands);
2907 return standard_80387_constant_opcode (operands[1]);
2917 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2918 (set_attr "mode" "XF,XF,XF,SI,SI")])
2920 ;; Possible store forwarding (partial memory) stall in alternative 4.
2921 (define_insn "*movxf_internal"
2922 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2923 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,Yx*rF"))]
2924 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2925 && (!can_create_pseudo_p ()
2926 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2927 || GET_CODE (operands[1]) != CONST_DOUBLE
2928 || (optimize_function_for_size_p (cfun)
2929 && standard_80387_constant_p (operands[1]) > 0
2930 && !memory_operand (operands[0], XFmode))
2931 || (!TARGET_MEMORY_MISMATCH_STALL
2932 && memory_operand (operands[0], XFmode)))"
2934 switch (which_alternative)
2938 return output_387_reg_move (insn, operands);
2941 return standard_80387_constant_opcode (operands[1]);
2951 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2952 (set_attr "mode" "XF,XF,XF,SI,SI")])
2954 (define_insn "*movdf_internal_rex64"
2955 [(set (match_operand:DF 0 "nonimmediate_operand"
2956 "=?Yf*f,?m ,?Yf*f,?r,?m,?r,?r,x,x,x,m,Yi,r ")
2957 (match_operand:DF 1 "general_operand"
2958 "Yf*fm ,Yf*f ,G ,rm,rC,C ,F ,C,x,m,x,r ,Yi"))]
2959 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2960 && (!can_create_pseudo_p ()
2961 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2962 || GET_CODE (operands[1]) != CONST_DOUBLE
2963 || (optimize_function_for_size_p (cfun)
2964 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2965 && standard_80387_constant_p (operands[1]) > 0)
2966 || (TARGET_SSE2 && TARGET_SSE_MATH
2967 && standard_sse_constant_p (operands[1]))))
2968 || memory_operand (operands[0], DFmode))"
2970 switch (which_alternative)
2974 return output_387_reg_move (insn, operands);
2977 return standard_80387_constant_opcode (operands[1]);
2981 return "mov{q}\t{%1, %0|%0, %1}";
2984 return "mov{l}\t{%1, %k0|%k0, %1}";
2987 return "movabs{q}\t{%1, %0|%0, %1}";
2990 return standard_sse_constant_opcode (insn, operands[1]);
2995 switch (get_attr_mode (insn))
2998 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2999 return "%vmovapd\t{%1, %0|%0, %1}";
3001 return "%vmovaps\t{%1, %0|%0, %1}";
3004 return "%vmovq\t{%1, %0|%0, %1}";
3006 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3007 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3008 return "%vmovsd\t{%1, %0|%0, %1}";
3010 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3012 return "%vmovlps\t{%1, %d0|%d0, %1}";
3019 /* Handle broken assemblers that require movd instead of movq. */
3020 return "%vmovd\t{%1, %0|%0, %1}";
3027 (cond [(eq_attr "alternative" "0,1,2")
3028 (const_string "fmov")
3029 (eq_attr "alternative" "3,4,5,6")
3030 (const_string "imov")
3031 (eq_attr "alternative" "7")
3032 (const_string "sselog1")
3034 (const_string "ssemov")))
3037 (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3039 (const_string "*")))
3040 (set (attr "length_immediate")
3042 (and (eq_attr "alternative" "6") (eq_attr "type" "imov"))
3044 (const_string "*")))
3045 (set (attr "prefix")
3046 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
3047 (const_string "orig")
3048 (const_string "maybe_vex")))
3049 (set (attr "prefix_data16")
3050 (if_then_else (eq_attr "mode" "V1DF")
3052 (const_string "*")))
3054 (cond [(eq_attr "alternative" "0,1,2")
3056 (eq_attr "alternative" "3,4,6,11,12")
3058 (eq_attr "alternative" "5")
3061 /* xorps is one byte shorter. */
3062 (eq_attr "alternative" "7")
3063 (cond [(match_test "optimize_function_for_size_p (cfun)")
3064 (const_string "V4SF")
3065 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3068 (const_string "V2DF"))
3070 /* For architectures resolving dependencies on
3071 whole SSE registers use APD move to break dependency
3072 chains, otherwise use short move to avoid extra work.
3074 movaps encodes one byte shorter. */
3075 (eq_attr "alternative" "8")
3077 [(match_test "optimize_function_for_size_p (cfun)")
3078 (const_string "V4SF")
3079 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3080 (const_string "V2DF")
3082 (const_string "DF"))
3083 /* For architectures resolving dependencies on register
3084 parts we may avoid extra work to zero out upper part
3086 (eq_attr "alternative" "9")
3088 (match_test "TARGET_SSE_SPLIT_REGS")
3089 (const_string "V1DF")
3090 (const_string "DF"))
3092 (const_string "DF")))])
3094 ;; Possible store forwarding (partial memory) stall in alternative 4.
3095 (define_insn "*movdf_internal"
3096 [(set (match_operand:DF 0 "nonimmediate_operand"
3097 "=Yf*f,m ,Yf*f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3098 (match_operand:DF 1 "general_operand"
3099 "Yf*fm,Yf*f,G ,Yd*roF,Yd*rF,C,x,m,x,C ,*x,m ,*x"))]
3100 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3101 && (!can_create_pseudo_p ()
3102 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3103 || GET_CODE (operands[1]) != CONST_DOUBLE
3104 || (optimize_function_for_size_p (cfun)
3105 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3106 && standard_80387_constant_p (operands[1]) > 0)
3107 || (TARGET_SSE2 && TARGET_SSE_MATH
3108 && standard_sse_constant_p (operands[1])))
3109 && !memory_operand (operands[0], DFmode))
3110 || (!TARGET_MEMORY_MISMATCH_STALL
3111 && memory_operand (operands[0], DFmode)))"
3113 switch (which_alternative)
3117 return output_387_reg_move (insn, operands);
3120 return standard_80387_constant_opcode (operands[1]);
3128 return standard_sse_constant_opcode (insn, operands[1]);
3136 switch (get_attr_mode (insn))
3139 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3140 return "%vmovapd\t{%1, %0|%0, %1}";
3142 return "%vmovaps\t{%1, %0|%0, %1}";
3145 return "%vmovq\t{%1, %0|%0, %1}";
3147 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3148 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3149 return "%vmovsd\t{%1, %0|%0, %1}";
3151 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3153 return "%vmovlps\t{%1, %d0|%d0, %1}";
3163 (if_then_else (eq_attr "alternative" "5,6,7,8")
3164 (const_string "sse2")
3165 (const_string "*")))
3167 (cond [(eq_attr "alternative" "0,1,2")
3168 (const_string "fmov")
3169 (eq_attr "alternative" "3,4")
3170 (const_string "multi")
3171 (eq_attr "alternative" "5,9")
3172 (const_string "sselog1")
3174 (const_string "ssemov")))
3175 (set (attr "prefix")
3176 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3177 (const_string "orig")
3178 (const_string "maybe_vex")))
3179 (set (attr "prefix_data16")
3180 (if_then_else (eq_attr "mode" "V1DF")
3182 (const_string "*")))
3184 (cond [(eq_attr "alternative" "0,1,2")
3186 (eq_attr "alternative" "3,4")
3189 /* For SSE1, we have many fewer alternatives. */
3190 (not (match_test "TARGET_SSE2"))
3192 (eq_attr "alternative" "5,6,9,10")
3193 (const_string "V4SF")
3194 (const_string "V2SF"))
3196 /* xorps is one byte shorter. */
3197 (eq_attr "alternative" "5,9")
3198 (cond [(match_test "optimize_function_for_size_p (cfun)")
3199 (const_string "V4SF")
3200 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3203 (const_string "V2DF"))
3205 /* For architectures resolving dependencies on
3206 whole SSE registers use APD move to break dependency
3207 chains, otherwise use short move to avoid extra work.
3209 movaps encodes one byte shorter. */
3210 (eq_attr "alternative" "6,10")
3212 [(match_test "optimize_function_for_size_p (cfun)")
3213 (const_string "V4SF")
3214 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3215 (const_string "V2DF")
3217 (const_string "DF"))
3218 /* For architectures resolving dependencies on register
3219 parts we may avoid extra work to zero out upper part
3221 (eq_attr "alternative" "7,11")
3223 (match_test "TARGET_SSE_SPLIT_REGS")
3224 (const_string "V1DF")
3225 (const_string "DF"))
3227 (const_string "DF")))])
3229 (define_insn "*movsf_internal"
3230 [(set (match_operand:SF 0 "nonimmediate_operand"
3231 "=Yf*f,m ,Yf*f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3232 (match_operand:SF 1 "general_operand"
3233 "Yf*fm,Yf*f,G ,rmF,rF,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3234 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3235 && (!can_create_pseudo_p ()
3236 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3237 || GET_CODE (operands[1]) != CONST_DOUBLE
3238 || (optimize_function_for_size_p (cfun)
3239 && ((!TARGET_SSE_MATH
3240 && standard_80387_constant_p (operands[1]) > 0)
3242 && standard_sse_constant_p (operands[1]))))
3243 || memory_operand (operands[0], SFmode))"
3245 switch (which_alternative)
3249 return output_387_reg_move (insn, operands);
3252 return standard_80387_constant_opcode (operands[1]);
3256 return "mov{l}\t{%1, %0|%0, %1}";
3259 return standard_sse_constant_opcode (insn, operands[1]);
3262 if (get_attr_mode (insn) == MODE_V4SF)
3263 return "%vmovaps\t{%1, %0|%0, %1}";
3265 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3269 return "%vmovss\t{%1, %0|%0, %1}";
3275 return "movd\t{%1, %0|%0, %1}";
3278 return "movq\t{%1, %0|%0, %1}";
3282 return "%vmovd\t{%1, %0|%0, %1}";
3289 (cond [(eq_attr "alternative" "0,1,2")
3290 (const_string "fmov")
3291 (eq_attr "alternative" "3,4")
3292 (const_string "imov")
3293 (eq_attr "alternative" "5")
3294 (const_string "sselog1")
3295 (eq_attr "alternative" "9,10,11,14,15")
3296 (const_string "mmxmov")
3298 (const_string "ssemov")))
3299 (set (attr "prefix")
3300 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3301 (const_string "maybe_vex")
3302 (const_string "orig")))
3304 (cond [(eq_attr "alternative" "3,4,9,10")
3306 (eq_attr "alternative" "5")
3308 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3309 (match_test "TARGET_SSE2"))
3310 (not (match_test "optimize_function_for_size_p (cfun)")))
3312 (const_string "V4SF"))
3313 /* For architectures resolving dependencies on
3314 whole SSE registers use APS move to break dependency
3315 chains, otherwise use short move to avoid extra work.
3317 Do the same for architectures resolving dependencies on
3318 the parts. While in DF mode it is better to always handle
3319 just register parts, the SF mode is different due to lack
3320 of instructions to load just part of the register. It is
3321 better to maintain the whole registers in single format
3322 to avoid problems on using packed logical operations. */
3323 (eq_attr "alternative" "6")
3325 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3326 (match_test "TARGET_SSE_SPLIT_REGS"))
3327 (const_string "V4SF")
3328 (const_string "SF"))
3329 (eq_attr "alternative" "11")
3330 (const_string "DI")]
3331 (const_string "SF")))])
3334 [(set (match_operand 0 "any_fp_register_operand" "")
3335 (match_operand 1 "memory_operand" ""))]
3337 && (GET_MODE (operands[0]) == TFmode
3338 || GET_MODE (operands[0]) == XFmode
3339 || GET_MODE (operands[0]) == DFmode
3340 || GET_MODE (operands[0]) == SFmode)
3341 && (operands[2] = find_constant_src (insn))"
3342 [(set (match_dup 0) (match_dup 2))]
3344 rtx c = operands[2];
3345 int r = REGNO (operands[0]);
3347 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3348 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3353 [(set (match_operand 0 "any_fp_register_operand" "")
3354 (float_extend (match_operand 1 "memory_operand" "")))]
3356 && (GET_MODE (operands[0]) == TFmode
3357 || GET_MODE (operands[0]) == XFmode
3358 || GET_MODE (operands[0]) == DFmode)
3359 && (operands[2] = find_constant_src (insn))"
3360 [(set (match_dup 0) (match_dup 2))]
3362 rtx c = operands[2];
3363 int r = REGNO (operands[0]);
3365 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3366 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3370 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3372 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3373 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3375 && (standard_80387_constant_p (operands[1]) == 8
3376 || standard_80387_constant_p (operands[1]) == 9)"
3377 [(set (match_dup 0)(match_dup 1))
3379 (neg:X87MODEF (match_dup 0)))]
3383 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3384 if (real_isnegzero (&r))
3385 operands[1] = CONST0_RTX (<MODE>mode);
3387 operands[1] = CONST1_RTX (<MODE>mode);
3391 [(set (match_operand 0 "nonimmediate_operand" "")
3392 (match_operand 1 "general_operand" ""))]
3394 && (GET_MODE (operands[0]) == TFmode
3395 || GET_MODE (operands[0]) == XFmode
3396 || GET_MODE (operands[0]) == DFmode)
3397 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3399 "ix86_split_long_move (operands); DONE;")
3401 (define_insn "swapxf"
3402 [(set (match_operand:XF 0 "register_operand" "+f")
3403 (match_operand:XF 1 "register_operand" "+f"))
3408 if (STACK_TOP_P (operands[0]))
3413 [(set_attr "type" "fxch")
3414 (set_attr "mode" "XF")])
3416 (define_insn "*swap<mode>"
3417 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3418 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3421 "TARGET_80387 || reload_completed"
3423 if (STACK_TOP_P (operands[0]))
3428 [(set_attr "type" "fxch")
3429 (set_attr "mode" "<MODE>")])
3431 ;; Zero extension instructions
3433 (define_expand "zero_extendsidi2"
3434 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3435 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3440 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3445 (define_insn "*zero_extendsidi2_rex64"
3446 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?!*y,?*Yi,*x")
3448 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3451 mov{l}\t{%1, %k0|%k0, %1}
3453 movd\t{%1, %0|%0, %1}
3454 movd\t{%1, %0|%0, %1}
3455 %vmovd\t{%1, %0|%0, %1}
3456 %vmovd\t{%1, %0|%0, %1}"
3457 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3458 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3459 (set_attr "prefix_0f" "0,*,*,*,*,*")
3460 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3463 [(set (match_operand:DI 0 "memory_operand" "")
3464 (zero_extend:DI (match_dup 0)))]
3466 [(set (match_dup 4) (const_int 0))]
3467 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3469 ;; %%% Kill me once multi-word ops are sane.
3470 (define_insn "zero_extendsidi2_1"
3471 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?!*y,?*Yi,*x")
3473 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3474 (clobber (reg:CC FLAGS_REG))]
3480 movd\t{%1, %0|%0, %1}
3481 movd\t{%1, %0|%0, %1}
3482 %vmovd\t{%1, %0|%0, %1}
3483 %vmovd\t{%1, %0|%0, %1}"
3484 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3485 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3486 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3487 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3490 [(set (match_operand:DI 0 "register_operand" "")
3491 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3492 (clobber (reg:CC FLAGS_REG))]
3493 "!TARGET_64BIT && reload_completed
3494 && true_regnum (operands[0]) == true_regnum (operands[1])"
3495 [(set (match_dup 4) (const_int 0))]
3496 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3499 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3500 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3501 (clobber (reg:CC FLAGS_REG))]
3502 "!TARGET_64BIT && reload_completed
3503 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3504 [(set (match_dup 3) (match_dup 1))
3505 (set (match_dup 4) (const_int 0))]
3506 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3508 (define_insn "zero_extend<mode>di2"
3509 [(set (match_operand:DI 0 "register_operand" "=r")
3511 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3513 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3514 [(set_attr "type" "imovx")
3515 (set_attr "mode" "SI")])
3517 (define_expand "zero_extendhisi2"
3518 [(set (match_operand:SI 0 "register_operand" "")
3519 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3522 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3524 operands[1] = force_reg (HImode, operands[1]);
3525 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3530 (define_insn_and_split "zero_extendhisi2_and"
3531 [(set (match_operand:SI 0 "register_operand" "=r")
3532 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3533 (clobber (reg:CC FLAGS_REG))]
3534 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3536 "&& reload_completed"
3537 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3538 (clobber (reg:CC FLAGS_REG))])]
3540 [(set_attr "type" "alu1")
3541 (set_attr "mode" "SI")])
3543 (define_insn "*zero_extendhisi2_movzwl"
3544 [(set (match_operand:SI 0 "register_operand" "=r")
3545 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3546 "!TARGET_ZERO_EXTEND_WITH_AND
3547 || optimize_function_for_size_p (cfun)"
3548 "movz{wl|x}\t{%1, %0|%0, %1}"
3549 [(set_attr "type" "imovx")
3550 (set_attr "mode" "SI")])
3552 (define_expand "zero_extendqi<mode>2"
3554 [(set (match_operand:SWI24 0 "register_operand" "")
3555 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3556 (clobber (reg:CC FLAGS_REG))])])
3558 (define_insn "*zero_extendqi<mode>2_and"
3559 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3560 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3561 (clobber (reg:CC FLAGS_REG))]
3562 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3564 [(set_attr "type" "alu1")
3565 (set_attr "mode" "<MODE>")])
3567 ;; When source and destination does not overlap, clear destination
3568 ;; first and then do the movb
3570 [(set (match_operand:SWI24 0 "register_operand" "")
3571 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3572 (clobber (reg:CC FLAGS_REG))]
3574 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3575 && ANY_QI_REG_P (operands[0])
3576 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3577 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3578 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3580 operands[2] = gen_lowpart (QImode, operands[0]);
3581 ix86_expand_clear (operands[0]);
3584 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3585 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3586 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3587 (clobber (reg:CC FLAGS_REG))]
3588 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3590 [(set_attr "type" "imovx,alu1")
3591 (set_attr "mode" "<MODE>")])
3593 ;; For the movzbl case strip only the clobber
3595 [(set (match_operand:SWI24 0 "register_operand" "")
3596 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3597 (clobber (reg:CC FLAGS_REG))]
3599 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3600 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3602 (zero_extend:SWI24 (match_dup 1)))])
3604 ; zero extend to SImode to avoid partial register stalls
3605 (define_insn "*zero_extendqi<mode>2_movzbl"
3606 [(set (match_operand:SWI24 0 "register_operand" "=r")
3607 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3609 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3610 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3611 [(set_attr "type" "imovx")
3612 (set_attr "mode" "SI")])
3614 ;; Rest is handled by single and.
3616 [(set (match_operand:SWI24 0 "register_operand" "")
3617 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3618 (clobber (reg:CC FLAGS_REG))]
3620 && true_regnum (operands[0]) == true_regnum (operands[1])"
3621 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3622 (clobber (reg:CC FLAGS_REG))])])
3624 ;; Sign extension instructions
3626 (define_expand "extendsidi2"
3627 [(set (match_operand:DI 0 "register_operand" "")
3628 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3633 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3638 (define_insn "*extendsidi2_rex64"
3639 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3640 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3644 movs{lq|x}\t{%1, %0|%0, %1}"
3645 [(set_attr "type" "imovx")
3646 (set_attr "mode" "DI")
3647 (set_attr "prefix_0f" "0")
3648 (set_attr "modrm" "0,1")])
3650 (define_insn "extendsidi2_1"
3651 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3652 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3653 (clobber (reg:CC FLAGS_REG))
3654 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3658 ;; Extend to memory case when source register does die.
3660 [(set (match_operand:DI 0 "memory_operand" "")
3661 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3662 (clobber (reg:CC FLAGS_REG))
3663 (clobber (match_operand:SI 2 "register_operand" ""))]
3665 && dead_or_set_p (insn, operands[1])
3666 && !reg_mentioned_p (operands[1], operands[0]))"
3667 [(set (match_dup 3) (match_dup 1))
3668 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3669 (clobber (reg:CC FLAGS_REG))])
3670 (set (match_dup 4) (match_dup 1))]
3671 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3673 ;; Extend to memory case when source register does not die.
3675 [(set (match_operand:DI 0 "memory_operand" "")
3676 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3677 (clobber (reg:CC FLAGS_REG))
3678 (clobber (match_operand:SI 2 "register_operand" ""))]
3682 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3684 emit_move_insn (operands[3], operands[1]);
3686 /* Generate a cltd if possible and doing so it profitable. */
3687 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3688 && true_regnum (operands[1]) == AX_REG
3689 && true_regnum (operands[2]) == DX_REG)
3691 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3695 emit_move_insn (operands[2], operands[1]);
3696 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3698 emit_move_insn (operands[4], operands[2]);
3702 ;; Extend to register case. Optimize case where source and destination
3703 ;; registers match and cases where we can use cltd.
3705 [(set (match_operand:DI 0 "register_operand" "")
3706 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3707 (clobber (reg:CC FLAGS_REG))
3708 (clobber (match_scratch:SI 2 ""))]
3712 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3714 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3715 emit_move_insn (operands[3], operands[1]);
3717 /* Generate a cltd if possible and doing so it profitable. */
3718 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3719 && true_regnum (operands[3]) == AX_REG
3720 && true_regnum (operands[4]) == DX_REG)
3722 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3726 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3727 emit_move_insn (operands[4], operands[1]);
3729 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3733 (define_insn "extend<mode>di2"
3734 [(set (match_operand:DI 0 "register_operand" "=r")
3736 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3738 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3739 [(set_attr "type" "imovx")
3740 (set_attr "mode" "DI")])
3742 (define_insn "extendhisi2"
3743 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3744 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3747 switch (get_attr_prefix_0f (insn))
3750 return "{cwtl|cwde}";
3752 return "movs{wl|x}\t{%1, %0|%0, %1}";
3755 [(set_attr "type" "imovx")
3756 (set_attr "mode" "SI")
3757 (set (attr "prefix_0f")
3758 ;; movsx is short decodable while cwtl is vector decoded.
3759 (if_then_else (and (eq_attr "cpu" "!k6")
3760 (eq_attr "alternative" "0"))
3762 (const_string "1")))
3764 (if_then_else (eq_attr "prefix_0f" "0")
3766 (const_string "1")))])
3768 (define_insn "*extendhisi2_zext"
3769 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3772 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3775 switch (get_attr_prefix_0f (insn))
3778 return "{cwtl|cwde}";
3780 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3783 [(set_attr "type" "imovx")
3784 (set_attr "mode" "SI")
3785 (set (attr "prefix_0f")
3786 ;; movsx is short decodable while cwtl is vector decoded.
3787 (if_then_else (and (eq_attr "cpu" "!k6")
3788 (eq_attr "alternative" "0"))
3790 (const_string "1")))
3792 (if_then_else (eq_attr "prefix_0f" "0")
3794 (const_string "1")))])
3796 (define_insn "extendqisi2"
3797 [(set (match_operand:SI 0 "register_operand" "=r")
3798 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3800 "movs{bl|x}\t{%1, %0|%0, %1}"
3801 [(set_attr "type" "imovx")
3802 (set_attr "mode" "SI")])
3804 (define_insn "*extendqisi2_zext"
3805 [(set (match_operand:DI 0 "register_operand" "=r")
3807 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3809 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3810 [(set_attr "type" "imovx")
3811 (set_attr "mode" "SI")])
3813 (define_insn "extendqihi2"
3814 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3815 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3818 switch (get_attr_prefix_0f (insn))
3821 return "{cbtw|cbw}";
3823 return "movs{bw|x}\t{%1, %0|%0, %1}";
3826 [(set_attr "type" "imovx")
3827 (set_attr "mode" "HI")
3828 (set (attr "prefix_0f")
3829 ;; movsx is short decodable while cwtl is vector decoded.
3830 (if_then_else (and (eq_attr "cpu" "!k6")
3831 (eq_attr "alternative" "0"))
3833 (const_string "1")))
3835 (if_then_else (eq_attr "prefix_0f" "0")
3837 (const_string "1")))])
3839 ;; Conversions between float and double.
3841 ;; These are all no-ops in the model used for the 80387.
3842 ;; So just emit moves.
3844 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3846 [(set (match_operand:DF 0 "push_operand" "")
3847 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3849 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3850 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3853 [(set (match_operand:XF 0 "push_operand" "")
3854 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3856 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3857 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3858 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3860 (define_expand "extendsfdf2"
3861 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3862 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3863 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3865 /* ??? Needed for compress_float_constant since all fp constants
3866 are TARGET_LEGITIMATE_CONSTANT_P. */
3867 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3869 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3870 && standard_80387_constant_p (operands[1]) > 0)
3872 operands[1] = simplify_const_unary_operation
3873 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3874 emit_move_insn_1 (operands[0], operands[1]);
3877 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3881 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3883 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3885 We do the conversion post reload to avoid producing of 128bit spills
3886 that might lead to ICE on 32bit target. The sequence unlikely combine
3889 [(set (match_operand:DF 0 "register_operand" "")
3891 (match_operand:SF 1 "nonimmediate_operand" "")))]
3892 "TARGET_USE_VECTOR_FP_CONVERTS
3893 && optimize_insn_for_speed_p ()
3894 && reload_completed && SSE_REG_P (operands[0])"
3899 (parallel [(const_int 0) (const_int 1)]))))]
3901 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3902 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3903 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3904 Try to avoid move when unpacking can be done in source. */
3905 if (REG_P (operands[1]))
3907 /* If it is unsafe to overwrite upper half of source, we need
3908 to move to destination and unpack there. */
3909 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3910 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3911 && true_regnum (operands[0]) != true_regnum (operands[1]))
3913 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3914 emit_move_insn (tmp, operands[1]);
3917 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3918 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3922 emit_insn (gen_vec_setv4sf_0 (operands[3],
3923 CONST0_RTX (V4SFmode), operands[1]));
3926 (define_insn "*extendsfdf2_mixed"
3927 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3929 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3930 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3932 switch (which_alternative)
3936 return output_387_reg_move (insn, operands);
3939 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3945 [(set_attr "type" "fmov,fmov,ssecvt")
3946 (set_attr "prefix" "orig,orig,maybe_vex")
3947 (set_attr "mode" "SF,XF,DF")])
3949 (define_insn "*extendsfdf2_sse"
3950 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3951 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3952 "TARGET_SSE2 && TARGET_SSE_MATH"
3953 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3954 [(set_attr "type" "ssecvt")
3955 (set_attr "prefix" "maybe_vex")
3956 (set_attr "mode" "DF")])
3958 (define_insn "*extendsfdf2_i387"
3959 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3960 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3962 "* return output_387_reg_move (insn, operands);"
3963 [(set_attr "type" "fmov")
3964 (set_attr "mode" "SF,XF")])
3966 (define_expand "extend<mode>xf2"
3967 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3968 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3971 /* ??? Needed for compress_float_constant since all fp constants
3972 are TARGET_LEGITIMATE_CONSTANT_P. */
3973 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3975 if (standard_80387_constant_p (operands[1]) > 0)
3977 operands[1] = simplify_const_unary_operation
3978 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3979 emit_move_insn_1 (operands[0], operands[1]);
3982 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3986 (define_insn "*extend<mode>xf2_i387"
3987 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3989 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3991 "* return output_387_reg_move (insn, operands);"
3992 [(set_attr "type" "fmov")
3993 (set_attr "mode" "<MODE>,XF")])
3995 ;; %%% This seems bad bad news.
3996 ;; This cannot output into an f-reg because there is no way to be sure
3997 ;; of truncating in that case. Otherwise this is just like a simple move
3998 ;; insn. So we pretend we can output to a reg in order to get better
3999 ;; register preferencing, but we really use a stack slot.
4001 ;; Conversion from DFmode to SFmode.
4003 (define_expand "truncdfsf2"
4004 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4006 (match_operand:DF 1 "nonimmediate_operand" "")))]
4007 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4009 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4011 else if (flag_unsafe_math_optimizations)
4015 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
4016 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4021 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4023 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4025 We do the conversion post reload to avoid producing of 128bit spills
4026 that might lead to ICE on 32bit target. The sequence unlikely combine
4029 [(set (match_operand:SF 0 "register_operand" "")
4031 (match_operand:DF 1 "nonimmediate_operand" "")))]
4032 "TARGET_USE_VECTOR_FP_CONVERTS
4033 && optimize_insn_for_speed_p ()
4034 && reload_completed && SSE_REG_P (operands[0])"
4037 (float_truncate:V2SF
4041 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4042 operands[3] = CONST0_RTX (V2SFmode);
4043 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4044 /* Use movsd for loading from memory, unpcklpd for registers.
4045 Try to avoid move when unpacking can be done in source, or SSE3
4046 movddup is available. */
4047 if (REG_P (operands[1]))
4050 && true_regnum (operands[0]) != true_regnum (operands[1])
4051 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4052 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4054 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4055 emit_move_insn (tmp, operands[1]);
4058 else if (!TARGET_SSE3)
4059 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4060 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4063 emit_insn (gen_sse2_loadlpd (operands[4],
4064 CONST0_RTX (V2DFmode), operands[1]));
4067 (define_expand "truncdfsf2_with_temp"
4068 [(parallel [(set (match_operand:SF 0 "" "")
4069 (float_truncate:SF (match_operand:DF 1 "" "")))
4070 (clobber (match_operand:SF 2 "" ""))])])
4072 (define_insn "*truncdfsf_fast_mixed"
4073 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4075 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4076 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4078 switch (which_alternative)
4081 return output_387_reg_move (insn, operands);
4083 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4088 [(set_attr "type" "fmov,ssecvt")
4089 (set_attr "prefix" "orig,maybe_vex")
4090 (set_attr "mode" "SF")])
4092 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4093 ;; because nothing we do here is unsafe.
4094 (define_insn "*truncdfsf_fast_sse"
4095 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4097 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4098 "TARGET_SSE2 && TARGET_SSE_MATH"
4099 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4100 [(set_attr "type" "ssecvt")
4101 (set_attr "prefix" "maybe_vex")
4102 (set_attr "mode" "SF")])
4104 (define_insn "*truncdfsf_fast_i387"
4105 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4107 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4108 "TARGET_80387 && flag_unsafe_math_optimizations"
4109 "* return output_387_reg_move (insn, operands);"
4110 [(set_attr "type" "fmov")
4111 (set_attr "mode" "SF")])
4113 (define_insn "*truncdfsf_mixed"
4114 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4116 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4117 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4118 "TARGET_MIX_SSE_I387"
4120 switch (which_alternative)
4123 return output_387_reg_move (insn, operands);
4125 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4131 [(set_attr "isa" "*,sse2,*,*,*")
4132 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4133 (set_attr "unit" "*,*,i387,i387,i387")
4134 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4135 (set_attr "mode" "SF")])
4137 (define_insn "*truncdfsf_i387"
4138 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4140 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4141 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4144 switch (which_alternative)
4147 return output_387_reg_move (insn, operands);
4153 [(set_attr "type" "fmov,multi,multi,multi")
4154 (set_attr "unit" "*,i387,i387,i387")
4155 (set_attr "mode" "SF")])
4157 (define_insn "*truncdfsf2_i387_1"
4158 [(set (match_operand:SF 0 "memory_operand" "=m")
4160 (match_operand:DF 1 "register_operand" "f")))]
4162 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4163 && !TARGET_MIX_SSE_I387"
4164 "* return output_387_reg_move (insn, operands);"
4165 [(set_attr "type" "fmov")
4166 (set_attr "mode" "SF")])
4169 [(set (match_operand:SF 0 "register_operand" "")
4171 (match_operand:DF 1 "fp_register_operand" "")))
4172 (clobber (match_operand 2 "" ""))]
4174 [(set (match_dup 2) (match_dup 1))
4175 (set (match_dup 0) (match_dup 2))]
4176 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4178 ;; Conversion from XFmode to {SF,DF}mode
4180 (define_expand "truncxf<mode>2"
4181 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4182 (float_truncate:MODEF
4183 (match_operand:XF 1 "register_operand" "")))
4184 (clobber (match_dup 2))])]
4187 if (flag_unsafe_math_optimizations)
4189 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4190 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4191 if (reg != operands[0])
4192 emit_move_insn (operands[0], reg);
4196 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4199 (define_insn "*truncxfsf2_mixed"
4200 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4202 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4203 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4206 gcc_assert (!which_alternative);
4207 return output_387_reg_move (insn, operands);
4209 [(set_attr "type" "fmov,multi,multi,multi")
4210 (set_attr "unit" "*,i387,i387,i387")
4211 (set_attr "mode" "SF")])
4213 (define_insn "*truncxfdf2_mixed"
4214 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4216 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4217 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4220 gcc_assert (!which_alternative);
4221 return output_387_reg_move (insn, operands);
4223 [(set_attr "isa" "*,*,sse2,*")
4224 (set_attr "type" "fmov,multi,multi,multi")
4225 (set_attr "unit" "*,i387,i387,i387")
4226 (set_attr "mode" "DF")])
4228 (define_insn "truncxf<mode>2_i387_noop"
4229 [(set (match_operand:MODEF 0 "register_operand" "=f")
4230 (float_truncate:MODEF
4231 (match_operand:XF 1 "register_operand" "f")))]
4232 "TARGET_80387 && flag_unsafe_math_optimizations"
4233 "* return output_387_reg_move (insn, operands);"
4234 [(set_attr "type" "fmov")
4235 (set_attr "mode" "<MODE>")])
4237 (define_insn "*truncxf<mode>2_i387"
4238 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4239 (float_truncate:MODEF
4240 (match_operand:XF 1 "register_operand" "f")))]
4242 "* return output_387_reg_move (insn, operands);"
4243 [(set_attr "type" "fmov")
4244 (set_attr "mode" "<MODE>")])
4247 [(set (match_operand:MODEF 0 "register_operand" "")
4248 (float_truncate:MODEF
4249 (match_operand:XF 1 "register_operand" "")))
4250 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4251 "TARGET_80387 && reload_completed"
4252 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4253 (set (match_dup 0) (match_dup 2))])
4256 [(set (match_operand:MODEF 0 "memory_operand" "")
4257 (float_truncate:MODEF
4258 (match_operand:XF 1 "register_operand" "")))
4259 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4261 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4263 ;; Signed conversion to DImode.
4265 (define_expand "fix_truncxfdi2"
4266 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4267 (fix:DI (match_operand:XF 1 "register_operand" "")))
4268 (clobber (reg:CC FLAGS_REG))])]
4273 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4278 (define_expand "fix_trunc<mode>di2"
4279 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4280 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4281 (clobber (reg:CC FLAGS_REG))])]
4282 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4285 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4287 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4290 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4292 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4293 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4294 if (out != operands[0])
4295 emit_move_insn (operands[0], out);
4300 ;; Signed conversion to SImode.
4302 (define_expand "fix_truncxfsi2"
4303 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4304 (fix:SI (match_operand:XF 1 "register_operand" "")))
4305 (clobber (reg:CC FLAGS_REG))])]
4310 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4315 (define_expand "fix_trunc<mode>si2"
4316 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4317 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4318 (clobber (reg:CC FLAGS_REG))])]
4319 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4322 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4324 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4327 if (SSE_FLOAT_MODE_P (<MODE>mode))
4329 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4330 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4331 if (out != operands[0])
4332 emit_move_insn (operands[0], out);
4337 ;; Signed conversion to HImode.
4339 (define_expand "fix_trunc<mode>hi2"
4340 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4341 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4342 (clobber (reg:CC FLAGS_REG))])]
4344 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4348 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4353 ;; Unsigned conversion to SImode.
4355 (define_expand "fixuns_trunc<mode>si2"
4357 [(set (match_operand:SI 0 "register_operand" "")
4359 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4361 (clobber (match_scratch:<ssevecmode> 3 ""))
4362 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4363 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4365 enum machine_mode mode = <MODE>mode;
4366 enum machine_mode vecmode = <ssevecmode>mode;
4367 REAL_VALUE_TYPE TWO31r;
4370 if (optimize_insn_for_size_p ())
4373 real_ldexp (&TWO31r, &dconst1, 31);
4374 two31 = const_double_from_real_value (TWO31r, mode);
4375 two31 = ix86_build_const_vector (vecmode, true, two31);
4376 operands[2] = force_reg (vecmode, two31);
4379 (define_insn_and_split "*fixuns_trunc<mode>_1"
4380 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4382 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4383 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4384 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4385 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4386 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4387 && optimize_function_for_speed_p (cfun)"
4389 "&& reload_completed"
4392 ix86_split_convert_uns_si_sse (operands);
4396 ;; Unsigned conversion to HImode.
4397 ;; Without these patterns, we'll try the unsigned SI conversion which
4398 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4400 (define_expand "fixuns_trunc<mode>hi2"
4402 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4403 (set (match_operand:HI 0 "nonimmediate_operand" "")
4404 (subreg:HI (match_dup 2) 0))]
4405 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4406 "operands[2] = gen_reg_rtx (SImode);")
4408 ;; When SSE is available, it is always faster to use it!
4409 (define_insn "fix_trunc<mode>di_sse"
4410 [(set (match_operand:DI 0 "register_operand" "=r,r")
4411 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4412 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4413 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4414 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4415 [(set_attr "type" "sseicvt")
4416 (set_attr "prefix" "maybe_vex")
4417 (set_attr "prefix_rex" "1")
4418 (set_attr "mode" "<MODE>")
4419 (set_attr "athlon_decode" "double,vector")
4420 (set_attr "amdfam10_decode" "double,double")
4421 (set_attr "bdver1_decode" "double,double")])
4423 (define_insn "fix_trunc<mode>si_sse"
4424 [(set (match_operand:SI 0 "register_operand" "=r,r")
4425 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4426 "SSE_FLOAT_MODE_P (<MODE>mode)
4427 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4428 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4429 [(set_attr "type" "sseicvt")
4430 (set_attr "prefix" "maybe_vex")
4431 (set_attr "mode" "<MODE>")
4432 (set_attr "athlon_decode" "double,vector")
4433 (set_attr "amdfam10_decode" "double,double")
4434 (set_attr "bdver1_decode" "double,double")])
4436 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4438 [(set (match_operand:MODEF 0 "register_operand" "")
4439 (match_operand:MODEF 1 "memory_operand" ""))
4440 (set (match_operand:SWI48x 2 "register_operand" "")
4441 (fix:SWI48x (match_dup 0)))]
4442 "TARGET_SHORTEN_X87_SSE
4443 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4444 && peep2_reg_dead_p (2, operands[0])"
4445 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4447 ;; Avoid vector decoded forms of the instruction.
4449 [(match_scratch:DF 2 "x")
4450 (set (match_operand:SWI48x 0 "register_operand" "")
4451 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4452 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4453 [(set (match_dup 2) (match_dup 1))
4454 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4457 [(match_scratch:SF 2 "x")
4458 (set (match_operand:SWI48x 0 "register_operand" "")
4459 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4460 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4461 [(set (match_dup 2) (match_dup 1))
4462 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4464 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4465 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4466 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4467 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4469 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4470 && (TARGET_64BIT || <MODE>mode != DImode))
4472 && can_create_pseudo_p ()"
4477 if (memory_operand (operands[0], VOIDmode))
4478 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4481 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4482 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4488 [(set_attr "type" "fisttp")
4489 (set_attr "mode" "<MODE>")])
4491 (define_insn "fix_trunc<mode>_i387_fisttp"
4492 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4493 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4494 (clobber (match_scratch:XF 2 "=&1f"))]
4495 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4497 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4498 && (TARGET_64BIT || <MODE>mode != DImode))
4499 && TARGET_SSE_MATH)"
4500 "* return output_fix_trunc (insn, operands, true);"
4501 [(set_attr "type" "fisttp")
4502 (set_attr "mode" "<MODE>")])
4504 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4505 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4506 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4507 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4508 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4509 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4511 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4512 && (TARGET_64BIT || <MODE>mode != DImode))
4513 && TARGET_SSE_MATH)"
4515 [(set_attr "type" "fisttp")
4516 (set_attr "mode" "<MODE>")])
4519 [(set (match_operand:SWI248x 0 "register_operand" "")
4520 (fix:SWI248x (match_operand 1 "register_operand" "")))
4521 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4522 (clobber (match_scratch 3 ""))]
4524 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4525 (clobber (match_dup 3))])
4526 (set (match_dup 0) (match_dup 2))])
4529 [(set (match_operand:SWI248x 0 "memory_operand" "")
4530 (fix:SWI248x (match_operand 1 "register_operand" "")))
4531 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4532 (clobber (match_scratch 3 ""))]
4534 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4535 (clobber (match_dup 3))])])
4537 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4538 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4539 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4540 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4541 ;; function in i386.c.
4542 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4543 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4544 (fix:SWI248x (match_operand 1 "register_operand" "")))
4545 (clobber (reg:CC FLAGS_REG))]
4546 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4548 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4549 && (TARGET_64BIT || <MODE>mode != DImode))
4550 && can_create_pseudo_p ()"
4555 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4557 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4558 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4559 if (memory_operand (operands[0], VOIDmode))
4560 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4561 operands[2], operands[3]));
4564 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4565 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4566 operands[2], operands[3],
4571 [(set_attr "type" "fistp")
4572 (set_attr "i387_cw" "trunc")
4573 (set_attr "mode" "<MODE>")])
4575 (define_insn "fix_truncdi_i387"
4576 [(set (match_operand:DI 0 "memory_operand" "=m")
4577 (fix:DI (match_operand 1 "register_operand" "f")))
4578 (use (match_operand:HI 2 "memory_operand" "m"))
4579 (use (match_operand:HI 3 "memory_operand" "m"))
4580 (clobber (match_scratch:XF 4 "=&1f"))]
4581 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4583 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4584 "* return output_fix_trunc (insn, operands, false);"
4585 [(set_attr "type" "fistp")
4586 (set_attr "i387_cw" "trunc")
4587 (set_attr "mode" "DI")])
4589 (define_insn "fix_truncdi_i387_with_temp"
4590 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4591 (fix:DI (match_operand 1 "register_operand" "f,f")))
4592 (use (match_operand:HI 2 "memory_operand" "m,m"))
4593 (use (match_operand:HI 3 "memory_operand" "m,m"))
4594 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4595 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4596 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4598 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4600 [(set_attr "type" "fistp")
4601 (set_attr "i387_cw" "trunc")
4602 (set_attr "mode" "DI")])
4605 [(set (match_operand:DI 0 "register_operand" "")
4606 (fix:DI (match_operand 1 "register_operand" "")))
4607 (use (match_operand:HI 2 "memory_operand" ""))
4608 (use (match_operand:HI 3 "memory_operand" ""))
4609 (clobber (match_operand:DI 4 "memory_operand" ""))
4610 (clobber (match_scratch 5 ""))]
4612 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4615 (clobber (match_dup 5))])
4616 (set (match_dup 0) (match_dup 4))])
4619 [(set (match_operand:DI 0 "memory_operand" "")
4620 (fix:DI (match_operand 1 "register_operand" "")))
4621 (use (match_operand:HI 2 "memory_operand" ""))
4622 (use (match_operand:HI 3 "memory_operand" ""))
4623 (clobber (match_operand:DI 4 "memory_operand" ""))
4624 (clobber (match_scratch 5 ""))]
4626 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4629 (clobber (match_dup 5))])])
4631 (define_insn "fix_trunc<mode>_i387"
4632 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4633 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4634 (use (match_operand:HI 2 "memory_operand" "m"))
4635 (use (match_operand:HI 3 "memory_operand" "m"))]
4636 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4638 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4639 "* return output_fix_trunc (insn, operands, false);"
4640 [(set_attr "type" "fistp")
4641 (set_attr "i387_cw" "trunc")
4642 (set_attr "mode" "<MODE>")])
4644 (define_insn "fix_trunc<mode>_i387_with_temp"
4645 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4646 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4647 (use (match_operand:HI 2 "memory_operand" "m,m"))
4648 (use (match_operand:HI 3 "memory_operand" "m,m"))
4649 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4650 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4652 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4654 [(set_attr "type" "fistp")
4655 (set_attr "i387_cw" "trunc")
4656 (set_attr "mode" "<MODE>")])
4659 [(set (match_operand:SWI24 0 "register_operand" "")
4660 (fix:SWI24 (match_operand 1 "register_operand" "")))
4661 (use (match_operand:HI 2 "memory_operand" ""))
4662 (use (match_operand:HI 3 "memory_operand" ""))
4663 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4665 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4667 (use (match_dup 3))])
4668 (set (match_dup 0) (match_dup 4))])
4671 [(set (match_operand:SWI24 0 "memory_operand" "")
4672 (fix:SWI24 (match_operand 1 "register_operand" "")))
4673 (use (match_operand:HI 2 "memory_operand" ""))
4674 (use (match_operand:HI 3 "memory_operand" ""))
4675 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4677 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4679 (use (match_dup 3))])])
4681 (define_insn "x86_fnstcw_1"
4682 [(set (match_operand:HI 0 "memory_operand" "=m")
4683 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4686 [(set (attr "length")
4687 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4688 (set_attr "mode" "HI")
4689 (set_attr "unit" "i387")
4690 (set_attr "bdver1_decode" "vector")])
4692 (define_insn "x86_fldcw_1"
4693 [(set (reg:HI FPCR_REG)
4694 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4697 [(set (attr "length")
4698 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4699 (set_attr "mode" "HI")
4700 (set_attr "unit" "i387")
4701 (set_attr "athlon_decode" "vector")
4702 (set_attr "amdfam10_decode" "vector")
4703 (set_attr "bdver1_decode" "vector")])
4705 ;; Conversion between fixed point and floating point.
4707 ;; Even though we only accept memory inputs, the backend _really_
4708 ;; wants to be able to do this between registers.
4710 (define_expand "floathi<mode>2"
4711 [(set (match_operand:X87MODEF 0 "register_operand" "")
4712 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4714 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4715 || TARGET_MIX_SSE_I387)")
4717 ;; Pre-reload splitter to add memory clobber to the pattern.
4718 (define_insn_and_split "*floathi<mode>2_1"
4719 [(set (match_operand:X87MODEF 0 "register_operand" "")
4720 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4722 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4723 || TARGET_MIX_SSE_I387)
4724 && can_create_pseudo_p ()"
4727 [(parallel [(set (match_dup 0)
4728 (float:X87MODEF (match_dup 1)))
4729 (clobber (match_dup 2))])]
4730 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4732 (define_insn "*floathi<mode>2_i387_with_temp"
4733 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4734 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4735 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4737 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4738 || TARGET_MIX_SSE_I387)"
4740 [(set_attr "type" "fmov,multi")
4741 (set_attr "mode" "<MODE>")
4742 (set_attr "unit" "*,i387")
4743 (set_attr "fp_int_src" "true")])
4745 (define_insn "*floathi<mode>2_i387"
4746 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4747 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4749 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4750 || TARGET_MIX_SSE_I387)"
4752 [(set_attr "type" "fmov")
4753 (set_attr "mode" "<MODE>")
4754 (set_attr "fp_int_src" "true")])
4757 [(set (match_operand:X87MODEF 0 "register_operand" "")
4758 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4759 (clobber (match_operand:HI 2 "memory_operand" ""))]
4761 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4762 || TARGET_MIX_SSE_I387)
4763 && reload_completed"
4764 [(set (match_dup 2) (match_dup 1))
4765 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4768 [(set (match_operand:X87MODEF 0 "register_operand" "")
4769 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4770 (clobber (match_operand:HI 2 "memory_operand" ""))]
4772 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4773 || TARGET_MIX_SSE_I387)
4774 && reload_completed"
4775 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4777 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4778 [(set (match_operand:X87MODEF 0 "register_operand" "")
4780 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4782 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4783 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4785 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4786 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4787 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4789 rtx reg = gen_reg_rtx (XFmode);
4790 rtx (*insn)(rtx, rtx);
4792 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4794 if (<X87MODEF:MODE>mode == SFmode)
4795 insn = gen_truncxfsf2;
4796 else if (<X87MODEF:MODE>mode == DFmode)
4797 insn = gen_truncxfdf2;
4801 emit_insn (insn (operands[0], reg));
4806 ;; Pre-reload splitter to add memory clobber to the pattern.
4807 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4808 [(set (match_operand:X87MODEF 0 "register_operand" "")
4809 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4811 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4812 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4813 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4814 || TARGET_MIX_SSE_I387))
4815 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4816 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4817 && ((<SWI48x:MODE>mode == SImode
4818 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4819 && optimize_function_for_speed_p (cfun)
4820 && flag_trapping_math)
4821 || !(TARGET_INTER_UNIT_CONVERSIONS
4822 || optimize_function_for_size_p (cfun)))))
4823 && can_create_pseudo_p ()"
4826 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4827 (clobber (match_dup 2))])]
4829 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4831 /* Avoid store forwarding (partial memory) stall penalty
4832 by passing DImode value through XMM registers. */
4833 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4834 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4835 && optimize_function_for_speed_p (cfun))
4837 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4844 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4845 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4847 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4848 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4849 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4850 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4852 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4853 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4854 (set_attr "unit" "*,i387,*,*,*")
4855 (set_attr "athlon_decode" "*,*,double,direct,double")
4856 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4857 (set_attr "bdver1_decode" "*,*,double,direct,double")
4858 (set_attr "fp_int_src" "true")])
4860 (define_insn "*floatsi<mode>2_vector_mixed"
4861 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4862 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4863 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4864 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4868 [(set_attr "type" "fmov,sseicvt")
4869 (set_attr "mode" "<MODE>,<ssevecmode>")
4870 (set_attr "unit" "i387,*")
4871 (set_attr "athlon_decode" "*,direct")
4872 (set_attr "amdfam10_decode" "*,double")
4873 (set_attr "bdver1_decode" "*,direct")
4874 (set_attr "fp_int_src" "true")])
4876 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4877 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4879 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4880 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4881 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4882 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4884 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4885 (set_attr "mode" "<MODEF:MODE>")
4886 (set_attr "unit" "*,i387,*,*")
4887 (set_attr "athlon_decode" "*,*,double,direct")
4888 (set_attr "amdfam10_decode" "*,*,vector,double")
4889 (set_attr "bdver1_decode" "*,*,double,direct")
4890 (set_attr "fp_int_src" "true")])
4893 [(set (match_operand:MODEF 0 "register_operand" "")
4894 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4895 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4896 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4897 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4898 && TARGET_INTER_UNIT_CONVERSIONS
4900 && (SSE_REG_P (operands[0])
4901 || (GET_CODE (operands[0]) == SUBREG
4902 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4903 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4906 [(set (match_operand:MODEF 0 "register_operand" "")
4907 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4908 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4909 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4910 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4911 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4913 && (SSE_REG_P (operands[0])
4914 || (GET_CODE (operands[0]) == SUBREG
4915 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4916 [(set (match_dup 2) (match_dup 1))
4917 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4919 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4920 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4922 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4923 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4924 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4925 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4928 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4929 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4930 [(set_attr "type" "fmov,sseicvt,sseicvt")
4931 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4932 (set_attr "mode" "<MODEF:MODE>")
4933 (set (attr "prefix_rex")
4935 (and (eq_attr "prefix" "maybe_vex")
4936 (match_test "<SWI48x:MODE>mode == DImode"))
4938 (const_string "*")))
4939 (set_attr "unit" "i387,*,*")
4940 (set_attr "athlon_decode" "*,double,direct")
4941 (set_attr "amdfam10_decode" "*,vector,double")
4942 (set_attr "bdver1_decode" "*,double,direct")
4943 (set_attr "fp_int_src" "true")])
4945 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4946 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4948 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4949 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4950 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4951 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4954 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4955 [(set_attr "type" "fmov,sseicvt")
4956 (set_attr "prefix" "orig,maybe_vex")
4957 (set_attr "mode" "<MODEF:MODE>")
4958 (set (attr "prefix_rex")
4960 (and (eq_attr "prefix" "maybe_vex")
4961 (match_test "<SWI48x:MODE>mode == DImode"))
4963 (const_string "*")))
4964 (set_attr "athlon_decode" "*,direct")
4965 (set_attr "amdfam10_decode" "*,double")
4966 (set_attr "bdver1_decode" "*,direct")
4967 (set_attr "fp_int_src" "true")])
4969 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4970 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4972 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4973 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4974 "TARGET_SSE2 && TARGET_SSE_MATH
4975 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4977 [(set_attr "type" "sseicvt")
4978 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4979 (set_attr "athlon_decode" "double,direct,double")
4980 (set_attr "amdfam10_decode" "vector,double,double")
4981 (set_attr "bdver1_decode" "double,direct,double")
4982 (set_attr "fp_int_src" "true")])
4984 (define_insn "*floatsi<mode>2_vector_sse"
4985 [(set (match_operand:MODEF 0 "register_operand" "=x")
4986 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4987 "TARGET_SSE2 && TARGET_SSE_MATH
4988 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4990 [(set_attr "type" "sseicvt")
4991 (set_attr "mode" "<MODE>")
4992 (set_attr "athlon_decode" "direct")
4993 (set_attr "amdfam10_decode" "double")
4994 (set_attr "bdver1_decode" "direct")
4995 (set_attr "fp_int_src" "true")])
4998 [(set (match_operand:MODEF 0 "register_operand" "")
4999 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5000 (clobber (match_operand:SI 2 "memory_operand" ""))]
5001 "TARGET_SSE2 && TARGET_SSE_MATH
5002 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5004 && (SSE_REG_P (operands[0])
5005 || (GET_CODE (operands[0]) == SUBREG
5006 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5009 rtx op1 = operands[1];
5011 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5013 if (GET_CODE (op1) == SUBREG)
5014 op1 = SUBREG_REG (op1);
5016 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5018 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5019 emit_insn (gen_sse2_loadld (operands[4],
5020 CONST0_RTX (V4SImode), operands[1]));
5022 /* We can ignore possible trapping value in the
5023 high part of SSE register for non-trapping math. */
5024 else if (SSE_REG_P (op1) && !flag_trapping_math)
5025 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5028 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5029 emit_move_insn (operands[2], operands[1]);
5030 emit_insn (gen_sse2_loadld (operands[4],
5031 CONST0_RTX (V4SImode), operands[2]));
5033 if (<ssevecmode>mode == V4SFmode)
5034 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5036 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5041 [(set (match_operand:MODEF 0 "register_operand" "")
5042 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5043 (clobber (match_operand:SI 2 "memory_operand" ""))]
5044 "TARGET_SSE2 && TARGET_SSE_MATH
5045 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5047 && (SSE_REG_P (operands[0])
5048 || (GET_CODE (operands[0]) == SUBREG
5049 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5052 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5054 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5056 emit_insn (gen_sse2_loadld (operands[4],
5057 CONST0_RTX (V4SImode), operands[1]));
5058 if (<ssevecmode>mode == V4SFmode)
5059 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5061 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5066 [(set (match_operand:MODEF 0 "register_operand" "")
5067 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5068 "TARGET_SSE2 && TARGET_SSE_MATH
5069 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5071 && (SSE_REG_P (operands[0])
5072 || (GET_CODE (operands[0]) == SUBREG
5073 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5076 rtx op1 = operands[1];
5078 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5080 if (GET_CODE (op1) == SUBREG)
5081 op1 = SUBREG_REG (op1);
5083 if (GENERAL_REG_P (op1))
5085 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5086 if (TARGET_INTER_UNIT_MOVES)
5087 emit_insn (gen_sse2_loadld (operands[4],
5088 CONST0_RTX (V4SImode), operands[1]));
5091 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5093 emit_insn (gen_sse2_loadld (operands[4],
5094 CONST0_RTX (V4SImode), operands[5]));
5095 ix86_free_from_memory (GET_MODE (operands[1]));
5098 /* We can ignore possible trapping value in the
5099 high part of SSE register for non-trapping math. */
5100 else if (SSE_REG_P (op1) && !flag_trapping_math)
5101 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5104 if (<ssevecmode>mode == V4SFmode)
5105 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5107 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5112 [(set (match_operand:MODEF 0 "register_operand" "")
5113 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5114 "TARGET_SSE2 && TARGET_SSE_MATH
5115 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5117 && (SSE_REG_P (operands[0])
5118 || (GET_CODE (operands[0]) == SUBREG
5119 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5122 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5124 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5126 emit_insn (gen_sse2_loadld (operands[4],
5127 CONST0_RTX (V4SImode), operands[1]));
5128 if (<ssevecmode>mode == V4SFmode)
5129 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5131 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5135 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5136 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5138 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5139 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5140 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5141 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5143 [(set_attr "type" "sseicvt")
5144 (set_attr "mode" "<MODEF:MODE>")
5145 (set_attr "athlon_decode" "double,direct")
5146 (set_attr "amdfam10_decode" "vector,double")
5147 (set_attr "bdver1_decode" "double,direct")
5148 (set_attr "fp_int_src" "true")])
5150 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5151 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5153 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5154 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5155 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5156 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5157 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5158 [(set_attr "type" "sseicvt")
5159 (set_attr "prefix" "maybe_vex")
5160 (set_attr "mode" "<MODEF:MODE>")
5161 (set (attr "prefix_rex")
5163 (and (eq_attr "prefix" "maybe_vex")
5164 (match_test "<SWI48x:MODE>mode == DImode"))
5166 (const_string "*")))
5167 (set_attr "athlon_decode" "double,direct")
5168 (set_attr "amdfam10_decode" "vector,double")
5169 (set_attr "bdver1_decode" "double,direct")
5170 (set_attr "fp_int_src" "true")])
5173 [(set (match_operand:MODEF 0 "register_operand" "")
5174 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5175 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5176 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5177 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5178 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5180 && (SSE_REG_P (operands[0])
5181 || (GET_CODE (operands[0]) == SUBREG
5182 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5183 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5185 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5186 [(set (match_operand:MODEF 0 "register_operand" "=x")
5188 (match_operand:SWI48x 1 "memory_operand" "m")))]
5189 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5190 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5191 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5192 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5193 [(set_attr "type" "sseicvt")
5194 (set_attr "prefix" "maybe_vex")
5195 (set_attr "mode" "<MODEF:MODE>")
5196 (set (attr "prefix_rex")
5198 (and (eq_attr "prefix" "maybe_vex")
5199 (match_test "<SWI48x:MODE>mode == DImode"))
5201 (const_string "*")))
5202 (set_attr "athlon_decode" "direct")
5203 (set_attr "amdfam10_decode" "double")
5204 (set_attr "bdver1_decode" "direct")
5205 (set_attr "fp_int_src" "true")])
5208 [(set (match_operand:MODEF 0 "register_operand" "")
5209 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5210 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5211 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5212 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5213 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5215 && (SSE_REG_P (operands[0])
5216 || (GET_CODE (operands[0]) == SUBREG
5217 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5218 [(set (match_dup 2) (match_dup 1))
5219 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5222 [(set (match_operand:MODEF 0 "register_operand" "")
5223 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5224 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5225 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5226 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5228 && (SSE_REG_P (operands[0])
5229 || (GET_CODE (operands[0]) == SUBREG
5230 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5231 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5233 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5234 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5236 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5237 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5239 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5243 [(set_attr "type" "fmov,multi")
5244 (set_attr "mode" "<X87MODEF:MODE>")
5245 (set_attr "unit" "*,i387")
5246 (set_attr "fp_int_src" "true")])
5248 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5249 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5251 (match_operand:SWI48x 1 "memory_operand" "m")))]
5253 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5255 [(set_attr "type" "fmov")
5256 (set_attr "mode" "<X87MODEF:MODE>")
5257 (set_attr "fp_int_src" "true")])
5260 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5261 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5262 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5264 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5265 && reload_completed"
5266 [(set (match_dup 2) (match_dup 1))
5267 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5270 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5271 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5272 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5274 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5275 && reload_completed"
5276 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5278 ;; Avoid store forwarding (partial memory) stall penalty
5279 ;; by passing DImode value through XMM registers. */
5281 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5282 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5284 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5285 (clobber (match_scratch:V4SI 3 "=X,x"))
5286 (clobber (match_scratch:V4SI 4 "=X,x"))
5287 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5288 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5289 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5290 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5292 [(set_attr "type" "multi")
5293 (set_attr "mode" "<X87MODEF:MODE>")
5294 (set_attr "unit" "i387")
5295 (set_attr "fp_int_src" "true")])
5298 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5299 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5300 (clobber (match_scratch:V4SI 3 ""))
5301 (clobber (match_scratch:V4SI 4 ""))
5302 (clobber (match_operand:DI 2 "memory_operand" ""))]
5303 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5304 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5305 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5306 && reload_completed"
5307 [(set (match_dup 2) (match_dup 3))
5308 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5310 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5311 Assemble the 64-bit DImode value in an xmm register. */
5312 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5313 gen_rtx_SUBREG (SImode, operands[1], 0)));
5314 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5315 gen_rtx_SUBREG (SImode, operands[1], 4)));
5316 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5319 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5323 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5324 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5325 (clobber (match_scratch:V4SI 3 ""))
5326 (clobber (match_scratch:V4SI 4 ""))
5327 (clobber (match_operand:DI 2 "memory_operand" ""))]
5328 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5329 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5330 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5331 && reload_completed"
5332 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5334 ;; Avoid store forwarding (partial memory) stall penalty by extending
5335 ;; SImode value to DImode through XMM register instead of pushing two
5336 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5337 ;; targets benefit from this optimization. Also note that fild
5338 ;; loads from memory only.
5340 (define_insn "*floatunssi<mode>2_1"
5341 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5342 (unsigned_float:X87MODEF
5343 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5344 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5345 (clobber (match_scratch:SI 3 "=X,x"))]
5347 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5350 [(set_attr "type" "multi")
5351 (set_attr "mode" "<MODE>")])
5354 [(set (match_operand:X87MODEF 0 "register_operand" "")
5355 (unsigned_float:X87MODEF
5356 (match_operand:SI 1 "register_operand" "")))
5357 (clobber (match_operand:DI 2 "memory_operand" ""))
5358 (clobber (match_scratch:SI 3 ""))]
5360 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5362 && reload_completed"
5363 [(set (match_dup 2) (match_dup 1))
5365 (float:X87MODEF (match_dup 2)))]
5366 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5369 [(set (match_operand:X87MODEF 0 "register_operand" "")
5370 (unsigned_float:X87MODEF
5371 (match_operand:SI 1 "memory_operand" "")))
5372 (clobber (match_operand:DI 2 "memory_operand" ""))
5373 (clobber (match_scratch:SI 3 ""))]
5375 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5377 && reload_completed"
5378 [(set (match_dup 2) (match_dup 3))
5380 (float:X87MODEF (match_dup 2)))]
5382 emit_move_insn (operands[3], operands[1]);
5383 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5386 (define_expand "floatunssi<mode>2"
5388 [(set (match_operand:X87MODEF 0 "register_operand" "")
5389 (unsigned_float:X87MODEF
5390 (match_operand:SI 1 "nonimmediate_operand" "")))
5391 (clobber (match_dup 2))
5392 (clobber (match_scratch:SI 3 ""))])]
5394 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5396 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5398 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5400 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5404 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5407 (define_expand "floatunsdisf2"
5408 [(use (match_operand:SF 0 "register_operand" ""))
5409 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5410 "TARGET_64BIT && TARGET_SSE_MATH"
5411 "x86_emit_floatuns (operands); DONE;")
5413 (define_expand "floatunsdidf2"
5414 [(use (match_operand:DF 0 "register_operand" ""))
5415 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5416 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5417 && TARGET_SSE2 && TARGET_SSE_MATH"
5420 x86_emit_floatuns (operands);
5422 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5426 ;; Load effective address instructions
5428 (define_insn_and_split "*lea<mode>"
5429 [(set (match_operand:SWI48 0 "register_operand" "=r")
5430 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5433 rtx addr = operands[1];
5435 if (SImode_address_operand (addr, VOIDmode))
5437 gcc_assert (TARGET_64BIT);
5438 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5441 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5443 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5446 ix86_split_lea_for_addr (operands, <MODE>mode);
5449 [(set_attr "type" "lea")
5452 (match_operand 1 "SImode_address_operand")
5454 (const_string "<MODE>")))])
5458 (define_expand "add<mode>3"
5459 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5460 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5461 (match_operand:SDWIM 2 "<general_operand>" "")))]
5463 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5465 (define_insn_and_split "*add<dwi>3_doubleword"
5466 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5468 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5469 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5470 (clobber (reg:CC FLAGS_REG))]
5471 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5474 [(parallel [(set (reg:CC FLAGS_REG)
5475 (unspec:CC [(match_dup 1) (match_dup 2)]
5478 (plus:DWIH (match_dup 1) (match_dup 2)))])
5479 (parallel [(set (match_dup 3)
5483 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5485 (clobber (reg:CC FLAGS_REG))])]
5486 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5488 (define_insn "*add<mode>3_cc"
5489 [(set (reg:CC FLAGS_REG)
5491 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5492 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5494 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5495 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5496 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5497 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5498 [(set_attr "type" "alu")
5499 (set_attr "mode" "<MODE>")])
5501 (define_insn "addqi3_cc"
5502 [(set (reg:CC FLAGS_REG)
5504 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5505 (match_operand:QI 2 "general_operand" "qn,qm")]
5507 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5508 (plus:QI (match_dup 1) (match_dup 2)))]
5509 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5510 "add{b}\t{%2, %0|%0, %2}"
5511 [(set_attr "type" "alu")
5512 (set_attr "mode" "QI")])
5514 (define_insn "*add<mode>_1"
5515 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5517 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5518 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5519 (clobber (reg:CC FLAGS_REG))]
5520 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5522 switch (get_attr_type (insn))
5528 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5529 if (operands[2] == const1_rtx)
5530 return "inc{<imodesuffix>}\t%0";
5533 gcc_assert (operands[2] == constm1_rtx);
5534 return "dec{<imodesuffix>}\t%0";
5538 /* For most processors, ADD is faster than LEA. This alternative
5539 was added to use ADD as much as possible. */
5540 if (which_alternative == 2)
5543 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5546 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5547 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5548 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5550 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5554 (cond [(eq_attr "alternative" "3")
5555 (const_string "lea")
5556 (match_operand:SWI48 2 "incdec_operand" "")
5557 (const_string "incdec")
5559 (const_string "alu")))
5560 (set (attr "length_immediate")
5562 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5564 (const_string "*")))
5565 (set_attr "mode" "<MODE>")])
5567 ;; It may seem that nonimmediate operand is proper one for operand 1.
5568 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5569 ;; we take care in ix86_binary_operator_ok to not allow two memory
5570 ;; operands so proper swapping will be done in reload. This allow
5571 ;; patterns constructed from addsi_1 to match.
5573 (define_insn "addsi_1_zext"
5574 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5576 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5577 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5578 (clobber (reg:CC FLAGS_REG))]
5579 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5581 switch (get_attr_type (insn))
5587 if (operands[2] == const1_rtx)
5588 return "inc{l}\t%k0";
5591 gcc_assert (operands[2] == constm1_rtx);
5592 return "dec{l}\t%k0";
5596 /* For most processors, ADD is faster than LEA. This alternative
5597 was added to use ADD as much as possible. */
5598 if (which_alternative == 1)
5601 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5604 if (x86_maybe_negate_const_int (&operands[2], SImode))
5605 return "sub{l}\t{%2, %k0|%k0, %2}";
5607 return "add{l}\t{%2, %k0|%k0, %2}";
5611 (cond [(eq_attr "alternative" "2")
5612 (const_string "lea")
5613 (match_operand:SI 2 "incdec_operand" "")
5614 (const_string "incdec")
5616 (const_string "alu")))
5617 (set (attr "length_immediate")
5619 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5621 (const_string "*")))
5622 (set_attr "mode" "SI")])
5624 (define_insn "*addhi_1"
5625 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5626 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5627 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5628 (clobber (reg:CC FLAGS_REG))]
5629 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5631 switch (get_attr_type (insn))
5637 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5638 if (operands[2] == const1_rtx)
5639 return "inc{w}\t%0";
5642 gcc_assert (operands[2] == constm1_rtx);
5643 return "dec{w}\t%0";
5647 /* For most processors, ADD is faster than LEA. This alternative
5648 was added to use ADD as much as possible. */
5649 if (which_alternative == 2)
5652 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5655 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5656 if (x86_maybe_negate_const_int (&operands[2], HImode))
5657 return "sub{w}\t{%2, %0|%0, %2}";
5659 return "add{w}\t{%2, %0|%0, %2}";
5663 (cond [(eq_attr "alternative" "3")
5664 (const_string "lea")
5665 (match_operand:HI 2 "incdec_operand" "")
5666 (const_string "incdec")
5668 (const_string "alu")))
5669 (set (attr "length_immediate")
5671 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5673 (const_string "*")))
5674 (set_attr "mode" "HI,HI,HI,SI")])
5676 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5677 (define_insn "*addqi_1"
5678 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5679 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5680 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5681 (clobber (reg:CC FLAGS_REG))]
5682 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5684 bool widen = (which_alternative == 3 || which_alternative == 4);
5686 switch (get_attr_type (insn))
5692 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5693 if (operands[2] == const1_rtx)
5694 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5697 gcc_assert (operands[2] == constm1_rtx);
5698 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5702 /* For most processors, ADD is faster than LEA. These alternatives
5703 were added to use ADD as much as possible. */
5704 if (which_alternative == 2 || which_alternative == 4)
5707 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5710 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5711 if (x86_maybe_negate_const_int (&operands[2], QImode))
5714 return "sub{l}\t{%2, %k0|%k0, %2}";
5716 return "sub{b}\t{%2, %0|%0, %2}";
5719 return "add{l}\t{%k2, %k0|%k0, %k2}";
5721 return "add{b}\t{%2, %0|%0, %2}";
5725 (cond [(eq_attr "alternative" "5")
5726 (const_string "lea")
5727 (match_operand:QI 2 "incdec_operand" "")
5728 (const_string "incdec")
5730 (const_string "alu")))
5731 (set (attr "length_immediate")
5733 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5735 (const_string "*")))
5736 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5738 (define_insn "*addqi_1_slp"
5739 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5740 (plus:QI (match_dup 0)
5741 (match_operand:QI 1 "general_operand" "qn,qm")))
5742 (clobber (reg:CC FLAGS_REG))]
5743 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5744 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5746 switch (get_attr_type (insn))
5749 if (operands[1] == const1_rtx)
5750 return "inc{b}\t%0";
5753 gcc_assert (operands[1] == constm1_rtx);
5754 return "dec{b}\t%0";
5758 if (x86_maybe_negate_const_int (&operands[1], QImode))
5759 return "sub{b}\t{%1, %0|%0, %1}";
5761 return "add{b}\t{%1, %0|%0, %1}";
5765 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5766 (const_string "incdec")
5767 (const_string "alu1")))
5768 (set (attr "memory")
5769 (if_then_else (match_operand 1 "memory_operand" "")
5770 (const_string "load")
5771 (const_string "none")))
5772 (set_attr "mode" "QI")])
5774 ;; Split non destructive adds if we cannot use lea.
5776 [(set (match_operand:SWI48 0 "register_operand" "")
5777 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5778 (match_operand:SWI48 2 "nonmemory_operand" "")))
5779 (clobber (reg:CC FLAGS_REG))]
5780 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5781 [(set (match_dup 0) (match_dup 1))
5782 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5783 (clobber (reg:CC FLAGS_REG))])])
5785 ;; Convert add to the lea pattern to avoid flags dependency.
5787 [(set (match_operand:SWI 0 "register_operand" "")
5788 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5789 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5790 (clobber (reg:CC FLAGS_REG))]
5791 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5794 enum machine_mode mode = <MODE>mode;
5797 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5800 operands[0] = gen_lowpart (mode, operands[0]);
5801 operands[1] = gen_lowpart (mode, operands[1]);
5802 operands[2] = gen_lowpart (mode, operands[2]);
5805 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5807 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5811 ;; Convert add to the lea pattern to avoid flags dependency.
5813 [(set (match_operand:DI 0 "register_operand" "")
5815 (plus:SI (match_operand:SI 1 "register_operand" "")
5816 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5817 (clobber (reg:CC FLAGS_REG))]
5818 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5820 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5822 (define_insn "*add<mode>_2"
5823 [(set (reg FLAGS_REG)
5826 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5827 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5829 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5830 (plus:SWI (match_dup 1) (match_dup 2)))]
5831 "ix86_match_ccmode (insn, CCGOCmode)
5832 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5834 switch (get_attr_type (insn))
5837 if (operands[2] == const1_rtx)
5838 return "inc{<imodesuffix>}\t%0";
5841 gcc_assert (operands[2] == constm1_rtx);
5842 return "dec{<imodesuffix>}\t%0";
5846 if (which_alternative == 2)
5849 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5852 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5853 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5854 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5856 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5860 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5861 (const_string "incdec")
5862 (const_string "alu")))
5863 (set (attr "length_immediate")
5865 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5867 (const_string "*")))
5868 (set_attr "mode" "<MODE>")])
5870 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5871 (define_insn "*addsi_2_zext"
5872 [(set (reg FLAGS_REG)
5874 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5875 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5877 (set (match_operand:DI 0 "register_operand" "=r,r")
5878 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5879 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5880 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5882 switch (get_attr_type (insn))
5885 if (operands[2] == const1_rtx)
5886 return "inc{l}\t%k0";
5889 gcc_assert (operands[2] == constm1_rtx);
5890 return "dec{l}\t%k0";
5894 if (which_alternative == 1)
5897 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5900 if (x86_maybe_negate_const_int (&operands[2], SImode))
5901 return "sub{l}\t{%2, %k0|%k0, %2}";
5903 return "add{l}\t{%2, %k0|%k0, %2}";
5907 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5908 (const_string "incdec")
5909 (const_string "alu")))
5910 (set (attr "length_immediate")
5912 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5914 (const_string "*")))
5915 (set_attr "mode" "SI")])
5917 (define_insn "*add<mode>_3"
5918 [(set (reg FLAGS_REG)
5920 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5921 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5922 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5923 "ix86_match_ccmode (insn, CCZmode)
5924 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5926 switch (get_attr_type (insn))
5929 if (operands[2] == const1_rtx)
5930 return "inc{<imodesuffix>}\t%0";
5933 gcc_assert (operands[2] == constm1_rtx);
5934 return "dec{<imodesuffix>}\t%0";
5938 if (which_alternative == 1)
5941 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5944 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5945 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5946 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5948 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5952 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5953 (const_string "incdec")
5954 (const_string "alu")))
5955 (set (attr "length_immediate")
5957 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5959 (const_string "*")))
5960 (set_attr "mode" "<MODE>")])
5962 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5963 (define_insn "*addsi_3_zext"
5964 [(set (reg FLAGS_REG)
5966 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5967 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5968 (set (match_operand:DI 0 "register_operand" "=r,r")
5969 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5970 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5971 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5973 switch (get_attr_type (insn))
5976 if (operands[2] == const1_rtx)
5977 return "inc{l}\t%k0";
5980 gcc_assert (operands[2] == constm1_rtx);
5981 return "dec{l}\t%k0";
5985 if (which_alternative == 1)
5988 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5991 if (x86_maybe_negate_const_int (&operands[2], SImode))
5992 return "sub{l}\t{%2, %k0|%k0, %2}";
5994 return "add{l}\t{%2, %k0|%k0, %2}";
5998 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5999 (const_string "incdec")
6000 (const_string "alu")))
6001 (set (attr "length_immediate")
6003 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6005 (const_string "*")))
6006 (set_attr "mode" "SI")])
6008 ; For comparisons against 1, -1 and 128, we may generate better code
6009 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6010 ; is matched then. We can't accept general immediate, because for
6011 ; case of overflows, the result is messed up.
6012 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6013 ; only for comparisons not depending on it.
6015 (define_insn "*adddi_4"
6016 [(set (reg FLAGS_REG)
6018 (match_operand:DI 1 "nonimmediate_operand" "0")
6019 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6020 (clobber (match_scratch:DI 0 "=rm"))]
6022 && ix86_match_ccmode (insn, CCGCmode)"
6024 switch (get_attr_type (insn))
6027 if (operands[2] == constm1_rtx)
6028 return "inc{q}\t%0";
6031 gcc_assert (operands[2] == const1_rtx);
6032 return "dec{q}\t%0";
6036 if (x86_maybe_negate_const_int (&operands[2], DImode))
6037 return "add{q}\t{%2, %0|%0, %2}";
6039 return "sub{q}\t{%2, %0|%0, %2}";
6043 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6044 (const_string "incdec")
6045 (const_string "alu")))
6046 (set (attr "length_immediate")
6048 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6050 (const_string "*")))
6051 (set_attr "mode" "DI")])
6053 ; For comparisons against 1, -1 and 128, we may generate better code
6054 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6055 ; is matched then. We can't accept general immediate, because for
6056 ; case of overflows, the result is messed up.
6057 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6058 ; only for comparisons not depending on it.
6060 (define_insn "*add<mode>_4"
6061 [(set (reg FLAGS_REG)
6063 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6064 (match_operand:SWI124 2 "const_int_operand" "n")))
6065 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6066 "ix86_match_ccmode (insn, CCGCmode)"
6068 switch (get_attr_type (insn))
6071 if (operands[2] == constm1_rtx)
6072 return "inc{<imodesuffix>}\t%0";
6075 gcc_assert (operands[2] == const1_rtx);
6076 return "dec{<imodesuffix>}\t%0";
6080 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6081 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6083 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6087 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6088 (const_string "incdec")
6089 (const_string "alu")))
6090 (set (attr "length_immediate")
6092 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6094 (const_string "*")))
6095 (set_attr "mode" "<MODE>")])
6097 (define_insn "*add<mode>_5"
6098 [(set (reg FLAGS_REG)
6101 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6102 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6104 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6105 "ix86_match_ccmode (insn, CCGOCmode)
6106 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6108 switch (get_attr_type (insn))
6111 if (operands[2] == const1_rtx)
6112 return "inc{<imodesuffix>}\t%0";
6115 gcc_assert (operands[2] == constm1_rtx);
6116 return "dec{<imodesuffix>}\t%0";
6120 if (which_alternative == 1)
6123 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6126 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6127 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6128 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6130 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6134 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6135 (const_string "incdec")
6136 (const_string "alu")))
6137 (set (attr "length_immediate")
6139 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6141 (const_string "*")))
6142 (set_attr "mode" "<MODE>")])
6144 (define_insn "*addqi_ext_1_rex64"
6145 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6150 (match_operand 1 "ext_register_operand" "0")
6153 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6154 (clobber (reg:CC FLAGS_REG))]
6157 switch (get_attr_type (insn))
6160 if (operands[2] == const1_rtx)
6161 return "inc{b}\t%h0";
6164 gcc_assert (operands[2] == constm1_rtx);
6165 return "dec{b}\t%h0";
6169 return "add{b}\t{%2, %h0|%h0, %2}";
6173 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6174 (const_string "incdec")
6175 (const_string "alu")))
6176 (set_attr "modrm" "1")
6177 (set_attr "mode" "QI")])
6179 (define_insn "addqi_ext_1"
6180 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6185 (match_operand 1 "ext_register_operand" "0")
6188 (match_operand:QI 2 "general_operand" "Qmn")))
6189 (clobber (reg:CC FLAGS_REG))]
6192 switch (get_attr_type (insn))
6195 if (operands[2] == const1_rtx)
6196 return "inc{b}\t%h0";
6199 gcc_assert (operands[2] == constm1_rtx);
6200 return "dec{b}\t%h0";
6204 return "add{b}\t{%2, %h0|%h0, %2}";
6208 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6209 (const_string "incdec")
6210 (const_string "alu")))
6211 (set_attr "modrm" "1")
6212 (set_attr "mode" "QI")])
6214 (define_insn "*addqi_ext_2"
6215 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6220 (match_operand 1 "ext_register_operand" "%0")
6224 (match_operand 2 "ext_register_operand" "Q")
6227 (clobber (reg:CC FLAGS_REG))]
6229 "add{b}\t{%h2, %h0|%h0, %h2}"
6230 [(set_attr "type" "alu")
6231 (set_attr "mode" "QI")])
6233 ;; The lea patterns for modes less than 32 bits need to be matched by
6234 ;; several insns converted to real lea by splitters.
6236 (define_insn_and_split "*lea_general_1"
6237 [(set (match_operand 0 "register_operand" "=r")
6238 (plus (plus (match_operand 1 "index_register_operand" "l")
6239 (match_operand 2 "register_operand" "r"))
6240 (match_operand 3 "immediate_operand" "i")))]
6241 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6242 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6243 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6244 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6245 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6246 || GET_MODE (operands[3]) == VOIDmode)"
6248 "&& reload_completed"
6251 enum machine_mode mode = SImode;
6254 operands[0] = gen_lowpart (mode, operands[0]);
6255 operands[1] = gen_lowpart (mode, operands[1]);
6256 operands[2] = gen_lowpart (mode, operands[2]);
6257 operands[3] = gen_lowpart (mode, operands[3]);
6259 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6262 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6265 [(set_attr "type" "lea")
6266 (set_attr "mode" "SI")])
6268 (define_insn_and_split "*lea_general_2"
6269 [(set (match_operand 0 "register_operand" "=r")
6270 (plus (mult (match_operand 1 "index_register_operand" "l")
6271 (match_operand 2 "const248_operand" "n"))
6272 (match_operand 3 "nonmemory_operand" "ri")))]
6273 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6274 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6275 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6276 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6277 || GET_MODE (operands[3]) == VOIDmode)"
6279 "&& reload_completed"
6282 enum machine_mode mode = SImode;
6285 operands[0] = gen_lowpart (mode, operands[0]);
6286 operands[1] = gen_lowpart (mode, operands[1]);
6287 operands[3] = gen_lowpart (mode, operands[3]);
6289 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6292 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6295 [(set_attr "type" "lea")
6296 (set_attr "mode" "SI")])
6298 (define_insn_and_split "*lea_general_3"
6299 [(set (match_operand 0 "register_operand" "=r")
6300 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6301 (match_operand 2 "const248_operand" "n"))
6302 (match_operand 3 "register_operand" "r"))
6303 (match_operand 4 "immediate_operand" "i")))]
6304 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6305 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6306 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6307 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6309 "&& reload_completed"
6312 enum machine_mode mode = SImode;
6315 operands[0] = gen_lowpart (mode, operands[0]);
6316 operands[1] = gen_lowpart (mode, operands[1]);
6317 operands[3] = gen_lowpart (mode, operands[3]);
6318 operands[4] = gen_lowpart (mode, operands[4]);
6320 pat = gen_rtx_PLUS (mode,
6322 gen_rtx_MULT (mode, operands[1],
6327 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6330 [(set_attr "type" "lea")
6331 (set_attr "mode" "SI")])
6333 (define_insn_and_split "*lea_general_4"
6334 [(set (match_operand 0 "register_operand" "=r")
6336 (match_operand 1 "index_register_operand" "l")
6337 (match_operand 2 "const_int_operand" "n"))
6338 (match_operand 3 "const_int_operand" "n")))]
6339 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6340 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6341 || GET_MODE (operands[0]) == SImode
6342 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6343 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6344 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6345 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6346 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6348 "&& reload_completed"
6351 enum machine_mode mode = GET_MODE (operands[0]);
6354 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6357 operands[0] = gen_lowpart (mode, operands[0]);
6358 operands[1] = gen_lowpart (mode, operands[1]);
6361 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6363 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6364 INTVAL (operands[3]));
6366 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6369 [(set_attr "type" "lea")
6371 (if_then_else (match_operand:DI 0 "" "")
6373 (const_string "SI")))])
6375 ;; Subtract instructions
6377 (define_expand "sub<mode>3"
6378 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6379 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6380 (match_operand:SDWIM 2 "<general_operand>" "")))]
6382 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6384 (define_insn_and_split "*sub<dwi>3_doubleword"
6385 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6387 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6388 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6389 (clobber (reg:CC FLAGS_REG))]
6390 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6393 [(parallel [(set (reg:CC FLAGS_REG)
6394 (compare:CC (match_dup 1) (match_dup 2)))
6396 (minus:DWIH (match_dup 1) (match_dup 2)))])
6397 (parallel [(set (match_dup 3)
6401 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6403 (clobber (reg:CC FLAGS_REG))])]
6404 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6406 (define_insn "*sub<mode>_1"
6407 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6409 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6410 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6411 (clobber (reg:CC FLAGS_REG))]
6412 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6413 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6414 [(set_attr "type" "alu")
6415 (set_attr "mode" "<MODE>")])
6417 (define_insn "*subsi_1_zext"
6418 [(set (match_operand:DI 0 "register_operand" "=r")
6420 (minus:SI (match_operand:SI 1 "register_operand" "0")
6421 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6422 (clobber (reg:CC FLAGS_REG))]
6423 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6424 "sub{l}\t{%2, %k0|%k0, %2}"
6425 [(set_attr "type" "alu")
6426 (set_attr "mode" "SI")])
6428 (define_insn "*subqi_1_slp"
6429 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6430 (minus:QI (match_dup 0)
6431 (match_operand:QI 1 "general_operand" "qn,qm")))
6432 (clobber (reg:CC FLAGS_REG))]
6433 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6434 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6435 "sub{b}\t{%1, %0|%0, %1}"
6436 [(set_attr "type" "alu1")
6437 (set_attr "mode" "QI")])
6439 (define_insn "*sub<mode>_2"
6440 [(set (reg FLAGS_REG)
6443 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6444 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6446 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6447 (minus:SWI (match_dup 1) (match_dup 2)))]
6448 "ix86_match_ccmode (insn, CCGOCmode)
6449 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6450 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6451 [(set_attr "type" "alu")
6452 (set_attr "mode" "<MODE>")])
6454 (define_insn "*subsi_2_zext"
6455 [(set (reg FLAGS_REG)
6457 (minus:SI (match_operand:SI 1 "register_operand" "0")
6458 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6460 (set (match_operand:DI 0 "register_operand" "=r")
6462 (minus:SI (match_dup 1)
6464 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6465 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6466 "sub{l}\t{%2, %k0|%k0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "SI")])
6470 (define_insn "*sub<mode>_3"
6471 [(set (reg FLAGS_REG)
6472 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6473 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6474 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6475 (minus:SWI (match_dup 1) (match_dup 2)))]
6476 "ix86_match_ccmode (insn, CCmode)
6477 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6478 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6479 [(set_attr "type" "alu")
6480 (set_attr "mode" "<MODE>")])
6482 (define_insn "*subsi_3_zext"
6483 [(set (reg FLAGS_REG)
6484 (compare (match_operand:SI 1 "register_operand" "0")
6485 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6486 (set (match_operand:DI 0 "register_operand" "=r")
6488 (minus:SI (match_dup 1)
6490 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6491 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6492 "sub{l}\t{%2, %1|%1, %2}"
6493 [(set_attr "type" "alu")
6494 (set_attr "mode" "SI")])
6496 ;; Add with carry and subtract with borrow
6498 (define_expand "<plusminus_insn><mode>3_carry"
6500 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6502 (match_operand:SWI 1 "nonimmediate_operand" "")
6503 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6504 [(match_operand 3 "flags_reg_operand" "")
6506 (match_operand:SWI 2 "<general_operand>" ""))))
6507 (clobber (reg:CC FLAGS_REG))])]
6508 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6510 (define_insn "*<plusminus_insn><mode>3_carry"
6511 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6513 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6515 (match_operator 3 "ix86_carry_flag_operator"
6516 [(reg FLAGS_REG) (const_int 0)])
6517 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6518 (clobber (reg:CC FLAGS_REG))]
6519 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6520 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6521 [(set_attr "type" "alu")
6522 (set_attr "use_carry" "1")
6523 (set_attr "pent_pair" "pu")
6524 (set_attr "mode" "<MODE>")])
6526 (define_insn "*addsi3_carry_zext"
6527 [(set (match_operand:DI 0 "register_operand" "=r")
6529 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6530 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6531 [(reg FLAGS_REG) (const_int 0)])
6532 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6533 (clobber (reg:CC FLAGS_REG))]
6534 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6535 "adc{l}\t{%2, %k0|%k0, %2}"
6536 [(set_attr "type" "alu")
6537 (set_attr "use_carry" "1")
6538 (set_attr "pent_pair" "pu")
6539 (set_attr "mode" "SI")])
6541 (define_insn "*subsi3_carry_zext"
6542 [(set (match_operand:DI 0 "register_operand" "=r")
6544 (minus:SI (match_operand:SI 1 "register_operand" "0")
6545 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6546 [(reg FLAGS_REG) (const_int 0)])
6547 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6548 (clobber (reg:CC FLAGS_REG))]
6549 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6550 "sbb{l}\t{%2, %k0|%k0, %2}"
6551 [(set_attr "type" "alu")
6552 (set_attr "pent_pair" "pu")
6553 (set_attr "mode" "SI")])
6555 ;; Overflow setting add and subtract instructions
6557 (define_insn "*add<mode>3_cconly_overflow"
6558 [(set (reg:CCC FLAGS_REG)
6561 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6562 (match_operand:SWI 2 "<general_operand>" "<g>"))
6564 (clobber (match_scratch:SWI 0 "=<r>"))]
6565 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6566 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6567 [(set_attr "type" "alu")
6568 (set_attr "mode" "<MODE>")])
6570 (define_insn "*sub<mode>3_cconly_overflow"
6571 [(set (reg:CCC FLAGS_REG)
6574 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6575 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6578 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6579 [(set_attr "type" "icmp")
6580 (set_attr "mode" "<MODE>")])
6582 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6583 [(set (reg:CCC FLAGS_REG)
6586 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6587 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6589 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6590 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6591 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6592 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6593 [(set_attr "type" "alu")
6594 (set_attr "mode" "<MODE>")])
6596 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6597 [(set (reg:CCC FLAGS_REG)
6600 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6601 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6603 (set (match_operand:DI 0 "register_operand" "=r")
6604 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6605 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6606 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6607 [(set_attr "type" "alu")
6608 (set_attr "mode" "SI")])
6610 ;; The patterns that match these are at the end of this file.
6612 (define_expand "<plusminus_insn>xf3"
6613 [(set (match_operand:XF 0 "register_operand" "")
6615 (match_operand:XF 1 "register_operand" "")
6616 (match_operand:XF 2 "register_operand" "")))]
6619 (define_expand "<plusminus_insn><mode>3"
6620 [(set (match_operand:MODEF 0 "register_operand" "")
6622 (match_operand:MODEF 1 "register_operand" "")
6623 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6624 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6625 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6627 ;; Multiply instructions
6629 (define_expand "mul<mode>3"
6630 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6632 (match_operand:SWIM248 1 "register_operand" "")
6633 (match_operand:SWIM248 2 "<general_operand>" "")))
6634 (clobber (reg:CC FLAGS_REG))])])
6636 (define_expand "mulqi3"
6637 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6639 (match_operand:QI 1 "register_operand" "")
6640 (match_operand:QI 2 "nonimmediate_operand" "")))
6641 (clobber (reg:CC FLAGS_REG))])]
6642 "TARGET_QIMODE_MATH")
6645 ;; IMUL reg32/64, reg32/64, imm8 Direct
6646 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6647 ;; IMUL reg32/64, reg32/64, imm32 Direct
6648 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6649 ;; IMUL reg32/64, reg32/64 Direct
6650 ;; IMUL reg32/64, mem32/64 Direct
6652 ;; On BDVER1, all above IMULs use DirectPath
6654 (define_insn "*mul<mode>3_1"
6655 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6657 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6658 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6659 (clobber (reg:CC FLAGS_REG))]
6660 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6662 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6663 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6664 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6665 [(set_attr "type" "imul")
6666 (set_attr "prefix_0f" "0,0,1")
6667 (set (attr "athlon_decode")
6668 (cond [(eq_attr "cpu" "athlon")
6669 (const_string "vector")
6670 (eq_attr "alternative" "1")
6671 (const_string "vector")
6672 (and (eq_attr "alternative" "2")
6673 (match_operand 1 "memory_operand" ""))
6674 (const_string "vector")]
6675 (const_string "direct")))
6676 (set (attr "amdfam10_decode")
6677 (cond [(and (eq_attr "alternative" "0,1")
6678 (match_operand 1 "memory_operand" ""))
6679 (const_string "vector")]
6680 (const_string "direct")))
6681 (set_attr "bdver1_decode" "direct")
6682 (set_attr "mode" "<MODE>")])
6684 (define_insn "*mulsi3_1_zext"
6685 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6687 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6688 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6689 (clobber (reg:CC FLAGS_REG))]
6691 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6693 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6694 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6695 imul{l}\t{%2, %k0|%k0, %2}"
6696 [(set_attr "type" "imul")
6697 (set_attr "prefix_0f" "0,0,1")
6698 (set (attr "athlon_decode")
6699 (cond [(eq_attr "cpu" "athlon")
6700 (const_string "vector")
6701 (eq_attr "alternative" "1")
6702 (const_string "vector")
6703 (and (eq_attr "alternative" "2")
6704 (match_operand 1 "memory_operand" ""))
6705 (const_string "vector")]
6706 (const_string "direct")))
6707 (set (attr "amdfam10_decode")
6708 (cond [(and (eq_attr "alternative" "0,1")
6709 (match_operand 1 "memory_operand" ""))
6710 (const_string "vector")]
6711 (const_string "direct")))
6712 (set_attr "bdver1_decode" "direct")
6713 (set_attr "mode" "SI")])
6716 ;; IMUL reg16, reg16, imm8 VectorPath
6717 ;; IMUL reg16, mem16, imm8 VectorPath
6718 ;; IMUL reg16, reg16, imm16 VectorPath
6719 ;; IMUL reg16, mem16, imm16 VectorPath
6720 ;; IMUL reg16, reg16 Direct
6721 ;; IMUL reg16, mem16 Direct
6723 ;; On BDVER1, all HI MULs use DoublePath
6725 (define_insn "*mulhi3_1"
6726 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6727 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6728 (match_operand:HI 2 "general_operand" "K,n,mr")))
6729 (clobber (reg:CC FLAGS_REG))]
6731 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6733 imul{w}\t{%2, %1, %0|%0, %1, %2}
6734 imul{w}\t{%2, %1, %0|%0, %1, %2}
6735 imul{w}\t{%2, %0|%0, %2}"
6736 [(set_attr "type" "imul")
6737 (set_attr "prefix_0f" "0,0,1")
6738 (set (attr "athlon_decode")
6739 (cond [(eq_attr "cpu" "athlon")
6740 (const_string "vector")
6741 (eq_attr "alternative" "1,2")
6742 (const_string "vector")]
6743 (const_string "direct")))
6744 (set (attr "amdfam10_decode")
6745 (cond [(eq_attr "alternative" "0,1")
6746 (const_string "vector")]
6747 (const_string "direct")))
6748 (set_attr "bdver1_decode" "double")
6749 (set_attr "mode" "HI")])
6751 ;;On AMDFAM10 and BDVER1
6755 (define_insn "*mulqi3_1"
6756 [(set (match_operand:QI 0 "register_operand" "=a")
6757 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6758 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6759 (clobber (reg:CC FLAGS_REG))]
6761 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6763 [(set_attr "type" "imul")
6764 (set_attr "length_immediate" "0")
6765 (set (attr "athlon_decode")
6766 (if_then_else (eq_attr "cpu" "athlon")
6767 (const_string "vector")
6768 (const_string "direct")))
6769 (set_attr "amdfam10_decode" "direct")
6770 (set_attr "bdver1_decode" "direct")
6771 (set_attr "mode" "QI")])
6773 (define_expand "<u>mul<mode><dwi>3"
6774 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6777 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6779 (match_operand:DWIH 2 "register_operand" ""))))
6780 (clobber (reg:CC FLAGS_REG))])])
6782 (define_expand "<u>mulqihi3"
6783 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6786 (match_operand:QI 1 "nonimmediate_operand" ""))
6788 (match_operand:QI 2 "register_operand" ""))))
6789 (clobber (reg:CC FLAGS_REG))])]
6790 "TARGET_QIMODE_MATH")
6792 (define_insn "*bmi2_umulditi3_1"
6793 [(set (match_operand:DI 0 "register_operand" "=r")
6795 (match_operand:DI 2 "nonimmediate_operand" "%d")
6796 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6797 (set (match_operand:DI 1 "register_operand" "=r")
6800 (mult:TI (zero_extend:TI (match_dup 2))
6801 (zero_extend:TI (match_dup 3)))
6803 "TARGET_64BIT && TARGET_BMI2
6804 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6805 "mulx\t{%3, %0, %1|%1, %0, %3}"
6806 [(set_attr "type" "imulx")
6807 (set_attr "prefix" "vex")
6808 (set_attr "mode" "DI")])
6810 (define_insn "*bmi2_umulsidi3_1"
6811 [(set (match_operand:SI 0 "register_operand" "=r")
6813 (match_operand:SI 2 "nonimmediate_operand" "%d")
6814 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6815 (set (match_operand:SI 1 "register_operand" "=r")
6818 (mult:DI (zero_extend:DI (match_dup 2))
6819 (zero_extend:DI (match_dup 3)))
6821 "!TARGET_64BIT && TARGET_BMI2
6822 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6823 "mulx\t{%3, %0, %1|%1, %0, %3}"
6824 [(set_attr "type" "imulx")
6825 (set_attr "prefix" "vex")
6826 (set_attr "mode" "SI")])
6828 (define_insn "*umul<mode><dwi>3_1"
6829 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6832 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6834 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6835 (clobber (reg:CC FLAGS_REG))]
6836 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6838 mul{<imodesuffix>}\t%2
6840 [(set_attr "isa" "*,bmi2")
6841 (set_attr "type" "imul,imulx")
6842 (set_attr "length_immediate" "0,*")
6843 (set (attr "athlon_decode")
6844 (cond [(eq_attr "alternative" "0")
6845 (if_then_else (eq_attr "cpu" "athlon")
6846 (const_string "vector")
6847 (const_string "double"))]
6848 (const_string "*")))
6849 (set_attr "amdfam10_decode" "double,*")
6850 (set_attr "bdver1_decode" "direct,*")
6851 (set_attr "prefix" "orig,vex")
6852 (set_attr "mode" "<MODE>")])
6854 ;; Convert mul to the mulx pattern to avoid flags dependency.
6856 [(set (match_operand:<DWI> 0 "register_operand" "")
6859 (match_operand:DWIH 1 "register_operand" ""))
6861 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6862 (clobber (reg:CC FLAGS_REG))]
6863 "TARGET_BMI2 && reload_completed
6864 && true_regnum (operands[1]) == DX_REG"
6865 [(parallel [(set (match_dup 3)
6866 (mult:DWIH (match_dup 1) (match_dup 2)))
6870 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6871 (zero_extend:<DWI> (match_dup 2)))
6874 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6876 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6879 (define_insn "*mul<mode><dwi>3_1"
6880 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6883 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6885 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6886 (clobber (reg:CC FLAGS_REG))]
6887 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6888 "imul{<imodesuffix>}\t%2"
6889 [(set_attr "type" "imul")
6890 (set_attr "length_immediate" "0")
6891 (set (attr "athlon_decode")
6892 (if_then_else (eq_attr "cpu" "athlon")
6893 (const_string "vector")
6894 (const_string "double")))
6895 (set_attr "amdfam10_decode" "double")
6896 (set_attr "bdver1_decode" "direct")
6897 (set_attr "mode" "<MODE>")])
6899 (define_insn "*<u>mulqihi3_1"
6900 [(set (match_operand:HI 0 "register_operand" "=a")
6903 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6905 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6906 (clobber (reg:CC FLAGS_REG))]
6908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6909 "<sgnprefix>mul{b}\t%2"
6910 [(set_attr "type" "imul")
6911 (set_attr "length_immediate" "0")
6912 (set (attr "athlon_decode")
6913 (if_then_else (eq_attr "cpu" "athlon")
6914 (const_string "vector")
6915 (const_string "direct")))
6916 (set_attr "amdfam10_decode" "direct")
6917 (set_attr "bdver1_decode" "direct")
6918 (set_attr "mode" "QI")])
6920 (define_expand "<s>mul<mode>3_highpart"
6921 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6926 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6928 (match_operand:SWI48 2 "register_operand" "")))
6930 (clobber (match_scratch:SWI48 3 ""))
6931 (clobber (reg:CC FLAGS_REG))])]
6933 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6935 (define_insn "*<s>muldi3_highpart_1"
6936 [(set (match_operand:DI 0 "register_operand" "=d")
6941 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6943 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6945 (clobber (match_scratch:DI 3 "=1"))
6946 (clobber (reg:CC FLAGS_REG))]
6948 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6949 "<sgnprefix>mul{q}\t%2"
6950 [(set_attr "type" "imul")
6951 (set_attr "length_immediate" "0")
6952 (set (attr "athlon_decode")
6953 (if_then_else (eq_attr "cpu" "athlon")
6954 (const_string "vector")
6955 (const_string "double")))
6956 (set_attr "amdfam10_decode" "double")
6957 (set_attr "bdver1_decode" "direct")
6958 (set_attr "mode" "DI")])
6960 (define_insn "*<s>mulsi3_highpart_1"
6961 [(set (match_operand:SI 0 "register_operand" "=d")
6966 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6968 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6970 (clobber (match_scratch:SI 3 "=1"))
6971 (clobber (reg:CC FLAGS_REG))]
6972 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6973 "<sgnprefix>mul{l}\t%2"
6974 [(set_attr "type" "imul")
6975 (set_attr "length_immediate" "0")
6976 (set (attr "athlon_decode")
6977 (if_then_else (eq_attr "cpu" "athlon")
6978 (const_string "vector")
6979 (const_string "double")))
6980 (set_attr "amdfam10_decode" "double")
6981 (set_attr "bdver1_decode" "direct")
6982 (set_attr "mode" "SI")])
6984 (define_insn "*<s>mulsi3_highpart_zext"
6985 [(set (match_operand:DI 0 "register_operand" "=d")
6986 (zero_extend:DI (truncate:SI
6988 (mult:DI (any_extend:DI
6989 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6991 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6993 (clobber (match_scratch:SI 3 "=1"))
6994 (clobber (reg:CC FLAGS_REG))]
6996 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6997 "<sgnprefix>mul{l}\t%2"
6998 [(set_attr "type" "imul")
6999 (set_attr "length_immediate" "0")
7000 (set (attr "athlon_decode")
7001 (if_then_else (eq_attr "cpu" "athlon")
7002 (const_string "vector")
7003 (const_string "double")))
7004 (set_attr "amdfam10_decode" "double")
7005 (set_attr "bdver1_decode" "direct")
7006 (set_attr "mode" "SI")])
7008 ;; The patterns that match these are at the end of this file.
7010 (define_expand "mulxf3"
7011 [(set (match_operand:XF 0 "register_operand" "")
7012 (mult:XF (match_operand:XF 1 "register_operand" "")
7013 (match_operand:XF 2 "register_operand" "")))]
7016 (define_expand "mul<mode>3"
7017 [(set (match_operand:MODEF 0 "register_operand" "")
7018 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7019 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7020 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7021 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7023 ;; Divide instructions
7025 ;; The patterns that match these are at the end of this file.
7027 (define_expand "divxf3"
7028 [(set (match_operand:XF 0 "register_operand" "")
7029 (div:XF (match_operand:XF 1 "register_operand" "")
7030 (match_operand:XF 2 "register_operand" "")))]
7033 (define_expand "divdf3"
7034 [(set (match_operand:DF 0 "register_operand" "")
7035 (div:DF (match_operand:DF 1 "register_operand" "")
7036 (match_operand:DF 2 "nonimmediate_operand" "")))]
7037 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7038 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7040 (define_expand "divsf3"
7041 [(set (match_operand:SF 0 "register_operand" "")
7042 (div:SF (match_operand:SF 1 "register_operand" "")
7043 (match_operand:SF 2 "nonimmediate_operand" "")))]
7044 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7049 && optimize_insn_for_speed_p ()
7050 && flag_finite_math_only && !flag_trapping_math
7051 && flag_unsafe_math_optimizations)
7053 ix86_emit_swdivsf (operands[0], operands[1],
7054 operands[2], SFmode);
7059 ;; Divmod instructions.
7061 (define_expand "divmod<mode>4"
7062 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7064 (match_operand:SWIM248 1 "register_operand" "")
7065 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7066 (set (match_operand:SWIM248 3 "register_operand" "")
7067 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7068 (clobber (reg:CC FLAGS_REG))])])
7070 ;; Split with 8bit unsigned divide:
7071 ;; if (dividend an divisor are in [0-255])
7072 ;; use 8bit unsigned integer divide
7074 ;; use original integer divide
7076 [(set (match_operand:SWI48 0 "register_operand" "")
7077 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7078 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7079 (set (match_operand:SWI48 1 "register_operand" "")
7080 (mod:SWI48 (match_dup 2) (match_dup 3)))
7081 (clobber (reg:CC FLAGS_REG))]
7082 "TARGET_USE_8BIT_IDIV
7083 && TARGET_QIMODE_MATH
7084 && can_create_pseudo_p ()
7085 && !optimize_insn_for_size_p ()"
7087 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7089 (define_insn_and_split "divmod<mode>4_1"
7090 [(set (match_operand:SWI48 0 "register_operand" "=a")
7091 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7092 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7093 (set (match_operand:SWI48 1 "register_operand" "=&d")
7094 (mod:SWI48 (match_dup 2) (match_dup 3)))
7095 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7096 (clobber (reg:CC FLAGS_REG))]
7100 [(parallel [(set (match_dup 1)
7101 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7102 (clobber (reg:CC FLAGS_REG))])
7103 (parallel [(set (match_dup 0)
7104 (div:SWI48 (match_dup 2) (match_dup 3)))
7106 (mod:SWI48 (match_dup 2) (match_dup 3)))
7108 (clobber (reg:CC FLAGS_REG))])]
7110 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7112 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7113 operands[4] = operands[2];
7116 /* Avoid use of cltd in favor of a mov+shift. */
7117 emit_move_insn (operands[1], operands[2]);
7118 operands[4] = operands[1];
7121 [(set_attr "type" "multi")
7122 (set_attr "mode" "<MODE>")])
7124 (define_insn_and_split "*divmod<mode>4"
7125 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7126 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7127 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7128 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7129 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7130 (clobber (reg:CC FLAGS_REG))]
7134 [(parallel [(set (match_dup 1)
7135 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7136 (clobber (reg:CC FLAGS_REG))])
7137 (parallel [(set (match_dup 0)
7138 (div:SWIM248 (match_dup 2) (match_dup 3)))
7140 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7142 (clobber (reg:CC FLAGS_REG))])]
7144 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7146 if (<MODE>mode != HImode
7147 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7148 operands[4] = operands[2];
7151 /* Avoid use of cltd in favor of a mov+shift. */
7152 emit_move_insn (operands[1], operands[2]);
7153 operands[4] = operands[1];
7156 [(set_attr "type" "multi")
7157 (set_attr "mode" "<MODE>")])
7159 (define_insn "*divmod<mode>4_noext"
7160 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7161 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7162 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7163 (set (match_operand:SWIM248 1 "register_operand" "=d")
7164 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7165 (use (match_operand:SWIM248 4 "register_operand" "1"))
7166 (clobber (reg:CC FLAGS_REG))]
7168 "idiv{<imodesuffix>}\t%3"
7169 [(set_attr "type" "idiv")
7170 (set_attr "mode" "<MODE>")])
7172 (define_expand "divmodqi4"
7173 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7175 (match_operand:QI 1 "register_operand" "")
7176 (match_operand:QI 2 "nonimmediate_operand" "")))
7177 (set (match_operand:QI 3 "register_operand" "")
7178 (mod:QI (match_dup 1) (match_dup 2)))
7179 (clobber (reg:CC FLAGS_REG))])]
7180 "TARGET_QIMODE_MATH"
7185 tmp0 = gen_reg_rtx (HImode);
7186 tmp1 = gen_reg_rtx (HImode);
7188 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7190 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7191 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7193 /* Extract remainder from AH. */
7194 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7195 insn = emit_move_insn (operands[3], tmp1);
7197 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7198 set_unique_reg_note (insn, REG_EQUAL, mod);
7200 /* Extract quotient from AL. */
7201 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7203 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7204 set_unique_reg_note (insn, REG_EQUAL, div);
7209 ;; Divide AX by r/m8, with result stored in
7212 ;; Change div/mod to HImode and extend the second argument to HImode
7213 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7214 ;; combine may fail.
7215 (define_insn "divmodhiqi3"
7216 [(set (match_operand:HI 0 "register_operand" "=a")
7221 (mod:HI (match_operand:HI 1 "register_operand" "0")
7223 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7227 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7228 (clobber (reg:CC FLAGS_REG))]
7229 "TARGET_QIMODE_MATH"
7231 [(set_attr "type" "idiv")
7232 (set_attr "mode" "QI")])
7234 (define_expand "udivmod<mode>4"
7235 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7237 (match_operand:SWIM248 1 "register_operand" "")
7238 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7239 (set (match_operand:SWIM248 3 "register_operand" "")
7240 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7241 (clobber (reg:CC FLAGS_REG))])])
7243 ;; Split with 8bit unsigned divide:
7244 ;; if (dividend an divisor are in [0-255])
7245 ;; use 8bit unsigned integer divide
7247 ;; use original integer divide
7249 [(set (match_operand:SWI48 0 "register_operand" "")
7250 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7251 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7252 (set (match_operand:SWI48 1 "register_operand" "")
7253 (umod:SWI48 (match_dup 2) (match_dup 3)))
7254 (clobber (reg:CC FLAGS_REG))]
7255 "TARGET_USE_8BIT_IDIV
7256 && TARGET_QIMODE_MATH
7257 && can_create_pseudo_p ()
7258 && !optimize_insn_for_size_p ()"
7260 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7262 (define_insn_and_split "udivmod<mode>4_1"
7263 [(set (match_operand:SWI48 0 "register_operand" "=a")
7264 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7265 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7266 (set (match_operand:SWI48 1 "register_operand" "=&d")
7267 (umod:SWI48 (match_dup 2) (match_dup 3)))
7268 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7269 (clobber (reg:CC FLAGS_REG))]
7273 [(set (match_dup 1) (const_int 0))
7274 (parallel [(set (match_dup 0)
7275 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7277 (umod:SWI48 (match_dup 2) (match_dup 3)))
7279 (clobber (reg:CC FLAGS_REG))])]
7281 [(set_attr "type" "multi")
7282 (set_attr "mode" "<MODE>")])
7284 (define_insn_and_split "*udivmod<mode>4"
7285 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7286 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7287 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7288 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7289 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7290 (clobber (reg:CC FLAGS_REG))]
7294 [(set (match_dup 1) (const_int 0))
7295 (parallel [(set (match_dup 0)
7296 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7298 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7300 (clobber (reg:CC FLAGS_REG))])]
7302 [(set_attr "type" "multi")
7303 (set_attr "mode" "<MODE>")])
7305 (define_insn "*udivmod<mode>4_noext"
7306 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7307 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7308 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7309 (set (match_operand:SWIM248 1 "register_operand" "=d")
7310 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7311 (use (match_operand:SWIM248 4 "register_operand" "1"))
7312 (clobber (reg:CC FLAGS_REG))]
7314 "div{<imodesuffix>}\t%3"
7315 [(set_attr "type" "idiv")
7316 (set_attr "mode" "<MODE>")])
7318 (define_expand "udivmodqi4"
7319 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7321 (match_operand:QI 1 "register_operand" "")
7322 (match_operand:QI 2 "nonimmediate_operand" "")))
7323 (set (match_operand:QI 3 "register_operand" "")
7324 (umod:QI (match_dup 1) (match_dup 2)))
7325 (clobber (reg:CC FLAGS_REG))])]
7326 "TARGET_QIMODE_MATH"
7331 tmp0 = gen_reg_rtx (HImode);
7332 tmp1 = gen_reg_rtx (HImode);
7334 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7336 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7337 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7339 /* Extract remainder from AH. */
7340 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7341 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7342 insn = emit_move_insn (operands[3], tmp1);
7344 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7345 set_unique_reg_note (insn, REG_EQUAL, mod);
7347 /* Extract quotient from AL. */
7348 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7350 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7351 set_unique_reg_note (insn, REG_EQUAL, div);
7356 (define_insn "udivmodhiqi3"
7357 [(set (match_operand:HI 0 "register_operand" "=a")
7362 (mod:HI (match_operand:HI 1 "register_operand" "0")
7364 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7368 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7369 (clobber (reg:CC FLAGS_REG))]
7370 "TARGET_QIMODE_MATH"
7372 [(set_attr "type" "idiv")
7373 (set_attr "mode" "QI")])
7375 ;; We cannot use div/idiv for double division, because it causes
7376 ;; "division by zero" on the overflow and that's not what we expect
7377 ;; from truncate. Because true (non truncating) double division is
7378 ;; never generated, we can't create this insn anyway.
7381 ; [(set (match_operand:SI 0 "register_operand" "=a")
7383 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7385 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7386 ; (set (match_operand:SI 3 "register_operand" "=d")
7388 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7389 ; (clobber (reg:CC FLAGS_REG))]
7391 ; "div{l}\t{%2, %0|%0, %2}"
7392 ; [(set_attr "type" "idiv")])
7394 ;;- Logical AND instructions
7396 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7397 ;; Note that this excludes ah.
7399 (define_expand "testsi_ccno_1"
7400 [(set (reg:CCNO FLAGS_REG)
7402 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7403 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7406 (define_expand "testqi_ccz_1"
7407 [(set (reg:CCZ FLAGS_REG)
7408 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7409 (match_operand:QI 1 "nonmemory_operand" ""))
7412 (define_expand "testdi_ccno_1"
7413 [(set (reg:CCNO FLAGS_REG)
7415 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7416 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7418 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7420 (define_insn "*testdi_1"
7421 [(set (reg FLAGS_REG)
7424 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7425 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7427 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7428 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7430 test{l}\t{%k1, %k0|%k0, %k1}
7431 test{l}\t{%k1, %k0|%k0, %k1}
7432 test{q}\t{%1, %0|%0, %1}
7433 test{q}\t{%1, %0|%0, %1}
7434 test{q}\t{%1, %0|%0, %1}"
7435 [(set_attr "type" "test")
7436 (set_attr "modrm" "0,1,0,1,1")
7437 (set_attr "mode" "SI,SI,DI,DI,DI")])
7439 (define_insn "*testqi_1_maybe_si"
7440 [(set (reg FLAGS_REG)
7443 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7444 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7446 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7447 && ix86_match_ccmode (insn,
7448 CONST_INT_P (operands[1])
7449 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7451 if (which_alternative == 3)
7453 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7454 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7455 return "test{l}\t{%1, %k0|%k0, %1}";
7457 return "test{b}\t{%1, %0|%0, %1}";
7459 [(set_attr "type" "test")
7460 (set_attr "modrm" "0,1,1,1")
7461 (set_attr "mode" "QI,QI,QI,SI")
7462 (set_attr "pent_pair" "uv,np,uv,np")])
7464 (define_insn "*test<mode>_1"
7465 [(set (reg FLAGS_REG)
7468 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7469 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7471 "ix86_match_ccmode (insn, CCNOmode)
7472 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7473 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7474 [(set_attr "type" "test")
7475 (set_attr "modrm" "0,1,1")
7476 (set_attr "mode" "<MODE>")
7477 (set_attr "pent_pair" "uv,np,uv")])
7479 (define_expand "testqi_ext_ccno_0"
7480 [(set (reg:CCNO FLAGS_REG)
7484 (match_operand 0 "ext_register_operand" "")
7487 (match_operand 1 "const_int_operand" ""))
7490 (define_insn "*testqi_ext_0"
7491 [(set (reg FLAGS_REG)
7495 (match_operand 0 "ext_register_operand" "Q")
7498 (match_operand 1 "const_int_operand" "n"))
7500 "ix86_match_ccmode (insn, CCNOmode)"
7501 "test{b}\t{%1, %h0|%h0, %1}"
7502 [(set_attr "type" "test")
7503 (set_attr "mode" "QI")
7504 (set_attr "length_immediate" "1")
7505 (set_attr "modrm" "1")
7506 (set_attr "pent_pair" "np")])
7508 (define_insn "*testqi_ext_1_rex64"
7509 [(set (reg FLAGS_REG)
7513 (match_operand 0 "ext_register_operand" "Q")
7517 (match_operand:QI 1 "register_operand" "Q")))
7519 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7520 "test{b}\t{%1, %h0|%h0, %1}"
7521 [(set_attr "type" "test")
7522 (set_attr "mode" "QI")])
7524 (define_insn "*testqi_ext_1"
7525 [(set (reg FLAGS_REG)
7529 (match_operand 0 "ext_register_operand" "Q")
7533 (match_operand:QI 1 "general_operand" "Qm")))
7535 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7536 "test{b}\t{%1, %h0|%h0, %1}"
7537 [(set_attr "type" "test")
7538 (set_attr "mode" "QI")])
7540 (define_insn "*testqi_ext_2"
7541 [(set (reg FLAGS_REG)
7545 (match_operand 0 "ext_register_operand" "Q")
7549 (match_operand 1 "ext_register_operand" "Q")
7553 "ix86_match_ccmode (insn, CCNOmode)"
7554 "test{b}\t{%h1, %h0|%h0, %h1}"
7555 [(set_attr "type" "test")
7556 (set_attr "mode" "QI")])
7558 (define_insn "*testqi_ext_3_rex64"
7559 [(set (reg FLAGS_REG)
7560 (compare (zero_extract:DI
7561 (match_operand 0 "nonimmediate_operand" "rm")
7562 (match_operand:DI 1 "const_int_operand" "")
7563 (match_operand:DI 2 "const_int_operand" ""))
7566 && ix86_match_ccmode (insn, CCNOmode)
7567 && INTVAL (operands[1]) > 0
7568 && INTVAL (operands[2]) >= 0
7569 /* Ensure that resulting mask is zero or sign extended operand. */
7570 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7571 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7572 && INTVAL (operands[1]) > 32))
7573 && (GET_MODE (operands[0]) == SImode
7574 || GET_MODE (operands[0]) == DImode
7575 || GET_MODE (operands[0]) == HImode
7576 || GET_MODE (operands[0]) == QImode)"
7579 ;; Combine likes to form bit extractions for some tests. Humor it.
7580 (define_insn "*testqi_ext_3"
7581 [(set (reg FLAGS_REG)
7582 (compare (zero_extract:SI
7583 (match_operand 0 "nonimmediate_operand" "rm")
7584 (match_operand:SI 1 "const_int_operand" "")
7585 (match_operand:SI 2 "const_int_operand" ""))
7587 "ix86_match_ccmode (insn, CCNOmode)
7588 && INTVAL (operands[1]) > 0
7589 && INTVAL (operands[2]) >= 0
7590 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7591 && (GET_MODE (operands[0]) == SImode
7592 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7593 || GET_MODE (operands[0]) == HImode
7594 || GET_MODE (operands[0]) == QImode)"
7598 [(set (match_operand 0 "flags_reg_operand" "")
7599 (match_operator 1 "compare_operator"
7601 (match_operand 2 "nonimmediate_operand" "")
7602 (match_operand 3 "const_int_operand" "")
7603 (match_operand 4 "const_int_operand" ""))
7605 "ix86_match_ccmode (insn, CCNOmode)"
7606 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7608 rtx val = operands[2];
7609 HOST_WIDE_INT len = INTVAL (operands[3]);
7610 HOST_WIDE_INT pos = INTVAL (operands[4]);
7612 enum machine_mode mode, submode;
7614 mode = GET_MODE (val);
7617 /* ??? Combine likes to put non-volatile mem extractions in QImode
7618 no matter the size of the test. So find a mode that works. */
7619 if (! MEM_VOLATILE_P (val))
7621 mode = smallest_mode_for_size (pos + len, MODE_INT);
7622 val = adjust_address (val, mode, 0);
7625 else if (GET_CODE (val) == SUBREG
7626 && (submode = GET_MODE (SUBREG_REG (val)),
7627 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7628 && pos + len <= GET_MODE_BITSIZE (submode)
7629 && GET_MODE_CLASS (submode) == MODE_INT)
7631 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7633 val = SUBREG_REG (val);
7635 else if (mode == HImode && pos + len <= 8)
7637 /* Small HImode tests can be converted to QImode. */
7639 val = gen_lowpart (QImode, val);
7642 if (len == HOST_BITS_PER_WIDE_INT)
7645 mask = ((HOST_WIDE_INT)1 << len) - 1;
7648 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7651 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7652 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7653 ;; this is relatively important trick.
7654 ;; Do the conversion only post-reload to avoid limiting of the register class
7657 [(set (match_operand 0 "flags_reg_operand" "")
7658 (match_operator 1 "compare_operator"
7659 [(and (match_operand 2 "register_operand" "")
7660 (match_operand 3 "const_int_operand" ""))
7663 && QI_REG_P (operands[2])
7664 && GET_MODE (operands[2]) != QImode
7665 && ((ix86_match_ccmode (insn, CCZmode)
7666 && !(INTVAL (operands[3]) & ~(255 << 8)))
7667 || (ix86_match_ccmode (insn, CCNOmode)
7668 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7671 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7675 operands[2] = gen_lowpart (SImode, operands[2]);
7676 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7680 [(set (match_operand 0 "flags_reg_operand" "")
7681 (match_operator 1 "compare_operator"
7682 [(and (match_operand 2 "nonimmediate_operand" "")
7683 (match_operand 3 "const_int_operand" ""))
7686 && GET_MODE (operands[2]) != QImode
7687 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7688 && ((ix86_match_ccmode (insn, CCZmode)
7689 && !(INTVAL (operands[3]) & ~255))
7690 || (ix86_match_ccmode (insn, CCNOmode)
7691 && !(INTVAL (operands[3]) & ~127)))"
7693 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7696 operands[2] = gen_lowpart (QImode, operands[2]);
7697 operands[3] = gen_lowpart (QImode, operands[3]);
7700 ;; %%% This used to optimize known byte-wide and operations to memory,
7701 ;; and sometimes to QImode registers. If this is considered useful,
7702 ;; it should be done with splitters.
7704 (define_expand "and<mode>3"
7705 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7706 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7707 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7710 if (<MODE>mode == DImode
7711 && GET_CODE (operands[2]) == CONST_INT
7712 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7713 && REG_P (operands[1]))
7714 emit_insn (gen_zero_extendsidi2 (operands[0],
7715 gen_lowpart (SImode, operands[1])));
7717 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7721 (define_insn "*anddi_1"
7722 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7724 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7725 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7726 (clobber (reg:CC FLAGS_REG))]
7727 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7729 switch (get_attr_type (insn))
7733 enum machine_mode mode;
7735 gcc_assert (CONST_INT_P (operands[2]));
7736 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7738 else if (INTVAL (operands[2]) == 0xffff)
7742 gcc_assert (INTVAL (operands[2]) == 0xff);
7746 operands[1] = gen_lowpart (mode, operands[1]);
7748 return "mov{l}\t{%1, %k0|%k0, %1}";
7749 else if (mode == HImode)
7750 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7752 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7757 if (get_attr_mode (insn) == MODE_SI)
7758 return "and{l}\t{%k2, %k0|%k0, %k2}";
7760 return "and{q}\t{%2, %0|%0, %2}";
7763 [(set_attr "type" "alu,alu,alu,imovx")
7764 (set_attr "length_immediate" "*,*,*,0")
7765 (set (attr "prefix_rex")
7767 (and (eq_attr "type" "imovx")
7768 (and (match_test "INTVAL (operands[2]) == 0xff")
7769 (match_operand 1 "ext_QIreg_operand" "")))
7771 (const_string "*")))
7772 (set_attr "mode" "SI,DI,DI,SI")])
7774 (define_insn "*andsi_1"
7775 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7776 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7777 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7778 (clobber (reg:CC FLAGS_REG))]
7779 "ix86_binary_operator_ok (AND, SImode, operands)"
7781 switch (get_attr_type (insn))
7785 enum machine_mode mode;
7787 gcc_assert (CONST_INT_P (operands[2]));
7788 if (INTVAL (operands[2]) == 0xffff)
7792 gcc_assert (INTVAL (operands[2]) == 0xff);
7796 operands[1] = gen_lowpart (mode, operands[1]);
7798 return "movz{wl|x}\t{%1, %0|%0, %1}";
7800 return "movz{bl|x}\t{%1, %0|%0, %1}";
7804 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7805 return "and{l}\t{%2, %0|%0, %2}";
7808 [(set_attr "type" "alu,alu,imovx")
7809 (set (attr "prefix_rex")
7811 (and (eq_attr "type" "imovx")
7812 (and (match_test "INTVAL (operands[2]) == 0xff")
7813 (match_operand 1 "ext_QIreg_operand" "")))
7815 (const_string "*")))
7816 (set_attr "length_immediate" "*,*,0")
7817 (set_attr "mode" "SI")])
7819 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7820 (define_insn "*andsi_1_zext"
7821 [(set (match_operand:DI 0 "register_operand" "=r")
7823 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7824 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7825 (clobber (reg:CC FLAGS_REG))]
7826 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7827 "and{l}\t{%2, %k0|%k0, %2}"
7828 [(set_attr "type" "alu")
7829 (set_attr "mode" "SI")])
7831 (define_insn "*andhi_1"
7832 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7833 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7834 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7835 (clobber (reg:CC FLAGS_REG))]
7836 "ix86_binary_operator_ok (AND, HImode, operands)"
7838 switch (get_attr_type (insn))
7841 gcc_assert (CONST_INT_P (operands[2]));
7842 gcc_assert (INTVAL (operands[2]) == 0xff);
7843 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7846 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7848 return "and{w}\t{%2, %0|%0, %2}";
7851 [(set_attr "type" "alu,alu,imovx")
7852 (set_attr "length_immediate" "*,*,0")
7853 (set (attr "prefix_rex")
7855 (and (eq_attr "type" "imovx")
7856 (match_operand 1 "ext_QIreg_operand" ""))
7858 (const_string "*")))
7859 (set_attr "mode" "HI,HI,SI")])
7861 ;; %%% Potential partial reg stall on alternative 2. What to do?
7862 (define_insn "*andqi_1"
7863 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7864 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7865 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7866 (clobber (reg:CC FLAGS_REG))]
7867 "ix86_binary_operator_ok (AND, QImode, operands)"
7869 and{b}\t{%2, %0|%0, %2}
7870 and{b}\t{%2, %0|%0, %2}
7871 and{l}\t{%k2, %k0|%k0, %k2}"
7872 [(set_attr "type" "alu")
7873 (set_attr "mode" "QI,QI,SI")])
7875 (define_insn "*andqi_1_slp"
7876 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7877 (and:QI (match_dup 0)
7878 (match_operand:QI 1 "general_operand" "qn,qmn")))
7879 (clobber (reg:CC FLAGS_REG))]
7880 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7881 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7882 "and{b}\t{%1, %0|%0, %1}"
7883 [(set_attr "type" "alu1")
7884 (set_attr "mode" "QI")])
7887 [(set (match_operand 0 "register_operand" "")
7889 (const_int -65536)))
7890 (clobber (reg:CC FLAGS_REG))]
7891 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7892 || optimize_function_for_size_p (cfun)"
7893 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7894 "operands[1] = gen_lowpart (HImode, operands[0]);")
7897 [(set (match_operand 0 "ext_register_operand" "")
7900 (clobber (reg:CC FLAGS_REG))]
7901 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7902 && reload_completed"
7903 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7904 "operands[1] = gen_lowpart (QImode, operands[0]);")
7907 [(set (match_operand 0 "ext_register_operand" "")
7909 (const_int -65281)))
7910 (clobber (reg:CC FLAGS_REG))]
7911 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7912 && reload_completed"
7913 [(parallel [(set (zero_extract:SI (match_dup 0)
7917 (zero_extract:SI (match_dup 0)
7920 (zero_extract:SI (match_dup 0)
7923 (clobber (reg:CC FLAGS_REG))])]
7924 "operands[0] = gen_lowpart (SImode, operands[0]);")
7926 (define_insn "*anddi_2"
7927 [(set (reg FLAGS_REG)
7930 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7931 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7933 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7934 (and:DI (match_dup 1) (match_dup 2)))]
7935 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7936 && ix86_binary_operator_ok (AND, DImode, operands)"
7938 and{l}\t{%k2, %k0|%k0, %k2}
7939 and{q}\t{%2, %0|%0, %2}
7940 and{q}\t{%2, %0|%0, %2}"
7941 [(set_attr "type" "alu")
7942 (set_attr "mode" "SI,DI,DI")])
7944 (define_insn "*andqi_2_maybe_si"
7945 [(set (reg FLAGS_REG)
7947 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7948 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7950 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7951 (and:QI (match_dup 1) (match_dup 2)))]
7952 "ix86_binary_operator_ok (AND, QImode, operands)
7953 && ix86_match_ccmode (insn,
7954 CONST_INT_P (operands[2])
7955 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7957 if (which_alternative == 2)
7959 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7960 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7961 return "and{l}\t{%2, %k0|%k0, %2}";
7963 return "and{b}\t{%2, %0|%0, %2}";
7965 [(set_attr "type" "alu")
7966 (set_attr "mode" "QI,QI,SI")])
7968 (define_insn "*and<mode>_2"
7969 [(set (reg FLAGS_REG)
7970 (compare (and:SWI124
7971 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7972 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7974 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7975 (and:SWI124 (match_dup 1) (match_dup 2)))]
7976 "ix86_match_ccmode (insn, CCNOmode)
7977 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7978 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7979 [(set_attr "type" "alu")
7980 (set_attr "mode" "<MODE>")])
7982 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7983 (define_insn "*andsi_2_zext"
7984 [(set (reg FLAGS_REG)
7986 (match_operand:SI 1 "nonimmediate_operand" "%0")
7987 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7989 (set (match_operand:DI 0 "register_operand" "=r")
7990 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7991 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7992 && ix86_binary_operator_ok (AND, SImode, operands)"
7993 "and{l}\t{%2, %k0|%k0, %2}"
7994 [(set_attr "type" "alu")
7995 (set_attr "mode" "SI")])
7997 (define_insn "*andqi_2_slp"
7998 [(set (reg FLAGS_REG)
8000 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8001 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8003 (set (strict_low_part (match_dup 0))
8004 (and:QI (match_dup 0) (match_dup 1)))]
8005 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8006 && ix86_match_ccmode (insn, CCNOmode)
8007 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8008 "and{b}\t{%1, %0|%0, %1}"
8009 [(set_attr "type" "alu1")
8010 (set_attr "mode" "QI")])
8012 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8013 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8014 ;; for a QImode operand, which of course failed.
8015 (define_insn "andqi_ext_0"
8016 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8021 (match_operand 1 "ext_register_operand" "0")
8024 (match_operand 2 "const_int_operand" "n")))
8025 (clobber (reg:CC FLAGS_REG))]
8027 "and{b}\t{%2, %h0|%h0, %2}"
8028 [(set_attr "type" "alu")
8029 (set_attr "length_immediate" "1")
8030 (set_attr "modrm" "1")
8031 (set_attr "mode" "QI")])
8033 ;; Generated by peephole translating test to and. This shows up
8034 ;; often in fp comparisons.
8035 (define_insn "*andqi_ext_0_cc"
8036 [(set (reg FLAGS_REG)
8040 (match_operand 1 "ext_register_operand" "0")
8043 (match_operand 2 "const_int_operand" "n"))
8045 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8054 "ix86_match_ccmode (insn, CCNOmode)"
8055 "and{b}\t{%2, %h0|%h0, %2}"
8056 [(set_attr "type" "alu")
8057 (set_attr "length_immediate" "1")
8058 (set_attr "modrm" "1")
8059 (set_attr "mode" "QI")])
8061 (define_insn "*andqi_ext_1_rex64"
8062 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8067 (match_operand 1 "ext_register_operand" "0")
8071 (match_operand 2 "ext_register_operand" "Q"))))
8072 (clobber (reg:CC FLAGS_REG))]
8074 "and{b}\t{%2, %h0|%h0, %2}"
8075 [(set_attr "type" "alu")
8076 (set_attr "length_immediate" "0")
8077 (set_attr "mode" "QI")])
8079 (define_insn "*andqi_ext_1"
8080 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8085 (match_operand 1 "ext_register_operand" "0")
8089 (match_operand:QI 2 "general_operand" "Qm"))))
8090 (clobber (reg:CC FLAGS_REG))]
8092 "and{b}\t{%2, %h0|%h0, %2}"
8093 [(set_attr "type" "alu")
8094 (set_attr "length_immediate" "0")
8095 (set_attr "mode" "QI")])
8097 (define_insn "*andqi_ext_2"
8098 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8103 (match_operand 1 "ext_register_operand" "%0")
8107 (match_operand 2 "ext_register_operand" "Q")
8110 (clobber (reg:CC FLAGS_REG))]
8112 "and{b}\t{%h2, %h0|%h0, %h2}"
8113 [(set_attr "type" "alu")
8114 (set_attr "length_immediate" "0")
8115 (set_attr "mode" "QI")])
8117 ;; Convert wide AND instructions with immediate operand to shorter QImode
8118 ;; equivalents when possible.
8119 ;; Don't do the splitting with memory operands, since it introduces risk
8120 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8121 ;; for size, but that can (should?) be handled by generic code instead.
8123 [(set (match_operand 0 "register_operand" "")
8124 (and (match_operand 1 "register_operand" "")
8125 (match_operand 2 "const_int_operand" "")))
8126 (clobber (reg:CC FLAGS_REG))]
8128 && QI_REG_P (operands[0])
8129 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8130 && !(~INTVAL (operands[2]) & ~(255 << 8))
8131 && GET_MODE (operands[0]) != QImode"
8132 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8133 (and:SI (zero_extract:SI (match_dup 1)
8134 (const_int 8) (const_int 8))
8136 (clobber (reg:CC FLAGS_REG))])]
8138 operands[0] = gen_lowpart (SImode, operands[0]);
8139 operands[1] = gen_lowpart (SImode, operands[1]);
8140 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8143 ;; Since AND can be encoded with sign extended immediate, this is only
8144 ;; profitable when 7th bit is not set.
8146 [(set (match_operand 0 "register_operand" "")
8147 (and (match_operand 1 "general_operand" "")
8148 (match_operand 2 "const_int_operand" "")))
8149 (clobber (reg:CC FLAGS_REG))]
8151 && ANY_QI_REG_P (operands[0])
8152 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8153 && !(~INTVAL (operands[2]) & ~255)
8154 && !(INTVAL (operands[2]) & 128)
8155 && GET_MODE (operands[0]) != QImode"
8156 [(parallel [(set (strict_low_part (match_dup 0))
8157 (and:QI (match_dup 1)
8159 (clobber (reg:CC FLAGS_REG))])]
8161 operands[0] = gen_lowpart (QImode, operands[0]);
8162 operands[1] = gen_lowpart (QImode, operands[1]);
8163 operands[2] = gen_lowpart (QImode, operands[2]);
8166 ;; Logical inclusive and exclusive OR instructions
8168 ;; %%% This used to optimize known byte-wide and operations to memory.
8169 ;; If this is considered useful, it should be done with splitters.
8171 (define_expand "<code><mode>3"
8172 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8173 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8174 (match_operand:SWIM 2 "<general_operand>" "")))]
8176 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8178 (define_insn "*<code><mode>_1"
8179 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8181 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8182 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8183 (clobber (reg:CC FLAGS_REG))]
8184 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8185 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8186 [(set_attr "type" "alu")
8187 (set_attr "mode" "<MODE>")])
8189 ;; %%% Potential partial reg stall on alternative 2. What to do?
8190 (define_insn "*<code>qi_1"
8191 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8192 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8193 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8194 (clobber (reg:CC FLAGS_REG))]
8195 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8197 <logic>{b}\t{%2, %0|%0, %2}
8198 <logic>{b}\t{%2, %0|%0, %2}
8199 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "mode" "QI,QI,SI")])
8203 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8204 (define_insn "*<code>si_1_zext"
8205 [(set (match_operand:DI 0 "register_operand" "=r")
8207 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8208 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8209 (clobber (reg:CC FLAGS_REG))]
8210 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8211 "<logic>{l}\t{%2, %k0|%k0, %2}"
8212 [(set_attr "type" "alu")
8213 (set_attr "mode" "SI")])
8215 (define_insn "*<code>si_1_zext_imm"
8216 [(set (match_operand:DI 0 "register_operand" "=r")
8218 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8219 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8220 (clobber (reg:CC FLAGS_REG))]
8221 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8222 "<logic>{l}\t{%2, %k0|%k0, %2}"
8223 [(set_attr "type" "alu")
8224 (set_attr "mode" "SI")])
8226 (define_insn "*<code>qi_1_slp"
8227 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8228 (any_or:QI (match_dup 0)
8229 (match_operand:QI 1 "general_operand" "qmn,qn")))
8230 (clobber (reg:CC FLAGS_REG))]
8231 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8232 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8233 "<logic>{b}\t{%1, %0|%0, %1}"
8234 [(set_attr "type" "alu1")
8235 (set_attr "mode" "QI")])
8237 (define_insn "*<code><mode>_2"
8238 [(set (reg FLAGS_REG)
8239 (compare (any_or:SWI
8240 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8241 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8243 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8244 (any_or:SWI (match_dup 1) (match_dup 2)))]
8245 "ix86_match_ccmode (insn, CCNOmode)
8246 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8247 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8248 [(set_attr "type" "alu")
8249 (set_attr "mode" "<MODE>")])
8251 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8252 ;; ??? Special case for immediate operand is missing - it is tricky.
8253 (define_insn "*<code>si_2_zext"
8254 [(set (reg FLAGS_REG)
8255 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8256 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8258 (set (match_operand:DI 0 "register_operand" "=r")
8259 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8260 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8261 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8262 "<logic>{l}\t{%2, %k0|%k0, %2}"
8263 [(set_attr "type" "alu")
8264 (set_attr "mode" "SI")])
8266 (define_insn "*<code>si_2_zext_imm"
8267 [(set (reg FLAGS_REG)
8269 (match_operand:SI 1 "nonimmediate_operand" "%0")
8270 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8272 (set (match_operand:DI 0 "register_operand" "=r")
8273 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8274 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8275 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8276 "<logic>{l}\t{%2, %k0|%k0, %2}"
8277 [(set_attr "type" "alu")
8278 (set_attr "mode" "SI")])
8280 (define_insn "*<code>qi_2_slp"
8281 [(set (reg FLAGS_REG)
8282 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8283 (match_operand:QI 1 "general_operand" "qmn,qn"))
8285 (set (strict_low_part (match_dup 0))
8286 (any_or:QI (match_dup 0) (match_dup 1)))]
8287 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8288 && ix86_match_ccmode (insn, CCNOmode)
8289 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8290 "<logic>{b}\t{%1, %0|%0, %1}"
8291 [(set_attr "type" "alu1")
8292 (set_attr "mode" "QI")])
8294 (define_insn "*<code><mode>_3"
8295 [(set (reg FLAGS_REG)
8296 (compare (any_or:SWI
8297 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8298 (match_operand:SWI 2 "<general_operand>" "<g>"))
8300 (clobber (match_scratch:SWI 0 "=<r>"))]
8301 "ix86_match_ccmode (insn, CCNOmode)
8302 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8303 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8304 [(set_attr "type" "alu")
8305 (set_attr "mode" "<MODE>")])
8307 (define_insn "*<code>qi_ext_0"
8308 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8313 (match_operand 1 "ext_register_operand" "0")
8316 (match_operand 2 "const_int_operand" "n")))
8317 (clobber (reg:CC FLAGS_REG))]
8318 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8319 "<logic>{b}\t{%2, %h0|%h0, %2}"
8320 [(set_attr "type" "alu")
8321 (set_attr "length_immediate" "1")
8322 (set_attr "modrm" "1")
8323 (set_attr "mode" "QI")])
8325 (define_insn "*<code>qi_ext_1_rex64"
8326 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8331 (match_operand 1 "ext_register_operand" "0")
8335 (match_operand 2 "ext_register_operand" "Q"))))
8336 (clobber (reg:CC FLAGS_REG))]
8338 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8339 "<logic>{b}\t{%2, %h0|%h0, %2}"
8340 [(set_attr "type" "alu")
8341 (set_attr "length_immediate" "0")
8342 (set_attr "mode" "QI")])
8344 (define_insn "*<code>qi_ext_1"
8345 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8350 (match_operand 1 "ext_register_operand" "0")
8354 (match_operand:QI 2 "general_operand" "Qm"))))
8355 (clobber (reg:CC FLAGS_REG))]
8357 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8358 "<logic>{b}\t{%2, %h0|%h0, %2}"
8359 [(set_attr "type" "alu")
8360 (set_attr "length_immediate" "0")
8361 (set_attr "mode" "QI")])
8363 (define_insn "*<code>qi_ext_2"
8364 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8368 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8371 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8374 (clobber (reg:CC FLAGS_REG))]
8375 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8376 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8377 [(set_attr "type" "alu")
8378 (set_attr "length_immediate" "0")
8379 (set_attr "mode" "QI")])
8382 [(set (match_operand 0 "register_operand" "")
8383 (any_or (match_operand 1 "register_operand" "")
8384 (match_operand 2 "const_int_operand" "")))
8385 (clobber (reg:CC FLAGS_REG))]
8387 && QI_REG_P (operands[0])
8388 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8389 && !(INTVAL (operands[2]) & ~(255 << 8))
8390 && GET_MODE (operands[0]) != QImode"
8391 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8392 (any_or:SI (zero_extract:SI (match_dup 1)
8393 (const_int 8) (const_int 8))
8395 (clobber (reg:CC FLAGS_REG))])]
8397 operands[0] = gen_lowpart (SImode, operands[0]);
8398 operands[1] = gen_lowpart (SImode, operands[1]);
8399 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8402 ;; Since OR can be encoded with sign extended immediate, this is only
8403 ;; profitable when 7th bit is set.
8405 [(set (match_operand 0 "register_operand" "")
8406 (any_or (match_operand 1 "general_operand" "")
8407 (match_operand 2 "const_int_operand" "")))
8408 (clobber (reg:CC FLAGS_REG))]
8410 && ANY_QI_REG_P (operands[0])
8411 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8412 && !(INTVAL (operands[2]) & ~255)
8413 && (INTVAL (operands[2]) & 128)
8414 && GET_MODE (operands[0]) != QImode"
8415 [(parallel [(set (strict_low_part (match_dup 0))
8416 (any_or:QI (match_dup 1)
8418 (clobber (reg:CC FLAGS_REG))])]
8420 operands[0] = gen_lowpart (QImode, operands[0]);
8421 operands[1] = gen_lowpart (QImode, operands[1]);
8422 operands[2] = gen_lowpart (QImode, operands[2]);
8425 (define_expand "xorqi_cc_ext_1"
8427 (set (reg:CCNO FLAGS_REG)
8431 (match_operand 1 "ext_register_operand" "")
8434 (match_operand:QI 2 "general_operand" ""))
8436 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8446 (define_insn "*xorqi_cc_ext_1_rex64"
8447 [(set (reg FLAGS_REG)
8451 (match_operand 1 "ext_register_operand" "0")
8454 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8456 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8465 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8466 "xor{b}\t{%2, %h0|%h0, %2}"
8467 [(set_attr "type" "alu")
8468 (set_attr "modrm" "1")
8469 (set_attr "mode" "QI")])
8471 (define_insn "*xorqi_cc_ext_1"
8472 [(set (reg FLAGS_REG)
8476 (match_operand 1 "ext_register_operand" "0")
8479 (match_operand:QI 2 "general_operand" "qmn"))
8481 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8490 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8491 "xor{b}\t{%2, %h0|%h0, %2}"
8492 [(set_attr "type" "alu")
8493 (set_attr "modrm" "1")
8494 (set_attr "mode" "QI")])
8496 ;; Negation instructions
8498 (define_expand "neg<mode>2"
8499 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8500 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8502 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8504 (define_insn_and_split "*neg<dwi>2_doubleword"
8505 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8506 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8507 (clobber (reg:CC FLAGS_REG))]
8508 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8512 [(set (reg:CCZ FLAGS_REG)
8513 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8514 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8517 (plus:DWIH (match_dup 3)
8518 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8520 (clobber (reg:CC FLAGS_REG))])
8523 (neg:DWIH (match_dup 2)))
8524 (clobber (reg:CC FLAGS_REG))])]
8525 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8527 (define_insn "*neg<mode>2_1"
8528 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8529 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8530 (clobber (reg:CC FLAGS_REG))]
8531 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8532 "neg{<imodesuffix>}\t%0"
8533 [(set_attr "type" "negnot")
8534 (set_attr "mode" "<MODE>")])
8536 ;; Combine is quite creative about this pattern.
8537 (define_insn "*negsi2_1_zext"
8538 [(set (match_operand:DI 0 "register_operand" "=r")
8540 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8543 (clobber (reg:CC FLAGS_REG))]
8544 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8546 [(set_attr "type" "negnot")
8547 (set_attr "mode" "SI")])
8549 ;; The problem with neg is that it does not perform (compare x 0),
8550 ;; it really performs (compare 0 x), which leaves us with the zero
8551 ;; flag being the only useful item.
8553 (define_insn "*neg<mode>2_cmpz"
8554 [(set (reg:CCZ FLAGS_REG)
8556 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8558 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8559 (neg:SWI (match_dup 1)))]
8560 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8561 "neg{<imodesuffix>}\t%0"
8562 [(set_attr "type" "negnot")
8563 (set_attr "mode" "<MODE>")])
8565 (define_insn "*negsi2_cmpz_zext"
8566 [(set (reg:CCZ FLAGS_REG)
8570 (match_operand:DI 1 "register_operand" "0")
8574 (set (match_operand:DI 0 "register_operand" "=r")
8575 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8578 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8580 [(set_attr "type" "negnot")
8581 (set_attr "mode" "SI")])
8583 ;; Changing of sign for FP values is doable using integer unit too.
8585 (define_expand "<code><mode>2"
8586 [(set (match_operand:X87MODEF 0 "register_operand" "")
8587 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8588 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8589 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8591 (define_insn "*absneg<mode>2_mixed"
8592 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8593 (match_operator:MODEF 3 "absneg_operator"
8594 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8595 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8596 (clobber (reg:CC FLAGS_REG))]
8597 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8600 (define_insn "*absneg<mode>2_sse"
8601 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8602 (match_operator:MODEF 3 "absneg_operator"
8603 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8604 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8605 (clobber (reg:CC FLAGS_REG))]
8606 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8609 (define_insn "*absneg<mode>2_i387"
8610 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8611 (match_operator:X87MODEF 3 "absneg_operator"
8612 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8613 (use (match_operand 2 "" ""))
8614 (clobber (reg:CC FLAGS_REG))]
8615 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8618 (define_expand "<code>tf2"
8619 [(set (match_operand:TF 0 "register_operand" "")
8620 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8622 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8624 (define_insn "*absnegtf2_sse"
8625 [(set (match_operand:TF 0 "register_operand" "=x,x")
8626 (match_operator:TF 3 "absneg_operator"
8627 [(match_operand:TF 1 "register_operand" "0,x")]))
8628 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8629 (clobber (reg:CC FLAGS_REG))]
8633 ;; Splitters for fp abs and neg.
8636 [(set (match_operand 0 "fp_register_operand" "")
8637 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8638 (use (match_operand 2 "" ""))
8639 (clobber (reg:CC FLAGS_REG))]
8641 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8644 [(set (match_operand 0 "register_operand" "")
8645 (match_operator 3 "absneg_operator"
8646 [(match_operand 1 "register_operand" "")]))
8647 (use (match_operand 2 "nonimmediate_operand" ""))
8648 (clobber (reg:CC FLAGS_REG))]
8649 "reload_completed && SSE_REG_P (operands[0])"
8650 [(set (match_dup 0) (match_dup 3))]
8652 enum machine_mode mode = GET_MODE (operands[0]);
8653 enum machine_mode vmode = GET_MODE (operands[2]);
8656 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8657 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8658 if (operands_match_p (operands[0], operands[2]))
8661 operands[1] = operands[2];
8664 if (GET_CODE (operands[3]) == ABS)
8665 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8667 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8672 [(set (match_operand:SF 0 "register_operand" "")
8673 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8674 (use (match_operand:V4SF 2 "" ""))
8675 (clobber (reg:CC FLAGS_REG))]
8677 [(parallel [(set (match_dup 0) (match_dup 1))
8678 (clobber (reg:CC FLAGS_REG))])]
8681 operands[0] = gen_lowpart (SImode, operands[0]);
8682 if (GET_CODE (operands[1]) == ABS)
8684 tmp = gen_int_mode (0x7fffffff, SImode);
8685 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8689 tmp = gen_int_mode (0x80000000, SImode);
8690 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8696 [(set (match_operand:DF 0 "register_operand" "")
8697 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8698 (use (match_operand 2 "" ""))
8699 (clobber (reg:CC FLAGS_REG))]
8701 [(parallel [(set (match_dup 0) (match_dup 1))
8702 (clobber (reg:CC FLAGS_REG))])]
8707 tmp = gen_lowpart (DImode, operands[0]);
8708 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8711 if (GET_CODE (operands[1]) == ABS)
8714 tmp = gen_rtx_NOT (DImode, tmp);
8718 operands[0] = gen_highpart (SImode, operands[0]);
8719 if (GET_CODE (operands[1]) == ABS)
8721 tmp = gen_int_mode (0x7fffffff, SImode);
8722 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8726 tmp = gen_int_mode (0x80000000, SImode);
8727 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8734 [(set (match_operand:XF 0 "register_operand" "")
8735 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8736 (use (match_operand 2 "" ""))
8737 (clobber (reg:CC FLAGS_REG))]
8739 [(parallel [(set (match_dup 0) (match_dup 1))
8740 (clobber (reg:CC FLAGS_REG))])]
8743 operands[0] = gen_rtx_REG (SImode,
8744 true_regnum (operands[0])
8745 + (TARGET_64BIT ? 1 : 2));
8746 if (GET_CODE (operands[1]) == ABS)
8748 tmp = GEN_INT (0x7fff);
8749 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8753 tmp = GEN_INT (0x8000);
8754 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8759 ;; Conditionalize these after reload. If they match before reload, we
8760 ;; lose the clobber and ability to use integer instructions.
8762 (define_insn "*<code><mode>2_1"
8763 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8764 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8766 && (reload_completed
8767 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8768 "f<absneg_mnemonic>"
8769 [(set_attr "type" "fsgn")
8770 (set_attr "mode" "<MODE>")])
8772 (define_insn "*<code>extendsfdf2"
8773 [(set (match_operand:DF 0 "register_operand" "=f")
8774 (absneg:DF (float_extend:DF
8775 (match_operand:SF 1 "register_operand" "0"))))]
8776 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8777 "f<absneg_mnemonic>"
8778 [(set_attr "type" "fsgn")
8779 (set_attr "mode" "DF")])
8781 (define_insn "*<code>extendsfxf2"
8782 [(set (match_operand:XF 0 "register_operand" "=f")
8783 (absneg:XF (float_extend:XF
8784 (match_operand:SF 1 "register_operand" "0"))))]
8786 "f<absneg_mnemonic>"
8787 [(set_attr "type" "fsgn")
8788 (set_attr "mode" "XF")])
8790 (define_insn "*<code>extenddfxf2"
8791 [(set (match_operand:XF 0 "register_operand" "=f")
8792 (absneg:XF (float_extend:XF
8793 (match_operand:DF 1 "register_operand" "0"))))]
8795 "f<absneg_mnemonic>"
8796 [(set_attr "type" "fsgn")
8797 (set_attr "mode" "XF")])
8799 ;; Copysign instructions
8801 (define_mode_iterator CSGNMODE [SF DF TF])
8802 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8804 (define_expand "copysign<mode>3"
8805 [(match_operand:CSGNMODE 0 "register_operand" "")
8806 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8807 (match_operand:CSGNMODE 2 "register_operand" "")]
8808 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8809 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8810 "ix86_expand_copysign (operands); DONE;")
8812 (define_insn_and_split "copysign<mode>3_const"
8813 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8815 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8816 (match_operand:CSGNMODE 2 "register_operand" "0")
8817 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8819 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8820 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8822 "&& reload_completed"
8824 "ix86_split_copysign_const (operands); DONE;")
8826 (define_insn "copysign<mode>3_var"
8827 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8829 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8830 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8831 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8832 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8834 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8835 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8836 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8840 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8842 [(match_operand:CSGNMODE 2 "register_operand" "")
8843 (match_operand:CSGNMODE 3 "register_operand" "")
8844 (match_operand:<CSGNVMODE> 4 "" "")
8845 (match_operand:<CSGNVMODE> 5 "" "")]
8847 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8848 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8849 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8850 && reload_completed"
8852 "ix86_split_copysign_var (operands); DONE;")
8854 ;; One complement instructions
8856 (define_expand "one_cmpl<mode>2"
8857 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8858 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8860 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8862 (define_insn "*one_cmpl<mode>2_1"
8863 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8864 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8865 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8866 "not{<imodesuffix>}\t%0"
8867 [(set_attr "type" "negnot")
8868 (set_attr "mode" "<MODE>")])
8870 ;; %%% Potential partial reg stall on alternative 1. What to do?
8871 (define_insn "*one_cmplqi2_1"
8872 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8873 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8874 "ix86_unary_operator_ok (NOT, QImode, operands)"
8878 [(set_attr "type" "negnot")
8879 (set_attr "mode" "QI,SI")])
8881 ;; ??? Currently never generated - xor is used instead.
8882 (define_insn "*one_cmplsi2_1_zext"
8883 [(set (match_operand:DI 0 "register_operand" "=r")
8885 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8886 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8888 [(set_attr "type" "negnot")
8889 (set_attr "mode" "SI")])
8891 (define_insn "*one_cmpl<mode>2_2"
8892 [(set (reg FLAGS_REG)
8893 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8895 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8896 (not:SWI (match_dup 1)))]
8897 "ix86_match_ccmode (insn, CCNOmode)
8898 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8900 [(set_attr "type" "alu1")
8901 (set_attr "mode" "<MODE>")])
8904 [(set (match_operand 0 "flags_reg_operand" "")
8905 (match_operator 2 "compare_operator"
8906 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8908 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8909 (not:SWI (match_dup 3)))]
8910 "ix86_match_ccmode (insn, CCNOmode)"
8911 [(parallel [(set (match_dup 0)
8912 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8915 (xor:SWI (match_dup 3) (const_int -1)))])])
8917 ;; ??? Currently never generated - xor is used instead.
8918 (define_insn "*one_cmplsi2_2_zext"
8919 [(set (reg FLAGS_REG)
8920 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8922 (set (match_operand:DI 0 "register_operand" "=r")
8923 (zero_extend:DI (not:SI (match_dup 1))))]
8924 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8925 && ix86_unary_operator_ok (NOT, SImode, operands)"
8927 [(set_attr "type" "alu1")
8928 (set_attr "mode" "SI")])
8931 [(set (match_operand 0 "flags_reg_operand" "")
8932 (match_operator 2 "compare_operator"
8933 [(not:SI (match_operand:SI 3 "register_operand" ""))
8935 (set (match_operand:DI 1 "register_operand" "")
8936 (zero_extend:DI (not:SI (match_dup 3))))]
8937 "ix86_match_ccmode (insn, CCNOmode)"
8938 [(parallel [(set (match_dup 0)
8939 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8942 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8944 ;; Shift instructions
8946 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8947 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8948 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8949 ;; from the assembler input.
8951 ;; This instruction shifts the target reg/mem as usual, but instead of
8952 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8953 ;; is a left shift double, bits are taken from the high order bits of
8954 ;; reg, else if the insn is a shift right double, bits are taken from the
8955 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8956 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8958 ;; Since sh[lr]d does not change the `reg' operand, that is done
8959 ;; separately, making all shifts emit pairs of shift double and normal
8960 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8961 ;; support a 63 bit shift, each shift where the count is in a reg expands
8962 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8964 ;; If the shift count is a constant, we need never emit more than one
8965 ;; shift pair, instead using moves and sign extension for counts greater
8968 (define_expand "ashl<mode>3"
8969 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8970 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8971 (match_operand:QI 2 "nonmemory_operand" "")))]
8973 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8975 (define_insn "*ashl<mode>3_doubleword"
8976 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8977 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8978 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8979 (clobber (reg:CC FLAGS_REG))]
8982 [(set_attr "type" "multi")])
8985 [(set (match_operand:DWI 0 "register_operand" "")
8986 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8987 (match_operand:QI 2 "nonmemory_operand" "")))
8988 (clobber (reg:CC FLAGS_REG))]
8989 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8991 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8993 ;; By default we don't ask for a scratch register, because when DWImode
8994 ;; values are manipulated, registers are already at a premium. But if
8995 ;; we have one handy, we won't turn it away.
8998 [(match_scratch:DWIH 3 "r")
8999 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9001 (match_operand:<DWI> 1 "nonmemory_operand" "")
9002 (match_operand:QI 2 "nonmemory_operand" "")))
9003 (clobber (reg:CC FLAGS_REG))])
9007 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
9009 (define_insn "x86_64_shld"
9010 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9011 (ior:DI (ashift:DI (match_dup 0)
9012 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9013 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9014 (minus:QI (const_int 64) (match_dup 2)))))
9015 (clobber (reg:CC FLAGS_REG))]
9017 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9018 [(set_attr "type" "ishift")
9019 (set_attr "prefix_0f" "1")
9020 (set_attr "mode" "DI")
9021 (set_attr "athlon_decode" "vector")
9022 (set_attr "amdfam10_decode" "vector")
9023 (set_attr "bdver1_decode" "vector")])
9025 (define_insn "x86_shld"
9026 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9027 (ior:SI (ashift:SI (match_dup 0)
9028 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9029 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9030 (minus:QI (const_int 32) (match_dup 2)))))
9031 (clobber (reg:CC FLAGS_REG))]
9033 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9034 [(set_attr "type" "ishift")
9035 (set_attr "prefix_0f" "1")
9036 (set_attr "mode" "SI")
9037 (set_attr "pent_pair" "np")
9038 (set_attr "athlon_decode" "vector")
9039 (set_attr "amdfam10_decode" "vector")
9040 (set_attr "bdver1_decode" "vector")])
9042 (define_expand "x86_shift<mode>_adj_1"
9043 [(set (reg:CCZ FLAGS_REG)
9044 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9047 (set (match_operand:SWI48 0 "register_operand" "")
9048 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9049 (match_operand:SWI48 1 "register_operand" "")
9052 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9053 (match_operand:SWI48 3 "register_operand" "")
9056 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9058 (define_expand "x86_shift<mode>_adj_2"
9059 [(use (match_operand:SWI48 0 "register_operand" ""))
9060 (use (match_operand:SWI48 1 "register_operand" ""))
9061 (use (match_operand:QI 2 "register_operand" ""))]
9064 rtx label = gen_label_rtx ();
9067 emit_insn (gen_testqi_ccz_1 (operands[2],
9068 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9070 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9071 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9072 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9073 gen_rtx_LABEL_REF (VOIDmode, label),
9075 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9076 JUMP_LABEL (tmp) = label;
9078 emit_move_insn (operands[0], operands[1]);
9079 ix86_expand_clear (operands[1]);
9082 LABEL_NUSES (label) = 1;
9087 ;; Avoid useless masking of count operand.
9088 (define_insn "*ashl<mode>3_mask"
9089 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9091 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9094 (match_operand:SI 2 "register_operand" "c")
9095 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9096 (clobber (reg:CC FLAGS_REG))]
9097 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9098 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9099 == GET_MODE_BITSIZE (<MODE>mode)-1"
9101 return "sal{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9103 [(set_attr "type" "ishift")
9104 (set_attr "mode" "<MODE>")])
9106 (define_insn "*bmi2_ashl<mode>3_1"
9107 [(set (match_operand:SWI48 0 "register_operand" "=r")
9108 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9109 (match_operand:SWI48 2 "register_operand" "r")))]
9111 "shlx\t{%2, %1, %0|%0, %1, %2}"
9112 [(set_attr "type" "ishiftx")
9113 (set_attr "mode" "<MODE>")])
9115 (define_insn "*ashl<mode>3_1"
9116 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9117 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9118 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9122 switch (get_attr_type (insn))
9129 gcc_assert (operands[2] == const1_rtx);
9130 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9131 return "add{<imodesuffix>}\t%0, %0";
9134 if (operands[2] == const1_rtx
9135 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9136 return "sal{<imodesuffix>}\t%0";
9138 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9141 [(set_attr "isa" "*,*,bmi2")
9143 (cond [(eq_attr "alternative" "1")
9144 (const_string "lea")
9145 (eq_attr "alternative" "2")
9146 (const_string "ishiftx")
9147 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9148 (match_operand 0 "register_operand" ""))
9149 (match_operand 2 "const1_operand" ""))
9150 (const_string "alu")
9152 (const_string "ishift")))
9153 (set (attr "length_immediate")
9155 (ior (eq_attr "type" "alu")
9156 (and (eq_attr "type" "ishift")
9157 (and (match_operand 2 "const1_operand" "")
9158 (ior (match_test "TARGET_SHIFT1")
9159 (match_test "optimize_function_for_size_p (cfun)")))))
9161 (const_string "*")))
9162 (set_attr "mode" "<MODE>")])
9164 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9166 [(set (match_operand:SWI48 0 "register_operand" "")
9167 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9168 (match_operand:QI 2 "register_operand" "")))
9169 (clobber (reg:CC FLAGS_REG))]
9170 "TARGET_BMI2 && reload_completed"
9172 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9173 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9175 (define_insn "*bmi2_ashlsi3_1_zext"
9176 [(set (match_operand:DI 0 "register_operand" "=r")
9178 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9179 (match_operand:SI 2 "register_operand" "r"))))]
9180 "TARGET_64BIT && TARGET_BMI2"
9181 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9182 [(set_attr "type" "ishiftx")
9183 (set_attr "mode" "SI")])
9185 (define_insn "*ashlsi3_1_zext"
9186 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9188 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9189 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9190 (clobber (reg:CC FLAGS_REG))]
9191 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9193 switch (get_attr_type (insn))
9200 gcc_assert (operands[2] == const1_rtx);
9201 return "add{l}\t%k0, %k0";
9204 if (operands[2] == const1_rtx
9205 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9206 return "sal{l}\t%k0";
9208 return "sal{l}\t{%2, %k0|%k0, %2}";
9211 [(set_attr "isa" "*,*,bmi2")
9213 (cond [(eq_attr "alternative" "1")
9214 (const_string "lea")
9215 (eq_attr "alternative" "2")
9216 (const_string "ishiftx")
9217 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9218 (match_operand 2 "const1_operand" ""))
9219 (const_string "alu")
9221 (const_string "ishift")))
9222 (set (attr "length_immediate")
9224 (ior (eq_attr "type" "alu")
9225 (and (eq_attr "type" "ishift")
9226 (and (match_operand 2 "const1_operand" "")
9227 (ior (match_test "TARGET_SHIFT1")
9228 (match_test "optimize_function_for_size_p (cfun)")))))
9230 (const_string "*")))
9231 (set_attr "mode" "SI")])
9233 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9235 [(set (match_operand:DI 0 "register_operand" "")
9237 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9238 (match_operand:QI 2 "register_operand" ""))))
9239 (clobber (reg:CC FLAGS_REG))]
9240 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9242 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9243 "operands[2] = gen_lowpart (SImode, operands[2]);")
9245 (define_insn "*ashlhi3_1"
9246 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9247 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9248 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9249 (clobber (reg:CC FLAGS_REG))]
9250 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9252 switch (get_attr_type (insn))
9258 gcc_assert (operands[2] == const1_rtx);
9259 return "add{w}\t%0, %0";
9262 if (operands[2] == const1_rtx
9263 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9264 return "sal{w}\t%0";
9266 return "sal{w}\t{%2, %0|%0, %2}";
9270 (cond [(eq_attr "alternative" "1")
9271 (const_string "lea")
9272 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9273 (match_operand 0 "register_operand" ""))
9274 (match_operand 2 "const1_operand" ""))
9275 (const_string "alu")
9277 (const_string "ishift")))
9278 (set (attr "length_immediate")
9280 (ior (eq_attr "type" "alu")
9281 (and (eq_attr "type" "ishift")
9282 (and (match_operand 2 "const1_operand" "")
9283 (ior (match_test "TARGET_SHIFT1")
9284 (match_test "optimize_function_for_size_p (cfun)")))))
9286 (const_string "*")))
9287 (set_attr "mode" "HI,SI")])
9289 ;; %%% Potential partial reg stall on alternative 1. What to do?
9290 (define_insn "*ashlqi3_1"
9291 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9292 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9293 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9294 (clobber (reg:CC FLAGS_REG))]
9295 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9297 switch (get_attr_type (insn))
9303 gcc_assert (operands[2] == const1_rtx);
9304 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9305 return "add{l}\t%k0, %k0";
9307 return "add{b}\t%0, %0";
9310 if (operands[2] == const1_rtx
9311 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9313 if (get_attr_mode (insn) == MODE_SI)
9314 return "sal{l}\t%k0";
9316 return "sal{b}\t%0";
9320 if (get_attr_mode (insn) == MODE_SI)
9321 return "sal{l}\t{%2, %k0|%k0, %2}";
9323 return "sal{b}\t{%2, %0|%0, %2}";
9328 (cond [(eq_attr "alternative" "2")
9329 (const_string "lea")
9330 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9331 (match_operand 0 "register_operand" ""))
9332 (match_operand 2 "const1_operand" ""))
9333 (const_string "alu")
9335 (const_string "ishift")))
9336 (set (attr "length_immediate")
9338 (ior (eq_attr "type" "alu")
9339 (and (eq_attr "type" "ishift")
9340 (and (match_operand 2 "const1_operand" "")
9341 (ior (match_test "TARGET_SHIFT1")
9342 (match_test "optimize_function_for_size_p (cfun)")))))
9344 (const_string "*")))
9345 (set_attr "mode" "QI,SI,SI")])
9347 (define_insn "*ashlqi3_1_slp"
9348 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9349 (ashift:QI (match_dup 0)
9350 (match_operand:QI 1 "nonmemory_operand" "cI")))
9351 (clobber (reg:CC FLAGS_REG))]
9352 "(optimize_function_for_size_p (cfun)
9353 || !TARGET_PARTIAL_FLAG_REG_STALL
9354 || (operands[1] == const1_rtx
9356 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9358 switch (get_attr_type (insn))
9361 gcc_assert (operands[1] == const1_rtx);
9362 return "add{b}\t%0, %0";
9365 if (operands[1] == const1_rtx
9366 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9367 return "sal{b}\t%0";
9369 return "sal{b}\t{%1, %0|%0, %1}";
9373 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9374 (match_operand 0 "register_operand" ""))
9375 (match_operand 1 "const1_operand" ""))
9376 (const_string "alu")
9378 (const_string "ishift1")))
9379 (set (attr "length_immediate")
9381 (ior (eq_attr "type" "alu")
9382 (and (eq_attr "type" "ishift1")
9383 (and (match_operand 1 "const1_operand" "")
9384 (ior (match_test "TARGET_SHIFT1")
9385 (match_test "optimize_function_for_size_p (cfun)")))))
9387 (const_string "*")))
9388 (set_attr "mode" "QI")])
9390 ;; Convert ashift to the lea pattern to avoid flags dependency.
9392 [(set (match_operand 0 "register_operand" "")
9393 (ashift (match_operand 1 "index_register_operand" "")
9394 (match_operand:QI 2 "const_int_operand" "")))
9395 (clobber (reg:CC FLAGS_REG))]
9396 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9398 && true_regnum (operands[0]) != true_regnum (operands[1])"
9401 enum machine_mode mode = GET_MODE (operands[0]);
9404 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9407 operands[0] = gen_lowpart (mode, operands[0]);
9408 operands[1] = gen_lowpart (mode, operands[1]);
9411 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9413 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9415 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9419 ;; Convert ashift to the lea pattern to avoid flags dependency.
9421 [(set (match_operand:DI 0 "register_operand" "")
9423 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9424 (match_operand:QI 2 "const_int_operand" ""))))
9425 (clobber (reg:CC FLAGS_REG))]
9426 "TARGET_64BIT && reload_completed
9427 && true_regnum (operands[0]) != true_regnum (operands[1])"
9429 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9431 operands[1] = gen_lowpart (DImode, operands[1]);
9432 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9435 ;; This pattern can't accept a variable shift count, since shifts by
9436 ;; zero don't affect the flags. We assume that shifts by constant
9437 ;; zero are optimized away.
9438 (define_insn "*ashl<mode>3_cmp"
9439 [(set (reg FLAGS_REG)
9441 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9442 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9444 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9445 (ashift:SWI (match_dup 1) (match_dup 2)))]
9446 "(optimize_function_for_size_p (cfun)
9447 || !TARGET_PARTIAL_FLAG_REG_STALL
9448 || (operands[2] == const1_rtx
9450 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9451 && ix86_match_ccmode (insn, CCGOCmode)
9452 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9454 switch (get_attr_type (insn))
9457 gcc_assert (operands[2] == const1_rtx);
9458 return "add{<imodesuffix>}\t%0, %0";
9461 if (operands[2] == const1_rtx
9462 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9463 return "sal{<imodesuffix>}\t%0";
9465 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9469 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9470 (match_operand 0 "register_operand" ""))
9471 (match_operand 2 "const1_operand" ""))
9472 (const_string "alu")
9474 (const_string "ishift")))
9475 (set (attr "length_immediate")
9477 (ior (eq_attr "type" "alu")
9478 (and (eq_attr "type" "ishift")
9479 (and (match_operand 2 "const1_operand" "")
9480 (ior (match_test "TARGET_SHIFT1")
9481 (match_test "optimize_function_for_size_p (cfun)")))))
9483 (const_string "*")))
9484 (set_attr "mode" "<MODE>")])
9486 (define_insn "*ashlsi3_cmp_zext"
9487 [(set (reg FLAGS_REG)
9489 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9490 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9492 (set (match_operand:DI 0 "register_operand" "=r")
9493 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9495 && (optimize_function_for_size_p (cfun)
9496 || !TARGET_PARTIAL_FLAG_REG_STALL
9497 || (operands[2] == const1_rtx
9499 || TARGET_DOUBLE_WITH_ADD)))
9500 && ix86_match_ccmode (insn, CCGOCmode)
9501 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9503 switch (get_attr_type (insn))
9506 gcc_assert (operands[2] == const1_rtx);
9507 return "add{l}\t%k0, %k0";
9510 if (operands[2] == const1_rtx
9511 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9512 return "sal{l}\t%k0";
9514 return "sal{l}\t{%2, %k0|%k0, %2}";
9518 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9519 (match_operand 2 "const1_operand" ""))
9520 (const_string "alu")
9522 (const_string "ishift")))
9523 (set (attr "length_immediate")
9525 (ior (eq_attr "type" "alu")
9526 (and (eq_attr "type" "ishift")
9527 (and (match_operand 2 "const1_operand" "")
9528 (ior (match_test "TARGET_SHIFT1")
9529 (match_test "optimize_function_for_size_p (cfun)")))))
9531 (const_string "*")))
9532 (set_attr "mode" "SI")])
9534 (define_insn "*ashl<mode>3_cconly"
9535 [(set (reg FLAGS_REG)
9537 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9538 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9540 (clobber (match_scratch:SWI 0 "=<r>"))]
9541 "(optimize_function_for_size_p (cfun)
9542 || !TARGET_PARTIAL_FLAG_REG_STALL
9543 || (operands[2] == const1_rtx
9545 || TARGET_DOUBLE_WITH_ADD)))
9546 && ix86_match_ccmode (insn, CCGOCmode)"
9548 switch (get_attr_type (insn))
9551 gcc_assert (operands[2] == const1_rtx);
9552 return "add{<imodesuffix>}\t%0, %0";
9555 if (operands[2] == const1_rtx
9556 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9557 return "sal{<imodesuffix>}\t%0";
9559 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9563 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9564 (match_operand 0 "register_operand" ""))
9565 (match_operand 2 "const1_operand" ""))
9566 (const_string "alu")
9568 (const_string "ishift")))
9569 (set (attr "length_immediate")
9571 (ior (eq_attr "type" "alu")
9572 (and (eq_attr "type" "ishift")
9573 (and (match_operand 2 "const1_operand" "")
9574 (ior (match_test "TARGET_SHIFT1")
9575 (match_test "optimize_function_for_size_p (cfun)")))))
9577 (const_string "*")))
9578 (set_attr "mode" "<MODE>")])
9580 ;; See comment above `ashl<mode>3' about how this works.
9582 (define_expand "<shift_insn><mode>3"
9583 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9584 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9585 (match_operand:QI 2 "nonmemory_operand" "")))]
9587 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9589 ;; Avoid useless masking of count operand.
9590 (define_insn "*<shift_insn><mode>3_mask"
9591 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9593 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9596 (match_operand:SI 2 "register_operand" "c")
9597 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9598 (clobber (reg:CC FLAGS_REG))]
9599 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9600 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9601 == GET_MODE_BITSIZE (<MODE>mode)-1"
9603 return "<shift>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
9605 [(set_attr "type" "ishift")
9606 (set_attr "mode" "<MODE>")])
9608 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9609 [(set (match_operand:DWI 0 "register_operand" "=r")
9610 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9611 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9612 (clobber (reg:CC FLAGS_REG))]
9615 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9617 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9618 [(set_attr "type" "multi")])
9620 ;; By default we don't ask for a scratch register, because when DWImode
9621 ;; values are manipulated, registers are already at a premium. But if
9622 ;; we have one handy, we won't turn it away.
9625 [(match_scratch:DWIH 3 "r")
9626 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9628 (match_operand:<DWI> 1 "register_operand" "")
9629 (match_operand:QI 2 "nonmemory_operand" "")))
9630 (clobber (reg:CC FLAGS_REG))])
9634 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9636 (define_insn "x86_64_shrd"
9637 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9638 (ior:DI (ashiftrt:DI (match_dup 0)
9639 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9640 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9641 (minus:QI (const_int 64) (match_dup 2)))))
9642 (clobber (reg:CC FLAGS_REG))]
9644 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9645 [(set_attr "type" "ishift")
9646 (set_attr "prefix_0f" "1")
9647 (set_attr "mode" "DI")
9648 (set_attr "athlon_decode" "vector")
9649 (set_attr "amdfam10_decode" "vector")
9650 (set_attr "bdver1_decode" "vector")])
9652 (define_insn "x86_shrd"
9653 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9654 (ior:SI (ashiftrt:SI (match_dup 0)
9655 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9656 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9657 (minus:QI (const_int 32) (match_dup 2)))))
9658 (clobber (reg:CC FLAGS_REG))]
9660 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9661 [(set_attr "type" "ishift")
9662 (set_attr "prefix_0f" "1")
9663 (set_attr "mode" "SI")
9664 (set_attr "pent_pair" "np")
9665 (set_attr "athlon_decode" "vector")
9666 (set_attr "amdfam10_decode" "vector")
9667 (set_attr "bdver1_decode" "vector")])
9669 (define_insn "ashrdi3_cvt"
9670 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9671 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9672 (match_operand:QI 2 "const_int_operand" "")))
9673 (clobber (reg:CC FLAGS_REG))]
9674 "TARGET_64BIT && INTVAL (operands[2]) == 63
9675 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9676 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9679 sar{q}\t{%2, %0|%0, %2}"
9680 [(set_attr "type" "imovx,ishift")
9681 (set_attr "prefix_0f" "0,*")
9682 (set_attr "length_immediate" "0,*")
9683 (set_attr "modrm" "0,1")
9684 (set_attr "mode" "DI")])
9686 (define_insn "ashrsi3_cvt"
9687 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9688 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9689 (match_operand:QI 2 "const_int_operand" "")))
9690 (clobber (reg:CC FLAGS_REG))]
9691 "INTVAL (operands[2]) == 31
9692 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9693 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9696 sar{l}\t{%2, %0|%0, %2}"
9697 [(set_attr "type" "imovx,ishift")
9698 (set_attr "prefix_0f" "0,*")
9699 (set_attr "length_immediate" "0,*")
9700 (set_attr "modrm" "0,1")
9701 (set_attr "mode" "SI")])
9703 (define_insn "*ashrsi3_cvt_zext"
9704 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9706 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9707 (match_operand:QI 2 "const_int_operand" ""))))
9708 (clobber (reg:CC FLAGS_REG))]
9709 "TARGET_64BIT && INTVAL (operands[2]) == 31
9710 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9711 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9714 sar{l}\t{%2, %k0|%k0, %2}"
9715 [(set_attr "type" "imovx,ishift")
9716 (set_attr "prefix_0f" "0,*")
9717 (set_attr "length_immediate" "0,*")
9718 (set_attr "modrm" "0,1")
9719 (set_attr "mode" "SI")])
9721 (define_expand "x86_shift<mode>_adj_3"
9722 [(use (match_operand:SWI48 0 "register_operand" ""))
9723 (use (match_operand:SWI48 1 "register_operand" ""))
9724 (use (match_operand:QI 2 "register_operand" ""))]
9727 rtx label = gen_label_rtx ();
9730 emit_insn (gen_testqi_ccz_1 (operands[2],
9731 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9733 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9734 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9735 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9736 gen_rtx_LABEL_REF (VOIDmode, label),
9738 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9739 JUMP_LABEL (tmp) = label;
9741 emit_move_insn (operands[0], operands[1]);
9742 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9743 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9745 LABEL_NUSES (label) = 1;
9750 (define_insn "*bmi2_<shift_insn><mode>3_1"
9751 [(set (match_operand:SWI48 0 "register_operand" "=r")
9752 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9753 (match_operand:SWI48 2 "register_operand" "r")))]
9755 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9756 [(set_attr "type" "ishiftx")
9757 (set_attr "mode" "<MODE>")])
9759 (define_insn "*<shift_insn><mode>3_1"
9760 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9762 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9763 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9764 (clobber (reg:CC FLAGS_REG))]
9765 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9767 switch (get_attr_type (insn))
9773 if (operands[2] == const1_rtx
9774 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9775 return "<shift>{<imodesuffix>}\t%0";
9777 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9780 [(set_attr "isa" "*,bmi2")
9781 (set_attr "type" "ishift,ishiftx")
9782 (set (attr "length_immediate")
9784 (and (match_operand 2 "const1_operand" "")
9785 (ior (match_test "TARGET_SHIFT1")
9786 (match_test "optimize_function_for_size_p (cfun)")))
9788 (const_string "*")))
9789 (set_attr "mode" "<MODE>")])
9791 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9793 [(set (match_operand:SWI48 0 "register_operand" "")
9794 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9795 (match_operand:QI 2 "register_operand" "")))
9796 (clobber (reg:CC FLAGS_REG))]
9797 "TARGET_BMI2 && reload_completed"
9799 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9800 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9802 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9803 [(set (match_operand:DI 0 "register_operand" "=r")
9805 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9806 (match_operand:SI 2 "register_operand" "r"))))]
9807 "TARGET_64BIT && TARGET_BMI2"
9808 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9809 [(set_attr "type" "ishiftx")
9810 (set_attr "mode" "SI")])
9812 (define_insn "*<shift_insn>si3_1_zext"
9813 [(set (match_operand:DI 0 "register_operand" "=r,r")
9815 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9816 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9817 (clobber (reg:CC FLAGS_REG))]
9818 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9820 switch (get_attr_type (insn))
9826 if (operands[2] == const1_rtx
9827 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9828 return "<shift>{l}\t%k0";
9830 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9833 [(set_attr "isa" "*,bmi2")
9834 (set_attr "type" "ishift,ishiftx")
9835 (set (attr "length_immediate")
9837 (and (match_operand 2 "const1_operand" "")
9838 (ior (match_test "TARGET_SHIFT1")
9839 (match_test "optimize_function_for_size_p (cfun)")))
9841 (const_string "*")))
9842 (set_attr "mode" "SI")])
9844 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9846 [(set (match_operand:DI 0 "register_operand" "")
9848 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9849 (match_operand:QI 2 "register_operand" ""))))
9850 (clobber (reg:CC FLAGS_REG))]
9851 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9853 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9854 "operands[2] = gen_lowpart (SImode, operands[2]);")
9856 (define_insn "*<shift_insn><mode>3_1"
9857 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9859 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9860 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9861 (clobber (reg:CC FLAGS_REG))]
9862 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9864 if (operands[2] == const1_rtx
9865 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9866 return "<shift>{<imodesuffix>}\t%0";
9868 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9870 [(set_attr "type" "ishift")
9871 (set (attr "length_immediate")
9873 (and (match_operand 2 "const1_operand" "")
9874 (ior (match_test "TARGET_SHIFT1")
9875 (match_test "optimize_function_for_size_p (cfun)")))
9877 (const_string "*")))
9878 (set_attr "mode" "<MODE>")])
9880 (define_insn "*<shift_insn>qi3_1_slp"
9881 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9882 (any_shiftrt:QI (match_dup 0)
9883 (match_operand:QI 1 "nonmemory_operand" "cI")))
9884 (clobber (reg:CC FLAGS_REG))]
9885 "(optimize_function_for_size_p (cfun)
9886 || !TARGET_PARTIAL_REG_STALL
9887 || (operands[1] == const1_rtx
9890 if (operands[1] == const1_rtx
9891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9892 return "<shift>{b}\t%0";
9894 return "<shift>{b}\t{%1, %0|%0, %1}";
9896 [(set_attr "type" "ishift1")
9897 (set (attr "length_immediate")
9899 (and (match_operand 1 "const1_operand" "")
9900 (ior (match_test "TARGET_SHIFT1")
9901 (match_test "optimize_function_for_size_p (cfun)")))
9903 (const_string "*")))
9904 (set_attr "mode" "QI")])
9906 ;; This pattern can't accept a variable shift count, since shifts by
9907 ;; zero don't affect the flags. We assume that shifts by constant
9908 ;; zero are optimized away.
9909 (define_insn "*<shift_insn><mode>3_cmp"
9910 [(set (reg FLAGS_REG)
9913 (match_operand:SWI 1 "nonimmediate_operand" "0")
9914 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9916 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9917 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9918 "(optimize_function_for_size_p (cfun)
9919 || !TARGET_PARTIAL_FLAG_REG_STALL
9920 || (operands[2] == const1_rtx
9922 && ix86_match_ccmode (insn, CCGOCmode)
9923 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9925 if (operands[2] == const1_rtx
9926 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9927 return "<shift>{<imodesuffix>}\t%0";
9929 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9931 [(set_attr "type" "ishift")
9932 (set (attr "length_immediate")
9934 (and (match_operand 2 "const1_operand" "")
9935 (ior (match_test "TARGET_SHIFT1")
9936 (match_test "optimize_function_for_size_p (cfun)")))
9938 (const_string "*")))
9939 (set_attr "mode" "<MODE>")])
9941 (define_insn "*<shift_insn>si3_cmp_zext"
9942 [(set (reg FLAGS_REG)
9944 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9945 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9947 (set (match_operand:DI 0 "register_operand" "=r")
9948 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9950 && (optimize_function_for_size_p (cfun)
9951 || !TARGET_PARTIAL_FLAG_REG_STALL
9952 || (operands[2] == const1_rtx
9954 && ix86_match_ccmode (insn, CCGOCmode)
9955 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9957 if (operands[2] == const1_rtx
9958 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9959 return "<shift>{l}\t%k0";
9961 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9963 [(set_attr "type" "ishift")
9964 (set (attr "length_immediate")
9966 (and (match_operand 2 "const1_operand" "")
9967 (ior (match_test "TARGET_SHIFT1")
9968 (match_test "optimize_function_for_size_p (cfun)")))
9970 (const_string "*")))
9971 (set_attr "mode" "SI")])
9973 (define_insn "*<shift_insn><mode>3_cconly"
9974 [(set (reg FLAGS_REG)
9977 (match_operand:SWI 1 "register_operand" "0")
9978 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9980 (clobber (match_scratch:SWI 0 "=<r>"))]
9981 "(optimize_function_for_size_p (cfun)
9982 || !TARGET_PARTIAL_FLAG_REG_STALL
9983 || (operands[2] == const1_rtx
9985 && ix86_match_ccmode (insn, CCGOCmode)"
9987 if (operands[2] == const1_rtx
9988 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9989 return "<shift>{<imodesuffix>}\t%0";
9991 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9993 [(set_attr "type" "ishift")
9994 (set (attr "length_immediate")
9996 (and (match_operand 2 "const1_operand" "")
9997 (ior (match_test "TARGET_SHIFT1")
9998 (match_test "optimize_function_for_size_p (cfun)")))
10000 (const_string "*")))
10001 (set_attr "mode" "<MODE>")])
10003 ;; Rotate instructions
10005 (define_expand "<rotate_insn>ti3"
10006 [(set (match_operand:TI 0 "register_operand" "")
10007 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10008 (match_operand:QI 2 "nonmemory_operand" "")))]
10011 if (const_1_to_63_operand (operands[2], VOIDmode))
10012 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10013 (operands[0], operands[1], operands[2]));
10020 (define_expand "<rotate_insn>di3"
10021 [(set (match_operand:DI 0 "shiftdi_operand" "")
10022 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10023 (match_operand:QI 2 "nonmemory_operand" "")))]
10027 ix86_expand_binary_operator (<CODE>, DImode, operands);
10028 else if (const_1_to_31_operand (operands[2], VOIDmode))
10029 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10030 (operands[0], operands[1], operands[2]));
10037 (define_expand "<rotate_insn><mode>3"
10038 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10039 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10040 (match_operand:QI 2 "nonmemory_operand" "")))]
10042 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10044 ;; Avoid useless masking of count operand.
10045 (define_insn "*<rotate_insn><mode>3_mask"
10046 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10048 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10051 (match_operand:SI 2 "register_operand" "c")
10052 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10053 (clobber (reg:CC FLAGS_REG))]
10054 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10055 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10056 == GET_MODE_BITSIZE (<MODE>mode)-1"
10058 return "<rotate>{<imodesuffix>}\t{%b2, %0|%0, %b2}";
10060 [(set_attr "type" "rotate")
10061 (set_attr "mode" "<MODE>")])
10063 ;; Implement rotation using two double-precision
10064 ;; shift instructions and a scratch register.
10066 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10067 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10068 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10069 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10070 (clobber (reg:CC FLAGS_REG))
10071 (clobber (match_scratch:DWIH 3 "=&r"))]
10075 [(set (match_dup 3) (match_dup 4))
10077 [(set (match_dup 4)
10078 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10079 (lshiftrt:DWIH (match_dup 5)
10080 (minus:QI (match_dup 6) (match_dup 2)))))
10081 (clobber (reg:CC FLAGS_REG))])
10083 [(set (match_dup 5)
10084 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10085 (lshiftrt:DWIH (match_dup 3)
10086 (minus:QI (match_dup 6) (match_dup 2)))))
10087 (clobber (reg:CC FLAGS_REG))])]
10089 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10091 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10094 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10095 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10096 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10097 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10098 (clobber (reg:CC FLAGS_REG))
10099 (clobber (match_scratch:DWIH 3 "=&r"))]
10103 [(set (match_dup 3) (match_dup 4))
10105 [(set (match_dup 4)
10106 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10107 (ashift:DWIH (match_dup 5)
10108 (minus:QI (match_dup 6) (match_dup 2)))))
10109 (clobber (reg:CC FLAGS_REG))])
10111 [(set (match_dup 5)
10112 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10113 (ashift:DWIH (match_dup 3)
10114 (minus:QI (match_dup 6) (match_dup 2)))))
10115 (clobber (reg:CC FLAGS_REG))])]
10117 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10119 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10122 (define_insn "*bmi2_rorx<mode>3_1"
10123 [(set (match_operand:SWI48 0 "register_operand" "=r")
10124 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10125 (match_operand:QI 2 "immediate_operand" "<S>")))]
10127 "rorx\t{%2, %1, %0|%0, %1, %2}"
10128 [(set_attr "type" "rotatex")
10129 (set_attr "mode" "<MODE>")])
10131 (define_insn "*<rotate_insn><mode>3_1"
10132 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10134 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10135 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10136 (clobber (reg:CC FLAGS_REG))]
10137 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10139 switch (get_attr_type (insn))
10145 if (operands[2] == const1_rtx
10146 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10147 return "<rotate>{<imodesuffix>}\t%0";
10149 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10152 [(set_attr "isa" "*,bmi2")
10153 (set_attr "type" "rotate,rotatex")
10154 (set (attr "length_immediate")
10156 (and (eq_attr "type" "rotate")
10157 (and (match_operand 2 "const1_operand" "")
10158 (ior (match_test "TARGET_SHIFT1")
10159 (match_test "optimize_function_for_size_p (cfun)"))))
10161 (const_string "*")))
10162 (set_attr "mode" "<MODE>")])
10164 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10166 [(set (match_operand:SWI48 0 "register_operand" "")
10167 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10168 (match_operand:QI 2 "immediate_operand" "")))
10169 (clobber (reg:CC FLAGS_REG))]
10170 "TARGET_BMI2 && reload_completed"
10171 [(set (match_dup 0)
10172 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10175 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10179 [(set (match_operand:SWI48 0 "register_operand" "")
10180 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10181 (match_operand:QI 2 "immediate_operand" "")))
10182 (clobber (reg:CC FLAGS_REG))]
10183 "TARGET_BMI2 && reload_completed"
10184 [(set (match_dup 0)
10185 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10187 (define_insn "*bmi2_rorxsi3_1_zext"
10188 [(set (match_operand:DI 0 "register_operand" "=r")
10190 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10191 (match_operand:QI 2 "immediate_operand" "I"))))]
10192 "TARGET_64BIT && TARGET_BMI2"
10193 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10194 [(set_attr "type" "rotatex")
10195 (set_attr "mode" "SI")])
10197 (define_insn "*<rotate_insn>si3_1_zext"
10198 [(set (match_operand:DI 0 "register_operand" "=r,r")
10200 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10201 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10202 (clobber (reg:CC FLAGS_REG))]
10203 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10205 switch (get_attr_type (insn))
10211 if (operands[2] == const1_rtx
10212 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10213 return "<rotate>{l}\t%k0";
10215 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10218 [(set_attr "isa" "*,bmi2")
10219 (set_attr "type" "rotate,rotatex")
10220 (set (attr "length_immediate")
10222 (and (eq_attr "type" "rotate")
10223 (and (match_operand 2 "const1_operand" "")
10224 (ior (match_test "TARGET_SHIFT1")
10225 (match_test "optimize_function_for_size_p (cfun)"))))
10227 (const_string "*")))
10228 (set_attr "mode" "SI")])
10230 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10232 [(set (match_operand:DI 0 "register_operand" "")
10234 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10235 (match_operand:QI 2 "immediate_operand" ""))))
10236 (clobber (reg:CC FLAGS_REG))]
10237 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10238 [(set (match_dup 0)
10239 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10242 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10246 [(set (match_operand:DI 0 "register_operand" "")
10248 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10249 (match_operand:QI 2 "immediate_operand" ""))))
10250 (clobber (reg:CC FLAGS_REG))]
10251 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10252 [(set (match_dup 0)
10253 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10255 (define_insn "*<rotate_insn><mode>3_1"
10256 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10257 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10258 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10259 (clobber (reg:CC FLAGS_REG))]
10260 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10262 if (operands[2] == const1_rtx
10263 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10264 return "<rotate>{<imodesuffix>}\t%0";
10266 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10268 [(set_attr "type" "rotate")
10269 (set (attr "length_immediate")
10271 (and (match_operand 2 "const1_operand" "")
10272 (ior (match_test "TARGET_SHIFT1")
10273 (match_test "optimize_function_for_size_p (cfun)")))
10275 (const_string "*")))
10276 (set_attr "mode" "<MODE>")])
10278 (define_insn "*<rotate_insn>qi3_1_slp"
10279 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10280 (any_rotate:QI (match_dup 0)
10281 (match_operand:QI 1 "nonmemory_operand" "cI")))
10282 (clobber (reg:CC FLAGS_REG))]
10283 "(optimize_function_for_size_p (cfun)
10284 || !TARGET_PARTIAL_REG_STALL
10285 || (operands[1] == const1_rtx
10286 && TARGET_SHIFT1))"
10288 if (operands[1] == const1_rtx
10289 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10290 return "<rotate>{b}\t%0";
10292 return "<rotate>{b}\t{%1, %0|%0, %1}";
10294 [(set_attr "type" "rotate1")
10295 (set (attr "length_immediate")
10297 (and (match_operand 1 "const1_operand" "")
10298 (ior (match_test "TARGET_SHIFT1")
10299 (match_test "optimize_function_for_size_p (cfun)")))
10301 (const_string "*")))
10302 (set_attr "mode" "QI")])
10305 [(set (match_operand:HI 0 "register_operand" "")
10306 (any_rotate:HI (match_dup 0) (const_int 8)))
10307 (clobber (reg:CC FLAGS_REG))]
10309 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10310 [(parallel [(set (strict_low_part (match_dup 0))
10311 (bswap:HI (match_dup 0)))
10312 (clobber (reg:CC FLAGS_REG))])])
10314 ;; Bit set / bit test instructions
10316 (define_expand "extv"
10317 [(set (match_operand:SI 0 "register_operand" "")
10318 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10319 (match_operand:SI 2 "const8_operand" "")
10320 (match_operand:SI 3 "const8_operand" "")))]
10323 /* Handle extractions from %ah et al. */
10324 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10327 /* From mips.md: extract_bit_field doesn't verify that our source
10328 matches the predicate, so check it again here. */
10329 if (! ext_register_operand (operands[1], VOIDmode))
10333 (define_expand "extzv"
10334 [(set (match_operand:SI 0 "register_operand" "")
10335 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10336 (match_operand:SI 2 "const8_operand" "")
10337 (match_operand:SI 3 "const8_operand" "")))]
10340 /* Handle extractions from %ah et al. */
10341 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10344 /* From mips.md: extract_bit_field doesn't verify that our source
10345 matches the predicate, so check it again here. */
10346 if (! ext_register_operand (operands[1], VOIDmode))
10350 (define_expand "insv"
10351 [(set (zero_extract (match_operand 0 "register_operand" "")
10352 (match_operand 1 "const_int_operand" "")
10353 (match_operand 2 "const_int_operand" ""))
10354 (match_operand 3 "register_operand" ""))]
10357 rtx (*gen_mov_insv_1) (rtx, rtx);
10359 if (ix86_expand_pinsr (operands))
10362 /* Handle insertions to %ah et al. */
10363 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10366 /* From mips.md: insert_bit_field doesn't verify that our source
10367 matches the predicate, so check it again here. */
10368 if (! ext_register_operand (operands[0], VOIDmode))
10371 gen_mov_insv_1 = (TARGET_64BIT
10372 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10374 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10378 ;; %%% bts, btr, btc, bt.
10379 ;; In general these instructions are *slow* when applied to memory,
10380 ;; since they enforce atomic operation. When applied to registers,
10381 ;; it depends on the cpu implementation. They're never faster than
10382 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10383 ;; no point. But in 64-bit, we can't hold the relevant immediates
10384 ;; within the instruction itself, so operating on bits in the high
10385 ;; 32-bits of a register becomes easier.
10387 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10388 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10389 ;; negdf respectively, so they can never be disabled entirely.
10391 (define_insn "*btsq"
10392 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10394 (match_operand:DI 1 "const_0_to_63_operand" ""))
10396 (clobber (reg:CC FLAGS_REG))]
10397 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10398 "bts{q}\t{%1, %0|%0, %1}"
10399 [(set_attr "type" "alu1")
10400 (set_attr "prefix_0f" "1")
10401 (set_attr "mode" "DI")])
10403 (define_insn "*btrq"
10404 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10406 (match_operand:DI 1 "const_0_to_63_operand" ""))
10408 (clobber (reg:CC FLAGS_REG))]
10409 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10410 "btr{q}\t{%1, %0|%0, %1}"
10411 [(set_attr "type" "alu1")
10412 (set_attr "prefix_0f" "1")
10413 (set_attr "mode" "DI")])
10415 (define_insn "*btcq"
10416 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10418 (match_operand:DI 1 "const_0_to_63_operand" ""))
10419 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10420 (clobber (reg:CC FLAGS_REG))]
10421 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10422 "btc{q}\t{%1, %0|%0, %1}"
10423 [(set_attr "type" "alu1")
10424 (set_attr "prefix_0f" "1")
10425 (set_attr "mode" "DI")])
10427 ;; Allow Nocona to avoid these instructions if a register is available.
10430 [(match_scratch:DI 2 "r")
10431 (parallel [(set (zero_extract:DI
10432 (match_operand:DI 0 "register_operand" "")
10434 (match_operand:DI 1 "const_0_to_63_operand" ""))
10436 (clobber (reg:CC FLAGS_REG))])]
10437 "TARGET_64BIT && !TARGET_USE_BT"
10440 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10443 if (HOST_BITS_PER_WIDE_INT >= 64)
10444 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10445 else if (i < HOST_BITS_PER_WIDE_INT)
10446 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10448 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10450 op1 = immed_double_const (lo, hi, DImode);
10453 emit_move_insn (operands[2], op1);
10457 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10462 [(match_scratch:DI 2 "r")
10463 (parallel [(set (zero_extract:DI
10464 (match_operand:DI 0 "register_operand" "")
10466 (match_operand:DI 1 "const_0_to_63_operand" ""))
10468 (clobber (reg:CC FLAGS_REG))])]
10469 "TARGET_64BIT && !TARGET_USE_BT"
10472 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10475 if (HOST_BITS_PER_WIDE_INT >= 64)
10476 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10477 else if (i < HOST_BITS_PER_WIDE_INT)
10478 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10480 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10482 op1 = immed_double_const (~lo, ~hi, DImode);
10485 emit_move_insn (operands[2], op1);
10489 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10494 [(match_scratch:DI 2 "r")
10495 (parallel [(set (zero_extract:DI
10496 (match_operand:DI 0 "register_operand" "")
10498 (match_operand:DI 1 "const_0_to_63_operand" ""))
10499 (not:DI (zero_extract:DI
10500 (match_dup 0) (const_int 1) (match_dup 1))))
10501 (clobber (reg:CC FLAGS_REG))])]
10502 "TARGET_64BIT && !TARGET_USE_BT"
10505 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10508 if (HOST_BITS_PER_WIDE_INT >= 64)
10509 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10510 else if (i < HOST_BITS_PER_WIDE_INT)
10511 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10513 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10515 op1 = immed_double_const (lo, hi, DImode);
10518 emit_move_insn (operands[2], op1);
10522 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10526 (define_insn "*bt<mode>"
10527 [(set (reg:CCC FLAGS_REG)
10529 (zero_extract:SWI48
10530 (match_operand:SWI48 0 "register_operand" "r")
10532 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10534 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10535 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10536 [(set_attr "type" "alu1")
10537 (set_attr "prefix_0f" "1")
10538 (set_attr "mode" "<MODE>")])
10540 ;; Store-flag instructions.
10542 ;; For all sCOND expanders, also expand the compare or test insn that
10543 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10545 (define_insn_and_split "*setcc_di_1"
10546 [(set (match_operand:DI 0 "register_operand" "=q")
10547 (match_operator:DI 1 "ix86_comparison_operator"
10548 [(reg FLAGS_REG) (const_int 0)]))]
10549 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10551 "&& reload_completed"
10552 [(set (match_dup 2) (match_dup 1))
10553 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10555 PUT_MODE (operands[1], QImode);
10556 operands[2] = gen_lowpart (QImode, operands[0]);
10559 (define_insn_and_split "*setcc_si_1_and"
10560 [(set (match_operand:SI 0 "register_operand" "=q")
10561 (match_operator:SI 1 "ix86_comparison_operator"
10562 [(reg FLAGS_REG) (const_int 0)]))
10563 (clobber (reg:CC FLAGS_REG))]
10564 "!TARGET_PARTIAL_REG_STALL
10565 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10567 "&& reload_completed"
10568 [(set (match_dup 2) (match_dup 1))
10569 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10570 (clobber (reg:CC FLAGS_REG))])]
10572 PUT_MODE (operands[1], QImode);
10573 operands[2] = gen_lowpart (QImode, operands[0]);
10576 (define_insn_and_split "*setcc_si_1_movzbl"
10577 [(set (match_operand:SI 0 "register_operand" "=q")
10578 (match_operator:SI 1 "ix86_comparison_operator"
10579 [(reg FLAGS_REG) (const_int 0)]))]
10580 "!TARGET_PARTIAL_REG_STALL
10581 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10583 "&& reload_completed"
10584 [(set (match_dup 2) (match_dup 1))
10585 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10587 PUT_MODE (operands[1], QImode);
10588 operands[2] = gen_lowpart (QImode, operands[0]);
10591 (define_insn "*setcc_qi"
10592 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10593 (match_operator:QI 1 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)]))]
10597 [(set_attr "type" "setcc")
10598 (set_attr "mode" "QI")])
10600 (define_insn "*setcc_qi_slp"
10601 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10602 (match_operator:QI 1 "ix86_comparison_operator"
10603 [(reg FLAGS_REG) (const_int 0)]))]
10606 [(set_attr "type" "setcc")
10607 (set_attr "mode" "QI")])
10609 ;; In general it is not safe to assume too much about CCmode registers,
10610 ;; so simplify-rtx stops when it sees a second one. Under certain
10611 ;; conditions this is safe on x86, so help combine not create
10618 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10619 (ne:QI (match_operator 1 "ix86_comparison_operator"
10620 [(reg FLAGS_REG) (const_int 0)])
10623 [(set (match_dup 0) (match_dup 1))]
10624 "PUT_MODE (operands[1], QImode);")
10627 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10628 (ne:QI (match_operator 1 "ix86_comparison_operator"
10629 [(reg FLAGS_REG) (const_int 0)])
10632 [(set (match_dup 0) (match_dup 1))]
10633 "PUT_MODE (operands[1], QImode);")
10636 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10637 (eq:QI (match_operator 1 "ix86_comparison_operator"
10638 [(reg FLAGS_REG) (const_int 0)])
10641 [(set (match_dup 0) (match_dup 1))]
10643 rtx new_op1 = copy_rtx (operands[1]);
10644 operands[1] = new_op1;
10645 PUT_MODE (new_op1, QImode);
10646 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10647 GET_MODE (XEXP (new_op1, 0))));
10649 /* Make sure that (a) the CCmode we have for the flags is strong
10650 enough for the reversed compare or (b) we have a valid FP compare. */
10651 if (! ix86_comparison_operator (new_op1, VOIDmode))
10656 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10657 (eq:QI (match_operator 1 "ix86_comparison_operator"
10658 [(reg FLAGS_REG) (const_int 0)])
10661 [(set (match_dup 0) (match_dup 1))]
10663 rtx new_op1 = copy_rtx (operands[1]);
10664 operands[1] = new_op1;
10665 PUT_MODE (new_op1, QImode);
10666 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10667 GET_MODE (XEXP (new_op1, 0))));
10669 /* Make sure that (a) the CCmode we have for the flags is strong
10670 enough for the reversed compare or (b) we have a valid FP compare. */
10671 if (! ix86_comparison_operator (new_op1, VOIDmode))
10675 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10676 ;; subsequent logical operations are used to imitate conditional moves.
10677 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10680 (define_insn "setcc_<mode>_sse"
10681 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10682 (match_operator:MODEF 3 "sse_comparison_operator"
10683 [(match_operand:MODEF 1 "register_operand" "0,x")
10684 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10685 "SSE_FLOAT_MODE_P (<MODE>mode)"
10687 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10688 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10689 [(set_attr "isa" "noavx,avx")
10690 (set_attr "type" "ssecmp")
10691 (set_attr "length_immediate" "1")
10692 (set_attr "prefix" "orig,vex")
10693 (set_attr "mode" "<MODE>")])
10695 ;; Basic conditional jump instructions.
10696 ;; We ignore the overflow flag for signed branch instructions.
10698 (define_insn "*jcc_1"
10700 (if_then_else (match_operator 1 "ix86_comparison_operator"
10701 [(reg FLAGS_REG) (const_int 0)])
10702 (label_ref (match_operand 0 "" ""))
10706 [(set_attr "type" "ibr")
10707 (set_attr "modrm" "0")
10708 (set (attr "length")
10709 (if_then_else (and (ge (minus (match_dup 0) (pc))
10711 (lt (minus (match_dup 0) (pc))
10716 (define_insn "*jcc_2"
10718 (if_then_else (match_operator 1 "ix86_comparison_operator"
10719 [(reg FLAGS_REG) (const_int 0)])
10721 (label_ref (match_operand 0 "" ""))))]
10724 [(set_attr "type" "ibr")
10725 (set_attr "modrm" "0")
10726 (set (attr "length")
10727 (if_then_else (and (ge (minus (match_dup 0) (pc))
10729 (lt (minus (match_dup 0) (pc))
10734 ;; In general it is not safe to assume too much about CCmode registers,
10735 ;; so simplify-rtx stops when it sees a second one. Under certain
10736 ;; conditions this is safe on x86, so help combine not create
10744 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10745 [(reg FLAGS_REG) (const_int 0)])
10747 (label_ref (match_operand 1 "" ""))
10751 (if_then_else (match_dup 0)
10752 (label_ref (match_dup 1))
10754 "PUT_MODE (operands[0], VOIDmode);")
10758 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10759 [(reg FLAGS_REG) (const_int 0)])
10761 (label_ref (match_operand 1 "" ""))
10765 (if_then_else (match_dup 0)
10766 (label_ref (match_dup 1))
10769 rtx new_op0 = copy_rtx (operands[0]);
10770 operands[0] = new_op0;
10771 PUT_MODE (new_op0, VOIDmode);
10772 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10773 GET_MODE (XEXP (new_op0, 0))));
10775 /* Make sure that (a) the CCmode we have for the flags is strong
10776 enough for the reversed compare or (b) we have a valid FP compare. */
10777 if (! ix86_comparison_operator (new_op0, VOIDmode))
10781 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10782 ;; pass generates from shift insn with QImode operand. Actually, the mode
10783 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10784 ;; appropriate modulo of the bit offset value.
10786 (define_insn_and_split "*jcc_bt<mode>"
10788 (if_then_else (match_operator 0 "bt_comparison_operator"
10789 [(zero_extract:SWI48
10790 (match_operand:SWI48 1 "register_operand" "r")
10793 (match_operand:QI 2 "register_operand" "r")))
10795 (label_ref (match_operand 3 "" ""))
10797 (clobber (reg:CC FLAGS_REG))]
10798 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10801 [(set (reg:CCC FLAGS_REG)
10803 (zero_extract:SWI48
10809 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10810 (label_ref (match_dup 3))
10813 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10815 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10818 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10819 ;; also for DImode, this is what combine produces.
10820 (define_insn_and_split "*jcc_bt<mode>_mask"
10822 (if_then_else (match_operator 0 "bt_comparison_operator"
10823 [(zero_extract:SWI48
10824 (match_operand:SWI48 1 "register_operand" "r")
10827 (match_operand:SI 2 "register_operand" "r")
10828 (match_operand:SI 3 "const_int_operand" "n")))])
10829 (label_ref (match_operand 4 "" ""))
10831 (clobber (reg:CC FLAGS_REG))]
10832 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10833 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10834 == GET_MODE_BITSIZE (<MODE>mode)-1"
10837 [(set (reg:CCC FLAGS_REG)
10839 (zero_extract:SWI48
10845 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10846 (label_ref (match_dup 4))
10849 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10851 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10854 (define_insn_and_split "*jcc_btsi_1"
10856 (if_then_else (match_operator 0 "bt_comparison_operator"
10859 (match_operand:SI 1 "register_operand" "r")
10860 (match_operand:QI 2 "register_operand" "r"))
10863 (label_ref (match_operand 3 "" ""))
10865 (clobber (reg:CC FLAGS_REG))]
10866 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10869 [(set (reg:CCC FLAGS_REG)
10877 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10878 (label_ref (match_dup 3))
10881 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10883 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10886 ;; avoid useless masking of bit offset operand
10887 (define_insn_and_split "*jcc_btsi_mask_1"
10890 (match_operator 0 "bt_comparison_operator"
10893 (match_operand:SI 1 "register_operand" "r")
10896 (match_operand:SI 2 "register_operand" "r")
10897 (match_operand:SI 3 "const_int_operand" "n")) 0))
10900 (label_ref (match_operand 4 "" ""))
10902 (clobber (reg:CC FLAGS_REG))]
10903 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10904 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10907 [(set (reg:CCC FLAGS_REG)
10915 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10916 (label_ref (match_dup 4))
10918 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10920 ;; Define combination compare-and-branch fp compare instructions to help
10923 (define_insn "*fp_jcc_1_387"
10925 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10926 [(match_operand 1 "register_operand" "f")
10927 (match_operand 2 "nonimmediate_operand" "fm")])
10928 (label_ref (match_operand 3 "" ""))
10930 (clobber (reg:CCFP FPSR_REG))
10931 (clobber (reg:CCFP FLAGS_REG))
10932 (clobber (match_scratch:HI 4 "=a"))]
10934 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10935 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10936 && SELECT_CC_MODE (GET_CODE (operands[0]),
10937 operands[1], operands[2]) == CCFPmode
10941 (define_insn "*fp_jcc_1r_387"
10943 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10944 [(match_operand 1 "register_operand" "f")
10945 (match_operand 2 "nonimmediate_operand" "fm")])
10947 (label_ref (match_operand 3 "" ""))))
10948 (clobber (reg:CCFP FPSR_REG))
10949 (clobber (reg:CCFP FLAGS_REG))
10950 (clobber (match_scratch:HI 4 "=a"))]
10952 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10953 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10954 && SELECT_CC_MODE (GET_CODE (operands[0]),
10955 operands[1], operands[2]) == CCFPmode
10959 (define_insn "*fp_jcc_2_387"
10961 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10962 [(match_operand 1 "register_operand" "f")
10963 (match_operand 2 "register_operand" "f")])
10964 (label_ref (match_operand 3 "" ""))
10966 (clobber (reg:CCFP FPSR_REG))
10967 (clobber (reg:CCFP FLAGS_REG))
10968 (clobber (match_scratch:HI 4 "=a"))]
10969 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10970 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10974 (define_insn "*fp_jcc_2r_387"
10976 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10977 [(match_operand 1 "register_operand" "f")
10978 (match_operand 2 "register_operand" "f")])
10980 (label_ref (match_operand 3 "" ""))))
10981 (clobber (reg:CCFP FPSR_REG))
10982 (clobber (reg:CCFP FLAGS_REG))
10983 (clobber (match_scratch:HI 4 "=a"))]
10984 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10985 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10989 (define_insn "*fp_jcc_3_387"
10991 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10992 [(match_operand 1 "register_operand" "f")
10993 (match_operand 2 "const0_operand" "")])
10994 (label_ref (match_operand 3 "" ""))
10996 (clobber (reg:CCFP FPSR_REG))
10997 (clobber (reg:CCFP FLAGS_REG))
10998 (clobber (match_scratch:HI 4 "=a"))]
10999 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11000 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11001 && SELECT_CC_MODE (GET_CODE (operands[0]),
11002 operands[1], operands[2]) == CCFPmode
11008 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11009 [(match_operand 1 "register_operand" "")
11010 (match_operand 2 "nonimmediate_operand" "")])
11011 (match_operand 3 "" "")
11012 (match_operand 4 "" "")))
11013 (clobber (reg:CCFP FPSR_REG))
11014 (clobber (reg:CCFP FLAGS_REG))]
11018 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11019 operands[3], operands[4], NULL_RTX, NULL_RTX);
11025 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11026 [(match_operand 1 "register_operand" "")
11027 (match_operand 2 "general_operand" "")])
11028 (match_operand 3 "" "")
11029 (match_operand 4 "" "")))
11030 (clobber (reg:CCFP FPSR_REG))
11031 (clobber (reg:CCFP FLAGS_REG))
11032 (clobber (match_scratch:HI 5 "=a"))]
11036 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11037 operands[3], operands[4], operands[5], NULL_RTX);
11041 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11042 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11043 ;; with a precedence over other operators and is always put in the first
11044 ;; place. Swap condition and operands to match ficom instruction.
11046 (define_insn "*fp_jcc_4_<mode>_387"
11049 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11050 [(match_operator 1 "float_operator"
11051 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11052 (match_operand 3 "register_operand" "f,f")])
11053 (label_ref (match_operand 4 "" ""))
11055 (clobber (reg:CCFP FPSR_REG))
11056 (clobber (reg:CCFP FLAGS_REG))
11057 (clobber (match_scratch:HI 5 "=a,a"))]
11058 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11059 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11060 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11061 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11068 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11069 [(match_operator 1 "float_operator"
11070 [(match_operand:SWI24 2 "memory_operand" "")])
11071 (match_operand 3 "register_operand" "")])
11072 (match_operand 4 "" "")
11073 (match_operand 5 "" "")))
11074 (clobber (reg:CCFP FPSR_REG))
11075 (clobber (reg:CCFP FLAGS_REG))
11076 (clobber (match_scratch:HI 6 "=a"))]
11080 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11082 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11083 operands[3], operands[7],
11084 operands[4], operands[5], operands[6], NULL_RTX);
11088 ;; %%% Kill this when reload knows how to do it.
11092 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11093 [(match_operator 1 "float_operator"
11094 [(match_operand:SWI24 2 "register_operand" "")])
11095 (match_operand 3 "register_operand" "")])
11096 (match_operand 4 "" "")
11097 (match_operand 5 "" "")))
11098 (clobber (reg:CCFP FPSR_REG))
11099 (clobber (reg:CCFP FLAGS_REG))
11100 (clobber (match_scratch:HI 6 "=a"))]
11104 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11105 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11107 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11108 operands[3], operands[7],
11109 operands[4], operands[5], operands[6], operands[2]);
11113 ;; Unconditional and other jump instructions
11115 (define_insn "jump"
11117 (label_ref (match_operand 0 "" "")))]
11120 [(set_attr "type" "ibr")
11121 (set (attr "length")
11122 (if_then_else (and (ge (minus (match_dup 0) (pc))
11124 (lt (minus (match_dup 0) (pc))
11128 (set_attr "modrm" "0")])
11130 (define_expand "indirect_jump"
11131 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11133 (define_insn "*indirect_jump"
11134 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11137 [(set_attr "type" "ibr")
11138 (set_attr "length_immediate" "0")])
11140 (define_expand "tablejump"
11141 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11142 (use (label_ref (match_operand 1 "" "")))])]
11145 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11146 relative. Convert the relative address to an absolute address. */
11150 enum rtx_code code;
11152 /* We can't use @GOTOFF for text labels on VxWorks;
11153 see gotoff_operand. */
11154 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11158 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11160 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11164 op1 = pic_offset_table_rtx;
11169 op0 = pic_offset_table_rtx;
11173 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11176 else if (TARGET_X32)
11177 operands[0] = convert_memory_address (Pmode, operands[0]);
11180 (define_insn "*tablejump_1"
11181 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11182 (use (label_ref (match_operand 1 "" "")))]
11185 [(set_attr "type" "ibr")
11186 (set_attr "length_immediate" "0")])
11188 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11191 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11192 (set (match_operand:QI 1 "register_operand" "")
11193 (match_operator:QI 2 "ix86_comparison_operator"
11194 [(reg FLAGS_REG) (const_int 0)]))
11195 (set (match_operand 3 "q_regs_operand" "")
11196 (zero_extend (match_dup 1)))]
11197 "(peep2_reg_dead_p (3, operands[1])
11198 || operands_match_p (operands[1], operands[3]))
11199 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11200 [(set (match_dup 4) (match_dup 0))
11201 (set (strict_low_part (match_dup 5))
11204 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11205 operands[5] = gen_lowpart (QImode, operands[3]);
11206 ix86_expand_clear (operands[3]);
11209 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11212 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11213 (set (match_operand:QI 1 "register_operand" "")
11214 (match_operator:QI 2 "ix86_comparison_operator"
11215 [(reg FLAGS_REG) (const_int 0)]))
11216 (parallel [(set (match_operand 3 "q_regs_operand" "")
11217 (zero_extend (match_dup 1)))
11218 (clobber (reg:CC FLAGS_REG))])]
11219 "(peep2_reg_dead_p (3, operands[1])
11220 || operands_match_p (operands[1], operands[3]))
11221 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11222 [(set (match_dup 4) (match_dup 0))
11223 (set (strict_low_part (match_dup 5))
11226 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11227 operands[5] = gen_lowpart (QImode, operands[3]);
11228 ix86_expand_clear (operands[3]);
11231 ;; Call instructions.
11233 ;; The predicates normally associated with named expanders are not properly
11234 ;; checked for calls. This is a bug in the generic code, but it isn't that
11235 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11237 ;; P6 processors will jump to the address after the decrement when %esp
11238 ;; is used as a call operand, so they will execute return address as a code.
11239 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11241 ;; Register constraint for call instruction.
11242 (define_mode_attr c [(SI "l") (DI "r")])
11244 ;; Call subroutine returning no value.
11246 (define_expand "call"
11247 [(call (match_operand:QI 0 "" "")
11248 (match_operand 1 "" ""))
11249 (use (match_operand 2 "" ""))]
11252 ix86_expand_call (NULL, operands[0], operands[1],
11253 operands[2], NULL, false);
11257 (define_expand "sibcall"
11258 [(call (match_operand:QI 0 "" "")
11259 (match_operand 1 "" ""))
11260 (use (match_operand 2 "" ""))]
11263 ix86_expand_call (NULL, operands[0], operands[1],
11264 operands[2], NULL, true);
11268 (define_insn_and_split "*call_vzeroupper"
11269 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11270 (match_operand 1 "" ""))
11271 (unspec [(match_operand 2 "const_int_operand" "")]
11272 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11273 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11275 "&& reload_completed"
11277 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11278 [(set_attr "type" "call")])
11280 (define_insn "*call"
11281 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11282 (match_operand 1 "" ""))]
11283 "!SIBLING_CALL_P (insn)"
11284 "* return ix86_output_call_insn (insn, operands[0]);"
11285 [(set_attr "type" "call")])
11287 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11288 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11289 (match_operand 1 "" ""))
11290 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11291 (clobber (reg:TI XMM6_REG))
11292 (clobber (reg:TI XMM7_REG))
11293 (clobber (reg:TI XMM8_REG))
11294 (clobber (reg:TI XMM9_REG))
11295 (clobber (reg:TI XMM10_REG))
11296 (clobber (reg:TI XMM11_REG))
11297 (clobber (reg:TI XMM12_REG))
11298 (clobber (reg:TI XMM13_REG))
11299 (clobber (reg:TI XMM14_REG))
11300 (clobber (reg:TI XMM15_REG))
11301 (clobber (reg:DI SI_REG))
11302 (clobber (reg:DI DI_REG))
11303 (unspec [(match_operand 2 "const_int_operand" "")]
11304 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11305 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11307 "&& reload_completed"
11309 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11310 [(set_attr "type" "call")])
11312 (define_insn "*call_rex64_ms_sysv"
11313 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11314 (match_operand 1 "" ""))
11315 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11316 (clobber (reg:TI XMM6_REG))
11317 (clobber (reg:TI XMM7_REG))
11318 (clobber (reg:TI XMM8_REG))
11319 (clobber (reg:TI XMM9_REG))
11320 (clobber (reg:TI XMM10_REG))
11321 (clobber (reg:TI XMM11_REG))
11322 (clobber (reg:TI XMM12_REG))
11323 (clobber (reg:TI XMM13_REG))
11324 (clobber (reg:TI XMM14_REG))
11325 (clobber (reg:TI XMM15_REG))
11326 (clobber (reg:DI SI_REG))
11327 (clobber (reg:DI DI_REG))]
11328 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11329 "* return ix86_output_call_insn (insn, operands[0]);"
11330 [(set_attr "type" "call")])
11332 (define_insn_and_split "*sibcall_vzeroupper"
11333 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11334 (match_operand 1 "" ""))
11335 (unspec [(match_operand 2 "const_int_operand" "")]
11336 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11337 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11339 "&& reload_completed"
11341 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11342 [(set_attr "type" "call")])
11344 (define_insn "*sibcall"
11345 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11346 (match_operand 1 "" ""))]
11347 "SIBLING_CALL_P (insn)"
11348 "* return ix86_output_call_insn (insn, operands[0]);"
11349 [(set_attr "type" "call")])
11351 (define_expand "call_pop"
11352 [(parallel [(call (match_operand:QI 0 "" "")
11353 (match_operand:SI 1 "" ""))
11354 (set (reg:SI SP_REG)
11355 (plus:SI (reg:SI SP_REG)
11356 (match_operand:SI 3 "" "")))])]
11359 ix86_expand_call (NULL, operands[0], operands[1],
11360 operands[2], operands[3], false);
11364 (define_insn_and_split "*call_pop_vzeroupper"
11365 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11366 (match_operand:SI 1 "" ""))
11367 (set (reg:SI SP_REG)
11368 (plus:SI (reg:SI SP_REG)
11369 (match_operand:SI 2 "immediate_operand" "i")))
11370 (unspec [(match_operand 3 "const_int_operand" "")]
11371 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11372 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11374 "&& reload_completed"
11376 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11377 [(set_attr "type" "call")])
11379 (define_insn "*call_pop"
11380 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11381 (match_operand 1 "" ""))
11382 (set (reg:SI SP_REG)
11383 (plus:SI (reg:SI SP_REG)
11384 (match_operand:SI 2 "immediate_operand" "i")))]
11385 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11386 "* return ix86_output_call_insn (insn, operands[0]);"
11387 [(set_attr "type" "call")])
11389 (define_insn_and_split "*sibcall_pop_vzeroupper"
11390 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11391 (match_operand 1 "" ""))
11392 (set (reg:SI SP_REG)
11393 (plus:SI (reg:SI SP_REG)
11394 (match_operand:SI 2 "immediate_operand" "i")))
11395 (unspec [(match_operand 3 "const_int_operand" "")]
11396 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11397 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11399 "&& reload_completed"
11401 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11402 [(set_attr "type" "call")])
11404 (define_insn "*sibcall_pop"
11405 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11406 (match_operand 1 "" ""))
11407 (set (reg:SI SP_REG)
11408 (plus:SI (reg:SI SP_REG)
11409 (match_operand:SI 2 "immediate_operand" "i")))]
11410 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11411 "* return ix86_output_call_insn (insn, operands[0]);"
11412 [(set_attr "type" "call")])
11414 ;; Call subroutine, returning value in operand 0
11416 (define_expand "call_value"
11417 [(set (match_operand 0 "" "")
11418 (call (match_operand:QI 1 "" "")
11419 (match_operand 2 "" "")))
11420 (use (match_operand 3 "" ""))]
11423 ix86_expand_call (operands[0], operands[1], operands[2],
11424 operands[3], NULL, false);
11428 (define_expand "sibcall_value"
11429 [(set (match_operand 0 "" "")
11430 (call (match_operand:QI 1 "" "")
11431 (match_operand 2 "" "")))
11432 (use (match_operand 3 "" ""))]
11435 ix86_expand_call (operands[0], operands[1], operands[2],
11436 operands[3], NULL, true);
11440 (define_insn_and_split "*call_value_vzeroupper"
11441 [(set (match_operand 0 "" "")
11442 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11443 (match_operand 2 "" "")))
11444 (unspec [(match_operand 3 "const_int_operand" "")]
11445 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11446 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11448 "&& reload_completed"
11450 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11451 [(set_attr "type" "callv")])
11453 (define_insn "*call_value"
11454 [(set (match_operand 0 "" "")
11455 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11456 (match_operand 2 "" "")))]
11457 "!SIBLING_CALL_P (insn)"
11458 "* return ix86_output_call_insn (insn, operands[1]);"
11459 [(set_attr "type" "callv")])
11461 (define_insn_and_split "*sibcall_value_vzeroupper"
11462 [(set (match_operand 0 "" "")
11463 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11464 (match_operand 2 "" "")))
11465 (unspec [(match_operand 3 "const_int_operand" "")]
11466 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11467 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11469 "&& reload_completed"
11471 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11472 [(set_attr "type" "callv")])
11474 (define_insn "*sibcall_value"
11475 [(set (match_operand 0 "" "")
11476 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11477 (match_operand 2 "" "")))]
11478 "SIBLING_CALL_P (insn)"
11479 "* return ix86_output_call_insn (insn, operands[1]);"
11480 [(set_attr "type" "callv")])
11482 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11483 [(set (match_operand 0 "" "")
11484 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11485 (match_operand 2 "" "")))
11486 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11487 (clobber (reg:TI XMM6_REG))
11488 (clobber (reg:TI XMM7_REG))
11489 (clobber (reg:TI XMM8_REG))
11490 (clobber (reg:TI XMM9_REG))
11491 (clobber (reg:TI XMM10_REG))
11492 (clobber (reg:TI XMM11_REG))
11493 (clobber (reg:TI XMM12_REG))
11494 (clobber (reg:TI XMM13_REG))
11495 (clobber (reg:TI XMM14_REG))
11496 (clobber (reg:TI XMM15_REG))
11497 (clobber (reg:DI SI_REG))
11498 (clobber (reg:DI DI_REG))
11499 (unspec [(match_operand 3 "const_int_operand" "")]
11500 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11501 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11503 "&& reload_completed"
11505 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11506 [(set_attr "type" "callv")])
11508 (define_insn "*call_value_rex64_ms_sysv"
11509 [(set (match_operand 0 "" "")
11510 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11511 (match_operand 2 "" "")))
11512 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11513 (clobber (reg:TI XMM6_REG))
11514 (clobber (reg:TI XMM7_REG))
11515 (clobber (reg:TI XMM8_REG))
11516 (clobber (reg:TI XMM9_REG))
11517 (clobber (reg:TI XMM10_REG))
11518 (clobber (reg:TI XMM11_REG))
11519 (clobber (reg:TI XMM12_REG))
11520 (clobber (reg:TI XMM13_REG))
11521 (clobber (reg:TI XMM14_REG))
11522 (clobber (reg:TI XMM15_REG))
11523 (clobber (reg:DI SI_REG))
11524 (clobber (reg:DI DI_REG))]
11525 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11526 "* return ix86_output_call_insn (insn, operands[1]);"
11527 [(set_attr "type" "callv")])
11529 (define_expand "call_value_pop"
11530 [(parallel [(set (match_operand 0 "" "")
11531 (call (match_operand:QI 1 "" "")
11532 (match_operand:SI 2 "" "")))
11533 (set (reg:SI SP_REG)
11534 (plus:SI (reg:SI SP_REG)
11535 (match_operand:SI 4 "" "")))])]
11538 ix86_expand_call (operands[0], operands[1], operands[2],
11539 operands[3], operands[4], false);
11543 (define_insn_and_split "*call_value_pop_vzeroupper"
11544 [(set (match_operand 0 "" "")
11545 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11546 (match_operand 2 "" "")))
11547 (set (reg:SI SP_REG)
11548 (plus:SI (reg:SI SP_REG)
11549 (match_operand:SI 3 "immediate_operand" "i")))
11550 (unspec [(match_operand 4 "const_int_operand" "")]
11551 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11552 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11554 "&& reload_completed"
11556 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11557 [(set_attr "type" "callv")])
11559 (define_insn "*call_value_pop"
11560 [(set (match_operand 0 "" "")
11561 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11562 (match_operand 2 "" "")))
11563 (set (reg:SI SP_REG)
11564 (plus:SI (reg:SI SP_REG)
11565 (match_operand:SI 3 "immediate_operand" "i")))]
11566 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11567 "* return ix86_output_call_insn (insn, operands[1]);"
11568 [(set_attr "type" "callv")])
11570 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11571 [(set (match_operand 0 "" "")
11572 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11573 (match_operand 2 "" "")))
11574 (set (reg:SI SP_REG)
11575 (plus:SI (reg:SI SP_REG)
11576 (match_operand:SI 3 "immediate_operand" "i")))
11577 (unspec [(match_operand 4 "const_int_operand" "")]
11578 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11579 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11581 "&& reload_completed"
11583 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11584 [(set_attr "type" "callv")])
11586 (define_insn "*sibcall_value_pop"
11587 [(set (match_operand 0 "" "")
11588 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11589 (match_operand 2 "" "")))
11590 (set (reg:SI SP_REG)
11591 (plus:SI (reg:SI SP_REG)
11592 (match_operand:SI 3 "immediate_operand" "i")))]
11593 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11594 "* return ix86_output_call_insn (insn, operands[1]);"
11595 [(set_attr "type" "callv")])
11597 ;; Call subroutine returning any type.
11599 (define_expand "untyped_call"
11600 [(parallel [(call (match_operand 0 "" "")
11602 (match_operand 1 "" "")
11603 (match_operand 2 "" "")])]
11608 /* In order to give reg-stack an easier job in validating two
11609 coprocessor registers as containing a possible return value,
11610 simply pretend the untyped call returns a complex long double
11613 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11614 and should have the default ABI. */
11616 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11617 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11618 operands[0], const0_rtx,
11619 GEN_INT ((TARGET_64BIT
11620 ? (ix86_abi == SYSV_ABI
11621 ? X86_64_SSE_REGPARM_MAX
11622 : X86_64_MS_SSE_REGPARM_MAX)
11623 : X86_32_SSE_REGPARM_MAX)
11627 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11629 rtx set = XVECEXP (operands[2], 0, i);
11630 emit_move_insn (SET_DEST (set), SET_SRC (set));
11633 /* The optimizer does not know that the call sets the function value
11634 registers we stored in the result block. We avoid problems by
11635 claiming that all hard registers are used and clobbered at this
11637 emit_insn (gen_blockage ());
11642 ;; Prologue and epilogue instructions
11644 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11645 ;; all of memory. This blocks insns from being moved across this point.
11647 (define_insn "blockage"
11648 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11651 [(set_attr "length" "0")])
11653 ;; Do not schedule instructions accessing memory across this point.
11655 (define_expand "memory_blockage"
11656 [(set (match_dup 0)
11657 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11660 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11661 MEM_VOLATILE_P (operands[0]) = 1;
11664 (define_insn "*memory_blockage"
11665 [(set (match_operand:BLK 0 "" "")
11666 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11669 [(set_attr "length" "0")])
11671 ;; As USE insns aren't meaningful after reload, this is used instead
11672 ;; to prevent deleting instructions setting registers for PIC code
11673 (define_insn "prologue_use"
11674 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11677 [(set_attr "length" "0")])
11679 ;; Insn emitted into the body of a function to return from a function.
11680 ;; This is only done if the function's epilogue is known to be simple.
11681 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11683 (define_expand "return"
11685 "ix86_can_use_return_insn_p ()"
11687 ix86_maybe_emit_epilogue_vzeroupper ();
11688 if (crtl->args.pops_args)
11690 rtx popc = GEN_INT (crtl->args.pops_args);
11691 emit_jump_insn (gen_simple_return_pop_internal (popc));
11696 ;; We need to disable this for TARGET_SEH, as otherwise
11697 ;; shrink-wrapped prologue gets enabled too. This might exceed
11698 ;; the maximum size of prologue in unwind information.
11700 (define_expand "simple_return"
11704 ix86_maybe_emit_epilogue_vzeroupper ();
11705 if (crtl->args.pops_args)
11707 rtx popc = GEN_INT (crtl->args.pops_args);
11708 emit_jump_insn (gen_simple_return_pop_internal (popc));
11713 (define_insn "simple_return_internal"
11717 [(set_attr "length" "1")
11718 (set_attr "atom_unit" "jeu")
11719 (set_attr "length_immediate" "0")
11720 (set_attr "modrm" "0")])
11722 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11723 ;; instruction Athlon and K8 have.
11725 (define_insn "simple_return_internal_long"
11727 (unspec [(const_int 0)] UNSPEC_REP)]
11730 [(set_attr "length" "2")
11731 (set_attr "atom_unit" "jeu")
11732 (set_attr "length_immediate" "0")
11733 (set_attr "prefix_rep" "1")
11734 (set_attr "modrm" "0")])
11736 (define_insn "simple_return_pop_internal"
11738 (use (match_operand:SI 0 "const_int_operand" ""))]
11741 [(set_attr "length" "3")
11742 (set_attr "atom_unit" "jeu")
11743 (set_attr "length_immediate" "2")
11744 (set_attr "modrm" "0")])
11746 (define_insn "simple_return_indirect_internal"
11748 (use (match_operand:SI 0 "register_operand" "r"))]
11751 [(set_attr "type" "ibr")
11752 (set_attr "length_immediate" "0")])
11758 [(set_attr "length" "1")
11759 (set_attr "length_immediate" "0")
11760 (set_attr "modrm" "0")])
11762 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11763 (define_insn "nops"
11764 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11768 int num = INTVAL (operands[0]);
11770 gcc_assert (num >= 1 && num <= 8);
11773 fputs ("\tnop\n", asm_out_file);
11777 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11778 (set_attr "length_immediate" "0")
11779 (set_attr "modrm" "0")])
11781 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11782 ;; branch prediction penalty for the third jump in a 16-byte
11786 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11789 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11790 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11792 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11793 The align insn is used to avoid 3 jump instructions in the row to improve
11794 branch prediction and the benefits hardly outweigh the cost of extra 8
11795 nops on the average inserted by full alignment pseudo operation. */
11799 [(set_attr "length" "16")])
11801 (define_expand "prologue"
11804 "ix86_expand_prologue (); DONE;")
11806 (define_insn "set_got"
11807 [(set (match_operand:SI 0 "register_operand" "=r")
11808 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11809 (clobber (reg:CC FLAGS_REG))]
11811 "* return output_set_got (operands[0], NULL_RTX);"
11812 [(set_attr "type" "multi")
11813 (set_attr "length" "12")])
11815 (define_insn "set_got_labelled"
11816 [(set (match_operand:SI 0 "register_operand" "=r")
11817 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11819 (clobber (reg:CC FLAGS_REG))]
11821 "* return output_set_got (operands[0], operands[1]);"
11822 [(set_attr "type" "multi")
11823 (set_attr "length" "12")])
11825 (define_insn "set_got_rex64"
11826 [(set (match_operand:DI 0 "register_operand" "=r")
11827 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11829 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11830 [(set_attr "type" "lea")
11831 (set_attr "length_address" "4")
11832 (set_attr "mode" "DI")])
11834 (define_insn "set_rip_rex64"
11835 [(set (match_operand:DI 0 "register_operand" "=r")
11836 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11838 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11839 [(set_attr "type" "lea")
11840 (set_attr "length_address" "4")
11841 (set_attr "mode" "DI")])
11843 (define_insn "set_got_offset_rex64"
11844 [(set (match_operand:DI 0 "register_operand" "=r")
11846 [(label_ref (match_operand 1 "" ""))]
11847 UNSPEC_SET_GOT_OFFSET))]
11849 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11850 [(set_attr "type" "imov")
11851 (set_attr "length_immediate" "0")
11852 (set_attr "length_address" "8")
11853 (set_attr "mode" "DI")])
11855 (define_expand "epilogue"
11858 "ix86_expand_epilogue (1); DONE;")
11860 (define_expand "sibcall_epilogue"
11863 "ix86_expand_epilogue (0); DONE;")
11865 (define_expand "eh_return"
11866 [(use (match_operand 0 "register_operand" ""))]
11869 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11871 /* Tricky bit: we write the address of the handler to which we will
11872 be returning into someone else's stack frame, one word below the
11873 stack address we wish to restore. */
11874 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11875 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11876 tmp = gen_rtx_MEM (Pmode, tmp);
11877 emit_move_insn (tmp, ra);
11879 emit_jump_insn (gen_eh_return_internal ());
11884 (define_insn_and_split "eh_return_internal"
11888 "epilogue_completed"
11890 "ix86_expand_epilogue (2); DONE;")
11892 (define_insn "leave"
11893 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11894 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11895 (clobber (mem:BLK (scratch)))]
11898 [(set_attr "type" "leave")])
11900 (define_insn "leave_rex64"
11901 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11902 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11903 (clobber (mem:BLK (scratch)))]
11906 [(set_attr "type" "leave")])
11908 ;; Handle -fsplit-stack.
11910 (define_expand "split_stack_prologue"
11914 ix86_expand_split_stack_prologue ();
11918 ;; In order to support the call/return predictor, we use a return
11919 ;; instruction which the middle-end doesn't see.
11920 (define_insn "split_stack_return"
11921 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11922 UNSPECV_SPLIT_STACK_RETURN)]
11925 if (operands[0] == const0_rtx)
11930 [(set_attr "atom_unit" "jeu")
11931 (set_attr "modrm" "0")
11932 (set (attr "length")
11933 (if_then_else (match_operand:SI 0 "const0_operand" "")
11936 (set (attr "length_immediate")
11937 (if_then_else (match_operand:SI 0 "const0_operand" "")
11941 ;; If there are operand 0 bytes available on the stack, jump to
11944 (define_expand "split_stack_space_check"
11945 [(set (pc) (if_then_else
11946 (ltu (minus (reg SP_REG)
11947 (match_operand 0 "register_operand" ""))
11948 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11949 (label_ref (match_operand 1 "" ""))
11953 rtx reg, size, limit;
11955 reg = gen_reg_rtx (Pmode);
11956 size = force_reg (Pmode, operands[0]);
11957 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11958 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11959 UNSPEC_STACK_CHECK);
11960 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11961 ix86_expand_branch (GEU, reg, limit, operands[1]);
11966 ;; Bit manipulation instructions.
11968 (define_expand "ffs<mode>2"
11969 [(set (match_dup 2) (const_int -1))
11970 (parallel [(set (reg:CCZ FLAGS_REG)
11972 (match_operand:SWI48 1 "nonimmediate_operand" "")
11974 (set (match_operand:SWI48 0 "register_operand" "")
11975 (ctz:SWI48 (match_dup 1)))])
11976 (set (match_dup 0) (if_then_else:SWI48
11977 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11980 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11981 (clobber (reg:CC FLAGS_REG))])]
11984 if (<MODE>mode == SImode && !TARGET_CMOVE)
11986 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11989 operands[2] = gen_reg_rtx (<MODE>mode);
11992 (define_insn_and_split "ffssi2_no_cmove"
11993 [(set (match_operand:SI 0 "register_operand" "=r")
11994 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11995 (clobber (match_scratch:SI 2 "=&q"))
11996 (clobber (reg:CC FLAGS_REG))]
11999 "&& reload_completed"
12000 [(parallel [(set (reg:CCZ FLAGS_REG)
12001 (compare:CCZ (match_dup 1) (const_int 0)))
12002 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12003 (set (strict_low_part (match_dup 3))
12004 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12005 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12006 (clobber (reg:CC FLAGS_REG))])
12007 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12008 (clobber (reg:CC FLAGS_REG))])
12009 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12010 (clobber (reg:CC FLAGS_REG))])]
12012 operands[3] = gen_lowpart (QImode, operands[2]);
12013 ix86_expand_clear (operands[2]);
12016 (define_insn "*ffs<mode>_1"
12017 [(set (reg:CCZ FLAGS_REG)
12018 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12020 (set (match_operand:SWI48 0 "register_operand" "=r")
12021 (ctz:SWI48 (match_dup 1)))]
12023 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12024 [(set_attr "type" "alu1")
12025 (set_attr "prefix_0f" "1")
12026 (set_attr "mode" "<MODE>")])
12028 (define_insn "ctz<mode>2"
12029 [(set (match_operand:SWI248 0 "register_operand" "=r")
12030 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12031 (clobber (reg:CC FLAGS_REG))]
12035 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12037 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12039 [(set_attr "type" "alu1")
12040 (set_attr "prefix_0f" "1")
12041 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12042 (set_attr "mode" "<MODE>")])
12044 (define_expand "clz<mode>2"
12046 [(set (match_operand:SWI248 0 "register_operand" "")
12049 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12050 (clobber (reg:CC FLAGS_REG))])
12052 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12053 (clobber (reg:CC FLAGS_REG))])]
12058 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12061 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12064 (define_insn "clz<mode>2_lzcnt"
12065 [(set (match_operand:SWI248 0 "register_operand" "=r")
12066 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12067 (clobber (reg:CC FLAGS_REG))]
12069 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12070 [(set_attr "prefix_rep" "1")
12071 (set_attr "type" "bitmanip")
12072 (set_attr "mode" "<MODE>")])
12074 ;; BMI instructions.
12075 (define_insn "*bmi_andn_<mode>"
12076 [(set (match_operand:SWI48 0 "register_operand" "=r")
12079 (match_operand:SWI48 1 "register_operand" "r"))
12080 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12081 (clobber (reg:CC FLAGS_REG))]
12083 "andn\t{%2, %1, %0|%0, %1, %2}"
12084 [(set_attr "type" "bitmanip")
12085 (set_attr "mode" "<MODE>")])
12087 (define_insn "bmi_bextr_<mode>"
12088 [(set (match_operand:SWI48 0 "register_operand" "=r")
12089 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12090 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12092 (clobber (reg:CC FLAGS_REG))]
12094 "bextr\t{%2, %1, %0|%0, %1, %2}"
12095 [(set_attr "type" "bitmanip")
12096 (set_attr "mode" "<MODE>")])
12098 (define_insn "*bmi_blsi_<mode>"
12099 [(set (match_operand:SWI48 0 "register_operand" "=r")
12102 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12104 (clobber (reg:CC FLAGS_REG))]
12106 "blsi\t{%1, %0|%0, %1}"
12107 [(set_attr "type" "bitmanip")
12108 (set_attr "mode" "<MODE>")])
12110 (define_insn "*bmi_blsmsk_<mode>"
12111 [(set (match_operand:SWI48 0 "register_operand" "=r")
12114 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12117 (clobber (reg:CC FLAGS_REG))]
12119 "blsmsk\t{%1, %0|%0, %1}"
12120 [(set_attr "type" "bitmanip")
12121 (set_attr "mode" "<MODE>")])
12123 (define_insn "*bmi_blsr_<mode>"
12124 [(set (match_operand:SWI48 0 "register_operand" "=r")
12127 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12130 (clobber (reg:CC FLAGS_REG))]
12132 "blsr\t{%1, %0|%0, %1}"
12133 [(set_attr "type" "bitmanip")
12134 (set_attr "mode" "<MODE>")])
12136 ;; BMI2 instructions.
12137 (define_insn "bmi2_bzhi_<mode>3"
12138 [(set (match_operand:SWI48 0 "register_operand" "=r")
12139 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12140 (lshiftrt:SWI48 (const_int -1)
12141 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12142 (clobber (reg:CC FLAGS_REG))]
12144 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12145 [(set_attr "type" "bitmanip")
12146 (set_attr "prefix" "vex")
12147 (set_attr "mode" "<MODE>")])
12149 (define_insn "bmi2_pdep_<mode>3"
12150 [(set (match_operand:SWI48 0 "register_operand" "=r")
12151 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12152 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12155 "pdep\t{%2, %1, %0|%0, %1, %2}"
12156 [(set_attr "type" "bitmanip")
12157 (set_attr "prefix" "vex")
12158 (set_attr "mode" "<MODE>")])
12160 (define_insn "bmi2_pext_<mode>3"
12161 [(set (match_operand:SWI48 0 "register_operand" "=r")
12162 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12163 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12166 "pext\t{%2, %1, %0|%0, %1, %2}"
12167 [(set_attr "type" "bitmanip")
12168 (set_attr "prefix" "vex")
12169 (set_attr "mode" "<MODE>")])
12171 ;; TBM instructions.
12172 (define_insn "tbm_bextri_<mode>"
12173 [(set (match_operand:SWI48 0 "register_operand" "=r")
12174 (zero_extract:SWI48
12175 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12176 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12177 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12178 (clobber (reg:CC FLAGS_REG))]
12181 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12182 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12184 [(set_attr "type" "bitmanip")
12185 (set_attr "mode" "<MODE>")])
12187 (define_insn "*tbm_blcfill_<mode>"
12188 [(set (match_operand:SWI48 0 "register_operand" "=r")
12191 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12194 (clobber (reg:CC FLAGS_REG))]
12196 "blcfill\t{%1, %0|%0, %1}"
12197 [(set_attr "type" "bitmanip")
12198 (set_attr "mode" "<MODE>")])
12200 (define_insn "*tbm_blci_<mode>"
12201 [(set (match_operand:SWI48 0 "register_operand" "=r")
12205 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12208 (clobber (reg:CC FLAGS_REG))]
12210 "blci\t{%1, %0|%0, %1}"
12211 [(set_attr "type" "bitmanip")
12212 (set_attr "mode" "<MODE>")])
12214 (define_insn "*tbm_blcic_<mode>"
12215 [(set (match_operand:SWI48 0 "register_operand" "=r")
12218 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12222 (clobber (reg:CC FLAGS_REG))]
12224 "blcic\t{%1, %0|%0, %1}"
12225 [(set_attr "type" "bitmanip")
12226 (set_attr "mode" "<MODE>")])
12228 (define_insn "*tbm_blcmsk_<mode>"
12229 [(set (match_operand:SWI48 0 "register_operand" "=r")
12232 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235 (clobber (reg:CC FLAGS_REG))]
12237 "blcmsk\t{%1, %0|%0, %1}"
12238 [(set_attr "type" "bitmanip")
12239 (set_attr "mode" "<MODE>")])
12241 (define_insn "*tbm_blcs_<mode>"
12242 [(set (match_operand:SWI48 0 "register_operand" "=r")
12245 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12248 (clobber (reg:CC FLAGS_REG))]
12250 "blcs\t{%1, %0|%0, %1}"
12251 [(set_attr "type" "bitmanip")
12252 (set_attr "mode" "<MODE>")])
12254 (define_insn "*tbm_blsfill_<mode>"
12255 [(set (match_operand:SWI48 0 "register_operand" "=r")
12258 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12261 (clobber (reg:CC FLAGS_REG))]
12263 "blsfill\t{%1, %0|%0, %1}"
12264 [(set_attr "type" "bitmanip")
12265 (set_attr "mode" "<MODE>")])
12267 (define_insn "*tbm_blsic_<mode>"
12268 [(set (match_operand:SWI48 0 "register_operand" "=r")
12271 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12275 (clobber (reg:CC FLAGS_REG))]
12277 "blsic\t{%1, %0|%0, %1}"
12278 [(set_attr "type" "bitmanip")
12279 (set_attr "mode" "<MODE>")])
12281 (define_insn "*tbm_t1mskc_<mode>"
12282 [(set (match_operand:SWI48 0 "register_operand" "=r")
12285 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12289 (clobber (reg:CC FLAGS_REG))]
12291 "t1mskc\t{%1, %0|%0, %1}"
12292 [(set_attr "type" "bitmanip")
12293 (set_attr "mode" "<MODE>")])
12295 (define_insn "*tbm_tzmsk_<mode>"
12296 [(set (match_operand:SWI48 0 "register_operand" "=r")
12299 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12303 (clobber (reg:CC FLAGS_REG))]
12305 "tzmsk\t{%1, %0|%0, %1}"
12306 [(set_attr "type" "bitmanip")
12307 (set_attr "mode" "<MODE>")])
12309 (define_insn "bsr_rex64"
12310 [(set (match_operand:DI 0 "register_operand" "=r")
12311 (minus:DI (const_int 63)
12312 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12313 (clobber (reg:CC FLAGS_REG))]
12315 "bsr{q}\t{%1, %0|%0, %1}"
12316 [(set_attr "type" "alu1")
12317 (set_attr "prefix_0f" "1")
12318 (set_attr "mode" "DI")])
12321 [(set (match_operand:SI 0 "register_operand" "=r")
12322 (minus:SI (const_int 31)
12323 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12324 (clobber (reg:CC FLAGS_REG))]
12326 "bsr{l}\t{%1, %0|%0, %1}"
12327 [(set_attr "type" "alu1")
12328 (set_attr "prefix_0f" "1")
12329 (set_attr "mode" "SI")])
12331 (define_insn "*bsrhi"
12332 [(set (match_operand:HI 0 "register_operand" "=r")
12333 (minus:HI (const_int 15)
12334 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12335 (clobber (reg:CC FLAGS_REG))]
12337 "bsr{w}\t{%1, %0|%0, %1}"
12338 [(set_attr "type" "alu1")
12339 (set_attr "prefix_0f" "1")
12340 (set_attr "mode" "HI")])
12342 (define_insn "popcount<mode>2"
12343 [(set (match_operand:SWI248 0 "register_operand" "=r")
12345 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12346 (clobber (reg:CC FLAGS_REG))]
12350 return "popcnt\t{%1, %0|%0, %1}";
12352 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12355 [(set_attr "prefix_rep" "1")
12356 (set_attr "type" "bitmanip")
12357 (set_attr "mode" "<MODE>")])
12359 (define_insn "*popcount<mode>2_cmp"
12360 [(set (reg FLAGS_REG)
12363 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12365 (set (match_operand:SWI248 0 "register_operand" "=r")
12366 (popcount:SWI248 (match_dup 1)))]
12367 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12370 return "popcnt\t{%1, %0|%0, %1}";
12372 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12375 [(set_attr "prefix_rep" "1")
12376 (set_attr "type" "bitmanip")
12377 (set_attr "mode" "<MODE>")])
12379 (define_insn "*popcountsi2_cmp_zext"
12380 [(set (reg FLAGS_REG)
12382 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12384 (set (match_operand:DI 0 "register_operand" "=r")
12385 (zero_extend:DI(popcount:SI (match_dup 1))))]
12386 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12389 return "popcnt\t{%1, %0|%0, %1}";
12391 return "popcnt{l}\t{%1, %0|%0, %1}";
12394 [(set_attr "prefix_rep" "1")
12395 (set_attr "type" "bitmanip")
12396 (set_attr "mode" "SI")])
12398 (define_expand "bswap<mode>2"
12399 [(set (match_operand:SWI48 0 "register_operand" "")
12400 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12403 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12405 rtx x = operands[0];
12407 emit_move_insn (x, operands[1]);
12408 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12409 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12410 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12415 (define_insn "*bswap<mode>2_movbe"
12416 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12417 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12419 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12422 movbe\t{%1, %0|%0, %1}
12423 movbe\t{%1, %0|%0, %1}"
12424 [(set_attr "type" "bitmanip,imov,imov")
12425 (set_attr "modrm" "0,1,1")
12426 (set_attr "prefix_0f" "*,1,1")
12427 (set_attr "prefix_extra" "*,1,1")
12428 (set_attr "mode" "<MODE>")])
12430 (define_insn "*bswap<mode>2_1"
12431 [(set (match_operand:SWI48 0 "register_operand" "=r")
12432 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12435 [(set_attr "type" "bitmanip")
12436 (set_attr "modrm" "0")
12437 (set_attr "mode" "<MODE>")])
12439 (define_insn "*bswaphi_lowpart_1"
12440 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12441 (bswap:HI (match_dup 0)))
12442 (clobber (reg:CC FLAGS_REG))]
12443 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12445 xchg{b}\t{%h0, %b0|%b0, %h0}
12446 rol{w}\t{$8, %0|%0, 8}"
12447 [(set_attr "length" "2,4")
12448 (set_attr "mode" "QI,HI")])
12450 (define_insn "bswaphi_lowpart"
12451 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12452 (bswap:HI (match_dup 0)))
12453 (clobber (reg:CC FLAGS_REG))]
12455 "rol{w}\t{$8, %0|%0, 8}"
12456 [(set_attr "length" "4")
12457 (set_attr "mode" "HI")])
12459 (define_expand "paritydi2"
12460 [(set (match_operand:DI 0 "register_operand" "")
12461 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12464 rtx scratch = gen_reg_rtx (QImode);
12467 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12468 NULL_RTX, operands[1]));
12470 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12471 gen_rtx_REG (CCmode, FLAGS_REG),
12473 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12476 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12479 rtx tmp = gen_reg_rtx (SImode);
12481 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12482 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12487 (define_expand "paritysi2"
12488 [(set (match_operand:SI 0 "register_operand" "")
12489 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12492 rtx scratch = gen_reg_rtx (QImode);
12495 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12497 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12498 gen_rtx_REG (CCmode, FLAGS_REG),
12500 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12502 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12506 (define_insn_and_split "paritydi2_cmp"
12507 [(set (reg:CC FLAGS_REG)
12508 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12510 (clobber (match_scratch:DI 0 "=r"))
12511 (clobber (match_scratch:SI 1 "=&r"))
12512 (clobber (match_scratch:HI 2 "=Q"))]
12515 "&& reload_completed"
12517 [(set (match_dup 1)
12518 (xor:SI (match_dup 1) (match_dup 4)))
12519 (clobber (reg:CC FLAGS_REG))])
12521 [(set (reg:CC FLAGS_REG)
12522 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12523 (clobber (match_dup 1))
12524 (clobber (match_dup 2))])]
12526 operands[4] = gen_lowpart (SImode, operands[3]);
12530 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12531 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12534 operands[1] = gen_highpart (SImode, operands[3]);
12537 (define_insn_and_split "paritysi2_cmp"
12538 [(set (reg:CC FLAGS_REG)
12539 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12541 (clobber (match_scratch:SI 0 "=r"))
12542 (clobber (match_scratch:HI 1 "=&Q"))]
12545 "&& reload_completed"
12547 [(set (match_dup 1)
12548 (xor:HI (match_dup 1) (match_dup 3)))
12549 (clobber (reg:CC FLAGS_REG))])
12551 [(set (reg:CC FLAGS_REG)
12552 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12553 (clobber (match_dup 1))])]
12555 operands[3] = gen_lowpart (HImode, operands[2]);
12557 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12558 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12561 (define_insn "*parityhi2_cmp"
12562 [(set (reg:CC FLAGS_REG)
12563 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12565 (clobber (match_scratch:HI 0 "=Q"))]
12567 "xor{b}\t{%h0, %b0|%b0, %h0}"
12568 [(set_attr "length" "2")
12569 (set_attr "mode" "HI")])
12572 ;; Thread-local storage patterns for ELF.
12574 ;; Note that these code sequences must appear exactly as shown
12575 ;; in order to allow linker relaxation.
12577 (define_insn "*tls_global_dynamic_32_gnu"
12578 [(set (match_operand:SI 0 "register_operand" "=a")
12580 [(match_operand:SI 1 "register_operand" "b")
12581 (match_operand:SI 2 "tls_symbolic_operand" "")
12582 (match_operand:SI 3 "constant_call_address_operand" "z")]
12584 (clobber (match_scratch:SI 4 "=d"))
12585 (clobber (match_scratch:SI 5 "=c"))
12586 (clobber (reg:CC FLAGS_REG))]
12587 "!TARGET_64BIT && TARGET_GNU_TLS"
12590 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12591 if (TARGET_SUN_TLS)
12592 #ifdef HAVE_AS_IX86_TLSGDPLT
12593 return "call\t%a2@tlsgdplt";
12595 return "call\t%p3@plt";
12597 return "call\t%P3";
12599 [(set_attr "type" "multi")
12600 (set_attr "length" "12")])
12602 (define_expand "tls_global_dynamic_32"
12604 [(set (match_operand:SI 0 "register_operand" "")
12605 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12606 (match_operand:SI 1 "tls_symbolic_operand" "")
12607 (match_operand:SI 3 "constant_call_address_operand" "")]
12609 (clobber (match_scratch:SI 4 ""))
12610 (clobber (match_scratch:SI 5 ""))
12611 (clobber (reg:CC FLAGS_REG))])])
12613 (define_insn "*tls_global_dynamic_64"
12614 [(set (match_operand:DI 0 "register_operand" "=a")
12616 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12617 (match_operand:DI 3 "" "")))
12618 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12623 fputs (ASM_BYTE "0x66\n", asm_out_file);
12625 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12626 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12627 fputs ("\trex64\n", asm_out_file);
12628 if (TARGET_SUN_TLS)
12629 return "call\t%p2@plt";
12630 return "call\t%P2";
12632 [(set_attr "type" "multi")
12633 (set (attr "length")
12634 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12636 (define_expand "tls_global_dynamic_64"
12638 [(set (match_operand:DI 0 "register_operand" "")
12640 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12642 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12645 (define_insn "*tls_local_dynamic_base_32_gnu"
12646 [(set (match_operand:SI 0 "register_operand" "=a")
12648 [(match_operand:SI 1 "register_operand" "b")
12649 (match_operand:SI 2 "constant_call_address_operand" "z")]
12650 UNSPEC_TLS_LD_BASE))
12651 (clobber (match_scratch:SI 3 "=d"))
12652 (clobber (match_scratch:SI 4 "=c"))
12653 (clobber (reg:CC FLAGS_REG))]
12654 "!TARGET_64BIT && TARGET_GNU_TLS"
12657 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12658 if (TARGET_SUN_TLS)
12659 #ifdef HAVE_AS_IX86_TLSLDMPLT
12660 return "call\t%&@tlsldmplt";
12662 return "call\t%p2@plt";
12664 return "call\t%P2";
12666 [(set_attr "type" "multi")
12667 (set_attr "length" "11")])
12669 (define_expand "tls_local_dynamic_base_32"
12671 [(set (match_operand:SI 0 "register_operand" "")
12673 [(match_operand:SI 1 "register_operand" "")
12674 (match_operand:SI 2 "constant_call_address_operand" "")]
12675 UNSPEC_TLS_LD_BASE))
12676 (clobber (match_scratch:SI 3 ""))
12677 (clobber (match_scratch:SI 4 ""))
12678 (clobber (reg:CC FLAGS_REG))])])
12680 (define_insn "*tls_local_dynamic_base_64"
12681 [(set (match_operand:DI 0 "register_operand" "=a")
12683 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12684 (match_operand:DI 2 "" "")))
12685 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12689 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12690 if (TARGET_SUN_TLS)
12691 return "call\t%p1@plt";
12692 return "call\t%P1";
12694 [(set_attr "type" "multi")
12695 (set_attr "length" "12")])
12697 (define_expand "tls_local_dynamic_base_64"
12699 [(set (match_operand:DI 0 "register_operand" "")
12701 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12703 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12705 ;; Local dynamic of a single variable is a lose. Show combine how
12706 ;; to convert that back to global dynamic.
12708 (define_insn_and_split "*tls_local_dynamic_32_once"
12709 [(set (match_operand:SI 0 "register_operand" "=a")
12711 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12712 (match_operand:SI 2 "constant_call_address_operand" "z")]
12713 UNSPEC_TLS_LD_BASE)
12714 (const:SI (unspec:SI
12715 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12717 (clobber (match_scratch:SI 4 "=d"))
12718 (clobber (match_scratch:SI 5 "=c"))
12719 (clobber (reg:CC FLAGS_REG))]
12724 [(set (match_dup 0)
12725 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12727 (clobber (match_dup 4))
12728 (clobber (match_dup 5))
12729 (clobber (reg:CC FLAGS_REG))])])
12731 ;; Segment register for the thread base ptr load
12732 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12734 ;; Load and add the thread base pointer from %<tp_seg>:0.
12735 (define_insn "*load_tp_x32"
12736 [(set (match_operand:SI 0 "register_operand" "=r")
12737 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12739 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12740 [(set_attr "type" "imov")
12741 (set_attr "modrm" "0")
12742 (set_attr "length" "7")
12743 (set_attr "memory" "load")
12744 (set_attr "imm_disp" "false")])
12746 (define_insn "*load_tp_x32_zext"
12747 [(set (match_operand:DI 0 "register_operand" "=r")
12748 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12750 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12751 [(set_attr "type" "imov")
12752 (set_attr "modrm" "0")
12753 (set_attr "length" "7")
12754 (set_attr "memory" "load")
12755 (set_attr "imm_disp" "false")])
12757 (define_insn "*load_tp_<mode>"
12758 [(set (match_operand:P 0 "register_operand" "=r")
12759 (unspec:P [(const_int 0)] UNSPEC_TP))]
12761 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12762 [(set_attr "type" "imov")
12763 (set_attr "modrm" "0")
12764 (set_attr "length" "7")
12765 (set_attr "memory" "load")
12766 (set_attr "imm_disp" "false")])
12768 (define_insn "*add_tp_x32"
12769 [(set (match_operand:SI 0 "register_operand" "=r")
12770 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12771 (match_operand:SI 1 "register_operand" "0")))
12772 (clobber (reg:CC FLAGS_REG))]
12774 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12775 [(set_attr "type" "alu")
12776 (set_attr "modrm" "0")
12777 (set_attr "length" "7")
12778 (set_attr "memory" "load")
12779 (set_attr "imm_disp" "false")])
12781 (define_insn "*add_tp_x32_zext"
12782 [(set (match_operand:DI 0 "register_operand" "=r")
12784 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12785 (match_operand:SI 1 "register_operand" "0"))))
12786 (clobber (reg:CC FLAGS_REG))]
12788 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12789 [(set_attr "type" "alu")
12790 (set_attr "modrm" "0")
12791 (set_attr "length" "7")
12792 (set_attr "memory" "load")
12793 (set_attr "imm_disp" "false")])
12795 (define_insn "*add_tp_<mode>"
12796 [(set (match_operand:P 0 "register_operand" "=r")
12797 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12798 (match_operand:P 1 "register_operand" "0")))
12799 (clobber (reg:CC FLAGS_REG))]
12801 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12802 [(set_attr "type" "alu")
12803 (set_attr "modrm" "0")
12804 (set_attr "length" "7")
12805 (set_attr "memory" "load")
12806 (set_attr "imm_disp" "false")])
12808 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12809 ;; %rax as destination of the initial executable code sequence.
12810 (define_insn "tls_initial_exec_64_sun"
12811 [(set (match_operand:DI 0 "register_operand" "=a")
12813 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12814 UNSPEC_TLS_IE_SUN))
12815 (clobber (reg:CC FLAGS_REG))]
12816 "TARGET_64BIT && TARGET_SUN_TLS"
12819 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12820 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12822 [(set_attr "type" "multi")])
12824 ;; GNU2 TLS patterns can be split.
12826 (define_expand "tls_dynamic_gnu2_32"
12827 [(set (match_dup 3)
12828 (plus:SI (match_operand:SI 2 "register_operand" "")
12830 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12833 [(set (match_operand:SI 0 "register_operand" "")
12834 (unspec:SI [(match_dup 1) (match_dup 3)
12835 (match_dup 2) (reg:SI SP_REG)]
12837 (clobber (reg:CC FLAGS_REG))])]
12838 "!TARGET_64BIT && TARGET_GNU2_TLS"
12840 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12841 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12844 (define_insn "*tls_dynamic_gnu2_lea_32"
12845 [(set (match_operand:SI 0 "register_operand" "=r")
12846 (plus:SI (match_operand:SI 1 "register_operand" "b")
12848 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12849 UNSPEC_TLSDESC))))]
12850 "!TARGET_64BIT && TARGET_GNU2_TLS"
12851 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12852 [(set_attr "type" "lea")
12853 (set_attr "mode" "SI")
12854 (set_attr "length" "6")
12855 (set_attr "length_address" "4")])
12857 (define_insn "*tls_dynamic_gnu2_call_32"
12858 [(set (match_operand:SI 0 "register_operand" "=a")
12859 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12860 (match_operand:SI 2 "register_operand" "0")
12861 ;; we have to make sure %ebx still points to the GOT
12862 (match_operand:SI 3 "register_operand" "b")
12865 (clobber (reg:CC FLAGS_REG))]
12866 "!TARGET_64BIT && TARGET_GNU2_TLS"
12867 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12868 [(set_attr "type" "call")
12869 (set_attr "length" "2")
12870 (set_attr "length_address" "0")])
12872 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12873 [(set (match_operand:SI 0 "register_operand" "=&a")
12875 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12876 (match_operand:SI 4 "" "")
12877 (match_operand:SI 2 "register_operand" "b")
12880 (const:SI (unspec:SI
12881 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12883 (clobber (reg:CC FLAGS_REG))]
12884 "!TARGET_64BIT && TARGET_GNU2_TLS"
12887 [(set (match_dup 0) (match_dup 5))]
12889 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12890 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12893 (define_expand "tls_dynamic_gnu2_64"
12894 [(set (match_dup 2)
12895 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12898 [(set (match_operand:DI 0 "register_operand" "")
12899 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12901 (clobber (reg:CC FLAGS_REG))])]
12902 "TARGET_64BIT && TARGET_GNU2_TLS"
12904 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12905 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12908 (define_insn "*tls_dynamic_gnu2_lea_64"
12909 [(set (match_operand:DI 0 "register_operand" "=r")
12910 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12912 "TARGET_64BIT && TARGET_GNU2_TLS"
12913 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12914 [(set_attr "type" "lea")
12915 (set_attr "mode" "DI")
12916 (set_attr "length" "7")
12917 (set_attr "length_address" "4")])
12919 (define_insn "*tls_dynamic_gnu2_call_64"
12920 [(set (match_operand:DI 0 "register_operand" "=a")
12921 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12922 (match_operand:DI 2 "register_operand" "0")
12925 (clobber (reg:CC FLAGS_REG))]
12926 "TARGET_64BIT && TARGET_GNU2_TLS"
12927 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12928 [(set_attr "type" "call")
12929 (set_attr "length" "2")
12930 (set_attr "length_address" "0")])
12932 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12933 [(set (match_operand:DI 0 "register_operand" "=&a")
12935 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12936 (match_operand:DI 3 "" "")
12939 (const:DI (unspec:DI
12940 [(match_operand 1 "tls_symbolic_operand" "")]
12942 (clobber (reg:CC FLAGS_REG))]
12943 "TARGET_64BIT && TARGET_GNU2_TLS"
12946 [(set (match_dup 0) (match_dup 4))]
12948 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12949 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12952 ;; These patterns match the binary 387 instructions for addM3, subM3,
12953 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12954 ;; SFmode. The first is the normal insn, the second the same insn but
12955 ;; with one operand a conversion, and the third the same insn but with
12956 ;; the other operand a conversion. The conversion may be SFmode or
12957 ;; SImode if the target mode DFmode, but only SImode if the target mode
12960 ;; Gcc is slightly more smart about handling normal two address instructions
12961 ;; so use special patterns for add and mull.
12963 (define_insn "*fop_<mode>_comm_mixed"
12964 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12965 (match_operator:MODEF 3 "binary_fp_operator"
12966 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12967 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12968 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12969 && COMMUTATIVE_ARITH_P (operands[3])
12970 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12971 "* return output_387_binary_op (insn, operands);"
12972 [(set (attr "type")
12973 (if_then_else (eq_attr "alternative" "1,2")
12974 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12975 (const_string "ssemul")
12976 (const_string "sseadd"))
12977 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12978 (const_string "fmul")
12979 (const_string "fop"))))
12980 (set_attr "isa" "*,noavx,avx")
12981 (set_attr "prefix" "orig,orig,vex")
12982 (set_attr "mode" "<MODE>")])
12984 (define_insn "*fop_<mode>_comm_sse"
12985 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12986 (match_operator:MODEF 3 "binary_fp_operator"
12987 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12988 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12989 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12990 && COMMUTATIVE_ARITH_P (operands[3])
12991 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12992 "* return output_387_binary_op (insn, operands);"
12993 [(set (attr "type")
12994 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12995 (const_string "ssemul")
12996 (const_string "sseadd")))
12997 (set_attr "isa" "noavx,avx")
12998 (set_attr "prefix" "orig,vex")
12999 (set_attr "mode" "<MODE>")])
13001 (define_insn "*fop_<mode>_comm_i387"
13002 [(set (match_operand:MODEF 0 "register_operand" "=f")
13003 (match_operator:MODEF 3 "binary_fp_operator"
13004 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13005 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13006 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13007 && COMMUTATIVE_ARITH_P (operands[3])
13008 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13009 "* return output_387_binary_op (insn, operands);"
13010 [(set (attr "type")
13011 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13012 (const_string "fmul")
13013 (const_string "fop")))
13014 (set_attr "mode" "<MODE>")])
13016 (define_insn "*fop_<mode>_1_mixed"
13017 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13018 (match_operator:MODEF 3 "binary_fp_operator"
13019 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13020 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13021 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13022 && !COMMUTATIVE_ARITH_P (operands[3])
13023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13024 "* return output_387_binary_op (insn, operands);"
13025 [(set (attr "type")
13026 (cond [(and (eq_attr "alternative" "2,3")
13027 (match_operand:MODEF 3 "mult_operator" ""))
13028 (const_string "ssemul")
13029 (and (eq_attr "alternative" "2,3")
13030 (match_operand:MODEF 3 "div_operator" ""))
13031 (const_string "ssediv")
13032 (eq_attr "alternative" "2,3")
13033 (const_string "sseadd")
13034 (match_operand:MODEF 3 "mult_operator" "")
13035 (const_string "fmul")
13036 (match_operand:MODEF 3 "div_operator" "")
13037 (const_string "fdiv")
13039 (const_string "fop")))
13040 (set_attr "isa" "*,*,noavx,avx")
13041 (set_attr "prefix" "orig,orig,orig,vex")
13042 (set_attr "mode" "<MODE>")])
13044 (define_insn "*rcpsf2_sse"
13045 [(set (match_operand:SF 0 "register_operand" "=x")
13046 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13049 "%vrcpss\t{%1, %d0|%d0, %1}"
13050 [(set_attr "type" "sse")
13051 (set_attr "atom_sse_attr" "rcp")
13052 (set_attr "prefix" "maybe_vex")
13053 (set_attr "mode" "SF")])
13055 (define_insn "*fop_<mode>_1_sse"
13056 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13057 (match_operator:MODEF 3 "binary_fp_operator"
13058 [(match_operand:MODEF 1 "register_operand" "0,x")
13059 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13060 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13061 && !COMMUTATIVE_ARITH_P (operands[3])"
13062 "* return output_387_binary_op (insn, operands);"
13063 [(set (attr "type")
13064 (cond [(match_operand:MODEF 3 "mult_operator" "")
13065 (const_string "ssemul")
13066 (match_operand:MODEF 3 "div_operator" "")
13067 (const_string "ssediv")
13069 (const_string "sseadd")))
13070 (set_attr "isa" "noavx,avx")
13071 (set_attr "prefix" "orig,vex")
13072 (set_attr "mode" "<MODE>")])
13074 ;; This pattern is not fully shadowed by the pattern above.
13075 (define_insn "*fop_<mode>_1_i387"
13076 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13077 (match_operator:MODEF 3 "binary_fp_operator"
13078 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13079 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13080 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13081 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13082 && !COMMUTATIVE_ARITH_P (operands[3])
13083 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13084 "* return output_387_binary_op (insn, operands);"
13085 [(set (attr "type")
13086 (cond [(match_operand:MODEF 3 "mult_operator" "")
13087 (const_string "fmul")
13088 (match_operand:MODEF 3 "div_operator" "")
13089 (const_string "fdiv")
13091 (const_string "fop")))
13092 (set_attr "mode" "<MODE>")])
13094 ;; ??? Add SSE splitters for these!
13095 (define_insn "*fop_<MODEF:mode>_2_i387"
13096 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13097 (match_operator:MODEF 3 "binary_fp_operator"
13099 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13100 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13101 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13102 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13103 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13104 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13105 [(set (attr "type")
13106 (cond [(match_operand:MODEF 3 "mult_operator" "")
13107 (const_string "fmul")
13108 (match_operand:MODEF 3 "div_operator" "")
13109 (const_string "fdiv")
13111 (const_string "fop")))
13112 (set_attr "fp_int_src" "true")
13113 (set_attr "mode" "<SWI24:MODE>")])
13115 (define_insn "*fop_<MODEF:mode>_3_i387"
13116 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13117 (match_operator:MODEF 3 "binary_fp_operator"
13118 [(match_operand:MODEF 1 "register_operand" "0,0")
13120 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13121 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13122 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13123 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13124 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13125 [(set (attr "type")
13126 (cond [(match_operand:MODEF 3 "mult_operator" "")
13127 (const_string "fmul")
13128 (match_operand:MODEF 3 "div_operator" "")
13129 (const_string "fdiv")
13131 (const_string "fop")))
13132 (set_attr "fp_int_src" "true")
13133 (set_attr "mode" "<MODE>")])
13135 (define_insn "*fop_df_4_i387"
13136 [(set (match_operand:DF 0 "register_operand" "=f,f")
13137 (match_operator:DF 3 "binary_fp_operator"
13139 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13140 (match_operand:DF 2 "register_operand" "0,f")]))]
13141 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13142 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13143 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13144 "* return output_387_binary_op (insn, operands);"
13145 [(set (attr "type")
13146 (cond [(match_operand:DF 3 "mult_operator" "")
13147 (const_string "fmul")
13148 (match_operand:DF 3 "div_operator" "")
13149 (const_string "fdiv")
13151 (const_string "fop")))
13152 (set_attr "mode" "SF")])
13154 (define_insn "*fop_df_5_i387"
13155 [(set (match_operand:DF 0 "register_operand" "=f,f")
13156 (match_operator:DF 3 "binary_fp_operator"
13157 [(match_operand:DF 1 "register_operand" "0,f")
13159 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13160 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13161 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13162 "* return output_387_binary_op (insn, operands);"
13163 [(set (attr "type")
13164 (cond [(match_operand:DF 3 "mult_operator" "")
13165 (const_string "fmul")
13166 (match_operand:DF 3 "div_operator" "")
13167 (const_string "fdiv")
13169 (const_string "fop")))
13170 (set_attr "mode" "SF")])
13172 (define_insn "*fop_df_6_i387"
13173 [(set (match_operand:DF 0 "register_operand" "=f,f")
13174 (match_operator:DF 3 "binary_fp_operator"
13176 (match_operand:SF 1 "register_operand" "0,f"))
13178 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13179 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13180 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13181 "* return output_387_binary_op (insn, operands);"
13182 [(set (attr "type")
13183 (cond [(match_operand:DF 3 "mult_operator" "")
13184 (const_string "fmul")
13185 (match_operand:DF 3 "div_operator" "")
13186 (const_string "fdiv")
13188 (const_string "fop")))
13189 (set_attr "mode" "SF")])
13191 (define_insn "*fop_xf_comm_i387"
13192 [(set (match_operand:XF 0 "register_operand" "=f")
13193 (match_operator:XF 3 "binary_fp_operator"
13194 [(match_operand:XF 1 "register_operand" "%0")
13195 (match_operand:XF 2 "register_operand" "f")]))]
13197 && COMMUTATIVE_ARITH_P (operands[3])"
13198 "* return output_387_binary_op (insn, operands);"
13199 [(set (attr "type")
13200 (if_then_else (match_operand:XF 3 "mult_operator" "")
13201 (const_string "fmul")
13202 (const_string "fop")))
13203 (set_attr "mode" "XF")])
13205 (define_insn "*fop_xf_1_i387"
13206 [(set (match_operand:XF 0 "register_operand" "=f,f")
13207 (match_operator:XF 3 "binary_fp_operator"
13208 [(match_operand:XF 1 "register_operand" "0,f")
13209 (match_operand:XF 2 "register_operand" "f,0")]))]
13211 && !COMMUTATIVE_ARITH_P (operands[3])"
13212 "* return output_387_binary_op (insn, operands);"
13213 [(set (attr "type")
13214 (cond [(match_operand:XF 3 "mult_operator" "")
13215 (const_string "fmul")
13216 (match_operand:XF 3 "div_operator" "")
13217 (const_string "fdiv")
13219 (const_string "fop")))
13220 (set_attr "mode" "XF")])
13222 (define_insn "*fop_xf_2_i387"
13223 [(set (match_operand:XF 0 "register_operand" "=f,f")
13224 (match_operator:XF 3 "binary_fp_operator"
13226 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13227 (match_operand:XF 2 "register_operand" "0,0")]))]
13228 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13229 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13230 [(set (attr "type")
13231 (cond [(match_operand:XF 3 "mult_operator" "")
13232 (const_string "fmul")
13233 (match_operand:XF 3 "div_operator" "")
13234 (const_string "fdiv")
13236 (const_string "fop")))
13237 (set_attr "fp_int_src" "true")
13238 (set_attr "mode" "<MODE>")])
13240 (define_insn "*fop_xf_3_i387"
13241 [(set (match_operand:XF 0 "register_operand" "=f,f")
13242 (match_operator:XF 3 "binary_fp_operator"
13243 [(match_operand:XF 1 "register_operand" "0,0")
13245 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13246 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13247 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13248 [(set (attr "type")
13249 (cond [(match_operand:XF 3 "mult_operator" "")
13250 (const_string "fmul")
13251 (match_operand:XF 3 "div_operator" "")
13252 (const_string "fdiv")
13254 (const_string "fop")))
13255 (set_attr "fp_int_src" "true")
13256 (set_attr "mode" "<MODE>")])
13258 (define_insn "*fop_xf_4_i387"
13259 [(set (match_operand:XF 0 "register_operand" "=f,f")
13260 (match_operator:XF 3 "binary_fp_operator"
13262 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13263 (match_operand:XF 2 "register_operand" "0,f")]))]
13265 "* return output_387_binary_op (insn, operands);"
13266 [(set (attr "type")
13267 (cond [(match_operand:XF 3 "mult_operator" "")
13268 (const_string "fmul")
13269 (match_operand:XF 3 "div_operator" "")
13270 (const_string "fdiv")
13272 (const_string "fop")))
13273 (set_attr "mode" "<MODE>")])
13275 (define_insn "*fop_xf_5_i387"
13276 [(set (match_operand:XF 0 "register_operand" "=f,f")
13277 (match_operator:XF 3 "binary_fp_operator"
13278 [(match_operand:XF 1 "register_operand" "0,f")
13280 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13282 "* return output_387_binary_op (insn, operands);"
13283 [(set (attr "type")
13284 (cond [(match_operand:XF 3 "mult_operator" "")
13285 (const_string "fmul")
13286 (match_operand:XF 3 "div_operator" "")
13287 (const_string "fdiv")
13289 (const_string "fop")))
13290 (set_attr "mode" "<MODE>")])
13292 (define_insn "*fop_xf_6_i387"
13293 [(set (match_operand:XF 0 "register_operand" "=f,f")
13294 (match_operator:XF 3 "binary_fp_operator"
13296 (match_operand:MODEF 1 "register_operand" "0,f"))
13298 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13300 "* return output_387_binary_op (insn, operands);"
13301 [(set (attr "type")
13302 (cond [(match_operand:XF 3 "mult_operator" "")
13303 (const_string "fmul")
13304 (match_operand:XF 3 "div_operator" "")
13305 (const_string "fdiv")
13307 (const_string "fop")))
13308 (set_attr "mode" "<MODE>")])
13311 [(set (match_operand 0 "register_operand" "")
13312 (match_operator 3 "binary_fp_operator"
13313 [(float (match_operand:SWI24 1 "register_operand" ""))
13314 (match_operand 2 "register_operand" "")]))]
13316 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13317 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13320 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13321 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13322 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13323 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13324 GET_MODE (operands[3]),
13327 ix86_free_from_memory (GET_MODE (operands[1]));
13332 [(set (match_operand 0 "register_operand" "")
13333 (match_operator 3 "binary_fp_operator"
13334 [(match_operand 1 "register_operand" "")
13335 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13337 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13338 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13341 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13342 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13343 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13344 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13345 GET_MODE (operands[3]),
13348 ix86_free_from_memory (GET_MODE (operands[2]));
13352 ;; FPU special functions.
13354 ;; This pattern implements a no-op XFmode truncation for
13355 ;; all fancy i386 XFmode math functions.
13357 (define_insn "truncxf<mode>2_i387_noop_unspec"
13358 [(set (match_operand:MODEF 0 "register_operand" "=f")
13359 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13360 UNSPEC_TRUNC_NOOP))]
13361 "TARGET_USE_FANCY_MATH_387"
13362 "* return output_387_reg_move (insn, operands);"
13363 [(set_attr "type" "fmov")
13364 (set_attr "mode" "<MODE>")])
13366 (define_insn "sqrtxf2"
13367 [(set (match_operand:XF 0 "register_operand" "=f")
13368 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13369 "TARGET_USE_FANCY_MATH_387"
13371 [(set_attr "type" "fpspc")
13372 (set_attr "mode" "XF")
13373 (set_attr "athlon_decode" "direct")
13374 (set_attr "amdfam10_decode" "direct")
13375 (set_attr "bdver1_decode" "direct")])
13377 (define_insn "sqrt_extend<mode>xf2_i387"
13378 [(set (match_operand:XF 0 "register_operand" "=f")
13381 (match_operand:MODEF 1 "register_operand" "0"))))]
13382 "TARGET_USE_FANCY_MATH_387"
13384 [(set_attr "type" "fpspc")
13385 (set_attr "mode" "XF")
13386 (set_attr "athlon_decode" "direct")
13387 (set_attr "amdfam10_decode" "direct")
13388 (set_attr "bdver1_decode" "direct")])
13390 (define_insn "*rsqrtsf2_sse"
13391 [(set (match_operand:SF 0 "register_operand" "=x")
13392 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13395 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13396 [(set_attr "type" "sse")
13397 (set_attr "atom_sse_attr" "rcp")
13398 (set_attr "prefix" "maybe_vex")
13399 (set_attr "mode" "SF")])
13401 (define_expand "rsqrtsf2"
13402 [(set (match_operand:SF 0 "register_operand" "")
13403 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13407 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13411 (define_insn "*sqrt<mode>2_sse"
13412 [(set (match_operand:MODEF 0 "register_operand" "=x")
13414 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13415 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13416 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13417 [(set_attr "type" "sse")
13418 (set_attr "atom_sse_attr" "sqrt")
13419 (set_attr "prefix" "maybe_vex")
13420 (set_attr "mode" "<MODE>")
13421 (set_attr "athlon_decode" "*")
13422 (set_attr "amdfam10_decode" "*")
13423 (set_attr "bdver1_decode" "*")])
13425 (define_expand "sqrt<mode>2"
13426 [(set (match_operand:MODEF 0 "register_operand" "")
13428 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13429 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13430 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13432 if (<MODE>mode == SFmode
13434 && TARGET_RECIP_SQRT
13435 && !optimize_function_for_size_p (cfun)
13436 && flag_finite_math_only && !flag_trapping_math
13437 && flag_unsafe_math_optimizations)
13439 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13443 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13445 rtx op0 = gen_reg_rtx (XFmode);
13446 rtx op1 = force_reg (<MODE>mode, operands[1]);
13448 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13449 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13454 (define_insn "fpremxf4_i387"
13455 [(set (match_operand:XF 0 "register_operand" "=f")
13456 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13457 (match_operand:XF 3 "register_operand" "1")]
13459 (set (match_operand:XF 1 "register_operand" "=u")
13460 (unspec:XF [(match_dup 2) (match_dup 3)]
13462 (set (reg:CCFP FPSR_REG)
13463 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13465 "TARGET_USE_FANCY_MATH_387"
13467 [(set_attr "type" "fpspc")
13468 (set_attr "mode" "XF")])
13470 (define_expand "fmodxf3"
13471 [(use (match_operand:XF 0 "register_operand" ""))
13472 (use (match_operand:XF 1 "general_operand" ""))
13473 (use (match_operand:XF 2 "general_operand" ""))]
13474 "TARGET_USE_FANCY_MATH_387"
13476 rtx label = gen_label_rtx ();
13478 rtx op1 = gen_reg_rtx (XFmode);
13479 rtx op2 = gen_reg_rtx (XFmode);
13481 emit_move_insn (op2, operands[2]);
13482 emit_move_insn (op1, operands[1]);
13484 emit_label (label);
13485 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13486 ix86_emit_fp_unordered_jump (label);
13487 LABEL_NUSES (label) = 1;
13489 emit_move_insn (operands[0], op1);
13493 (define_expand "fmod<mode>3"
13494 [(use (match_operand:MODEF 0 "register_operand" ""))
13495 (use (match_operand:MODEF 1 "general_operand" ""))
13496 (use (match_operand:MODEF 2 "general_operand" ""))]
13497 "TARGET_USE_FANCY_MATH_387"
13499 rtx (*gen_truncxf) (rtx, rtx);
13501 rtx label = gen_label_rtx ();
13503 rtx op1 = gen_reg_rtx (XFmode);
13504 rtx op2 = gen_reg_rtx (XFmode);
13506 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13507 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13509 emit_label (label);
13510 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13511 ix86_emit_fp_unordered_jump (label);
13512 LABEL_NUSES (label) = 1;
13514 /* Truncate the result properly for strict SSE math. */
13515 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13516 && !TARGET_MIX_SSE_I387)
13517 gen_truncxf = gen_truncxf<mode>2;
13519 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13521 emit_insn (gen_truncxf (operands[0], op1));
13525 (define_insn "fprem1xf4_i387"
13526 [(set (match_operand:XF 0 "register_operand" "=f")
13527 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13528 (match_operand:XF 3 "register_operand" "1")]
13530 (set (match_operand:XF 1 "register_operand" "=u")
13531 (unspec:XF [(match_dup 2) (match_dup 3)]
13533 (set (reg:CCFP FPSR_REG)
13534 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13536 "TARGET_USE_FANCY_MATH_387"
13538 [(set_attr "type" "fpspc")
13539 (set_attr "mode" "XF")])
13541 (define_expand "remainderxf3"
13542 [(use (match_operand:XF 0 "register_operand" ""))
13543 (use (match_operand:XF 1 "general_operand" ""))
13544 (use (match_operand:XF 2 "general_operand" ""))]
13545 "TARGET_USE_FANCY_MATH_387"
13547 rtx label = gen_label_rtx ();
13549 rtx op1 = gen_reg_rtx (XFmode);
13550 rtx op2 = gen_reg_rtx (XFmode);
13552 emit_move_insn (op2, operands[2]);
13553 emit_move_insn (op1, operands[1]);
13555 emit_label (label);
13556 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13557 ix86_emit_fp_unordered_jump (label);
13558 LABEL_NUSES (label) = 1;
13560 emit_move_insn (operands[0], op1);
13564 (define_expand "remainder<mode>3"
13565 [(use (match_operand:MODEF 0 "register_operand" ""))
13566 (use (match_operand:MODEF 1 "general_operand" ""))
13567 (use (match_operand:MODEF 2 "general_operand" ""))]
13568 "TARGET_USE_FANCY_MATH_387"
13570 rtx (*gen_truncxf) (rtx, rtx);
13572 rtx label = gen_label_rtx ();
13574 rtx op1 = gen_reg_rtx (XFmode);
13575 rtx op2 = gen_reg_rtx (XFmode);
13577 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13578 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13580 emit_label (label);
13582 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13583 ix86_emit_fp_unordered_jump (label);
13584 LABEL_NUSES (label) = 1;
13586 /* Truncate the result properly for strict SSE math. */
13587 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13588 && !TARGET_MIX_SSE_I387)
13589 gen_truncxf = gen_truncxf<mode>2;
13591 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13593 emit_insn (gen_truncxf (operands[0], op1));
13597 (define_insn "*sinxf2_i387"
13598 [(set (match_operand:XF 0 "register_operand" "=f")
13599 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13600 "TARGET_USE_FANCY_MATH_387
13601 && flag_unsafe_math_optimizations"
13603 [(set_attr "type" "fpspc")
13604 (set_attr "mode" "XF")])
13606 (define_insn "*sin_extend<mode>xf2_i387"
13607 [(set (match_operand:XF 0 "register_operand" "=f")
13608 (unspec:XF [(float_extend:XF
13609 (match_operand:MODEF 1 "register_operand" "0"))]
13611 "TARGET_USE_FANCY_MATH_387
13612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13613 || TARGET_MIX_SSE_I387)
13614 && flag_unsafe_math_optimizations"
13616 [(set_attr "type" "fpspc")
13617 (set_attr "mode" "XF")])
13619 (define_insn "*cosxf2_i387"
13620 [(set (match_operand:XF 0 "register_operand" "=f")
13621 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13622 "TARGET_USE_FANCY_MATH_387
13623 && flag_unsafe_math_optimizations"
13625 [(set_attr "type" "fpspc")
13626 (set_attr "mode" "XF")])
13628 (define_insn "*cos_extend<mode>xf2_i387"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(float_extend:XF
13631 (match_operand:MODEF 1 "register_operand" "0"))]
13633 "TARGET_USE_FANCY_MATH_387
13634 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13635 || TARGET_MIX_SSE_I387)
13636 && flag_unsafe_math_optimizations"
13638 [(set_attr "type" "fpspc")
13639 (set_attr "mode" "XF")])
13641 ;; When sincos pattern is defined, sin and cos builtin functions will be
13642 ;; expanded to sincos pattern with one of its outputs left unused.
13643 ;; CSE pass will figure out if two sincos patterns can be combined,
13644 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13645 ;; depending on the unused output.
13647 (define_insn "sincosxf3"
13648 [(set (match_operand:XF 0 "register_operand" "=f")
13649 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13650 UNSPEC_SINCOS_COS))
13651 (set (match_operand:XF 1 "register_operand" "=u")
13652 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13653 "TARGET_USE_FANCY_MATH_387
13654 && flag_unsafe_math_optimizations"
13656 [(set_attr "type" "fpspc")
13657 (set_attr "mode" "XF")])
13660 [(set (match_operand:XF 0 "register_operand" "")
13661 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13662 UNSPEC_SINCOS_COS))
13663 (set (match_operand:XF 1 "register_operand" "")
13664 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13665 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13666 && can_create_pseudo_p ()"
13667 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13670 [(set (match_operand:XF 0 "register_operand" "")
13671 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13672 UNSPEC_SINCOS_COS))
13673 (set (match_operand:XF 1 "register_operand" "")
13674 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13675 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13676 && can_create_pseudo_p ()"
13677 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13679 (define_insn "sincos_extend<mode>xf3_i387"
13680 [(set (match_operand:XF 0 "register_operand" "=f")
13681 (unspec:XF [(float_extend:XF
13682 (match_operand:MODEF 2 "register_operand" "0"))]
13683 UNSPEC_SINCOS_COS))
13684 (set (match_operand:XF 1 "register_operand" "=u")
13685 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13686 "TARGET_USE_FANCY_MATH_387
13687 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13688 || TARGET_MIX_SSE_I387)
13689 && flag_unsafe_math_optimizations"
13691 [(set_attr "type" "fpspc")
13692 (set_attr "mode" "XF")])
13695 [(set (match_operand:XF 0 "register_operand" "")
13696 (unspec:XF [(float_extend:XF
13697 (match_operand:MODEF 2 "register_operand" ""))]
13698 UNSPEC_SINCOS_COS))
13699 (set (match_operand:XF 1 "register_operand" "")
13700 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13701 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13702 && can_create_pseudo_p ()"
13703 [(set (match_dup 1)
13704 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13707 [(set (match_operand:XF 0 "register_operand" "")
13708 (unspec:XF [(float_extend:XF
13709 (match_operand:MODEF 2 "register_operand" ""))]
13710 UNSPEC_SINCOS_COS))
13711 (set (match_operand:XF 1 "register_operand" "")
13712 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13713 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13714 && can_create_pseudo_p ()"
13715 [(set (match_dup 0)
13716 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13718 (define_expand "sincos<mode>3"
13719 [(use (match_operand:MODEF 0 "register_operand" ""))
13720 (use (match_operand:MODEF 1 "register_operand" ""))
13721 (use (match_operand:MODEF 2 "register_operand" ""))]
13722 "TARGET_USE_FANCY_MATH_387
13723 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13724 || TARGET_MIX_SSE_I387)
13725 && flag_unsafe_math_optimizations"
13727 rtx op0 = gen_reg_rtx (XFmode);
13728 rtx op1 = gen_reg_rtx (XFmode);
13730 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13731 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13732 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13736 (define_insn "fptanxf4_i387"
13737 [(set (match_operand:XF 0 "register_operand" "=f")
13738 (match_operand:XF 3 "const_double_operand" "F"))
13739 (set (match_operand:XF 1 "register_operand" "=u")
13740 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13742 "TARGET_USE_FANCY_MATH_387
13743 && flag_unsafe_math_optimizations
13744 && standard_80387_constant_p (operands[3]) == 2"
13746 [(set_attr "type" "fpspc")
13747 (set_attr "mode" "XF")])
13749 (define_insn "fptan_extend<mode>xf4_i387"
13750 [(set (match_operand:MODEF 0 "register_operand" "=f")
13751 (match_operand:MODEF 3 "const_double_operand" "F"))
13752 (set (match_operand:XF 1 "register_operand" "=u")
13753 (unspec:XF [(float_extend:XF
13754 (match_operand:MODEF 2 "register_operand" "0"))]
13756 "TARGET_USE_FANCY_MATH_387
13757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13758 || TARGET_MIX_SSE_I387)
13759 && flag_unsafe_math_optimizations
13760 && standard_80387_constant_p (operands[3]) == 2"
13762 [(set_attr "type" "fpspc")
13763 (set_attr "mode" "XF")])
13765 (define_expand "tanxf2"
13766 [(use (match_operand:XF 0 "register_operand" ""))
13767 (use (match_operand:XF 1 "register_operand" ""))]
13768 "TARGET_USE_FANCY_MATH_387
13769 && flag_unsafe_math_optimizations"
13771 rtx one = gen_reg_rtx (XFmode);
13772 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13774 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13778 (define_expand "tan<mode>2"
13779 [(use (match_operand:MODEF 0 "register_operand" ""))
13780 (use (match_operand:MODEF 1 "register_operand" ""))]
13781 "TARGET_USE_FANCY_MATH_387
13782 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13783 || TARGET_MIX_SSE_I387)
13784 && flag_unsafe_math_optimizations"
13786 rtx op0 = gen_reg_rtx (XFmode);
13788 rtx one = gen_reg_rtx (<MODE>mode);
13789 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13791 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13792 operands[1], op2));
13793 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13797 (define_insn "*fpatanxf3_i387"
13798 [(set (match_operand:XF 0 "register_operand" "=f")
13799 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13800 (match_operand:XF 2 "register_operand" "u")]
13802 (clobber (match_scratch:XF 3 "=2"))]
13803 "TARGET_USE_FANCY_MATH_387
13804 && flag_unsafe_math_optimizations"
13806 [(set_attr "type" "fpspc")
13807 (set_attr "mode" "XF")])
13809 (define_insn "fpatan_extend<mode>xf3_i387"
13810 [(set (match_operand:XF 0 "register_operand" "=f")
13811 (unspec:XF [(float_extend:XF
13812 (match_operand:MODEF 1 "register_operand" "0"))
13814 (match_operand:MODEF 2 "register_operand" "u"))]
13816 (clobber (match_scratch:XF 3 "=2"))]
13817 "TARGET_USE_FANCY_MATH_387
13818 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13819 || TARGET_MIX_SSE_I387)
13820 && flag_unsafe_math_optimizations"
13822 [(set_attr "type" "fpspc")
13823 (set_attr "mode" "XF")])
13825 (define_expand "atan2xf3"
13826 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13827 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13828 (match_operand:XF 1 "register_operand" "")]
13830 (clobber (match_scratch:XF 3 ""))])]
13831 "TARGET_USE_FANCY_MATH_387
13832 && flag_unsafe_math_optimizations")
13834 (define_expand "atan2<mode>3"
13835 [(use (match_operand:MODEF 0 "register_operand" ""))
13836 (use (match_operand:MODEF 1 "register_operand" ""))
13837 (use (match_operand:MODEF 2 "register_operand" ""))]
13838 "TARGET_USE_FANCY_MATH_387
13839 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13840 || TARGET_MIX_SSE_I387)
13841 && flag_unsafe_math_optimizations"
13843 rtx op0 = gen_reg_rtx (XFmode);
13845 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13846 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13850 (define_expand "atanxf2"
13851 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13852 (unspec:XF [(match_dup 2)
13853 (match_operand:XF 1 "register_operand" "")]
13855 (clobber (match_scratch:XF 3 ""))])]
13856 "TARGET_USE_FANCY_MATH_387
13857 && flag_unsafe_math_optimizations"
13859 operands[2] = gen_reg_rtx (XFmode);
13860 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13863 (define_expand "atan<mode>2"
13864 [(use (match_operand:MODEF 0 "register_operand" ""))
13865 (use (match_operand:MODEF 1 "register_operand" ""))]
13866 "TARGET_USE_FANCY_MATH_387
13867 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13868 || TARGET_MIX_SSE_I387)
13869 && flag_unsafe_math_optimizations"
13871 rtx op0 = gen_reg_rtx (XFmode);
13873 rtx op2 = gen_reg_rtx (<MODE>mode);
13874 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13876 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13877 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13881 (define_expand "asinxf2"
13882 [(set (match_dup 2)
13883 (mult:XF (match_operand:XF 1 "register_operand" "")
13885 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13886 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13887 (parallel [(set (match_operand:XF 0 "register_operand" "")
13888 (unspec:XF [(match_dup 5) (match_dup 1)]
13890 (clobber (match_scratch:XF 6 ""))])]
13891 "TARGET_USE_FANCY_MATH_387
13892 && flag_unsafe_math_optimizations"
13896 if (optimize_insn_for_size_p ())
13899 for (i = 2; i < 6; i++)
13900 operands[i] = gen_reg_rtx (XFmode);
13902 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13905 (define_expand "asin<mode>2"
13906 [(use (match_operand:MODEF 0 "register_operand" ""))
13907 (use (match_operand:MODEF 1 "general_operand" ""))]
13908 "TARGET_USE_FANCY_MATH_387
13909 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13910 || TARGET_MIX_SSE_I387)
13911 && flag_unsafe_math_optimizations"
13913 rtx op0 = gen_reg_rtx (XFmode);
13914 rtx op1 = gen_reg_rtx (XFmode);
13916 if (optimize_insn_for_size_p ())
13919 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13920 emit_insn (gen_asinxf2 (op0, op1));
13921 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13925 (define_expand "acosxf2"
13926 [(set (match_dup 2)
13927 (mult:XF (match_operand:XF 1 "register_operand" "")
13929 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13930 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13931 (parallel [(set (match_operand:XF 0 "register_operand" "")
13932 (unspec:XF [(match_dup 1) (match_dup 5)]
13934 (clobber (match_scratch:XF 6 ""))])]
13935 "TARGET_USE_FANCY_MATH_387
13936 && flag_unsafe_math_optimizations"
13940 if (optimize_insn_for_size_p ())
13943 for (i = 2; i < 6; i++)
13944 operands[i] = gen_reg_rtx (XFmode);
13946 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13949 (define_expand "acos<mode>2"
13950 [(use (match_operand:MODEF 0 "register_operand" ""))
13951 (use (match_operand:MODEF 1 "general_operand" ""))]
13952 "TARGET_USE_FANCY_MATH_387
13953 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13954 || TARGET_MIX_SSE_I387)
13955 && flag_unsafe_math_optimizations"
13957 rtx op0 = gen_reg_rtx (XFmode);
13958 rtx op1 = gen_reg_rtx (XFmode);
13960 if (optimize_insn_for_size_p ())
13963 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13964 emit_insn (gen_acosxf2 (op0, op1));
13965 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13969 (define_insn "fyl2xxf3_i387"
13970 [(set (match_operand:XF 0 "register_operand" "=f")
13971 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13972 (match_operand:XF 2 "register_operand" "u")]
13974 (clobber (match_scratch:XF 3 "=2"))]
13975 "TARGET_USE_FANCY_MATH_387
13976 && flag_unsafe_math_optimizations"
13978 [(set_attr "type" "fpspc")
13979 (set_attr "mode" "XF")])
13981 (define_insn "fyl2x_extend<mode>xf3_i387"
13982 [(set (match_operand:XF 0 "register_operand" "=f")
13983 (unspec:XF [(float_extend:XF
13984 (match_operand:MODEF 1 "register_operand" "0"))
13985 (match_operand:XF 2 "register_operand" "u")]
13987 (clobber (match_scratch:XF 3 "=2"))]
13988 "TARGET_USE_FANCY_MATH_387
13989 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13990 || TARGET_MIX_SSE_I387)
13991 && flag_unsafe_math_optimizations"
13993 [(set_attr "type" "fpspc")
13994 (set_attr "mode" "XF")])
13996 (define_expand "logxf2"
13997 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13998 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13999 (match_dup 2)] UNSPEC_FYL2X))
14000 (clobber (match_scratch:XF 3 ""))])]
14001 "TARGET_USE_FANCY_MATH_387
14002 && flag_unsafe_math_optimizations"
14004 operands[2] = gen_reg_rtx (XFmode);
14005 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14008 (define_expand "log<mode>2"
14009 [(use (match_operand:MODEF 0 "register_operand" ""))
14010 (use (match_operand:MODEF 1 "register_operand" ""))]
14011 "TARGET_USE_FANCY_MATH_387
14012 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14013 || TARGET_MIX_SSE_I387)
14014 && flag_unsafe_math_optimizations"
14016 rtx op0 = gen_reg_rtx (XFmode);
14018 rtx op2 = gen_reg_rtx (XFmode);
14019 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14021 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14022 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14026 (define_expand "log10xf2"
14027 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14028 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14029 (match_dup 2)] UNSPEC_FYL2X))
14030 (clobber (match_scratch:XF 3 ""))])]
14031 "TARGET_USE_FANCY_MATH_387
14032 && flag_unsafe_math_optimizations"
14034 operands[2] = gen_reg_rtx (XFmode);
14035 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14038 (define_expand "log10<mode>2"
14039 [(use (match_operand:MODEF 0 "register_operand" ""))
14040 (use (match_operand:MODEF 1 "register_operand" ""))]
14041 "TARGET_USE_FANCY_MATH_387
14042 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14043 || TARGET_MIX_SSE_I387)
14044 && flag_unsafe_math_optimizations"
14046 rtx op0 = gen_reg_rtx (XFmode);
14048 rtx op2 = gen_reg_rtx (XFmode);
14049 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14051 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14052 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14056 (define_expand "log2xf2"
14057 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14058 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14059 (match_dup 2)] UNSPEC_FYL2X))
14060 (clobber (match_scratch:XF 3 ""))])]
14061 "TARGET_USE_FANCY_MATH_387
14062 && flag_unsafe_math_optimizations"
14064 operands[2] = gen_reg_rtx (XFmode);
14065 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14068 (define_expand "log2<mode>2"
14069 [(use (match_operand:MODEF 0 "register_operand" ""))
14070 (use (match_operand:MODEF 1 "register_operand" ""))]
14071 "TARGET_USE_FANCY_MATH_387
14072 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14073 || TARGET_MIX_SSE_I387)
14074 && flag_unsafe_math_optimizations"
14076 rtx op0 = gen_reg_rtx (XFmode);
14078 rtx op2 = gen_reg_rtx (XFmode);
14079 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14081 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14082 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14086 (define_insn "fyl2xp1xf3_i387"
14087 [(set (match_operand:XF 0 "register_operand" "=f")
14088 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14089 (match_operand:XF 2 "register_operand" "u")]
14091 (clobber (match_scratch:XF 3 "=2"))]
14092 "TARGET_USE_FANCY_MATH_387
14093 && flag_unsafe_math_optimizations"
14095 [(set_attr "type" "fpspc")
14096 (set_attr "mode" "XF")])
14098 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14099 [(set (match_operand:XF 0 "register_operand" "=f")
14100 (unspec:XF [(float_extend:XF
14101 (match_operand:MODEF 1 "register_operand" "0"))
14102 (match_operand:XF 2 "register_operand" "u")]
14104 (clobber (match_scratch:XF 3 "=2"))]
14105 "TARGET_USE_FANCY_MATH_387
14106 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14107 || TARGET_MIX_SSE_I387)
14108 && flag_unsafe_math_optimizations"
14110 [(set_attr "type" "fpspc")
14111 (set_attr "mode" "XF")])
14113 (define_expand "log1pxf2"
14114 [(use (match_operand:XF 0 "register_operand" ""))
14115 (use (match_operand:XF 1 "register_operand" ""))]
14116 "TARGET_USE_FANCY_MATH_387
14117 && flag_unsafe_math_optimizations"
14119 if (optimize_insn_for_size_p ())
14122 ix86_emit_i387_log1p (operands[0], operands[1]);
14126 (define_expand "log1p<mode>2"
14127 [(use (match_operand:MODEF 0 "register_operand" ""))
14128 (use (match_operand:MODEF 1 "register_operand" ""))]
14129 "TARGET_USE_FANCY_MATH_387
14130 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14131 || TARGET_MIX_SSE_I387)
14132 && flag_unsafe_math_optimizations"
14136 if (optimize_insn_for_size_p ())
14139 op0 = gen_reg_rtx (XFmode);
14141 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14143 ix86_emit_i387_log1p (op0, operands[1]);
14144 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14148 (define_insn "fxtractxf3_i387"
14149 [(set (match_operand:XF 0 "register_operand" "=f")
14150 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14151 UNSPEC_XTRACT_FRACT))
14152 (set (match_operand:XF 1 "register_operand" "=u")
14153 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14154 "TARGET_USE_FANCY_MATH_387
14155 && flag_unsafe_math_optimizations"
14157 [(set_attr "type" "fpspc")
14158 (set_attr "mode" "XF")])
14160 (define_insn "fxtract_extend<mode>xf3_i387"
14161 [(set (match_operand:XF 0 "register_operand" "=f")
14162 (unspec:XF [(float_extend:XF
14163 (match_operand:MODEF 2 "register_operand" "0"))]
14164 UNSPEC_XTRACT_FRACT))
14165 (set (match_operand:XF 1 "register_operand" "=u")
14166 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14167 "TARGET_USE_FANCY_MATH_387
14168 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14169 || TARGET_MIX_SSE_I387)
14170 && flag_unsafe_math_optimizations"
14172 [(set_attr "type" "fpspc")
14173 (set_attr "mode" "XF")])
14175 (define_expand "logbxf2"
14176 [(parallel [(set (match_dup 2)
14177 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14178 UNSPEC_XTRACT_FRACT))
14179 (set (match_operand:XF 0 "register_operand" "")
14180 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14181 "TARGET_USE_FANCY_MATH_387
14182 && flag_unsafe_math_optimizations"
14183 "operands[2] = gen_reg_rtx (XFmode);")
14185 (define_expand "logb<mode>2"
14186 [(use (match_operand:MODEF 0 "register_operand" ""))
14187 (use (match_operand:MODEF 1 "register_operand" ""))]
14188 "TARGET_USE_FANCY_MATH_387
14189 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14190 || TARGET_MIX_SSE_I387)
14191 && flag_unsafe_math_optimizations"
14193 rtx op0 = gen_reg_rtx (XFmode);
14194 rtx op1 = gen_reg_rtx (XFmode);
14196 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14197 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14201 (define_expand "ilogbxf2"
14202 [(use (match_operand:SI 0 "register_operand" ""))
14203 (use (match_operand:XF 1 "register_operand" ""))]
14204 "TARGET_USE_FANCY_MATH_387
14205 && flag_unsafe_math_optimizations"
14209 if (optimize_insn_for_size_p ())
14212 op0 = gen_reg_rtx (XFmode);
14213 op1 = gen_reg_rtx (XFmode);
14215 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14216 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14220 (define_expand "ilogb<mode>2"
14221 [(use (match_operand:SI 0 "register_operand" ""))
14222 (use (match_operand:MODEF 1 "register_operand" ""))]
14223 "TARGET_USE_FANCY_MATH_387
14224 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14225 || TARGET_MIX_SSE_I387)
14226 && flag_unsafe_math_optimizations"
14230 if (optimize_insn_for_size_p ())
14233 op0 = gen_reg_rtx (XFmode);
14234 op1 = gen_reg_rtx (XFmode);
14236 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14237 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14241 (define_insn "*f2xm1xf2_i387"
14242 [(set (match_operand:XF 0 "register_operand" "=f")
14243 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14245 "TARGET_USE_FANCY_MATH_387
14246 && flag_unsafe_math_optimizations"
14248 [(set_attr "type" "fpspc")
14249 (set_attr "mode" "XF")])
14251 (define_insn "*fscalexf4_i387"
14252 [(set (match_operand:XF 0 "register_operand" "=f")
14253 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14254 (match_operand:XF 3 "register_operand" "1")]
14255 UNSPEC_FSCALE_FRACT))
14256 (set (match_operand:XF 1 "register_operand" "=u")
14257 (unspec:XF [(match_dup 2) (match_dup 3)]
14258 UNSPEC_FSCALE_EXP))]
14259 "TARGET_USE_FANCY_MATH_387
14260 && flag_unsafe_math_optimizations"
14262 [(set_attr "type" "fpspc")
14263 (set_attr "mode" "XF")])
14265 (define_expand "expNcorexf3"
14266 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14267 (match_operand:XF 2 "register_operand" "")))
14268 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14269 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14270 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14271 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14272 (parallel [(set (match_operand:XF 0 "register_operand" "")
14273 (unspec:XF [(match_dup 8) (match_dup 4)]
14274 UNSPEC_FSCALE_FRACT))
14276 (unspec:XF [(match_dup 8) (match_dup 4)]
14277 UNSPEC_FSCALE_EXP))])]
14278 "TARGET_USE_FANCY_MATH_387
14279 && flag_unsafe_math_optimizations"
14283 if (optimize_insn_for_size_p ())
14286 for (i = 3; i < 10; i++)
14287 operands[i] = gen_reg_rtx (XFmode);
14289 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14292 (define_expand "expxf2"
14293 [(use (match_operand:XF 0 "register_operand" ""))
14294 (use (match_operand:XF 1 "register_operand" ""))]
14295 "TARGET_USE_FANCY_MATH_387
14296 && flag_unsafe_math_optimizations"
14300 if (optimize_insn_for_size_p ())
14303 op2 = gen_reg_rtx (XFmode);
14304 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14306 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14310 (define_expand "exp<mode>2"
14311 [(use (match_operand:MODEF 0 "register_operand" ""))
14312 (use (match_operand:MODEF 1 "general_operand" ""))]
14313 "TARGET_USE_FANCY_MATH_387
14314 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14315 || TARGET_MIX_SSE_I387)
14316 && flag_unsafe_math_optimizations"
14320 if (optimize_insn_for_size_p ())
14323 op0 = gen_reg_rtx (XFmode);
14324 op1 = gen_reg_rtx (XFmode);
14326 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14327 emit_insn (gen_expxf2 (op0, op1));
14328 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14332 (define_expand "exp10xf2"
14333 [(use (match_operand:XF 0 "register_operand" ""))
14334 (use (match_operand:XF 1 "register_operand" ""))]
14335 "TARGET_USE_FANCY_MATH_387
14336 && flag_unsafe_math_optimizations"
14340 if (optimize_insn_for_size_p ())
14343 op2 = gen_reg_rtx (XFmode);
14344 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14346 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14350 (define_expand "exp10<mode>2"
14351 [(use (match_operand:MODEF 0 "register_operand" ""))
14352 (use (match_operand:MODEF 1 "general_operand" ""))]
14353 "TARGET_USE_FANCY_MATH_387
14354 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14355 || TARGET_MIX_SSE_I387)
14356 && flag_unsafe_math_optimizations"
14360 if (optimize_insn_for_size_p ())
14363 op0 = gen_reg_rtx (XFmode);
14364 op1 = gen_reg_rtx (XFmode);
14366 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14367 emit_insn (gen_exp10xf2 (op0, op1));
14368 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14372 (define_expand "exp2xf2"
14373 [(use (match_operand:XF 0 "register_operand" ""))
14374 (use (match_operand:XF 1 "register_operand" ""))]
14375 "TARGET_USE_FANCY_MATH_387
14376 && flag_unsafe_math_optimizations"
14380 if (optimize_insn_for_size_p ())
14383 op2 = gen_reg_rtx (XFmode);
14384 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14386 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14390 (define_expand "exp2<mode>2"
14391 [(use (match_operand:MODEF 0 "register_operand" ""))
14392 (use (match_operand:MODEF 1 "general_operand" ""))]
14393 "TARGET_USE_FANCY_MATH_387
14394 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14395 || TARGET_MIX_SSE_I387)
14396 && flag_unsafe_math_optimizations"
14400 if (optimize_insn_for_size_p ())
14403 op0 = gen_reg_rtx (XFmode);
14404 op1 = gen_reg_rtx (XFmode);
14406 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14407 emit_insn (gen_exp2xf2 (op0, op1));
14408 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14412 (define_expand "expm1xf2"
14413 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14415 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14416 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14417 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14418 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14419 (parallel [(set (match_dup 7)
14420 (unspec:XF [(match_dup 6) (match_dup 4)]
14421 UNSPEC_FSCALE_FRACT))
14423 (unspec:XF [(match_dup 6) (match_dup 4)]
14424 UNSPEC_FSCALE_EXP))])
14425 (parallel [(set (match_dup 10)
14426 (unspec:XF [(match_dup 9) (match_dup 8)]
14427 UNSPEC_FSCALE_FRACT))
14428 (set (match_dup 11)
14429 (unspec:XF [(match_dup 9) (match_dup 8)]
14430 UNSPEC_FSCALE_EXP))])
14431 (set (match_dup 12) (minus:XF (match_dup 10)
14432 (float_extend:XF (match_dup 13))))
14433 (set (match_operand:XF 0 "register_operand" "")
14434 (plus:XF (match_dup 12) (match_dup 7)))]
14435 "TARGET_USE_FANCY_MATH_387
14436 && flag_unsafe_math_optimizations"
14440 if (optimize_insn_for_size_p ())
14443 for (i = 2; i < 13; i++)
14444 operands[i] = gen_reg_rtx (XFmode);
14447 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14449 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14452 (define_expand "expm1<mode>2"
14453 [(use (match_operand:MODEF 0 "register_operand" ""))
14454 (use (match_operand:MODEF 1 "general_operand" ""))]
14455 "TARGET_USE_FANCY_MATH_387
14456 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14457 || TARGET_MIX_SSE_I387)
14458 && flag_unsafe_math_optimizations"
14462 if (optimize_insn_for_size_p ())
14465 op0 = gen_reg_rtx (XFmode);
14466 op1 = gen_reg_rtx (XFmode);
14468 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14469 emit_insn (gen_expm1xf2 (op0, op1));
14470 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14474 (define_expand "ldexpxf3"
14475 [(set (match_dup 3)
14476 (float:XF (match_operand:SI 2 "register_operand" "")))
14477 (parallel [(set (match_operand:XF 0 " register_operand" "")
14478 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14480 UNSPEC_FSCALE_FRACT))
14482 (unspec:XF [(match_dup 1) (match_dup 3)]
14483 UNSPEC_FSCALE_EXP))])]
14484 "TARGET_USE_FANCY_MATH_387
14485 && flag_unsafe_math_optimizations"
14487 if (optimize_insn_for_size_p ())
14490 operands[3] = gen_reg_rtx (XFmode);
14491 operands[4] = gen_reg_rtx (XFmode);
14494 (define_expand "ldexp<mode>3"
14495 [(use (match_operand:MODEF 0 "register_operand" ""))
14496 (use (match_operand:MODEF 1 "general_operand" ""))
14497 (use (match_operand:SI 2 "register_operand" ""))]
14498 "TARGET_USE_FANCY_MATH_387
14499 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14500 || TARGET_MIX_SSE_I387)
14501 && flag_unsafe_math_optimizations"
14505 if (optimize_insn_for_size_p ())
14508 op0 = gen_reg_rtx (XFmode);
14509 op1 = gen_reg_rtx (XFmode);
14511 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14512 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14513 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14517 (define_expand "scalbxf3"
14518 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14519 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14520 (match_operand:XF 2 "register_operand" "")]
14521 UNSPEC_FSCALE_FRACT))
14523 (unspec:XF [(match_dup 1) (match_dup 2)]
14524 UNSPEC_FSCALE_EXP))])]
14525 "TARGET_USE_FANCY_MATH_387
14526 && flag_unsafe_math_optimizations"
14528 if (optimize_insn_for_size_p ())
14531 operands[3] = gen_reg_rtx (XFmode);
14534 (define_expand "scalb<mode>3"
14535 [(use (match_operand:MODEF 0 "register_operand" ""))
14536 (use (match_operand:MODEF 1 "general_operand" ""))
14537 (use (match_operand:MODEF 2 "general_operand" ""))]
14538 "TARGET_USE_FANCY_MATH_387
14539 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14540 || TARGET_MIX_SSE_I387)
14541 && flag_unsafe_math_optimizations"
14545 if (optimize_insn_for_size_p ())
14548 op0 = gen_reg_rtx (XFmode);
14549 op1 = gen_reg_rtx (XFmode);
14550 op2 = gen_reg_rtx (XFmode);
14552 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14553 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14554 emit_insn (gen_scalbxf3 (op0, op1, op2));
14555 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14559 (define_expand "significandxf2"
14560 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14561 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14562 UNSPEC_XTRACT_FRACT))
14564 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14565 "TARGET_USE_FANCY_MATH_387
14566 && flag_unsafe_math_optimizations"
14567 "operands[2] = gen_reg_rtx (XFmode);")
14569 (define_expand "significand<mode>2"
14570 [(use (match_operand:MODEF 0 "register_operand" ""))
14571 (use (match_operand:MODEF 1 "register_operand" ""))]
14572 "TARGET_USE_FANCY_MATH_387
14573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14574 || TARGET_MIX_SSE_I387)
14575 && flag_unsafe_math_optimizations"
14577 rtx op0 = gen_reg_rtx (XFmode);
14578 rtx op1 = gen_reg_rtx (XFmode);
14580 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14581 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14586 (define_insn "sse4_1_round<mode>2"
14587 [(set (match_operand:MODEF 0 "register_operand" "=x")
14588 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14589 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14592 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14593 [(set_attr "type" "ssecvt")
14594 (set_attr "prefix_extra" "1")
14595 (set_attr "prefix" "maybe_vex")
14596 (set_attr "mode" "<MODE>")])
14598 (define_insn "rintxf2"
14599 [(set (match_operand:XF 0 "register_operand" "=f")
14600 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14602 "TARGET_USE_FANCY_MATH_387
14603 && flag_unsafe_math_optimizations"
14605 [(set_attr "type" "fpspc")
14606 (set_attr "mode" "XF")])
14608 (define_expand "rint<mode>2"
14609 [(use (match_operand:MODEF 0 "register_operand" ""))
14610 (use (match_operand:MODEF 1 "register_operand" ""))]
14611 "(TARGET_USE_FANCY_MATH_387
14612 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14613 || TARGET_MIX_SSE_I387)
14614 && flag_unsafe_math_optimizations)
14615 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14616 && !flag_trapping_math)"
14618 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14619 && !flag_trapping_math)
14622 emit_insn (gen_sse4_1_round<mode>2
14623 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14624 else if (optimize_insn_for_size_p ())
14627 ix86_expand_rint (operands[0], operands[1]);
14631 rtx op0 = gen_reg_rtx (XFmode);
14632 rtx op1 = gen_reg_rtx (XFmode);
14634 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14635 emit_insn (gen_rintxf2 (op0, op1));
14637 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14642 (define_expand "round<mode>2"
14643 [(match_operand:X87MODEF 0 "register_operand" "")
14644 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14645 "(TARGET_USE_FANCY_MATH_387
14646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14647 || TARGET_MIX_SSE_I387)
14648 && flag_unsafe_math_optimizations)
14649 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14650 && !flag_trapping_math && !flag_rounding_math)"
14652 if (optimize_insn_for_size_p ())
14655 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14656 && !flag_trapping_math && !flag_rounding_math)
14660 operands[1] = force_reg (<MODE>mode, operands[1]);
14661 ix86_expand_round_sse4 (operands[0], operands[1]);
14663 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14664 ix86_expand_round (operands[0], operands[1]);
14666 ix86_expand_rounddf_32 (operands[0], operands[1]);
14670 operands[1] = force_reg (<MODE>mode, operands[1]);
14671 ix86_emit_i387_round (operands[0], operands[1]);
14676 (define_insn_and_split "*fistdi2_1"
14677 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14678 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14680 "TARGET_USE_FANCY_MATH_387
14681 && can_create_pseudo_p ()"
14686 if (memory_operand (operands[0], VOIDmode))
14687 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14690 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14691 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14696 [(set_attr "type" "fpspc")
14697 (set_attr "mode" "DI")])
14699 (define_insn "fistdi2"
14700 [(set (match_operand:DI 0 "memory_operand" "=m")
14701 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14703 (clobber (match_scratch:XF 2 "=&1f"))]
14704 "TARGET_USE_FANCY_MATH_387"
14705 "* return output_fix_trunc (insn, operands, false);"
14706 [(set_attr "type" "fpspc")
14707 (set_attr "mode" "DI")])
14709 (define_insn "fistdi2_with_temp"
14710 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14711 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14713 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14714 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14715 "TARGET_USE_FANCY_MATH_387"
14717 [(set_attr "type" "fpspc")
14718 (set_attr "mode" "DI")])
14721 [(set (match_operand:DI 0 "register_operand" "")
14722 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14724 (clobber (match_operand:DI 2 "memory_operand" ""))
14725 (clobber (match_scratch 3 ""))]
14727 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14728 (clobber (match_dup 3))])
14729 (set (match_dup 0) (match_dup 2))])
14732 [(set (match_operand:DI 0 "memory_operand" "")
14733 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14735 (clobber (match_operand:DI 2 "memory_operand" ""))
14736 (clobber (match_scratch 3 ""))]
14738 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14739 (clobber (match_dup 3))])])
14741 (define_insn_and_split "*fist<mode>2_1"
14742 [(set (match_operand:SWI24 0 "register_operand" "")
14743 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14745 "TARGET_USE_FANCY_MATH_387
14746 && can_create_pseudo_p ()"
14751 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14752 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14756 [(set_attr "type" "fpspc")
14757 (set_attr "mode" "<MODE>")])
14759 (define_insn "fist<mode>2"
14760 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14761 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14763 "TARGET_USE_FANCY_MATH_387"
14764 "* return output_fix_trunc (insn, operands, false);"
14765 [(set_attr "type" "fpspc")
14766 (set_attr "mode" "<MODE>")])
14768 (define_insn "fist<mode>2_with_temp"
14769 [(set (match_operand:SWI24 0 "register_operand" "=r")
14770 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14772 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14773 "TARGET_USE_FANCY_MATH_387"
14775 [(set_attr "type" "fpspc")
14776 (set_attr "mode" "<MODE>")])
14779 [(set (match_operand:SWI24 0 "register_operand" "")
14780 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14782 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14784 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14785 (set (match_dup 0) (match_dup 2))])
14788 [(set (match_operand:SWI24 0 "memory_operand" "")
14789 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14791 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14793 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14795 (define_expand "lrintxf<mode>2"
14796 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14797 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14799 "TARGET_USE_FANCY_MATH_387")
14801 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14802 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14803 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14804 UNSPEC_FIX_NOTRUNC))]
14805 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14806 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14808 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14809 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14810 (match_operand:X87MODEF 1 "register_operand" "")]
14811 "(TARGET_USE_FANCY_MATH_387
14812 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14813 || TARGET_MIX_SSE_I387)
14814 && flag_unsafe_math_optimizations)
14815 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14816 && <SWI248x:MODE>mode != HImode
14817 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14818 && !flag_trapping_math && !flag_rounding_math)"
14820 if (optimize_insn_for_size_p ())
14823 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14824 && <SWI248x:MODE>mode != HImode
14825 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14826 && !flag_trapping_math && !flag_rounding_math)
14827 ix86_expand_lround (operands[0], operands[1]);
14829 ix86_emit_i387_round (operands[0], operands[1]);
14833 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14834 (define_insn_and_split "frndintxf2_floor"
14835 [(set (match_operand:XF 0 "register_operand" "")
14836 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14837 UNSPEC_FRNDINT_FLOOR))
14838 (clobber (reg:CC FLAGS_REG))]
14839 "TARGET_USE_FANCY_MATH_387
14840 && flag_unsafe_math_optimizations
14841 && can_create_pseudo_p ()"
14846 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14848 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14849 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14851 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14852 operands[2], operands[3]));
14855 [(set_attr "type" "frndint")
14856 (set_attr "i387_cw" "floor")
14857 (set_attr "mode" "XF")])
14859 (define_insn "frndintxf2_floor_i387"
14860 [(set (match_operand:XF 0 "register_operand" "=f")
14861 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14862 UNSPEC_FRNDINT_FLOOR))
14863 (use (match_operand:HI 2 "memory_operand" "m"))
14864 (use (match_operand:HI 3 "memory_operand" "m"))]
14865 "TARGET_USE_FANCY_MATH_387
14866 && flag_unsafe_math_optimizations"
14867 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14868 [(set_attr "type" "frndint")
14869 (set_attr "i387_cw" "floor")
14870 (set_attr "mode" "XF")])
14872 (define_expand "floorxf2"
14873 [(use (match_operand:XF 0 "register_operand" ""))
14874 (use (match_operand:XF 1 "register_operand" ""))]
14875 "TARGET_USE_FANCY_MATH_387
14876 && flag_unsafe_math_optimizations"
14878 if (optimize_insn_for_size_p ())
14880 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14884 (define_expand "floor<mode>2"
14885 [(use (match_operand:MODEF 0 "register_operand" ""))
14886 (use (match_operand:MODEF 1 "register_operand" ""))]
14887 "(TARGET_USE_FANCY_MATH_387
14888 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14889 || TARGET_MIX_SSE_I387)
14890 && flag_unsafe_math_optimizations)
14891 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14892 && !flag_trapping_math)"
14894 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14895 && !flag_trapping_math)
14898 emit_insn (gen_sse4_1_round<mode>2
14899 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14900 else if (optimize_insn_for_size_p ())
14902 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14903 ix86_expand_floorceil (operands[0], operands[1], true);
14905 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14911 if (optimize_insn_for_size_p ())
14914 op0 = gen_reg_rtx (XFmode);
14915 op1 = gen_reg_rtx (XFmode);
14916 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14917 emit_insn (gen_frndintxf2_floor (op0, op1));
14919 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14924 (define_insn_and_split "*fist<mode>2_floor_1"
14925 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14926 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14927 UNSPEC_FIST_FLOOR))
14928 (clobber (reg:CC FLAGS_REG))]
14929 "TARGET_USE_FANCY_MATH_387
14930 && flag_unsafe_math_optimizations
14931 && can_create_pseudo_p ()"
14936 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14938 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14939 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14940 if (memory_operand (operands[0], VOIDmode))
14941 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14942 operands[2], operands[3]));
14945 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14946 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14947 operands[2], operands[3],
14952 [(set_attr "type" "fistp")
14953 (set_attr "i387_cw" "floor")
14954 (set_attr "mode" "<MODE>")])
14956 (define_insn "fistdi2_floor"
14957 [(set (match_operand:DI 0 "memory_operand" "=m")
14958 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14959 UNSPEC_FIST_FLOOR))
14960 (use (match_operand:HI 2 "memory_operand" "m"))
14961 (use (match_operand:HI 3 "memory_operand" "m"))
14962 (clobber (match_scratch:XF 4 "=&1f"))]
14963 "TARGET_USE_FANCY_MATH_387
14964 && flag_unsafe_math_optimizations"
14965 "* return output_fix_trunc (insn, operands, false);"
14966 [(set_attr "type" "fistp")
14967 (set_attr "i387_cw" "floor")
14968 (set_attr "mode" "DI")])
14970 (define_insn "fistdi2_floor_with_temp"
14971 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14972 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14973 UNSPEC_FIST_FLOOR))
14974 (use (match_operand:HI 2 "memory_operand" "m,m"))
14975 (use (match_operand:HI 3 "memory_operand" "m,m"))
14976 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14977 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14978 "TARGET_USE_FANCY_MATH_387
14979 && flag_unsafe_math_optimizations"
14981 [(set_attr "type" "fistp")
14982 (set_attr "i387_cw" "floor")
14983 (set_attr "mode" "DI")])
14986 [(set (match_operand:DI 0 "register_operand" "")
14987 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14988 UNSPEC_FIST_FLOOR))
14989 (use (match_operand:HI 2 "memory_operand" ""))
14990 (use (match_operand:HI 3 "memory_operand" ""))
14991 (clobber (match_operand:DI 4 "memory_operand" ""))
14992 (clobber (match_scratch 5 ""))]
14994 [(parallel [(set (match_dup 4)
14995 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14996 (use (match_dup 2))
14997 (use (match_dup 3))
14998 (clobber (match_dup 5))])
14999 (set (match_dup 0) (match_dup 4))])
15002 [(set (match_operand:DI 0 "memory_operand" "")
15003 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15004 UNSPEC_FIST_FLOOR))
15005 (use (match_operand:HI 2 "memory_operand" ""))
15006 (use (match_operand:HI 3 "memory_operand" ""))
15007 (clobber (match_operand:DI 4 "memory_operand" ""))
15008 (clobber (match_scratch 5 ""))]
15010 [(parallel [(set (match_dup 0)
15011 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15012 (use (match_dup 2))
15013 (use (match_dup 3))
15014 (clobber (match_dup 5))])])
15016 (define_insn "fist<mode>2_floor"
15017 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15018 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15019 UNSPEC_FIST_FLOOR))
15020 (use (match_operand:HI 2 "memory_operand" "m"))
15021 (use (match_operand:HI 3 "memory_operand" "m"))]
15022 "TARGET_USE_FANCY_MATH_387
15023 && flag_unsafe_math_optimizations"
15024 "* return output_fix_trunc (insn, operands, false);"
15025 [(set_attr "type" "fistp")
15026 (set_attr "i387_cw" "floor")
15027 (set_attr "mode" "<MODE>")])
15029 (define_insn "fist<mode>2_floor_with_temp"
15030 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15031 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15032 UNSPEC_FIST_FLOOR))
15033 (use (match_operand:HI 2 "memory_operand" "m,m"))
15034 (use (match_operand:HI 3 "memory_operand" "m,m"))
15035 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15036 "TARGET_USE_FANCY_MATH_387
15037 && flag_unsafe_math_optimizations"
15039 [(set_attr "type" "fistp")
15040 (set_attr "i387_cw" "floor")
15041 (set_attr "mode" "<MODE>")])
15044 [(set (match_operand:SWI24 0 "register_operand" "")
15045 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15046 UNSPEC_FIST_FLOOR))
15047 (use (match_operand:HI 2 "memory_operand" ""))
15048 (use (match_operand:HI 3 "memory_operand" ""))
15049 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15051 [(parallel [(set (match_dup 4)
15052 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15053 (use (match_dup 2))
15054 (use (match_dup 3))])
15055 (set (match_dup 0) (match_dup 4))])
15058 [(set (match_operand:SWI24 0 "memory_operand" "")
15059 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15060 UNSPEC_FIST_FLOOR))
15061 (use (match_operand:HI 2 "memory_operand" ""))
15062 (use (match_operand:HI 3 "memory_operand" ""))
15063 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15065 [(parallel [(set (match_dup 0)
15066 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15067 (use (match_dup 2))
15068 (use (match_dup 3))])])
15070 (define_expand "lfloorxf<mode>2"
15071 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15072 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15073 UNSPEC_FIST_FLOOR))
15074 (clobber (reg:CC FLAGS_REG))])]
15075 "TARGET_USE_FANCY_MATH_387
15076 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15077 && flag_unsafe_math_optimizations")
15079 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15080 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15081 (match_operand:MODEF 1 "register_operand" "")]
15082 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15083 && !flag_trapping_math"
15085 if (TARGET_64BIT && optimize_insn_for_size_p ())
15087 ix86_expand_lfloorceil (operands[0], operands[1], true);
15091 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15092 (define_insn_and_split "frndintxf2_ceil"
15093 [(set (match_operand:XF 0 "register_operand" "")
15094 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15095 UNSPEC_FRNDINT_CEIL))
15096 (clobber (reg:CC FLAGS_REG))]
15097 "TARGET_USE_FANCY_MATH_387
15098 && flag_unsafe_math_optimizations
15099 && can_create_pseudo_p ()"
15104 ix86_optimize_mode_switching[I387_CEIL] = 1;
15106 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15107 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15109 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15110 operands[2], operands[3]));
15113 [(set_attr "type" "frndint")
15114 (set_attr "i387_cw" "ceil")
15115 (set_attr "mode" "XF")])
15117 (define_insn "frndintxf2_ceil_i387"
15118 [(set (match_operand:XF 0 "register_operand" "=f")
15119 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15120 UNSPEC_FRNDINT_CEIL))
15121 (use (match_operand:HI 2 "memory_operand" "m"))
15122 (use (match_operand:HI 3 "memory_operand" "m"))]
15123 "TARGET_USE_FANCY_MATH_387
15124 && flag_unsafe_math_optimizations"
15125 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15126 [(set_attr "type" "frndint")
15127 (set_attr "i387_cw" "ceil")
15128 (set_attr "mode" "XF")])
15130 (define_expand "ceilxf2"
15131 [(use (match_operand:XF 0 "register_operand" ""))
15132 (use (match_operand:XF 1 "register_operand" ""))]
15133 "TARGET_USE_FANCY_MATH_387
15134 && flag_unsafe_math_optimizations"
15136 if (optimize_insn_for_size_p ())
15138 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15142 (define_expand "ceil<mode>2"
15143 [(use (match_operand:MODEF 0 "register_operand" ""))
15144 (use (match_operand:MODEF 1 "register_operand" ""))]
15145 "(TARGET_USE_FANCY_MATH_387
15146 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15147 || TARGET_MIX_SSE_I387)
15148 && flag_unsafe_math_optimizations)
15149 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15150 && !flag_trapping_math)"
15152 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15153 && !flag_trapping_math)
15156 emit_insn (gen_sse4_1_round<mode>2
15157 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15158 else if (optimize_insn_for_size_p ())
15160 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15161 ix86_expand_floorceil (operands[0], operands[1], false);
15163 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15169 if (optimize_insn_for_size_p ())
15172 op0 = gen_reg_rtx (XFmode);
15173 op1 = gen_reg_rtx (XFmode);
15174 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15175 emit_insn (gen_frndintxf2_ceil (op0, op1));
15177 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15182 (define_insn_and_split "*fist<mode>2_ceil_1"
15183 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15184 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15186 (clobber (reg:CC FLAGS_REG))]
15187 "TARGET_USE_FANCY_MATH_387
15188 && flag_unsafe_math_optimizations
15189 && can_create_pseudo_p ()"
15194 ix86_optimize_mode_switching[I387_CEIL] = 1;
15196 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15197 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15198 if (memory_operand (operands[0], VOIDmode))
15199 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15200 operands[2], operands[3]));
15203 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15204 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15205 operands[2], operands[3],
15210 [(set_attr "type" "fistp")
15211 (set_attr "i387_cw" "ceil")
15212 (set_attr "mode" "<MODE>")])
15214 (define_insn "fistdi2_ceil"
15215 [(set (match_operand:DI 0 "memory_operand" "=m")
15216 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15218 (use (match_operand:HI 2 "memory_operand" "m"))
15219 (use (match_operand:HI 3 "memory_operand" "m"))
15220 (clobber (match_scratch:XF 4 "=&1f"))]
15221 "TARGET_USE_FANCY_MATH_387
15222 && flag_unsafe_math_optimizations"
15223 "* return output_fix_trunc (insn, operands, false);"
15224 [(set_attr "type" "fistp")
15225 (set_attr "i387_cw" "ceil")
15226 (set_attr "mode" "DI")])
15228 (define_insn "fistdi2_ceil_with_temp"
15229 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15230 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15232 (use (match_operand:HI 2 "memory_operand" "m,m"))
15233 (use (match_operand:HI 3 "memory_operand" "m,m"))
15234 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15235 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15236 "TARGET_USE_FANCY_MATH_387
15237 && flag_unsafe_math_optimizations"
15239 [(set_attr "type" "fistp")
15240 (set_attr "i387_cw" "ceil")
15241 (set_attr "mode" "DI")])
15244 [(set (match_operand:DI 0 "register_operand" "")
15245 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15247 (use (match_operand:HI 2 "memory_operand" ""))
15248 (use (match_operand:HI 3 "memory_operand" ""))
15249 (clobber (match_operand:DI 4 "memory_operand" ""))
15250 (clobber (match_scratch 5 ""))]
15252 [(parallel [(set (match_dup 4)
15253 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15254 (use (match_dup 2))
15255 (use (match_dup 3))
15256 (clobber (match_dup 5))])
15257 (set (match_dup 0) (match_dup 4))])
15260 [(set (match_operand:DI 0 "memory_operand" "")
15261 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15263 (use (match_operand:HI 2 "memory_operand" ""))
15264 (use (match_operand:HI 3 "memory_operand" ""))
15265 (clobber (match_operand:DI 4 "memory_operand" ""))
15266 (clobber (match_scratch 5 ""))]
15268 [(parallel [(set (match_dup 0)
15269 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15270 (use (match_dup 2))
15271 (use (match_dup 3))
15272 (clobber (match_dup 5))])])
15274 (define_insn "fist<mode>2_ceil"
15275 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15276 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15278 (use (match_operand:HI 2 "memory_operand" "m"))
15279 (use (match_operand:HI 3 "memory_operand" "m"))]
15280 "TARGET_USE_FANCY_MATH_387
15281 && flag_unsafe_math_optimizations"
15282 "* return output_fix_trunc (insn, operands, false);"
15283 [(set_attr "type" "fistp")
15284 (set_attr "i387_cw" "ceil")
15285 (set_attr "mode" "<MODE>")])
15287 (define_insn "fist<mode>2_ceil_with_temp"
15288 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15289 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15291 (use (match_operand:HI 2 "memory_operand" "m,m"))
15292 (use (match_operand:HI 3 "memory_operand" "m,m"))
15293 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15294 "TARGET_USE_FANCY_MATH_387
15295 && flag_unsafe_math_optimizations"
15297 [(set_attr "type" "fistp")
15298 (set_attr "i387_cw" "ceil")
15299 (set_attr "mode" "<MODE>")])
15302 [(set (match_operand:SWI24 0 "register_operand" "")
15303 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15305 (use (match_operand:HI 2 "memory_operand" ""))
15306 (use (match_operand:HI 3 "memory_operand" ""))
15307 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15309 [(parallel [(set (match_dup 4)
15310 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15311 (use (match_dup 2))
15312 (use (match_dup 3))])
15313 (set (match_dup 0) (match_dup 4))])
15316 [(set (match_operand:SWI24 0 "memory_operand" "")
15317 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15319 (use (match_operand:HI 2 "memory_operand" ""))
15320 (use (match_operand:HI 3 "memory_operand" ""))
15321 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15323 [(parallel [(set (match_dup 0)
15324 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15325 (use (match_dup 2))
15326 (use (match_dup 3))])])
15328 (define_expand "lceilxf<mode>2"
15329 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15330 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15332 (clobber (reg:CC FLAGS_REG))])]
15333 "TARGET_USE_FANCY_MATH_387
15334 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15335 && flag_unsafe_math_optimizations")
15337 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15338 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15339 (match_operand:MODEF 1 "register_operand" "")]
15340 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15341 && !flag_trapping_math"
15343 ix86_expand_lfloorceil (operands[0], operands[1], false);
15347 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15348 (define_insn_and_split "frndintxf2_trunc"
15349 [(set (match_operand:XF 0 "register_operand" "")
15350 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15351 UNSPEC_FRNDINT_TRUNC))
15352 (clobber (reg:CC FLAGS_REG))]
15353 "TARGET_USE_FANCY_MATH_387
15354 && flag_unsafe_math_optimizations
15355 && can_create_pseudo_p ()"
15360 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15362 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15363 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15365 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15366 operands[2], operands[3]));
15369 [(set_attr "type" "frndint")
15370 (set_attr "i387_cw" "trunc")
15371 (set_attr "mode" "XF")])
15373 (define_insn "frndintxf2_trunc_i387"
15374 [(set (match_operand:XF 0 "register_operand" "=f")
15375 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15376 UNSPEC_FRNDINT_TRUNC))
15377 (use (match_operand:HI 2 "memory_operand" "m"))
15378 (use (match_operand:HI 3 "memory_operand" "m"))]
15379 "TARGET_USE_FANCY_MATH_387
15380 && flag_unsafe_math_optimizations"
15381 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15382 [(set_attr "type" "frndint")
15383 (set_attr "i387_cw" "trunc")
15384 (set_attr "mode" "XF")])
15386 (define_expand "btruncxf2"
15387 [(use (match_operand:XF 0 "register_operand" ""))
15388 (use (match_operand:XF 1 "register_operand" ""))]
15389 "TARGET_USE_FANCY_MATH_387
15390 && flag_unsafe_math_optimizations"
15392 if (optimize_insn_for_size_p ())
15394 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15398 (define_expand "btrunc<mode>2"
15399 [(use (match_operand:MODEF 0 "register_operand" ""))
15400 (use (match_operand:MODEF 1 "register_operand" ""))]
15401 "(TARGET_USE_FANCY_MATH_387
15402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15403 || TARGET_MIX_SSE_I387)
15404 && flag_unsafe_math_optimizations)
15405 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15406 && !flag_trapping_math)"
15408 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15409 && !flag_trapping_math)
15412 emit_insn (gen_sse4_1_round<mode>2
15413 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15414 else if (optimize_insn_for_size_p ())
15416 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15417 ix86_expand_trunc (operands[0], operands[1]);
15419 ix86_expand_truncdf_32 (operands[0], operands[1]);
15425 if (optimize_insn_for_size_p ())
15428 op0 = gen_reg_rtx (XFmode);
15429 op1 = gen_reg_rtx (XFmode);
15430 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15431 emit_insn (gen_frndintxf2_trunc (op0, op1));
15433 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15438 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15439 (define_insn_and_split "frndintxf2_mask_pm"
15440 [(set (match_operand:XF 0 "register_operand" "")
15441 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15442 UNSPEC_FRNDINT_MASK_PM))
15443 (clobber (reg:CC FLAGS_REG))]
15444 "TARGET_USE_FANCY_MATH_387
15445 && flag_unsafe_math_optimizations
15446 && can_create_pseudo_p ()"
15451 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15453 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15454 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15456 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15457 operands[2], operands[3]));
15460 [(set_attr "type" "frndint")
15461 (set_attr "i387_cw" "mask_pm")
15462 (set_attr "mode" "XF")])
15464 (define_insn "frndintxf2_mask_pm_i387"
15465 [(set (match_operand:XF 0 "register_operand" "=f")
15466 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15467 UNSPEC_FRNDINT_MASK_PM))
15468 (use (match_operand:HI 2 "memory_operand" "m"))
15469 (use (match_operand:HI 3 "memory_operand" "m"))]
15470 "TARGET_USE_FANCY_MATH_387
15471 && flag_unsafe_math_optimizations"
15472 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15473 [(set_attr "type" "frndint")
15474 (set_attr "i387_cw" "mask_pm")
15475 (set_attr "mode" "XF")])
15477 (define_expand "nearbyintxf2"
15478 [(use (match_operand:XF 0 "register_operand" ""))
15479 (use (match_operand:XF 1 "register_operand" ""))]
15480 "TARGET_USE_FANCY_MATH_387
15481 && flag_unsafe_math_optimizations"
15483 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15487 (define_expand "nearbyint<mode>2"
15488 [(use (match_operand:MODEF 0 "register_operand" ""))
15489 (use (match_operand:MODEF 1 "register_operand" ""))]
15490 "TARGET_USE_FANCY_MATH_387
15491 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15492 || TARGET_MIX_SSE_I387)
15493 && flag_unsafe_math_optimizations"
15495 rtx op0 = gen_reg_rtx (XFmode);
15496 rtx op1 = gen_reg_rtx (XFmode);
15498 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15499 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15501 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15505 (define_insn "fxam<mode>2_i387"
15506 [(set (match_operand:HI 0 "register_operand" "=a")
15508 [(match_operand:X87MODEF 1 "register_operand" "f")]
15510 "TARGET_USE_FANCY_MATH_387"
15511 "fxam\n\tfnstsw\t%0"
15512 [(set_attr "type" "multi")
15513 (set_attr "length" "4")
15514 (set_attr "unit" "i387")
15515 (set_attr "mode" "<MODE>")])
15517 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15518 [(set (match_operand:HI 0 "register_operand" "")
15520 [(match_operand:MODEF 1 "memory_operand" "")]
15522 "TARGET_USE_FANCY_MATH_387
15523 && can_create_pseudo_p ()"
15526 [(set (match_dup 2)(match_dup 1))
15528 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15530 operands[2] = gen_reg_rtx (<MODE>mode);
15532 MEM_VOLATILE_P (operands[1]) = 1;
15534 [(set_attr "type" "multi")
15535 (set_attr "unit" "i387")
15536 (set_attr "mode" "<MODE>")])
15538 (define_expand "isinfxf2"
15539 [(use (match_operand:SI 0 "register_operand" ""))
15540 (use (match_operand:XF 1 "register_operand" ""))]
15541 "TARGET_USE_FANCY_MATH_387
15542 && TARGET_C99_FUNCTIONS"
15544 rtx mask = GEN_INT (0x45);
15545 rtx val = GEN_INT (0x05);
15549 rtx scratch = gen_reg_rtx (HImode);
15550 rtx res = gen_reg_rtx (QImode);
15552 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15554 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15555 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15556 cond = gen_rtx_fmt_ee (EQ, QImode,
15557 gen_rtx_REG (CCmode, FLAGS_REG),
15559 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15560 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15564 (define_expand "isinf<mode>2"
15565 [(use (match_operand:SI 0 "register_operand" ""))
15566 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15567 "TARGET_USE_FANCY_MATH_387
15568 && TARGET_C99_FUNCTIONS
15569 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15571 rtx mask = GEN_INT (0x45);
15572 rtx val = GEN_INT (0x05);
15576 rtx scratch = gen_reg_rtx (HImode);
15577 rtx res = gen_reg_rtx (QImode);
15579 /* Remove excess precision by forcing value through memory. */
15580 if (memory_operand (operands[1], VOIDmode))
15581 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15584 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15586 emit_move_insn (temp, operands[1]);
15587 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15590 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15591 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15592 cond = gen_rtx_fmt_ee (EQ, QImode,
15593 gen_rtx_REG (CCmode, FLAGS_REG),
15595 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15596 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15600 (define_expand "signbitxf2"
15601 [(use (match_operand:SI 0 "register_operand" ""))
15602 (use (match_operand:XF 1 "register_operand" ""))]
15603 "TARGET_USE_FANCY_MATH_387"
15605 rtx scratch = gen_reg_rtx (HImode);
15607 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15608 emit_insn (gen_andsi3 (operands[0],
15609 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15613 (define_insn "movmsk_df"
15614 [(set (match_operand:SI 0 "register_operand" "=r")
15616 [(match_operand:DF 1 "register_operand" "x")]
15618 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15619 "%vmovmskpd\t{%1, %0|%0, %1}"
15620 [(set_attr "type" "ssemov")
15621 (set_attr "prefix" "maybe_vex")
15622 (set_attr "mode" "DF")])
15624 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15625 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15626 (define_expand "signbitdf2"
15627 [(use (match_operand:SI 0 "register_operand" ""))
15628 (use (match_operand:DF 1 "register_operand" ""))]
15629 "TARGET_USE_FANCY_MATH_387
15630 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15632 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15634 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15635 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15639 rtx scratch = gen_reg_rtx (HImode);
15641 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15642 emit_insn (gen_andsi3 (operands[0],
15643 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15648 (define_expand "signbitsf2"
15649 [(use (match_operand:SI 0 "register_operand" ""))
15650 (use (match_operand:SF 1 "register_operand" ""))]
15651 "TARGET_USE_FANCY_MATH_387
15652 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15654 rtx scratch = gen_reg_rtx (HImode);
15656 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15657 emit_insn (gen_andsi3 (operands[0],
15658 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15662 ;; Block operation instructions
15665 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15668 [(set_attr "length" "1")
15669 (set_attr "length_immediate" "0")
15670 (set_attr "modrm" "0")])
15672 (define_expand "movmem<mode>"
15673 [(use (match_operand:BLK 0 "memory_operand" ""))
15674 (use (match_operand:BLK 1 "memory_operand" ""))
15675 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15676 (use (match_operand:SWI48 3 "const_int_operand" ""))
15677 (use (match_operand:SI 4 "const_int_operand" ""))
15678 (use (match_operand:SI 5 "const_int_operand" ""))]
15681 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15682 operands[4], operands[5]))
15688 ;; Most CPUs don't like single string operations
15689 ;; Handle this case here to simplify previous expander.
15691 (define_expand "strmov"
15692 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15693 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15694 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15695 (clobber (reg:CC FLAGS_REG))])
15696 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15697 (clobber (reg:CC FLAGS_REG))])]
15700 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15702 /* If .md ever supports :P for Pmode, these can be directly
15703 in the pattern above. */
15704 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15705 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15707 /* Can't use this if the user has appropriated esi or edi. */
15708 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15709 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15711 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15712 operands[2], operands[3],
15713 operands[5], operands[6]));
15717 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15720 (define_expand "strmov_singleop"
15721 [(parallel [(set (match_operand 1 "memory_operand" "")
15722 (match_operand 3 "memory_operand" ""))
15723 (set (match_operand 0 "register_operand" "")
15724 (match_operand 4 "" ""))
15725 (set (match_operand 2 "register_operand" "")
15726 (match_operand 5 "" ""))])]
15728 "ix86_current_function_needs_cld = 1;")
15730 (define_insn "*strmovdi_rex_1"
15731 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15732 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15733 (set (match_operand:DI 0 "register_operand" "=D")
15734 (plus:DI (match_dup 2)
15736 (set (match_operand:DI 1 "register_operand" "=S")
15737 (plus:DI (match_dup 3)
15740 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15742 [(set_attr "type" "str")
15743 (set_attr "memory" "both")
15744 (set_attr "mode" "DI")])
15746 (define_insn "*strmovsi_1"
15747 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15748 (mem:SI (match_operand:P 3 "register_operand" "1")))
15749 (set (match_operand:P 0 "register_operand" "=D")
15750 (plus:P (match_dup 2)
15752 (set (match_operand:P 1 "register_operand" "=S")
15753 (plus:P (match_dup 3)
15755 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15757 [(set_attr "type" "str")
15758 (set_attr "memory" "both")
15759 (set_attr "mode" "SI")])
15761 (define_insn "*strmovhi_1"
15762 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15763 (mem:HI (match_operand:P 3 "register_operand" "1")))
15764 (set (match_operand:P 0 "register_operand" "=D")
15765 (plus:P (match_dup 2)
15767 (set (match_operand:P 1 "register_operand" "=S")
15768 (plus:P (match_dup 3)
15770 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15772 [(set_attr "type" "str")
15773 (set_attr "memory" "both")
15774 (set_attr "mode" "HI")])
15776 (define_insn "*strmovqi_1"
15777 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15778 (mem:QI (match_operand:P 3 "register_operand" "1")))
15779 (set (match_operand:P 0 "register_operand" "=D")
15780 (plus:P (match_dup 2)
15782 (set (match_operand:P 1 "register_operand" "=S")
15783 (plus:P (match_dup 3)
15785 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15787 [(set_attr "type" "str")
15788 (set_attr "memory" "both")
15789 (set (attr "prefix_rex")
15791 (match_test "<P:MODE>mode == DImode")
15793 (const_string "*")))
15794 (set_attr "mode" "QI")])
15796 (define_expand "rep_mov"
15797 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15798 (set (match_operand 0 "register_operand" "")
15799 (match_operand 5 "" ""))
15800 (set (match_operand 2 "register_operand" "")
15801 (match_operand 6 "" ""))
15802 (set (match_operand 1 "memory_operand" "")
15803 (match_operand 3 "memory_operand" ""))
15804 (use (match_dup 4))])]
15806 "ix86_current_function_needs_cld = 1;")
15808 (define_insn "*rep_movdi_rex64"
15809 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15810 (set (match_operand:DI 0 "register_operand" "=D")
15811 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15813 (match_operand:DI 3 "register_operand" "0")))
15814 (set (match_operand:DI 1 "register_operand" "=S")
15815 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15816 (match_operand:DI 4 "register_operand" "1")))
15817 (set (mem:BLK (match_dup 3))
15818 (mem:BLK (match_dup 4)))
15819 (use (match_dup 5))]
15821 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15823 [(set_attr "type" "str")
15824 (set_attr "prefix_rep" "1")
15825 (set_attr "memory" "both")
15826 (set_attr "mode" "DI")])
15828 (define_insn "*rep_movsi"
15829 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15830 (set (match_operand:P 0 "register_operand" "=D")
15831 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15833 (match_operand:P 3 "register_operand" "0")))
15834 (set (match_operand:P 1 "register_operand" "=S")
15835 (plus:P (ashift:P (match_dup 5) (const_int 2))
15836 (match_operand:P 4 "register_operand" "1")))
15837 (set (mem:BLK (match_dup 3))
15838 (mem:BLK (match_dup 4)))
15839 (use (match_dup 5))]
15840 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15841 "rep{%;} movs{l|d}"
15842 [(set_attr "type" "str")
15843 (set_attr "prefix_rep" "1")
15844 (set_attr "memory" "both")
15845 (set_attr "mode" "SI")])
15847 (define_insn "*rep_movqi"
15848 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15849 (set (match_operand:P 0 "register_operand" "=D")
15850 (plus:P (match_operand:P 3 "register_operand" "0")
15851 (match_operand:P 5 "register_operand" "2")))
15852 (set (match_operand:P 1 "register_operand" "=S")
15853 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15854 (set (mem:BLK (match_dup 3))
15855 (mem:BLK (match_dup 4)))
15856 (use (match_dup 5))]
15857 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15859 [(set_attr "type" "str")
15860 (set_attr "prefix_rep" "1")
15861 (set_attr "memory" "both")
15862 (set_attr "mode" "QI")])
15864 (define_expand "setmem<mode>"
15865 [(use (match_operand:BLK 0 "memory_operand" ""))
15866 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15867 (use (match_operand:QI 2 "nonmemory_operand" ""))
15868 (use (match_operand 3 "const_int_operand" ""))
15869 (use (match_operand:SI 4 "const_int_operand" ""))
15870 (use (match_operand:SI 5 "const_int_operand" ""))]
15873 if (ix86_expand_setmem (operands[0], operands[1],
15874 operands[2], operands[3],
15875 operands[4], operands[5]))
15881 ;; Most CPUs don't like single string operations
15882 ;; Handle this case here to simplify previous expander.
15884 (define_expand "strset"
15885 [(set (match_operand 1 "memory_operand" "")
15886 (match_operand 2 "register_operand" ""))
15887 (parallel [(set (match_operand 0 "register_operand" "")
15889 (clobber (reg:CC FLAGS_REG))])]
15892 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15893 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15895 /* If .md ever supports :P for Pmode, this can be directly
15896 in the pattern above. */
15897 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15898 GEN_INT (GET_MODE_SIZE (GET_MODE
15900 /* Can't use this if the user has appropriated eax or edi. */
15901 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15902 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15904 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15910 (define_expand "strset_singleop"
15911 [(parallel [(set (match_operand 1 "memory_operand" "")
15912 (match_operand 2 "register_operand" ""))
15913 (set (match_operand 0 "register_operand" "")
15914 (match_operand 3 "" ""))
15915 (unspec [(const_int 0)] UNSPEC_STOS)])]
15917 "ix86_current_function_needs_cld = 1;")
15919 (define_insn "*strsetdi_rex_1"
15920 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15921 (match_operand:DI 2 "register_operand" "a"))
15922 (set (match_operand:DI 0 "register_operand" "=D")
15923 (plus:DI (match_dup 1)
15925 (unspec [(const_int 0)] UNSPEC_STOS)]
15927 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15929 [(set_attr "type" "str")
15930 (set_attr "memory" "store")
15931 (set_attr "mode" "DI")])
15933 (define_insn "*strsetsi_1"
15934 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15935 (match_operand:SI 2 "register_operand" "a"))
15936 (set (match_operand:P 0 "register_operand" "=D")
15937 (plus:P (match_dup 1)
15939 (unspec [(const_int 0)] UNSPEC_STOS)]
15940 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15942 [(set_attr "type" "str")
15943 (set_attr "memory" "store")
15944 (set_attr "mode" "SI")])
15946 (define_insn "*strsethi_1"
15947 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15948 (match_operand:HI 2 "register_operand" "a"))
15949 (set (match_operand:P 0 "register_operand" "=D")
15950 (plus:P (match_dup 1)
15952 (unspec [(const_int 0)] UNSPEC_STOS)]
15953 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15955 [(set_attr "type" "str")
15956 (set_attr "memory" "store")
15957 (set_attr "mode" "HI")])
15959 (define_insn "*strsetqi_1"
15960 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15961 (match_operand:QI 2 "register_operand" "a"))
15962 (set (match_operand:P 0 "register_operand" "=D")
15963 (plus:P (match_dup 1)
15965 (unspec [(const_int 0)] UNSPEC_STOS)]
15966 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15968 [(set_attr "type" "str")
15969 (set_attr "memory" "store")
15970 (set (attr "prefix_rex")
15972 (match_test "<P:MODE>mode == DImode")
15974 (const_string "*")))
15975 (set_attr "mode" "QI")])
15977 (define_expand "rep_stos"
15978 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15979 (set (match_operand 0 "register_operand" "")
15980 (match_operand 4 "" ""))
15981 (set (match_operand 2 "memory_operand" "") (const_int 0))
15982 (use (match_operand 3 "register_operand" ""))
15983 (use (match_dup 1))])]
15985 "ix86_current_function_needs_cld = 1;")
15987 (define_insn "*rep_stosdi_rex64"
15988 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15989 (set (match_operand:DI 0 "register_operand" "=D")
15990 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15992 (match_operand:DI 3 "register_operand" "0")))
15993 (set (mem:BLK (match_dup 3))
15995 (use (match_operand:DI 2 "register_operand" "a"))
15996 (use (match_dup 4))]
15998 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16000 [(set_attr "type" "str")
16001 (set_attr "prefix_rep" "1")
16002 (set_attr "memory" "store")
16003 (set_attr "mode" "DI")])
16005 (define_insn "*rep_stossi"
16006 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16007 (set (match_operand:P 0 "register_operand" "=D")
16008 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16010 (match_operand:P 3 "register_operand" "0")))
16011 (set (mem:BLK (match_dup 3))
16013 (use (match_operand:SI 2 "register_operand" "a"))
16014 (use (match_dup 4))]
16015 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16016 "rep{%;} stos{l|d}"
16017 [(set_attr "type" "str")
16018 (set_attr "prefix_rep" "1")
16019 (set_attr "memory" "store")
16020 (set_attr "mode" "SI")])
16022 (define_insn "*rep_stosqi"
16023 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16024 (set (match_operand:P 0 "register_operand" "=D")
16025 (plus:P (match_operand:P 3 "register_operand" "0")
16026 (match_operand:P 4 "register_operand" "1")))
16027 (set (mem:BLK (match_dup 3))
16029 (use (match_operand:QI 2 "register_operand" "a"))
16030 (use (match_dup 4))]
16031 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16033 [(set_attr "type" "str")
16034 (set_attr "prefix_rep" "1")
16035 (set_attr "memory" "store")
16036 (set (attr "prefix_rex")
16038 (match_test "<P:MODE>mode == DImode")
16040 (const_string "*")))
16041 (set_attr "mode" "QI")])
16043 (define_expand "cmpstrnsi"
16044 [(set (match_operand:SI 0 "register_operand" "")
16045 (compare:SI (match_operand:BLK 1 "general_operand" "")
16046 (match_operand:BLK 2 "general_operand" "")))
16047 (use (match_operand 3 "general_operand" ""))
16048 (use (match_operand 4 "immediate_operand" ""))]
16051 rtx addr1, addr2, out, outlow, count, countreg, align;
16053 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16056 /* Can't use this if the user has appropriated ecx, esi or edi. */
16057 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16062 out = gen_reg_rtx (SImode);
16064 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16065 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16066 if (addr1 != XEXP (operands[1], 0))
16067 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16068 if (addr2 != XEXP (operands[2], 0))
16069 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16071 count = operands[3];
16072 countreg = ix86_zero_extend_to_Pmode (count);
16074 /* %%% Iff we are testing strict equality, we can use known alignment
16075 to good advantage. This may be possible with combine, particularly
16076 once cc0 is dead. */
16077 align = operands[4];
16079 if (CONST_INT_P (count))
16081 if (INTVAL (count) == 0)
16083 emit_move_insn (operands[0], const0_rtx);
16086 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16087 operands[1], operands[2]));
16091 rtx (*gen_cmp) (rtx, rtx);
16093 gen_cmp = (TARGET_64BIT
16094 ? gen_cmpdi_1 : gen_cmpsi_1);
16096 emit_insn (gen_cmp (countreg, countreg));
16097 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16098 operands[1], operands[2]));
16101 outlow = gen_lowpart (QImode, out);
16102 emit_insn (gen_cmpintqi (outlow));
16103 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16105 if (operands[0] != out)
16106 emit_move_insn (operands[0], out);
16111 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16113 (define_expand "cmpintqi"
16114 [(set (match_dup 1)
16115 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16117 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16118 (parallel [(set (match_operand:QI 0 "register_operand" "")
16119 (minus:QI (match_dup 1)
16121 (clobber (reg:CC FLAGS_REG))])]
16124 operands[1] = gen_reg_rtx (QImode);
16125 operands[2] = gen_reg_rtx (QImode);
16128 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16129 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16131 (define_expand "cmpstrnqi_nz_1"
16132 [(parallel [(set (reg:CC FLAGS_REG)
16133 (compare:CC (match_operand 4 "memory_operand" "")
16134 (match_operand 5 "memory_operand" "")))
16135 (use (match_operand 2 "register_operand" ""))
16136 (use (match_operand:SI 3 "immediate_operand" ""))
16137 (clobber (match_operand 0 "register_operand" ""))
16138 (clobber (match_operand 1 "register_operand" ""))
16139 (clobber (match_dup 2))])]
16141 "ix86_current_function_needs_cld = 1;")
16143 (define_insn "*cmpstrnqi_nz_1"
16144 [(set (reg:CC FLAGS_REG)
16145 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16146 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16147 (use (match_operand:P 6 "register_operand" "2"))
16148 (use (match_operand:SI 3 "immediate_operand" "i"))
16149 (clobber (match_operand:P 0 "register_operand" "=S"))
16150 (clobber (match_operand:P 1 "register_operand" "=D"))
16151 (clobber (match_operand:P 2 "register_operand" "=c"))]
16152 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16154 [(set_attr "type" "str")
16155 (set_attr "mode" "QI")
16156 (set (attr "prefix_rex")
16158 (match_test "<P:MODE>mode == DImode")
16160 (const_string "*")))
16161 (set_attr "prefix_rep" "1")])
16163 ;; The same, but the count is not known to not be zero.
16165 (define_expand "cmpstrnqi_1"
16166 [(parallel [(set (reg:CC FLAGS_REG)
16167 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16169 (compare:CC (match_operand 4 "memory_operand" "")
16170 (match_operand 5 "memory_operand" ""))
16172 (use (match_operand:SI 3 "immediate_operand" ""))
16173 (use (reg:CC FLAGS_REG))
16174 (clobber (match_operand 0 "register_operand" ""))
16175 (clobber (match_operand 1 "register_operand" ""))
16176 (clobber (match_dup 2))])]
16178 "ix86_current_function_needs_cld = 1;")
16180 (define_insn "*cmpstrnqi_1"
16181 [(set (reg:CC FLAGS_REG)
16182 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16184 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16185 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16187 (use (match_operand:SI 3 "immediate_operand" "i"))
16188 (use (reg:CC FLAGS_REG))
16189 (clobber (match_operand:P 0 "register_operand" "=S"))
16190 (clobber (match_operand:P 1 "register_operand" "=D"))
16191 (clobber (match_operand:P 2 "register_operand" "=c"))]
16192 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16194 [(set_attr "type" "str")
16195 (set_attr "mode" "QI")
16196 (set (attr "prefix_rex")
16198 (match_test "<P:MODE>mode == DImode")
16200 (const_string "*")))
16201 (set_attr "prefix_rep" "1")])
16203 (define_expand "strlen<mode>"
16204 [(set (match_operand:P 0 "register_operand" "")
16205 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16206 (match_operand:QI 2 "immediate_operand" "")
16207 (match_operand 3 "immediate_operand" "")]
16211 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16217 (define_expand "strlenqi_1"
16218 [(parallel [(set (match_operand 0 "register_operand" "")
16219 (match_operand 2 "" ""))
16220 (clobber (match_operand 1 "register_operand" ""))
16221 (clobber (reg:CC FLAGS_REG))])]
16223 "ix86_current_function_needs_cld = 1;")
16225 (define_insn "*strlenqi_1"
16226 [(set (match_operand:P 0 "register_operand" "=&c")
16227 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16228 (match_operand:QI 2 "register_operand" "a")
16229 (match_operand:P 3 "immediate_operand" "i")
16230 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16231 (clobber (match_operand:P 1 "register_operand" "=D"))
16232 (clobber (reg:CC FLAGS_REG))]
16233 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16235 [(set_attr "type" "str")
16236 (set_attr "mode" "QI")
16237 (set (attr "prefix_rex")
16239 (match_test "<P:MODE>mode == DImode")
16241 (const_string "*")))
16242 (set_attr "prefix_rep" "1")])
16244 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16245 ;; handled in combine, but it is not currently up to the task.
16246 ;; When used for their truth value, the cmpstrn* expanders generate
16255 ;; The intermediate three instructions are unnecessary.
16257 ;; This one handles cmpstrn*_nz_1...
16260 (set (reg:CC FLAGS_REG)
16261 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16262 (mem:BLK (match_operand 5 "register_operand" ""))))
16263 (use (match_operand 6 "register_operand" ""))
16264 (use (match_operand:SI 3 "immediate_operand" ""))
16265 (clobber (match_operand 0 "register_operand" ""))
16266 (clobber (match_operand 1 "register_operand" ""))
16267 (clobber (match_operand 2 "register_operand" ""))])
16268 (set (match_operand:QI 7 "register_operand" "")
16269 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16270 (set (match_operand:QI 8 "register_operand" "")
16271 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16272 (set (reg FLAGS_REG)
16273 (compare (match_dup 7) (match_dup 8)))
16275 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16277 (set (reg:CC FLAGS_REG)
16278 (compare:CC (mem:BLK (match_dup 4))
16279 (mem:BLK (match_dup 5))))
16280 (use (match_dup 6))
16281 (use (match_dup 3))
16282 (clobber (match_dup 0))
16283 (clobber (match_dup 1))
16284 (clobber (match_dup 2))])])
16286 ;; ...and this one handles cmpstrn*_1.
16289 (set (reg:CC FLAGS_REG)
16290 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16292 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16293 (mem:BLK (match_operand 5 "register_operand" "")))
16295 (use (match_operand:SI 3 "immediate_operand" ""))
16296 (use (reg:CC FLAGS_REG))
16297 (clobber (match_operand 0 "register_operand" ""))
16298 (clobber (match_operand 1 "register_operand" ""))
16299 (clobber (match_operand 2 "register_operand" ""))])
16300 (set (match_operand:QI 7 "register_operand" "")
16301 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16302 (set (match_operand:QI 8 "register_operand" "")
16303 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16304 (set (reg FLAGS_REG)
16305 (compare (match_dup 7) (match_dup 8)))
16307 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16309 (set (reg:CC FLAGS_REG)
16310 (if_then_else:CC (ne (match_dup 6)
16312 (compare:CC (mem:BLK (match_dup 4))
16313 (mem:BLK (match_dup 5)))
16315 (use (match_dup 3))
16316 (use (reg:CC FLAGS_REG))
16317 (clobber (match_dup 0))
16318 (clobber (match_dup 1))
16319 (clobber (match_dup 2))])])
16321 ;; Conditional move instructions.
16323 (define_expand "mov<mode>cc"
16324 [(set (match_operand:SWIM 0 "register_operand" "")
16325 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16326 (match_operand:SWIM 2 "<general_operand>" "")
16327 (match_operand:SWIM 3 "<general_operand>" "")))]
16329 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16331 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16332 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16333 ;; So just document what we're doing explicitly.
16335 (define_expand "x86_mov<mode>cc_0_m1"
16337 [(set (match_operand:SWI48 0 "register_operand" "")
16338 (if_then_else:SWI48
16339 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16340 [(match_operand 1 "flags_reg_operand" "")
16344 (clobber (reg:CC FLAGS_REG))])])
16346 (define_insn "*x86_mov<mode>cc_0_m1"
16347 [(set (match_operand:SWI48 0 "register_operand" "=r")
16348 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16349 [(reg FLAGS_REG) (const_int 0)])
16352 (clobber (reg:CC FLAGS_REG))]
16354 "sbb{<imodesuffix>}\t%0, %0"
16355 ; Since we don't have the proper number of operands for an alu insn,
16356 ; fill in all the blanks.
16357 [(set_attr "type" "alu")
16358 (set_attr "use_carry" "1")
16359 (set_attr "pent_pair" "pu")
16360 (set_attr "memory" "none")
16361 (set_attr "imm_disp" "false")
16362 (set_attr "mode" "<MODE>")
16363 (set_attr "length_immediate" "0")])
16365 (define_insn "*x86_mov<mode>cc_0_m1_se"
16366 [(set (match_operand:SWI48 0 "register_operand" "=r")
16367 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16368 [(reg FLAGS_REG) (const_int 0)])
16371 (clobber (reg:CC FLAGS_REG))]
16373 "sbb{<imodesuffix>}\t%0, %0"
16374 [(set_attr "type" "alu")
16375 (set_attr "use_carry" "1")
16376 (set_attr "pent_pair" "pu")
16377 (set_attr "memory" "none")
16378 (set_attr "imm_disp" "false")
16379 (set_attr "mode" "<MODE>")
16380 (set_attr "length_immediate" "0")])
16382 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16383 [(set (match_operand:SWI48 0 "register_operand" "=r")
16384 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16385 [(reg FLAGS_REG) (const_int 0)])))
16386 (clobber (reg:CC FLAGS_REG))]
16388 "sbb{<imodesuffix>}\t%0, %0"
16389 [(set_attr "type" "alu")
16390 (set_attr "use_carry" "1")
16391 (set_attr "pent_pair" "pu")
16392 (set_attr "memory" "none")
16393 (set_attr "imm_disp" "false")
16394 (set_attr "mode" "<MODE>")
16395 (set_attr "length_immediate" "0")])
16397 (define_insn "*mov<mode>cc_noc"
16398 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16399 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16400 [(reg FLAGS_REG) (const_int 0)])
16401 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16402 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16403 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16405 cmov%O2%C1\t{%2, %0|%0, %2}
16406 cmov%O2%c1\t{%3, %0|%0, %3}"
16407 [(set_attr "type" "icmov")
16408 (set_attr "mode" "<MODE>")])
16410 (define_insn "*movqicc_noc"
16411 [(set (match_operand:QI 0 "register_operand" "=r,r")
16412 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16413 [(reg FLAGS_REG) (const_int 0)])
16414 (match_operand:QI 2 "register_operand" "r,0")
16415 (match_operand:QI 3 "register_operand" "0,r")))]
16416 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16418 [(set_attr "type" "icmov")
16419 (set_attr "mode" "QI")])
16422 [(set (match_operand 0 "register_operand")
16423 (if_then_else (match_operator 1 "ix86_comparison_operator"
16424 [(reg FLAGS_REG) (const_int 0)])
16425 (match_operand 2 "register_operand")
16426 (match_operand 3 "register_operand")))]
16427 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16428 && (GET_MODE (operands[0]) == QImode
16429 || GET_MODE (operands[0]) == HImode)
16430 && reload_completed"
16431 [(set (match_dup 0)
16432 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16434 operands[0] = gen_lowpart (SImode, operands[0]);
16435 operands[2] = gen_lowpart (SImode, operands[2]);
16436 operands[3] = gen_lowpart (SImode, operands[3]);
16439 (define_expand "mov<mode>cc"
16440 [(set (match_operand:X87MODEF 0 "register_operand" "")
16441 (if_then_else:X87MODEF
16442 (match_operand 1 "ix86_fp_comparison_operator" "")
16443 (match_operand:X87MODEF 2 "register_operand" "")
16444 (match_operand:X87MODEF 3 "register_operand" "")))]
16445 "(TARGET_80387 && TARGET_CMOVE)
16446 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16447 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16449 (define_insn "*movxfcc_1"
16450 [(set (match_operand:XF 0 "register_operand" "=f,f")
16451 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16452 [(reg FLAGS_REG) (const_int 0)])
16453 (match_operand:XF 2 "register_operand" "f,0")
16454 (match_operand:XF 3 "register_operand" "0,f")))]
16455 "TARGET_80387 && TARGET_CMOVE"
16457 fcmov%F1\t{%2, %0|%0, %2}
16458 fcmov%f1\t{%3, %0|%0, %3}"
16459 [(set_attr "type" "fcmov")
16460 (set_attr "mode" "XF")])
16462 (define_insn "*movdfcc_1_rex64"
16463 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16464 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16465 [(reg FLAGS_REG) (const_int 0)])
16466 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16467 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16468 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16469 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16471 fcmov%F1\t{%2, %0|%0, %2}
16472 fcmov%f1\t{%3, %0|%0, %3}
16473 cmov%O2%C1\t{%2, %0|%0, %2}
16474 cmov%O2%c1\t{%3, %0|%0, %3}"
16475 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16476 (set_attr "mode" "DF,DF,DI,DI")])
16478 (define_insn "*movdfcc_1"
16479 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16480 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16481 [(reg FLAGS_REG) (const_int 0)])
16482 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16483 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16484 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16485 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16487 fcmov%F1\t{%2, %0|%0, %2}
16488 fcmov%f1\t{%3, %0|%0, %3}
16491 [(set_attr "type" "fcmov,fcmov,multi,multi")
16492 (set_attr "mode" "DF,DF,DI,DI")])
16495 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16496 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16497 [(reg FLAGS_REG) (const_int 0)])
16498 (match_operand:DF 2 "nonimmediate_operand")
16499 (match_operand:DF 3 "nonimmediate_operand")))]
16500 "!TARGET_64BIT && reload_completed"
16501 [(set (match_dup 2)
16502 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16504 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16506 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16507 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16510 (define_insn "*movsfcc_1_387"
16511 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16512 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16513 [(reg FLAGS_REG) (const_int 0)])
16514 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16515 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16516 "TARGET_80387 && TARGET_CMOVE
16517 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16519 fcmov%F1\t{%2, %0|%0, %2}
16520 fcmov%f1\t{%3, %0|%0, %3}
16521 cmov%O2%C1\t{%2, %0|%0, %2}
16522 cmov%O2%c1\t{%3, %0|%0, %3}"
16523 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16524 (set_attr "mode" "SF,SF,SI,SI")])
16526 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16527 ;; the scalar versions to have only XMM registers as operands.
16529 ;; XOP conditional move
16530 (define_insn "*xop_pcmov_<mode>"
16531 [(set (match_operand:MODEF 0 "register_operand" "=x")
16532 (if_then_else:MODEF
16533 (match_operand:MODEF 1 "register_operand" "x")
16534 (match_operand:MODEF 2 "register_operand" "x")
16535 (match_operand:MODEF 3 "register_operand" "x")))]
16537 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16538 [(set_attr "type" "sse4arg")])
16540 ;; These versions of the min/max patterns are intentionally ignorant of
16541 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16542 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16543 ;; are undefined in this condition, we're certain this is correct.
16545 (define_insn "<code><mode>3"
16546 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16548 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16549 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16550 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16552 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16553 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16554 [(set_attr "isa" "noavx,avx")
16555 (set_attr "prefix" "orig,vex")
16556 (set_attr "type" "sseadd")
16557 (set_attr "mode" "<MODE>")])
16559 ;; These versions of the min/max patterns implement exactly the operations
16560 ;; min = (op1 < op2 ? op1 : op2)
16561 ;; max = (!(op1 < op2) ? op1 : op2)
16562 ;; Their operands are not commutative, and thus they may be used in the
16563 ;; presence of -0.0 and NaN.
16565 (define_insn "*ieee_smin<mode>3"
16566 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16568 [(match_operand:MODEF 1 "register_operand" "0,x")
16569 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16571 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16573 min<ssemodesuffix>\t{%2, %0|%0, %2}
16574 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16575 [(set_attr "isa" "noavx,avx")
16576 (set_attr "prefix" "orig,vex")
16577 (set_attr "type" "sseadd")
16578 (set_attr "mode" "<MODE>")])
16580 (define_insn "*ieee_smax<mode>3"
16581 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16583 [(match_operand:MODEF 1 "register_operand" "0,x")
16584 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16586 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16588 max<ssemodesuffix>\t{%2, %0|%0, %2}
16589 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16590 [(set_attr "isa" "noavx,avx")
16591 (set_attr "prefix" "orig,vex")
16592 (set_attr "type" "sseadd")
16593 (set_attr "mode" "<MODE>")])
16595 ;; Make two stack loads independent:
16597 ;; fld %st(0) -> fld bb
16598 ;; fmul bb fmul %st(1), %st
16600 ;; Actually we only match the last two instructions for simplicity.
16602 [(set (match_operand 0 "fp_register_operand" "")
16603 (match_operand 1 "fp_register_operand" ""))
16605 (match_operator 2 "binary_fp_operator"
16607 (match_operand 3 "memory_operand" "")]))]
16608 "REGNO (operands[0]) != REGNO (operands[1])"
16609 [(set (match_dup 0) (match_dup 3))
16610 (set (match_dup 0) (match_dup 4))]
16612 ;; The % modifier is not operational anymore in peephole2's, so we have to
16613 ;; swap the operands manually in the case of addition and multiplication.
16617 if (COMMUTATIVE_ARITH_P (operands[2]))
16618 op0 = operands[0], op1 = operands[1];
16620 op0 = operands[1], op1 = operands[0];
16622 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16623 GET_MODE (operands[2]),
16627 ;; Conditional addition patterns
16628 (define_expand "add<mode>cc"
16629 [(match_operand:SWI 0 "register_operand" "")
16630 (match_operand 1 "ordered_comparison_operator" "")
16631 (match_operand:SWI 2 "register_operand" "")
16632 (match_operand:SWI 3 "const_int_operand" "")]
16634 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16636 ;; Misc patterns (?)
16638 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16639 ;; Otherwise there will be nothing to keep
16641 ;; [(set (reg ebp) (reg esp))]
16642 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16643 ;; (clobber (eflags)]
16644 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16646 ;; in proper program order.
16648 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16649 [(set (match_operand:P 0 "register_operand" "=r,r")
16650 (plus:P (match_operand:P 1 "register_operand" "0,r")
16651 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16652 (clobber (reg:CC FLAGS_REG))
16653 (clobber (mem:BLK (scratch)))]
16656 switch (get_attr_type (insn))
16659 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16662 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16663 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16664 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16666 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16669 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16670 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16673 [(set (attr "type")
16674 (cond [(and (eq_attr "alternative" "0")
16675 (not (match_test "TARGET_OPT_AGU")))
16676 (const_string "alu")
16677 (match_operand:<MODE> 2 "const0_operand" "")
16678 (const_string "imov")
16680 (const_string "lea")))
16681 (set (attr "length_immediate")
16682 (cond [(eq_attr "type" "imov")
16684 (and (eq_attr "type" "alu")
16685 (match_operand 2 "const128_operand" ""))
16688 (const_string "*")))
16689 (set_attr "mode" "<MODE>")])
16691 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16692 [(set (match_operand:P 0 "register_operand" "=r")
16693 (minus:P (match_operand:P 1 "register_operand" "0")
16694 (match_operand:P 2 "register_operand" "r")))
16695 (clobber (reg:CC FLAGS_REG))
16696 (clobber (mem:BLK (scratch)))]
16698 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16699 [(set_attr "type" "alu")
16700 (set_attr "mode" "<MODE>")])
16702 (define_insn "allocate_stack_worker_probe_<mode>"
16703 [(set (match_operand:P 0 "register_operand" "=a")
16704 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16705 UNSPECV_STACK_PROBE))
16706 (clobber (reg:CC FLAGS_REG))]
16707 "ix86_target_stack_probe ()"
16708 "call\t___chkstk_ms"
16709 [(set_attr "type" "multi")
16710 (set_attr "length" "5")])
16712 (define_expand "allocate_stack"
16713 [(match_operand 0 "register_operand" "")
16714 (match_operand 1 "general_operand" "")]
16715 "ix86_target_stack_probe ()"
16719 #ifndef CHECK_STACK_LIMIT
16720 #define CHECK_STACK_LIMIT 0
16723 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16724 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16726 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16727 stack_pointer_rtx, 0, OPTAB_DIRECT);
16728 if (x != stack_pointer_rtx)
16729 emit_move_insn (stack_pointer_rtx, x);
16733 x = copy_to_mode_reg (Pmode, operands[1]);
16735 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16737 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16738 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16739 stack_pointer_rtx, 0, OPTAB_DIRECT);
16740 if (x != stack_pointer_rtx)
16741 emit_move_insn (stack_pointer_rtx, x);
16744 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16748 ;; Use IOR for stack probes, this is shorter.
16749 (define_expand "probe_stack"
16750 [(match_operand 0 "memory_operand" "")]
16753 rtx (*gen_ior3) (rtx, rtx, rtx);
16755 gen_ior3 = (GET_MODE (operands[0]) == DImode
16756 ? gen_iordi3 : gen_iorsi3);
16758 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16762 (define_insn "adjust_stack_and_probe<mode>"
16763 [(set (match_operand:P 0 "register_operand" "=r")
16764 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16765 UNSPECV_PROBE_STACK_RANGE))
16766 (set (reg:P SP_REG)
16767 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16768 (clobber (reg:CC FLAGS_REG))
16769 (clobber (mem:BLK (scratch)))]
16771 "* return output_adjust_stack_and_probe (operands[0]);"
16772 [(set_attr "type" "multi")])
16774 (define_insn "probe_stack_range<mode>"
16775 [(set (match_operand:P 0 "register_operand" "=r")
16776 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16777 (match_operand:P 2 "const_int_operand" "n")]
16778 UNSPECV_PROBE_STACK_RANGE))
16779 (clobber (reg:CC FLAGS_REG))]
16781 "* return output_probe_stack_range (operands[0], operands[2]);"
16782 [(set_attr "type" "multi")])
16784 (define_expand "builtin_setjmp_receiver"
16785 [(label_ref (match_operand 0 "" ""))]
16786 "!TARGET_64BIT && flag_pic"
16792 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16793 rtx label_rtx = gen_label_rtx ();
16794 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16795 xops[0] = xops[1] = picreg;
16796 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16797 ix86_expand_binary_operator (MINUS, SImode, xops);
16801 emit_insn (gen_set_got (pic_offset_table_rtx));
16805 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16808 [(set (match_operand 0 "register_operand" "")
16809 (match_operator 3 "promotable_binary_operator"
16810 [(match_operand 1 "register_operand" "")
16811 (match_operand 2 "aligned_operand" "")]))
16812 (clobber (reg:CC FLAGS_REG))]
16813 "! TARGET_PARTIAL_REG_STALL && reload_completed
16814 && ((GET_MODE (operands[0]) == HImode
16815 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16816 /* ??? next two lines just !satisfies_constraint_K (...) */
16817 || !CONST_INT_P (operands[2])
16818 || satisfies_constraint_K (operands[2])))
16819 || (GET_MODE (operands[0]) == QImode
16820 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16821 [(parallel [(set (match_dup 0)
16822 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16823 (clobber (reg:CC FLAGS_REG))])]
16825 operands[0] = gen_lowpart (SImode, operands[0]);
16826 operands[1] = gen_lowpart (SImode, operands[1]);
16827 if (GET_CODE (operands[3]) != ASHIFT)
16828 operands[2] = gen_lowpart (SImode, operands[2]);
16829 PUT_MODE (operands[3], SImode);
16832 ; Promote the QImode tests, as i386 has encoding of the AND
16833 ; instruction with 32-bit sign-extended immediate and thus the
16834 ; instruction size is unchanged, except in the %eax case for
16835 ; which it is increased by one byte, hence the ! optimize_size.
16837 [(set (match_operand 0 "flags_reg_operand" "")
16838 (match_operator 2 "compare_operator"
16839 [(and (match_operand 3 "aligned_operand" "")
16840 (match_operand 4 "const_int_operand" ""))
16842 (set (match_operand 1 "register_operand" "")
16843 (and (match_dup 3) (match_dup 4)))]
16844 "! TARGET_PARTIAL_REG_STALL && reload_completed
16845 && optimize_insn_for_speed_p ()
16846 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16847 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16848 /* Ensure that the operand will remain sign-extended immediate. */
16849 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16850 [(parallel [(set (match_dup 0)
16851 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16854 (and:SI (match_dup 3) (match_dup 4)))])]
16857 = gen_int_mode (INTVAL (operands[4])
16858 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16859 operands[1] = gen_lowpart (SImode, operands[1]);
16860 operands[3] = gen_lowpart (SImode, operands[3]);
16863 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16864 ; the TEST instruction with 32-bit sign-extended immediate and thus
16865 ; the instruction size would at least double, which is not what we
16866 ; want even with ! optimize_size.
16868 [(set (match_operand 0 "flags_reg_operand" "")
16869 (match_operator 1 "compare_operator"
16870 [(and (match_operand:HI 2 "aligned_operand" "")
16871 (match_operand:HI 3 "const_int_operand" ""))
16873 "! TARGET_PARTIAL_REG_STALL && reload_completed
16874 && ! TARGET_FAST_PREFIX
16875 && optimize_insn_for_speed_p ()
16876 /* Ensure that the operand will remain sign-extended immediate. */
16877 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16878 [(set (match_dup 0)
16879 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16883 = gen_int_mode (INTVAL (operands[3])
16884 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16885 operands[2] = gen_lowpart (SImode, operands[2]);
16889 [(set (match_operand 0 "register_operand" "")
16890 (neg (match_operand 1 "register_operand" "")))
16891 (clobber (reg:CC FLAGS_REG))]
16892 "! TARGET_PARTIAL_REG_STALL && reload_completed
16893 && (GET_MODE (operands[0]) == HImode
16894 || (GET_MODE (operands[0]) == QImode
16895 && (TARGET_PROMOTE_QImode
16896 || optimize_insn_for_size_p ())))"
16897 [(parallel [(set (match_dup 0)
16898 (neg:SI (match_dup 1)))
16899 (clobber (reg:CC FLAGS_REG))])]
16901 operands[0] = gen_lowpart (SImode, operands[0]);
16902 operands[1] = gen_lowpart (SImode, operands[1]);
16906 [(set (match_operand 0 "register_operand" "")
16907 (not (match_operand 1 "register_operand" "")))]
16908 "! TARGET_PARTIAL_REG_STALL && reload_completed
16909 && (GET_MODE (operands[0]) == HImode
16910 || (GET_MODE (operands[0]) == QImode
16911 && (TARGET_PROMOTE_QImode
16912 || optimize_insn_for_size_p ())))"
16913 [(set (match_dup 0)
16914 (not:SI (match_dup 1)))]
16916 operands[0] = gen_lowpart (SImode, operands[0]);
16917 operands[1] = gen_lowpart (SImode, operands[1]);
16920 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16921 ;; transform a complex memory operation into two memory to register operations.
16923 ;; Don't push memory operands
16925 [(set (match_operand:SWI 0 "push_operand" "")
16926 (match_operand:SWI 1 "memory_operand" ""))
16927 (match_scratch:SWI 2 "<r>")]
16928 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16929 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16930 [(set (match_dup 2) (match_dup 1))
16931 (set (match_dup 0) (match_dup 2))])
16933 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16936 [(set (match_operand:SF 0 "push_operand" "")
16937 (match_operand:SF 1 "memory_operand" ""))
16938 (match_scratch:SF 2 "r")]
16939 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16940 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16941 [(set (match_dup 2) (match_dup 1))
16942 (set (match_dup 0) (match_dup 2))])
16944 ;; Don't move an immediate directly to memory when the instruction
16947 [(match_scratch:SWI124 1 "<r>")
16948 (set (match_operand:SWI124 0 "memory_operand" "")
16950 "optimize_insn_for_speed_p ()
16951 && !TARGET_USE_MOV0
16952 && TARGET_SPLIT_LONG_MOVES
16953 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16954 && peep2_regno_dead_p (0, FLAGS_REG)"
16955 [(parallel [(set (match_dup 2) (const_int 0))
16956 (clobber (reg:CC FLAGS_REG))])
16957 (set (match_dup 0) (match_dup 1))]
16958 "operands[2] = gen_lowpart (SImode, operands[1]);")
16961 [(match_scratch:SWI124 2 "<r>")
16962 (set (match_operand:SWI124 0 "memory_operand" "")
16963 (match_operand:SWI124 1 "immediate_operand" ""))]
16964 "optimize_insn_for_speed_p ()
16965 && TARGET_SPLIT_LONG_MOVES
16966 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16967 [(set (match_dup 2) (match_dup 1))
16968 (set (match_dup 0) (match_dup 2))])
16970 ;; Don't compare memory with zero, load and use a test instead.
16972 [(set (match_operand 0 "flags_reg_operand" "")
16973 (match_operator 1 "compare_operator"
16974 [(match_operand:SI 2 "memory_operand" "")
16976 (match_scratch:SI 3 "r")]
16977 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16978 [(set (match_dup 3) (match_dup 2))
16979 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16981 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16982 ;; Don't split NOTs with a displacement operand, because resulting XOR
16983 ;; will not be pairable anyway.
16985 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16986 ;; represented using a modRM byte. The XOR replacement is long decoded,
16987 ;; so this split helps here as well.
16989 ;; Note: Can't do this as a regular split because we can't get proper
16990 ;; lifetime information then.
16993 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16994 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16995 "optimize_insn_for_speed_p ()
16996 && ((TARGET_NOT_UNPAIRABLE
16997 && (!MEM_P (operands[0])
16998 || !memory_displacement_operand (operands[0], <MODE>mode)))
16999 || (TARGET_NOT_VECTORMODE
17000 && long_memory_operand (operands[0], <MODE>mode)))
17001 && peep2_regno_dead_p (0, FLAGS_REG)"
17002 [(parallel [(set (match_dup 0)
17003 (xor:SWI124 (match_dup 1) (const_int -1)))
17004 (clobber (reg:CC FLAGS_REG))])])
17006 ;; Non pairable "test imm, reg" instructions can be translated to
17007 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17008 ;; byte opcode instead of two, have a short form for byte operands),
17009 ;; so do it for other CPUs as well. Given that the value was dead,
17010 ;; this should not create any new dependencies. Pass on the sub-word
17011 ;; versions if we're concerned about partial register stalls.
17014 [(set (match_operand 0 "flags_reg_operand" "")
17015 (match_operator 1 "compare_operator"
17016 [(and:SI (match_operand:SI 2 "register_operand" "")
17017 (match_operand:SI 3 "immediate_operand" ""))
17019 "ix86_match_ccmode (insn, CCNOmode)
17020 && (true_regnum (operands[2]) != AX_REG
17021 || satisfies_constraint_K (operands[3]))
17022 && peep2_reg_dead_p (1, operands[2])"
17024 [(set (match_dup 0)
17025 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17028 (and:SI (match_dup 2) (match_dup 3)))])])
17030 ;; We don't need to handle HImode case, because it will be promoted to SImode
17031 ;; on ! TARGET_PARTIAL_REG_STALL
17034 [(set (match_operand 0 "flags_reg_operand" "")
17035 (match_operator 1 "compare_operator"
17036 [(and:QI (match_operand:QI 2 "register_operand" "")
17037 (match_operand:QI 3 "immediate_operand" ""))
17039 "! TARGET_PARTIAL_REG_STALL
17040 && ix86_match_ccmode (insn, CCNOmode)
17041 && true_regnum (operands[2]) != AX_REG
17042 && peep2_reg_dead_p (1, operands[2])"
17044 [(set (match_dup 0)
17045 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17048 (and:QI (match_dup 2) (match_dup 3)))])])
17051 [(set (match_operand 0 "flags_reg_operand" "")
17052 (match_operator 1 "compare_operator"
17055 (match_operand 2 "ext_register_operand" "")
17058 (match_operand 3 "const_int_operand" ""))
17060 "! TARGET_PARTIAL_REG_STALL
17061 && ix86_match_ccmode (insn, CCNOmode)
17062 && true_regnum (operands[2]) != AX_REG
17063 && peep2_reg_dead_p (1, operands[2])"
17064 [(parallel [(set (match_dup 0)
17073 (set (zero_extract:SI (match_dup 2)
17081 (match_dup 3)))])])
17083 ;; Don't do logical operations with memory inputs.
17085 [(match_scratch:SI 2 "r")
17086 (parallel [(set (match_operand:SI 0 "register_operand" "")
17087 (match_operator:SI 3 "arith_or_logical_operator"
17089 (match_operand:SI 1 "memory_operand" "")]))
17090 (clobber (reg:CC FLAGS_REG))])]
17091 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17092 [(set (match_dup 2) (match_dup 1))
17093 (parallel [(set (match_dup 0)
17094 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17095 (clobber (reg:CC FLAGS_REG))])])
17098 [(match_scratch:SI 2 "r")
17099 (parallel [(set (match_operand:SI 0 "register_operand" "")
17100 (match_operator:SI 3 "arith_or_logical_operator"
17101 [(match_operand:SI 1 "memory_operand" "")
17103 (clobber (reg:CC FLAGS_REG))])]
17104 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17105 [(set (match_dup 2) (match_dup 1))
17106 (parallel [(set (match_dup 0)
17107 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17108 (clobber (reg:CC FLAGS_REG))])])
17110 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17111 ;; refers to the destination of the load!
17114 [(set (match_operand:SI 0 "register_operand" "")
17115 (match_operand:SI 1 "register_operand" ""))
17116 (parallel [(set (match_dup 0)
17117 (match_operator:SI 3 "commutative_operator"
17119 (match_operand:SI 2 "memory_operand" "")]))
17120 (clobber (reg:CC FLAGS_REG))])]
17121 "REGNO (operands[0]) != REGNO (operands[1])
17122 && GENERAL_REGNO_P (REGNO (operands[0]))
17123 && GENERAL_REGNO_P (REGNO (operands[1]))"
17124 [(set (match_dup 0) (match_dup 4))
17125 (parallel [(set (match_dup 0)
17126 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17127 (clobber (reg:CC FLAGS_REG))])]
17128 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17131 [(set (match_operand 0 "register_operand" "")
17132 (match_operand 1 "register_operand" ""))
17134 (match_operator 3 "commutative_operator"
17136 (match_operand 2 "memory_operand" "")]))]
17137 "REGNO (operands[0]) != REGNO (operands[1])
17138 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17139 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17140 [(set (match_dup 0) (match_dup 2))
17142 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17144 ; Don't do logical operations with memory outputs
17146 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17147 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17148 ; the same decoder scheduling characteristics as the original.
17151 [(match_scratch:SI 2 "r")
17152 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17153 (match_operator:SI 3 "arith_or_logical_operator"
17155 (match_operand:SI 1 "nonmemory_operand" "")]))
17156 (clobber (reg:CC FLAGS_REG))])]
17157 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17158 /* Do not split stack checking probes. */
17159 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17160 [(set (match_dup 2) (match_dup 0))
17161 (parallel [(set (match_dup 2)
17162 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17163 (clobber (reg:CC FLAGS_REG))])
17164 (set (match_dup 0) (match_dup 2))])
17167 [(match_scratch:SI 2 "r")
17168 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17169 (match_operator:SI 3 "arith_or_logical_operator"
17170 [(match_operand:SI 1 "nonmemory_operand" "")
17172 (clobber (reg:CC FLAGS_REG))])]
17173 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17174 /* Do not split stack checking probes. */
17175 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17176 [(set (match_dup 2) (match_dup 0))
17177 (parallel [(set (match_dup 2)
17178 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17179 (clobber (reg:CC FLAGS_REG))])
17180 (set (match_dup 0) (match_dup 2))])
17182 ;; Attempt to use arith or logical operations with memory outputs with
17183 ;; setting of flags.
17185 [(set (match_operand:SWI 0 "register_operand" "")
17186 (match_operand:SWI 1 "memory_operand" ""))
17187 (parallel [(set (match_dup 0)
17188 (match_operator:SWI 3 "plusminuslogic_operator"
17190 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17191 (clobber (reg:CC FLAGS_REG))])
17192 (set (match_dup 1) (match_dup 0))
17193 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17194 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17195 && peep2_reg_dead_p (4, operands[0])
17196 && !reg_overlap_mentioned_p (operands[0], operands[1])
17197 && !reg_overlap_mentioned_p (operands[0], operands[2])
17198 && (<MODE>mode != QImode
17199 || immediate_operand (operands[2], QImode)
17200 || q_regs_operand (operands[2], QImode))
17201 && ix86_match_ccmode (peep2_next_insn (3),
17202 (GET_CODE (operands[3]) == PLUS
17203 || GET_CODE (operands[3]) == MINUS)
17204 ? CCGOCmode : CCNOmode)"
17205 [(parallel [(set (match_dup 4) (match_dup 5))
17206 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17207 (match_dup 2)]))])]
17209 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17210 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17211 copy_rtx (operands[1]),
17212 copy_rtx (operands[2]));
17213 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17214 operands[5], const0_rtx);
17218 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17219 (match_operator:SWI 2 "plusminuslogic_operator"
17221 (match_operand:SWI 1 "memory_operand" "")]))
17222 (clobber (reg:CC FLAGS_REG))])
17223 (set (match_dup 1) (match_dup 0))
17224 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17225 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17226 && GET_CODE (operands[2]) != MINUS
17227 && peep2_reg_dead_p (3, operands[0])
17228 && !reg_overlap_mentioned_p (operands[0], operands[1])
17229 && ix86_match_ccmode (peep2_next_insn (2),
17230 GET_CODE (operands[2]) == PLUS
17231 ? CCGOCmode : CCNOmode)"
17232 [(parallel [(set (match_dup 3) (match_dup 4))
17233 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17234 (match_dup 0)]))])]
17236 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17237 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17238 copy_rtx (operands[1]),
17239 copy_rtx (operands[0]));
17240 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17241 operands[4], const0_rtx);
17245 [(set (match_operand:SWI12 0 "register_operand" "")
17246 (match_operand:SWI12 1 "memory_operand" ""))
17247 (parallel [(set (match_operand:SI 4 "register_operand" "")
17248 (match_operator:SI 3 "plusminuslogic_operator"
17250 (match_operand:SI 2 "nonmemory_operand" "")]))
17251 (clobber (reg:CC FLAGS_REG))])
17252 (set (match_dup 1) (match_dup 0))
17253 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17254 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17255 && REG_P (operands[0]) && REG_P (operands[4])
17256 && REGNO (operands[0]) == REGNO (operands[4])
17257 && peep2_reg_dead_p (4, operands[0])
17258 && (<MODE>mode != QImode
17259 || immediate_operand (operands[2], SImode)
17260 || q_regs_operand (operands[2], SImode))
17261 && !reg_overlap_mentioned_p (operands[0], operands[1])
17262 && !reg_overlap_mentioned_p (operands[0], operands[2])
17263 && ix86_match_ccmode (peep2_next_insn (3),
17264 (GET_CODE (operands[3]) == PLUS
17265 || GET_CODE (operands[3]) == MINUS)
17266 ? CCGOCmode : CCNOmode)"
17267 [(parallel [(set (match_dup 4) (match_dup 5))
17268 (set (match_dup 1) (match_dup 6))])]
17270 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17271 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17272 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17273 copy_rtx (operands[1]), operands[2]);
17274 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17275 operands[5], const0_rtx);
17276 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17277 copy_rtx (operands[1]),
17278 copy_rtx (operands[2]));
17281 ;; Attempt to always use XOR for zeroing registers.
17283 [(set (match_operand 0 "register_operand" "")
17284 (match_operand 1 "const0_operand" ""))]
17285 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17286 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17287 && GENERAL_REG_P (operands[0])
17288 && peep2_regno_dead_p (0, FLAGS_REG)"
17289 [(parallel [(set (match_dup 0) (const_int 0))
17290 (clobber (reg:CC FLAGS_REG))])]
17291 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17294 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17296 "(GET_MODE (operands[0]) == QImode
17297 || GET_MODE (operands[0]) == HImode)
17298 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17299 && peep2_regno_dead_p (0, FLAGS_REG)"
17300 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17301 (clobber (reg:CC FLAGS_REG))])])
17303 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17305 [(set (match_operand:SWI248 0 "register_operand" "")
17307 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17308 && peep2_regno_dead_p (0, FLAGS_REG)"
17309 [(parallel [(set (match_dup 0) (const_int -1))
17310 (clobber (reg:CC FLAGS_REG))])]
17312 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17313 operands[0] = gen_lowpart (SImode, operands[0]);
17316 ;; Attempt to convert simple lea to add/shift.
17317 ;; These can be created by move expanders.
17320 [(set (match_operand:SWI48 0 "register_operand" "")
17321 (plus:SWI48 (match_dup 0)
17322 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17323 "peep2_regno_dead_p (0, FLAGS_REG)"
17324 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17325 (clobber (reg:CC FLAGS_REG))])])
17328 [(set (match_operand:SI 0 "register_operand" "")
17329 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17330 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17332 && peep2_regno_dead_p (0, FLAGS_REG)
17333 && REGNO (operands[0]) == REGNO (operands[1])"
17334 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17335 (clobber (reg:CC FLAGS_REG))])]
17336 "operands[2] = gen_lowpart (SImode, operands[2]);")
17339 [(set (match_operand:SWI48 0 "register_operand" "")
17340 (mult:SWI48 (match_dup 0)
17341 (match_operand:SWI48 1 "const_int_operand" "")))]
17342 "exact_log2 (INTVAL (operands[1])) >= 0
17343 && peep2_regno_dead_p (0, FLAGS_REG)"
17344 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17345 (clobber (reg:CC FLAGS_REG))])]
17346 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17349 [(set (match_operand:SI 0 "register_operand" "")
17350 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17351 (match_operand:DI 2 "const_int_operand" "")) 0))]
17353 && exact_log2 (INTVAL (operands[2])) >= 0
17354 && REGNO (operands[0]) == REGNO (operands[1])
17355 && peep2_regno_dead_p (0, FLAGS_REG)"
17356 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17357 (clobber (reg:CC FLAGS_REG))])]
17358 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17360 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17361 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17362 ;; On many CPUs it is also faster, since special hardware to avoid esp
17363 ;; dependencies is present.
17365 ;; While some of these conversions may be done using splitters, we use
17366 ;; peepholes in order to allow combine_stack_adjustments pass to see
17367 ;; nonobfuscated RTL.
17369 ;; Convert prologue esp subtractions to push.
17370 ;; We need register to push. In order to keep verify_flow_info happy we have
17372 ;; - use scratch and clobber it in order to avoid dependencies
17373 ;; - use already live register
17374 ;; We can't use the second way right now, since there is no reliable way how to
17375 ;; verify that given register is live. First choice will also most likely in
17376 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17377 ;; call clobbered registers are dead. We may want to use base pointer as an
17378 ;; alternative when no register is available later.
17381 [(match_scratch:P 1 "r")
17382 (parallel [(set (reg:P SP_REG)
17383 (plus:P (reg:P SP_REG)
17384 (match_operand:P 0 "const_int_operand" "")))
17385 (clobber (reg:CC FLAGS_REG))
17386 (clobber (mem:BLK (scratch)))])]
17387 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17388 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17389 [(clobber (match_dup 1))
17390 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17391 (clobber (mem:BLK (scratch)))])])
17394 [(match_scratch:P 1 "r")
17395 (parallel [(set (reg:P SP_REG)
17396 (plus:P (reg:P SP_REG)
17397 (match_operand:P 0 "const_int_operand" "")))
17398 (clobber (reg:CC FLAGS_REG))
17399 (clobber (mem:BLK (scratch)))])]
17400 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17401 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17402 [(clobber (match_dup 1))
17403 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17404 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17405 (clobber (mem:BLK (scratch)))])])
17407 ;; Convert esp subtractions to push.
17409 [(match_scratch:P 1 "r")
17410 (parallel [(set (reg:P SP_REG)
17411 (plus:P (reg:P SP_REG)
17412 (match_operand:P 0 "const_int_operand" "")))
17413 (clobber (reg:CC FLAGS_REG))])]
17414 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17415 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17416 [(clobber (match_dup 1))
17417 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17420 [(match_scratch:P 1 "r")
17421 (parallel [(set (reg:P SP_REG)
17422 (plus:P (reg:P SP_REG)
17423 (match_operand:P 0 "const_int_operand" "")))
17424 (clobber (reg:CC FLAGS_REG))])]
17425 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17426 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17427 [(clobber (match_dup 1))
17428 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17429 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17431 ;; Convert epilogue deallocator to pop.
17433 [(match_scratch:P 1 "r")
17434 (parallel [(set (reg:P SP_REG)
17435 (plus:P (reg:P SP_REG)
17436 (match_operand:P 0 "const_int_operand" "")))
17437 (clobber (reg:CC FLAGS_REG))
17438 (clobber (mem:BLK (scratch)))])]
17439 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17440 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17441 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17442 (clobber (mem:BLK (scratch)))])])
17444 ;; Two pops case is tricky, since pop causes dependency
17445 ;; on destination register. We use two registers if available.
17447 [(match_scratch:P 1 "r")
17448 (match_scratch:P 2 "r")
17449 (parallel [(set (reg:P SP_REG)
17450 (plus:P (reg:P SP_REG)
17451 (match_operand:P 0 "const_int_operand" "")))
17452 (clobber (reg:CC FLAGS_REG))
17453 (clobber (mem:BLK (scratch)))])]
17454 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17455 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17456 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17457 (clobber (mem:BLK (scratch)))])
17458 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17461 [(match_scratch:P 1 "r")
17462 (parallel [(set (reg:P SP_REG)
17463 (plus:P (reg:P SP_REG)
17464 (match_operand:P 0 "const_int_operand" "")))
17465 (clobber (reg:CC FLAGS_REG))
17466 (clobber (mem:BLK (scratch)))])]
17467 "optimize_insn_for_size_p ()
17468 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17469 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17470 (clobber (mem:BLK (scratch)))])
17471 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17473 ;; Convert esp additions to pop.
17475 [(match_scratch:P 1 "r")
17476 (parallel [(set (reg:P SP_REG)
17477 (plus:P (reg:P SP_REG)
17478 (match_operand:P 0 "const_int_operand" "")))
17479 (clobber (reg:CC FLAGS_REG))])]
17480 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17481 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17483 ;; Two pops case is tricky, since pop causes dependency
17484 ;; on destination register. We use two registers if available.
17486 [(match_scratch:P 1 "r")
17487 (match_scratch:P 2 "r")
17488 (parallel [(set (reg:P SP_REG)
17489 (plus:P (reg:P SP_REG)
17490 (match_operand:P 0 "const_int_operand" "")))
17491 (clobber (reg:CC FLAGS_REG))])]
17492 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17493 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17494 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17497 [(match_scratch:P 1 "r")
17498 (parallel [(set (reg:P SP_REG)
17499 (plus:P (reg:P SP_REG)
17500 (match_operand:P 0 "const_int_operand" "")))
17501 (clobber (reg:CC FLAGS_REG))])]
17502 "optimize_insn_for_size_p ()
17503 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17504 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17505 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17507 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17508 ;; required and register dies. Similarly for 128 to -128.
17510 [(set (match_operand 0 "flags_reg_operand" "")
17511 (match_operator 1 "compare_operator"
17512 [(match_operand 2 "register_operand" "")
17513 (match_operand 3 "const_int_operand" "")]))]
17514 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17515 && incdec_operand (operands[3], GET_MODE (operands[3])))
17516 || (!TARGET_FUSE_CMP_AND_BRANCH
17517 && INTVAL (operands[3]) == 128))
17518 && ix86_match_ccmode (insn, CCGCmode)
17519 && peep2_reg_dead_p (1, operands[2])"
17520 [(parallel [(set (match_dup 0)
17521 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17522 (clobber (match_dup 2))])])
17524 ;; Convert imul by three, five and nine into lea
17527 [(set (match_operand:SWI48 0 "register_operand" "")
17528 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17529 (match_operand:SWI48 2 "const359_operand" "")))
17530 (clobber (reg:CC FLAGS_REG))])]
17531 "!TARGET_PARTIAL_REG_STALL
17532 || <MODE>mode == SImode
17533 || optimize_function_for_size_p (cfun)"
17534 [(set (match_dup 0)
17535 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17537 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17541 [(set (match_operand:SWI48 0 "register_operand" "")
17542 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17543 (match_operand:SWI48 2 "const359_operand" "")))
17544 (clobber (reg:CC FLAGS_REG))])]
17545 "optimize_insn_for_speed_p ()
17546 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17547 [(set (match_dup 0) (match_dup 1))
17549 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17551 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17553 ;; imul $32bit_imm, mem, reg is vector decoded, while
17554 ;; imul $32bit_imm, reg, reg is direct decoded.
17556 [(match_scratch:SWI48 3 "r")
17557 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17558 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17559 (match_operand:SWI48 2 "immediate_operand" "")))
17560 (clobber (reg:CC FLAGS_REG))])]
17561 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17562 && !satisfies_constraint_K (operands[2])"
17563 [(set (match_dup 3) (match_dup 1))
17564 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17565 (clobber (reg:CC FLAGS_REG))])])
17568 [(match_scratch:SI 3 "r")
17569 (parallel [(set (match_operand:DI 0 "register_operand" "")
17571 (mult:SI (match_operand:SI 1 "memory_operand" "")
17572 (match_operand:SI 2 "immediate_operand" ""))))
17573 (clobber (reg:CC FLAGS_REG))])]
17575 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17576 && !satisfies_constraint_K (operands[2])"
17577 [(set (match_dup 3) (match_dup 1))
17578 (parallel [(set (match_dup 0)
17579 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17580 (clobber (reg:CC FLAGS_REG))])])
17582 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17583 ;; Convert it into imul reg, reg
17584 ;; It would be better to force assembler to encode instruction using long
17585 ;; immediate, but there is apparently no way to do so.
17587 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17589 (match_operand:SWI248 1 "nonimmediate_operand" "")
17590 (match_operand:SWI248 2 "const_int_operand" "")))
17591 (clobber (reg:CC FLAGS_REG))])
17592 (match_scratch:SWI248 3 "r")]
17593 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17594 && satisfies_constraint_K (operands[2])"
17595 [(set (match_dup 3) (match_dup 2))
17596 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17597 (clobber (reg:CC FLAGS_REG))])]
17599 if (!rtx_equal_p (operands[0], operands[1]))
17600 emit_move_insn (operands[0], operands[1]);
17603 ;; After splitting up read-modify operations, array accesses with memory
17604 ;; operands might end up in form:
17606 ;; movl 4(%esp), %edx
17608 ;; instead of pre-splitting:
17610 ;; addl 4(%esp), %eax
17612 ;; movl 4(%esp), %edx
17613 ;; leal (%edx,%eax,4), %eax
17616 [(match_scratch:P 5 "r")
17617 (parallel [(set (match_operand 0 "register_operand" "")
17618 (ashift (match_operand 1 "register_operand" "")
17619 (match_operand 2 "const_int_operand" "")))
17620 (clobber (reg:CC FLAGS_REG))])
17621 (parallel [(set (match_operand 3 "register_operand" "")
17622 (plus (match_dup 0)
17623 (match_operand 4 "x86_64_general_operand" "")))
17624 (clobber (reg:CC FLAGS_REG))])]
17625 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17626 /* Validate MODE for lea. */
17627 && ((!TARGET_PARTIAL_REG_STALL
17628 && (GET_MODE (operands[0]) == QImode
17629 || GET_MODE (operands[0]) == HImode))
17630 || GET_MODE (operands[0]) == SImode
17631 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17632 && (rtx_equal_p (operands[0], operands[3])
17633 || peep2_reg_dead_p (2, operands[0]))
17634 /* We reorder load and the shift. */
17635 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17636 [(set (match_dup 5) (match_dup 4))
17637 (set (match_dup 0) (match_dup 1))]
17639 enum machine_mode op1mode = GET_MODE (operands[1]);
17640 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17641 int scale = 1 << INTVAL (operands[2]);
17642 rtx index = gen_lowpart (Pmode, operands[1]);
17643 rtx base = gen_lowpart (Pmode, operands[5]);
17644 rtx dest = gen_lowpart (mode, operands[3]);
17646 operands[1] = gen_rtx_PLUS (Pmode, base,
17647 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17648 operands[5] = base;
17650 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17651 if (op1mode != Pmode)
17652 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17653 operands[0] = dest;
17656 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17657 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17658 ;; caught for use by garbage collectors and the like. Using an insn that
17659 ;; maps to SIGILL makes it more likely the program will rightfully die.
17660 ;; Keeping with tradition, "6" is in honor of #UD.
17661 (define_insn "trap"
17662 [(trap_if (const_int 1) (const_int 6))]
17664 { return ASM_SHORT "0x0b0f"; }
17665 [(set_attr "length" "2")])
17667 (define_expand "prefetch"
17668 [(prefetch (match_operand 0 "address_operand" "")
17669 (match_operand:SI 1 "const_int_operand" "")
17670 (match_operand:SI 2 "const_int_operand" ""))]
17671 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17673 int rw = INTVAL (operands[1]);
17674 int locality = INTVAL (operands[2]);
17676 gcc_assert (rw == 0 || rw == 1);
17677 gcc_assert (IN_RANGE (locality, 0, 3));
17679 if (TARGET_PREFETCHW && rw)
17680 operands[2] = GEN_INT (3);
17681 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17682 supported by SSE counterpart or the SSE prefetch is not available
17683 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17685 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17686 operands[2] = GEN_INT (3);
17688 operands[1] = const0_rtx;
17691 (define_insn "*prefetch_sse"
17692 [(prefetch (match_operand 0 "address_operand" "p")
17694 (match_operand:SI 1 "const_int_operand" ""))]
17695 "TARGET_PREFETCH_SSE"
17697 static const char * const patterns[4] = {
17698 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17701 int locality = INTVAL (operands[1]);
17702 gcc_assert (IN_RANGE (locality, 0, 3));
17704 return patterns[locality];
17706 [(set_attr "type" "sse")
17707 (set_attr "atom_sse_attr" "prefetch")
17708 (set (attr "length_address")
17709 (symbol_ref "memory_address_length (operands[0], false)"))
17710 (set_attr "memory" "none")])
17712 (define_insn "*prefetch_3dnow"
17713 [(prefetch (match_operand 0 "address_operand" "p")
17714 (match_operand:SI 1 "const_int_operand" "n")
17716 "TARGET_3DNOW || TARGET_PREFETCHW"
17718 if (INTVAL (operands[1]) == 0)
17719 return "prefetch\t%a0";
17721 return "prefetchw\t%a0";
17723 [(set_attr "type" "mmx")
17724 (set (attr "length_address")
17725 (symbol_ref "memory_address_length (operands[0], false)"))
17726 (set_attr "memory" "none")])
17728 (define_expand "stack_protect_set"
17729 [(match_operand 0 "memory_operand" "")
17730 (match_operand 1 "memory_operand" "")]
17731 "!TARGET_HAS_BIONIC"
17733 rtx (*insn)(rtx, rtx);
17735 #ifdef TARGET_THREAD_SSP_OFFSET
17736 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17737 insn = (TARGET_LP64
17738 ? gen_stack_tls_protect_set_di
17739 : gen_stack_tls_protect_set_si);
17741 insn = (TARGET_LP64
17742 ? gen_stack_protect_set_di
17743 : gen_stack_protect_set_si);
17746 emit_insn (insn (operands[0], operands[1]));
17750 (define_insn "stack_protect_set_<mode>"
17751 [(set (match_operand:PTR 0 "memory_operand" "=m")
17752 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17754 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17755 (clobber (reg:CC FLAGS_REG))]
17756 "!TARGET_HAS_BIONIC"
17757 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17758 [(set_attr "type" "multi")])
17760 (define_insn "stack_tls_protect_set_<mode>"
17761 [(set (match_operand:PTR 0 "memory_operand" "=m")
17762 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17763 UNSPEC_SP_TLS_SET))
17764 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17765 (clobber (reg:CC FLAGS_REG))]
17767 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17768 [(set_attr "type" "multi")])
17770 (define_expand "stack_protect_test"
17771 [(match_operand 0 "memory_operand" "")
17772 (match_operand 1 "memory_operand" "")
17773 (match_operand 2 "" "")]
17774 "!TARGET_HAS_BIONIC"
17776 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17778 rtx (*insn)(rtx, rtx, rtx);
17780 #ifdef TARGET_THREAD_SSP_OFFSET
17781 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17782 insn = (TARGET_LP64
17783 ? gen_stack_tls_protect_test_di
17784 : gen_stack_tls_protect_test_si);
17786 insn = (TARGET_LP64
17787 ? gen_stack_protect_test_di
17788 : gen_stack_protect_test_si);
17791 emit_insn (insn (flags, operands[0], operands[1]));
17793 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17794 flags, const0_rtx, operands[2]));
17798 (define_insn "stack_protect_test_<mode>"
17799 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17800 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17801 (match_operand:PTR 2 "memory_operand" "m")]
17803 (clobber (match_scratch:PTR 3 "=&r"))]
17804 "!TARGET_HAS_BIONIC"
17805 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17806 [(set_attr "type" "multi")])
17808 (define_insn "stack_tls_protect_test_<mode>"
17809 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17810 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17811 (match_operand:PTR 2 "const_int_operand" "i")]
17812 UNSPEC_SP_TLS_TEST))
17813 (clobber (match_scratch:PTR 3 "=r"))]
17815 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17816 [(set_attr "type" "multi")])
17818 (define_insn "sse4_2_crc32<mode>"
17819 [(set (match_operand:SI 0 "register_operand" "=r")
17821 [(match_operand:SI 1 "register_operand" "0")
17822 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17824 "TARGET_SSE4_2 || TARGET_CRC32"
17825 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17826 [(set_attr "type" "sselog1")
17827 (set_attr "prefix_rep" "1")
17828 (set_attr "prefix_extra" "1")
17829 (set (attr "prefix_data16")
17830 (if_then_else (match_operand:HI 2 "" "")
17832 (const_string "*")))
17833 (set (attr "prefix_rex")
17834 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17836 (const_string "*")))
17837 (set_attr "mode" "SI")])
17839 (define_insn "sse4_2_crc32di"
17840 [(set (match_operand:DI 0 "register_operand" "=r")
17842 [(match_operand:DI 1 "register_operand" "0")
17843 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17845 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17846 "crc32{q}\t{%2, %0|%0, %2}"
17847 [(set_attr "type" "sselog1")
17848 (set_attr "prefix_rep" "1")
17849 (set_attr "prefix_extra" "1")
17850 (set_attr "mode" "DI")])
17852 (define_expand "rdpmc"
17853 [(match_operand:DI 0 "register_operand" "")
17854 (match_operand:SI 1 "register_operand" "")]
17857 rtx reg = gen_reg_rtx (DImode);
17860 /* Force operand 1 into ECX. */
17861 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17862 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17863 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17868 rtvec vec = rtvec_alloc (2);
17869 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17870 rtx upper = gen_reg_rtx (DImode);
17871 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17872 gen_rtvec (1, const0_rtx),
17874 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17875 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17877 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17878 NULL, 1, OPTAB_DIRECT);
17879 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17883 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17884 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17888 (define_insn "*rdpmc"
17889 [(set (match_operand:DI 0 "register_operand" "=A")
17890 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17894 [(set_attr "type" "other")
17895 (set_attr "length" "2")])
17897 (define_insn "*rdpmc_rex64"
17898 [(set (match_operand:DI 0 "register_operand" "=a")
17899 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17901 (set (match_operand:DI 1 "register_operand" "=d")
17902 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17905 [(set_attr "type" "other")
17906 (set_attr "length" "2")])
17908 (define_expand "rdtsc"
17909 [(set (match_operand:DI 0 "register_operand" "")
17910 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17915 rtvec vec = rtvec_alloc (2);
17916 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17917 rtx upper = gen_reg_rtx (DImode);
17918 rtx lower = gen_reg_rtx (DImode);
17919 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17920 gen_rtvec (1, const0_rtx),
17922 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17923 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17925 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17926 NULL, 1, OPTAB_DIRECT);
17927 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17929 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17934 (define_insn "*rdtsc"
17935 [(set (match_operand:DI 0 "register_operand" "=A")
17936 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17939 [(set_attr "type" "other")
17940 (set_attr "length" "2")])
17942 (define_insn "*rdtsc_rex64"
17943 [(set (match_operand:DI 0 "register_operand" "=a")
17944 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17945 (set (match_operand:DI 1 "register_operand" "=d")
17946 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17949 [(set_attr "type" "other")
17950 (set_attr "length" "2")])
17952 (define_expand "rdtscp"
17953 [(match_operand:DI 0 "register_operand" "")
17954 (match_operand:SI 1 "memory_operand" "")]
17957 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17958 gen_rtvec (1, const0_rtx),
17960 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17961 gen_rtvec (1, const0_rtx),
17963 rtx reg = gen_reg_rtx (DImode);
17964 rtx tmp = gen_reg_rtx (SImode);
17968 rtvec vec = rtvec_alloc (3);
17969 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17970 rtx upper = gen_reg_rtx (DImode);
17971 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17972 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17973 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17975 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17976 NULL, 1, OPTAB_DIRECT);
17977 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17982 rtvec vec = rtvec_alloc (2);
17983 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17984 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17985 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17988 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17989 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17993 (define_insn "*rdtscp"
17994 [(set (match_operand:DI 0 "register_operand" "=A")
17995 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17996 (set (match_operand:SI 1 "register_operand" "=c")
17997 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18000 [(set_attr "type" "other")
18001 (set_attr "length" "3")])
18003 (define_insn "*rdtscp_rex64"
18004 [(set (match_operand:DI 0 "register_operand" "=a")
18005 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18006 (set (match_operand:DI 1 "register_operand" "=d")
18007 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18008 (set (match_operand:SI 2 "register_operand" "=c")
18009 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18012 [(set_attr "type" "other")
18013 (set_attr "length" "3")])
18015 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18017 ;; LWP instructions
18019 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18021 (define_expand "lwp_llwpcb"
18022 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18023 UNSPECV_LLWP_INTRINSIC)]
18026 (define_insn "*lwp_llwpcb<mode>1"
18027 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18028 UNSPECV_LLWP_INTRINSIC)]
18031 [(set_attr "type" "lwp")
18032 (set_attr "mode" "<MODE>")
18033 (set_attr "length" "5")])
18035 (define_expand "lwp_slwpcb"
18036 [(set (match_operand 0 "register_operand" "=r")
18037 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18042 insn = (TARGET_64BIT
18044 : gen_lwp_slwpcbsi);
18046 emit_insn (insn (operands[0]));
18050 (define_insn "lwp_slwpcb<mode>"
18051 [(set (match_operand:P 0 "register_operand" "=r")
18052 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18055 [(set_attr "type" "lwp")
18056 (set_attr "mode" "<MODE>")
18057 (set_attr "length" "5")])
18059 (define_expand "lwp_lwpval<mode>3"
18060 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18061 (match_operand:SI 2 "nonimmediate_operand" "rm")
18062 (match_operand:SI 3 "const_int_operand" "i")]
18063 UNSPECV_LWPVAL_INTRINSIC)]
18065 ;; Avoid unused variable warning.
18066 "(void) operands[0];")
18068 (define_insn "*lwp_lwpval<mode>3_1"
18069 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18070 (match_operand:SI 1 "nonimmediate_operand" "rm")
18071 (match_operand:SI 2 "const_int_operand" "i")]
18072 UNSPECV_LWPVAL_INTRINSIC)]
18074 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18075 [(set_attr "type" "lwp")
18076 (set_attr "mode" "<MODE>")
18077 (set (attr "length")
18078 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18080 (define_expand "lwp_lwpins<mode>3"
18081 [(set (reg:CCC FLAGS_REG)
18082 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18083 (match_operand:SI 2 "nonimmediate_operand" "rm")
18084 (match_operand:SI 3 "const_int_operand" "i")]
18085 UNSPECV_LWPINS_INTRINSIC))
18086 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18087 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18090 (define_insn "*lwp_lwpins<mode>3_1"
18091 [(set (reg:CCC FLAGS_REG)
18092 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18093 (match_operand:SI 1 "nonimmediate_operand" "rm")
18094 (match_operand:SI 2 "const_int_operand" "i")]
18095 UNSPECV_LWPINS_INTRINSIC))]
18097 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18098 [(set_attr "type" "lwp")
18099 (set_attr "mode" "<MODE>")
18100 (set (attr "length")
18101 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18103 (define_insn "rdfsbase<mode>"
18104 [(set (match_operand:SWI48 0 "register_operand" "=r")
18105 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18106 "TARGET_64BIT && TARGET_FSGSBASE"
18108 [(set_attr "type" "other")
18109 (set_attr "prefix_extra" "2")])
18111 (define_insn "rdgsbase<mode>"
18112 [(set (match_operand:SWI48 0 "register_operand" "=r")
18113 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18114 "TARGET_64BIT && TARGET_FSGSBASE"
18116 [(set_attr "type" "other")
18117 (set_attr "prefix_extra" "2")])
18119 (define_insn "wrfsbase<mode>"
18120 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18122 "TARGET_64BIT && TARGET_FSGSBASE"
18124 [(set_attr "type" "other")
18125 (set_attr "prefix_extra" "2")])
18127 (define_insn "wrgsbase<mode>"
18128 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18130 "TARGET_64BIT && TARGET_FSGSBASE"
18132 [(set_attr "type" "other")
18133 (set_attr "prefix_extra" "2")])
18135 (define_insn "rdrand<mode>_1"
18136 [(set (match_operand:SWI248 0 "register_operand" "=r")
18137 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18138 (set (reg:CCC FLAGS_REG)
18139 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18142 [(set_attr "type" "other")
18143 (set_attr "prefix_extra" "1")])
18145 (define_expand "pause"
18146 [(set (match_dup 0)
18147 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18150 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18151 MEM_VOLATILE_P (operands[0]) = 1;
18154 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18155 ;; They have the same encoding.
18156 (define_insn "*pause"
18157 [(set (match_operand:BLK 0 "" "")
18158 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18161 [(set_attr "length" "2")
18162 (set_attr "memory" "unknown")])
18166 (include "sync.md")