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
113 ;; For SSE/MMX support:
121 ;; Generic math support
123 UNSPEC_IEEE_MIN ; not commutative
124 UNSPEC_IEEE_MAX ; not commutative
126 ;; x87 Floating point
142 UNSPEC_FRNDINT_MASK_PM
146 ;; x87 Double output FP
181 (define_c_enum "unspecv" [
184 UNSPECV_PROBE_STACK_RANGE
187 UNSPECV_SPLIT_STACK_RETURN
193 UNSPECV_LLWP_INTRINSIC
194 UNSPECV_SLWP_INTRINSIC
195 UNSPECV_LWPVAL_INTRINSIC
196 UNSPECV_LWPINS_INTRINSIC
202 ;; For RDRAND support
206 ;; Constants to represent rounding modes in the ROUND instruction
215 ;; Constants to represent pcomtrue/pcomfalse variants
225 ;; Constants used in the XOP pperm instruction
227 [(PPERM_SRC 0x00) /* copy source */
228 (PPERM_INVERT 0x20) /* invert source */
229 (PPERM_REVERSE 0x40) /* bit reverse source */
230 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
231 (PPERM_ZERO 0x80) /* all 0's */
232 (PPERM_ONES 0xa0) /* all 1's */
233 (PPERM_SIGN 0xc0) /* propagate sign bit */
234 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
235 (PPERM_SRC1 0x00) /* use first source byte */
236 (PPERM_SRC2 0x10) /* use second source byte */
239 ;; Registers by name.
292 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
295 ;; In C guard expressions, put expressions which may be compile-time
296 ;; constants first. This allows for better optimization. For
297 ;; example, write "TARGET_64BIT && reload_completed", not
298 ;; "reload_completed && TARGET_64BIT".
302 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
303 atom,generic64,amdfam10,bdver1,bdver2,btver1"
304 (const (symbol_ref "ix86_schedule")))
306 ;; A basic instruction type. Refinements due to arguments to be
307 ;; provided in other attributes.
310 alu,alu1,negnot,imov,imovx,lea,
311 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
312 icmp,test,ibr,setcc,icmov,
313 push,pop,call,callv,leave,
315 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
316 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
317 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
318 ssemuladd,sse4arg,lwp,
319 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
320 (const_string "other"))
322 ;; Main data type used by the insn
324 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
325 (const_string "unknown"))
327 ;; The CPU unit operations uses.
328 (define_attr "unit" "integer,i387,sse,mmx,unknown"
329 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
330 (const_string "i387")
331 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
332 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
333 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
335 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
337 (eq_attr "type" "other")
338 (const_string "unknown")]
339 (const_string "integer")))
341 ;; The (bounding maximum) length of an instruction immediate.
342 (define_attr "length_immediate" ""
343 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
346 (eq_attr "unit" "i387,sse,mmx")
348 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
349 rotate,rotatex,rotate1,imul,icmp,push,pop")
350 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
351 (eq_attr "type" "imov,test")
352 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
353 (eq_attr "type" "call")
354 (if_then_else (match_operand 0 "constant_call_address_operand" "")
357 (eq_attr "type" "callv")
358 (if_then_else (match_operand 1 "constant_call_address_operand" "")
361 ;; We don't know the size before shorten_branches. Expect
362 ;; the instruction to fit for better scheduling.
363 (eq_attr "type" "ibr")
366 (symbol_ref "/* Update immediate_length and other attributes! */
367 gcc_unreachable (),1")))
369 ;; The (bounding maximum) length of an instruction address.
370 (define_attr "length_address" ""
371 (cond [(eq_attr "type" "str,other,multi,fxch")
373 (and (eq_attr "type" "call")
374 (match_operand 0 "constant_call_address_operand" ""))
376 (and (eq_attr "type" "callv")
377 (match_operand 1 "constant_call_address_operand" ""))
380 (symbol_ref "ix86_attr_length_address_default (insn)")))
382 ;; Set when length prefix is used.
383 (define_attr "prefix_data16" ""
384 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
386 (eq_attr "mode" "HI")
388 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
393 ;; Set when string REP prefix is used.
394 (define_attr "prefix_rep" ""
395 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
397 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
402 ;; Set when 0f opcode prefix is used.
403 (define_attr "prefix_0f" ""
405 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
406 (eq_attr "unit" "sse,mmx"))
410 ;; Set when REX opcode prefix is used.
411 (define_attr "prefix_rex" ""
412 (cond [(not (match_test "TARGET_64BIT"))
414 (and (eq_attr "mode" "DI")
415 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
416 (eq_attr "unit" "!mmx")))
418 (and (eq_attr "mode" "QI")
419 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
421 (match_test "x86_extended_reg_mentioned_p (insn)")
423 (and (eq_attr "type" "imovx")
424 (match_operand:QI 1 "ext_QIreg_operand" ""))
429 ;; There are also additional prefixes in 3DNOW, SSSE3.
430 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
431 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
432 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
433 (define_attr "prefix_extra" ""
434 (cond [(eq_attr "type" "ssemuladd,sse4arg")
436 (eq_attr "type" "sseiadd1,ssecvt1")
441 ;; Prefix used: original, VEX or maybe VEX.
442 (define_attr "prefix" "orig,vex,maybe_vex"
443 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
445 (const_string "orig")))
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
450 ;; The length of VEX prefix
451 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
452 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
453 ;; still prefix_0f 1, with prefix_extra 1.
454 (define_attr "length_vex" ""
455 (if_then_else (and (eq_attr "prefix_0f" "1")
456 (eq_attr "prefix_extra" "0"))
457 (if_then_else (eq_attr "prefix_vex_w" "1")
458 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
459 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
460 (if_then_else (eq_attr "prefix_vex_w" "1")
461 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
462 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
464 ;; Set when modrm byte is used.
465 (define_attr "modrm" ""
466 (cond [(eq_attr "type" "str,leave")
468 (eq_attr "unit" "i387")
470 (and (eq_attr "type" "incdec")
471 (and (not (match_test "TARGET_64BIT"))
472 (ior (match_operand:SI 1 "register_operand" "")
473 (match_operand:HI 1 "register_operand" ""))))
475 (and (eq_attr "type" "push")
476 (not (match_operand 1 "memory_operand" "")))
478 (and (eq_attr "type" "pop")
479 (not (match_operand 0 "memory_operand" "")))
481 (and (eq_attr "type" "imov")
482 (and (not (eq_attr "mode" "DI"))
483 (ior (and (match_operand 0 "register_operand" "")
484 (match_operand 1 "immediate_operand" ""))
485 (ior (and (match_operand 0 "ax_reg_operand" "")
486 (match_operand 1 "memory_displacement_only_operand" ""))
487 (and (match_operand 0 "memory_displacement_only_operand" "")
488 (match_operand 1 "ax_reg_operand" ""))))))
490 (and (eq_attr "type" "call")
491 (match_operand 0 "constant_call_address_operand" ""))
493 (and (eq_attr "type" "callv")
494 (match_operand 1 "constant_call_address_operand" ""))
496 (and (eq_attr "type" "alu,alu1,icmp,test")
497 (match_operand 0 "ax_reg_operand" ""))
498 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
502 ;; The (bounding maximum) length of an instruction in bytes.
503 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
504 ;; Later we may want to split them and compute proper length as for
506 (define_attr "length" ""
507 (cond [(eq_attr "type" "other,multi,fistp,frndint")
509 (eq_attr "type" "fcmp")
511 (eq_attr "unit" "i387")
513 (plus (attr "prefix_data16")
514 (attr "length_address")))
515 (ior (eq_attr "prefix" "vex")
516 (and (eq_attr "prefix" "maybe_vex")
517 (match_test "TARGET_AVX")))
518 (plus (attr "length_vex")
519 (plus (attr "length_immediate")
521 (attr "length_address"))))]
522 (plus (plus (attr "modrm")
523 (plus (attr "prefix_0f")
524 (plus (attr "prefix_rex")
525 (plus (attr "prefix_extra")
527 (plus (attr "prefix_rep")
528 (plus (attr "prefix_data16")
529 (plus (attr "length_immediate")
530 (attr "length_address")))))))
532 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
533 ;; `store' if there is a simple memory reference therein, or `unknown'
534 ;; if the instruction is complex.
536 (define_attr "memory" "none,load,store,both,unknown"
537 (cond [(eq_attr "type" "other,multi,str,lwp")
538 (const_string "unknown")
539 (eq_attr "type" "lea,fcmov,fpspc")
540 (const_string "none")
541 (eq_attr "type" "fistp,leave")
542 (const_string "both")
543 (eq_attr "type" "frndint")
544 (const_string "load")
545 (eq_attr "type" "push")
546 (if_then_else (match_operand 1 "memory_operand" "")
547 (const_string "both")
548 (const_string "store"))
549 (eq_attr "type" "pop")
550 (if_then_else (match_operand 0 "memory_operand" "")
551 (const_string "both")
552 (const_string "load"))
553 (eq_attr "type" "setcc")
554 (if_then_else (match_operand 0 "memory_operand" "")
555 (const_string "store")
556 (const_string "none"))
557 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
558 (if_then_else (ior (match_operand 0 "memory_operand" "")
559 (match_operand 1 "memory_operand" ""))
560 (const_string "load")
561 (const_string "none"))
562 (eq_attr "type" "ibr")
563 (if_then_else (match_operand 0 "memory_operand" "")
564 (const_string "load")
565 (const_string "none"))
566 (eq_attr "type" "call")
567 (if_then_else (match_operand 0 "constant_call_address_operand" "")
568 (const_string "none")
569 (const_string "load"))
570 (eq_attr "type" "callv")
571 (if_then_else (match_operand 1 "constant_call_address_operand" "")
572 (const_string "none")
573 (const_string "load"))
574 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
575 (match_operand 1 "memory_operand" ""))
576 (const_string "both")
577 (and (match_operand 0 "memory_operand" "")
578 (match_operand 1 "memory_operand" ""))
579 (const_string "both")
580 (match_operand 0 "memory_operand" "")
581 (const_string "store")
582 (match_operand 1 "memory_operand" "")
583 (const_string "load")
585 "!alu1,negnot,ishift1,
586 imov,imovx,icmp,test,bitmanip,
588 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
589 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
590 (match_operand 2 "memory_operand" ""))
591 (const_string "load")
592 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
593 (match_operand 3 "memory_operand" ""))
594 (const_string "load")
596 (const_string "none")))
598 ;; Indicates if an instruction has both an immediate and a displacement.
600 (define_attr "imm_disp" "false,true,unknown"
601 (cond [(eq_attr "type" "other,multi")
602 (const_string "unknown")
603 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
604 (and (match_operand 0 "memory_displacement_operand" "")
605 (match_operand 1 "immediate_operand" "")))
606 (const_string "true")
607 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
608 (and (match_operand 0 "memory_displacement_operand" "")
609 (match_operand 2 "immediate_operand" "")))
610 (const_string "true")
612 (const_string "false")))
614 ;; Indicates if an FP operation has an integer source.
616 (define_attr "fp_int_src" "false,true"
617 (const_string "false"))
619 ;; Defines rounding mode of an FP operation.
621 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
622 (const_string "any"))
624 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
625 (define_attr "use_carry" "0,1" (const_string "0"))
627 ;; Define attribute to indicate unaligned ssemov insns
628 (define_attr "movu" "0,1" (const_string "0"))
630 ;; Used to control the "enabled" attribute on a per-instruction basis.
631 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
632 (const_string "base"))
634 (define_attr "enabled" ""
635 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
636 (eq_attr "isa" "sse2_noavx")
637 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
638 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
639 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
640 (eq_attr "isa" "sse4_noavx")
641 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
642 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
643 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
644 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
648 ;; Describe a user's asm statement.
649 (define_asm_attributes
650 [(set_attr "length" "128")
651 (set_attr "type" "multi")])
653 (define_code_iterator plusminus [plus minus])
655 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
657 ;; Base name for define_insn
658 (define_code_attr plusminus_insn
659 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
660 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
662 ;; Base name for insn mnemonic.
663 (define_code_attr plusminus_mnemonic
664 [(plus "add") (ss_plus "adds") (us_plus "addus")
665 (minus "sub") (ss_minus "subs") (us_minus "subus")])
666 (define_code_attr plusminus_carry_mnemonic
667 [(plus "adc") (minus "sbb")])
669 ;; Mark commutative operators as such in constraints.
670 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
671 (minus "") (ss_minus "") (us_minus "")])
673 ;; Mapping of max and min
674 (define_code_iterator maxmin [smax smin umax umin])
676 ;; Mapping of signed max and min
677 (define_code_iterator smaxmin [smax smin])
679 ;; Mapping of unsigned max and min
680 (define_code_iterator umaxmin [umax umin])
682 ;; Base name for integer and FP insn mnemonic
683 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
684 (umax "maxu") (umin "minu")])
685 (define_code_attr maxmin_float [(smax "max") (smin "min")])
687 ;; Mapping of logic operators
688 (define_code_iterator any_logic [and ior xor])
689 (define_code_iterator any_or [ior xor])
691 ;; Base name for insn mnemonic.
692 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
694 ;; Mapping of logic-shift operators
695 (define_code_iterator any_lshift [ashift lshiftrt])
697 ;; Mapping of shift-right operators
698 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
700 ;; Base name for define_insn
701 (define_code_attr shift_insn
702 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
704 ;; Base name for insn mnemonic.
705 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
706 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
708 ;; Mapping of rotate operators
709 (define_code_iterator any_rotate [rotate rotatert])
711 ;; Base name for define_insn
712 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
714 ;; Base name for insn mnemonic.
715 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
717 ;; Mapping of abs neg operators
718 (define_code_iterator absneg [abs neg])
720 ;; Base name for x87 insn mnemonic.
721 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
723 ;; Used in signed and unsigned widening multiplications.
724 (define_code_iterator any_extend [sign_extend zero_extend])
726 ;; Prefix for insn menmonic.
727 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
729 ;; Prefix for define_insn
730 (define_code_attr u [(sign_extend "") (zero_extend "u")])
731 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
733 ;; All integer modes.
734 (define_mode_iterator SWI1248x [QI HI SI DI])
736 ;; All integer modes without QImode.
737 (define_mode_iterator SWI248x [HI SI DI])
739 ;; All integer modes without QImode and HImode.
740 (define_mode_iterator SWI48x [SI DI])
742 ;; All integer modes without SImode and DImode.
743 (define_mode_iterator SWI12 [QI HI])
745 ;; All integer modes without DImode.
746 (define_mode_iterator SWI124 [QI HI SI])
748 ;; All integer modes without QImode and DImode.
749 (define_mode_iterator SWI24 [HI SI])
751 ;; Single word integer modes.
752 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
754 ;; Single word integer modes without QImode.
755 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
757 ;; Single word integer modes without QImode and HImode.
758 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
760 ;; All math-dependant single and double word integer modes.
761 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
762 (HI "TARGET_HIMODE_MATH")
763 SI DI (TI "TARGET_64BIT")])
765 ;; Math-dependant single word integer modes.
766 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
767 (HI "TARGET_HIMODE_MATH")
768 SI (DI "TARGET_64BIT")])
770 ;; Math-dependant integer modes without DImode.
771 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
772 (HI "TARGET_HIMODE_MATH")
775 ;; Math-dependant single word integer modes without QImode.
776 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
777 SI (DI "TARGET_64BIT")])
779 ;; Double word integer modes.
780 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
781 (TI "TARGET_64BIT")])
783 ;; Double word integer modes as mode attribute.
784 (define_mode_attr DWI [(SI "DI") (DI "TI")])
785 (define_mode_attr dwi [(SI "di") (DI "ti")])
787 ;; Half mode for double word integer modes.
788 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
789 (DI "TARGET_64BIT")])
791 ;; Instruction suffix for integer modes.
792 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
794 ;; Pointer size prefix for integer modes (Intel asm dialect)
795 (define_mode_attr iptrsize [(QI "BYTE")
800 ;; Register class for integer modes.
801 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
803 ;; Immediate operand constraint for integer modes.
804 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
806 ;; General operand constraint for word modes.
807 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
809 ;; Immediate operand constraint for double integer modes.
810 (define_mode_attr di [(SI "nF") (DI "e")])
812 ;; Immediate operand constraint for shifts.
813 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
815 ;; General operand predicate for integer modes.
816 (define_mode_attr general_operand
817 [(QI "general_operand")
818 (HI "general_operand")
819 (SI "x86_64_general_operand")
820 (DI "x86_64_general_operand")
821 (TI "x86_64_general_operand")])
823 ;; General sign/zero extend operand predicate for integer modes.
824 (define_mode_attr general_szext_operand
825 [(QI "general_operand")
826 (HI "general_operand")
827 (SI "x86_64_szext_general_operand")
828 (DI "x86_64_szext_general_operand")])
830 ;; Immediate operand predicate for integer modes.
831 (define_mode_attr immediate_operand
832 [(QI "immediate_operand")
833 (HI "immediate_operand")
834 (SI "x86_64_immediate_operand")
835 (DI "x86_64_immediate_operand")])
837 ;; Nonmemory operand predicate for integer modes.
838 (define_mode_attr nonmemory_operand
839 [(QI "nonmemory_operand")
840 (HI "nonmemory_operand")
841 (SI "x86_64_nonmemory_operand")
842 (DI "x86_64_nonmemory_operand")])
844 ;; Operand predicate for shifts.
845 (define_mode_attr shift_operand
846 [(QI "nonimmediate_operand")
847 (HI "nonimmediate_operand")
848 (SI "nonimmediate_operand")
849 (DI "shiftdi_operand")
850 (TI "register_operand")])
852 ;; Operand predicate for shift argument.
853 (define_mode_attr shift_immediate_operand
854 [(QI "const_1_to_31_operand")
855 (HI "const_1_to_31_operand")
856 (SI "const_1_to_31_operand")
857 (DI "const_1_to_63_operand")])
859 ;; Input operand predicate for arithmetic left shifts.
860 (define_mode_attr ashl_input_operand
861 [(QI "nonimmediate_operand")
862 (HI "nonimmediate_operand")
863 (SI "nonimmediate_operand")
864 (DI "ashldi_input_operand")
865 (TI "reg_or_pm1_operand")])
867 ;; SSE and x87 SFmode and DFmode floating point modes
868 (define_mode_iterator MODEF [SF DF])
870 ;; All x87 floating point modes
871 (define_mode_iterator X87MODEF [SF DF XF])
873 ;; SSE instruction suffix for various modes
874 (define_mode_attr ssemodesuffix
876 (V8SF "ps") (V4DF "pd")
877 (V4SF "ps") (V2DF "pd")
878 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
879 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
881 ;; SSE vector suffix for floating point modes
882 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
884 ;; SSE vector mode corresponding to a scalar mode
885 (define_mode_attr ssevecmode
886 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
888 ;; Instruction suffix for REX 64bit operators.
889 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
891 ;; This mode iterator allows :P to be used for patterns that operate on
892 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
893 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
895 ;; This mode iterator allows :PTR to be used for patterns that operate on
896 ;; ptr_mode sized quantities.
897 (define_mode_iterator PTR
898 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
900 ;; Scheduling descriptions
902 (include "pentium.md")
905 (include "athlon.md")
906 (include "bdver1.md")
912 ;; Operand and operator predicates and constraints
914 (include "predicates.md")
915 (include "constraints.md")
918 ;; Compare and branch/compare and store instructions.
920 (define_expand "cbranch<mode>4"
921 [(set (reg:CC FLAGS_REG)
922 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
923 (match_operand:SDWIM 2 "<general_operand>" "")))
924 (set (pc) (if_then_else
925 (match_operator 0 "ordered_comparison_operator"
926 [(reg:CC FLAGS_REG) (const_int 0)])
927 (label_ref (match_operand 3 "" ""))
931 if (MEM_P (operands[1]) && MEM_P (operands[2]))
932 operands[1] = force_reg (<MODE>mode, operands[1]);
933 ix86_expand_branch (GET_CODE (operands[0]),
934 operands[1], operands[2], operands[3]);
938 (define_expand "cstore<mode>4"
939 [(set (reg:CC FLAGS_REG)
940 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
941 (match_operand:SWIM 3 "<general_operand>" "")))
942 (set (match_operand:QI 0 "register_operand" "")
943 (match_operator 1 "ordered_comparison_operator"
944 [(reg:CC FLAGS_REG) (const_int 0)]))]
947 if (MEM_P (operands[2]) && MEM_P (operands[3]))
948 operands[2] = force_reg (<MODE>mode, operands[2]);
949 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
950 operands[2], operands[3]);
954 (define_expand "cmp<mode>_1"
955 [(set (reg:CC FLAGS_REG)
956 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
957 (match_operand:SWI48 1 "<general_operand>" "")))])
959 (define_insn "*cmp<mode>_ccno_1"
960 [(set (reg FLAGS_REG)
961 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
962 (match_operand:SWI 1 "const0_operand" "")))]
963 "ix86_match_ccmode (insn, CCNOmode)"
965 test{<imodesuffix>}\t%0, %0
966 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
967 [(set_attr "type" "test,icmp")
968 (set_attr "length_immediate" "0,1")
969 (set_attr "mode" "<MODE>")])
971 (define_insn "*cmp<mode>_1"
972 [(set (reg FLAGS_REG)
973 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
974 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
975 "ix86_match_ccmode (insn, CCmode)"
976 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
977 [(set_attr "type" "icmp")
978 (set_attr "mode" "<MODE>")])
980 (define_insn "*cmp<mode>_minus_1"
981 [(set (reg FLAGS_REG)
983 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
984 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
986 "ix86_match_ccmode (insn, CCGOCmode)"
987 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
988 [(set_attr "type" "icmp")
989 (set_attr "mode" "<MODE>")])
991 (define_insn "*cmpqi_ext_1"
992 [(set (reg FLAGS_REG)
994 (match_operand:QI 0 "general_operand" "Qm")
997 (match_operand 1 "ext_register_operand" "Q")
1000 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001 "cmp{b}\t{%h1, %0|%0, %h1}"
1002 [(set_attr "type" "icmp")
1003 (set_attr "mode" "QI")])
1005 (define_insn "*cmpqi_ext_1_rex64"
1006 [(set (reg FLAGS_REG)
1008 (match_operand:QI 0 "register_operand" "Q")
1011 (match_operand 1 "ext_register_operand" "Q")
1013 (const_int 8)) 0)))]
1014 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015 "cmp{b}\t{%h1, %0|%0, %h1}"
1016 [(set_attr "type" "icmp")
1017 (set_attr "mode" "QI")])
1019 (define_insn "*cmpqi_ext_2"
1020 [(set (reg FLAGS_REG)
1024 (match_operand 0 "ext_register_operand" "Q")
1027 (match_operand:QI 1 "const0_operand" "")))]
1028 "ix86_match_ccmode (insn, CCNOmode)"
1030 [(set_attr "type" "test")
1031 (set_attr "length_immediate" "0")
1032 (set_attr "mode" "QI")])
1034 (define_expand "cmpqi_ext_3"
1035 [(set (reg:CC FLAGS_REG)
1039 (match_operand 0 "ext_register_operand" "")
1042 (match_operand:QI 1 "immediate_operand" "")))])
1044 (define_insn "*cmpqi_ext_3_insn"
1045 [(set (reg FLAGS_REG)
1049 (match_operand 0 "ext_register_operand" "Q")
1052 (match_operand:QI 1 "general_operand" "Qmn")))]
1053 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1054 "cmp{b}\t{%1, %h0|%h0, %1}"
1055 [(set_attr "type" "icmp")
1056 (set_attr "modrm" "1")
1057 (set_attr "mode" "QI")])
1059 (define_insn "*cmpqi_ext_3_insn_rex64"
1060 [(set (reg FLAGS_REG)
1064 (match_operand 0 "ext_register_operand" "Q")
1067 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1068 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1069 "cmp{b}\t{%1, %h0|%h0, %1}"
1070 [(set_attr "type" "icmp")
1071 (set_attr "modrm" "1")
1072 (set_attr "mode" "QI")])
1074 (define_insn "*cmpqi_ext_4"
1075 [(set (reg FLAGS_REG)
1079 (match_operand 0 "ext_register_operand" "Q")
1084 (match_operand 1 "ext_register_operand" "Q")
1086 (const_int 8)) 0)))]
1087 "ix86_match_ccmode (insn, CCmode)"
1088 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1089 [(set_attr "type" "icmp")
1090 (set_attr "mode" "QI")])
1092 ;; These implement float point compares.
1093 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1094 ;; which would allow mix and match FP modes on the compares. Which is what
1095 ;; the old patterns did, but with many more of them.
1097 (define_expand "cbranchxf4"
1098 [(set (reg:CC FLAGS_REG)
1099 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1100 (match_operand:XF 2 "nonmemory_operand" "")))
1101 (set (pc) (if_then_else
1102 (match_operator 0 "ix86_fp_comparison_operator"
1105 (label_ref (match_operand 3 "" ""))
1109 ix86_expand_branch (GET_CODE (operands[0]),
1110 operands[1], operands[2], operands[3]);
1114 (define_expand "cstorexf4"
1115 [(set (reg:CC FLAGS_REG)
1116 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1117 (match_operand:XF 3 "nonmemory_operand" "")))
1118 (set (match_operand:QI 0 "register_operand" "")
1119 (match_operator 1 "ix86_fp_comparison_operator"
1124 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1125 operands[2], operands[3]);
1129 (define_expand "cbranch<mode>4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1132 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1133 (set (pc) (if_then_else
1134 (match_operator 0 "ix86_fp_comparison_operator"
1137 (label_ref (match_operand 3 "" ""))
1139 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1141 ix86_expand_branch (GET_CODE (operands[0]),
1142 operands[1], operands[2], operands[3]);
1146 (define_expand "cstore<mode>4"
1147 [(set (reg:CC FLAGS_REG)
1148 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1149 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1150 (set (match_operand:QI 0 "register_operand" "")
1151 (match_operator 1 "ix86_fp_comparison_operator"
1154 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1156 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1157 operands[2], operands[3]);
1161 (define_expand "cbranchcc4"
1162 [(set (pc) (if_then_else
1163 (match_operator 0 "comparison_operator"
1164 [(match_operand 1 "flags_reg_operand" "")
1165 (match_operand 2 "const0_operand" "")])
1166 (label_ref (match_operand 3 "" ""))
1170 ix86_expand_branch (GET_CODE (operands[0]),
1171 operands[1], operands[2], operands[3]);
1175 (define_expand "cstorecc4"
1176 [(set (match_operand:QI 0 "register_operand" "")
1177 (match_operator 1 "comparison_operator"
1178 [(match_operand 2 "flags_reg_operand" "")
1179 (match_operand 3 "const0_operand" "")]))]
1182 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1183 operands[2], operands[3]);
1188 ;; FP compares, step 1:
1189 ;; Set the FP condition codes.
1191 ;; CCFPmode compare with exceptions
1192 ;; CCFPUmode compare with no exceptions
1194 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1195 ;; used to manage the reg stack popping would not be preserved.
1197 (define_insn "*cmpfp_0"
1198 [(set (match_operand:HI 0 "register_operand" "=a")
1201 (match_operand 1 "register_operand" "f")
1202 (match_operand 2 "const0_operand" ""))]
1204 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1205 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1206 "* return output_fp_compare (insn, operands, false, false);"
1207 [(set_attr "type" "multi")
1208 (set_attr "unit" "i387")
1210 (cond [(match_operand:SF 1 "" "")
1212 (match_operand:DF 1 "" "")
1215 (const_string "XF")))])
1217 (define_insn_and_split "*cmpfp_0_cc"
1218 [(set (reg:CCFP FLAGS_REG)
1220 (match_operand 1 "register_operand" "f")
1221 (match_operand 2 "const0_operand" "")))
1222 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1223 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1224 && TARGET_SAHF && !TARGET_CMOVE
1225 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1227 "&& reload_completed"
1230 [(compare:CCFP (match_dup 1)(match_dup 2))]
1232 (set (reg:CC FLAGS_REG)
1233 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1235 [(set_attr "type" "multi")
1236 (set_attr "unit" "i387")
1238 (cond [(match_operand:SF 1 "" "")
1240 (match_operand:DF 1 "" "")
1243 (const_string "XF")))])
1245 (define_insn "*cmpfp_xf"
1246 [(set (match_operand:HI 0 "register_operand" "=a")
1249 (match_operand:XF 1 "register_operand" "f")
1250 (match_operand:XF 2 "register_operand" "f"))]
1253 "* return output_fp_compare (insn, operands, false, false);"
1254 [(set_attr "type" "multi")
1255 (set_attr "unit" "i387")
1256 (set_attr "mode" "XF")])
1258 (define_insn_and_split "*cmpfp_xf_cc"
1259 [(set (reg:CCFP FLAGS_REG)
1261 (match_operand:XF 1 "register_operand" "f")
1262 (match_operand:XF 2 "register_operand" "f")))
1263 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1265 && TARGET_SAHF && !TARGET_CMOVE"
1267 "&& reload_completed"
1270 [(compare:CCFP (match_dup 1)(match_dup 2))]
1272 (set (reg:CC FLAGS_REG)
1273 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1275 [(set_attr "type" "multi")
1276 (set_attr "unit" "i387")
1277 (set_attr "mode" "XF")])
1279 (define_insn "*cmpfp_<mode>"
1280 [(set (match_operand:HI 0 "register_operand" "=a")
1283 (match_operand:MODEF 1 "register_operand" "f")
1284 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1287 "* return output_fp_compare (insn, operands, false, false);"
1288 [(set_attr "type" "multi")
1289 (set_attr "unit" "i387")
1290 (set_attr "mode" "<MODE>")])
1292 (define_insn_and_split "*cmpfp_<mode>_cc"
1293 [(set (reg:CCFP FLAGS_REG)
1295 (match_operand:MODEF 1 "register_operand" "f")
1296 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1297 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1299 && TARGET_SAHF && !TARGET_CMOVE"
1301 "&& reload_completed"
1304 [(compare:CCFP (match_dup 1)(match_dup 2))]
1306 (set (reg:CC FLAGS_REG)
1307 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "<MODE>")])
1313 (define_insn "*cmpfp_u"
1314 [(set (match_operand:HI 0 "register_operand" "=a")
1317 (match_operand 1 "register_operand" "f")
1318 (match_operand 2 "register_operand" "f"))]
1320 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1322 "* return output_fp_compare (insn, operands, false, true);"
1323 [(set_attr "type" "multi")
1324 (set_attr "unit" "i387")
1326 (cond [(match_operand:SF 1 "" "")
1328 (match_operand:DF 1 "" "")
1331 (const_string "XF")))])
1333 (define_insn_and_split "*cmpfp_u_cc"
1334 [(set (reg:CCFPU FLAGS_REG)
1336 (match_operand 1 "register_operand" "f")
1337 (match_operand 2 "register_operand" "f")))
1338 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1339 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1340 && TARGET_SAHF && !TARGET_CMOVE
1341 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1343 "&& reload_completed"
1346 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1348 (set (reg:CC FLAGS_REG)
1349 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351 [(set_attr "type" "multi")
1352 (set_attr "unit" "i387")
1354 (cond [(match_operand:SF 1 "" "")
1356 (match_operand:DF 1 "" "")
1359 (const_string "XF")))])
1361 (define_insn "*cmpfp_<mode>"
1362 [(set (match_operand:HI 0 "register_operand" "=a")
1365 (match_operand 1 "register_operand" "f")
1366 (match_operator 3 "float_operator"
1367 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1369 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1370 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1371 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1372 "* return output_fp_compare (insn, operands, false, false);"
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1375 (set_attr "fp_int_src" "true")
1376 (set_attr "mode" "<MODE>")])
1378 (define_insn_and_split "*cmpfp_<mode>_cc"
1379 [(set (reg:CCFP FLAGS_REG)
1381 (match_operand 1 "register_operand" "f")
1382 (match_operator 3 "float_operator"
1383 [(match_operand:SWI24 2 "memory_operand" "m")])))
1384 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1386 && TARGET_SAHF && !TARGET_CMOVE
1387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1388 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1390 "&& reload_completed"
1395 (match_op_dup 3 [(match_dup 2)]))]
1397 (set (reg:CC FLAGS_REG)
1398 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1400 [(set_attr "type" "multi")
1401 (set_attr "unit" "i387")
1402 (set_attr "fp_int_src" "true")
1403 (set_attr "mode" "<MODE>")])
1405 ;; FP compares, step 2
1406 ;; Move the fpsw to ax.
1408 (define_insn "x86_fnstsw_1"
1409 [(set (match_operand:HI 0 "register_operand" "=a")
1410 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1413 [(set (attr "length")
1414 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1415 (set_attr "mode" "SI")
1416 (set_attr "unit" "i387")])
1418 ;; FP compares, step 3
1419 ;; Get ax into flags, general case.
1421 (define_insn "x86_sahf_1"
1422 [(set (reg:CC FLAGS_REG)
1423 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1427 #ifndef HAVE_AS_IX86_SAHF
1429 return ASM_BYTE "0x9e";
1434 [(set_attr "length" "1")
1435 (set_attr "athlon_decode" "vector")
1436 (set_attr "amdfam10_decode" "direct")
1437 (set_attr "bdver1_decode" "direct")
1438 (set_attr "mode" "SI")])
1440 ;; Pentium Pro can do steps 1 through 3 in one go.
1441 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1442 ;; (these i387 instructions set flags directly)
1443 (define_insn "*cmpfp_i_mixed"
1444 [(set (reg:CCFP FLAGS_REG)
1445 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1446 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1447 "TARGET_MIX_SSE_I387
1448 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1449 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1450 "* return output_fp_compare (insn, operands, true, false);"
1451 [(set_attr "type" "fcmp,ssecomi")
1452 (set_attr "prefix" "orig,maybe_vex")
1454 (if_then_else (match_operand:SF 1 "" "")
1456 (const_string "DF")))
1457 (set (attr "prefix_rep")
1458 (if_then_else (eq_attr "type" "ssecomi")
1460 (const_string "*")))
1461 (set (attr "prefix_data16")
1462 (cond [(eq_attr "type" "fcmp")
1464 (eq_attr "mode" "DF")
1467 (const_string "0")))
1468 (set_attr "athlon_decode" "vector")
1469 (set_attr "amdfam10_decode" "direct")
1470 (set_attr "bdver1_decode" "double")])
1472 (define_insn "*cmpfp_i_sse"
1473 [(set (reg:CCFP FLAGS_REG)
1474 (compare:CCFP (match_operand 0 "register_operand" "x")
1475 (match_operand 1 "nonimmediate_operand" "xm")))]
1477 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1478 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1479 "* return output_fp_compare (insn, operands, true, false);"
1480 [(set_attr "type" "ssecomi")
1481 (set_attr "prefix" "maybe_vex")
1483 (if_then_else (match_operand:SF 1 "" "")
1485 (const_string "DF")))
1486 (set_attr "prefix_rep" "0")
1487 (set (attr "prefix_data16")
1488 (if_then_else (eq_attr "mode" "DF")
1490 (const_string "0")))
1491 (set_attr "athlon_decode" "vector")
1492 (set_attr "amdfam10_decode" "direct")
1493 (set_attr "bdver1_decode" "double")])
1495 (define_insn "*cmpfp_i_i387"
1496 [(set (reg:CCFP FLAGS_REG)
1497 (compare:CCFP (match_operand 0 "register_operand" "f")
1498 (match_operand 1 "register_operand" "f")))]
1499 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1501 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, true, false);"
1504 [(set_attr "type" "fcmp")
1506 (cond [(match_operand:SF 1 "" "")
1508 (match_operand:DF 1 "" "")
1511 (const_string "XF")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")
1514 (set_attr "bdver1_decode" "double")])
1516 (define_insn "*cmpfp_iu_mixed"
1517 [(set (reg:CCFPU FLAGS_REG)
1518 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1519 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1520 "TARGET_MIX_SSE_I387
1521 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1522 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523 "* return output_fp_compare (insn, operands, true, true);"
1524 [(set_attr "type" "fcmp,ssecomi")
1525 (set_attr "prefix" "orig,maybe_vex")
1527 (if_then_else (match_operand:SF 1 "" "")
1529 (const_string "DF")))
1530 (set (attr "prefix_rep")
1531 (if_then_else (eq_attr "type" "ssecomi")
1533 (const_string "*")))
1534 (set (attr "prefix_data16")
1535 (cond [(eq_attr "type" "fcmp")
1537 (eq_attr "mode" "DF")
1540 (const_string "0")))
1541 (set_attr "athlon_decode" "vector")
1542 (set_attr "amdfam10_decode" "direct")
1543 (set_attr "bdver1_decode" "double")])
1545 (define_insn "*cmpfp_iu_sse"
1546 [(set (reg:CCFPU FLAGS_REG)
1547 (compare:CCFPU (match_operand 0 "register_operand" "x")
1548 (match_operand 1 "nonimmediate_operand" "xm")))]
1550 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1551 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1552 "* return output_fp_compare (insn, operands, true, true);"
1553 [(set_attr "type" "ssecomi")
1554 (set_attr "prefix" "maybe_vex")
1556 (if_then_else (match_operand:SF 1 "" "")
1558 (const_string "DF")))
1559 (set_attr "prefix_rep" "0")
1560 (set (attr "prefix_data16")
1561 (if_then_else (eq_attr "mode" "DF")
1563 (const_string "0")))
1564 (set_attr "athlon_decode" "vector")
1565 (set_attr "amdfam10_decode" "direct")
1566 (set_attr "bdver1_decode" "double")])
1568 (define_insn "*cmpfp_iu_387"
1569 [(set (reg:CCFPU FLAGS_REG)
1570 (compare:CCFPU (match_operand 0 "register_operand" "f")
1571 (match_operand 1 "register_operand" "f")))]
1572 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1574 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, true, true);"
1577 [(set_attr "type" "fcmp")
1579 (cond [(match_operand:SF 1 "" "")
1581 (match_operand:DF 1 "" "")
1584 (const_string "XF")))
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")
1587 (set_attr "bdver1_decode" "direct")])
1589 ;; Push/pop instructions.
1591 (define_insn "*push<mode>2"
1592 [(set (match_operand:DWI 0 "push_operand" "=<")
1593 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1596 [(set_attr "type" "multi")
1597 (set_attr "mode" "<MODE>")])
1600 [(set (match_operand:TI 0 "push_operand" "")
1601 (match_operand:TI 1 "general_operand" ""))]
1602 "TARGET_64BIT && reload_completed
1603 && !SSE_REG_P (operands[1])"
1605 "ix86_split_long_move (operands); DONE;")
1607 (define_insn "*pushdi2_rex64"
1608 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1609 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1614 [(set_attr "type" "push,multi")
1615 (set_attr "mode" "DI")])
1617 ;; Convert impossible pushes of immediate to existing instructions.
1618 ;; First try to get scratch register and go through it. In case this
1619 ;; fails, push sign extended lower part first and then overwrite
1620 ;; upper part by 32bit move.
1622 [(match_scratch:DI 2 "r")
1623 (set (match_operand:DI 0 "push_operand" "")
1624 (match_operand:DI 1 "immediate_operand" ""))]
1625 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1626 && !x86_64_immediate_operand (operands[1], DImode)"
1627 [(set (match_dup 2) (match_dup 1))
1628 (set (match_dup 0) (match_dup 2))])
1630 ;; We need to define this as both peepholer and splitter for case
1631 ;; peephole2 pass is not run.
1632 ;; "&& 1" is needed to keep it from matching the previous pattern.
1634 [(set (match_operand:DI 0 "push_operand" "")
1635 (match_operand:DI 1 "immediate_operand" ""))]
1636 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1637 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1638 [(set (match_dup 0) (match_dup 1))
1639 (set (match_dup 2) (match_dup 3))]
1641 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1643 operands[1] = gen_lowpart (DImode, operands[2]);
1644 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1649 [(set (match_operand:DI 0 "push_operand" "")
1650 (match_operand:DI 1 "immediate_operand" ""))]
1651 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1652 ? epilogue_completed : reload_completed)
1653 && !symbolic_operand (operands[1], DImode)
1654 && !x86_64_immediate_operand (operands[1], DImode)"
1655 [(set (match_dup 0) (match_dup 1))
1656 (set (match_dup 2) (match_dup 3))]
1658 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1660 operands[1] = gen_lowpart (DImode, operands[2]);
1661 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1666 [(set (match_operand:DI 0 "push_operand" "")
1667 (match_operand:DI 1 "general_operand" ""))]
1668 "!TARGET_64BIT && reload_completed
1669 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1671 "ix86_split_long_move (operands); DONE;")
1673 (define_insn "*pushsi2"
1674 [(set (match_operand:SI 0 "push_operand" "=<")
1675 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1678 [(set_attr "type" "push")
1679 (set_attr "mode" "SI")])
1681 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1682 ;; "push a byte/word". But actually we use pushl, which has the effect
1683 ;; of rounding the amount pushed up to a word.
1685 ;; For TARGET_64BIT we always round up to 8 bytes.
1686 (define_insn "*push<mode>2_rex64"
1687 [(set (match_operand:SWI124 0 "push_operand" "=X")
1688 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1691 [(set_attr "type" "push")
1692 (set_attr "mode" "DI")])
1694 (define_insn "*push<mode>2"
1695 [(set (match_operand:SWI12 0 "push_operand" "=X")
1696 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1699 [(set_attr "type" "push")
1700 (set_attr "mode" "SI")])
1702 (define_insn "*push<mode>2_prologue"
1703 [(set (match_operand:P 0 "push_operand" "=<")
1704 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1705 (clobber (mem:BLK (scratch)))]
1707 "push{<imodesuffix>}\t%1"
1708 [(set_attr "type" "push")
1709 (set_attr "mode" "<MODE>")])
1711 (define_insn "*pop<mode>1"
1712 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1713 (match_operand:P 1 "pop_operand" ">"))]
1715 "pop{<imodesuffix>}\t%0"
1716 [(set_attr "type" "pop")
1717 (set_attr "mode" "<MODE>")])
1719 (define_insn "*pop<mode>1_epilogue"
1720 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1721 (match_operand:P 1 "pop_operand" ">"))
1722 (clobber (mem:BLK (scratch)))]
1724 "pop{<imodesuffix>}\t%0"
1725 [(set_attr "type" "pop")
1726 (set_attr "mode" "<MODE>")])
1728 ;; Move instructions.
1730 (define_expand "movoi"
1731 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1732 (match_operand:OI 1 "general_operand" ""))]
1734 "ix86_expand_move (OImode, operands); DONE;")
1736 (define_expand "movti"
1737 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1738 (match_operand:TI 1 "nonimmediate_operand" ""))]
1739 "TARGET_64BIT || TARGET_SSE"
1742 ix86_expand_move (TImode, operands);
1743 else if (push_operand (operands[0], TImode))
1744 ix86_expand_push (TImode, operands[1]);
1746 ix86_expand_vector_move (TImode, operands);
1750 ;; This expands to what emit_move_complex would generate if we didn't
1751 ;; have a movti pattern. Having this avoids problems with reload on
1752 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1753 ;; to have around all the time.
1754 (define_expand "movcdi"
1755 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1756 (match_operand:CDI 1 "general_operand" ""))]
1759 if (push_operand (operands[0], CDImode))
1760 emit_move_complex_push (CDImode, operands[0], operands[1]);
1762 emit_move_complex_parts (operands[0], operands[1]);
1766 (define_expand "mov<mode>"
1767 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1768 (match_operand:SWI1248x 1 "general_operand" ""))]
1770 "ix86_expand_move (<MODE>mode, operands); DONE;")
1772 (define_insn "*mov<mode>_xor"
1773 [(set (match_operand:SWI48 0 "register_operand" "=r")
1774 (match_operand:SWI48 1 "const0_operand" ""))
1775 (clobber (reg:CC FLAGS_REG))]
1778 [(set_attr "type" "alu1")
1779 (set_attr "mode" "SI")
1780 (set_attr "length_immediate" "0")])
1782 (define_insn "*mov<mode>_or"
1783 [(set (match_operand:SWI48 0 "register_operand" "=r")
1784 (match_operand:SWI48 1 "const_int_operand" ""))
1785 (clobber (reg:CC FLAGS_REG))]
1787 && operands[1] == constm1_rtx"
1788 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1789 [(set_attr "type" "alu1")
1790 (set_attr "mode" "<MODE>")
1791 (set_attr "length_immediate" "1")])
1793 (define_insn "*movoi_internal_avx"
1794 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1795 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1796 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1798 switch (which_alternative)
1801 return standard_sse_constant_opcode (insn, operands[1]);
1804 if (misaligned_operand (operands[0], OImode)
1805 || misaligned_operand (operands[1], OImode))
1806 return "vmovdqu\t{%1, %0|%0, %1}";
1808 return "vmovdqa\t{%1, %0|%0, %1}";
1813 [(set_attr "type" "sselog1,ssemov,ssemov")
1814 (set_attr "prefix" "vex")
1815 (set_attr "mode" "OI")])
1817 (define_insn "*movti_internal_rex64"
1818 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1819 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1820 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1822 switch (which_alternative)
1828 return standard_sse_constant_opcode (insn, operands[1]);
1831 /* TDmode values are passed as TImode on the stack. Moving them
1832 to stack may result in unaligned memory access. */
1833 if (misaligned_operand (operands[0], TImode)
1834 || misaligned_operand (operands[1], TImode))
1836 if (get_attr_mode (insn) == MODE_V4SF)
1837 return "%vmovups\t{%1, %0|%0, %1}";
1839 return "%vmovdqu\t{%1, %0|%0, %1}";
1843 if (get_attr_mode (insn) == MODE_V4SF)
1844 return "%vmovaps\t{%1, %0|%0, %1}";
1846 return "%vmovdqa\t{%1, %0|%0, %1}";
1852 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1853 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1855 (cond [(eq_attr "alternative" "2,3")
1857 (match_test "optimize_function_for_size_p (cfun)")
1858 (const_string "V4SF")
1859 (const_string "TI"))
1860 (eq_attr "alternative" "4")
1862 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1863 (match_test "optimize_function_for_size_p (cfun)"))
1864 (const_string "V4SF")
1865 (const_string "TI"))]
1866 (const_string "DI")))])
1869 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1870 (match_operand:TI 1 "general_operand" ""))]
1872 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1874 "ix86_split_long_move (operands); DONE;")
1876 (define_insn "*movti_internal_sse"
1877 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1878 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1879 "TARGET_SSE && !TARGET_64BIT
1880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1882 switch (which_alternative)
1885 return standard_sse_constant_opcode (insn, operands[1]);
1888 /* TDmode values are passed as TImode on the stack. Moving them
1889 to stack may result in unaligned memory access. */
1890 if (misaligned_operand (operands[0], TImode)
1891 || misaligned_operand (operands[1], TImode))
1893 if (get_attr_mode (insn) == MODE_V4SF)
1894 return "%vmovups\t{%1, %0|%0, %1}";
1896 return "%vmovdqu\t{%1, %0|%0, %1}";
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vmovaps\t{%1, %0|%0, %1}";
1903 return "%vmovdqa\t{%1, %0|%0, %1}";
1909 [(set_attr "type" "sselog1,ssemov,ssemov")
1910 (set_attr "prefix" "maybe_vex")
1912 (cond [(ior (not (match_test "TARGET_SSE2"))
1913 (match_test "optimize_function_for_size_p (cfun)"))
1914 (const_string "V4SF")
1915 (and (eq_attr "alternative" "2")
1916 (match_test "TARGET_SSE_TYPELESS_STORES"))
1917 (const_string "V4SF")]
1918 (const_string "TI")))])
1920 (define_insn "*movdi_internal_rex64"
1921 [(set (match_operand:DI 0 "nonimmediate_operand"
1922 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1923 (match_operand:DI 1 "general_operand"
1924 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1925 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1927 switch (get_attr_type (insn))
1930 if (SSE_REG_P (operands[0]))
1931 return "movq2dq\t{%1, %0|%0, %1}";
1933 return "movdq2q\t{%1, %0|%0, %1}";
1936 if (get_attr_mode (insn) == MODE_TI)
1937 return "%vmovdqa\t{%1, %0|%0, %1}";
1938 /* Handle broken assemblers that require movd instead of movq. */
1939 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1940 return "%vmovd\t{%1, %0|%0, %1}";
1942 return "%vmovq\t{%1, %0|%0, %1}";
1945 /* Handle broken assemblers that require movd instead of movq. */
1946 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1947 return "movd\t{%1, %0|%0, %1}";
1949 return "movq\t{%1, %0|%0, %1}";
1952 return standard_sse_constant_opcode (insn, operands[1]);
1955 return "pxor\t%0, %0";
1961 return "lea{q}\t{%E1, %0|%0, %E1}";
1964 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1965 if (get_attr_mode (insn) == MODE_SI)
1966 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1967 else if (which_alternative == 2)
1968 return "movabs{q}\t{%1, %0|%0, %1}";
1969 else if (ix86_use_lea_for_mov (insn, operands))
1970 return "lea{q}\t{%E1, %0|%0, %E1}";
1972 return "mov{q}\t{%1, %0|%0, %1}";
1976 (cond [(eq_attr "alternative" "4")
1977 (const_string "multi")
1978 (eq_attr "alternative" "5")
1979 (const_string "mmx")
1980 (eq_attr "alternative" "6,7,8,9")
1981 (const_string "mmxmov")
1982 (eq_attr "alternative" "10")
1983 (const_string "sselog1")
1984 (eq_attr "alternative" "11,12,13,14,15")
1985 (const_string "ssemov")
1986 (eq_attr "alternative" "16,17")
1987 (const_string "ssecvt")
1988 (match_operand 1 "pic_32bit_operand" "")
1989 (const_string "lea")
1991 (const_string "imov")))
1994 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1996 (const_string "*")))
1997 (set (attr "length_immediate")
1999 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2001 (const_string "*")))
2002 (set (attr "prefix_rex")
2003 (if_then_else (eq_attr "alternative" "8,9")
2005 (const_string "*")))
2006 (set (attr "prefix_data16")
2007 (if_then_else (eq_attr "alternative" "11")
2009 (const_string "*")))
2010 (set (attr "prefix")
2011 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2012 (const_string "maybe_vex")
2013 (const_string "orig")))
2014 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2016 ;; Reload patterns to support multi-word load/store
2017 ;; with non-offsetable address.
2018 (define_expand "reload_noff_store"
2019 [(parallel [(match_operand 0 "memory_operand" "=m")
2020 (match_operand 1 "register_operand" "r")
2021 (match_operand:DI 2 "register_operand" "=&r")])]
2024 rtx mem = operands[0];
2025 rtx addr = XEXP (mem, 0);
2027 emit_move_insn (operands[2], addr);
2028 mem = replace_equiv_address_nv (mem, operands[2]);
2030 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2034 (define_expand "reload_noff_load"
2035 [(parallel [(match_operand 0 "register_operand" "=r")
2036 (match_operand 1 "memory_operand" "m")
2037 (match_operand:DI 2 "register_operand" "=r")])]
2040 rtx mem = operands[1];
2041 rtx addr = XEXP (mem, 0);
2043 emit_move_insn (operands[2], addr);
2044 mem = replace_equiv_address_nv (mem, operands[2]);
2046 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2050 ;; Convert impossible stores of immediate to existing instructions.
2051 ;; First try to get scratch register and go through it. In case this
2052 ;; fails, move by 32bit parts.
2054 [(match_scratch:DI 2 "r")
2055 (set (match_operand:DI 0 "memory_operand" "")
2056 (match_operand:DI 1 "immediate_operand" ""))]
2057 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2058 && !x86_64_immediate_operand (operands[1], DImode)"
2059 [(set (match_dup 2) (match_dup 1))
2060 (set (match_dup 0) (match_dup 2))])
2062 ;; We need to define this as both peepholer and splitter for case
2063 ;; peephole2 pass is not run.
2064 ;; "&& 1" is needed to keep it from matching the previous pattern.
2066 [(set (match_operand:DI 0 "memory_operand" "")
2067 (match_operand:DI 1 "immediate_operand" ""))]
2068 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2069 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2070 [(set (match_dup 2) (match_dup 3))
2071 (set (match_dup 4) (match_dup 5))]
2072 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2075 [(set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2078 ? epilogue_completed : reload_completed)
2079 && !symbolic_operand (operands[1], DImode)
2080 && !x86_64_immediate_operand (operands[1], DImode)"
2081 [(set (match_dup 2) (match_dup 3))
2082 (set (match_dup 4) (match_dup 5))]
2083 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2085 (define_insn "*movdi_internal"
2086 [(set (match_operand:DI 0 "nonimmediate_operand"
2087 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2088 (match_operand:DI 1 "general_operand"
2089 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2090 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2092 switch (get_attr_type (insn))
2095 if (SSE_REG_P (operands[0]))
2096 return "movq2dq\t{%1, %0|%0, %1}";
2098 return "movdq2q\t{%1, %0|%0, %1}";
2101 switch (get_attr_mode (insn))
2104 return "%vmovdqa\t{%1, %0|%0, %1}";
2106 return "%vmovq\t{%1, %0|%0, %1}";
2108 return "movaps\t{%1, %0|%0, %1}";
2110 return "movlps\t{%1, %0|%0, %1}";
2116 return "movq\t{%1, %0|%0, %1}";
2119 return standard_sse_constant_opcode (insn, operands[1]);
2122 return "pxor\t%0, %0";
2132 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2133 (const_string "sse2")
2134 (eq_attr "alternative" "9,10,11,12")
2135 (const_string "noavx")
2137 (const_string "*")))
2139 (cond [(eq_attr "alternative" "0,1")
2140 (const_string "multi")
2141 (eq_attr "alternative" "2")
2142 (const_string "mmx")
2143 (eq_attr "alternative" "3,4")
2144 (const_string "mmxmov")
2145 (eq_attr "alternative" "5,9")
2146 (const_string "sselog1")
2147 (eq_attr "alternative" "13,14")
2148 (const_string "ssecvt")
2150 (const_string "ssemov")))
2151 (set (attr "prefix")
2152 (if_then_else (eq_attr "alternative" "5,6,7,8")
2153 (const_string "maybe_vex")
2154 (const_string "orig")))
2155 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2158 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2159 (match_operand:DI 1 "general_operand" ""))]
2160 "!TARGET_64BIT && reload_completed
2161 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2162 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2164 "ix86_split_long_move (operands); DONE;")
2166 (define_insn "*movsi_internal"
2167 [(set (match_operand:SI 0 "nonimmediate_operand"
2168 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2169 (match_operand:SI 1 "general_operand"
2170 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2171 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2173 switch (get_attr_type (insn))
2176 return standard_sse_constant_opcode (insn, operands[1]);
2179 switch (get_attr_mode (insn))
2182 return "%vmovdqa\t{%1, %0|%0, %1}";
2184 return "%vmovaps\t{%1, %0|%0, %1}";
2186 return "%vmovd\t{%1, %0|%0, %1}";
2188 return "%vmovss\t{%1, %0|%0, %1}";
2194 return "pxor\t%0, %0";
2197 if (get_attr_mode (insn) == MODE_DI)
2198 return "movq\t{%1, %0|%0, %1}";
2199 return "movd\t{%1, %0|%0, %1}";
2202 return "lea{l}\t{%E1, %0|%0, %E1}";
2205 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2206 if (ix86_use_lea_for_mov (insn, operands))
2207 return "lea{l}\t{%E1, %0|%0, %E1}";
2209 return "mov{l}\t{%1, %0|%0, %1}";
2213 (cond [(eq_attr "alternative" "2")
2214 (const_string "mmx")
2215 (eq_attr "alternative" "3,4,5")
2216 (const_string "mmxmov")
2217 (eq_attr "alternative" "6")
2218 (const_string "sselog1")
2219 (eq_attr "alternative" "7,8,9,10,11")
2220 (const_string "ssemov")
2221 (match_operand 1 "pic_32bit_operand" "")
2222 (const_string "lea")
2224 (const_string "imov")))
2225 (set (attr "prefix")
2226 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2227 (const_string "orig")
2228 (const_string "maybe_vex")))
2229 (set (attr "prefix_data16")
2230 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2232 (const_string "*")))
2234 (cond [(eq_attr "alternative" "2,3")
2236 (eq_attr "alternative" "6,7")
2238 (not (match_test "TARGET_SSE2"))
2239 (const_string "V4SF")
2240 (const_string "TI"))
2241 (and (eq_attr "alternative" "8,9,10,11")
2242 (not (match_test "TARGET_SSE2")))
2245 (const_string "SI")))])
2247 (define_insn "*movhi_internal"
2248 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2249 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2250 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2252 switch (get_attr_type (insn))
2255 /* movzwl is faster than movw on p2 due to partial word stalls,
2256 though not as fast as an aligned movl. */
2257 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2259 if (get_attr_mode (insn) == MODE_SI)
2260 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2262 return "mov{w}\t{%1, %0|%0, %1}";
2266 (cond [(match_test "optimize_function_for_size_p (cfun)")
2267 (const_string "imov")
2268 (and (eq_attr "alternative" "0")
2269 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2270 (not (match_test "TARGET_HIMODE_MATH"))))
2271 (const_string "imov")
2272 (and (eq_attr "alternative" "1,2")
2273 (match_operand:HI 1 "aligned_operand" ""))
2274 (const_string "imov")
2275 (and (match_test "TARGET_MOVX")
2276 (eq_attr "alternative" "0,2"))
2277 (const_string "imovx")
2279 (const_string "imov")))
2281 (cond [(eq_attr "type" "imovx")
2283 (and (eq_attr "alternative" "1,2")
2284 (match_operand:HI 1 "aligned_operand" ""))
2286 (and (eq_attr "alternative" "0")
2287 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2288 (not (match_test "TARGET_HIMODE_MATH"))))
2291 (const_string "HI")))])
2293 ;; Situation is quite tricky about when to choose full sized (SImode) move
2294 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2295 ;; partial register dependency machines (such as AMD Athlon), where QImode
2296 ;; moves issue extra dependency and for partial register stalls machines
2297 ;; that don't use QImode patterns (and QImode move cause stall on the next
2300 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2301 ;; register stall machines with, where we use QImode instructions, since
2302 ;; partial register stall can be caused there. Then we use movzx.
2303 (define_insn "*movqi_internal"
2304 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2305 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2306 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2308 switch (get_attr_type (insn))
2311 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2312 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2314 if (get_attr_mode (insn) == MODE_SI)
2315 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2317 return "mov{b}\t{%1, %0|%0, %1}";
2321 (cond [(and (eq_attr "alternative" "5")
2322 (not (match_operand:QI 1 "aligned_operand" "")))
2323 (const_string "imovx")
2324 (match_test "optimize_function_for_size_p (cfun)")
2325 (const_string "imov")
2326 (and (eq_attr "alternative" "3")
2327 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2328 (not (match_test "TARGET_QIMODE_MATH"))))
2329 (const_string "imov")
2330 (eq_attr "alternative" "3,5")
2331 (const_string "imovx")
2332 (and (match_test "TARGET_MOVX")
2333 (eq_attr "alternative" "2"))
2334 (const_string "imovx")
2336 (const_string "imov")))
2338 (cond [(eq_attr "alternative" "3,4,5")
2340 (eq_attr "alternative" "6")
2342 (eq_attr "type" "imovx")
2344 (and (eq_attr "type" "imov")
2345 (and (eq_attr "alternative" "0,1")
2346 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2347 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2348 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2350 ;; Avoid partial register stalls when not using QImode arithmetic
2351 (and (eq_attr "type" "imov")
2352 (and (eq_attr "alternative" "0,1")
2353 (and (match_test "TARGET_PARTIAL_REG_STALL")
2354 (not (match_test "TARGET_QIMODE_MATH")))))
2357 (const_string "QI")))])
2359 ;; Stores and loads of ax to arbitrary constant address.
2360 ;; We fake an second form of instruction to force reload to load address
2361 ;; into register when rax is not available
2362 (define_insn "*movabs<mode>_1"
2363 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2364 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2365 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2367 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2368 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2369 [(set_attr "type" "imov")
2370 (set_attr "modrm" "0,*")
2371 (set_attr "length_address" "8,0")
2372 (set_attr "length_immediate" "0,*")
2373 (set_attr "memory" "store")
2374 (set_attr "mode" "<MODE>")])
2376 (define_insn "*movabs<mode>_2"
2377 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2378 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2379 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2381 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2382 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2383 [(set_attr "type" "imov")
2384 (set_attr "modrm" "0,*")
2385 (set_attr "length_address" "8,0")
2386 (set_attr "length_immediate" "0")
2387 (set_attr "memory" "load")
2388 (set_attr "mode" "<MODE>")])
2390 (define_insn "*swap<mode>"
2391 [(set (match_operand:SWI48 0 "register_operand" "+r")
2392 (match_operand:SWI48 1 "register_operand" "+r"))
2396 "xchg{<imodesuffix>}\t%1, %0"
2397 [(set_attr "type" "imov")
2398 (set_attr "mode" "<MODE>")
2399 (set_attr "pent_pair" "np")
2400 (set_attr "athlon_decode" "vector")
2401 (set_attr "amdfam10_decode" "double")
2402 (set_attr "bdver1_decode" "double")])
2404 (define_insn "*swap<mode>_1"
2405 [(set (match_operand:SWI12 0 "register_operand" "+r")
2406 (match_operand:SWI12 1 "register_operand" "+r"))
2409 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2411 [(set_attr "type" "imov")
2412 (set_attr "mode" "SI")
2413 (set_attr "pent_pair" "np")
2414 (set_attr "athlon_decode" "vector")
2415 (set_attr "amdfam10_decode" "double")
2416 (set_attr "bdver1_decode" "double")])
2418 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2419 ;; is disabled for AMDFAM10
2420 (define_insn "*swap<mode>_2"
2421 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2422 (match_operand:SWI12 1 "register_operand" "+<r>"))
2425 "TARGET_PARTIAL_REG_STALL"
2426 "xchg{<imodesuffix>}\t%1, %0"
2427 [(set_attr "type" "imov")
2428 (set_attr "mode" "<MODE>")
2429 (set_attr "pent_pair" "np")
2430 (set_attr "athlon_decode" "vector")])
2432 (define_expand "movstrict<mode>"
2433 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2434 (match_operand:SWI12 1 "general_operand" ""))]
2437 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2439 if (GET_CODE (operands[0]) == SUBREG
2440 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2442 /* Don't generate memory->memory moves, go through a register */
2443 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2444 operands[1] = force_reg (<MODE>mode, operands[1]);
2447 (define_insn "*movstrict<mode>_1"
2448 [(set (strict_low_part
2449 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2450 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2451 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2452 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2453 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2454 [(set_attr "type" "imov")
2455 (set_attr "mode" "<MODE>")])
2457 (define_insn "*movstrict<mode>_xor"
2458 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2459 (match_operand:SWI12 1 "const0_operand" ""))
2460 (clobber (reg:CC FLAGS_REG))]
2462 "xor{<imodesuffix>}\t%0, %0"
2463 [(set_attr "type" "alu1")
2464 (set_attr "mode" "<MODE>")
2465 (set_attr "length_immediate" "0")])
2467 (define_insn "*mov<mode>_extv_1"
2468 [(set (match_operand:SWI24 0 "register_operand" "=R")
2469 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2473 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2474 [(set_attr "type" "imovx")
2475 (set_attr "mode" "SI")])
2477 (define_insn "*movqi_extv_1_rex64"
2478 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2479 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2484 switch (get_attr_type (insn))
2487 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2489 return "mov{b}\t{%h1, %0|%0, %h1}";
2493 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2494 (match_test "TARGET_MOVX"))
2495 (const_string "imovx")
2496 (const_string "imov")))
2498 (if_then_else (eq_attr "type" "imovx")
2500 (const_string "QI")))])
2502 (define_insn "*movqi_extv_1"
2503 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2504 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2509 switch (get_attr_type (insn))
2512 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2514 return "mov{b}\t{%h1, %0|%0, %h1}";
2518 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2519 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2520 (match_test "TARGET_MOVX")))
2521 (const_string "imovx")
2522 (const_string "imov")))
2524 (if_then_else (eq_attr "type" "imovx")
2526 (const_string "QI")))])
2528 (define_insn "*mov<mode>_extzv_1"
2529 [(set (match_operand:SWI48 0 "register_operand" "=R")
2530 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2534 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535 [(set_attr "type" "imovx")
2536 (set_attr "mode" "SI")])
2538 (define_insn "*movqi_extzv_2_rex64"
2539 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2541 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2546 switch (get_attr_type (insn))
2549 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2555 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2556 (match_test "TARGET_MOVX"))
2557 (const_string "imovx")
2558 (const_string "imov")))
2560 (if_then_else (eq_attr "type" "imovx")
2562 (const_string "QI")))])
2564 (define_insn "*movqi_extzv_2"
2565 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2567 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2572 switch (get_attr_type (insn))
2575 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2577 return "mov{b}\t{%h1, %0|%0, %h1}";
2581 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2582 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2583 (match_test "TARGET_MOVX")))
2584 (const_string "imovx")
2585 (const_string "imov")))
2587 (if_then_else (eq_attr "type" "imovx")
2589 (const_string "QI")))])
2591 (define_expand "mov<mode>_insv_1"
2592 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2595 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2597 (define_insn "*mov<mode>_insv_1_rex64"
2598 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2601 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2604 if (CONST_INT_P (operands[1]))
2605 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2606 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2608 [(set_attr "type" "imov")
2609 (set_attr "mode" "QI")])
2611 (define_insn "*movsi_insv_1"
2612 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2615 (match_operand:SI 1 "general_operand" "Qmn"))]
2618 if (CONST_INT_P (operands[1]))
2619 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2620 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2622 [(set_attr "type" "imov")
2623 (set_attr "mode" "QI")])
2625 (define_insn "*movqi_insv_2"
2626 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2629 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2632 "mov{b}\t{%h1, %h0|%h0, %h1}"
2633 [(set_attr "type" "imov")
2634 (set_attr "mode" "QI")])
2636 ;; Floating point push instructions.
2638 (define_insn "*pushtf"
2639 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2640 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2643 /* This insn should be already split before reg-stack. */
2646 [(set_attr "type" "multi")
2647 (set_attr "unit" "sse,*,*")
2648 (set_attr "mode" "TF,SI,SI")])
2650 ;; %%% Kill this when call knows how to work this out.
2652 [(set (match_operand:TF 0 "push_operand" "")
2653 (match_operand:TF 1 "sse_reg_operand" ""))]
2654 "TARGET_SSE2 && reload_completed"
2655 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2656 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2658 (define_insn "*pushxf"
2659 [(set (match_operand:XF 0 "push_operand" "=<,<")
2660 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2661 "optimize_function_for_speed_p (cfun)"
2663 /* This insn should be already split before reg-stack. */
2666 [(set_attr "type" "multi")
2667 (set_attr "unit" "i387,*")
2668 (set_attr "mode" "XF,SI")])
2670 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2671 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2672 ;; Pushing using integer instructions is longer except for constants
2673 ;; and direct memory references (assuming that any given constant is pushed
2674 ;; only once, but this ought to be handled elsewhere).
2676 (define_insn "*pushxf_nointeger"
2677 [(set (match_operand:XF 0 "push_operand" "=<,<")
2678 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2679 "optimize_function_for_size_p (cfun)"
2681 /* This insn should be already split before reg-stack. */
2684 [(set_attr "type" "multi")
2685 (set_attr "unit" "i387,*")
2686 (set_attr "mode" "XF,SI")])
2688 ;; %%% Kill this when call knows how to work this out.
2690 [(set (match_operand:XF 0 "push_operand" "")
2691 (match_operand:XF 1 "fp_register_operand" ""))]
2693 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2694 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2695 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2697 (define_insn "*pushdf_rex64"
2698 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2699 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2702 /* This insn should be already split before reg-stack. */
2705 [(set_attr "type" "multi")
2706 (set_attr "unit" "i387,*,*")
2707 (set_attr "mode" "DF,DI,DF")])
2709 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2710 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2711 ;; On the average, pushdf using integers can be still shorter.
2713 (define_insn "*pushdf"
2714 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2715 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2718 /* This insn should be already split before reg-stack. */
2721 [(set_attr "isa" "*,*,sse2")
2722 (set_attr "type" "multi")
2723 (set_attr "unit" "i387,*,*")
2724 (set_attr "mode" "DF,DI,DF")])
2726 ;; %%% Kill this when call knows how to work this out.
2728 [(set (match_operand:DF 0 "push_operand" "")
2729 (match_operand:DF 1 "any_fp_register_operand" ""))]
2731 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2732 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2734 (define_insn "*pushsf_rex64"
2735 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2736 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2739 /* Anything else should be already split before reg-stack. */
2740 gcc_assert (which_alternative == 1);
2741 return "push{q}\t%q1";
2743 [(set_attr "type" "multi,push,multi")
2744 (set_attr "unit" "i387,*,*")
2745 (set_attr "mode" "SF,DI,SF")])
2747 (define_insn "*pushsf"
2748 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2749 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2752 /* Anything else should be already split before reg-stack. */
2753 gcc_assert (which_alternative == 1);
2754 return "push{l}\t%1";
2756 [(set_attr "type" "multi,push,multi")
2757 (set_attr "unit" "i387,*,*")
2758 (set_attr "mode" "SF,SI,SF")])
2760 ;; %%% Kill this when call knows how to work this out.
2762 [(set (match_operand:SF 0 "push_operand" "")
2763 (match_operand:SF 1 "any_fp_register_operand" ""))]
2765 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2766 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2767 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2770 [(set (match_operand:SF 0 "push_operand" "")
2771 (match_operand:SF 1 "memory_operand" ""))]
2773 && (operands[2] = find_constant_src (insn))"
2774 [(set (match_dup 0) (match_dup 2))])
2777 [(set (match_operand 0 "push_operand" "")
2778 (match_operand 1 "general_operand" ""))]
2780 && (GET_MODE (operands[0]) == TFmode
2781 || GET_MODE (operands[0]) == XFmode
2782 || GET_MODE (operands[0]) == DFmode)
2783 && !ANY_FP_REG_P (operands[1])"
2785 "ix86_split_long_move (operands); DONE;")
2787 ;; Floating point move instructions.
2789 (define_expand "movtf"
2790 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2791 (match_operand:TF 1 "nonimmediate_operand" ""))]
2794 ix86_expand_move (TFmode, operands);
2798 (define_expand "mov<mode>"
2799 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2800 (match_operand:X87MODEF 1 "general_operand" ""))]
2802 "ix86_expand_move (<MODE>mode, operands); DONE;")
2804 (define_insn "*movtf_internal"
2805 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2806 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2808 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2809 && (!can_create_pseudo_p ()
2810 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2811 || GET_CODE (operands[1]) != CONST_DOUBLE
2812 || (optimize_function_for_size_p (cfun)
2813 && standard_sse_constant_p (operands[1])
2814 && !memory_operand (operands[0], TFmode))
2815 || (!TARGET_MEMORY_MISMATCH_STALL
2816 && memory_operand (operands[0], TFmode)))"
2818 switch (which_alternative)
2822 /* Handle misaligned load/store since we
2823 don't have movmisaligntf pattern. */
2824 if (misaligned_operand (operands[0], TFmode)
2825 || misaligned_operand (operands[1], TFmode))
2827 if (get_attr_mode (insn) == MODE_V4SF)
2828 return "%vmovups\t{%1, %0|%0, %1}";
2830 return "%vmovdqu\t{%1, %0|%0, %1}";
2834 if (get_attr_mode (insn) == MODE_V4SF)
2835 return "%vmovaps\t{%1, %0|%0, %1}";
2837 return "%vmovdqa\t{%1, %0|%0, %1}";
2841 return standard_sse_constant_opcode (insn, operands[1]);
2851 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2852 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2854 (cond [(eq_attr "alternative" "0,2")
2856 (match_test "optimize_function_for_size_p (cfun)")
2857 (const_string "V4SF")
2858 (const_string "TI"))
2859 (eq_attr "alternative" "1")
2861 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2862 (match_test "optimize_function_for_size_p (cfun)"))
2863 (const_string "V4SF")
2864 (const_string "TI"))]
2865 (const_string "DI")))])
2867 ;; Possible store forwarding (partial memory) stall in alternative 4.
2868 (define_insn "*movxf_internal"
2869 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2870 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2871 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2872 && (!can_create_pseudo_p ()
2873 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2874 || GET_CODE (operands[1]) != CONST_DOUBLE
2875 || (optimize_function_for_size_p (cfun)
2876 && standard_80387_constant_p (operands[1]) > 0
2877 && !memory_operand (operands[0], XFmode))
2878 || (!TARGET_MEMORY_MISMATCH_STALL
2879 && memory_operand (operands[0], XFmode)))"
2881 switch (which_alternative)
2885 return output_387_reg_move (insn, operands);
2888 return standard_80387_constant_opcode (operands[1]);
2898 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2899 (set_attr "mode" "XF,XF,XF,SI,SI")])
2901 (define_insn "*movdf_internal_rex64"
2902 [(set (match_operand:DF 0 "nonimmediate_operand"
2903 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2904 (match_operand:DF 1 "general_operand"
2905 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2906 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2907 && (!can_create_pseudo_p ()
2908 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2909 || GET_CODE (operands[1]) != CONST_DOUBLE
2910 || (optimize_function_for_size_p (cfun)
2911 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2912 && standard_80387_constant_p (operands[1]) > 0)
2913 || (TARGET_SSE2 && TARGET_SSE_MATH
2914 && standard_sse_constant_p (operands[1]))))
2915 || memory_operand (operands[0], DFmode))"
2917 switch (which_alternative)
2921 return output_387_reg_move (insn, operands);
2924 return standard_80387_constant_opcode (operands[1]);
2928 return "mov{q}\t{%1, %0|%0, %1}";
2931 return "movabs{q}\t{%1, %0|%0, %1}";
2937 return standard_sse_constant_opcode (insn, operands[1]);
2942 switch (get_attr_mode (insn))
2945 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2946 return "%vmovapd\t{%1, %0|%0, %1}";
2948 return "%vmovaps\t{%1, %0|%0, %1}";
2951 return "%vmovq\t{%1, %0|%0, %1}";
2953 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2954 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2955 return "%vmovsd\t{%1, %0|%0, %1}";
2957 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2959 return "%vmovlps\t{%1, %d0|%d0, %1}";
2966 /* Handle broken assemblers that require movd instead of movq. */
2967 return "%vmovd\t{%1, %0|%0, %1}";
2974 (cond [(eq_attr "alternative" "0,1,2")
2975 (const_string "fmov")
2976 (eq_attr "alternative" "3,4,5")
2977 (const_string "imov")
2978 (eq_attr "alternative" "6")
2979 (const_string "multi")
2980 (eq_attr "alternative" "7")
2981 (const_string "sselog1")
2983 (const_string "ssemov")))
2986 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2988 (const_string "*")))
2989 (set (attr "length_immediate")
2991 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2993 (const_string "*")))
2994 (set (attr "prefix")
2995 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2996 (const_string "orig")
2997 (const_string "maybe_vex")))
2998 (set (attr "prefix_data16")
2999 (if_then_else (eq_attr "mode" "V1DF")
3001 (const_string "*")))
3003 (cond [(eq_attr "alternative" "0,1,2")
3005 (eq_attr "alternative" "3,4,5,6,11,12")
3008 /* xorps is one byte shorter. */
3009 (eq_attr "alternative" "7")
3010 (cond [(match_test "optimize_function_for_size_p (cfun)")
3011 (const_string "V4SF")
3012 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3015 (const_string "V2DF"))
3017 /* For architectures resolving dependencies on
3018 whole SSE registers use APD move to break dependency
3019 chains, otherwise use short move to avoid extra work.
3021 movaps encodes one byte shorter. */
3022 (eq_attr "alternative" "8")
3024 [(match_test "optimize_function_for_size_p (cfun)")
3025 (const_string "V4SF")
3026 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3027 (const_string "V2DF")
3029 (const_string "DF"))
3030 /* For architectures resolving dependencies on register
3031 parts we may avoid extra work to zero out upper part
3033 (eq_attr "alternative" "9")
3035 (match_test "TARGET_SSE_SPLIT_REGS")
3036 (const_string "V1DF")
3037 (const_string "DF"))
3039 (const_string "DF")))])
3041 ;; Possible store forwarding (partial memory) stall in alternative 4.
3042 (define_insn "*movdf_internal"
3043 [(set (match_operand:DF 0 "nonimmediate_operand"
3044 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3045 (match_operand:DF 1 "general_operand"
3046 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3047 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3048 && (!can_create_pseudo_p ()
3049 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3050 || GET_CODE (operands[1]) != CONST_DOUBLE
3051 || (optimize_function_for_size_p (cfun)
3052 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3053 && standard_80387_constant_p (operands[1]) > 0)
3054 || (TARGET_SSE2 && TARGET_SSE_MATH
3055 && standard_sse_constant_p (operands[1])))
3056 && !memory_operand (operands[0], DFmode))
3057 || (!TARGET_MEMORY_MISMATCH_STALL
3058 && memory_operand (operands[0], DFmode)))"
3060 switch (which_alternative)
3064 return output_387_reg_move (insn, operands);
3067 return standard_80387_constant_opcode (operands[1]);
3075 return standard_sse_constant_opcode (insn, operands[1]);
3083 switch (get_attr_mode (insn))
3086 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3087 return "%vmovapd\t{%1, %0|%0, %1}";
3089 return "%vmovaps\t{%1, %0|%0, %1}";
3092 return "%vmovq\t{%1, %0|%0, %1}";
3094 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3095 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3096 return "%vmovsd\t{%1, %0|%0, %1}";
3098 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3100 return "%vmovlps\t{%1, %d0|%d0, %1}";
3110 (if_then_else (eq_attr "alternative" "5,6,7,8")
3111 (const_string "sse2")
3112 (const_string "*")))
3114 (cond [(eq_attr "alternative" "0,1,2")
3115 (const_string "fmov")
3116 (eq_attr "alternative" "3,4")
3117 (const_string "multi")
3118 (eq_attr "alternative" "5,9")
3119 (const_string "sselog1")
3121 (const_string "ssemov")))
3122 (set (attr "prefix")
3123 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3124 (const_string "orig")
3125 (const_string "maybe_vex")))
3126 (set (attr "prefix_data16")
3127 (if_then_else (eq_attr "mode" "V1DF")
3129 (const_string "*")))
3131 (cond [(eq_attr "alternative" "0,1,2")
3133 (eq_attr "alternative" "3,4")
3136 /* For SSE1, we have many fewer alternatives. */
3137 (not (match_test "TARGET_SSE2"))
3139 (eq_attr "alternative" "5,6,9,10")
3140 (const_string "V4SF")
3141 (const_string "V2SF"))
3143 /* xorps is one byte shorter. */
3144 (eq_attr "alternative" "5,9")
3145 (cond [(match_test "optimize_function_for_size_p (cfun)")
3146 (const_string "V4SF")
3147 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3150 (const_string "V2DF"))
3152 /* For architectures resolving dependencies on
3153 whole SSE registers use APD move to break dependency
3154 chains, otherwise use short move to avoid extra work.
3156 movaps encodes one byte shorter. */
3157 (eq_attr "alternative" "6,10")
3159 [(match_test "optimize_function_for_size_p (cfun)")
3160 (const_string "V4SF")
3161 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3162 (const_string "V2DF")
3164 (const_string "DF"))
3165 /* For architectures resolving dependencies on register
3166 parts we may avoid extra work to zero out upper part
3168 (eq_attr "alternative" "7,11")
3170 (match_test "TARGET_SSE_SPLIT_REGS")
3171 (const_string "V1DF")
3172 (const_string "DF"))
3174 (const_string "DF")))])
3176 (define_insn "*movsf_internal"
3177 [(set (match_operand:SF 0 "nonimmediate_operand"
3178 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3179 (match_operand:SF 1 "general_operand"
3180 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3181 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3182 && (!can_create_pseudo_p ()
3183 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3184 || GET_CODE (operands[1]) != CONST_DOUBLE
3185 || (optimize_function_for_size_p (cfun)
3186 && ((!TARGET_SSE_MATH
3187 && standard_80387_constant_p (operands[1]) > 0)
3189 && standard_sse_constant_p (operands[1]))))
3190 || memory_operand (operands[0], SFmode))"
3192 switch (which_alternative)
3196 return output_387_reg_move (insn, operands);
3199 return standard_80387_constant_opcode (operands[1]);
3203 return "mov{l}\t{%1, %0|%0, %1}";
3206 return standard_sse_constant_opcode (insn, operands[1]);
3209 if (get_attr_mode (insn) == MODE_V4SF)
3210 return "%vmovaps\t{%1, %0|%0, %1}";
3212 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3216 return "%vmovss\t{%1, %0|%0, %1}";
3222 return "movd\t{%1, %0|%0, %1}";
3225 return "movq\t{%1, %0|%0, %1}";
3229 return "%vmovd\t{%1, %0|%0, %1}";
3236 (cond [(eq_attr "alternative" "0,1,2")
3237 (const_string "fmov")
3238 (eq_attr "alternative" "3,4")
3239 (const_string "multi")
3240 (eq_attr "alternative" "5")
3241 (const_string "sselog1")
3242 (eq_attr "alternative" "9,10,11,14,15")
3243 (const_string "mmxmov")
3245 (const_string "ssemov")))
3246 (set (attr "prefix")
3247 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3248 (const_string "maybe_vex")
3249 (const_string "orig")))
3251 (cond [(eq_attr "alternative" "3,4,9,10")
3253 (eq_attr "alternative" "5")
3255 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3256 (match_test "TARGET_SSE2"))
3257 (not (match_test "optimize_function_for_size_p (cfun)")))
3259 (const_string "V4SF"))
3260 /* For architectures resolving dependencies on
3261 whole SSE registers use APS move to break dependency
3262 chains, otherwise use short move to avoid extra work.
3264 Do the same for architectures resolving dependencies on
3265 the parts. While in DF mode it is better to always handle
3266 just register parts, the SF mode is different due to lack
3267 of instructions to load just part of the register. It is
3268 better to maintain the whole registers in single format
3269 to avoid problems on using packed logical operations. */
3270 (eq_attr "alternative" "6")
3272 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3273 (match_test "TARGET_SSE_SPLIT_REGS"))
3274 (const_string "V4SF")
3275 (const_string "SF"))
3276 (eq_attr "alternative" "11")
3277 (const_string "DI")]
3278 (const_string "SF")))])
3281 [(set (match_operand 0 "any_fp_register_operand" "")
3282 (match_operand 1 "memory_operand" ""))]
3284 && (GET_MODE (operands[0]) == TFmode
3285 || GET_MODE (operands[0]) == XFmode
3286 || GET_MODE (operands[0]) == DFmode
3287 || GET_MODE (operands[0]) == SFmode)
3288 && (operands[2] = find_constant_src (insn))"
3289 [(set (match_dup 0) (match_dup 2))]
3291 rtx c = operands[2];
3292 int r = REGNO (operands[0]);
3294 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3295 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3300 [(set (match_operand 0 "any_fp_register_operand" "")
3301 (float_extend (match_operand 1 "memory_operand" "")))]
3303 && (GET_MODE (operands[0]) == TFmode
3304 || GET_MODE (operands[0]) == XFmode
3305 || GET_MODE (operands[0]) == DFmode)
3306 && (operands[2] = find_constant_src (insn))"
3307 [(set (match_dup 0) (match_dup 2))]
3309 rtx c = operands[2];
3310 int r = REGNO (operands[0]);
3312 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3313 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3317 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3319 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3320 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3322 && (standard_80387_constant_p (operands[1]) == 8
3323 || standard_80387_constant_p (operands[1]) == 9)"
3324 [(set (match_dup 0)(match_dup 1))
3326 (neg:X87MODEF (match_dup 0)))]
3330 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3331 if (real_isnegzero (&r))
3332 operands[1] = CONST0_RTX (<MODE>mode);
3334 operands[1] = CONST1_RTX (<MODE>mode);
3338 [(set (match_operand 0 "nonimmediate_operand" "")
3339 (match_operand 1 "general_operand" ""))]
3341 && (GET_MODE (operands[0]) == TFmode
3342 || GET_MODE (operands[0]) == XFmode
3343 || GET_MODE (operands[0]) == DFmode)
3344 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3346 "ix86_split_long_move (operands); DONE;")
3348 (define_insn "swapxf"
3349 [(set (match_operand:XF 0 "register_operand" "+f")
3350 (match_operand:XF 1 "register_operand" "+f"))
3355 if (STACK_TOP_P (operands[0]))
3360 [(set_attr "type" "fxch")
3361 (set_attr "mode" "XF")])
3363 (define_insn "*swap<mode>"
3364 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3365 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3368 "TARGET_80387 || reload_completed"
3370 if (STACK_TOP_P (operands[0]))
3375 [(set_attr "type" "fxch")
3376 (set_attr "mode" "<MODE>")])
3378 ;; Zero extension instructions
3380 (define_expand "zero_extendsidi2"
3381 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3382 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3387 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3392 (define_insn "*zero_extendsidi2_rex64"
3393 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3395 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3398 mov{l}\t{%1, %k0|%k0, %1}
3400 movd\t{%1, %0|%0, %1}
3401 movd\t{%1, %0|%0, %1}
3402 %vmovd\t{%1, %0|%0, %1}
3403 %vmovd\t{%1, %0|%0, %1}"
3404 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3405 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3406 (set_attr "prefix_0f" "0,*,*,*,*,*")
3407 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3410 [(set (match_operand:DI 0 "memory_operand" "")
3411 (zero_extend:DI (match_dup 0)))]
3413 [(set (match_dup 4) (const_int 0))]
3414 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3416 ;; %%% Kill me once multi-word ops are sane.
3417 (define_insn "zero_extendsidi2_1"
3418 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3420 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3421 (clobber (reg:CC FLAGS_REG))]
3427 movd\t{%1, %0|%0, %1}
3428 movd\t{%1, %0|%0, %1}
3429 %vmovd\t{%1, %0|%0, %1}
3430 %vmovd\t{%1, %0|%0, %1}"
3431 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3432 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3433 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3434 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3437 [(set (match_operand:DI 0 "register_operand" "")
3438 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3439 (clobber (reg:CC FLAGS_REG))]
3440 "!TARGET_64BIT && reload_completed
3441 && true_regnum (operands[0]) == true_regnum (operands[1])"
3442 [(set (match_dup 4) (const_int 0))]
3443 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3446 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3447 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3448 (clobber (reg:CC FLAGS_REG))]
3449 "!TARGET_64BIT && reload_completed
3450 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3451 [(set (match_dup 3) (match_dup 1))
3452 (set (match_dup 4) (const_int 0))]
3453 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3455 (define_insn "zero_extend<mode>di2"
3456 [(set (match_operand:DI 0 "register_operand" "=r")
3458 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3460 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3461 [(set_attr "type" "imovx")
3462 (set_attr "mode" "SI")])
3464 (define_expand "zero_extendhisi2"
3465 [(set (match_operand:SI 0 "register_operand" "")
3466 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3469 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3471 operands[1] = force_reg (HImode, operands[1]);
3472 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3477 (define_insn_and_split "zero_extendhisi2_and"
3478 [(set (match_operand:SI 0 "register_operand" "=r")
3479 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3480 (clobber (reg:CC FLAGS_REG))]
3481 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3483 "&& reload_completed"
3484 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3485 (clobber (reg:CC FLAGS_REG))])]
3487 [(set_attr "type" "alu1")
3488 (set_attr "mode" "SI")])
3490 (define_insn "*zero_extendhisi2_movzwl"
3491 [(set (match_operand:SI 0 "register_operand" "=r")
3492 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3493 "!TARGET_ZERO_EXTEND_WITH_AND
3494 || optimize_function_for_size_p (cfun)"
3495 "movz{wl|x}\t{%1, %0|%0, %1}"
3496 [(set_attr "type" "imovx")
3497 (set_attr "mode" "SI")])
3499 (define_expand "zero_extendqi<mode>2"
3501 [(set (match_operand:SWI24 0 "register_operand" "")
3502 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3503 (clobber (reg:CC FLAGS_REG))])])
3505 (define_insn "*zero_extendqi<mode>2_and"
3506 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3507 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3508 (clobber (reg:CC FLAGS_REG))]
3509 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3511 [(set_attr "type" "alu1")
3512 (set_attr "mode" "<MODE>")])
3514 ;; When source and destination does not overlap, clear destination
3515 ;; first and then do the movb
3517 [(set (match_operand:SWI24 0 "register_operand" "")
3518 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3519 (clobber (reg:CC FLAGS_REG))]
3521 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3522 && ANY_QI_REG_P (operands[0])
3523 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3524 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3525 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3527 operands[2] = gen_lowpart (QImode, operands[0]);
3528 ix86_expand_clear (operands[0]);
3531 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3532 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3533 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3534 (clobber (reg:CC FLAGS_REG))]
3535 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3537 [(set_attr "type" "imovx,alu1")
3538 (set_attr "mode" "<MODE>")])
3540 ;; For the movzbl case strip only the clobber
3542 [(set (match_operand:SWI24 0 "register_operand" "")
3543 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3544 (clobber (reg:CC FLAGS_REG))]
3546 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3547 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3549 (zero_extend:SWI24 (match_dup 1)))])
3551 ; zero extend to SImode to avoid partial register stalls
3552 (define_insn "*zero_extendqi<mode>2_movzbl"
3553 [(set (match_operand:SWI24 0 "register_operand" "=r")
3554 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3556 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3557 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3558 [(set_attr "type" "imovx")
3559 (set_attr "mode" "SI")])
3561 ;; Rest is handled by single and.
3563 [(set (match_operand:SWI24 0 "register_operand" "")
3564 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3565 (clobber (reg:CC FLAGS_REG))]
3567 && true_regnum (operands[0]) == true_regnum (operands[1])"
3568 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3569 (clobber (reg:CC FLAGS_REG))])])
3571 ;; Sign extension instructions
3573 (define_expand "extendsidi2"
3574 [(set (match_operand:DI 0 "register_operand" "")
3575 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3580 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3585 (define_insn "*extendsidi2_rex64"
3586 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3587 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3591 movs{lq|x}\t{%1, %0|%0, %1}"
3592 [(set_attr "type" "imovx")
3593 (set_attr "mode" "DI")
3594 (set_attr "prefix_0f" "0")
3595 (set_attr "modrm" "0,1")])
3597 (define_insn "extendsidi2_1"
3598 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3599 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3600 (clobber (reg:CC FLAGS_REG))
3601 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3605 ;; Extend to memory case when source register does die.
3607 [(set (match_operand:DI 0 "memory_operand" "")
3608 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3609 (clobber (reg:CC FLAGS_REG))
3610 (clobber (match_operand:SI 2 "register_operand" ""))]
3612 && dead_or_set_p (insn, operands[1])
3613 && !reg_mentioned_p (operands[1], operands[0]))"
3614 [(set (match_dup 3) (match_dup 1))
3615 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3616 (clobber (reg:CC FLAGS_REG))])
3617 (set (match_dup 4) (match_dup 1))]
3618 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3620 ;; Extend to memory case when source register does not die.
3622 [(set (match_operand:DI 0 "memory_operand" "")
3623 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3624 (clobber (reg:CC FLAGS_REG))
3625 (clobber (match_operand:SI 2 "register_operand" ""))]
3629 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3631 emit_move_insn (operands[3], operands[1]);
3633 /* Generate a cltd if possible and doing so it profitable. */
3634 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3635 && true_regnum (operands[1]) == AX_REG
3636 && true_regnum (operands[2]) == DX_REG)
3638 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3642 emit_move_insn (operands[2], operands[1]);
3643 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3645 emit_move_insn (operands[4], operands[2]);
3649 ;; Extend to register case. Optimize case where source and destination
3650 ;; registers match and cases where we can use cltd.
3652 [(set (match_operand:DI 0 "register_operand" "")
3653 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3654 (clobber (reg:CC FLAGS_REG))
3655 (clobber (match_scratch:SI 2 ""))]
3659 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3661 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3662 emit_move_insn (operands[3], operands[1]);
3664 /* Generate a cltd if possible and doing so it profitable. */
3665 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3666 && true_regnum (operands[3]) == AX_REG
3667 && true_regnum (operands[4]) == DX_REG)
3669 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3673 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3674 emit_move_insn (operands[4], operands[1]);
3676 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3680 (define_insn "extend<mode>di2"
3681 [(set (match_operand:DI 0 "register_operand" "=r")
3683 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3685 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3686 [(set_attr "type" "imovx")
3687 (set_attr "mode" "DI")])
3689 (define_insn "extendhisi2"
3690 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3691 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3694 switch (get_attr_prefix_0f (insn))
3697 return "{cwtl|cwde}";
3699 return "movs{wl|x}\t{%1, %0|%0, %1}";
3702 [(set_attr "type" "imovx")
3703 (set_attr "mode" "SI")
3704 (set (attr "prefix_0f")
3705 ;; movsx is short decodable while cwtl is vector decoded.
3706 (if_then_else (and (eq_attr "cpu" "!k6")
3707 (eq_attr "alternative" "0"))
3709 (const_string "1")))
3711 (if_then_else (eq_attr "prefix_0f" "0")
3713 (const_string "1")))])
3715 (define_insn "*extendhisi2_zext"
3716 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3719 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3722 switch (get_attr_prefix_0f (insn))
3725 return "{cwtl|cwde}";
3727 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3730 [(set_attr "type" "imovx")
3731 (set_attr "mode" "SI")
3732 (set (attr "prefix_0f")
3733 ;; movsx is short decodable while cwtl is vector decoded.
3734 (if_then_else (and (eq_attr "cpu" "!k6")
3735 (eq_attr "alternative" "0"))
3737 (const_string "1")))
3739 (if_then_else (eq_attr "prefix_0f" "0")
3741 (const_string "1")))])
3743 (define_insn "extendqisi2"
3744 [(set (match_operand:SI 0 "register_operand" "=r")
3745 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3747 "movs{bl|x}\t{%1, %0|%0, %1}"
3748 [(set_attr "type" "imovx")
3749 (set_attr "mode" "SI")])
3751 (define_insn "*extendqisi2_zext"
3752 [(set (match_operand:DI 0 "register_operand" "=r")
3754 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3756 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3757 [(set_attr "type" "imovx")
3758 (set_attr "mode" "SI")])
3760 (define_insn "extendqihi2"
3761 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3762 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3765 switch (get_attr_prefix_0f (insn))
3768 return "{cbtw|cbw}";
3770 return "movs{bw|x}\t{%1, %0|%0, %1}";
3773 [(set_attr "type" "imovx")
3774 (set_attr "mode" "HI")
3775 (set (attr "prefix_0f")
3776 ;; movsx is short decodable while cwtl is vector decoded.
3777 (if_then_else (and (eq_attr "cpu" "!k6")
3778 (eq_attr "alternative" "0"))
3780 (const_string "1")))
3782 (if_then_else (eq_attr "prefix_0f" "0")
3784 (const_string "1")))])
3786 ;; Conversions between float and double.
3788 ;; These are all no-ops in the model used for the 80387.
3789 ;; So just emit moves.
3791 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3793 [(set (match_operand:DF 0 "push_operand" "")
3794 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3796 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3797 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3800 [(set (match_operand:XF 0 "push_operand" "")
3801 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3803 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3804 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3805 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3807 (define_expand "extendsfdf2"
3808 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3809 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3810 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3812 /* ??? Needed for compress_float_constant since all fp constants
3813 are TARGET_LEGITIMATE_CONSTANT_P. */
3814 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3816 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3817 && standard_80387_constant_p (operands[1]) > 0)
3819 operands[1] = simplify_const_unary_operation
3820 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3821 emit_move_insn_1 (operands[0], operands[1]);
3824 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3828 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3830 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3832 We do the conversion post reload to avoid producing of 128bit spills
3833 that might lead to ICE on 32bit target. The sequence unlikely combine
3836 [(set (match_operand:DF 0 "register_operand" "")
3838 (match_operand:SF 1 "nonimmediate_operand" "")))]
3839 "TARGET_USE_VECTOR_FP_CONVERTS
3840 && optimize_insn_for_speed_p ()
3841 && reload_completed && SSE_REG_P (operands[0])"
3846 (parallel [(const_int 0) (const_int 1)]))))]
3848 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3849 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3850 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3851 Try to avoid move when unpacking can be done in source. */
3852 if (REG_P (operands[1]))
3854 /* If it is unsafe to overwrite upper half of source, we need
3855 to move to destination and unpack there. */
3856 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3857 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3858 && true_regnum (operands[0]) != true_regnum (operands[1]))
3860 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3861 emit_move_insn (tmp, operands[1]);
3864 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3865 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3869 emit_insn (gen_vec_setv4sf_0 (operands[3],
3870 CONST0_RTX (V4SFmode), operands[1]));
3873 (define_insn "*extendsfdf2_mixed"
3874 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3876 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3877 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3879 switch (which_alternative)
3883 return output_387_reg_move (insn, operands);
3886 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3892 [(set_attr "type" "fmov,fmov,ssecvt")
3893 (set_attr "prefix" "orig,orig,maybe_vex")
3894 (set_attr "mode" "SF,XF,DF")])
3896 (define_insn "*extendsfdf2_sse"
3897 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3898 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3899 "TARGET_SSE2 && TARGET_SSE_MATH"
3900 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3901 [(set_attr "type" "ssecvt")
3902 (set_attr "prefix" "maybe_vex")
3903 (set_attr "mode" "DF")])
3905 (define_insn "*extendsfdf2_i387"
3906 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3907 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3909 "* return output_387_reg_move (insn, operands);"
3910 [(set_attr "type" "fmov")
3911 (set_attr "mode" "SF,XF")])
3913 (define_expand "extend<mode>xf2"
3914 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3915 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3918 /* ??? Needed for compress_float_constant since all fp constants
3919 are TARGET_LEGITIMATE_CONSTANT_P. */
3920 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3922 if (standard_80387_constant_p (operands[1]) > 0)
3924 operands[1] = simplify_const_unary_operation
3925 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3926 emit_move_insn_1 (operands[0], operands[1]);
3929 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3933 (define_insn "*extend<mode>xf2_i387"
3934 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3936 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3938 "* return output_387_reg_move (insn, operands);"
3939 [(set_attr "type" "fmov")
3940 (set_attr "mode" "<MODE>,XF")])
3942 ;; %%% This seems bad bad news.
3943 ;; This cannot output into an f-reg because there is no way to be sure
3944 ;; of truncating in that case. Otherwise this is just like a simple move
3945 ;; insn. So we pretend we can output to a reg in order to get better
3946 ;; register preferencing, but we really use a stack slot.
3948 ;; Conversion from DFmode to SFmode.
3950 (define_expand "truncdfsf2"
3951 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3953 (match_operand:DF 1 "nonimmediate_operand" "")))]
3954 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3956 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3958 else if (flag_unsafe_math_optimizations)
3962 enum ix86_stack_slot slot = (virtuals_instantiated
3965 rtx temp = assign_386_stack_local (SFmode, slot);
3966 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3971 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3973 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3975 We do the conversion post reload to avoid producing of 128bit spills
3976 that might lead to ICE on 32bit target. The sequence unlikely combine
3979 [(set (match_operand:SF 0 "register_operand" "")
3981 (match_operand:DF 1 "nonimmediate_operand" "")))]
3982 "TARGET_USE_VECTOR_FP_CONVERTS
3983 && optimize_insn_for_speed_p ()
3984 && reload_completed && SSE_REG_P (operands[0])"
3987 (float_truncate:V2SF
3991 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3992 operands[3] = CONST0_RTX (V2SFmode);
3993 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3994 /* Use movsd for loading from memory, unpcklpd for registers.
3995 Try to avoid move when unpacking can be done in source, or SSE3
3996 movddup is available. */
3997 if (REG_P (operands[1]))
4000 && true_regnum (operands[0]) != true_regnum (operands[1])
4001 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4002 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4004 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4005 emit_move_insn (tmp, operands[1]);
4008 else if (!TARGET_SSE3)
4009 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4010 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4013 emit_insn (gen_sse2_loadlpd (operands[4],
4014 CONST0_RTX (V2DFmode), operands[1]));
4017 (define_expand "truncdfsf2_with_temp"
4018 [(parallel [(set (match_operand:SF 0 "" "")
4019 (float_truncate:SF (match_operand:DF 1 "" "")))
4020 (clobber (match_operand:SF 2 "" ""))])])
4022 (define_insn "*truncdfsf_fast_mixed"
4023 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4025 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4026 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4028 switch (which_alternative)
4031 return output_387_reg_move (insn, operands);
4033 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4038 [(set_attr "type" "fmov,ssecvt")
4039 (set_attr "prefix" "orig,maybe_vex")
4040 (set_attr "mode" "SF")])
4042 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4043 ;; because nothing we do here is unsafe.
4044 (define_insn "*truncdfsf_fast_sse"
4045 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4047 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4048 "TARGET_SSE2 && TARGET_SSE_MATH"
4049 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4050 [(set_attr "type" "ssecvt")
4051 (set_attr "prefix" "maybe_vex")
4052 (set_attr "mode" "SF")])
4054 (define_insn "*truncdfsf_fast_i387"
4055 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4057 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4058 "TARGET_80387 && flag_unsafe_math_optimizations"
4059 "* return output_387_reg_move (insn, operands);"
4060 [(set_attr "type" "fmov")
4061 (set_attr "mode" "SF")])
4063 (define_insn "*truncdfsf_mixed"
4064 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4066 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4067 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4068 "TARGET_MIX_SSE_I387"
4070 switch (which_alternative)
4073 return output_387_reg_move (insn, operands);
4075 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4081 [(set_attr "isa" "*,sse2,*,*,*")
4082 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4083 (set_attr "unit" "*,*,i387,i387,i387")
4084 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4085 (set_attr "mode" "SF")])
4087 (define_insn "*truncdfsf_i387"
4088 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4090 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4091 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4094 switch (which_alternative)
4097 return output_387_reg_move (insn, operands);
4103 [(set_attr "type" "fmov,multi,multi,multi")
4104 (set_attr "unit" "*,i387,i387,i387")
4105 (set_attr "mode" "SF")])
4107 (define_insn "*truncdfsf2_i387_1"
4108 [(set (match_operand:SF 0 "memory_operand" "=m")
4110 (match_operand:DF 1 "register_operand" "f")))]
4112 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4113 && !TARGET_MIX_SSE_I387"
4114 "* return output_387_reg_move (insn, operands);"
4115 [(set_attr "type" "fmov")
4116 (set_attr "mode" "SF")])
4119 [(set (match_operand:SF 0 "register_operand" "")
4121 (match_operand:DF 1 "fp_register_operand" "")))
4122 (clobber (match_operand 2 "" ""))]
4124 [(set (match_dup 2) (match_dup 1))
4125 (set (match_dup 0) (match_dup 2))]
4126 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4128 ;; Conversion from XFmode to {SF,DF}mode
4130 (define_expand "truncxf<mode>2"
4131 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4132 (float_truncate:MODEF
4133 (match_operand:XF 1 "register_operand" "")))
4134 (clobber (match_dup 2))])]
4137 if (flag_unsafe_math_optimizations)
4139 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4140 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4141 if (reg != operands[0])
4142 emit_move_insn (operands[0], reg);
4147 enum ix86_stack_slot slot = (virtuals_instantiated
4150 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4154 (define_insn "*truncxfsf2_mixed"
4155 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4157 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4158 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4161 gcc_assert (!which_alternative);
4162 return output_387_reg_move (insn, operands);
4164 [(set_attr "type" "fmov,multi,multi,multi")
4165 (set_attr "unit" "*,i387,i387,i387")
4166 (set_attr "mode" "SF")])
4168 (define_insn "*truncxfdf2_mixed"
4169 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4171 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4172 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4175 gcc_assert (!which_alternative);
4176 return output_387_reg_move (insn, operands);
4178 [(set_attr "isa" "*,*,sse2,*")
4179 (set_attr "type" "fmov,multi,multi,multi")
4180 (set_attr "unit" "*,i387,i387,i387")
4181 (set_attr "mode" "DF")])
4183 (define_insn "truncxf<mode>2_i387_noop"
4184 [(set (match_operand:MODEF 0 "register_operand" "=f")
4185 (float_truncate:MODEF
4186 (match_operand:XF 1 "register_operand" "f")))]
4187 "TARGET_80387 && flag_unsafe_math_optimizations"
4188 "* return output_387_reg_move (insn, operands);"
4189 [(set_attr "type" "fmov")
4190 (set_attr "mode" "<MODE>")])
4192 (define_insn "*truncxf<mode>2_i387"
4193 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4194 (float_truncate:MODEF
4195 (match_operand:XF 1 "register_operand" "f")))]
4197 "* return output_387_reg_move (insn, operands);"
4198 [(set_attr "type" "fmov")
4199 (set_attr "mode" "<MODE>")])
4202 [(set (match_operand:MODEF 0 "register_operand" "")
4203 (float_truncate:MODEF
4204 (match_operand:XF 1 "register_operand" "")))
4205 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4206 "TARGET_80387 && reload_completed"
4207 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4208 (set (match_dup 0) (match_dup 2))])
4211 [(set (match_operand:MODEF 0 "memory_operand" "")
4212 (float_truncate:MODEF
4213 (match_operand:XF 1 "register_operand" "")))
4214 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4216 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4218 ;; Signed conversion to DImode.
4220 (define_expand "fix_truncxfdi2"
4221 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4222 (fix:DI (match_operand:XF 1 "register_operand" "")))
4223 (clobber (reg:CC FLAGS_REG))])]
4228 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4233 (define_expand "fix_trunc<mode>di2"
4234 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4235 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4236 (clobber (reg:CC FLAGS_REG))])]
4237 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4240 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4242 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4245 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4247 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4248 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4249 if (out != operands[0])
4250 emit_move_insn (operands[0], out);
4255 ;; Signed conversion to SImode.
4257 (define_expand "fix_truncxfsi2"
4258 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4259 (fix:SI (match_operand:XF 1 "register_operand" "")))
4260 (clobber (reg:CC FLAGS_REG))])]
4265 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4270 (define_expand "fix_trunc<mode>si2"
4271 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4272 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4273 (clobber (reg:CC FLAGS_REG))])]
4274 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4277 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4279 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4282 if (SSE_FLOAT_MODE_P (<MODE>mode))
4284 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4285 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4286 if (out != operands[0])
4287 emit_move_insn (operands[0], out);
4292 ;; Signed conversion to HImode.
4294 (define_expand "fix_trunc<mode>hi2"
4295 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4296 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4297 (clobber (reg:CC FLAGS_REG))])]
4299 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4303 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4308 ;; Unsigned conversion to SImode.
4310 (define_expand "fixuns_trunc<mode>si2"
4312 [(set (match_operand:SI 0 "register_operand" "")
4314 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4316 (clobber (match_scratch:<ssevecmode> 3 ""))
4317 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4318 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4320 enum machine_mode mode = <MODE>mode;
4321 enum machine_mode vecmode = <ssevecmode>mode;
4322 REAL_VALUE_TYPE TWO31r;
4325 if (optimize_insn_for_size_p ())
4328 real_ldexp (&TWO31r, &dconst1, 31);
4329 two31 = const_double_from_real_value (TWO31r, mode);
4330 two31 = ix86_build_const_vector (vecmode, true, two31);
4331 operands[2] = force_reg (vecmode, two31);
4334 (define_insn_and_split "*fixuns_trunc<mode>_1"
4335 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4337 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4338 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4339 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4340 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4341 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4342 && optimize_function_for_speed_p (cfun)"
4344 "&& reload_completed"
4347 ix86_split_convert_uns_si_sse (operands);
4351 ;; Unsigned conversion to HImode.
4352 ;; Without these patterns, we'll try the unsigned SI conversion which
4353 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4355 (define_expand "fixuns_trunc<mode>hi2"
4357 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4358 (set (match_operand:HI 0 "nonimmediate_operand" "")
4359 (subreg:HI (match_dup 2) 0))]
4360 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4361 "operands[2] = gen_reg_rtx (SImode);")
4363 ;; When SSE is available, it is always faster to use it!
4364 (define_insn "fix_trunc<mode>di_sse"
4365 [(set (match_operand:DI 0 "register_operand" "=r,r")
4366 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4367 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4368 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4369 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4370 [(set_attr "type" "sseicvt")
4371 (set_attr "prefix" "maybe_vex")
4372 (set_attr "prefix_rex" "1")
4373 (set_attr "mode" "<MODE>")
4374 (set_attr "athlon_decode" "double,vector")
4375 (set_attr "amdfam10_decode" "double,double")
4376 (set_attr "bdver1_decode" "double,double")])
4378 (define_insn "fix_trunc<mode>si_sse"
4379 [(set (match_operand:SI 0 "register_operand" "=r,r")
4380 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4381 "SSE_FLOAT_MODE_P (<MODE>mode)
4382 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4383 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4384 [(set_attr "type" "sseicvt")
4385 (set_attr "prefix" "maybe_vex")
4386 (set_attr "mode" "<MODE>")
4387 (set_attr "athlon_decode" "double,vector")
4388 (set_attr "amdfam10_decode" "double,double")
4389 (set_attr "bdver1_decode" "double,double")])
4391 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4393 [(set (match_operand:MODEF 0 "register_operand" "")
4394 (match_operand:MODEF 1 "memory_operand" ""))
4395 (set (match_operand:SWI48x 2 "register_operand" "")
4396 (fix:SWI48x (match_dup 0)))]
4397 "TARGET_SHORTEN_X87_SSE
4398 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4399 && peep2_reg_dead_p (2, operands[0])"
4400 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4402 ;; Avoid vector decoded forms of the instruction.
4404 [(match_scratch:DF 2 "x")
4405 (set (match_operand:SWI48x 0 "register_operand" "")
4406 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4407 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4408 [(set (match_dup 2) (match_dup 1))
4409 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4412 [(match_scratch:SF 2 "x")
4413 (set (match_operand:SWI48x 0 "register_operand" "")
4414 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4415 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4416 [(set (match_dup 2) (match_dup 1))
4417 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4419 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4420 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4421 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4422 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4424 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4425 && (TARGET_64BIT || <MODE>mode != DImode))
4427 && can_create_pseudo_p ()"
4432 if (memory_operand (operands[0], VOIDmode))
4433 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4436 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4437 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4443 [(set_attr "type" "fisttp")
4444 (set_attr "mode" "<MODE>")])
4446 (define_insn "fix_trunc<mode>_i387_fisttp"
4447 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4448 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4449 (clobber (match_scratch:XF 2 "=&1f"))]
4450 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4452 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4453 && (TARGET_64BIT || <MODE>mode != DImode))
4454 && TARGET_SSE_MATH)"
4455 "* return output_fix_trunc (insn, operands, true);"
4456 [(set_attr "type" "fisttp")
4457 (set_attr "mode" "<MODE>")])
4459 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4460 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4461 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4462 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4463 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4464 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4466 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4467 && (TARGET_64BIT || <MODE>mode != DImode))
4468 && TARGET_SSE_MATH)"
4470 [(set_attr "type" "fisttp")
4471 (set_attr "mode" "<MODE>")])
4474 [(set (match_operand:SWI248x 0 "register_operand" "")
4475 (fix:SWI248x (match_operand 1 "register_operand" "")))
4476 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4477 (clobber (match_scratch 3 ""))]
4479 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4480 (clobber (match_dup 3))])
4481 (set (match_dup 0) (match_dup 2))])
4484 [(set (match_operand:SWI248x 0 "memory_operand" "")
4485 (fix:SWI248x (match_operand 1 "register_operand" "")))
4486 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4487 (clobber (match_scratch 3 ""))]
4489 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4490 (clobber (match_dup 3))])])
4492 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4493 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4494 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4495 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4496 ;; function in i386.c.
4497 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4498 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4499 (fix:SWI248x (match_operand 1 "register_operand" "")))
4500 (clobber (reg:CC FLAGS_REG))]
4501 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4503 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4504 && (TARGET_64BIT || <MODE>mode != DImode))
4505 && can_create_pseudo_p ()"
4510 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4512 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4513 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4514 if (memory_operand (operands[0], VOIDmode))
4515 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4516 operands[2], operands[3]));
4519 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4520 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4521 operands[2], operands[3],
4526 [(set_attr "type" "fistp")
4527 (set_attr "i387_cw" "trunc")
4528 (set_attr "mode" "<MODE>")])
4530 (define_insn "fix_truncdi_i387"
4531 [(set (match_operand:DI 0 "memory_operand" "=m")
4532 (fix:DI (match_operand 1 "register_operand" "f")))
4533 (use (match_operand:HI 2 "memory_operand" "m"))
4534 (use (match_operand:HI 3 "memory_operand" "m"))
4535 (clobber (match_scratch:XF 4 "=&1f"))]
4536 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4538 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4539 "* return output_fix_trunc (insn, operands, false);"
4540 [(set_attr "type" "fistp")
4541 (set_attr "i387_cw" "trunc")
4542 (set_attr "mode" "DI")])
4544 (define_insn "fix_truncdi_i387_with_temp"
4545 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4546 (fix:DI (match_operand 1 "register_operand" "f,f")))
4547 (use (match_operand:HI 2 "memory_operand" "m,m"))
4548 (use (match_operand:HI 3 "memory_operand" "m,m"))
4549 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4550 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4551 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4553 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4555 [(set_attr "type" "fistp")
4556 (set_attr "i387_cw" "trunc")
4557 (set_attr "mode" "DI")])
4560 [(set (match_operand:DI 0 "register_operand" "")
4561 (fix:DI (match_operand 1 "register_operand" "")))
4562 (use (match_operand:HI 2 "memory_operand" ""))
4563 (use (match_operand:HI 3 "memory_operand" ""))
4564 (clobber (match_operand:DI 4 "memory_operand" ""))
4565 (clobber (match_scratch 5 ""))]
4567 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4570 (clobber (match_dup 5))])
4571 (set (match_dup 0) (match_dup 4))])
4574 [(set (match_operand:DI 0 "memory_operand" "")
4575 (fix:DI (match_operand 1 "register_operand" "")))
4576 (use (match_operand:HI 2 "memory_operand" ""))
4577 (use (match_operand:HI 3 "memory_operand" ""))
4578 (clobber (match_operand:DI 4 "memory_operand" ""))
4579 (clobber (match_scratch 5 ""))]
4581 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4584 (clobber (match_dup 5))])])
4586 (define_insn "fix_trunc<mode>_i387"
4587 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4588 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4589 (use (match_operand:HI 2 "memory_operand" "m"))
4590 (use (match_operand:HI 3 "memory_operand" "m"))]
4591 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4593 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4594 "* return output_fix_trunc (insn, operands, false);"
4595 [(set_attr "type" "fistp")
4596 (set_attr "i387_cw" "trunc")
4597 (set_attr "mode" "<MODE>")])
4599 (define_insn "fix_trunc<mode>_i387_with_temp"
4600 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4601 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4602 (use (match_operand:HI 2 "memory_operand" "m,m"))
4603 (use (match_operand:HI 3 "memory_operand" "m,m"))
4604 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4605 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4607 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4609 [(set_attr "type" "fistp")
4610 (set_attr "i387_cw" "trunc")
4611 (set_attr "mode" "<MODE>")])
4614 [(set (match_operand:SWI24 0 "register_operand" "")
4615 (fix:SWI24 (match_operand 1 "register_operand" "")))
4616 (use (match_operand:HI 2 "memory_operand" ""))
4617 (use (match_operand:HI 3 "memory_operand" ""))
4618 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4620 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4622 (use (match_dup 3))])
4623 (set (match_dup 0) (match_dup 4))])
4626 [(set (match_operand:SWI24 0 "memory_operand" "")
4627 (fix:SWI24 (match_operand 1 "register_operand" "")))
4628 (use (match_operand:HI 2 "memory_operand" ""))
4629 (use (match_operand:HI 3 "memory_operand" ""))
4630 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4632 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4634 (use (match_dup 3))])])
4636 (define_insn "x86_fnstcw_1"
4637 [(set (match_operand:HI 0 "memory_operand" "=m")
4638 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4641 [(set (attr "length")
4642 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4643 (set_attr "mode" "HI")
4644 (set_attr "unit" "i387")
4645 (set_attr "bdver1_decode" "vector")])
4647 (define_insn "x86_fldcw_1"
4648 [(set (reg:HI FPCR_REG)
4649 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4652 [(set (attr "length")
4653 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4654 (set_attr "mode" "HI")
4655 (set_attr "unit" "i387")
4656 (set_attr "athlon_decode" "vector")
4657 (set_attr "amdfam10_decode" "vector")
4658 (set_attr "bdver1_decode" "vector")])
4660 ;; Conversion between fixed point and floating point.
4662 ;; Even though we only accept memory inputs, the backend _really_
4663 ;; wants to be able to do this between registers.
4665 (define_expand "floathi<mode>2"
4666 [(set (match_operand:X87MODEF 0 "register_operand" "")
4667 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4669 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4670 || TARGET_MIX_SSE_I387)")
4672 ;; Pre-reload splitter to add memory clobber to the pattern.
4673 (define_insn_and_split "*floathi<mode>2_1"
4674 [(set (match_operand:X87MODEF 0 "register_operand" "")
4675 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4677 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4678 || TARGET_MIX_SSE_I387)
4679 && can_create_pseudo_p ()"
4682 [(parallel [(set (match_dup 0)
4683 (float:X87MODEF (match_dup 1)))
4684 (clobber (match_dup 2))])]
4685 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4687 (define_insn "*floathi<mode>2_i387_with_temp"
4688 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4689 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4690 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4692 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4693 || TARGET_MIX_SSE_I387)"
4695 [(set_attr "type" "fmov,multi")
4696 (set_attr "mode" "<MODE>")
4697 (set_attr "unit" "*,i387")
4698 (set_attr "fp_int_src" "true")])
4700 (define_insn "*floathi<mode>2_i387"
4701 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4702 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4704 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4705 || TARGET_MIX_SSE_I387)"
4707 [(set_attr "type" "fmov")
4708 (set_attr "mode" "<MODE>")
4709 (set_attr "fp_int_src" "true")])
4712 [(set (match_operand:X87MODEF 0 "register_operand" "")
4713 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4714 (clobber (match_operand:HI 2 "memory_operand" ""))]
4716 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4717 || TARGET_MIX_SSE_I387)
4718 && reload_completed"
4719 [(set (match_dup 2) (match_dup 1))
4720 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4723 [(set (match_operand:X87MODEF 0 "register_operand" "")
4724 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4725 (clobber (match_operand:HI 2 "memory_operand" ""))]
4727 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4728 || TARGET_MIX_SSE_I387)
4729 && reload_completed"
4730 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4732 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4733 [(set (match_operand:X87MODEF 0 "register_operand" "")
4735 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4737 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4738 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4740 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4741 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4742 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4744 rtx reg = gen_reg_rtx (XFmode);
4745 rtx (*insn)(rtx, rtx);
4747 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4749 if (<X87MODEF:MODE>mode == SFmode)
4750 insn = gen_truncxfsf2;
4751 else if (<X87MODEF:MODE>mode == DFmode)
4752 insn = gen_truncxfdf2;
4756 emit_insn (insn (operands[0], reg));
4761 ;; Pre-reload splitter to add memory clobber to the pattern.
4762 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4763 [(set (match_operand:X87MODEF 0 "register_operand" "")
4764 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4766 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4767 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4768 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4769 || TARGET_MIX_SSE_I387))
4770 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4771 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4772 && ((<SWI48x:MODE>mode == SImode
4773 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4774 && optimize_function_for_speed_p (cfun)
4775 && flag_trapping_math)
4776 || !(TARGET_INTER_UNIT_CONVERSIONS
4777 || optimize_function_for_size_p (cfun)))))
4778 && can_create_pseudo_p ()"
4781 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4782 (clobber (match_dup 2))])]
4784 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4786 /* Avoid store forwarding (partial memory) stall penalty
4787 by passing DImode value through XMM registers. */
4788 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4789 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4790 && optimize_function_for_speed_p (cfun))
4792 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4799 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4800 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4802 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4803 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4804 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4805 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4807 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4808 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4809 (set_attr "unit" "*,i387,*,*,*")
4810 (set_attr "athlon_decode" "*,*,double,direct,double")
4811 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4812 (set_attr "bdver1_decode" "*,*,double,direct,double")
4813 (set_attr "fp_int_src" "true")])
4815 (define_insn "*floatsi<mode>2_vector_mixed"
4816 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4817 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4818 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4819 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4823 [(set_attr "type" "fmov,sseicvt")
4824 (set_attr "mode" "<MODE>,<ssevecmode>")
4825 (set_attr "unit" "i387,*")
4826 (set_attr "athlon_decode" "*,direct")
4827 (set_attr "amdfam10_decode" "*,double")
4828 (set_attr "bdver1_decode" "*,direct")
4829 (set_attr "fp_int_src" "true")])
4831 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4832 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4834 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4835 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4836 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4837 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4839 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4840 (set_attr "mode" "<MODEF:MODE>")
4841 (set_attr "unit" "*,i387,*,*")
4842 (set_attr "athlon_decode" "*,*,double,direct")
4843 (set_attr "amdfam10_decode" "*,*,vector,double")
4844 (set_attr "bdver1_decode" "*,*,double,direct")
4845 (set_attr "fp_int_src" "true")])
4848 [(set (match_operand:MODEF 0 "register_operand" "")
4849 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4850 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4851 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4852 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4853 && TARGET_INTER_UNIT_CONVERSIONS
4855 && (SSE_REG_P (operands[0])
4856 || (GET_CODE (operands[0]) == SUBREG
4857 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4858 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4861 [(set (match_operand:MODEF 0 "register_operand" "")
4862 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4863 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4864 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4865 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4866 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4868 && (SSE_REG_P (operands[0])
4869 || (GET_CODE (operands[0]) == SUBREG
4870 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4871 [(set (match_dup 2) (match_dup 1))
4872 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4874 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4875 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4877 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4878 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4879 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4880 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4883 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4884 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4885 [(set_attr "type" "fmov,sseicvt,sseicvt")
4886 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4887 (set_attr "mode" "<MODEF:MODE>")
4888 (set (attr "prefix_rex")
4890 (and (eq_attr "prefix" "maybe_vex")
4891 (match_test "<SWI48x:MODE>mode == DImode"))
4893 (const_string "*")))
4894 (set_attr "unit" "i387,*,*")
4895 (set_attr "athlon_decode" "*,double,direct")
4896 (set_attr "amdfam10_decode" "*,vector,double")
4897 (set_attr "bdver1_decode" "*,double,direct")
4898 (set_attr "fp_int_src" "true")])
4900 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4901 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4903 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4904 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4905 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4906 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4909 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4910 [(set_attr "type" "fmov,sseicvt")
4911 (set_attr "prefix" "orig,maybe_vex")
4912 (set_attr "mode" "<MODEF:MODE>")
4913 (set (attr "prefix_rex")
4915 (and (eq_attr "prefix" "maybe_vex")
4916 (match_test "<SWI48x:MODE>mode == DImode"))
4918 (const_string "*")))
4919 (set_attr "athlon_decode" "*,direct")
4920 (set_attr "amdfam10_decode" "*,double")
4921 (set_attr "bdver1_decode" "*,direct")
4922 (set_attr "fp_int_src" "true")])
4924 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4925 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4927 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4928 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4929 "TARGET_SSE2 && TARGET_SSE_MATH
4930 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4932 [(set_attr "type" "sseicvt")
4933 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4934 (set_attr "athlon_decode" "double,direct,double")
4935 (set_attr "amdfam10_decode" "vector,double,double")
4936 (set_attr "bdver1_decode" "double,direct,double")
4937 (set_attr "fp_int_src" "true")])
4939 (define_insn "*floatsi<mode>2_vector_sse"
4940 [(set (match_operand:MODEF 0 "register_operand" "=x")
4941 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4942 "TARGET_SSE2 && TARGET_SSE_MATH
4943 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4945 [(set_attr "type" "sseicvt")
4946 (set_attr "mode" "<MODE>")
4947 (set_attr "athlon_decode" "direct")
4948 (set_attr "amdfam10_decode" "double")
4949 (set_attr "bdver1_decode" "direct")
4950 (set_attr "fp_int_src" "true")])
4953 [(set (match_operand:MODEF 0 "register_operand" "")
4954 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4955 (clobber (match_operand:SI 2 "memory_operand" ""))]
4956 "TARGET_SSE2 && TARGET_SSE_MATH
4957 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4959 && (SSE_REG_P (operands[0])
4960 || (GET_CODE (operands[0]) == SUBREG
4961 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4964 rtx op1 = operands[1];
4966 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4968 if (GET_CODE (op1) == SUBREG)
4969 op1 = SUBREG_REG (op1);
4971 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4973 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4974 emit_insn (gen_sse2_loadld (operands[4],
4975 CONST0_RTX (V4SImode), operands[1]));
4977 /* We can ignore possible trapping value in the
4978 high part of SSE register for non-trapping math. */
4979 else if (SSE_REG_P (op1) && !flag_trapping_math)
4980 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4983 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4984 emit_move_insn (operands[2], operands[1]);
4985 emit_insn (gen_sse2_loadld (operands[4],
4986 CONST0_RTX (V4SImode), operands[2]));
4988 if (<ssevecmode>mode == V4SFmode)
4989 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4991 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4996 [(set (match_operand:MODEF 0 "register_operand" "")
4997 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4998 (clobber (match_operand:SI 2 "memory_operand" ""))]
4999 "TARGET_SSE2 && TARGET_SSE_MATH
5000 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5002 && (SSE_REG_P (operands[0])
5003 || (GET_CODE (operands[0]) == SUBREG
5004 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5007 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5009 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5011 emit_insn (gen_sse2_loadld (operands[4],
5012 CONST0_RTX (V4SImode), operands[1]));
5013 if (<ssevecmode>mode == V4SFmode)
5014 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5016 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5021 [(set (match_operand:MODEF 0 "register_operand" "")
5022 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5023 "TARGET_SSE2 && TARGET_SSE_MATH
5024 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5026 && (SSE_REG_P (operands[0])
5027 || (GET_CODE (operands[0]) == SUBREG
5028 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5031 rtx op1 = operands[1];
5033 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5035 if (GET_CODE (op1) == SUBREG)
5036 op1 = SUBREG_REG (op1);
5038 if (GENERAL_REG_P (op1))
5040 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5041 if (TARGET_INTER_UNIT_MOVES)
5042 emit_insn (gen_sse2_loadld (operands[4],
5043 CONST0_RTX (V4SImode), operands[1]));
5046 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5048 emit_insn (gen_sse2_loadld (operands[4],
5049 CONST0_RTX (V4SImode), operands[5]));
5050 ix86_free_from_memory (GET_MODE (operands[1]));
5053 /* We can ignore possible trapping value in the
5054 high part of SSE register for non-trapping math. */
5055 else if (SSE_REG_P (op1) && !flag_trapping_math)
5056 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5059 if (<ssevecmode>mode == V4SFmode)
5060 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5062 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5067 [(set (match_operand:MODEF 0 "register_operand" "")
5068 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5069 "TARGET_SSE2 && TARGET_SSE_MATH
5070 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5072 && (SSE_REG_P (operands[0])
5073 || (GET_CODE (operands[0]) == SUBREG
5074 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5077 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5079 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5081 emit_insn (gen_sse2_loadld (operands[4],
5082 CONST0_RTX (V4SImode), operands[1]));
5083 if (<ssevecmode>mode == V4SFmode)
5084 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5086 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5090 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5091 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5093 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5094 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5095 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5096 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5098 [(set_attr "type" "sseicvt")
5099 (set_attr "mode" "<MODEF:MODE>")
5100 (set_attr "athlon_decode" "double,direct")
5101 (set_attr "amdfam10_decode" "vector,double")
5102 (set_attr "bdver1_decode" "double,direct")
5103 (set_attr "fp_int_src" "true")])
5105 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5106 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5108 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5109 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5110 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5111 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5112 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5113 [(set_attr "type" "sseicvt")
5114 (set_attr "prefix" "maybe_vex")
5115 (set_attr "mode" "<MODEF:MODE>")
5116 (set (attr "prefix_rex")
5118 (and (eq_attr "prefix" "maybe_vex")
5119 (match_test "<SWI48x:MODE>mode == DImode"))
5121 (const_string "*")))
5122 (set_attr "athlon_decode" "double,direct")
5123 (set_attr "amdfam10_decode" "vector,double")
5124 (set_attr "bdver1_decode" "double,direct")
5125 (set_attr "fp_int_src" "true")])
5128 [(set (match_operand:MODEF 0 "register_operand" "")
5129 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5130 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5131 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5132 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5133 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5135 && (SSE_REG_P (operands[0])
5136 || (GET_CODE (operands[0]) == SUBREG
5137 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5138 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5140 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5141 [(set (match_operand:MODEF 0 "register_operand" "=x")
5143 (match_operand:SWI48x 1 "memory_operand" "m")))]
5144 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5145 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5146 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5147 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5148 [(set_attr "type" "sseicvt")
5149 (set_attr "prefix" "maybe_vex")
5150 (set_attr "mode" "<MODEF:MODE>")
5151 (set (attr "prefix_rex")
5153 (and (eq_attr "prefix" "maybe_vex")
5154 (match_test "<SWI48x:MODE>mode == DImode"))
5156 (const_string "*")))
5157 (set_attr "athlon_decode" "direct")
5158 (set_attr "amdfam10_decode" "double")
5159 (set_attr "bdver1_decode" "direct")
5160 (set_attr "fp_int_src" "true")])
5163 [(set (match_operand:MODEF 0 "register_operand" "")
5164 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5165 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5166 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5167 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5168 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5170 && (SSE_REG_P (operands[0])
5171 || (GET_CODE (operands[0]) == SUBREG
5172 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5173 [(set (match_dup 2) (match_dup 1))
5174 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5177 [(set (match_operand:MODEF 0 "register_operand" "")
5178 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5179 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5180 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5181 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5183 && (SSE_REG_P (operands[0])
5184 || (GET_CODE (operands[0]) == SUBREG
5185 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5186 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5188 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5189 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5191 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5192 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5194 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5198 [(set_attr "type" "fmov,multi")
5199 (set_attr "mode" "<X87MODEF:MODE>")
5200 (set_attr "unit" "*,i387")
5201 (set_attr "fp_int_src" "true")])
5203 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5204 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5206 (match_operand:SWI48x 1 "memory_operand" "m")))]
5208 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5210 [(set_attr "type" "fmov")
5211 (set_attr "mode" "<X87MODEF:MODE>")
5212 (set_attr "fp_int_src" "true")])
5215 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5216 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5217 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5219 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5220 && reload_completed"
5221 [(set (match_dup 2) (match_dup 1))
5222 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5225 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5226 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5227 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5229 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5230 && reload_completed"
5231 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5233 ;; Avoid store forwarding (partial memory) stall penalty
5234 ;; by passing DImode value through XMM registers. */
5236 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5237 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5239 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5240 (clobber (match_scratch:V4SI 3 "=X,x"))
5241 (clobber (match_scratch:V4SI 4 "=X,x"))
5242 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5243 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5244 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5245 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5247 [(set_attr "type" "multi")
5248 (set_attr "mode" "<X87MODEF:MODE>")
5249 (set_attr "unit" "i387")
5250 (set_attr "fp_int_src" "true")])
5253 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5254 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5255 (clobber (match_scratch:V4SI 3 ""))
5256 (clobber (match_scratch:V4SI 4 ""))
5257 (clobber (match_operand:DI 2 "memory_operand" ""))]
5258 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5259 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5260 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5261 && reload_completed"
5262 [(set (match_dup 2) (match_dup 3))
5263 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5265 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5266 Assemble the 64-bit DImode value in an xmm register. */
5267 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5268 gen_rtx_SUBREG (SImode, operands[1], 0)));
5269 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5270 gen_rtx_SUBREG (SImode, operands[1], 4)));
5271 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5274 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5278 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5279 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5280 (clobber (match_scratch:V4SI 3 ""))
5281 (clobber (match_scratch:V4SI 4 ""))
5282 (clobber (match_operand:DI 2 "memory_operand" ""))]
5283 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5284 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5285 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5286 && reload_completed"
5287 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5289 ;; Avoid store forwarding (partial memory) stall penalty by extending
5290 ;; SImode value to DImode through XMM register instead of pushing two
5291 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5292 ;; targets benefit from this optimization. Also note that fild
5293 ;; loads from memory only.
5295 (define_insn "*floatunssi<mode>2_1"
5296 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5297 (unsigned_float:X87MODEF
5298 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5299 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5300 (clobber (match_scratch:SI 3 "=X,x"))]
5302 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5305 [(set_attr "type" "multi")
5306 (set_attr "mode" "<MODE>")])
5309 [(set (match_operand:X87MODEF 0 "register_operand" "")
5310 (unsigned_float:X87MODEF
5311 (match_operand:SI 1 "register_operand" "")))
5312 (clobber (match_operand:DI 2 "memory_operand" ""))
5313 (clobber (match_scratch:SI 3 ""))]
5315 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5317 && reload_completed"
5318 [(set (match_dup 2) (match_dup 1))
5320 (float:X87MODEF (match_dup 2)))]
5321 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5324 [(set (match_operand:X87MODEF 0 "register_operand" "")
5325 (unsigned_float:X87MODEF
5326 (match_operand:SI 1 "memory_operand" "")))
5327 (clobber (match_operand:DI 2 "memory_operand" ""))
5328 (clobber (match_scratch:SI 3 ""))]
5330 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5332 && reload_completed"
5333 [(set (match_dup 2) (match_dup 3))
5335 (float:X87MODEF (match_dup 2)))]
5337 emit_move_insn (operands[3], operands[1]);
5338 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5341 (define_expand "floatunssi<mode>2"
5343 [(set (match_operand:X87MODEF 0 "register_operand" "")
5344 (unsigned_float:X87MODEF
5345 (match_operand:SI 1 "nonimmediate_operand" "")))
5346 (clobber (match_dup 2))
5347 (clobber (match_scratch:SI 3 ""))])]
5349 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5351 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5353 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5355 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5360 enum ix86_stack_slot slot = (virtuals_instantiated
5363 operands[2] = assign_386_stack_local (DImode, slot);
5367 (define_expand "floatunsdisf2"
5368 [(use (match_operand:SF 0 "register_operand" ""))
5369 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5370 "TARGET_64BIT && TARGET_SSE_MATH"
5371 "x86_emit_floatuns (operands); DONE;")
5373 (define_expand "floatunsdidf2"
5374 [(use (match_operand:DF 0 "register_operand" ""))
5375 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5376 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5377 && TARGET_SSE2 && TARGET_SSE_MATH"
5380 x86_emit_floatuns (operands);
5382 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5386 ;; Load effective address instructions
5388 (define_insn_and_split "*lea<mode>"
5389 [(set (match_operand:SWI48 0 "register_operand" "=r")
5390 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5393 rtx addr = operands[1];
5395 if (GET_CODE (addr) == SUBREG)
5397 gcc_assert (TARGET_64BIT);
5398 gcc_assert (<MODE>mode == SImode);
5399 gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
5400 return "lea{l}\t{%E1, %0|%0, %E1}";
5402 else if (GET_CODE (addr) == ZERO_EXTEND
5403 || GET_CODE (addr) == AND)
5405 gcc_assert (TARGET_64BIT);
5406 gcc_assert (<MODE>mode == DImode);
5407 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5410 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5412 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5415 ix86_split_lea_for_addr (operands, <MODE>mode);
5418 [(set_attr "type" "lea")
5419 (set_attr "mode" "<MODE>")])
5423 (define_expand "add<mode>3"
5424 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5425 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5426 (match_operand:SDWIM 2 "<general_operand>" "")))]
5428 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5430 (define_insn_and_split "*add<dwi>3_doubleword"
5431 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5433 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5434 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5435 (clobber (reg:CC FLAGS_REG))]
5436 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5439 [(parallel [(set (reg:CC FLAGS_REG)
5440 (unspec:CC [(match_dup 1) (match_dup 2)]
5443 (plus:DWIH (match_dup 1) (match_dup 2)))])
5444 (parallel [(set (match_dup 3)
5448 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5450 (clobber (reg:CC FLAGS_REG))])]
5451 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5453 (define_insn "*add<mode>3_cc"
5454 [(set (reg:CC FLAGS_REG)
5456 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5457 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5459 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5460 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5461 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5462 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5463 [(set_attr "type" "alu")
5464 (set_attr "mode" "<MODE>")])
5466 (define_insn "addqi3_cc"
5467 [(set (reg:CC FLAGS_REG)
5469 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5470 (match_operand:QI 2 "general_operand" "qn,qm")]
5472 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5473 (plus:QI (match_dup 1) (match_dup 2)))]
5474 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5475 "add{b}\t{%2, %0|%0, %2}"
5476 [(set_attr "type" "alu")
5477 (set_attr "mode" "QI")])
5479 (define_insn "*add<mode>_1"
5480 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5482 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5483 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5484 (clobber (reg:CC FLAGS_REG))]
5485 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5487 switch (get_attr_type (insn))
5493 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5494 if (operands[2] == const1_rtx)
5495 return "inc{<imodesuffix>}\t%0";
5498 gcc_assert (operands[2] == constm1_rtx);
5499 return "dec{<imodesuffix>}\t%0";
5503 /* For most processors, ADD is faster than LEA. This alternative
5504 was added to use ADD as much as possible. */
5505 if (which_alternative == 2)
5508 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5511 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5512 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5513 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5515 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5519 (cond [(eq_attr "alternative" "3")
5520 (const_string "lea")
5521 (match_operand:SWI48 2 "incdec_operand" "")
5522 (const_string "incdec")
5524 (const_string "alu")))
5525 (set (attr "length_immediate")
5527 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5529 (const_string "*")))
5530 (set_attr "mode" "<MODE>")])
5532 ;; It may seem that nonimmediate operand is proper one for operand 1.
5533 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5534 ;; we take care in ix86_binary_operator_ok to not allow two memory
5535 ;; operands so proper swapping will be done in reload. This allow
5536 ;; patterns constructed from addsi_1 to match.
5538 (define_insn "addsi_1_zext"
5539 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5541 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5542 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5543 (clobber (reg:CC FLAGS_REG))]
5544 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5546 switch (get_attr_type (insn))
5552 if (operands[2] == const1_rtx)
5553 return "inc{l}\t%k0";
5556 gcc_assert (operands[2] == constm1_rtx);
5557 return "dec{l}\t%k0";
5561 /* For most processors, ADD is faster than LEA. This alternative
5562 was added to use ADD as much as possible. */
5563 if (which_alternative == 1)
5566 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5569 if (x86_maybe_negate_const_int (&operands[2], SImode))
5570 return "sub{l}\t{%2, %k0|%k0, %2}";
5572 return "add{l}\t{%2, %k0|%k0, %2}";
5576 (cond [(eq_attr "alternative" "2")
5577 (const_string "lea")
5578 (match_operand:SI 2 "incdec_operand" "")
5579 (const_string "incdec")
5581 (const_string "alu")))
5582 (set (attr "length_immediate")
5584 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5586 (const_string "*")))
5587 (set_attr "mode" "SI")])
5589 (define_insn "*addhi_1"
5590 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5591 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5592 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5593 (clobber (reg:CC FLAGS_REG))]
5594 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5596 switch (get_attr_type (insn))
5602 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5603 if (operands[2] == const1_rtx)
5604 return "inc{w}\t%0";
5607 gcc_assert (operands[2] == constm1_rtx);
5608 return "dec{w}\t%0";
5612 /* For most processors, ADD is faster than LEA. This alternative
5613 was added to use ADD as much as possible. */
5614 if (which_alternative == 2)
5617 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5620 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5621 if (x86_maybe_negate_const_int (&operands[2], HImode))
5622 return "sub{w}\t{%2, %0|%0, %2}";
5624 return "add{w}\t{%2, %0|%0, %2}";
5628 (cond [(eq_attr "alternative" "3")
5629 (const_string "lea")
5630 (match_operand:HI 2 "incdec_operand" "")
5631 (const_string "incdec")
5633 (const_string "alu")))
5634 (set (attr "length_immediate")
5636 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5638 (const_string "*")))
5639 (set_attr "mode" "HI,HI,HI,SI")])
5641 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5642 (define_insn "*addqi_1"
5643 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5644 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5645 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5646 (clobber (reg:CC FLAGS_REG))]
5647 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5649 bool widen = (which_alternative == 3 || which_alternative == 4);
5651 switch (get_attr_type (insn))
5657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5658 if (operands[2] == const1_rtx)
5659 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5662 gcc_assert (operands[2] == constm1_rtx);
5663 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5667 /* For most processors, ADD is faster than LEA. These alternatives
5668 were added to use ADD as much as possible. */
5669 if (which_alternative == 2 || which_alternative == 4)
5672 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5675 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5676 if (x86_maybe_negate_const_int (&operands[2], QImode))
5679 return "sub{l}\t{%2, %k0|%k0, %2}";
5681 return "sub{b}\t{%2, %0|%0, %2}";
5684 return "add{l}\t{%k2, %k0|%k0, %k2}";
5686 return "add{b}\t{%2, %0|%0, %2}";
5690 (cond [(eq_attr "alternative" "5")
5691 (const_string "lea")
5692 (match_operand:QI 2 "incdec_operand" "")
5693 (const_string "incdec")
5695 (const_string "alu")))
5696 (set (attr "length_immediate")
5698 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5700 (const_string "*")))
5701 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5703 (define_insn "*addqi_1_slp"
5704 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5705 (plus:QI (match_dup 0)
5706 (match_operand:QI 1 "general_operand" "qn,qm")))
5707 (clobber (reg:CC FLAGS_REG))]
5708 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5709 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5711 switch (get_attr_type (insn))
5714 if (operands[1] == const1_rtx)
5715 return "inc{b}\t%0";
5718 gcc_assert (operands[1] == constm1_rtx);
5719 return "dec{b}\t%0";
5723 if (x86_maybe_negate_const_int (&operands[1], QImode))
5724 return "sub{b}\t{%1, %0|%0, %1}";
5726 return "add{b}\t{%1, %0|%0, %1}";
5730 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5731 (const_string "incdec")
5732 (const_string "alu1")))
5733 (set (attr "memory")
5734 (if_then_else (match_operand 1 "memory_operand" "")
5735 (const_string "load")
5736 (const_string "none")))
5737 (set_attr "mode" "QI")])
5739 ;; Split non destructive adds if we cannot use lea.
5741 [(set (match_operand:SWI48 0 "register_operand" "")
5742 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5743 (match_operand:SWI48 2 "nonmemory_operand" "")))
5744 (clobber (reg:CC FLAGS_REG))]
5745 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5746 [(set (match_dup 0) (match_dup 1))
5747 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5748 (clobber (reg:CC FLAGS_REG))])])
5750 ;; Convert add to the lea pattern to avoid flags dependency.
5752 [(set (match_operand:SWI 0 "register_operand" "")
5753 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5754 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5755 (clobber (reg:CC FLAGS_REG))]
5756 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5759 enum machine_mode mode = <MODE>mode;
5762 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5765 operands[0] = gen_lowpart (mode, operands[0]);
5766 operands[1] = gen_lowpart (mode, operands[1]);
5767 operands[2] = gen_lowpart (mode, operands[2]);
5770 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5772 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5776 ;; Convert add to the lea pattern to avoid flags dependency.
5778 [(set (match_operand:DI 0 "register_operand" "")
5780 (plus:SI (match_operand:SI 1 "register_operand" "")
5781 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5782 (clobber (reg:CC FLAGS_REG))]
5783 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5785 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5787 (define_insn "*add<mode>_2"
5788 [(set (reg FLAGS_REG)
5791 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5792 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5794 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5795 (plus:SWI (match_dup 1) (match_dup 2)))]
5796 "ix86_match_ccmode (insn, CCGOCmode)
5797 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5799 switch (get_attr_type (insn))
5802 if (operands[2] == const1_rtx)
5803 return "inc{<imodesuffix>}\t%0";
5806 gcc_assert (operands[2] == constm1_rtx);
5807 return "dec{<imodesuffix>}\t%0";
5811 if (which_alternative == 2)
5814 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5817 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5818 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5819 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5821 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5825 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5826 (const_string "incdec")
5827 (const_string "alu")))
5828 (set (attr "length_immediate")
5830 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5832 (const_string "*")))
5833 (set_attr "mode" "<MODE>")])
5835 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5836 (define_insn "*addsi_2_zext"
5837 [(set (reg FLAGS_REG)
5839 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5840 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5842 (set (match_operand:DI 0 "register_operand" "=r,r")
5843 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5844 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5845 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5847 switch (get_attr_type (insn))
5850 if (operands[2] == const1_rtx)
5851 return "inc{l}\t%k0";
5854 gcc_assert (operands[2] == constm1_rtx);
5855 return "dec{l}\t%k0";
5859 if (which_alternative == 1)
5862 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5865 if (x86_maybe_negate_const_int (&operands[2], SImode))
5866 return "sub{l}\t{%2, %k0|%k0, %2}";
5868 return "add{l}\t{%2, %k0|%k0, %2}";
5872 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5873 (const_string "incdec")
5874 (const_string "alu")))
5875 (set (attr "length_immediate")
5877 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5879 (const_string "*")))
5880 (set_attr "mode" "SI")])
5882 (define_insn "*add<mode>_3"
5883 [(set (reg FLAGS_REG)
5885 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5886 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5887 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5888 "ix86_match_ccmode (insn, CCZmode)
5889 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5891 switch (get_attr_type (insn))
5894 if (operands[2] == const1_rtx)
5895 return "inc{<imodesuffix>}\t%0";
5898 gcc_assert (operands[2] == constm1_rtx);
5899 return "dec{<imodesuffix>}\t%0";
5903 if (which_alternative == 1)
5906 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5909 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5910 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5911 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5913 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5917 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5918 (const_string "incdec")
5919 (const_string "alu")))
5920 (set (attr "length_immediate")
5922 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5924 (const_string "*")))
5925 (set_attr "mode" "<MODE>")])
5927 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5928 (define_insn "*addsi_3_zext"
5929 [(set (reg FLAGS_REG)
5931 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5932 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5933 (set (match_operand:DI 0 "register_operand" "=r,r")
5934 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5935 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5936 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5938 switch (get_attr_type (insn))
5941 if (operands[2] == const1_rtx)
5942 return "inc{l}\t%k0";
5945 gcc_assert (operands[2] == constm1_rtx);
5946 return "dec{l}\t%k0";
5950 if (which_alternative == 1)
5953 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5956 if (x86_maybe_negate_const_int (&operands[2], SImode))
5957 return "sub{l}\t{%2, %k0|%k0, %2}";
5959 return "add{l}\t{%2, %k0|%k0, %2}";
5963 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5964 (const_string "incdec")
5965 (const_string "alu")))
5966 (set (attr "length_immediate")
5968 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5970 (const_string "*")))
5971 (set_attr "mode" "SI")])
5973 ; For comparisons against 1, -1 and 128, we may generate better code
5974 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5975 ; is matched then. We can't accept general immediate, because for
5976 ; case of overflows, the result is messed up.
5977 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5978 ; only for comparisons not depending on it.
5980 (define_insn "*adddi_4"
5981 [(set (reg FLAGS_REG)
5983 (match_operand:DI 1 "nonimmediate_operand" "0")
5984 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5985 (clobber (match_scratch:DI 0 "=rm"))]
5987 && ix86_match_ccmode (insn, CCGCmode)"
5989 switch (get_attr_type (insn))
5992 if (operands[2] == constm1_rtx)
5993 return "inc{q}\t%0";
5996 gcc_assert (operands[2] == const1_rtx);
5997 return "dec{q}\t%0";
6001 if (x86_maybe_negate_const_int (&operands[2], DImode))
6002 return "add{q}\t{%2, %0|%0, %2}";
6004 return "sub{q}\t{%2, %0|%0, %2}";
6008 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6009 (const_string "incdec")
6010 (const_string "alu")))
6011 (set (attr "length_immediate")
6013 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6015 (const_string "*")))
6016 (set_attr "mode" "DI")])
6018 ; For comparisons against 1, -1 and 128, we may generate better code
6019 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6020 ; is matched then. We can't accept general immediate, because for
6021 ; case of overflows, the result is messed up.
6022 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6023 ; only for comparisons not depending on it.
6025 (define_insn "*add<mode>_4"
6026 [(set (reg FLAGS_REG)
6028 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6029 (match_operand:SWI124 2 "const_int_operand" "n")))
6030 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6031 "ix86_match_ccmode (insn, CCGCmode)"
6033 switch (get_attr_type (insn))
6036 if (operands[2] == constm1_rtx)
6037 return "inc{<imodesuffix>}\t%0";
6040 gcc_assert (operands[2] == const1_rtx);
6041 return "dec{<imodesuffix>}\t%0";
6045 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6046 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6048 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6052 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6053 (const_string "incdec")
6054 (const_string "alu")))
6055 (set (attr "length_immediate")
6057 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6059 (const_string "*")))
6060 (set_attr "mode" "<MODE>")])
6062 (define_insn "*add<mode>_5"
6063 [(set (reg FLAGS_REG)
6066 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6067 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6069 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6070 "ix86_match_ccmode (insn, CCGOCmode)
6071 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6073 switch (get_attr_type (insn))
6076 if (operands[2] == const1_rtx)
6077 return "inc{<imodesuffix>}\t%0";
6080 gcc_assert (operands[2] == constm1_rtx);
6081 return "dec{<imodesuffix>}\t%0";
6085 if (which_alternative == 1)
6088 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6091 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6092 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6093 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6095 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6099 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6100 (const_string "incdec")
6101 (const_string "alu")))
6102 (set (attr "length_immediate")
6104 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6106 (const_string "*")))
6107 (set_attr "mode" "<MODE>")])
6109 (define_insn "*addqi_ext_1_rex64"
6110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6115 (match_operand 1 "ext_register_operand" "0")
6118 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6119 (clobber (reg:CC FLAGS_REG))]
6122 switch (get_attr_type (insn))
6125 if (operands[2] == const1_rtx)
6126 return "inc{b}\t%h0";
6129 gcc_assert (operands[2] == constm1_rtx);
6130 return "dec{b}\t%h0";
6134 return "add{b}\t{%2, %h0|%h0, %2}";
6138 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6139 (const_string "incdec")
6140 (const_string "alu")))
6141 (set_attr "modrm" "1")
6142 (set_attr "mode" "QI")])
6144 (define_insn "addqi_ext_1"
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 "general_operand" "Qmn")))
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_2"
6180 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6185 (match_operand 1 "ext_register_operand" "%0")
6189 (match_operand 2 "ext_register_operand" "Q")
6192 (clobber (reg:CC FLAGS_REG))]
6194 "add{b}\t{%h2, %h0|%h0, %h2}"
6195 [(set_attr "type" "alu")
6196 (set_attr "mode" "QI")])
6198 ;; The lea patterns for modes less than 32 bits need to be matched by
6199 ;; several insns converted to real lea by splitters.
6201 (define_insn_and_split "*lea_general_1"
6202 [(set (match_operand 0 "register_operand" "=r")
6203 (plus (plus (match_operand 1 "index_register_operand" "l")
6204 (match_operand 2 "register_operand" "r"))
6205 (match_operand 3 "immediate_operand" "i")))]
6206 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6207 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6208 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6209 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6210 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6211 || GET_MODE (operands[3]) == VOIDmode)"
6213 "&& reload_completed"
6216 enum machine_mode mode = SImode;
6219 operands[0] = gen_lowpart (mode, operands[0]);
6220 operands[1] = gen_lowpart (mode, operands[1]);
6221 operands[2] = gen_lowpart (mode, operands[2]);
6222 operands[3] = gen_lowpart (mode, operands[3]);
6224 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6227 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6230 [(set_attr "type" "lea")
6231 (set_attr "mode" "SI")])
6233 (define_insn_and_split "*lea_general_2"
6234 [(set (match_operand 0 "register_operand" "=r")
6235 (plus (mult (match_operand 1 "index_register_operand" "l")
6236 (match_operand 2 "const248_operand" "n"))
6237 (match_operand 3 "nonmemory_operand" "ri")))]
6238 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6239 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6240 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6241 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6242 || GET_MODE (operands[3]) == VOIDmode)"
6244 "&& reload_completed"
6247 enum machine_mode mode = SImode;
6250 operands[0] = gen_lowpart (mode, operands[0]);
6251 operands[1] = gen_lowpart (mode, operands[1]);
6252 operands[3] = gen_lowpart (mode, operands[3]);
6254 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6257 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6260 [(set_attr "type" "lea")
6261 (set_attr "mode" "SI")])
6263 (define_insn_and_split "*lea_general_3"
6264 [(set (match_operand 0 "register_operand" "=r")
6265 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6266 (match_operand 2 "const248_operand" "n"))
6267 (match_operand 3 "register_operand" "r"))
6268 (match_operand 4 "immediate_operand" "i")))]
6269 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6270 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6271 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6272 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6274 "&& reload_completed"
6277 enum machine_mode mode = SImode;
6280 operands[0] = gen_lowpart (mode, operands[0]);
6281 operands[1] = gen_lowpart (mode, operands[1]);
6282 operands[3] = gen_lowpart (mode, operands[3]);
6283 operands[4] = gen_lowpart (mode, operands[4]);
6285 pat = gen_rtx_PLUS (mode,
6287 gen_rtx_MULT (mode, operands[1],
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_4"
6299 [(set (match_operand 0 "register_operand" "=r")
6301 (match_operand 1 "index_register_operand" "l")
6302 (match_operand 2 "const_int_operand" "n"))
6303 (match_operand 3 "const_int_operand" "n")))]
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]) == SImode
6307 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6308 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6309 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6310 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6311 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6313 "&& reload_completed"
6316 enum machine_mode mode = GET_MODE (operands[0]);
6319 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6322 operands[0] = gen_lowpart (mode, operands[0]);
6323 operands[1] = gen_lowpart (mode, operands[1]);
6326 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6328 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6329 INTVAL (operands[3]));
6331 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6334 [(set_attr "type" "lea")
6336 (if_then_else (match_operand:DI 0 "" "")
6338 (const_string "SI")))])
6340 ;; Subtract instructions
6342 (define_expand "sub<mode>3"
6343 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6344 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6345 (match_operand:SDWIM 2 "<general_operand>" "")))]
6347 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6349 (define_insn_and_split "*sub<dwi>3_doubleword"
6350 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6352 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6353 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6354 (clobber (reg:CC FLAGS_REG))]
6355 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6358 [(parallel [(set (reg:CC FLAGS_REG)
6359 (compare:CC (match_dup 1) (match_dup 2)))
6361 (minus:DWIH (match_dup 1) (match_dup 2)))])
6362 (parallel [(set (match_dup 3)
6366 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6368 (clobber (reg:CC FLAGS_REG))])]
6369 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6371 (define_insn "*sub<mode>_1"
6372 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6374 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6375 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6376 (clobber (reg:CC FLAGS_REG))]
6377 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6378 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6379 [(set_attr "type" "alu")
6380 (set_attr "mode" "<MODE>")])
6382 (define_insn "*subsi_1_zext"
6383 [(set (match_operand:DI 0 "register_operand" "=r")
6385 (minus:SI (match_operand:SI 1 "register_operand" "0")
6386 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6387 (clobber (reg:CC FLAGS_REG))]
6388 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6389 "sub{l}\t{%2, %k0|%k0, %2}"
6390 [(set_attr "type" "alu")
6391 (set_attr "mode" "SI")])
6393 (define_insn "*subqi_1_slp"
6394 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6395 (minus:QI (match_dup 0)
6396 (match_operand:QI 1 "general_operand" "qn,qm")))
6397 (clobber (reg:CC FLAGS_REG))]
6398 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6400 "sub{b}\t{%1, %0|%0, %1}"
6401 [(set_attr "type" "alu1")
6402 (set_attr "mode" "QI")])
6404 (define_insn "*sub<mode>_2"
6405 [(set (reg FLAGS_REG)
6408 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6409 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6411 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6412 (minus:SWI (match_dup 1) (match_dup 2)))]
6413 "ix86_match_ccmode (insn, CCGOCmode)
6414 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6415 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6416 [(set_attr "type" "alu")
6417 (set_attr "mode" "<MODE>")])
6419 (define_insn "*subsi_2_zext"
6420 [(set (reg FLAGS_REG)
6422 (minus:SI (match_operand:SI 1 "register_operand" "0")
6423 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6425 (set (match_operand:DI 0 "register_operand" "=r")
6427 (minus:SI (match_dup 1)
6429 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6430 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6431 "sub{l}\t{%2, %k0|%k0, %2}"
6432 [(set_attr "type" "alu")
6433 (set_attr "mode" "SI")])
6435 (define_insn "*sub<mode>_3"
6436 [(set (reg FLAGS_REG)
6437 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6438 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6439 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6440 (minus:SWI (match_dup 1) (match_dup 2)))]
6441 "ix86_match_ccmode (insn, CCmode)
6442 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6443 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6444 [(set_attr "type" "alu")
6445 (set_attr "mode" "<MODE>")])
6447 (define_insn "*subsi_3_zext"
6448 [(set (reg FLAGS_REG)
6449 (compare (match_operand:SI 1 "register_operand" "0")
6450 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6451 (set (match_operand:DI 0 "register_operand" "=r")
6453 (minus:SI (match_dup 1)
6455 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6456 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6457 "sub{l}\t{%2, %1|%1, %2}"
6458 [(set_attr "type" "alu")
6459 (set_attr "mode" "SI")])
6461 ;; Add with carry and subtract with borrow
6463 (define_expand "<plusminus_insn><mode>3_carry"
6465 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6467 (match_operand:SWI 1 "nonimmediate_operand" "")
6468 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6469 [(match_operand 3 "flags_reg_operand" "")
6471 (match_operand:SWI 2 "<general_operand>" ""))))
6472 (clobber (reg:CC FLAGS_REG))])]
6473 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6475 (define_insn "*<plusminus_insn><mode>3_carry"
6476 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6478 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6480 (match_operator 3 "ix86_carry_flag_operator"
6481 [(reg FLAGS_REG) (const_int 0)])
6482 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6483 (clobber (reg:CC FLAGS_REG))]
6484 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6485 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6486 [(set_attr "type" "alu")
6487 (set_attr "use_carry" "1")
6488 (set_attr "pent_pair" "pu")
6489 (set_attr "mode" "<MODE>")])
6491 (define_insn "*addsi3_carry_zext"
6492 [(set (match_operand:DI 0 "register_operand" "=r")
6494 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6495 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6496 [(reg FLAGS_REG) (const_int 0)])
6497 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6498 (clobber (reg:CC FLAGS_REG))]
6499 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6500 "adc{l}\t{%2, %k0|%k0, %2}"
6501 [(set_attr "type" "alu")
6502 (set_attr "use_carry" "1")
6503 (set_attr "pent_pair" "pu")
6504 (set_attr "mode" "SI")])
6506 (define_insn "*subsi3_carry_zext"
6507 [(set (match_operand:DI 0 "register_operand" "=r")
6509 (minus:SI (match_operand:SI 1 "register_operand" "0")
6510 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6511 [(reg FLAGS_REG) (const_int 0)])
6512 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6513 (clobber (reg:CC FLAGS_REG))]
6514 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6515 "sbb{l}\t{%2, %k0|%k0, %2}"
6516 [(set_attr "type" "alu")
6517 (set_attr "pent_pair" "pu")
6518 (set_attr "mode" "SI")])
6520 ;; Overflow setting add and subtract instructions
6522 (define_insn "*add<mode>3_cconly_overflow"
6523 [(set (reg:CCC FLAGS_REG)
6526 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6527 (match_operand:SWI 2 "<general_operand>" "<g>"))
6529 (clobber (match_scratch:SWI 0 "=<r>"))]
6530 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6531 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6532 [(set_attr "type" "alu")
6533 (set_attr "mode" "<MODE>")])
6535 (define_insn "*sub<mode>3_cconly_overflow"
6536 [(set (reg:CCC FLAGS_REG)
6539 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6540 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6543 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6544 [(set_attr "type" "icmp")
6545 (set_attr "mode" "<MODE>")])
6547 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6548 [(set (reg:CCC FLAGS_REG)
6551 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6552 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6554 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6555 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6556 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6557 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6558 [(set_attr "type" "alu")
6559 (set_attr "mode" "<MODE>")])
6561 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6562 [(set (reg:CCC FLAGS_REG)
6565 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6566 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6568 (set (match_operand:DI 0 "register_operand" "=r")
6569 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6570 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6571 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6572 [(set_attr "type" "alu")
6573 (set_attr "mode" "SI")])
6575 ;; The patterns that match these are at the end of this file.
6577 (define_expand "<plusminus_insn>xf3"
6578 [(set (match_operand:XF 0 "register_operand" "")
6580 (match_operand:XF 1 "register_operand" "")
6581 (match_operand:XF 2 "register_operand" "")))]
6584 (define_expand "<plusminus_insn><mode>3"
6585 [(set (match_operand:MODEF 0 "register_operand" "")
6587 (match_operand:MODEF 1 "register_operand" "")
6588 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6589 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6590 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6592 ;; Multiply instructions
6594 (define_expand "mul<mode>3"
6595 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6597 (match_operand:SWIM248 1 "register_operand" "")
6598 (match_operand:SWIM248 2 "<general_operand>" "")))
6599 (clobber (reg:CC FLAGS_REG))])])
6601 (define_expand "mulqi3"
6602 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6604 (match_operand:QI 1 "register_operand" "")
6605 (match_operand:QI 2 "nonimmediate_operand" "")))
6606 (clobber (reg:CC FLAGS_REG))])]
6607 "TARGET_QIMODE_MATH")
6610 ;; IMUL reg32/64, reg32/64, imm8 Direct
6611 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6612 ;; IMUL reg32/64, reg32/64, imm32 Direct
6613 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6614 ;; IMUL reg32/64, reg32/64 Direct
6615 ;; IMUL reg32/64, mem32/64 Direct
6617 ;; On BDVER1, all above IMULs use DirectPath
6619 (define_insn "*mul<mode>3_1"
6620 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6622 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6623 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6624 (clobber (reg:CC FLAGS_REG))]
6625 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6627 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6628 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6629 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6630 [(set_attr "type" "imul")
6631 (set_attr "prefix_0f" "0,0,1")
6632 (set (attr "athlon_decode")
6633 (cond [(eq_attr "cpu" "athlon")
6634 (const_string "vector")
6635 (eq_attr "alternative" "1")
6636 (const_string "vector")
6637 (and (eq_attr "alternative" "2")
6638 (match_operand 1 "memory_operand" ""))
6639 (const_string "vector")]
6640 (const_string "direct")))
6641 (set (attr "amdfam10_decode")
6642 (cond [(and (eq_attr "alternative" "0,1")
6643 (match_operand 1 "memory_operand" ""))
6644 (const_string "vector")]
6645 (const_string "direct")))
6646 (set_attr "bdver1_decode" "direct")
6647 (set_attr "mode" "<MODE>")])
6649 (define_insn "*mulsi3_1_zext"
6650 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6652 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6653 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6654 (clobber (reg:CC FLAGS_REG))]
6656 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6658 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6659 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6660 imul{l}\t{%2, %k0|%k0, %2}"
6661 [(set_attr "type" "imul")
6662 (set_attr "prefix_0f" "0,0,1")
6663 (set (attr "athlon_decode")
6664 (cond [(eq_attr "cpu" "athlon")
6665 (const_string "vector")
6666 (eq_attr "alternative" "1")
6667 (const_string "vector")
6668 (and (eq_attr "alternative" "2")
6669 (match_operand 1 "memory_operand" ""))
6670 (const_string "vector")]
6671 (const_string "direct")))
6672 (set (attr "amdfam10_decode")
6673 (cond [(and (eq_attr "alternative" "0,1")
6674 (match_operand 1 "memory_operand" ""))
6675 (const_string "vector")]
6676 (const_string "direct")))
6677 (set_attr "bdver1_decode" "direct")
6678 (set_attr "mode" "SI")])
6681 ;; IMUL reg16, reg16, imm8 VectorPath
6682 ;; IMUL reg16, mem16, imm8 VectorPath
6683 ;; IMUL reg16, reg16, imm16 VectorPath
6684 ;; IMUL reg16, mem16, imm16 VectorPath
6685 ;; IMUL reg16, reg16 Direct
6686 ;; IMUL reg16, mem16 Direct
6688 ;; On BDVER1, all HI MULs use DoublePath
6690 (define_insn "*mulhi3_1"
6691 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6692 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6693 (match_operand:HI 2 "general_operand" "K,n,mr")))
6694 (clobber (reg:CC FLAGS_REG))]
6696 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6698 imul{w}\t{%2, %1, %0|%0, %1, %2}
6699 imul{w}\t{%2, %1, %0|%0, %1, %2}
6700 imul{w}\t{%2, %0|%0, %2}"
6701 [(set_attr "type" "imul")
6702 (set_attr "prefix_0f" "0,0,1")
6703 (set (attr "athlon_decode")
6704 (cond [(eq_attr "cpu" "athlon")
6705 (const_string "vector")
6706 (eq_attr "alternative" "1,2")
6707 (const_string "vector")]
6708 (const_string "direct")))
6709 (set (attr "amdfam10_decode")
6710 (cond [(eq_attr "alternative" "0,1")
6711 (const_string "vector")]
6712 (const_string "direct")))
6713 (set_attr "bdver1_decode" "double")
6714 (set_attr "mode" "HI")])
6716 ;;On AMDFAM10 and BDVER1
6720 (define_insn "*mulqi3_1"
6721 [(set (match_operand:QI 0 "register_operand" "=a")
6722 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6723 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6724 (clobber (reg:CC FLAGS_REG))]
6726 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6728 [(set_attr "type" "imul")
6729 (set_attr "length_immediate" "0")
6730 (set (attr "athlon_decode")
6731 (if_then_else (eq_attr "cpu" "athlon")
6732 (const_string "vector")
6733 (const_string "direct")))
6734 (set_attr "amdfam10_decode" "direct")
6735 (set_attr "bdver1_decode" "direct")
6736 (set_attr "mode" "QI")])
6738 (define_expand "<u>mul<mode><dwi>3"
6739 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6742 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6744 (match_operand:DWIH 2 "register_operand" ""))))
6745 (clobber (reg:CC FLAGS_REG))])])
6747 (define_expand "<u>mulqihi3"
6748 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6751 (match_operand:QI 1 "nonimmediate_operand" ""))
6753 (match_operand:QI 2 "register_operand" ""))))
6754 (clobber (reg:CC FLAGS_REG))])]
6755 "TARGET_QIMODE_MATH")
6757 (define_insn "*bmi2_umulditi3_1"
6758 [(set (match_operand:DI 0 "register_operand" "=r")
6760 (match_operand:DI 2 "nonimmediate_operand" "%d")
6761 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6762 (set (match_operand:DI 1 "register_operand" "=r")
6765 (mult:TI (zero_extend:TI (match_dup 2))
6766 (zero_extend:TI (match_dup 3)))
6768 "TARGET_64BIT && TARGET_BMI2
6769 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6770 "mulx\t{%3, %0, %1|%1, %0, %3}"
6771 [(set_attr "type" "imulx")
6772 (set_attr "prefix" "vex")
6773 (set_attr "mode" "DI")])
6775 (define_insn "*bmi2_umulsidi3_1"
6776 [(set (match_operand:SI 0 "register_operand" "=r")
6778 (match_operand:SI 2 "nonimmediate_operand" "%d")
6779 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6780 (set (match_operand:SI 1 "register_operand" "=r")
6783 (mult:DI (zero_extend:DI (match_dup 2))
6784 (zero_extend:DI (match_dup 3)))
6786 "!TARGET_64BIT && TARGET_BMI2
6787 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6788 "mulx\t{%3, %0, %1|%1, %0, %3}"
6789 [(set_attr "type" "imulx")
6790 (set_attr "prefix" "vex")
6791 (set_attr "mode" "SI")])
6793 (define_insn "*umul<mode><dwi>3_1"
6794 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6797 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6799 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6800 (clobber (reg:CC FLAGS_REG))]
6801 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6803 mul{<imodesuffix>}\t%2
6805 [(set_attr "isa" "*,bmi2")
6806 (set_attr "type" "imul,imulx")
6807 (set_attr "length_immediate" "0,*")
6808 (set (attr "athlon_decode")
6809 (cond [(eq_attr "alternative" "0")
6810 (if_then_else (eq_attr "cpu" "athlon")
6811 (const_string "vector")
6812 (const_string "double"))]
6813 (const_string "*")))
6814 (set_attr "amdfam10_decode" "double,*")
6815 (set_attr "bdver1_decode" "direct,*")
6816 (set_attr "prefix" "orig,vex")
6817 (set_attr "mode" "<MODE>")])
6819 ;; Convert mul to the mulx pattern to avoid flags dependency.
6821 [(set (match_operand:<DWI> 0 "register_operand" "")
6824 (match_operand:DWIH 1 "register_operand" ""))
6826 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6827 (clobber (reg:CC FLAGS_REG))]
6828 "TARGET_BMI2 && reload_completed
6829 && true_regnum (operands[1]) == DX_REG"
6830 [(parallel [(set (match_dup 3)
6831 (mult:DWIH (match_dup 1) (match_dup 2)))
6835 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6836 (zero_extend:<DWI> (match_dup 2)))
6839 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6841 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6844 (define_insn "*mul<mode><dwi>3_1"
6845 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6848 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6850 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6851 (clobber (reg:CC FLAGS_REG))]
6852 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6853 "imul{<imodesuffix>}\t%2"
6854 [(set_attr "type" "imul")
6855 (set_attr "length_immediate" "0")
6856 (set (attr "athlon_decode")
6857 (if_then_else (eq_attr "cpu" "athlon")
6858 (const_string "vector")
6859 (const_string "double")))
6860 (set_attr "amdfam10_decode" "double")
6861 (set_attr "bdver1_decode" "direct")
6862 (set_attr "mode" "<MODE>")])
6864 (define_insn "*<u>mulqihi3_1"
6865 [(set (match_operand:HI 0 "register_operand" "=a")
6868 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6870 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6871 (clobber (reg:CC FLAGS_REG))]
6873 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6874 "<sgnprefix>mul{b}\t%2"
6875 [(set_attr "type" "imul")
6876 (set_attr "length_immediate" "0")
6877 (set (attr "athlon_decode")
6878 (if_then_else (eq_attr "cpu" "athlon")
6879 (const_string "vector")
6880 (const_string "direct")))
6881 (set_attr "amdfam10_decode" "direct")
6882 (set_attr "bdver1_decode" "direct")
6883 (set_attr "mode" "QI")])
6885 (define_expand "<s>mul<mode>3_highpart"
6886 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6891 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6893 (match_operand:SWI48 2 "register_operand" "")))
6895 (clobber (match_scratch:SWI48 3 ""))
6896 (clobber (reg:CC FLAGS_REG))])]
6898 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6900 (define_insn "*<s>muldi3_highpart_1"
6901 [(set (match_operand:DI 0 "register_operand" "=d")
6906 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6908 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6910 (clobber (match_scratch:DI 3 "=1"))
6911 (clobber (reg:CC FLAGS_REG))]
6913 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6914 "<sgnprefix>mul{q}\t%2"
6915 [(set_attr "type" "imul")
6916 (set_attr "length_immediate" "0")
6917 (set (attr "athlon_decode")
6918 (if_then_else (eq_attr "cpu" "athlon")
6919 (const_string "vector")
6920 (const_string "double")))
6921 (set_attr "amdfam10_decode" "double")
6922 (set_attr "bdver1_decode" "direct")
6923 (set_attr "mode" "DI")])
6925 (define_insn "*<s>mulsi3_highpart_1"
6926 [(set (match_operand:SI 0 "register_operand" "=d")
6931 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6933 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6935 (clobber (match_scratch:SI 3 "=1"))
6936 (clobber (reg:CC FLAGS_REG))]
6937 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6938 "<sgnprefix>mul{l}\t%2"
6939 [(set_attr "type" "imul")
6940 (set_attr "length_immediate" "0")
6941 (set (attr "athlon_decode")
6942 (if_then_else (eq_attr "cpu" "athlon")
6943 (const_string "vector")
6944 (const_string "double")))
6945 (set_attr "amdfam10_decode" "double")
6946 (set_attr "bdver1_decode" "direct")
6947 (set_attr "mode" "SI")])
6949 (define_insn "*<s>mulsi3_highpart_zext"
6950 [(set (match_operand:DI 0 "register_operand" "=d")
6951 (zero_extend:DI (truncate:SI
6953 (mult:DI (any_extend:DI
6954 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6956 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6958 (clobber (match_scratch:SI 3 "=1"))
6959 (clobber (reg:CC FLAGS_REG))]
6961 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6962 "<sgnprefix>mul{l}\t%2"
6963 [(set_attr "type" "imul")
6964 (set_attr "length_immediate" "0")
6965 (set (attr "athlon_decode")
6966 (if_then_else (eq_attr "cpu" "athlon")
6967 (const_string "vector")
6968 (const_string "double")))
6969 (set_attr "amdfam10_decode" "double")
6970 (set_attr "bdver1_decode" "direct")
6971 (set_attr "mode" "SI")])
6973 ;; The patterns that match these are at the end of this file.
6975 (define_expand "mulxf3"
6976 [(set (match_operand:XF 0 "register_operand" "")
6977 (mult:XF (match_operand:XF 1 "register_operand" "")
6978 (match_operand:XF 2 "register_operand" "")))]
6981 (define_expand "mul<mode>3"
6982 [(set (match_operand:MODEF 0 "register_operand" "")
6983 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6984 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6985 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6986 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6988 ;; Divide instructions
6990 ;; The patterns that match these are at the end of this file.
6992 (define_expand "divxf3"
6993 [(set (match_operand:XF 0 "register_operand" "")
6994 (div:XF (match_operand:XF 1 "register_operand" "")
6995 (match_operand:XF 2 "register_operand" "")))]
6998 (define_expand "divdf3"
6999 [(set (match_operand:DF 0 "register_operand" "")
7000 (div:DF (match_operand:DF 1 "register_operand" "")
7001 (match_operand:DF 2 "nonimmediate_operand" "")))]
7002 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7003 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7005 (define_expand "divsf3"
7006 [(set (match_operand:SF 0 "register_operand" "")
7007 (div:SF (match_operand:SF 1 "register_operand" "")
7008 (match_operand:SF 2 "nonimmediate_operand" "")))]
7009 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7014 && optimize_insn_for_speed_p ()
7015 && flag_finite_math_only && !flag_trapping_math
7016 && flag_unsafe_math_optimizations)
7018 ix86_emit_swdivsf (operands[0], operands[1],
7019 operands[2], SFmode);
7024 ;; Divmod instructions.
7026 (define_expand "divmod<mode>4"
7027 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7029 (match_operand:SWIM248 1 "register_operand" "")
7030 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7031 (set (match_operand:SWIM248 3 "register_operand" "")
7032 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7033 (clobber (reg:CC FLAGS_REG))])])
7035 ;; Split with 8bit unsigned divide:
7036 ;; if (dividend an divisor are in [0-255])
7037 ;; use 8bit unsigned integer divide
7039 ;; use original integer divide
7041 [(set (match_operand:SWI48 0 "register_operand" "")
7042 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7043 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7044 (set (match_operand:SWI48 1 "register_operand" "")
7045 (mod:SWI48 (match_dup 2) (match_dup 3)))
7046 (clobber (reg:CC FLAGS_REG))]
7047 "TARGET_USE_8BIT_IDIV
7048 && TARGET_QIMODE_MATH
7049 && can_create_pseudo_p ()
7050 && !optimize_insn_for_size_p ()"
7052 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7054 (define_insn_and_split "divmod<mode>4_1"
7055 [(set (match_operand:SWI48 0 "register_operand" "=a")
7056 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7057 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7058 (set (match_operand:SWI48 1 "register_operand" "=&d")
7059 (mod:SWI48 (match_dup 2) (match_dup 3)))
7060 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7061 (clobber (reg:CC FLAGS_REG))]
7065 [(parallel [(set (match_dup 1)
7066 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7067 (clobber (reg:CC FLAGS_REG))])
7068 (parallel [(set (match_dup 0)
7069 (div:SWI48 (match_dup 2) (match_dup 3)))
7071 (mod:SWI48 (match_dup 2) (match_dup 3)))
7073 (clobber (reg:CC FLAGS_REG))])]
7075 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7077 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7078 operands[4] = operands[2];
7081 /* Avoid use of cltd in favor of a mov+shift. */
7082 emit_move_insn (operands[1], operands[2]);
7083 operands[4] = operands[1];
7086 [(set_attr "type" "multi")
7087 (set_attr "mode" "<MODE>")])
7089 (define_insn_and_split "*divmod<mode>4"
7090 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7091 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7092 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7093 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7094 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7095 (clobber (reg:CC FLAGS_REG))]
7099 [(parallel [(set (match_dup 1)
7100 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7101 (clobber (reg:CC FLAGS_REG))])
7102 (parallel [(set (match_dup 0)
7103 (div:SWIM248 (match_dup 2) (match_dup 3)))
7105 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7107 (clobber (reg:CC FLAGS_REG))])]
7109 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7111 if (<MODE>mode != HImode
7112 && (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 "*divmod<mode>4_noext"
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 (use (match_operand:SWIM248 4 "register_operand" "1"))
7131 (clobber (reg:CC FLAGS_REG))]
7133 "idiv{<imodesuffix>}\t%3"
7134 [(set_attr "type" "idiv")
7135 (set_attr "mode" "<MODE>")])
7137 (define_expand "divmodqi4"
7138 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7140 (match_operand:QI 1 "register_operand" "")
7141 (match_operand:QI 2 "nonimmediate_operand" "")))
7142 (set (match_operand:QI 3 "register_operand" "")
7143 (mod:QI (match_dup 1) (match_dup 2)))
7144 (clobber (reg:CC FLAGS_REG))])]
7145 "TARGET_QIMODE_MATH"
7150 tmp0 = gen_reg_rtx (HImode);
7151 tmp1 = gen_reg_rtx (HImode);
7153 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7155 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7156 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7158 /* Extract remainder from AH. */
7159 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7160 insn = emit_move_insn (operands[3], tmp1);
7162 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7163 set_unique_reg_note (insn, REG_EQUAL, mod);
7165 /* Extract quotient from AL. */
7166 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7168 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7169 set_unique_reg_note (insn, REG_EQUAL, div);
7174 ;; Divide AX by r/m8, with result stored in
7177 ;; Change div/mod to HImode and extend the second argument to HImode
7178 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7179 ;; combine may fail.
7180 (define_insn "divmodhiqi3"
7181 [(set (match_operand:HI 0 "register_operand" "=a")
7186 (mod:HI (match_operand:HI 1 "register_operand" "0")
7188 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7192 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7193 (clobber (reg:CC FLAGS_REG))]
7194 "TARGET_QIMODE_MATH"
7196 [(set_attr "type" "idiv")
7197 (set_attr "mode" "QI")])
7199 (define_expand "udivmod<mode>4"
7200 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7202 (match_operand:SWIM248 1 "register_operand" "")
7203 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7204 (set (match_operand:SWIM248 3 "register_operand" "")
7205 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7206 (clobber (reg:CC FLAGS_REG))])])
7208 ;; Split with 8bit unsigned divide:
7209 ;; if (dividend an divisor are in [0-255])
7210 ;; use 8bit unsigned integer divide
7212 ;; use original integer divide
7214 [(set (match_operand:SWI48 0 "register_operand" "")
7215 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7216 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7217 (set (match_operand:SWI48 1 "register_operand" "")
7218 (umod:SWI48 (match_dup 2) (match_dup 3)))
7219 (clobber (reg:CC FLAGS_REG))]
7220 "TARGET_USE_8BIT_IDIV
7221 && TARGET_QIMODE_MATH
7222 && can_create_pseudo_p ()
7223 && !optimize_insn_for_size_p ()"
7225 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7227 (define_insn_and_split "udivmod<mode>4_1"
7228 [(set (match_operand:SWI48 0 "register_operand" "=a")
7229 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7230 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7231 (set (match_operand:SWI48 1 "register_operand" "=&d")
7232 (umod:SWI48 (match_dup 2) (match_dup 3)))
7233 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7234 (clobber (reg:CC FLAGS_REG))]
7238 [(set (match_dup 1) (const_int 0))
7239 (parallel [(set (match_dup 0)
7240 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7242 (umod:SWI48 (match_dup 2) (match_dup 3)))
7244 (clobber (reg:CC FLAGS_REG))])]
7246 [(set_attr "type" "multi")
7247 (set_attr "mode" "<MODE>")])
7249 (define_insn_and_split "*udivmod<mode>4"
7250 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7251 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7252 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7253 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7254 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7255 (clobber (reg:CC FLAGS_REG))]
7259 [(set (match_dup 1) (const_int 0))
7260 (parallel [(set (match_dup 0)
7261 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7263 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7265 (clobber (reg:CC FLAGS_REG))])]
7267 [(set_attr "type" "multi")
7268 (set_attr "mode" "<MODE>")])
7270 (define_insn "*udivmod<mode>4_noext"
7271 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7272 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7273 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7274 (set (match_operand:SWIM248 1 "register_operand" "=d")
7275 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7276 (use (match_operand:SWIM248 4 "register_operand" "1"))
7277 (clobber (reg:CC FLAGS_REG))]
7279 "div{<imodesuffix>}\t%3"
7280 [(set_attr "type" "idiv")
7281 (set_attr "mode" "<MODE>")])
7283 (define_expand "udivmodqi4"
7284 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7286 (match_operand:QI 1 "register_operand" "")
7287 (match_operand:QI 2 "nonimmediate_operand" "")))
7288 (set (match_operand:QI 3 "register_operand" "")
7289 (umod:QI (match_dup 1) (match_dup 2)))
7290 (clobber (reg:CC FLAGS_REG))])]
7291 "TARGET_QIMODE_MATH"
7296 tmp0 = gen_reg_rtx (HImode);
7297 tmp1 = gen_reg_rtx (HImode);
7299 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7301 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7302 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7304 /* Extract remainder from AH. */
7305 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7306 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7307 insn = emit_move_insn (operands[3], tmp1);
7309 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7310 set_unique_reg_note (insn, REG_EQUAL, mod);
7312 /* Extract quotient from AL. */
7313 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7315 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7316 set_unique_reg_note (insn, REG_EQUAL, div);
7321 (define_insn "udivmodhiqi3"
7322 [(set (match_operand:HI 0 "register_operand" "=a")
7327 (mod:HI (match_operand:HI 1 "register_operand" "0")
7329 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7333 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7334 (clobber (reg:CC FLAGS_REG))]
7335 "TARGET_QIMODE_MATH"
7337 [(set_attr "type" "idiv")
7338 (set_attr "mode" "QI")])
7340 ;; We cannot use div/idiv for double division, because it causes
7341 ;; "division by zero" on the overflow and that's not what we expect
7342 ;; from truncate. Because true (non truncating) double division is
7343 ;; never generated, we can't create this insn anyway.
7346 ; [(set (match_operand:SI 0 "register_operand" "=a")
7348 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7350 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7351 ; (set (match_operand:SI 3 "register_operand" "=d")
7353 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7354 ; (clobber (reg:CC FLAGS_REG))]
7356 ; "div{l}\t{%2, %0|%0, %2}"
7357 ; [(set_attr "type" "idiv")])
7359 ;;- Logical AND instructions
7361 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7362 ;; Note that this excludes ah.
7364 (define_expand "testsi_ccno_1"
7365 [(set (reg:CCNO FLAGS_REG)
7367 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7368 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7371 (define_expand "testqi_ccz_1"
7372 [(set (reg:CCZ FLAGS_REG)
7373 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7374 (match_operand:QI 1 "nonmemory_operand" ""))
7377 (define_expand "testdi_ccno_1"
7378 [(set (reg:CCNO FLAGS_REG)
7380 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7381 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7383 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7385 (define_insn "*testdi_1"
7386 [(set (reg FLAGS_REG)
7389 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7390 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7392 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7393 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7395 test{l}\t{%k1, %k0|%k0, %k1}
7396 test{l}\t{%k1, %k0|%k0, %k1}
7397 test{q}\t{%1, %0|%0, %1}
7398 test{q}\t{%1, %0|%0, %1}
7399 test{q}\t{%1, %0|%0, %1}"
7400 [(set_attr "type" "test")
7401 (set_attr "modrm" "0,1,0,1,1")
7402 (set_attr "mode" "SI,SI,DI,DI,DI")])
7404 (define_insn "*testqi_1_maybe_si"
7405 [(set (reg FLAGS_REG)
7408 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7409 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7411 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7412 && ix86_match_ccmode (insn,
7413 CONST_INT_P (operands[1])
7414 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7416 if (which_alternative == 3)
7418 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7419 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7420 return "test{l}\t{%1, %k0|%k0, %1}";
7422 return "test{b}\t{%1, %0|%0, %1}";
7424 [(set_attr "type" "test")
7425 (set_attr "modrm" "0,1,1,1")
7426 (set_attr "mode" "QI,QI,QI,SI")
7427 (set_attr "pent_pair" "uv,np,uv,np")])
7429 (define_insn "*test<mode>_1"
7430 [(set (reg FLAGS_REG)
7433 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7434 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7436 "ix86_match_ccmode (insn, CCNOmode)
7437 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7438 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7439 [(set_attr "type" "test")
7440 (set_attr "modrm" "0,1,1")
7441 (set_attr "mode" "<MODE>")
7442 (set_attr "pent_pair" "uv,np,uv")])
7444 (define_expand "testqi_ext_ccno_0"
7445 [(set (reg:CCNO FLAGS_REG)
7449 (match_operand 0 "ext_register_operand" "")
7452 (match_operand 1 "const_int_operand" ""))
7455 (define_insn "*testqi_ext_0"
7456 [(set (reg FLAGS_REG)
7460 (match_operand 0 "ext_register_operand" "Q")
7463 (match_operand 1 "const_int_operand" "n"))
7465 "ix86_match_ccmode (insn, CCNOmode)"
7466 "test{b}\t{%1, %h0|%h0, %1}"
7467 [(set_attr "type" "test")
7468 (set_attr "mode" "QI")
7469 (set_attr "length_immediate" "1")
7470 (set_attr "modrm" "1")
7471 (set_attr "pent_pair" "np")])
7473 (define_insn "*testqi_ext_1_rex64"
7474 [(set (reg FLAGS_REG)
7478 (match_operand 0 "ext_register_operand" "Q")
7482 (match_operand:QI 1 "register_operand" "Q")))
7484 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7485 "test{b}\t{%1, %h0|%h0, %1}"
7486 [(set_attr "type" "test")
7487 (set_attr "mode" "QI")])
7489 (define_insn "*testqi_ext_1"
7490 [(set (reg FLAGS_REG)
7494 (match_operand 0 "ext_register_operand" "Q")
7498 (match_operand:QI 1 "general_operand" "Qm")))
7500 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7501 "test{b}\t{%1, %h0|%h0, %1}"
7502 [(set_attr "type" "test")
7503 (set_attr "mode" "QI")])
7505 (define_insn "*testqi_ext_2"
7506 [(set (reg FLAGS_REG)
7510 (match_operand 0 "ext_register_operand" "Q")
7514 (match_operand 1 "ext_register_operand" "Q")
7518 "ix86_match_ccmode (insn, CCNOmode)"
7519 "test{b}\t{%h1, %h0|%h0, %h1}"
7520 [(set_attr "type" "test")
7521 (set_attr "mode" "QI")])
7523 (define_insn "*testqi_ext_3_rex64"
7524 [(set (reg FLAGS_REG)
7525 (compare (zero_extract:DI
7526 (match_operand 0 "nonimmediate_operand" "rm")
7527 (match_operand:DI 1 "const_int_operand" "")
7528 (match_operand:DI 2 "const_int_operand" ""))
7531 && ix86_match_ccmode (insn, CCNOmode)
7532 && INTVAL (operands[1]) > 0
7533 && INTVAL (operands[2]) >= 0
7534 /* Ensure that resulting mask is zero or sign extended operand. */
7535 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7536 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7537 && INTVAL (operands[1]) > 32))
7538 && (GET_MODE (operands[0]) == SImode
7539 || GET_MODE (operands[0]) == DImode
7540 || GET_MODE (operands[0]) == HImode
7541 || GET_MODE (operands[0]) == QImode)"
7544 ;; Combine likes to form bit extractions for some tests. Humor it.
7545 (define_insn "*testqi_ext_3"
7546 [(set (reg FLAGS_REG)
7547 (compare (zero_extract:SI
7548 (match_operand 0 "nonimmediate_operand" "rm")
7549 (match_operand:SI 1 "const_int_operand" "")
7550 (match_operand:SI 2 "const_int_operand" ""))
7552 "ix86_match_ccmode (insn, CCNOmode)
7553 && INTVAL (operands[1]) > 0
7554 && INTVAL (operands[2]) >= 0
7555 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7556 && (GET_MODE (operands[0]) == SImode
7557 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7558 || GET_MODE (operands[0]) == HImode
7559 || GET_MODE (operands[0]) == QImode)"
7563 [(set (match_operand 0 "flags_reg_operand" "")
7564 (match_operator 1 "compare_operator"
7566 (match_operand 2 "nonimmediate_operand" "")
7567 (match_operand 3 "const_int_operand" "")
7568 (match_operand 4 "const_int_operand" ""))
7570 "ix86_match_ccmode (insn, CCNOmode)"
7571 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7573 rtx val = operands[2];
7574 HOST_WIDE_INT len = INTVAL (operands[3]);
7575 HOST_WIDE_INT pos = INTVAL (operands[4]);
7577 enum machine_mode mode, submode;
7579 mode = GET_MODE (val);
7582 /* ??? Combine likes to put non-volatile mem extractions in QImode
7583 no matter the size of the test. So find a mode that works. */
7584 if (! MEM_VOLATILE_P (val))
7586 mode = smallest_mode_for_size (pos + len, MODE_INT);
7587 val = adjust_address (val, mode, 0);
7590 else if (GET_CODE (val) == SUBREG
7591 && (submode = GET_MODE (SUBREG_REG (val)),
7592 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7593 && pos + len <= GET_MODE_BITSIZE (submode)
7594 && GET_MODE_CLASS (submode) == MODE_INT)
7596 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7598 val = SUBREG_REG (val);
7600 else if (mode == HImode && pos + len <= 8)
7602 /* Small HImode tests can be converted to QImode. */
7604 val = gen_lowpart (QImode, val);
7607 if (len == HOST_BITS_PER_WIDE_INT)
7610 mask = ((HOST_WIDE_INT)1 << len) - 1;
7613 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7616 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7617 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7618 ;; this is relatively important trick.
7619 ;; Do the conversion only post-reload to avoid limiting of the register class
7622 [(set (match_operand 0 "flags_reg_operand" "")
7623 (match_operator 1 "compare_operator"
7624 [(and (match_operand 2 "register_operand" "")
7625 (match_operand 3 "const_int_operand" ""))
7628 && QI_REG_P (operands[2])
7629 && GET_MODE (operands[2]) != QImode
7630 && ((ix86_match_ccmode (insn, CCZmode)
7631 && !(INTVAL (operands[3]) & ~(255 << 8)))
7632 || (ix86_match_ccmode (insn, CCNOmode)
7633 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7636 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7640 operands[2] = gen_lowpart (SImode, operands[2]);
7641 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7645 [(set (match_operand 0 "flags_reg_operand" "")
7646 (match_operator 1 "compare_operator"
7647 [(and (match_operand 2 "nonimmediate_operand" "")
7648 (match_operand 3 "const_int_operand" ""))
7651 && GET_MODE (operands[2]) != QImode
7652 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7653 && ((ix86_match_ccmode (insn, CCZmode)
7654 && !(INTVAL (operands[3]) & ~255))
7655 || (ix86_match_ccmode (insn, CCNOmode)
7656 && !(INTVAL (operands[3]) & ~127)))"
7658 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7661 operands[2] = gen_lowpart (QImode, operands[2]);
7662 operands[3] = gen_lowpart (QImode, operands[3]);
7665 ;; %%% This used to optimize known byte-wide and operations to memory,
7666 ;; and sometimes to QImode registers. If this is considered useful,
7667 ;; it should be done with splitters.
7669 (define_expand "and<mode>3"
7670 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7671 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7672 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7675 if (<MODE>mode == DImode
7676 && GET_CODE (operands[2]) == CONST_INT
7677 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7678 && REG_P (operands[1]))
7679 emit_insn (gen_zero_extendsidi2 (operands[0],
7680 gen_lowpart (SImode, operands[1])));
7682 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7686 (define_insn "*anddi_1"
7687 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7689 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7690 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7691 (clobber (reg:CC FLAGS_REG))]
7692 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7694 switch (get_attr_type (insn))
7698 enum machine_mode mode;
7700 gcc_assert (CONST_INT_P (operands[2]));
7701 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7703 else if (INTVAL (operands[2]) == 0xffff)
7707 gcc_assert (INTVAL (operands[2]) == 0xff);
7711 operands[1] = gen_lowpart (mode, operands[1]);
7713 return "mov{l}\t{%1, %k0|%k0, %1}";
7714 else if (mode == HImode)
7715 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7717 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7721 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7722 if (get_attr_mode (insn) == MODE_SI)
7723 return "and{l}\t{%k2, %k0|%k0, %k2}";
7725 return "and{q}\t{%2, %0|%0, %2}";
7728 [(set_attr "type" "alu,alu,alu,imovx")
7729 (set_attr "length_immediate" "*,*,*,0")
7730 (set (attr "prefix_rex")
7732 (and (eq_attr "type" "imovx")
7733 (and (match_test "INTVAL (operands[2]) == 0xff")
7734 (match_operand 1 "ext_QIreg_operand" "")))
7736 (const_string "*")))
7737 (set_attr "mode" "SI,DI,DI,SI")])
7739 (define_insn "*andsi_1"
7740 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7741 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7742 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7743 (clobber (reg:CC FLAGS_REG))]
7744 "ix86_binary_operator_ok (AND, SImode, operands)"
7746 switch (get_attr_type (insn))
7750 enum machine_mode mode;
7752 gcc_assert (CONST_INT_P (operands[2]));
7753 if (INTVAL (operands[2]) == 0xffff)
7757 gcc_assert (INTVAL (operands[2]) == 0xff);
7761 operands[1] = gen_lowpart (mode, operands[1]);
7763 return "movz{wl|x}\t{%1, %0|%0, %1}";
7765 return "movz{bl|x}\t{%1, %0|%0, %1}";
7769 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7770 return "and{l}\t{%2, %0|%0, %2}";
7773 [(set_attr "type" "alu,alu,imovx")
7774 (set (attr "prefix_rex")
7776 (and (eq_attr "type" "imovx")
7777 (and (match_test "INTVAL (operands[2]) == 0xff")
7778 (match_operand 1 "ext_QIreg_operand" "")))
7780 (const_string "*")))
7781 (set_attr "length_immediate" "*,*,0")
7782 (set_attr "mode" "SI")])
7784 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7785 (define_insn "*andsi_1_zext"
7786 [(set (match_operand:DI 0 "register_operand" "=r")
7788 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7789 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7790 (clobber (reg:CC FLAGS_REG))]
7791 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7792 "and{l}\t{%2, %k0|%k0, %2}"
7793 [(set_attr "type" "alu")
7794 (set_attr "mode" "SI")])
7796 (define_insn "*andhi_1"
7797 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7798 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7799 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7800 (clobber (reg:CC FLAGS_REG))]
7801 "ix86_binary_operator_ok (AND, HImode, operands)"
7803 switch (get_attr_type (insn))
7806 gcc_assert (CONST_INT_P (operands[2]));
7807 gcc_assert (INTVAL (operands[2]) == 0xff);
7808 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7811 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7813 return "and{w}\t{%2, %0|%0, %2}";
7816 [(set_attr "type" "alu,alu,imovx")
7817 (set_attr "length_immediate" "*,*,0")
7818 (set (attr "prefix_rex")
7820 (and (eq_attr "type" "imovx")
7821 (match_operand 1 "ext_QIreg_operand" ""))
7823 (const_string "*")))
7824 (set_attr "mode" "HI,HI,SI")])
7826 ;; %%% Potential partial reg stall on alternative 2. What to do?
7827 (define_insn "*andqi_1"
7828 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7829 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7830 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7831 (clobber (reg:CC FLAGS_REG))]
7832 "ix86_binary_operator_ok (AND, QImode, operands)"
7834 and{b}\t{%2, %0|%0, %2}
7835 and{b}\t{%2, %0|%0, %2}
7836 and{l}\t{%k2, %k0|%k0, %k2}"
7837 [(set_attr "type" "alu")
7838 (set_attr "mode" "QI,QI,SI")])
7840 (define_insn "*andqi_1_slp"
7841 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7842 (and:QI (match_dup 0)
7843 (match_operand:QI 1 "general_operand" "qn,qmn")))
7844 (clobber (reg:CC FLAGS_REG))]
7845 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7846 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7847 "and{b}\t{%1, %0|%0, %1}"
7848 [(set_attr "type" "alu1")
7849 (set_attr "mode" "QI")])
7852 [(set (match_operand 0 "register_operand" "")
7854 (const_int -65536)))
7855 (clobber (reg:CC FLAGS_REG))]
7856 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7857 || optimize_function_for_size_p (cfun)"
7858 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7859 "operands[1] = gen_lowpart (HImode, operands[0]);")
7862 [(set (match_operand 0 "ext_register_operand" "")
7865 (clobber (reg:CC FLAGS_REG))]
7866 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7867 && reload_completed"
7868 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7869 "operands[1] = gen_lowpart (QImode, operands[0]);")
7872 [(set (match_operand 0 "ext_register_operand" "")
7874 (const_int -65281)))
7875 (clobber (reg:CC FLAGS_REG))]
7876 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7877 && reload_completed"
7878 [(parallel [(set (zero_extract:SI (match_dup 0)
7882 (zero_extract:SI (match_dup 0)
7885 (zero_extract:SI (match_dup 0)
7888 (clobber (reg:CC FLAGS_REG))])]
7889 "operands[0] = gen_lowpart (SImode, operands[0]);")
7891 (define_insn "*anddi_2"
7892 [(set (reg FLAGS_REG)
7895 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7896 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7898 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7899 (and:DI (match_dup 1) (match_dup 2)))]
7900 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7901 && ix86_binary_operator_ok (AND, DImode, operands)"
7903 and{l}\t{%k2, %k0|%k0, %k2}
7904 and{q}\t{%2, %0|%0, %2}
7905 and{q}\t{%2, %0|%0, %2}"
7906 [(set_attr "type" "alu")
7907 (set_attr "mode" "SI,DI,DI")])
7909 (define_insn "*andqi_2_maybe_si"
7910 [(set (reg FLAGS_REG)
7912 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7913 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7915 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7916 (and:QI (match_dup 1) (match_dup 2)))]
7917 "ix86_binary_operator_ok (AND, QImode, operands)
7918 && ix86_match_ccmode (insn,
7919 CONST_INT_P (operands[2])
7920 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7922 if (which_alternative == 2)
7924 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7925 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7926 return "and{l}\t{%2, %k0|%k0, %2}";
7928 return "and{b}\t{%2, %0|%0, %2}";
7930 [(set_attr "type" "alu")
7931 (set_attr "mode" "QI,QI,SI")])
7933 (define_insn "*and<mode>_2"
7934 [(set (reg FLAGS_REG)
7935 (compare (and:SWI124
7936 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7937 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7939 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7940 (and:SWI124 (match_dup 1) (match_dup 2)))]
7941 "ix86_match_ccmode (insn, CCNOmode)
7942 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7943 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7944 [(set_attr "type" "alu")
7945 (set_attr "mode" "<MODE>")])
7947 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7948 (define_insn "*andsi_2_zext"
7949 [(set (reg FLAGS_REG)
7951 (match_operand:SI 1 "nonimmediate_operand" "%0")
7952 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7954 (set (match_operand:DI 0 "register_operand" "=r")
7955 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7956 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7957 && ix86_binary_operator_ok (AND, SImode, operands)"
7958 "and{l}\t{%2, %k0|%k0, %2}"
7959 [(set_attr "type" "alu")
7960 (set_attr "mode" "SI")])
7962 (define_insn "*andqi_2_slp"
7963 [(set (reg FLAGS_REG)
7965 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7966 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7968 (set (strict_low_part (match_dup 0))
7969 (and:QI (match_dup 0) (match_dup 1)))]
7970 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7971 && ix86_match_ccmode (insn, CCNOmode)
7972 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7973 "and{b}\t{%1, %0|%0, %1}"
7974 [(set_attr "type" "alu1")
7975 (set_attr "mode" "QI")])
7977 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7978 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7979 ;; for a QImode operand, which of course failed.
7980 (define_insn "andqi_ext_0"
7981 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7986 (match_operand 1 "ext_register_operand" "0")
7989 (match_operand 2 "const_int_operand" "n")))
7990 (clobber (reg:CC FLAGS_REG))]
7992 "and{b}\t{%2, %h0|%h0, %2}"
7993 [(set_attr "type" "alu")
7994 (set_attr "length_immediate" "1")
7995 (set_attr "modrm" "1")
7996 (set_attr "mode" "QI")])
7998 ;; Generated by peephole translating test to and. This shows up
7999 ;; often in fp comparisons.
8000 (define_insn "*andqi_ext_0_cc"
8001 [(set (reg FLAGS_REG)
8005 (match_operand 1 "ext_register_operand" "0")
8008 (match_operand 2 "const_int_operand" "n"))
8010 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8019 "ix86_match_ccmode (insn, CCNOmode)"
8020 "and{b}\t{%2, %h0|%h0, %2}"
8021 [(set_attr "type" "alu")
8022 (set_attr "length_immediate" "1")
8023 (set_attr "modrm" "1")
8024 (set_attr "mode" "QI")])
8026 (define_insn "*andqi_ext_1_rex64"
8027 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8032 (match_operand 1 "ext_register_operand" "0")
8036 (match_operand 2 "ext_register_operand" "Q"))))
8037 (clobber (reg:CC FLAGS_REG))]
8039 "and{b}\t{%2, %h0|%h0, %2}"
8040 [(set_attr "type" "alu")
8041 (set_attr "length_immediate" "0")
8042 (set_attr "mode" "QI")])
8044 (define_insn "*andqi_ext_1"
8045 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8050 (match_operand 1 "ext_register_operand" "0")
8054 (match_operand:QI 2 "general_operand" "Qm"))))
8055 (clobber (reg:CC FLAGS_REG))]
8057 "and{b}\t{%2, %h0|%h0, %2}"
8058 [(set_attr "type" "alu")
8059 (set_attr "length_immediate" "0")
8060 (set_attr "mode" "QI")])
8062 (define_insn "*andqi_ext_2"
8063 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8068 (match_operand 1 "ext_register_operand" "%0")
8072 (match_operand 2 "ext_register_operand" "Q")
8075 (clobber (reg:CC FLAGS_REG))]
8077 "and{b}\t{%h2, %h0|%h0, %h2}"
8078 [(set_attr "type" "alu")
8079 (set_attr "length_immediate" "0")
8080 (set_attr "mode" "QI")])
8082 ;; Convert wide AND instructions with immediate operand to shorter QImode
8083 ;; equivalents when possible.
8084 ;; Don't do the splitting with memory operands, since it introduces risk
8085 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8086 ;; for size, but that can (should?) be handled by generic code instead.
8088 [(set (match_operand 0 "register_operand" "")
8089 (and (match_operand 1 "register_operand" "")
8090 (match_operand 2 "const_int_operand" "")))
8091 (clobber (reg:CC FLAGS_REG))]
8093 && QI_REG_P (operands[0])
8094 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8095 && !(~INTVAL (operands[2]) & ~(255 << 8))
8096 && GET_MODE (operands[0]) != QImode"
8097 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8098 (and:SI (zero_extract:SI (match_dup 1)
8099 (const_int 8) (const_int 8))
8101 (clobber (reg:CC FLAGS_REG))])]
8103 operands[0] = gen_lowpart (SImode, operands[0]);
8104 operands[1] = gen_lowpart (SImode, operands[1]);
8105 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8108 ;; Since AND can be encoded with sign extended immediate, this is only
8109 ;; profitable when 7th bit is not set.
8111 [(set (match_operand 0 "register_operand" "")
8112 (and (match_operand 1 "general_operand" "")
8113 (match_operand 2 "const_int_operand" "")))
8114 (clobber (reg:CC FLAGS_REG))]
8116 && ANY_QI_REG_P (operands[0])
8117 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8118 && !(~INTVAL (operands[2]) & ~255)
8119 && !(INTVAL (operands[2]) & 128)
8120 && GET_MODE (operands[0]) != QImode"
8121 [(parallel [(set (strict_low_part (match_dup 0))
8122 (and:QI (match_dup 1)
8124 (clobber (reg:CC FLAGS_REG))])]
8126 operands[0] = gen_lowpart (QImode, operands[0]);
8127 operands[1] = gen_lowpart (QImode, operands[1]);
8128 operands[2] = gen_lowpart (QImode, operands[2]);
8131 ;; Logical inclusive and exclusive OR instructions
8133 ;; %%% This used to optimize known byte-wide and operations to memory.
8134 ;; If this is considered useful, it should be done with splitters.
8136 (define_expand "<code><mode>3"
8137 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8138 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8139 (match_operand:SWIM 2 "<general_operand>" "")))]
8141 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8143 (define_insn "*<code><mode>_1"
8144 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8146 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8147 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8148 (clobber (reg:CC FLAGS_REG))]
8149 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8150 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8151 [(set_attr "type" "alu")
8152 (set_attr "mode" "<MODE>")])
8154 ;; %%% Potential partial reg stall on alternative 2. What to do?
8155 (define_insn "*<code>qi_1"
8156 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8157 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8158 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8159 (clobber (reg:CC FLAGS_REG))]
8160 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8162 <logic>{b}\t{%2, %0|%0, %2}
8163 <logic>{b}\t{%2, %0|%0, %2}
8164 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8165 [(set_attr "type" "alu")
8166 (set_attr "mode" "QI,QI,SI")])
8168 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8169 (define_insn "*<code>si_1_zext"
8170 [(set (match_operand:DI 0 "register_operand" "=r")
8172 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8173 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8174 (clobber (reg:CC FLAGS_REG))]
8175 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8176 "<logic>{l}\t{%2, %k0|%k0, %2}"
8177 [(set_attr "type" "alu")
8178 (set_attr "mode" "SI")])
8180 (define_insn "*<code>si_1_zext_imm"
8181 [(set (match_operand:DI 0 "register_operand" "=r")
8183 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8184 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8185 (clobber (reg:CC FLAGS_REG))]
8186 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8187 "<logic>{l}\t{%2, %k0|%k0, %2}"
8188 [(set_attr "type" "alu")
8189 (set_attr "mode" "SI")])
8191 (define_insn "*<code>qi_1_slp"
8192 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8193 (any_or:QI (match_dup 0)
8194 (match_operand:QI 1 "general_operand" "qmn,qn")))
8195 (clobber (reg:CC FLAGS_REG))]
8196 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8197 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8198 "<logic>{b}\t{%1, %0|%0, %1}"
8199 [(set_attr "type" "alu1")
8200 (set_attr "mode" "QI")])
8202 (define_insn "*<code><mode>_2"
8203 [(set (reg FLAGS_REG)
8204 (compare (any_or:SWI
8205 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8206 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8208 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8209 (any_or:SWI (match_dup 1) (match_dup 2)))]
8210 "ix86_match_ccmode (insn, CCNOmode)
8211 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8212 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8213 [(set_attr "type" "alu")
8214 (set_attr "mode" "<MODE>")])
8216 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8217 ;; ??? Special case for immediate operand is missing - it is tricky.
8218 (define_insn "*<code>si_2_zext"
8219 [(set (reg FLAGS_REG)
8220 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8221 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8223 (set (match_operand:DI 0 "register_operand" "=r")
8224 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8225 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8226 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8227 "<logic>{l}\t{%2, %k0|%k0, %2}"
8228 [(set_attr "type" "alu")
8229 (set_attr "mode" "SI")])
8231 (define_insn "*<code>si_2_zext_imm"
8232 [(set (reg FLAGS_REG)
8234 (match_operand:SI 1 "nonimmediate_operand" "%0")
8235 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8237 (set (match_operand:DI 0 "register_operand" "=r")
8238 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8239 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8240 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8241 "<logic>{l}\t{%2, %k0|%k0, %2}"
8242 [(set_attr "type" "alu")
8243 (set_attr "mode" "SI")])
8245 (define_insn "*<code>qi_2_slp"
8246 [(set (reg FLAGS_REG)
8247 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8248 (match_operand:QI 1 "general_operand" "qmn,qn"))
8250 (set (strict_low_part (match_dup 0))
8251 (any_or:QI (match_dup 0) (match_dup 1)))]
8252 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8253 && ix86_match_ccmode (insn, CCNOmode)
8254 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8255 "<logic>{b}\t{%1, %0|%0, %1}"
8256 [(set_attr "type" "alu1")
8257 (set_attr "mode" "QI")])
8259 (define_insn "*<code><mode>_3"
8260 [(set (reg FLAGS_REG)
8261 (compare (any_or:SWI
8262 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8263 (match_operand:SWI 2 "<general_operand>" "<g>"))
8265 (clobber (match_scratch:SWI 0 "=<r>"))]
8266 "ix86_match_ccmode (insn, CCNOmode)
8267 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8268 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8269 [(set_attr "type" "alu")
8270 (set_attr "mode" "<MODE>")])
8272 (define_insn "*<code>qi_ext_0"
8273 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8278 (match_operand 1 "ext_register_operand" "0")
8281 (match_operand 2 "const_int_operand" "n")))
8282 (clobber (reg:CC FLAGS_REG))]
8283 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8284 "<logic>{b}\t{%2, %h0|%h0, %2}"
8285 [(set_attr "type" "alu")
8286 (set_attr "length_immediate" "1")
8287 (set_attr "modrm" "1")
8288 (set_attr "mode" "QI")])
8290 (define_insn "*<code>qi_ext_1_rex64"
8291 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8296 (match_operand 1 "ext_register_operand" "0")
8300 (match_operand 2 "ext_register_operand" "Q"))))
8301 (clobber (reg:CC FLAGS_REG))]
8303 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8304 "<logic>{b}\t{%2, %h0|%h0, %2}"
8305 [(set_attr "type" "alu")
8306 (set_attr "length_immediate" "0")
8307 (set_attr "mode" "QI")])
8309 (define_insn "*<code>qi_ext_1"
8310 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8315 (match_operand 1 "ext_register_operand" "0")
8319 (match_operand:QI 2 "general_operand" "Qm"))))
8320 (clobber (reg:CC FLAGS_REG))]
8322 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8323 "<logic>{b}\t{%2, %h0|%h0, %2}"
8324 [(set_attr "type" "alu")
8325 (set_attr "length_immediate" "0")
8326 (set_attr "mode" "QI")])
8328 (define_insn "*<code>qi_ext_2"
8329 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8333 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8336 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8339 (clobber (reg:CC FLAGS_REG))]
8340 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8341 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8342 [(set_attr "type" "alu")
8343 (set_attr "length_immediate" "0")
8344 (set_attr "mode" "QI")])
8347 [(set (match_operand 0 "register_operand" "")
8348 (any_or (match_operand 1 "register_operand" "")
8349 (match_operand 2 "const_int_operand" "")))
8350 (clobber (reg:CC FLAGS_REG))]
8352 && QI_REG_P (operands[0])
8353 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8354 && !(INTVAL (operands[2]) & ~(255 << 8))
8355 && GET_MODE (operands[0]) != QImode"
8356 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8357 (any_or:SI (zero_extract:SI (match_dup 1)
8358 (const_int 8) (const_int 8))
8360 (clobber (reg:CC FLAGS_REG))])]
8362 operands[0] = gen_lowpart (SImode, operands[0]);
8363 operands[1] = gen_lowpart (SImode, operands[1]);
8364 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8367 ;; Since OR can be encoded with sign extended immediate, this is only
8368 ;; profitable when 7th bit is set.
8370 [(set (match_operand 0 "register_operand" "")
8371 (any_or (match_operand 1 "general_operand" "")
8372 (match_operand 2 "const_int_operand" "")))
8373 (clobber (reg:CC FLAGS_REG))]
8375 && ANY_QI_REG_P (operands[0])
8376 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8377 && !(INTVAL (operands[2]) & ~255)
8378 && (INTVAL (operands[2]) & 128)
8379 && GET_MODE (operands[0]) != QImode"
8380 [(parallel [(set (strict_low_part (match_dup 0))
8381 (any_or:QI (match_dup 1)
8383 (clobber (reg:CC FLAGS_REG))])]
8385 operands[0] = gen_lowpart (QImode, operands[0]);
8386 operands[1] = gen_lowpart (QImode, operands[1]);
8387 operands[2] = gen_lowpart (QImode, operands[2]);
8390 (define_expand "xorqi_cc_ext_1"
8392 (set (reg:CCNO FLAGS_REG)
8396 (match_operand 1 "ext_register_operand" "")
8399 (match_operand:QI 2 "general_operand" ""))
8401 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8411 (define_insn "*xorqi_cc_ext_1_rex64"
8412 [(set (reg FLAGS_REG)
8416 (match_operand 1 "ext_register_operand" "0")
8419 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8421 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8430 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8431 "xor{b}\t{%2, %h0|%h0, %2}"
8432 [(set_attr "type" "alu")
8433 (set_attr "modrm" "1")
8434 (set_attr "mode" "QI")])
8436 (define_insn "*xorqi_cc_ext_1"
8437 [(set (reg FLAGS_REG)
8441 (match_operand 1 "ext_register_operand" "0")
8444 (match_operand:QI 2 "general_operand" "qmn"))
8446 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8455 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8456 "xor{b}\t{%2, %h0|%h0, %2}"
8457 [(set_attr "type" "alu")
8458 (set_attr "modrm" "1")
8459 (set_attr "mode" "QI")])
8461 ;; Negation instructions
8463 (define_expand "neg<mode>2"
8464 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8465 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8467 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8469 (define_insn_and_split "*neg<dwi>2_doubleword"
8470 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8471 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8472 (clobber (reg:CC FLAGS_REG))]
8473 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8477 [(set (reg:CCZ FLAGS_REG)
8478 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8479 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8482 (plus:DWIH (match_dup 3)
8483 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8485 (clobber (reg:CC FLAGS_REG))])
8488 (neg:DWIH (match_dup 2)))
8489 (clobber (reg:CC FLAGS_REG))])]
8490 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8492 (define_insn "*neg<mode>2_1"
8493 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8494 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8495 (clobber (reg:CC FLAGS_REG))]
8496 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8497 "neg{<imodesuffix>}\t%0"
8498 [(set_attr "type" "negnot")
8499 (set_attr "mode" "<MODE>")])
8501 ;; Combine is quite creative about this pattern.
8502 (define_insn "*negsi2_1_zext"
8503 [(set (match_operand:DI 0 "register_operand" "=r")
8505 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8508 (clobber (reg:CC FLAGS_REG))]
8509 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8511 [(set_attr "type" "negnot")
8512 (set_attr "mode" "SI")])
8514 ;; The problem with neg is that it does not perform (compare x 0),
8515 ;; it really performs (compare 0 x), which leaves us with the zero
8516 ;; flag being the only useful item.
8518 (define_insn "*neg<mode>2_cmpz"
8519 [(set (reg:CCZ FLAGS_REG)
8521 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8523 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8524 (neg:SWI (match_dup 1)))]
8525 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8526 "neg{<imodesuffix>}\t%0"
8527 [(set_attr "type" "negnot")
8528 (set_attr "mode" "<MODE>")])
8530 (define_insn "*negsi2_cmpz_zext"
8531 [(set (reg:CCZ FLAGS_REG)
8535 (match_operand:DI 1 "register_operand" "0")
8539 (set (match_operand:DI 0 "register_operand" "=r")
8540 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8543 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8545 [(set_attr "type" "negnot")
8546 (set_attr "mode" "SI")])
8548 ;; Changing of sign for FP values is doable using integer unit too.
8550 (define_expand "<code><mode>2"
8551 [(set (match_operand:X87MODEF 0 "register_operand" "")
8552 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8553 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8554 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8556 (define_insn "*absneg<mode>2_mixed"
8557 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8558 (match_operator:MODEF 3 "absneg_operator"
8559 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8560 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8561 (clobber (reg:CC FLAGS_REG))]
8562 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8565 (define_insn "*absneg<mode>2_sse"
8566 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8567 (match_operator:MODEF 3 "absneg_operator"
8568 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8569 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8570 (clobber (reg:CC FLAGS_REG))]
8571 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8574 (define_insn "*absneg<mode>2_i387"
8575 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8576 (match_operator:X87MODEF 3 "absneg_operator"
8577 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8578 (use (match_operand 2 "" ""))
8579 (clobber (reg:CC FLAGS_REG))]
8580 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8583 (define_expand "<code>tf2"
8584 [(set (match_operand:TF 0 "register_operand" "")
8585 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8587 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8589 (define_insn "*absnegtf2_sse"
8590 [(set (match_operand:TF 0 "register_operand" "=x,x")
8591 (match_operator:TF 3 "absneg_operator"
8592 [(match_operand:TF 1 "register_operand" "0,x")]))
8593 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8594 (clobber (reg:CC FLAGS_REG))]
8598 ;; Splitters for fp abs and neg.
8601 [(set (match_operand 0 "fp_register_operand" "")
8602 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8603 (use (match_operand 2 "" ""))
8604 (clobber (reg:CC FLAGS_REG))]
8606 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8609 [(set (match_operand 0 "register_operand" "")
8610 (match_operator 3 "absneg_operator"
8611 [(match_operand 1 "register_operand" "")]))
8612 (use (match_operand 2 "nonimmediate_operand" ""))
8613 (clobber (reg:CC FLAGS_REG))]
8614 "reload_completed && SSE_REG_P (operands[0])"
8615 [(set (match_dup 0) (match_dup 3))]
8617 enum machine_mode mode = GET_MODE (operands[0]);
8618 enum machine_mode vmode = GET_MODE (operands[2]);
8621 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8622 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8623 if (operands_match_p (operands[0], operands[2]))
8626 operands[1] = operands[2];
8629 if (GET_CODE (operands[3]) == ABS)
8630 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8632 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8637 [(set (match_operand:SF 0 "register_operand" "")
8638 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8639 (use (match_operand:V4SF 2 "" ""))
8640 (clobber (reg:CC FLAGS_REG))]
8642 [(parallel [(set (match_dup 0) (match_dup 1))
8643 (clobber (reg:CC FLAGS_REG))])]
8646 operands[0] = gen_lowpart (SImode, operands[0]);
8647 if (GET_CODE (operands[1]) == ABS)
8649 tmp = gen_int_mode (0x7fffffff, SImode);
8650 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8654 tmp = gen_int_mode (0x80000000, SImode);
8655 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8661 [(set (match_operand:DF 0 "register_operand" "")
8662 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8663 (use (match_operand 2 "" ""))
8664 (clobber (reg:CC FLAGS_REG))]
8666 [(parallel [(set (match_dup 0) (match_dup 1))
8667 (clobber (reg:CC FLAGS_REG))])]
8672 tmp = gen_lowpart (DImode, operands[0]);
8673 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8676 if (GET_CODE (operands[1]) == ABS)
8679 tmp = gen_rtx_NOT (DImode, tmp);
8683 operands[0] = gen_highpart (SImode, operands[0]);
8684 if (GET_CODE (operands[1]) == ABS)
8686 tmp = gen_int_mode (0x7fffffff, SImode);
8687 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8691 tmp = gen_int_mode (0x80000000, SImode);
8692 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8699 [(set (match_operand:XF 0 "register_operand" "")
8700 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8701 (use (match_operand 2 "" ""))
8702 (clobber (reg:CC FLAGS_REG))]
8704 [(parallel [(set (match_dup 0) (match_dup 1))
8705 (clobber (reg:CC FLAGS_REG))])]
8708 operands[0] = gen_rtx_REG (SImode,
8709 true_regnum (operands[0])
8710 + (TARGET_64BIT ? 1 : 2));
8711 if (GET_CODE (operands[1]) == ABS)
8713 tmp = GEN_INT (0x7fff);
8714 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8718 tmp = GEN_INT (0x8000);
8719 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8724 ;; Conditionalize these after reload. If they match before reload, we
8725 ;; lose the clobber and ability to use integer instructions.
8727 (define_insn "*<code><mode>2_1"
8728 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8729 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8731 && (reload_completed
8732 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8733 "f<absneg_mnemonic>"
8734 [(set_attr "type" "fsgn")
8735 (set_attr "mode" "<MODE>")])
8737 (define_insn "*<code>extendsfdf2"
8738 [(set (match_operand:DF 0 "register_operand" "=f")
8739 (absneg:DF (float_extend:DF
8740 (match_operand:SF 1 "register_operand" "0"))))]
8741 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8742 "f<absneg_mnemonic>"
8743 [(set_attr "type" "fsgn")
8744 (set_attr "mode" "DF")])
8746 (define_insn "*<code>extendsfxf2"
8747 [(set (match_operand:XF 0 "register_operand" "=f")
8748 (absneg:XF (float_extend:XF
8749 (match_operand:SF 1 "register_operand" "0"))))]
8751 "f<absneg_mnemonic>"
8752 [(set_attr "type" "fsgn")
8753 (set_attr "mode" "XF")])
8755 (define_insn "*<code>extenddfxf2"
8756 [(set (match_operand:XF 0 "register_operand" "=f")
8757 (absneg:XF (float_extend:XF
8758 (match_operand:DF 1 "register_operand" "0"))))]
8760 "f<absneg_mnemonic>"
8761 [(set_attr "type" "fsgn")
8762 (set_attr "mode" "XF")])
8764 ;; Copysign instructions
8766 (define_mode_iterator CSGNMODE [SF DF TF])
8767 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8769 (define_expand "copysign<mode>3"
8770 [(match_operand:CSGNMODE 0 "register_operand" "")
8771 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8772 (match_operand:CSGNMODE 2 "register_operand" "")]
8773 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8774 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8775 "ix86_expand_copysign (operands); DONE;")
8777 (define_insn_and_split "copysign<mode>3_const"
8778 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8780 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8781 (match_operand:CSGNMODE 2 "register_operand" "0")
8782 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8784 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8785 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8787 "&& reload_completed"
8789 "ix86_split_copysign_const (operands); DONE;")
8791 (define_insn "copysign<mode>3_var"
8792 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8794 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8795 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8796 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8797 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8799 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8800 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8801 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8805 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8807 [(match_operand:CSGNMODE 2 "register_operand" "")
8808 (match_operand:CSGNMODE 3 "register_operand" "")
8809 (match_operand:<CSGNVMODE> 4 "" "")
8810 (match_operand:<CSGNVMODE> 5 "" "")]
8812 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8813 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8814 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8815 && reload_completed"
8817 "ix86_split_copysign_var (operands); DONE;")
8819 ;; One complement instructions
8821 (define_expand "one_cmpl<mode>2"
8822 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8823 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8825 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8827 (define_insn "*one_cmpl<mode>2_1"
8828 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8829 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8830 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8831 "not{<imodesuffix>}\t%0"
8832 [(set_attr "type" "negnot")
8833 (set_attr "mode" "<MODE>")])
8835 ;; %%% Potential partial reg stall on alternative 1. What to do?
8836 (define_insn "*one_cmplqi2_1"
8837 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8838 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8839 "ix86_unary_operator_ok (NOT, QImode, operands)"
8843 [(set_attr "type" "negnot")
8844 (set_attr "mode" "QI,SI")])
8846 ;; ??? Currently never generated - xor is used instead.
8847 (define_insn "*one_cmplsi2_1_zext"
8848 [(set (match_operand:DI 0 "register_operand" "=r")
8850 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8851 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8853 [(set_attr "type" "negnot")
8854 (set_attr "mode" "SI")])
8856 (define_insn "*one_cmpl<mode>2_2"
8857 [(set (reg FLAGS_REG)
8858 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8860 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8861 (not:SWI (match_dup 1)))]
8862 "ix86_match_ccmode (insn, CCNOmode)
8863 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8865 [(set_attr "type" "alu1")
8866 (set_attr "mode" "<MODE>")])
8869 [(set (match_operand 0 "flags_reg_operand" "")
8870 (match_operator 2 "compare_operator"
8871 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8873 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8874 (not:SWI (match_dup 3)))]
8875 "ix86_match_ccmode (insn, CCNOmode)"
8876 [(parallel [(set (match_dup 0)
8877 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8880 (xor:SWI (match_dup 3) (const_int -1)))])])
8882 ;; ??? Currently never generated - xor is used instead.
8883 (define_insn "*one_cmplsi2_2_zext"
8884 [(set (reg FLAGS_REG)
8885 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8887 (set (match_operand:DI 0 "register_operand" "=r")
8888 (zero_extend:DI (not:SI (match_dup 1))))]
8889 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8890 && ix86_unary_operator_ok (NOT, SImode, operands)"
8892 [(set_attr "type" "alu1")
8893 (set_attr "mode" "SI")])
8896 [(set (match_operand 0 "flags_reg_operand" "")
8897 (match_operator 2 "compare_operator"
8898 [(not:SI (match_operand:SI 3 "register_operand" ""))
8900 (set (match_operand:DI 1 "register_operand" "")
8901 (zero_extend:DI (not:SI (match_dup 3))))]
8902 "ix86_match_ccmode (insn, CCNOmode)"
8903 [(parallel [(set (match_dup 0)
8904 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8907 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8909 ;; Shift instructions
8911 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8912 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8913 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8914 ;; from the assembler input.
8916 ;; This instruction shifts the target reg/mem as usual, but instead of
8917 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8918 ;; is a left shift double, bits are taken from the high order bits of
8919 ;; reg, else if the insn is a shift right double, bits are taken from the
8920 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8921 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8923 ;; Since sh[lr]d does not change the `reg' operand, that is done
8924 ;; separately, making all shifts emit pairs of shift double and normal
8925 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8926 ;; support a 63 bit shift, each shift where the count is in a reg expands
8927 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8929 ;; If the shift count is a constant, we need never emit more than one
8930 ;; shift pair, instead using moves and sign extension for counts greater
8933 (define_expand "ashl<mode>3"
8934 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8935 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8936 (match_operand:QI 2 "nonmemory_operand" "")))]
8938 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8940 (define_insn "*ashl<mode>3_doubleword"
8941 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8942 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8943 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8944 (clobber (reg:CC FLAGS_REG))]
8947 [(set_attr "type" "multi")])
8950 [(set (match_operand:DWI 0 "register_operand" "")
8951 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8952 (match_operand:QI 2 "nonmemory_operand" "")))
8953 (clobber (reg:CC FLAGS_REG))]
8954 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8956 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8958 ;; By default we don't ask for a scratch register, because when DWImode
8959 ;; values are manipulated, registers are already at a premium. But if
8960 ;; we have one handy, we won't turn it away.
8963 [(match_scratch:DWIH 3 "r")
8964 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8966 (match_operand:<DWI> 1 "nonmemory_operand" "")
8967 (match_operand:QI 2 "nonmemory_operand" "")))
8968 (clobber (reg:CC FLAGS_REG))])
8972 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8974 (define_insn "x86_64_shld"
8975 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8976 (ior:DI (ashift:DI (match_dup 0)
8977 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8978 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8979 (minus:QI (const_int 64) (match_dup 2)))))
8980 (clobber (reg:CC FLAGS_REG))]
8982 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8983 [(set_attr "type" "ishift")
8984 (set_attr "prefix_0f" "1")
8985 (set_attr "mode" "DI")
8986 (set_attr "athlon_decode" "vector")
8987 (set_attr "amdfam10_decode" "vector")
8988 (set_attr "bdver1_decode" "vector")])
8990 (define_insn "x86_shld"
8991 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8992 (ior:SI (ashift:SI (match_dup 0)
8993 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8994 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8995 (minus:QI (const_int 32) (match_dup 2)))))
8996 (clobber (reg:CC FLAGS_REG))]
8998 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8999 [(set_attr "type" "ishift")
9000 (set_attr "prefix_0f" "1")
9001 (set_attr "mode" "SI")
9002 (set_attr "pent_pair" "np")
9003 (set_attr "athlon_decode" "vector")
9004 (set_attr "amdfam10_decode" "vector")
9005 (set_attr "bdver1_decode" "vector")])
9007 (define_expand "x86_shift<mode>_adj_1"
9008 [(set (reg:CCZ FLAGS_REG)
9009 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9012 (set (match_operand:SWI48 0 "register_operand" "")
9013 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9014 (match_operand:SWI48 1 "register_operand" "")
9017 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9018 (match_operand:SWI48 3 "register_operand" "")
9021 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9023 (define_expand "x86_shift<mode>_adj_2"
9024 [(use (match_operand:SWI48 0 "register_operand" ""))
9025 (use (match_operand:SWI48 1 "register_operand" ""))
9026 (use (match_operand:QI 2 "register_operand" ""))]
9029 rtx label = gen_label_rtx ();
9032 emit_insn (gen_testqi_ccz_1 (operands[2],
9033 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9035 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9036 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9037 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9038 gen_rtx_LABEL_REF (VOIDmode, label),
9040 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9041 JUMP_LABEL (tmp) = label;
9043 emit_move_insn (operands[0], operands[1]);
9044 ix86_expand_clear (operands[1]);
9047 LABEL_NUSES (label) = 1;
9052 ;; Avoid useless masking of count operand.
9053 (define_insn_and_split "*ashl<mode>3_mask"
9054 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9056 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9059 (match_operand:SI 2 "nonimmediate_operand" "c")
9060 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9061 (clobber (reg:CC FLAGS_REG))]
9062 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9063 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9064 == GET_MODE_BITSIZE (<MODE>mode)-1"
9067 [(parallel [(set (match_dup 0)
9068 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9069 (clobber (reg:CC FLAGS_REG))])]
9071 if (can_create_pseudo_p ())
9072 operands [2] = force_reg (SImode, operands[2]);
9074 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9076 [(set_attr "type" "ishift")
9077 (set_attr "mode" "<MODE>")])
9079 (define_insn "*bmi2_ashl<mode>3_1"
9080 [(set (match_operand:SWI48 0 "register_operand" "=r")
9081 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9082 (match_operand:SWI48 2 "register_operand" "r")))]
9084 "shlx\t{%2, %1, %0|%0, %1, %2}"
9085 [(set_attr "type" "ishiftx")
9086 (set_attr "mode" "<MODE>")])
9088 (define_insn "*ashl<mode>3_1"
9089 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9090 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9091 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9092 (clobber (reg:CC FLAGS_REG))]
9093 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9095 switch (get_attr_type (insn))
9102 gcc_assert (operands[2] == const1_rtx);
9103 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9104 return "add{<imodesuffix>}\t%0, %0";
9107 if (operands[2] == const1_rtx
9108 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9109 return "sal{<imodesuffix>}\t%0";
9111 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9114 [(set_attr "isa" "*,*,bmi2")
9116 (cond [(eq_attr "alternative" "1")
9117 (const_string "lea")
9118 (eq_attr "alternative" "2")
9119 (const_string "ishiftx")
9120 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9121 (match_operand 0 "register_operand" ""))
9122 (match_operand 2 "const1_operand" ""))
9123 (const_string "alu")
9125 (const_string "ishift")))
9126 (set (attr "length_immediate")
9128 (ior (eq_attr "type" "alu")
9129 (and (eq_attr "type" "ishift")
9130 (and (match_operand 2 "const1_operand" "")
9131 (ior (match_test "TARGET_SHIFT1")
9132 (match_test "optimize_function_for_size_p (cfun)")))))
9134 (const_string "*")))
9135 (set_attr "mode" "<MODE>")])
9137 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9139 [(set (match_operand:SWI48 0 "register_operand" "")
9140 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9141 (match_operand:QI 2 "register_operand" "")))
9142 (clobber (reg:CC FLAGS_REG))]
9143 "TARGET_BMI2 && reload_completed"
9145 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9146 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9148 (define_insn "*bmi2_ashlsi3_1_zext"
9149 [(set (match_operand:DI 0 "register_operand" "=r")
9151 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9152 (match_operand:SI 2 "register_operand" "r"))))]
9153 "TARGET_64BIT && TARGET_BMI2"
9154 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9155 [(set_attr "type" "ishiftx")
9156 (set_attr "mode" "SI")])
9158 (define_insn "*ashlsi3_1_zext"
9159 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9161 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9162 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9163 (clobber (reg:CC FLAGS_REG))]
9164 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9166 switch (get_attr_type (insn))
9173 gcc_assert (operands[2] == const1_rtx);
9174 return "add{l}\t%k0, %k0";
9177 if (operands[2] == const1_rtx
9178 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9179 return "sal{l}\t%k0";
9181 return "sal{l}\t{%2, %k0|%k0, %2}";
9184 [(set_attr "isa" "*,*,bmi2")
9186 (cond [(eq_attr "alternative" "1")
9187 (const_string "lea")
9188 (eq_attr "alternative" "2")
9189 (const_string "ishiftx")
9190 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9191 (match_operand 2 "const1_operand" ""))
9192 (const_string "alu")
9194 (const_string "ishift")))
9195 (set (attr "length_immediate")
9197 (ior (eq_attr "type" "alu")
9198 (and (eq_attr "type" "ishift")
9199 (and (match_operand 2 "const1_operand" "")
9200 (ior (match_test "TARGET_SHIFT1")
9201 (match_test "optimize_function_for_size_p (cfun)")))))
9203 (const_string "*")))
9204 (set_attr "mode" "SI")])
9206 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9208 [(set (match_operand:DI 0 "register_operand" "")
9210 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9211 (match_operand:QI 2 "register_operand" ""))))
9212 (clobber (reg:CC FLAGS_REG))]
9213 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9215 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9216 "operands[2] = gen_lowpart (SImode, operands[2]);")
9218 (define_insn "*ashlhi3_1"
9219 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9220 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9221 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9222 (clobber (reg:CC FLAGS_REG))]
9223 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9225 switch (get_attr_type (insn))
9231 gcc_assert (operands[2] == const1_rtx);
9232 return "add{w}\t%0, %0";
9235 if (operands[2] == const1_rtx
9236 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9237 return "sal{w}\t%0";
9239 return "sal{w}\t{%2, %0|%0, %2}";
9243 (cond [(eq_attr "alternative" "1")
9244 (const_string "lea")
9245 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9246 (match_operand 0 "register_operand" ""))
9247 (match_operand 2 "const1_operand" ""))
9248 (const_string "alu")
9250 (const_string "ishift")))
9251 (set (attr "length_immediate")
9253 (ior (eq_attr "type" "alu")
9254 (and (eq_attr "type" "ishift")
9255 (and (match_operand 2 "const1_operand" "")
9256 (ior (match_test "TARGET_SHIFT1")
9257 (match_test "optimize_function_for_size_p (cfun)")))))
9259 (const_string "*")))
9260 (set_attr "mode" "HI,SI")])
9262 ;; %%% Potential partial reg stall on alternative 1. What to do?
9263 (define_insn "*ashlqi3_1"
9264 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9265 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9266 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9267 (clobber (reg:CC FLAGS_REG))]
9268 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9270 switch (get_attr_type (insn))
9276 gcc_assert (operands[2] == const1_rtx);
9277 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9278 return "add{l}\t%k0, %k0";
9280 return "add{b}\t%0, %0";
9283 if (operands[2] == const1_rtx
9284 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9286 if (get_attr_mode (insn) == MODE_SI)
9287 return "sal{l}\t%k0";
9289 return "sal{b}\t%0";
9293 if (get_attr_mode (insn) == MODE_SI)
9294 return "sal{l}\t{%2, %k0|%k0, %2}";
9296 return "sal{b}\t{%2, %0|%0, %2}";
9301 (cond [(eq_attr "alternative" "2")
9302 (const_string "lea")
9303 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9304 (match_operand 0 "register_operand" ""))
9305 (match_operand 2 "const1_operand" ""))
9306 (const_string "alu")
9308 (const_string "ishift")))
9309 (set (attr "length_immediate")
9311 (ior (eq_attr "type" "alu")
9312 (and (eq_attr "type" "ishift")
9313 (and (match_operand 2 "const1_operand" "")
9314 (ior (match_test "TARGET_SHIFT1")
9315 (match_test "optimize_function_for_size_p (cfun)")))))
9317 (const_string "*")))
9318 (set_attr "mode" "QI,SI,SI")])
9320 (define_insn "*ashlqi3_1_slp"
9321 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9322 (ashift:QI (match_dup 0)
9323 (match_operand:QI 1 "nonmemory_operand" "cI")))
9324 (clobber (reg:CC FLAGS_REG))]
9325 "(optimize_function_for_size_p (cfun)
9326 || !TARGET_PARTIAL_FLAG_REG_STALL
9327 || (operands[1] == const1_rtx
9329 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9331 switch (get_attr_type (insn))
9334 gcc_assert (operands[1] == const1_rtx);
9335 return "add{b}\t%0, %0";
9338 if (operands[1] == const1_rtx
9339 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9340 return "sal{b}\t%0";
9342 return "sal{b}\t{%1, %0|%0, %1}";
9346 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9347 (match_operand 0 "register_operand" ""))
9348 (match_operand 1 "const1_operand" ""))
9349 (const_string "alu")
9351 (const_string "ishift1")))
9352 (set (attr "length_immediate")
9354 (ior (eq_attr "type" "alu")
9355 (and (eq_attr "type" "ishift1")
9356 (and (match_operand 1 "const1_operand" "")
9357 (ior (match_test "TARGET_SHIFT1")
9358 (match_test "optimize_function_for_size_p (cfun)")))))
9360 (const_string "*")))
9361 (set_attr "mode" "QI")])
9363 ;; Convert ashift to the lea pattern to avoid flags dependency.
9365 [(set (match_operand 0 "register_operand" "")
9366 (ashift (match_operand 1 "index_register_operand" "")
9367 (match_operand:QI 2 "const_int_operand" "")))
9368 (clobber (reg:CC FLAGS_REG))]
9369 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9371 && true_regnum (operands[0]) != true_regnum (operands[1])"
9374 enum machine_mode mode = GET_MODE (operands[0]);
9377 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9380 operands[0] = gen_lowpart (mode, operands[0]);
9381 operands[1] = gen_lowpart (mode, operands[1]);
9384 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9386 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9388 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9392 ;; Convert ashift to the lea pattern to avoid flags dependency.
9394 [(set (match_operand:DI 0 "register_operand" "")
9396 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9397 (match_operand:QI 2 "const_int_operand" ""))))
9398 (clobber (reg:CC FLAGS_REG))]
9399 "TARGET_64BIT && reload_completed
9400 && true_regnum (operands[0]) != true_regnum (operands[1])"
9402 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9404 operands[1] = gen_lowpart (DImode, operands[1]);
9405 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9408 ;; This pattern can't accept a variable shift count, since shifts by
9409 ;; zero don't affect the flags. We assume that shifts by constant
9410 ;; zero are optimized away.
9411 (define_insn "*ashl<mode>3_cmp"
9412 [(set (reg FLAGS_REG)
9414 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9415 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9417 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9418 (ashift:SWI (match_dup 1) (match_dup 2)))]
9419 "(optimize_function_for_size_p (cfun)
9420 || !TARGET_PARTIAL_FLAG_REG_STALL
9421 || (operands[2] == const1_rtx
9423 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9424 && ix86_match_ccmode (insn, CCGOCmode)
9425 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9427 switch (get_attr_type (insn))
9430 gcc_assert (operands[2] == const1_rtx);
9431 return "add{<imodesuffix>}\t%0, %0";
9434 if (operands[2] == const1_rtx
9435 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9436 return "sal{<imodesuffix>}\t%0";
9438 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9442 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9443 (match_operand 0 "register_operand" ""))
9444 (match_operand 2 "const1_operand" ""))
9445 (const_string "alu")
9447 (const_string "ishift")))
9448 (set (attr "length_immediate")
9450 (ior (eq_attr "type" "alu")
9451 (and (eq_attr "type" "ishift")
9452 (and (match_operand 2 "const1_operand" "")
9453 (ior (match_test "TARGET_SHIFT1")
9454 (match_test "optimize_function_for_size_p (cfun)")))))
9456 (const_string "*")))
9457 (set_attr "mode" "<MODE>")])
9459 (define_insn "*ashlsi3_cmp_zext"
9460 [(set (reg FLAGS_REG)
9462 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9463 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9465 (set (match_operand:DI 0 "register_operand" "=r")
9466 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9468 && (optimize_function_for_size_p (cfun)
9469 || !TARGET_PARTIAL_FLAG_REG_STALL
9470 || (operands[2] == const1_rtx
9472 || TARGET_DOUBLE_WITH_ADD)))
9473 && ix86_match_ccmode (insn, CCGOCmode)
9474 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9476 switch (get_attr_type (insn))
9479 gcc_assert (operands[2] == const1_rtx);
9480 return "add{l}\t%k0, %k0";
9483 if (operands[2] == const1_rtx
9484 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9485 return "sal{l}\t%k0";
9487 return "sal{l}\t{%2, %k0|%k0, %2}";
9491 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9492 (match_operand 2 "const1_operand" ""))
9493 (const_string "alu")
9495 (const_string "ishift")))
9496 (set (attr "length_immediate")
9498 (ior (eq_attr "type" "alu")
9499 (and (eq_attr "type" "ishift")
9500 (and (match_operand 2 "const1_operand" "")
9501 (ior (match_test "TARGET_SHIFT1")
9502 (match_test "optimize_function_for_size_p (cfun)")))))
9504 (const_string "*")))
9505 (set_attr "mode" "SI")])
9507 (define_insn "*ashl<mode>3_cconly"
9508 [(set (reg FLAGS_REG)
9510 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9511 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9513 (clobber (match_scratch:SWI 0 "=<r>"))]
9514 "(optimize_function_for_size_p (cfun)
9515 || !TARGET_PARTIAL_FLAG_REG_STALL
9516 || (operands[2] == const1_rtx
9518 || TARGET_DOUBLE_WITH_ADD)))
9519 && ix86_match_ccmode (insn, CCGOCmode)"
9521 switch (get_attr_type (insn))
9524 gcc_assert (operands[2] == const1_rtx);
9525 return "add{<imodesuffix>}\t%0, %0";
9528 if (operands[2] == const1_rtx
9529 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9530 return "sal{<imodesuffix>}\t%0";
9532 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9536 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9537 (match_operand 0 "register_operand" ""))
9538 (match_operand 2 "const1_operand" ""))
9539 (const_string "alu")
9541 (const_string "ishift")))
9542 (set (attr "length_immediate")
9544 (ior (eq_attr "type" "alu")
9545 (and (eq_attr "type" "ishift")
9546 (and (match_operand 2 "const1_operand" "")
9547 (ior (match_test "TARGET_SHIFT1")
9548 (match_test "optimize_function_for_size_p (cfun)")))))
9550 (const_string "*")))
9551 (set_attr "mode" "<MODE>")])
9553 ;; See comment above `ashl<mode>3' about how this works.
9555 (define_expand "<shift_insn><mode>3"
9556 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9557 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9558 (match_operand:QI 2 "nonmemory_operand" "")))]
9560 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9562 ;; Avoid useless masking of count operand.
9563 (define_insn_and_split "*<shift_insn><mode>3_mask"
9564 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9566 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9569 (match_operand:SI 2 "nonimmediate_operand" "c")
9570 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9571 (clobber (reg:CC FLAGS_REG))]
9572 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9573 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9574 == GET_MODE_BITSIZE (<MODE>mode)-1"
9577 [(parallel [(set (match_dup 0)
9578 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9579 (clobber (reg:CC FLAGS_REG))])]
9581 if (can_create_pseudo_p ())
9582 operands [2] = force_reg (SImode, operands[2]);
9584 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9586 [(set_attr "type" "ishift")
9587 (set_attr "mode" "<MODE>")])
9589 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9590 [(set (match_operand:DWI 0 "register_operand" "=r")
9591 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9592 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9593 (clobber (reg:CC FLAGS_REG))]
9596 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9598 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9599 [(set_attr "type" "multi")])
9601 ;; By default we don't ask for a scratch register, because when DWImode
9602 ;; values are manipulated, registers are already at a premium. But if
9603 ;; we have one handy, we won't turn it away.
9606 [(match_scratch:DWIH 3 "r")
9607 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9609 (match_operand:<DWI> 1 "register_operand" "")
9610 (match_operand:QI 2 "nonmemory_operand" "")))
9611 (clobber (reg:CC FLAGS_REG))])
9615 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9617 (define_insn "x86_64_shrd"
9618 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9619 (ior:DI (ashiftrt:DI (match_dup 0)
9620 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9621 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9622 (minus:QI (const_int 64) (match_dup 2)))))
9623 (clobber (reg:CC FLAGS_REG))]
9625 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9626 [(set_attr "type" "ishift")
9627 (set_attr "prefix_0f" "1")
9628 (set_attr "mode" "DI")
9629 (set_attr "athlon_decode" "vector")
9630 (set_attr "amdfam10_decode" "vector")
9631 (set_attr "bdver1_decode" "vector")])
9633 (define_insn "x86_shrd"
9634 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9635 (ior:SI (ashiftrt:SI (match_dup 0)
9636 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9637 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9638 (minus:QI (const_int 32) (match_dup 2)))))
9639 (clobber (reg:CC FLAGS_REG))]
9641 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9642 [(set_attr "type" "ishift")
9643 (set_attr "prefix_0f" "1")
9644 (set_attr "mode" "SI")
9645 (set_attr "pent_pair" "np")
9646 (set_attr "athlon_decode" "vector")
9647 (set_attr "amdfam10_decode" "vector")
9648 (set_attr "bdver1_decode" "vector")])
9650 (define_insn "ashrdi3_cvt"
9651 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9652 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9653 (match_operand:QI 2 "const_int_operand" "")))
9654 (clobber (reg:CC FLAGS_REG))]
9655 "TARGET_64BIT && INTVAL (operands[2]) == 63
9656 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9657 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9660 sar{q}\t{%2, %0|%0, %2}"
9661 [(set_attr "type" "imovx,ishift")
9662 (set_attr "prefix_0f" "0,*")
9663 (set_attr "length_immediate" "0,*")
9664 (set_attr "modrm" "0,1")
9665 (set_attr "mode" "DI")])
9667 (define_insn "ashrsi3_cvt"
9668 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9669 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9670 (match_operand:QI 2 "const_int_operand" "")))
9671 (clobber (reg:CC FLAGS_REG))]
9672 "INTVAL (operands[2]) == 31
9673 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9674 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9677 sar{l}\t{%2, %0|%0, %2}"
9678 [(set_attr "type" "imovx,ishift")
9679 (set_attr "prefix_0f" "0,*")
9680 (set_attr "length_immediate" "0,*")
9681 (set_attr "modrm" "0,1")
9682 (set_attr "mode" "SI")])
9684 (define_insn "*ashrsi3_cvt_zext"
9685 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9687 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9688 (match_operand:QI 2 "const_int_operand" ""))))
9689 (clobber (reg:CC FLAGS_REG))]
9690 "TARGET_64BIT && INTVAL (operands[2]) == 31
9691 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9692 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9695 sar{l}\t{%2, %k0|%k0, %2}"
9696 [(set_attr "type" "imovx,ishift")
9697 (set_attr "prefix_0f" "0,*")
9698 (set_attr "length_immediate" "0,*")
9699 (set_attr "modrm" "0,1")
9700 (set_attr "mode" "SI")])
9702 (define_expand "x86_shift<mode>_adj_3"
9703 [(use (match_operand:SWI48 0 "register_operand" ""))
9704 (use (match_operand:SWI48 1 "register_operand" ""))
9705 (use (match_operand:QI 2 "register_operand" ""))]
9708 rtx label = gen_label_rtx ();
9711 emit_insn (gen_testqi_ccz_1 (operands[2],
9712 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9714 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9715 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9716 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9717 gen_rtx_LABEL_REF (VOIDmode, label),
9719 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9720 JUMP_LABEL (tmp) = label;
9722 emit_move_insn (operands[0], operands[1]);
9723 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9724 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9726 LABEL_NUSES (label) = 1;
9731 (define_insn "*bmi2_<shift_insn><mode>3_1"
9732 [(set (match_operand:SWI48 0 "register_operand" "=r")
9733 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9734 (match_operand:SWI48 2 "register_operand" "r")))]
9736 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9737 [(set_attr "type" "ishiftx")
9738 (set_attr "mode" "<MODE>")])
9740 (define_insn "*<shift_insn><mode>3_1"
9741 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9743 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9744 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9745 (clobber (reg:CC FLAGS_REG))]
9746 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9748 switch (get_attr_type (insn))
9754 if (operands[2] == const1_rtx
9755 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9756 return "<shift>{<imodesuffix>}\t%0";
9758 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9761 [(set_attr "isa" "*,bmi2")
9762 (set_attr "type" "ishift,ishiftx")
9763 (set (attr "length_immediate")
9765 (and (match_operand 2 "const1_operand" "")
9766 (ior (match_test "TARGET_SHIFT1")
9767 (match_test "optimize_function_for_size_p (cfun)")))
9769 (const_string "*")))
9770 (set_attr "mode" "<MODE>")])
9772 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9774 [(set (match_operand:SWI48 0 "register_operand" "")
9775 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9776 (match_operand:QI 2 "register_operand" "")))
9777 (clobber (reg:CC FLAGS_REG))]
9778 "TARGET_BMI2 && reload_completed"
9780 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9781 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9783 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9784 [(set (match_operand:DI 0 "register_operand" "=r")
9786 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9787 (match_operand:SI 2 "register_operand" "r"))))]
9788 "TARGET_64BIT && TARGET_BMI2"
9789 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9790 [(set_attr "type" "ishiftx")
9791 (set_attr "mode" "SI")])
9793 (define_insn "*<shift_insn>si3_1_zext"
9794 [(set (match_operand:DI 0 "register_operand" "=r,r")
9796 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9797 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9798 (clobber (reg:CC FLAGS_REG))]
9799 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9801 switch (get_attr_type (insn))
9807 if (operands[2] == const1_rtx
9808 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9809 return "<shift>{l}\t%k0";
9811 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9814 [(set_attr "isa" "*,bmi2")
9815 (set_attr "type" "ishift,ishiftx")
9816 (set (attr "length_immediate")
9818 (and (match_operand 2 "const1_operand" "")
9819 (ior (match_test "TARGET_SHIFT1")
9820 (match_test "optimize_function_for_size_p (cfun)")))
9822 (const_string "*")))
9823 (set_attr "mode" "SI")])
9825 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9827 [(set (match_operand:DI 0 "register_operand" "")
9829 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9830 (match_operand:QI 2 "register_operand" ""))))
9831 (clobber (reg:CC FLAGS_REG))]
9832 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9834 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9835 "operands[2] = gen_lowpart (SImode, operands[2]);")
9837 (define_insn "*<shift_insn><mode>3_1"
9838 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9840 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9841 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9842 (clobber (reg:CC FLAGS_REG))]
9843 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9845 if (operands[2] == const1_rtx
9846 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9847 return "<shift>{<imodesuffix>}\t%0";
9849 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9851 [(set_attr "type" "ishift")
9852 (set (attr "length_immediate")
9854 (and (match_operand 2 "const1_operand" "")
9855 (ior (match_test "TARGET_SHIFT1")
9856 (match_test "optimize_function_for_size_p (cfun)")))
9858 (const_string "*")))
9859 (set_attr "mode" "<MODE>")])
9861 (define_insn "*<shift_insn>qi3_1_slp"
9862 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9863 (any_shiftrt:QI (match_dup 0)
9864 (match_operand:QI 1 "nonmemory_operand" "cI")))
9865 (clobber (reg:CC FLAGS_REG))]
9866 "(optimize_function_for_size_p (cfun)
9867 || !TARGET_PARTIAL_REG_STALL
9868 || (operands[1] == const1_rtx
9871 if (operands[1] == const1_rtx
9872 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9873 return "<shift>{b}\t%0";
9875 return "<shift>{b}\t{%1, %0|%0, %1}";
9877 [(set_attr "type" "ishift1")
9878 (set (attr "length_immediate")
9880 (and (match_operand 1 "const1_operand" "")
9881 (ior (match_test "TARGET_SHIFT1")
9882 (match_test "optimize_function_for_size_p (cfun)")))
9884 (const_string "*")))
9885 (set_attr "mode" "QI")])
9887 ;; This pattern can't accept a variable shift count, since shifts by
9888 ;; zero don't affect the flags. We assume that shifts by constant
9889 ;; zero are optimized away.
9890 (define_insn "*<shift_insn><mode>3_cmp"
9891 [(set (reg FLAGS_REG)
9894 (match_operand:SWI 1 "nonimmediate_operand" "0")
9895 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9897 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9898 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9899 "(optimize_function_for_size_p (cfun)
9900 || !TARGET_PARTIAL_FLAG_REG_STALL
9901 || (operands[2] == const1_rtx
9903 && ix86_match_ccmode (insn, CCGOCmode)
9904 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9906 if (operands[2] == const1_rtx
9907 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9908 return "<shift>{<imodesuffix>}\t%0";
9910 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9912 [(set_attr "type" "ishift")
9913 (set (attr "length_immediate")
9915 (and (match_operand 2 "const1_operand" "")
9916 (ior (match_test "TARGET_SHIFT1")
9917 (match_test "optimize_function_for_size_p (cfun)")))
9919 (const_string "*")))
9920 (set_attr "mode" "<MODE>")])
9922 (define_insn "*<shift_insn>si3_cmp_zext"
9923 [(set (reg FLAGS_REG)
9925 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9926 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9928 (set (match_operand:DI 0 "register_operand" "=r")
9929 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9931 && (optimize_function_for_size_p (cfun)
9932 || !TARGET_PARTIAL_FLAG_REG_STALL
9933 || (operands[2] == const1_rtx
9935 && ix86_match_ccmode (insn, CCGOCmode)
9936 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9938 if (operands[2] == const1_rtx
9939 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9940 return "<shift>{l}\t%k0";
9942 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9944 [(set_attr "type" "ishift")
9945 (set (attr "length_immediate")
9947 (and (match_operand 2 "const1_operand" "")
9948 (ior (match_test "TARGET_SHIFT1")
9949 (match_test "optimize_function_for_size_p (cfun)")))
9951 (const_string "*")))
9952 (set_attr "mode" "SI")])
9954 (define_insn "*<shift_insn><mode>3_cconly"
9955 [(set (reg FLAGS_REG)
9958 (match_operand:SWI 1 "register_operand" "0")
9959 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9961 (clobber (match_scratch:SWI 0 "=<r>"))]
9962 "(optimize_function_for_size_p (cfun)
9963 || !TARGET_PARTIAL_FLAG_REG_STALL
9964 || (operands[2] == const1_rtx
9966 && ix86_match_ccmode (insn, CCGOCmode)"
9968 if (operands[2] == const1_rtx
9969 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9970 return "<shift>{<imodesuffix>}\t%0";
9972 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9974 [(set_attr "type" "ishift")
9975 (set (attr "length_immediate")
9977 (and (match_operand 2 "const1_operand" "")
9978 (ior (match_test "TARGET_SHIFT1")
9979 (match_test "optimize_function_for_size_p (cfun)")))
9981 (const_string "*")))
9982 (set_attr "mode" "<MODE>")])
9984 ;; Rotate instructions
9986 (define_expand "<rotate_insn>ti3"
9987 [(set (match_operand:TI 0 "register_operand" "")
9988 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9989 (match_operand:QI 2 "nonmemory_operand" "")))]
9992 if (const_1_to_63_operand (operands[2], VOIDmode))
9993 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9994 (operands[0], operands[1], operands[2]));
10001 (define_expand "<rotate_insn>di3"
10002 [(set (match_operand:DI 0 "shiftdi_operand" "")
10003 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10004 (match_operand:QI 2 "nonmemory_operand" "")))]
10008 ix86_expand_binary_operator (<CODE>, DImode, operands);
10009 else if (const_1_to_31_operand (operands[2], VOIDmode))
10010 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10011 (operands[0], operands[1], operands[2]));
10018 (define_expand "<rotate_insn><mode>3"
10019 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10020 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10021 (match_operand:QI 2 "nonmemory_operand" "")))]
10023 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10025 ;; Avoid useless masking of count operand.
10026 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10027 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10029 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10032 (match_operand:SI 2 "nonimmediate_operand" "c")
10033 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10034 (clobber (reg:CC FLAGS_REG))]
10035 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10036 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10037 == GET_MODE_BITSIZE (<MODE>mode)-1"
10040 [(parallel [(set (match_dup 0)
10041 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10042 (clobber (reg:CC FLAGS_REG))])]
10044 if (can_create_pseudo_p ())
10045 operands [2] = force_reg (SImode, operands[2]);
10047 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10049 [(set_attr "type" "rotate")
10050 (set_attr "mode" "<MODE>")])
10052 ;; Implement rotation using two double-precision
10053 ;; shift instructions and a scratch register.
10055 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10056 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10057 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10058 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10059 (clobber (reg:CC FLAGS_REG))
10060 (clobber (match_scratch:DWIH 3 "=&r"))]
10064 [(set (match_dup 3) (match_dup 4))
10066 [(set (match_dup 4)
10067 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10068 (lshiftrt:DWIH (match_dup 5)
10069 (minus:QI (match_dup 6) (match_dup 2)))))
10070 (clobber (reg:CC FLAGS_REG))])
10072 [(set (match_dup 5)
10073 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10074 (lshiftrt:DWIH (match_dup 3)
10075 (minus:QI (match_dup 6) (match_dup 2)))))
10076 (clobber (reg:CC FLAGS_REG))])]
10078 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10080 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10083 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10084 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10085 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10086 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10087 (clobber (reg:CC FLAGS_REG))
10088 (clobber (match_scratch:DWIH 3 "=&r"))]
10092 [(set (match_dup 3) (match_dup 4))
10094 [(set (match_dup 4)
10095 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10096 (ashift:DWIH (match_dup 5)
10097 (minus:QI (match_dup 6) (match_dup 2)))))
10098 (clobber (reg:CC FLAGS_REG))])
10100 [(set (match_dup 5)
10101 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10102 (ashift:DWIH (match_dup 3)
10103 (minus:QI (match_dup 6) (match_dup 2)))))
10104 (clobber (reg:CC FLAGS_REG))])]
10106 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10108 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10111 (define_insn "*bmi2_rorx<mode>3_1"
10112 [(set (match_operand:SWI48 0 "register_operand" "=r")
10113 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10114 (match_operand:QI 2 "immediate_operand" "<S>")))]
10116 "rorx\t{%2, %1, %0|%0, %1, %2}"
10117 [(set_attr "type" "rotatex")
10118 (set_attr "mode" "<MODE>")])
10120 (define_insn "*<rotate_insn><mode>3_1"
10121 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10123 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10124 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10125 (clobber (reg:CC FLAGS_REG))]
10126 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10128 switch (get_attr_type (insn))
10134 if (operands[2] == const1_rtx
10135 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10136 return "<rotate>{<imodesuffix>}\t%0";
10138 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10141 [(set_attr "isa" "*,bmi2")
10142 (set_attr "type" "rotate,rotatex")
10143 (set (attr "length_immediate")
10145 (and (eq_attr "type" "rotate")
10146 (and (match_operand 2 "const1_operand" "")
10147 (ior (match_test "TARGET_SHIFT1")
10148 (match_test "optimize_function_for_size_p (cfun)"))))
10150 (const_string "*")))
10151 (set_attr "mode" "<MODE>")])
10153 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10155 [(set (match_operand:SWI48 0 "register_operand" "")
10156 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10157 (match_operand:QI 2 "immediate_operand" "")))
10158 (clobber (reg:CC FLAGS_REG))]
10159 "TARGET_BMI2 && reload_completed"
10160 [(set (match_dup 0)
10161 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10164 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10168 [(set (match_operand:SWI48 0 "register_operand" "")
10169 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10170 (match_operand:QI 2 "immediate_operand" "")))
10171 (clobber (reg:CC FLAGS_REG))]
10172 "TARGET_BMI2 && reload_completed"
10173 [(set (match_dup 0)
10174 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10176 (define_insn "*bmi2_rorxsi3_1_zext"
10177 [(set (match_operand:DI 0 "register_operand" "=r")
10179 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10180 (match_operand:QI 2 "immediate_operand" "I"))))]
10181 "TARGET_64BIT && TARGET_BMI2"
10182 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10183 [(set_attr "type" "rotatex")
10184 (set_attr "mode" "SI")])
10186 (define_insn "*<rotate_insn>si3_1_zext"
10187 [(set (match_operand:DI 0 "register_operand" "=r,r")
10189 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10190 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10191 (clobber (reg:CC FLAGS_REG))]
10192 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10194 switch (get_attr_type (insn))
10200 if (operands[2] == const1_rtx
10201 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10202 return "<rotate>{l}\t%k0";
10204 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10207 [(set_attr "isa" "*,bmi2")
10208 (set_attr "type" "rotate,rotatex")
10209 (set (attr "length_immediate")
10211 (and (eq_attr "type" "rotate")
10212 (and (match_operand 2 "const1_operand" "")
10213 (ior (match_test "TARGET_SHIFT1")
10214 (match_test "optimize_function_for_size_p (cfun)"))))
10216 (const_string "*")))
10217 (set_attr "mode" "SI")])
10219 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10221 [(set (match_operand:DI 0 "register_operand" "")
10223 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10224 (match_operand:QI 2 "immediate_operand" ""))))
10225 (clobber (reg:CC FLAGS_REG))]
10226 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10227 [(set (match_dup 0)
10228 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10231 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10235 [(set (match_operand:DI 0 "register_operand" "")
10237 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10238 (match_operand:QI 2 "immediate_operand" ""))))
10239 (clobber (reg:CC FLAGS_REG))]
10240 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10241 [(set (match_dup 0)
10242 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10244 (define_insn "*<rotate_insn><mode>3_1"
10245 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10246 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10247 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10248 (clobber (reg:CC FLAGS_REG))]
10249 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10251 if (operands[2] == const1_rtx
10252 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10253 return "<rotate>{<imodesuffix>}\t%0";
10255 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10257 [(set_attr "type" "rotate")
10258 (set (attr "length_immediate")
10260 (and (match_operand 2 "const1_operand" "")
10261 (ior (match_test "TARGET_SHIFT1")
10262 (match_test "optimize_function_for_size_p (cfun)")))
10264 (const_string "*")))
10265 (set_attr "mode" "<MODE>")])
10267 (define_insn "*<rotate_insn>qi3_1_slp"
10268 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10269 (any_rotate:QI (match_dup 0)
10270 (match_operand:QI 1 "nonmemory_operand" "cI")))
10271 (clobber (reg:CC FLAGS_REG))]
10272 "(optimize_function_for_size_p (cfun)
10273 || !TARGET_PARTIAL_REG_STALL
10274 || (operands[1] == const1_rtx
10275 && TARGET_SHIFT1))"
10277 if (operands[1] == const1_rtx
10278 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10279 return "<rotate>{b}\t%0";
10281 return "<rotate>{b}\t{%1, %0|%0, %1}";
10283 [(set_attr "type" "rotate1")
10284 (set (attr "length_immediate")
10286 (and (match_operand 1 "const1_operand" "")
10287 (ior (match_test "TARGET_SHIFT1")
10288 (match_test "optimize_function_for_size_p (cfun)")))
10290 (const_string "*")))
10291 (set_attr "mode" "QI")])
10294 [(set (match_operand:HI 0 "register_operand" "")
10295 (any_rotate:HI (match_dup 0) (const_int 8)))
10296 (clobber (reg:CC FLAGS_REG))]
10298 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10299 [(parallel [(set (strict_low_part (match_dup 0))
10300 (bswap:HI (match_dup 0)))
10301 (clobber (reg:CC FLAGS_REG))])])
10303 ;; Bit set / bit test instructions
10305 (define_expand "extv"
10306 [(set (match_operand:SI 0 "register_operand" "")
10307 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10308 (match_operand:SI 2 "const8_operand" "")
10309 (match_operand:SI 3 "const8_operand" "")))]
10312 /* Handle extractions from %ah et al. */
10313 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10316 /* From mips.md: extract_bit_field doesn't verify that our source
10317 matches the predicate, so check it again here. */
10318 if (! ext_register_operand (operands[1], VOIDmode))
10322 (define_expand "extzv"
10323 [(set (match_operand:SI 0 "register_operand" "")
10324 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10325 (match_operand:SI 2 "const8_operand" "")
10326 (match_operand:SI 3 "const8_operand" "")))]
10329 /* Handle extractions from %ah et al. */
10330 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10333 /* From mips.md: extract_bit_field doesn't verify that our source
10334 matches the predicate, so check it again here. */
10335 if (! ext_register_operand (operands[1], VOIDmode))
10339 (define_expand "insv"
10340 [(set (zero_extract (match_operand 0 "register_operand" "")
10341 (match_operand 1 "const_int_operand" "")
10342 (match_operand 2 "const_int_operand" ""))
10343 (match_operand 3 "register_operand" ""))]
10346 rtx (*gen_mov_insv_1) (rtx, rtx);
10348 if (ix86_expand_pinsr (operands))
10351 /* Handle insertions to %ah et al. */
10352 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10355 /* From mips.md: insert_bit_field doesn't verify that our source
10356 matches the predicate, so check it again here. */
10357 if (! ext_register_operand (operands[0], VOIDmode))
10360 gen_mov_insv_1 = (TARGET_64BIT
10361 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10363 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10367 ;; %%% bts, btr, btc, bt.
10368 ;; In general these instructions are *slow* when applied to memory,
10369 ;; since they enforce atomic operation. When applied to registers,
10370 ;; it depends on the cpu implementation. They're never faster than
10371 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10372 ;; no point. But in 64-bit, we can't hold the relevant immediates
10373 ;; within the instruction itself, so operating on bits in the high
10374 ;; 32-bits of a register becomes easier.
10376 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10377 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10378 ;; negdf respectively, so they can never be disabled entirely.
10380 (define_insn "*btsq"
10381 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10383 (match_operand:DI 1 "const_0_to_63_operand" ""))
10385 (clobber (reg:CC FLAGS_REG))]
10386 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10387 "bts{q}\t{%1, %0|%0, %1}"
10388 [(set_attr "type" "alu1")
10389 (set_attr "prefix_0f" "1")
10390 (set_attr "mode" "DI")])
10392 (define_insn "*btrq"
10393 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10395 (match_operand:DI 1 "const_0_to_63_operand" ""))
10397 (clobber (reg:CC FLAGS_REG))]
10398 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10399 "btr{q}\t{%1, %0|%0, %1}"
10400 [(set_attr "type" "alu1")
10401 (set_attr "prefix_0f" "1")
10402 (set_attr "mode" "DI")])
10404 (define_insn "*btcq"
10405 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10407 (match_operand:DI 1 "const_0_to_63_operand" ""))
10408 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10409 (clobber (reg:CC FLAGS_REG))]
10410 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10411 "btc{q}\t{%1, %0|%0, %1}"
10412 [(set_attr "type" "alu1")
10413 (set_attr "prefix_0f" "1")
10414 (set_attr "mode" "DI")])
10416 ;; Allow Nocona to avoid these instructions if a register is available.
10419 [(match_scratch:DI 2 "r")
10420 (parallel [(set (zero_extract:DI
10421 (match_operand:DI 0 "register_operand" "")
10423 (match_operand:DI 1 "const_0_to_63_operand" ""))
10425 (clobber (reg:CC FLAGS_REG))])]
10426 "TARGET_64BIT && !TARGET_USE_BT"
10429 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10432 if (HOST_BITS_PER_WIDE_INT >= 64)
10433 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10434 else if (i < HOST_BITS_PER_WIDE_INT)
10435 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10437 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10439 op1 = immed_double_const (lo, hi, DImode);
10442 emit_move_insn (operands[2], op1);
10446 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10451 [(match_scratch:DI 2 "r")
10452 (parallel [(set (zero_extract:DI
10453 (match_operand:DI 0 "register_operand" "")
10455 (match_operand:DI 1 "const_0_to_63_operand" ""))
10457 (clobber (reg:CC FLAGS_REG))])]
10458 "TARGET_64BIT && !TARGET_USE_BT"
10461 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10464 if (HOST_BITS_PER_WIDE_INT >= 64)
10465 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10466 else if (i < HOST_BITS_PER_WIDE_INT)
10467 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10469 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10471 op1 = immed_double_const (~lo, ~hi, DImode);
10474 emit_move_insn (operands[2], op1);
10478 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10483 [(match_scratch:DI 2 "r")
10484 (parallel [(set (zero_extract:DI
10485 (match_operand:DI 0 "register_operand" "")
10487 (match_operand:DI 1 "const_0_to_63_operand" ""))
10488 (not:DI (zero_extract:DI
10489 (match_dup 0) (const_int 1) (match_dup 1))))
10490 (clobber (reg:CC FLAGS_REG))])]
10491 "TARGET_64BIT && !TARGET_USE_BT"
10494 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10497 if (HOST_BITS_PER_WIDE_INT >= 64)
10498 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10499 else if (i < HOST_BITS_PER_WIDE_INT)
10500 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10502 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10504 op1 = immed_double_const (lo, hi, DImode);
10507 emit_move_insn (operands[2], op1);
10511 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10515 (define_insn "*bt<mode>"
10516 [(set (reg:CCC FLAGS_REG)
10518 (zero_extract:SWI48
10519 (match_operand:SWI48 0 "register_operand" "r")
10521 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10523 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10524 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10525 [(set_attr "type" "alu1")
10526 (set_attr "prefix_0f" "1")
10527 (set_attr "mode" "<MODE>")])
10529 ;; Store-flag instructions.
10531 ;; For all sCOND expanders, also expand the compare or test insn that
10532 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10534 (define_insn_and_split "*setcc_di_1"
10535 [(set (match_operand:DI 0 "register_operand" "=q")
10536 (match_operator:DI 1 "ix86_comparison_operator"
10537 [(reg FLAGS_REG) (const_int 0)]))]
10538 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10540 "&& reload_completed"
10541 [(set (match_dup 2) (match_dup 1))
10542 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10544 PUT_MODE (operands[1], QImode);
10545 operands[2] = gen_lowpart (QImode, operands[0]);
10548 (define_insn_and_split "*setcc_si_1_and"
10549 [(set (match_operand:SI 0 "register_operand" "=q")
10550 (match_operator:SI 1 "ix86_comparison_operator"
10551 [(reg FLAGS_REG) (const_int 0)]))
10552 (clobber (reg:CC FLAGS_REG))]
10553 "!TARGET_PARTIAL_REG_STALL
10554 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10556 "&& reload_completed"
10557 [(set (match_dup 2) (match_dup 1))
10558 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10559 (clobber (reg:CC FLAGS_REG))])]
10561 PUT_MODE (operands[1], QImode);
10562 operands[2] = gen_lowpart (QImode, operands[0]);
10565 (define_insn_and_split "*setcc_si_1_movzbl"
10566 [(set (match_operand:SI 0 "register_operand" "=q")
10567 (match_operator:SI 1 "ix86_comparison_operator"
10568 [(reg FLAGS_REG) (const_int 0)]))]
10569 "!TARGET_PARTIAL_REG_STALL
10570 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10572 "&& reload_completed"
10573 [(set (match_dup 2) (match_dup 1))
10574 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10576 PUT_MODE (operands[1], QImode);
10577 operands[2] = gen_lowpart (QImode, operands[0]);
10580 (define_insn "*setcc_qi"
10581 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10582 (match_operator:QI 1 "ix86_comparison_operator"
10583 [(reg FLAGS_REG) (const_int 0)]))]
10586 [(set_attr "type" "setcc")
10587 (set_attr "mode" "QI")])
10589 (define_insn "*setcc_qi_slp"
10590 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10591 (match_operator:QI 1 "ix86_comparison_operator"
10592 [(reg FLAGS_REG) (const_int 0)]))]
10595 [(set_attr "type" "setcc")
10596 (set_attr "mode" "QI")])
10598 ;; In general it is not safe to assume too much about CCmode registers,
10599 ;; so simplify-rtx stops when it sees a second one. Under certain
10600 ;; conditions this is safe on x86, so help combine not create
10607 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10608 (ne:QI (match_operator 1 "ix86_comparison_operator"
10609 [(reg FLAGS_REG) (const_int 0)])
10612 [(set (match_dup 0) (match_dup 1))]
10613 "PUT_MODE (operands[1], QImode);")
10616 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10617 (ne:QI (match_operator 1 "ix86_comparison_operator"
10618 [(reg FLAGS_REG) (const_int 0)])
10621 [(set (match_dup 0) (match_dup 1))]
10622 "PUT_MODE (operands[1], QImode);")
10625 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10626 (eq:QI (match_operator 1 "ix86_comparison_operator"
10627 [(reg FLAGS_REG) (const_int 0)])
10630 [(set (match_dup 0) (match_dup 1))]
10632 rtx new_op1 = copy_rtx (operands[1]);
10633 operands[1] = new_op1;
10634 PUT_MODE (new_op1, QImode);
10635 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10636 GET_MODE (XEXP (new_op1, 0))));
10638 /* Make sure that (a) the CCmode we have for the flags is strong
10639 enough for the reversed compare or (b) we have a valid FP compare. */
10640 if (! ix86_comparison_operator (new_op1, VOIDmode))
10645 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10646 (eq:QI (match_operator 1 "ix86_comparison_operator"
10647 [(reg FLAGS_REG) (const_int 0)])
10650 [(set (match_dup 0) (match_dup 1))]
10652 rtx new_op1 = copy_rtx (operands[1]);
10653 operands[1] = new_op1;
10654 PUT_MODE (new_op1, QImode);
10655 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10656 GET_MODE (XEXP (new_op1, 0))));
10658 /* Make sure that (a) the CCmode we have for the flags is strong
10659 enough for the reversed compare or (b) we have a valid FP compare. */
10660 if (! ix86_comparison_operator (new_op1, VOIDmode))
10664 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10665 ;; subsequent logical operations are used to imitate conditional moves.
10666 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10669 (define_insn "setcc_<mode>_sse"
10670 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10671 (match_operator:MODEF 3 "sse_comparison_operator"
10672 [(match_operand:MODEF 1 "register_operand" "0,x")
10673 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10674 "SSE_FLOAT_MODE_P (<MODE>mode)"
10676 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10677 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10678 [(set_attr "isa" "noavx,avx")
10679 (set_attr "type" "ssecmp")
10680 (set_attr "length_immediate" "1")
10681 (set_attr "prefix" "orig,vex")
10682 (set_attr "mode" "<MODE>")])
10684 ;; Basic conditional jump instructions.
10685 ;; We ignore the overflow flag for signed branch instructions.
10687 (define_insn "*jcc_1"
10689 (if_then_else (match_operator 1 "ix86_comparison_operator"
10690 [(reg FLAGS_REG) (const_int 0)])
10691 (label_ref (match_operand 0 "" ""))
10695 [(set_attr "type" "ibr")
10696 (set_attr "modrm" "0")
10697 (set (attr "length")
10698 (if_then_else (and (ge (minus (match_dup 0) (pc))
10700 (lt (minus (match_dup 0) (pc))
10705 (define_insn "*jcc_2"
10707 (if_then_else (match_operator 1 "ix86_comparison_operator"
10708 [(reg FLAGS_REG) (const_int 0)])
10710 (label_ref (match_operand 0 "" ""))))]
10713 [(set_attr "type" "ibr")
10714 (set_attr "modrm" "0")
10715 (set (attr "length")
10716 (if_then_else (and (ge (minus (match_dup 0) (pc))
10718 (lt (minus (match_dup 0) (pc))
10723 ;; In general it is not safe to assume too much about CCmode registers,
10724 ;; so simplify-rtx stops when it sees a second one. Under certain
10725 ;; conditions this is safe on x86, so help combine not create
10733 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10734 [(reg FLAGS_REG) (const_int 0)])
10736 (label_ref (match_operand 1 "" ""))
10740 (if_then_else (match_dup 0)
10741 (label_ref (match_dup 1))
10743 "PUT_MODE (operands[0], VOIDmode);")
10747 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10748 [(reg FLAGS_REG) (const_int 0)])
10750 (label_ref (match_operand 1 "" ""))
10754 (if_then_else (match_dup 0)
10755 (label_ref (match_dup 1))
10758 rtx new_op0 = copy_rtx (operands[0]);
10759 operands[0] = new_op0;
10760 PUT_MODE (new_op0, VOIDmode);
10761 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10762 GET_MODE (XEXP (new_op0, 0))));
10764 /* Make sure that (a) the CCmode we have for the flags is strong
10765 enough for the reversed compare or (b) we have a valid FP compare. */
10766 if (! ix86_comparison_operator (new_op0, VOIDmode))
10770 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10771 ;; pass generates from shift insn with QImode operand. Actually, the mode
10772 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10773 ;; appropriate modulo of the bit offset value.
10775 (define_insn_and_split "*jcc_bt<mode>"
10777 (if_then_else (match_operator 0 "bt_comparison_operator"
10778 [(zero_extract:SWI48
10779 (match_operand:SWI48 1 "register_operand" "r")
10782 (match_operand:QI 2 "register_operand" "r")))
10784 (label_ref (match_operand 3 "" ""))
10786 (clobber (reg:CC FLAGS_REG))]
10787 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10790 [(set (reg:CCC FLAGS_REG)
10792 (zero_extract:SWI48
10798 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10799 (label_ref (match_dup 3))
10802 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10804 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10807 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10808 ;; also for DImode, this is what combine produces.
10809 (define_insn_and_split "*jcc_bt<mode>_mask"
10811 (if_then_else (match_operator 0 "bt_comparison_operator"
10812 [(zero_extract:SWI48
10813 (match_operand:SWI48 1 "register_operand" "r")
10816 (match_operand:SI 2 "register_operand" "r")
10817 (match_operand:SI 3 "const_int_operand" "n")))])
10818 (label_ref (match_operand 4 "" ""))
10820 (clobber (reg:CC FLAGS_REG))]
10821 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10822 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10823 == GET_MODE_BITSIZE (<MODE>mode)-1"
10826 [(set (reg:CCC FLAGS_REG)
10828 (zero_extract:SWI48
10834 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10835 (label_ref (match_dup 4))
10838 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10840 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10843 (define_insn_and_split "*jcc_btsi_1"
10845 (if_then_else (match_operator 0 "bt_comparison_operator"
10848 (match_operand:SI 1 "register_operand" "r")
10849 (match_operand:QI 2 "register_operand" "r"))
10852 (label_ref (match_operand 3 "" ""))
10854 (clobber (reg:CC FLAGS_REG))]
10855 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10858 [(set (reg:CCC FLAGS_REG)
10866 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10867 (label_ref (match_dup 3))
10870 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10872 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10875 ;; avoid useless masking of bit offset operand
10876 (define_insn_and_split "*jcc_btsi_mask_1"
10879 (match_operator 0 "bt_comparison_operator"
10882 (match_operand:SI 1 "register_operand" "r")
10885 (match_operand:SI 2 "register_operand" "r")
10886 (match_operand:SI 3 "const_int_operand" "n")) 0))
10889 (label_ref (match_operand 4 "" ""))
10891 (clobber (reg:CC FLAGS_REG))]
10892 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10893 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10896 [(set (reg:CCC FLAGS_REG)
10904 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10905 (label_ref (match_dup 4))
10907 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10909 ;; Define combination compare-and-branch fp compare instructions to help
10912 (define_insn "*fp_jcc_1_387"
10914 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10915 [(match_operand 1 "register_operand" "f")
10916 (match_operand 2 "nonimmediate_operand" "fm")])
10917 (label_ref (match_operand 3 "" ""))
10919 (clobber (reg:CCFP FPSR_REG))
10920 (clobber (reg:CCFP FLAGS_REG))
10921 (clobber (match_scratch:HI 4 "=a"))]
10923 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10924 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10925 && SELECT_CC_MODE (GET_CODE (operands[0]),
10926 operands[1], operands[2]) == CCFPmode
10930 (define_insn "*fp_jcc_1r_387"
10932 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10933 [(match_operand 1 "register_operand" "f")
10934 (match_operand 2 "nonimmediate_operand" "fm")])
10936 (label_ref (match_operand 3 "" ""))))
10937 (clobber (reg:CCFP FPSR_REG))
10938 (clobber (reg:CCFP FLAGS_REG))
10939 (clobber (match_scratch:HI 4 "=a"))]
10941 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10942 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10943 && SELECT_CC_MODE (GET_CODE (operands[0]),
10944 operands[1], operands[2]) == CCFPmode
10948 (define_insn "*fp_jcc_2_387"
10950 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10951 [(match_operand 1 "register_operand" "f")
10952 (match_operand 2 "register_operand" "f")])
10953 (label_ref (match_operand 3 "" ""))
10955 (clobber (reg:CCFP FPSR_REG))
10956 (clobber (reg:CCFP FLAGS_REG))
10957 (clobber (match_scratch:HI 4 "=a"))]
10958 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10959 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10963 (define_insn "*fp_jcc_2r_387"
10965 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10966 [(match_operand 1 "register_operand" "f")
10967 (match_operand 2 "register_operand" "f")])
10969 (label_ref (match_operand 3 "" ""))))
10970 (clobber (reg:CCFP FPSR_REG))
10971 (clobber (reg:CCFP FLAGS_REG))
10972 (clobber (match_scratch:HI 4 "=a"))]
10973 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10974 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10978 (define_insn "*fp_jcc_3_387"
10980 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10981 [(match_operand 1 "register_operand" "f")
10982 (match_operand 2 "const0_operand" "")])
10983 (label_ref (match_operand 3 "" ""))
10985 (clobber (reg:CCFP FPSR_REG))
10986 (clobber (reg:CCFP FLAGS_REG))
10987 (clobber (match_scratch:HI 4 "=a"))]
10988 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10989 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10990 && SELECT_CC_MODE (GET_CODE (operands[0]),
10991 operands[1], operands[2]) == CCFPmode
10997 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10998 [(match_operand 1 "register_operand" "")
10999 (match_operand 2 "nonimmediate_operand" "")])
11000 (match_operand 3 "" "")
11001 (match_operand 4 "" "")))
11002 (clobber (reg:CCFP FPSR_REG))
11003 (clobber (reg:CCFP FLAGS_REG))]
11007 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11008 operands[3], operands[4], NULL_RTX, NULL_RTX);
11014 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11015 [(match_operand 1 "register_operand" "")
11016 (match_operand 2 "general_operand" "")])
11017 (match_operand 3 "" "")
11018 (match_operand 4 "" "")))
11019 (clobber (reg:CCFP FPSR_REG))
11020 (clobber (reg:CCFP FLAGS_REG))
11021 (clobber (match_scratch:HI 5 "=a"))]
11025 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11026 operands[3], operands[4], operands[5], NULL_RTX);
11030 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11031 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11032 ;; with a precedence over other operators and is always put in the first
11033 ;; place. Swap condition and operands to match ficom instruction.
11035 (define_insn "*fp_jcc_4_<mode>_387"
11038 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11039 [(match_operator 1 "float_operator"
11040 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11041 (match_operand 3 "register_operand" "f,f")])
11042 (label_ref (match_operand 4 "" ""))
11044 (clobber (reg:CCFP FPSR_REG))
11045 (clobber (reg:CCFP FLAGS_REG))
11046 (clobber (match_scratch:HI 5 "=a,a"))]
11047 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11048 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11049 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11050 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11057 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11058 [(match_operator 1 "float_operator"
11059 [(match_operand:SWI24 2 "memory_operand" "")])
11060 (match_operand 3 "register_operand" "")])
11061 (match_operand 4 "" "")
11062 (match_operand 5 "" "")))
11063 (clobber (reg:CCFP FPSR_REG))
11064 (clobber (reg:CCFP FLAGS_REG))
11065 (clobber (match_scratch:HI 6 "=a"))]
11069 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11071 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11072 operands[3], operands[7],
11073 operands[4], operands[5], operands[6], NULL_RTX);
11077 ;; %%% Kill this when reload knows how to do it.
11081 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11082 [(match_operator 1 "float_operator"
11083 [(match_operand:SWI24 2 "register_operand" "")])
11084 (match_operand 3 "register_operand" "")])
11085 (match_operand 4 "" "")
11086 (match_operand 5 "" "")))
11087 (clobber (reg:CCFP FPSR_REG))
11088 (clobber (reg:CCFP FLAGS_REG))
11089 (clobber (match_scratch:HI 6 "=a"))]
11093 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11094 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11096 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11097 operands[3], operands[7],
11098 operands[4], operands[5], operands[6], operands[2]);
11102 ;; Unconditional and other jump instructions
11104 (define_insn "jump"
11106 (label_ref (match_operand 0 "" "")))]
11109 [(set_attr "type" "ibr")
11110 (set (attr "length")
11111 (if_then_else (and (ge (minus (match_dup 0) (pc))
11113 (lt (minus (match_dup 0) (pc))
11117 (set_attr "modrm" "0")])
11119 (define_expand "indirect_jump"
11120 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11122 (define_insn "*indirect_jump"
11123 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11126 [(set_attr "type" "ibr")
11127 (set_attr "length_immediate" "0")])
11129 (define_expand "tablejump"
11130 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11131 (use (label_ref (match_operand 1 "" "")))])]
11134 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11135 relative. Convert the relative address to an absolute address. */
11139 enum rtx_code code;
11141 /* We can't use @GOTOFF for text labels on VxWorks;
11142 see gotoff_operand. */
11143 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11147 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11149 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11153 op1 = pic_offset_table_rtx;
11158 op0 = pic_offset_table_rtx;
11162 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11165 else if (TARGET_X32)
11166 operands[0] = convert_memory_address (Pmode, operands[0]);
11169 (define_insn "*tablejump_1"
11170 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11171 (use (label_ref (match_operand 1 "" "")))]
11174 [(set_attr "type" "ibr")
11175 (set_attr "length_immediate" "0")])
11177 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11180 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11181 (set (match_operand:QI 1 "register_operand" "")
11182 (match_operator:QI 2 "ix86_comparison_operator"
11183 [(reg FLAGS_REG) (const_int 0)]))
11184 (set (match_operand 3 "q_regs_operand" "")
11185 (zero_extend (match_dup 1)))]
11186 "(peep2_reg_dead_p (3, operands[1])
11187 || operands_match_p (operands[1], operands[3]))
11188 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11189 [(set (match_dup 4) (match_dup 0))
11190 (set (strict_low_part (match_dup 5))
11193 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11194 operands[5] = gen_lowpart (QImode, operands[3]);
11195 ix86_expand_clear (operands[3]);
11198 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11201 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11202 (set (match_operand:QI 1 "register_operand" "")
11203 (match_operator:QI 2 "ix86_comparison_operator"
11204 [(reg FLAGS_REG) (const_int 0)]))
11205 (parallel [(set (match_operand 3 "q_regs_operand" "")
11206 (zero_extend (match_dup 1)))
11207 (clobber (reg:CC FLAGS_REG))])]
11208 "(peep2_reg_dead_p (3, operands[1])
11209 || operands_match_p (operands[1], operands[3]))
11210 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11211 [(set (match_dup 4) (match_dup 0))
11212 (set (strict_low_part (match_dup 5))
11215 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11216 operands[5] = gen_lowpart (QImode, operands[3]);
11217 ix86_expand_clear (operands[3]);
11220 ;; Call instructions.
11222 ;; The predicates normally associated with named expanders are not properly
11223 ;; checked for calls. This is a bug in the generic code, but it isn't that
11224 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11226 ;; P6 processors will jump to the address after the decrement when %esp
11227 ;; is used as a call operand, so they will execute return address as a code.
11228 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11230 ;; Register constraint for call instruction.
11231 (define_mode_attr c [(SI "l") (DI "r")])
11233 ;; Call subroutine returning no value.
11235 (define_expand "call"
11236 [(call (match_operand:QI 0 "" "")
11237 (match_operand 1 "" ""))
11238 (use (match_operand 2 "" ""))]
11241 ix86_expand_call (NULL, operands[0], operands[1],
11242 operands[2], NULL, false);
11246 (define_expand "sibcall"
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, true);
11257 (define_insn_and_split "*call_vzeroupper"
11258 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11259 (match_operand 1 "" ""))
11260 (unspec [(match_operand 2 "const_int_operand" "")]
11261 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11262 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11264 "&& reload_completed"
11266 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11267 [(set_attr "type" "call")])
11269 (define_insn "*call"
11270 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11271 (match_operand 1 "" ""))]
11272 "!SIBLING_CALL_P (insn)"
11273 "* return ix86_output_call_insn (insn, operands[0]);"
11274 [(set_attr "type" "call")])
11276 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11277 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11278 (match_operand 1 "" ""))
11279 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11280 (clobber (reg:TI XMM6_REG))
11281 (clobber (reg:TI XMM7_REG))
11282 (clobber (reg:TI XMM8_REG))
11283 (clobber (reg:TI XMM9_REG))
11284 (clobber (reg:TI XMM10_REG))
11285 (clobber (reg:TI XMM11_REG))
11286 (clobber (reg:TI XMM12_REG))
11287 (clobber (reg:TI XMM13_REG))
11288 (clobber (reg:TI XMM14_REG))
11289 (clobber (reg:TI XMM15_REG))
11290 (clobber (reg:DI SI_REG))
11291 (clobber (reg:DI DI_REG))
11292 (unspec [(match_operand 2 "const_int_operand" "")]
11293 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11294 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11296 "&& reload_completed"
11298 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11299 [(set_attr "type" "call")])
11301 (define_insn "*call_rex64_ms_sysv"
11302 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11303 (match_operand 1 "" ""))
11304 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11305 (clobber (reg:TI XMM6_REG))
11306 (clobber (reg:TI XMM7_REG))
11307 (clobber (reg:TI XMM8_REG))
11308 (clobber (reg:TI XMM9_REG))
11309 (clobber (reg:TI XMM10_REG))
11310 (clobber (reg:TI XMM11_REG))
11311 (clobber (reg:TI XMM12_REG))
11312 (clobber (reg:TI XMM13_REG))
11313 (clobber (reg:TI XMM14_REG))
11314 (clobber (reg:TI XMM15_REG))
11315 (clobber (reg:DI SI_REG))
11316 (clobber (reg:DI DI_REG))]
11317 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11318 "* return ix86_output_call_insn (insn, operands[0]);"
11319 [(set_attr "type" "call")])
11321 (define_insn_and_split "*sibcall_vzeroupper"
11322 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11323 (match_operand 1 "" ""))
11324 (unspec [(match_operand 2 "const_int_operand" "")]
11325 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11326 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11328 "&& reload_completed"
11330 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11331 [(set_attr "type" "call")])
11333 (define_insn "*sibcall"
11334 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11335 (match_operand 1 "" ""))]
11336 "SIBLING_CALL_P (insn)"
11337 "* return ix86_output_call_insn (insn, operands[0]);"
11338 [(set_attr "type" "call")])
11340 (define_expand "call_pop"
11341 [(parallel [(call (match_operand:QI 0 "" "")
11342 (match_operand:SI 1 "" ""))
11343 (set (reg:SI SP_REG)
11344 (plus:SI (reg:SI SP_REG)
11345 (match_operand:SI 3 "" "")))])]
11348 ix86_expand_call (NULL, operands[0], operands[1],
11349 operands[2], operands[3], false);
11353 (define_insn_and_split "*call_pop_vzeroupper"
11354 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11355 (match_operand:SI 1 "" ""))
11356 (set (reg:SI SP_REG)
11357 (plus:SI (reg:SI SP_REG)
11358 (match_operand:SI 2 "immediate_operand" "i")))
11359 (unspec [(match_operand 3 "const_int_operand" "")]
11360 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11361 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11363 "&& reload_completed"
11365 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11366 [(set_attr "type" "call")])
11368 (define_insn "*call_pop"
11369 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11370 (match_operand 1 "" ""))
11371 (set (reg:SI SP_REG)
11372 (plus:SI (reg:SI SP_REG)
11373 (match_operand:SI 2 "immediate_operand" "i")))]
11374 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11375 "* return ix86_output_call_insn (insn, operands[0]);"
11376 [(set_attr "type" "call")])
11378 (define_insn_and_split "*sibcall_pop_vzeroupper"
11379 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11380 (match_operand 1 "" ""))
11381 (set (reg:SI SP_REG)
11382 (plus:SI (reg:SI SP_REG)
11383 (match_operand:SI 2 "immediate_operand" "i")))
11384 (unspec [(match_operand 3 "const_int_operand" "")]
11385 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11386 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11388 "&& reload_completed"
11390 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11391 [(set_attr "type" "call")])
11393 (define_insn "*sibcall_pop"
11394 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11395 (match_operand 1 "" ""))
11396 (set (reg:SI SP_REG)
11397 (plus:SI (reg:SI SP_REG)
11398 (match_operand:SI 2 "immediate_operand" "i")))]
11399 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11400 "* return ix86_output_call_insn (insn, operands[0]);"
11401 [(set_attr "type" "call")])
11403 ;; Call subroutine, returning value in operand 0
11405 (define_expand "call_value"
11406 [(set (match_operand 0 "" "")
11407 (call (match_operand:QI 1 "" "")
11408 (match_operand 2 "" "")))
11409 (use (match_operand 3 "" ""))]
11412 ix86_expand_call (operands[0], operands[1], operands[2],
11413 operands[3], NULL, false);
11417 (define_expand "sibcall_value"
11418 [(set (match_operand 0 "" "")
11419 (call (match_operand:QI 1 "" "")
11420 (match_operand 2 "" "")))
11421 (use (match_operand 3 "" ""))]
11424 ix86_expand_call (operands[0], operands[1], operands[2],
11425 operands[3], NULL, true);
11429 (define_insn_and_split "*call_value_vzeroupper"
11430 [(set (match_operand 0 "" "")
11431 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11432 (match_operand 2 "" "")))
11433 (unspec [(match_operand 3 "const_int_operand" "")]
11434 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11435 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11437 "&& reload_completed"
11439 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11440 [(set_attr "type" "callv")])
11442 (define_insn "*call_value"
11443 [(set (match_operand 0 "" "")
11444 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11445 (match_operand 2 "" "")))]
11446 "!SIBLING_CALL_P (insn)"
11447 "* return ix86_output_call_insn (insn, operands[1]);"
11448 [(set_attr "type" "callv")])
11450 (define_insn_and_split "*sibcall_value_vzeroupper"
11451 [(set (match_operand 0 "" "")
11452 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11453 (match_operand 2 "" "")))
11454 (unspec [(match_operand 3 "const_int_operand" "")]
11455 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11456 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11458 "&& reload_completed"
11460 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11461 [(set_attr "type" "callv")])
11463 (define_insn "*sibcall_value"
11464 [(set (match_operand 0 "" "")
11465 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11466 (match_operand 2 "" "")))]
11467 "SIBLING_CALL_P (insn)"
11468 "* return ix86_output_call_insn (insn, operands[1]);"
11469 [(set_attr "type" "callv")])
11471 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11472 [(set (match_operand 0 "" "")
11473 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11474 (match_operand 2 "" "")))
11475 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11476 (clobber (reg:TI XMM6_REG))
11477 (clobber (reg:TI XMM7_REG))
11478 (clobber (reg:TI XMM8_REG))
11479 (clobber (reg:TI XMM9_REG))
11480 (clobber (reg:TI XMM10_REG))
11481 (clobber (reg:TI XMM11_REG))
11482 (clobber (reg:TI XMM12_REG))
11483 (clobber (reg:TI XMM13_REG))
11484 (clobber (reg:TI XMM14_REG))
11485 (clobber (reg:TI XMM15_REG))
11486 (clobber (reg:DI SI_REG))
11487 (clobber (reg:DI DI_REG))
11488 (unspec [(match_operand 3 "const_int_operand" "")]
11489 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11490 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11492 "&& reload_completed"
11494 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11495 [(set_attr "type" "callv")])
11497 (define_insn "*call_value_rex64_ms_sysv"
11498 [(set (match_operand 0 "" "")
11499 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11500 (match_operand 2 "" "")))
11501 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11502 (clobber (reg:TI XMM6_REG))
11503 (clobber (reg:TI XMM7_REG))
11504 (clobber (reg:TI XMM8_REG))
11505 (clobber (reg:TI XMM9_REG))
11506 (clobber (reg:TI XMM10_REG))
11507 (clobber (reg:TI XMM11_REG))
11508 (clobber (reg:TI XMM12_REG))
11509 (clobber (reg:TI XMM13_REG))
11510 (clobber (reg:TI XMM14_REG))
11511 (clobber (reg:TI XMM15_REG))
11512 (clobber (reg:DI SI_REG))
11513 (clobber (reg:DI DI_REG))]
11514 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11515 "* return ix86_output_call_insn (insn, operands[1]);"
11516 [(set_attr "type" "callv")])
11518 (define_expand "call_value_pop"
11519 [(parallel [(set (match_operand 0 "" "")
11520 (call (match_operand:QI 1 "" "")
11521 (match_operand:SI 2 "" "")))
11522 (set (reg:SI SP_REG)
11523 (plus:SI (reg:SI SP_REG)
11524 (match_operand:SI 4 "" "")))])]
11527 ix86_expand_call (operands[0], operands[1], operands[2],
11528 operands[3], operands[4], false);
11532 (define_insn_and_split "*call_value_pop_vzeroupper"
11533 [(set (match_operand 0 "" "")
11534 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11535 (match_operand 2 "" "")))
11536 (set (reg:SI SP_REG)
11537 (plus:SI (reg:SI SP_REG)
11538 (match_operand:SI 3 "immediate_operand" "i")))
11539 (unspec [(match_operand 4 "const_int_operand" "")]
11540 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11541 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11543 "&& reload_completed"
11545 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11546 [(set_attr "type" "callv")])
11548 (define_insn "*call_value_pop"
11549 [(set (match_operand 0 "" "")
11550 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11551 (match_operand 2 "" "")))
11552 (set (reg:SI SP_REG)
11553 (plus:SI (reg:SI SP_REG)
11554 (match_operand:SI 3 "immediate_operand" "i")))]
11555 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11556 "* return ix86_output_call_insn (insn, operands[1]);"
11557 [(set_attr "type" "callv")])
11559 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11560 [(set (match_operand 0 "" "")
11561 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
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 (unspec [(match_operand 4 "const_int_operand" "")]
11567 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11568 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11570 "&& reload_completed"
11572 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11573 [(set_attr "type" "callv")])
11575 (define_insn "*sibcall_value_pop"
11576 [(set (match_operand 0 "" "")
11577 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11578 (match_operand 2 "" "")))
11579 (set (reg:SI SP_REG)
11580 (plus:SI (reg:SI SP_REG)
11581 (match_operand:SI 3 "immediate_operand" "i")))]
11582 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11583 "* return ix86_output_call_insn (insn, operands[1]);"
11584 [(set_attr "type" "callv")])
11586 ;; Call subroutine returning any type.
11588 (define_expand "untyped_call"
11589 [(parallel [(call (match_operand 0 "" "")
11591 (match_operand 1 "" "")
11592 (match_operand 2 "" "")])]
11597 /* In order to give reg-stack an easier job in validating two
11598 coprocessor registers as containing a possible return value,
11599 simply pretend the untyped call returns a complex long double
11602 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11603 and should have the default ABI. */
11605 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11606 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11607 operands[0], const0_rtx,
11608 GEN_INT ((TARGET_64BIT
11609 ? (ix86_abi == SYSV_ABI
11610 ? X86_64_SSE_REGPARM_MAX
11611 : X86_64_MS_SSE_REGPARM_MAX)
11612 : X86_32_SSE_REGPARM_MAX)
11616 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11618 rtx set = XVECEXP (operands[2], 0, i);
11619 emit_move_insn (SET_DEST (set), SET_SRC (set));
11622 /* The optimizer does not know that the call sets the function value
11623 registers we stored in the result block. We avoid problems by
11624 claiming that all hard registers are used and clobbered at this
11626 emit_insn (gen_blockage ());
11631 ;; Prologue and epilogue instructions
11633 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11634 ;; all of memory. This blocks insns from being moved across this point.
11636 (define_insn "blockage"
11637 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11640 [(set_attr "length" "0")])
11642 ;; Do not schedule instructions accessing memory across this point.
11644 (define_expand "memory_blockage"
11645 [(set (match_dup 0)
11646 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11649 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11650 MEM_VOLATILE_P (operands[0]) = 1;
11653 (define_insn "*memory_blockage"
11654 [(set (match_operand:BLK 0 "" "")
11655 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11658 [(set_attr "length" "0")])
11660 ;; As USE insns aren't meaningful after reload, this is used instead
11661 ;; to prevent deleting instructions setting registers for PIC code
11662 (define_insn "prologue_use"
11663 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11666 [(set_attr "length" "0")])
11668 ;; Insn emitted into the body of a function to return from a function.
11669 ;; This is only done if the function's epilogue is known to be simple.
11670 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11672 (define_expand "return"
11674 "ix86_can_use_return_insn_p ()"
11676 ix86_maybe_emit_epilogue_vzeroupper ();
11677 if (crtl->args.pops_args)
11679 rtx popc = GEN_INT (crtl->args.pops_args);
11680 emit_jump_insn (gen_simple_return_pop_internal (popc));
11685 ;; We need to disable this for TARGET_SEH, as otherwise
11686 ;; shrink-wrapped prologue gets enabled too. This might exceed
11687 ;; the maximum size of prologue in unwind information.
11689 (define_expand "simple_return"
11693 ix86_maybe_emit_epilogue_vzeroupper ();
11694 if (crtl->args.pops_args)
11696 rtx popc = GEN_INT (crtl->args.pops_args);
11697 emit_jump_insn (gen_simple_return_pop_internal (popc));
11702 (define_insn "simple_return_internal"
11706 [(set_attr "length" "1")
11707 (set_attr "atom_unit" "jeu")
11708 (set_attr "length_immediate" "0")
11709 (set_attr "modrm" "0")])
11711 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11712 ;; instruction Athlon and K8 have.
11714 (define_insn "simple_return_internal_long"
11716 (unspec [(const_int 0)] UNSPEC_REP)]
11719 [(set_attr "length" "2")
11720 (set_attr "atom_unit" "jeu")
11721 (set_attr "length_immediate" "0")
11722 (set_attr "prefix_rep" "1")
11723 (set_attr "modrm" "0")])
11725 (define_insn "simple_return_pop_internal"
11727 (use (match_operand:SI 0 "const_int_operand" ""))]
11730 [(set_attr "length" "3")
11731 (set_attr "atom_unit" "jeu")
11732 (set_attr "length_immediate" "2")
11733 (set_attr "modrm" "0")])
11735 (define_insn "simple_return_indirect_internal"
11737 (use (match_operand:SI 0 "register_operand" "r"))]
11740 [(set_attr "type" "ibr")
11741 (set_attr "length_immediate" "0")])
11747 [(set_attr "length" "1")
11748 (set_attr "length_immediate" "0")
11749 (set_attr "modrm" "0")])
11751 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11752 (define_insn "nops"
11753 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11757 int num = INTVAL (operands[0]);
11759 gcc_assert (num >= 1 && num <= 8);
11762 fputs ("\tnop\n", asm_out_file);
11766 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11767 (set_attr "length_immediate" "0")
11768 (set_attr "modrm" "0")])
11770 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11771 ;; branch prediction penalty for the third jump in a 16-byte
11775 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11778 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11779 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11781 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11782 The align insn is used to avoid 3 jump instructions in the row to improve
11783 branch prediction and the benefits hardly outweigh the cost of extra 8
11784 nops on the average inserted by full alignment pseudo operation. */
11788 [(set_attr "length" "16")])
11790 (define_expand "prologue"
11793 "ix86_expand_prologue (); DONE;")
11795 (define_insn "set_got"
11796 [(set (match_operand:SI 0 "register_operand" "=r")
11797 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11798 (clobber (reg:CC FLAGS_REG))]
11800 "* return output_set_got (operands[0], NULL_RTX);"
11801 [(set_attr "type" "multi")
11802 (set_attr "length" "12")])
11804 (define_insn "set_got_labelled"
11805 [(set (match_operand:SI 0 "register_operand" "=r")
11806 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11808 (clobber (reg:CC FLAGS_REG))]
11810 "* return output_set_got (operands[0], operands[1]);"
11811 [(set_attr "type" "multi")
11812 (set_attr "length" "12")])
11814 (define_insn "set_got_rex64"
11815 [(set (match_operand:DI 0 "register_operand" "=r")
11816 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11818 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11819 [(set_attr "type" "lea")
11820 (set_attr "length_address" "4")
11821 (set_attr "mode" "DI")])
11823 (define_insn "set_rip_rex64"
11824 [(set (match_operand:DI 0 "register_operand" "=r")
11825 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11827 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11828 [(set_attr "type" "lea")
11829 (set_attr "length_address" "4")
11830 (set_attr "mode" "DI")])
11832 (define_insn "set_got_offset_rex64"
11833 [(set (match_operand:DI 0 "register_operand" "=r")
11835 [(label_ref (match_operand 1 "" ""))]
11836 UNSPEC_SET_GOT_OFFSET))]
11838 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11839 [(set_attr "type" "imov")
11840 (set_attr "length_immediate" "0")
11841 (set_attr "length_address" "8")
11842 (set_attr "mode" "DI")])
11844 (define_expand "epilogue"
11847 "ix86_expand_epilogue (1); DONE;")
11849 (define_expand "sibcall_epilogue"
11852 "ix86_expand_epilogue (0); DONE;")
11854 (define_expand "eh_return"
11855 [(use (match_operand 0 "register_operand" ""))]
11858 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11860 /* Tricky bit: we write the address of the handler to which we will
11861 be returning into someone else's stack frame, one word below the
11862 stack address we wish to restore. */
11863 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11864 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11865 tmp = gen_rtx_MEM (Pmode, tmp);
11866 emit_move_insn (tmp, ra);
11868 emit_jump_insn (gen_eh_return_internal ());
11873 (define_insn_and_split "eh_return_internal"
11877 "epilogue_completed"
11879 "ix86_expand_epilogue (2); DONE;")
11881 (define_insn "leave"
11882 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11883 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11884 (clobber (mem:BLK (scratch)))]
11887 [(set_attr "type" "leave")])
11889 (define_insn "leave_rex64"
11890 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11891 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11892 (clobber (mem:BLK (scratch)))]
11895 [(set_attr "type" "leave")])
11897 ;; Handle -fsplit-stack.
11899 (define_expand "split_stack_prologue"
11903 ix86_expand_split_stack_prologue ();
11907 ;; In order to support the call/return predictor, we use a return
11908 ;; instruction which the middle-end doesn't see.
11909 (define_insn "split_stack_return"
11910 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11911 UNSPECV_SPLIT_STACK_RETURN)]
11914 if (operands[0] == const0_rtx)
11919 [(set_attr "atom_unit" "jeu")
11920 (set_attr "modrm" "0")
11921 (set (attr "length")
11922 (if_then_else (match_operand:SI 0 "const0_operand" "")
11925 (set (attr "length_immediate")
11926 (if_then_else (match_operand:SI 0 "const0_operand" "")
11930 ;; If there are operand 0 bytes available on the stack, jump to
11933 (define_expand "split_stack_space_check"
11934 [(set (pc) (if_then_else
11935 (ltu (minus (reg SP_REG)
11936 (match_operand 0 "register_operand" ""))
11937 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11938 (label_ref (match_operand 1 "" ""))
11942 rtx reg, size, limit;
11944 reg = gen_reg_rtx (Pmode);
11945 size = force_reg (Pmode, operands[0]);
11946 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11947 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11948 UNSPEC_STACK_CHECK);
11949 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11950 ix86_expand_branch (GEU, reg, limit, operands[1]);
11955 ;; Bit manipulation instructions.
11957 (define_expand "ffs<mode>2"
11958 [(set (match_dup 2) (const_int -1))
11959 (parallel [(set (reg:CCZ FLAGS_REG)
11961 (match_operand:SWI48 1 "nonimmediate_operand" "")
11963 (set (match_operand:SWI48 0 "register_operand" "")
11964 (ctz:SWI48 (match_dup 1)))])
11965 (set (match_dup 0) (if_then_else:SWI48
11966 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11969 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11970 (clobber (reg:CC FLAGS_REG))])]
11973 if (<MODE>mode == SImode && !TARGET_CMOVE)
11975 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11978 operands[2] = gen_reg_rtx (<MODE>mode);
11981 (define_insn_and_split "ffssi2_no_cmove"
11982 [(set (match_operand:SI 0 "register_operand" "=r")
11983 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11984 (clobber (match_scratch:SI 2 "=&q"))
11985 (clobber (reg:CC FLAGS_REG))]
11988 "&& reload_completed"
11989 [(parallel [(set (reg:CCZ FLAGS_REG)
11990 (compare:CCZ (match_dup 1) (const_int 0)))
11991 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11992 (set (strict_low_part (match_dup 3))
11993 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11994 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11995 (clobber (reg:CC FLAGS_REG))])
11996 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11997 (clobber (reg:CC FLAGS_REG))])
11998 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11999 (clobber (reg:CC FLAGS_REG))])]
12001 operands[3] = gen_lowpart (QImode, operands[2]);
12002 ix86_expand_clear (operands[2]);
12005 (define_insn "*ffs<mode>_1"
12006 [(set (reg:CCZ FLAGS_REG)
12007 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12009 (set (match_operand:SWI48 0 "register_operand" "=r")
12010 (ctz:SWI48 (match_dup 1)))]
12012 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12013 [(set_attr "type" "alu1")
12014 (set_attr "prefix_0f" "1")
12015 (set_attr "mode" "<MODE>")])
12017 (define_insn "ctz<mode>2"
12018 [(set (match_operand:SWI248 0 "register_operand" "=r")
12019 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12020 (clobber (reg:CC FLAGS_REG))]
12024 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12026 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12028 [(set_attr "type" "alu1")
12029 (set_attr "prefix_0f" "1")
12030 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12031 (set_attr "mode" "<MODE>")])
12033 (define_expand "clz<mode>2"
12035 [(set (match_operand:SWI248 0 "register_operand" "")
12038 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12039 (clobber (reg:CC FLAGS_REG))])
12041 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12042 (clobber (reg:CC FLAGS_REG))])]
12047 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12050 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12053 (define_insn "clz<mode>2_lzcnt"
12054 [(set (match_operand:SWI248 0 "register_operand" "=r")
12055 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12056 (clobber (reg:CC FLAGS_REG))]
12058 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12059 [(set_attr "prefix_rep" "1")
12060 (set_attr "type" "bitmanip")
12061 (set_attr "mode" "<MODE>")])
12063 ;; BMI instructions.
12064 (define_insn "*bmi_andn_<mode>"
12065 [(set (match_operand:SWI48 0 "register_operand" "=r")
12068 (match_operand:SWI48 1 "register_operand" "r"))
12069 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12070 (clobber (reg:CC FLAGS_REG))]
12072 "andn\t{%2, %1, %0|%0, %1, %2}"
12073 [(set_attr "type" "bitmanip")
12074 (set_attr "mode" "<MODE>")])
12076 (define_insn "bmi_bextr_<mode>"
12077 [(set (match_operand:SWI48 0 "register_operand" "=r")
12078 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12079 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12081 (clobber (reg:CC FLAGS_REG))]
12083 "bextr\t{%2, %1, %0|%0, %1, %2}"
12084 [(set_attr "type" "bitmanip")
12085 (set_attr "mode" "<MODE>")])
12087 (define_insn "*bmi_blsi_<mode>"
12088 [(set (match_operand:SWI48 0 "register_operand" "=r")
12091 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12093 (clobber (reg:CC FLAGS_REG))]
12095 "blsi\t{%1, %0|%0, %1}"
12096 [(set_attr "type" "bitmanip")
12097 (set_attr "mode" "<MODE>")])
12099 (define_insn "*bmi_blsmsk_<mode>"
12100 [(set (match_operand:SWI48 0 "register_operand" "=r")
12103 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12106 (clobber (reg:CC FLAGS_REG))]
12108 "blsmsk\t{%1, %0|%0, %1}"
12109 [(set_attr "type" "bitmanip")
12110 (set_attr "mode" "<MODE>")])
12112 (define_insn "*bmi_blsr_<mode>"
12113 [(set (match_operand:SWI48 0 "register_operand" "=r")
12116 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12119 (clobber (reg:CC FLAGS_REG))]
12121 "blsr\t{%1, %0|%0, %1}"
12122 [(set_attr "type" "bitmanip")
12123 (set_attr "mode" "<MODE>")])
12125 ;; BMI2 instructions.
12126 (define_insn "bmi2_bzhi_<mode>3"
12127 [(set (match_operand:SWI48 0 "register_operand" "=r")
12128 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12129 (lshiftrt:SWI48 (const_int -1)
12130 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12131 (clobber (reg:CC FLAGS_REG))]
12133 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12134 [(set_attr "type" "bitmanip")
12135 (set_attr "prefix" "vex")
12136 (set_attr "mode" "<MODE>")])
12138 (define_insn "bmi2_pdep_<mode>3"
12139 [(set (match_operand:SWI48 0 "register_operand" "=r")
12140 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12141 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12144 "pdep\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_pext_<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 "pext\t{%2, %1, %0|%0, %1, %2}"
12156 [(set_attr "type" "bitmanip")
12157 (set_attr "prefix" "vex")
12158 (set_attr "mode" "<MODE>")])
12160 ;; TBM instructions.
12161 (define_insn "tbm_bextri_<mode>"
12162 [(set (match_operand:SWI48 0 "register_operand" "=r")
12163 (zero_extract:SWI48
12164 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12165 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12166 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12167 (clobber (reg:CC FLAGS_REG))]
12170 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12171 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12173 [(set_attr "type" "bitmanip")
12174 (set_attr "mode" "<MODE>")])
12176 (define_insn "*tbm_blcfill_<mode>"
12177 [(set (match_operand:SWI48 0 "register_operand" "=r")
12180 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12183 (clobber (reg:CC FLAGS_REG))]
12185 "blcfill\t{%1, %0|%0, %1}"
12186 [(set_attr "type" "bitmanip")
12187 (set_attr "mode" "<MODE>")])
12189 (define_insn "*tbm_blci_<mode>"
12190 [(set (match_operand:SWI48 0 "register_operand" "=r")
12194 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12197 (clobber (reg:CC FLAGS_REG))]
12199 "blci\t{%1, %0|%0, %1}"
12200 [(set_attr "type" "bitmanip")
12201 (set_attr "mode" "<MODE>")])
12203 (define_insn "*tbm_blcic_<mode>"
12204 [(set (match_operand:SWI48 0 "register_operand" "=r")
12207 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12211 (clobber (reg:CC FLAGS_REG))]
12213 "blcic\t{%1, %0|%0, %1}"
12214 [(set_attr "type" "bitmanip")
12215 (set_attr "mode" "<MODE>")])
12217 (define_insn "*tbm_blcmsk_<mode>"
12218 [(set (match_operand:SWI48 0 "register_operand" "=r")
12221 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12224 (clobber (reg:CC FLAGS_REG))]
12226 "blcmsk\t{%1, %0|%0, %1}"
12227 [(set_attr "type" "bitmanip")
12228 (set_attr "mode" "<MODE>")])
12230 (define_insn "*tbm_blcs_<mode>"
12231 [(set (match_operand:SWI48 0 "register_operand" "=r")
12234 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12237 (clobber (reg:CC FLAGS_REG))]
12239 "blcs\t{%1, %0|%0, %1}"
12240 [(set_attr "type" "bitmanip")
12241 (set_attr "mode" "<MODE>")])
12243 (define_insn "*tbm_blsfill_<mode>"
12244 [(set (match_operand:SWI48 0 "register_operand" "=r")
12247 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12250 (clobber (reg:CC FLAGS_REG))]
12252 "blsfill\t{%1, %0|%0, %1}"
12253 [(set_attr "type" "bitmanip")
12254 (set_attr "mode" "<MODE>")])
12256 (define_insn "*tbm_blsic_<mode>"
12257 [(set (match_operand:SWI48 0 "register_operand" "=r")
12260 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12264 (clobber (reg:CC FLAGS_REG))]
12266 "blsic\t{%1, %0|%0, %1}"
12267 [(set_attr "type" "bitmanip")
12268 (set_attr "mode" "<MODE>")])
12270 (define_insn "*tbm_t1mskc_<mode>"
12271 [(set (match_operand:SWI48 0 "register_operand" "=r")
12274 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12278 (clobber (reg:CC FLAGS_REG))]
12280 "t1mskc\t{%1, %0|%0, %1}"
12281 [(set_attr "type" "bitmanip")
12282 (set_attr "mode" "<MODE>")])
12284 (define_insn "*tbm_tzmsk_<mode>"
12285 [(set (match_operand:SWI48 0 "register_operand" "=r")
12288 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12292 (clobber (reg:CC FLAGS_REG))]
12294 "tzmsk\t{%1, %0|%0, %1}"
12295 [(set_attr "type" "bitmanip")
12296 (set_attr "mode" "<MODE>")])
12298 (define_insn "bsr_rex64"
12299 [(set (match_operand:DI 0 "register_operand" "=r")
12300 (minus:DI (const_int 63)
12301 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12302 (clobber (reg:CC FLAGS_REG))]
12304 "bsr{q}\t{%1, %0|%0, %1}"
12305 [(set_attr "type" "alu1")
12306 (set_attr "prefix_0f" "1")
12307 (set_attr "mode" "DI")])
12310 [(set (match_operand:SI 0 "register_operand" "=r")
12311 (minus:SI (const_int 31)
12312 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12313 (clobber (reg:CC FLAGS_REG))]
12315 "bsr{l}\t{%1, %0|%0, %1}"
12316 [(set_attr "type" "alu1")
12317 (set_attr "prefix_0f" "1")
12318 (set_attr "mode" "SI")])
12320 (define_insn "*bsrhi"
12321 [(set (match_operand:HI 0 "register_operand" "=r")
12322 (minus:HI (const_int 15)
12323 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12324 (clobber (reg:CC FLAGS_REG))]
12326 "bsr{w}\t{%1, %0|%0, %1}"
12327 [(set_attr "type" "alu1")
12328 (set_attr "prefix_0f" "1")
12329 (set_attr "mode" "HI")])
12331 (define_insn "popcount<mode>2"
12332 [(set (match_operand:SWI248 0 "register_operand" "=r")
12334 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12335 (clobber (reg:CC FLAGS_REG))]
12339 return "popcnt\t{%1, %0|%0, %1}";
12341 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12344 [(set_attr "prefix_rep" "1")
12345 (set_attr "type" "bitmanip")
12346 (set_attr "mode" "<MODE>")])
12348 (define_insn "*popcount<mode>2_cmp"
12349 [(set (reg FLAGS_REG)
12352 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12354 (set (match_operand:SWI248 0 "register_operand" "=r")
12355 (popcount:SWI248 (match_dup 1)))]
12356 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12359 return "popcnt\t{%1, %0|%0, %1}";
12361 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12364 [(set_attr "prefix_rep" "1")
12365 (set_attr "type" "bitmanip")
12366 (set_attr "mode" "<MODE>")])
12368 (define_insn "*popcountsi2_cmp_zext"
12369 [(set (reg FLAGS_REG)
12371 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12373 (set (match_operand:DI 0 "register_operand" "=r")
12374 (zero_extend:DI(popcount:SI (match_dup 1))))]
12375 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12378 return "popcnt\t{%1, %0|%0, %1}";
12380 return "popcnt{l}\t{%1, %0|%0, %1}";
12383 [(set_attr "prefix_rep" "1")
12384 (set_attr "type" "bitmanip")
12385 (set_attr "mode" "SI")])
12387 (define_expand "bswap<mode>2"
12388 [(set (match_operand:SWI48 0 "register_operand" "")
12389 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12392 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12394 rtx x = operands[0];
12396 emit_move_insn (x, operands[1]);
12397 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12398 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12399 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12404 (define_insn "*bswap<mode>2_movbe"
12405 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12406 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12408 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12411 movbe\t{%1, %0|%0, %1}
12412 movbe\t{%1, %0|%0, %1}"
12413 [(set_attr "type" "bitmanip,imov,imov")
12414 (set_attr "modrm" "0,1,1")
12415 (set_attr "prefix_0f" "*,1,1")
12416 (set_attr "prefix_extra" "*,1,1")
12417 (set_attr "mode" "<MODE>")])
12419 (define_insn "*bswap<mode>2_1"
12420 [(set (match_operand:SWI48 0 "register_operand" "=r")
12421 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12424 [(set_attr "type" "bitmanip")
12425 (set_attr "modrm" "0")
12426 (set_attr "mode" "<MODE>")])
12428 (define_insn "*bswaphi_lowpart_1"
12429 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12430 (bswap:HI (match_dup 0)))
12431 (clobber (reg:CC FLAGS_REG))]
12432 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12434 xchg{b}\t{%h0, %b0|%b0, %h0}
12435 rol{w}\t{$8, %0|%0, 8}"
12436 [(set_attr "length" "2,4")
12437 (set_attr "mode" "QI,HI")])
12439 (define_insn "bswaphi_lowpart"
12440 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12441 (bswap:HI (match_dup 0)))
12442 (clobber (reg:CC FLAGS_REG))]
12444 "rol{w}\t{$8, %0|%0, 8}"
12445 [(set_attr "length" "4")
12446 (set_attr "mode" "HI")])
12448 (define_expand "paritydi2"
12449 [(set (match_operand:DI 0 "register_operand" "")
12450 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12453 rtx scratch = gen_reg_rtx (QImode);
12456 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12457 NULL_RTX, operands[1]));
12459 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12460 gen_rtx_REG (CCmode, FLAGS_REG),
12462 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12465 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12468 rtx tmp = gen_reg_rtx (SImode);
12470 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12471 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12476 (define_expand "paritysi2"
12477 [(set (match_operand:SI 0 "register_operand" "")
12478 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12481 rtx scratch = gen_reg_rtx (QImode);
12484 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12486 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12487 gen_rtx_REG (CCmode, FLAGS_REG),
12489 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12491 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12495 (define_insn_and_split "paritydi2_cmp"
12496 [(set (reg:CC FLAGS_REG)
12497 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12499 (clobber (match_scratch:DI 0 "=r"))
12500 (clobber (match_scratch:SI 1 "=&r"))
12501 (clobber (match_scratch:HI 2 "=Q"))]
12504 "&& reload_completed"
12506 [(set (match_dup 1)
12507 (xor:SI (match_dup 1) (match_dup 4)))
12508 (clobber (reg:CC FLAGS_REG))])
12510 [(set (reg:CC FLAGS_REG)
12511 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12512 (clobber (match_dup 1))
12513 (clobber (match_dup 2))])]
12515 operands[4] = gen_lowpart (SImode, operands[3]);
12519 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12520 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12523 operands[1] = gen_highpart (SImode, operands[3]);
12526 (define_insn_and_split "paritysi2_cmp"
12527 [(set (reg:CC FLAGS_REG)
12528 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12530 (clobber (match_scratch:SI 0 "=r"))
12531 (clobber (match_scratch:HI 1 "=&Q"))]
12534 "&& reload_completed"
12536 [(set (match_dup 1)
12537 (xor:HI (match_dup 1) (match_dup 3)))
12538 (clobber (reg:CC FLAGS_REG))])
12540 [(set (reg:CC FLAGS_REG)
12541 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12542 (clobber (match_dup 1))])]
12544 operands[3] = gen_lowpart (HImode, operands[2]);
12546 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12547 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12550 (define_insn "*parityhi2_cmp"
12551 [(set (reg:CC FLAGS_REG)
12552 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12554 (clobber (match_scratch:HI 0 "=Q"))]
12556 "xor{b}\t{%h0, %b0|%b0, %h0}"
12557 [(set_attr "length" "2")
12558 (set_attr "mode" "HI")])
12561 ;; Thread-local storage patterns for ELF.
12563 ;; Note that these code sequences must appear exactly as shown
12564 ;; in order to allow linker relaxation.
12566 (define_insn "*tls_global_dynamic_32_gnu"
12567 [(set (match_operand:SI 0 "register_operand" "=a")
12569 [(match_operand:SI 1 "register_operand" "b")
12570 (match_operand:SI 2 "tls_symbolic_operand" "")
12571 (match_operand:SI 3 "constant_call_address_operand" "z")]
12573 (clobber (match_scratch:SI 4 "=d"))
12574 (clobber (match_scratch:SI 5 "=c"))
12575 (clobber (reg:CC FLAGS_REG))]
12576 "!TARGET_64BIT && TARGET_GNU_TLS"
12579 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12580 if (TARGET_SUN_TLS)
12581 #ifdef HAVE_AS_IX86_TLSGDPLT
12582 return "call\t%a2@tlsgdplt";
12584 return "call\t%p3@plt";
12586 return "call\t%P3";
12588 [(set_attr "type" "multi")
12589 (set_attr "length" "12")])
12591 (define_expand "tls_global_dynamic_32"
12593 [(set (match_operand:SI 0 "register_operand" "")
12594 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12595 (match_operand:SI 1 "tls_symbolic_operand" "")
12596 (match_operand:SI 3 "constant_call_address_operand" "")]
12598 (clobber (match_scratch:SI 4 ""))
12599 (clobber (match_scratch:SI 5 ""))
12600 (clobber (reg:CC FLAGS_REG))])])
12602 (define_insn "*tls_global_dynamic_64"
12603 [(set (match_operand:DI 0 "register_operand" "=a")
12605 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12606 (match_operand:DI 3 "" "")))
12607 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12612 fputs (ASM_BYTE "0x66\n", asm_out_file);
12614 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12615 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12616 fputs ("\trex64\n", asm_out_file);
12617 if (TARGET_SUN_TLS)
12618 return "call\t%p2@plt";
12619 return "call\t%P2";
12621 [(set_attr "type" "multi")
12622 (set (attr "length")
12623 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12625 (define_expand "tls_global_dynamic_64"
12627 [(set (match_operand:DI 0 "register_operand" "")
12629 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12631 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12634 (define_insn "*tls_local_dynamic_base_32_gnu"
12635 [(set (match_operand:SI 0 "register_operand" "=a")
12637 [(match_operand:SI 1 "register_operand" "b")
12638 (match_operand:SI 2 "constant_call_address_operand" "z")]
12639 UNSPEC_TLS_LD_BASE))
12640 (clobber (match_scratch:SI 3 "=d"))
12641 (clobber (match_scratch:SI 4 "=c"))
12642 (clobber (reg:CC FLAGS_REG))]
12643 "!TARGET_64BIT && TARGET_GNU_TLS"
12646 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12647 if (TARGET_SUN_TLS)
12648 #ifdef HAVE_AS_IX86_TLSLDMPLT
12649 return "call\t%&@tlsldmplt";
12651 return "call\t%p2@plt";
12653 return "call\t%P2";
12655 [(set_attr "type" "multi")
12656 (set_attr "length" "11")])
12658 (define_expand "tls_local_dynamic_base_32"
12660 [(set (match_operand:SI 0 "register_operand" "")
12662 [(match_operand:SI 1 "register_operand" "")
12663 (match_operand:SI 2 "constant_call_address_operand" "")]
12664 UNSPEC_TLS_LD_BASE))
12665 (clobber (match_scratch:SI 3 ""))
12666 (clobber (match_scratch:SI 4 ""))
12667 (clobber (reg:CC FLAGS_REG))])])
12669 (define_insn "*tls_local_dynamic_base_64"
12670 [(set (match_operand:DI 0 "register_operand" "=a")
12672 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12673 (match_operand:DI 2 "" "")))
12674 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12678 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12679 if (TARGET_SUN_TLS)
12680 return "call\t%p1@plt";
12681 return "call\t%P1";
12683 [(set_attr "type" "multi")
12684 (set_attr "length" "12")])
12686 (define_expand "tls_local_dynamic_base_64"
12688 [(set (match_operand:DI 0 "register_operand" "")
12690 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12692 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12694 ;; Local dynamic of a single variable is a lose. Show combine how
12695 ;; to convert that back to global dynamic.
12697 (define_insn_and_split "*tls_local_dynamic_32_once"
12698 [(set (match_operand:SI 0 "register_operand" "=a")
12700 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12701 (match_operand:SI 2 "constant_call_address_operand" "z")]
12702 UNSPEC_TLS_LD_BASE)
12703 (const:SI (unspec:SI
12704 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12706 (clobber (match_scratch:SI 4 "=d"))
12707 (clobber (match_scratch:SI 5 "=c"))
12708 (clobber (reg:CC FLAGS_REG))]
12713 [(set (match_dup 0)
12714 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12716 (clobber (match_dup 4))
12717 (clobber (match_dup 5))
12718 (clobber (reg:CC FLAGS_REG))])])
12720 ;; Segment register for the thread base ptr load
12721 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12723 ;; Load and add the thread base pointer from %<tp_seg>:0.
12724 (define_insn "*load_tp_x32"
12725 [(set (match_operand:SI 0 "register_operand" "=r")
12726 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12728 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12729 [(set_attr "type" "imov")
12730 (set_attr "modrm" "0")
12731 (set_attr "length" "7")
12732 (set_attr "memory" "load")
12733 (set_attr "imm_disp" "false")])
12735 (define_insn "*load_tp_x32_zext"
12736 [(set (match_operand:DI 0 "register_operand" "=r")
12737 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12739 "mov{l}\t{%%fs:0, %k0|%k0, 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_<mode>"
12747 [(set (match_operand:P 0 "register_operand" "=r")
12748 (unspec:P [(const_int 0)] UNSPEC_TP))]
12750 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>: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 "*add_tp_x32"
12758 [(set (match_operand:SI 0 "register_operand" "=r")
12759 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12760 (match_operand:SI 1 "register_operand" "0")))
12761 (clobber (reg:CC FLAGS_REG))]
12763 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12764 [(set_attr "type" "alu")
12765 (set_attr "modrm" "0")
12766 (set_attr "length" "7")
12767 (set_attr "memory" "load")
12768 (set_attr "imm_disp" "false")])
12770 (define_insn "*add_tp_x32_zext"
12771 [(set (match_operand:DI 0 "register_operand" "=r")
12773 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12774 (match_operand:SI 1 "register_operand" "0"))))
12775 (clobber (reg:CC FLAGS_REG))]
12777 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12778 [(set_attr "type" "alu")
12779 (set_attr "modrm" "0")
12780 (set_attr "length" "7")
12781 (set_attr "memory" "load")
12782 (set_attr "imm_disp" "false")])
12784 (define_insn "*add_tp_<mode>"
12785 [(set (match_operand:P 0 "register_operand" "=r")
12786 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12787 (match_operand:P 1 "register_operand" "0")))
12788 (clobber (reg:CC FLAGS_REG))]
12790 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12791 [(set_attr "type" "alu")
12792 (set_attr "modrm" "0")
12793 (set_attr "length" "7")
12794 (set_attr "memory" "load")
12795 (set_attr "imm_disp" "false")])
12797 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12798 ;; %rax as destination of the initial executable code sequence.
12799 (define_insn "tls_initial_exec_64_sun"
12800 [(set (match_operand:DI 0 "register_operand" "=a")
12802 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12803 UNSPEC_TLS_IE_SUN))
12804 (clobber (reg:CC FLAGS_REG))]
12805 "TARGET_64BIT && TARGET_SUN_TLS"
12808 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12809 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12811 [(set_attr "type" "multi")])
12813 ;; GNU2 TLS patterns can be split.
12815 (define_expand "tls_dynamic_gnu2_32"
12816 [(set (match_dup 3)
12817 (plus:SI (match_operand:SI 2 "register_operand" "")
12819 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12822 [(set (match_operand:SI 0 "register_operand" "")
12823 (unspec:SI [(match_dup 1) (match_dup 3)
12824 (match_dup 2) (reg:SI SP_REG)]
12826 (clobber (reg:CC FLAGS_REG))])]
12827 "!TARGET_64BIT && TARGET_GNU2_TLS"
12829 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12830 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12833 (define_insn "*tls_dynamic_gnu2_lea_32"
12834 [(set (match_operand:SI 0 "register_operand" "=r")
12835 (plus:SI (match_operand:SI 1 "register_operand" "b")
12837 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12838 UNSPEC_TLSDESC))))]
12839 "!TARGET_64BIT && TARGET_GNU2_TLS"
12840 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12841 [(set_attr "type" "lea")
12842 (set_attr "mode" "SI")
12843 (set_attr "length" "6")
12844 (set_attr "length_address" "4")])
12846 (define_insn "*tls_dynamic_gnu2_call_32"
12847 [(set (match_operand:SI 0 "register_operand" "=a")
12848 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12849 (match_operand:SI 2 "register_operand" "0")
12850 ;; we have to make sure %ebx still points to the GOT
12851 (match_operand:SI 3 "register_operand" "b")
12854 (clobber (reg:CC FLAGS_REG))]
12855 "!TARGET_64BIT && TARGET_GNU2_TLS"
12856 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12857 [(set_attr "type" "call")
12858 (set_attr "length" "2")
12859 (set_attr "length_address" "0")])
12861 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12862 [(set (match_operand:SI 0 "register_operand" "=&a")
12864 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12865 (match_operand:SI 4 "" "")
12866 (match_operand:SI 2 "register_operand" "b")
12869 (const:SI (unspec:SI
12870 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12872 (clobber (reg:CC FLAGS_REG))]
12873 "!TARGET_64BIT && TARGET_GNU2_TLS"
12876 [(set (match_dup 0) (match_dup 5))]
12878 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12879 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12882 (define_expand "tls_dynamic_gnu2_64"
12883 [(set (match_dup 2)
12884 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12887 [(set (match_operand:DI 0 "register_operand" "")
12888 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12890 (clobber (reg:CC FLAGS_REG))])]
12891 "TARGET_64BIT && TARGET_GNU2_TLS"
12893 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12894 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12897 (define_insn "*tls_dynamic_gnu2_lea_64"
12898 [(set (match_operand:DI 0 "register_operand" "=r")
12899 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12901 "TARGET_64BIT && TARGET_GNU2_TLS"
12902 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12903 [(set_attr "type" "lea")
12904 (set_attr "mode" "DI")
12905 (set_attr "length" "7")
12906 (set_attr "length_address" "4")])
12908 (define_insn "*tls_dynamic_gnu2_call_64"
12909 [(set (match_operand:DI 0 "register_operand" "=a")
12910 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12911 (match_operand:DI 2 "register_operand" "0")
12914 (clobber (reg:CC FLAGS_REG))]
12915 "TARGET_64BIT && TARGET_GNU2_TLS"
12916 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12917 [(set_attr "type" "call")
12918 (set_attr "length" "2")
12919 (set_attr "length_address" "0")])
12921 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12922 [(set (match_operand:DI 0 "register_operand" "=&a")
12924 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12925 (match_operand:DI 3 "" "")
12928 (const:DI (unspec:DI
12929 [(match_operand 1 "tls_symbolic_operand" "")]
12931 (clobber (reg:CC FLAGS_REG))]
12932 "TARGET_64BIT && TARGET_GNU2_TLS"
12935 [(set (match_dup 0) (match_dup 4))]
12937 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12938 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12941 ;; These patterns match the binary 387 instructions for addM3, subM3,
12942 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12943 ;; SFmode. The first is the normal insn, the second the same insn but
12944 ;; with one operand a conversion, and the third the same insn but with
12945 ;; the other operand a conversion. The conversion may be SFmode or
12946 ;; SImode if the target mode DFmode, but only SImode if the target mode
12949 ;; Gcc is slightly more smart about handling normal two address instructions
12950 ;; so use special patterns for add and mull.
12952 (define_insn "*fop_<mode>_comm_mixed"
12953 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12954 (match_operator:MODEF 3 "binary_fp_operator"
12955 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12956 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12957 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12958 && COMMUTATIVE_ARITH_P (operands[3])
12959 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12960 "* return output_387_binary_op (insn, operands);"
12961 [(set (attr "type")
12962 (if_then_else (eq_attr "alternative" "1,2")
12963 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12964 (const_string "ssemul")
12965 (const_string "sseadd"))
12966 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12967 (const_string "fmul")
12968 (const_string "fop"))))
12969 (set_attr "isa" "*,noavx,avx")
12970 (set_attr "prefix" "orig,orig,vex")
12971 (set_attr "mode" "<MODE>")])
12973 (define_insn "*fop_<mode>_comm_sse"
12974 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12975 (match_operator:MODEF 3 "binary_fp_operator"
12976 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12977 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12978 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12979 && COMMUTATIVE_ARITH_P (operands[3])
12980 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12981 "* return output_387_binary_op (insn, operands);"
12982 [(set (attr "type")
12983 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12984 (const_string "ssemul")
12985 (const_string "sseadd")))
12986 (set_attr "isa" "noavx,avx")
12987 (set_attr "prefix" "orig,vex")
12988 (set_attr "mode" "<MODE>")])
12990 (define_insn "*fop_<mode>_comm_i387"
12991 [(set (match_operand:MODEF 0 "register_operand" "=f")
12992 (match_operator:MODEF 3 "binary_fp_operator"
12993 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12994 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12995 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12996 && COMMUTATIVE_ARITH_P (operands[3])
12997 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12998 "* return output_387_binary_op (insn, operands);"
12999 [(set (attr "type")
13000 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13001 (const_string "fmul")
13002 (const_string "fop")))
13003 (set_attr "mode" "<MODE>")])
13005 (define_insn "*fop_<mode>_1_mixed"
13006 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13007 (match_operator:MODEF 3 "binary_fp_operator"
13008 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13009 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13010 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13011 && !COMMUTATIVE_ARITH_P (operands[3])
13012 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13013 "* return output_387_binary_op (insn, operands);"
13014 [(set (attr "type")
13015 (cond [(and (eq_attr "alternative" "2,3")
13016 (match_operand:MODEF 3 "mult_operator" ""))
13017 (const_string "ssemul")
13018 (and (eq_attr "alternative" "2,3")
13019 (match_operand:MODEF 3 "div_operator" ""))
13020 (const_string "ssediv")
13021 (eq_attr "alternative" "2,3")
13022 (const_string "sseadd")
13023 (match_operand:MODEF 3 "mult_operator" "")
13024 (const_string "fmul")
13025 (match_operand:MODEF 3 "div_operator" "")
13026 (const_string "fdiv")
13028 (const_string "fop")))
13029 (set_attr "isa" "*,*,noavx,avx")
13030 (set_attr "prefix" "orig,orig,orig,vex")
13031 (set_attr "mode" "<MODE>")])
13033 (define_insn "*rcpsf2_sse"
13034 [(set (match_operand:SF 0 "register_operand" "=x")
13035 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13038 "%vrcpss\t{%1, %d0|%d0, %1}"
13039 [(set_attr "type" "sse")
13040 (set_attr "atom_sse_attr" "rcp")
13041 (set_attr "prefix" "maybe_vex")
13042 (set_attr "mode" "SF")])
13044 (define_insn "*fop_<mode>_1_sse"
13045 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13046 (match_operator:MODEF 3 "binary_fp_operator"
13047 [(match_operand:MODEF 1 "register_operand" "0,x")
13048 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13049 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13050 && !COMMUTATIVE_ARITH_P (operands[3])"
13051 "* return output_387_binary_op (insn, operands);"
13052 [(set (attr "type")
13053 (cond [(match_operand:MODEF 3 "mult_operator" "")
13054 (const_string "ssemul")
13055 (match_operand:MODEF 3 "div_operator" "")
13056 (const_string "ssediv")
13058 (const_string "sseadd")))
13059 (set_attr "isa" "noavx,avx")
13060 (set_attr "prefix" "orig,vex")
13061 (set_attr "mode" "<MODE>")])
13063 ;; This pattern is not fully shadowed by the pattern above.
13064 (define_insn "*fop_<mode>_1_i387"
13065 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13066 (match_operator:MODEF 3 "binary_fp_operator"
13067 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13068 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13069 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13070 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13071 && !COMMUTATIVE_ARITH_P (operands[3])
13072 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13073 "* return output_387_binary_op (insn, operands);"
13074 [(set (attr "type")
13075 (cond [(match_operand:MODEF 3 "mult_operator" "")
13076 (const_string "fmul")
13077 (match_operand:MODEF 3 "div_operator" "")
13078 (const_string "fdiv")
13080 (const_string "fop")))
13081 (set_attr "mode" "<MODE>")])
13083 ;; ??? Add SSE splitters for these!
13084 (define_insn "*fop_<MODEF:mode>_2_i387"
13085 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13086 (match_operator:MODEF 3 "binary_fp_operator"
13088 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13089 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13090 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13091 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13092 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13093 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13094 [(set (attr "type")
13095 (cond [(match_operand:MODEF 3 "mult_operator" "")
13096 (const_string "fmul")
13097 (match_operand:MODEF 3 "div_operator" "")
13098 (const_string "fdiv")
13100 (const_string "fop")))
13101 (set_attr "fp_int_src" "true")
13102 (set_attr "mode" "<SWI24:MODE>")])
13104 (define_insn "*fop_<MODEF:mode>_3_i387"
13105 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13106 (match_operator:MODEF 3 "binary_fp_operator"
13107 [(match_operand:MODEF 1 "register_operand" "0,0")
13109 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13110 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13111 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13112 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13113 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13114 [(set (attr "type")
13115 (cond [(match_operand:MODEF 3 "mult_operator" "")
13116 (const_string "fmul")
13117 (match_operand:MODEF 3 "div_operator" "")
13118 (const_string "fdiv")
13120 (const_string "fop")))
13121 (set_attr "fp_int_src" "true")
13122 (set_attr "mode" "<MODE>")])
13124 (define_insn "*fop_df_4_i387"
13125 [(set (match_operand:DF 0 "register_operand" "=f,f")
13126 (match_operator:DF 3 "binary_fp_operator"
13128 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13129 (match_operand:DF 2 "register_operand" "0,f")]))]
13130 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13131 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13132 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13133 "* return output_387_binary_op (insn, operands);"
13134 [(set (attr "type")
13135 (cond [(match_operand:DF 3 "mult_operator" "")
13136 (const_string "fmul")
13137 (match_operand:DF 3 "div_operator" "")
13138 (const_string "fdiv")
13140 (const_string "fop")))
13141 (set_attr "mode" "SF")])
13143 (define_insn "*fop_df_5_i387"
13144 [(set (match_operand:DF 0 "register_operand" "=f,f")
13145 (match_operator:DF 3 "binary_fp_operator"
13146 [(match_operand:DF 1 "register_operand" "0,f")
13148 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13149 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13150 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13151 "* return output_387_binary_op (insn, operands);"
13152 [(set (attr "type")
13153 (cond [(match_operand:DF 3 "mult_operator" "")
13154 (const_string "fmul")
13155 (match_operand:DF 3 "div_operator" "")
13156 (const_string "fdiv")
13158 (const_string "fop")))
13159 (set_attr "mode" "SF")])
13161 (define_insn "*fop_df_6_i387"
13162 [(set (match_operand:DF 0 "register_operand" "=f,f")
13163 (match_operator:DF 3 "binary_fp_operator"
13165 (match_operand:SF 1 "register_operand" "0,f"))
13167 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13168 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13169 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13170 "* return output_387_binary_op (insn, operands);"
13171 [(set (attr "type")
13172 (cond [(match_operand:DF 3 "mult_operator" "")
13173 (const_string "fmul")
13174 (match_operand:DF 3 "div_operator" "")
13175 (const_string "fdiv")
13177 (const_string "fop")))
13178 (set_attr "mode" "SF")])
13180 (define_insn "*fop_xf_comm_i387"
13181 [(set (match_operand:XF 0 "register_operand" "=f")
13182 (match_operator:XF 3 "binary_fp_operator"
13183 [(match_operand:XF 1 "register_operand" "%0")
13184 (match_operand:XF 2 "register_operand" "f")]))]
13186 && COMMUTATIVE_ARITH_P (operands[3])"
13187 "* return output_387_binary_op (insn, operands);"
13188 [(set (attr "type")
13189 (if_then_else (match_operand:XF 3 "mult_operator" "")
13190 (const_string "fmul")
13191 (const_string "fop")))
13192 (set_attr "mode" "XF")])
13194 (define_insn "*fop_xf_1_i387"
13195 [(set (match_operand:XF 0 "register_operand" "=f,f")
13196 (match_operator:XF 3 "binary_fp_operator"
13197 [(match_operand:XF 1 "register_operand" "0,f")
13198 (match_operand:XF 2 "register_operand" "f,0")]))]
13200 && !COMMUTATIVE_ARITH_P (operands[3])"
13201 "* return output_387_binary_op (insn, operands);"
13202 [(set (attr "type")
13203 (cond [(match_operand:XF 3 "mult_operator" "")
13204 (const_string "fmul")
13205 (match_operand:XF 3 "div_operator" "")
13206 (const_string "fdiv")
13208 (const_string "fop")))
13209 (set_attr "mode" "XF")])
13211 (define_insn "*fop_xf_2_i387"
13212 [(set (match_operand:XF 0 "register_operand" "=f,f")
13213 (match_operator:XF 3 "binary_fp_operator"
13215 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13216 (match_operand:XF 2 "register_operand" "0,0")]))]
13217 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13218 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13219 [(set (attr "type")
13220 (cond [(match_operand:XF 3 "mult_operator" "")
13221 (const_string "fmul")
13222 (match_operand:XF 3 "div_operator" "")
13223 (const_string "fdiv")
13225 (const_string "fop")))
13226 (set_attr "fp_int_src" "true")
13227 (set_attr "mode" "<MODE>")])
13229 (define_insn "*fop_xf_3_i387"
13230 [(set (match_operand:XF 0 "register_operand" "=f,f")
13231 (match_operator:XF 3 "binary_fp_operator"
13232 [(match_operand:XF 1 "register_operand" "0,0")
13234 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13235 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13236 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13237 [(set (attr "type")
13238 (cond [(match_operand:XF 3 "mult_operator" "")
13239 (const_string "fmul")
13240 (match_operand:XF 3 "div_operator" "")
13241 (const_string "fdiv")
13243 (const_string "fop")))
13244 (set_attr "fp_int_src" "true")
13245 (set_attr "mode" "<MODE>")])
13247 (define_insn "*fop_xf_4_i387"
13248 [(set (match_operand:XF 0 "register_operand" "=f,f")
13249 (match_operator:XF 3 "binary_fp_operator"
13251 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13252 (match_operand:XF 2 "register_operand" "0,f")]))]
13254 "* return output_387_binary_op (insn, operands);"
13255 [(set (attr "type")
13256 (cond [(match_operand:XF 3 "mult_operator" "")
13257 (const_string "fmul")
13258 (match_operand:XF 3 "div_operator" "")
13259 (const_string "fdiv")
13261 (const_string "fop")))
13262 (set_attr "mode" "<MODE>")])
13264 (define_insn "*fop_xf_5_i387"
13265 [(set (match_operand:XF 0 "register_operand" "=f,f")
13266 (match_operator:XF 3 "binary_fp_operator"
13267 [(match_operand:XF 1 "register_operand" "0,f")
13269 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13271 "* return output_387_binary_op (insn, operands);"
13272 [(set (attr "type")
13273 (cond [(match_operand:XF 3 "mult_operator" "")
13274 (const_string "fmul")
13275 (match_operand:XF 3 "div_operator" "")
13276 (const_string "fdiv")
13278 (const_string "fop")))
13279 (set_attr "mode" "<MODE>")])
13281 (define_insn "*fop_xf_6_i387"
13282 [(set (match_operand:XF 0 "register_operand" "=f,f")
13283 (match_operator:XF 3 "binary_fp_operator"
13285 (match_operand:MODEF 1 "register_operand" "0,f"))
13287 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13289 "* return output_387_binary_op (insn, operands);"
13290 [(set (attr "type")
13291 (cond [(match_operand:XF 3 "mult_operator" "")
13292 (const_string "fmul")
13293 (match_operand:XF 3 "div_operator" "")
13294 (const_string "fdiv")
13296 (const_string "fop")))
13297 (set_attr "mode" "<MODE>")])
13300 [(set (match_operand 0 "register_operand" "")
13301 (match_operator 3 "binary_fp_operator"
13302 [(float (match_operand:SWI24 1 "register_operand" ""))
13303 (match_operand 2 "register_operand" "")]))]
13305 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13306 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13309 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13310 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13311 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13312 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13313 GET_MODE (operands[3]),
13316 ix86_free_from_memory (GET_MODE (operands[1]));
13321 [(set (match_operand 0 "register_operand" "")
13322 (match_operator 3 "binary_fp_operator"
13323 [(match_operand 1 "register_operand" "")
13324 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13326 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13327 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13330 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13331 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13332 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13333 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13334 GET_MODE (operands[3]),
13337 ix86_free_from_memory (GET_MODE (operands[2]));
13341 ;; FPU special functions.
13343 ;; This pattern implements a no-op XFmode truncation for
13344 ;; all fancy i386 XFmode math functions.
13346 (define_insn "truncxf<mode>2_i387_noop_unspec"
13347 [(set (match_operand:MODEF 0 "register_operand" "=f")
13348 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13349 UNSPEC_TRUNC_NOOP))]
13350 "TARGET_USE_FANCY_MATH_387"
13351 "* return output_387_reg_move (insn, operands);"
13352 [(set_attr "type" "fmov")
13353 (set_attr "mode" "<MODE>")])
13355 (define_insn "sqrtxf2"
13356 [(set (match_operand:XF 0 "register_operand" "=f")
13357 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13358 "TARGET_USE_FANCY_MATH_387"
13360 [(set_attr "type" "fpspc")
13361 (set_attr "mode" "XF")
13362 (set_attr "athlon_decode" "direct")
13363 (set_attr "amdfam10_decode" "direct")
13364 (set_attr "bdver1_decode" "direct")])
13366 (define_insn "sqrt_extend<mode>xf2_i387"
13367 [(set (match_operand:XF 0 "register_operand" "=f")
13370 (match_operand:MODEF 1 "register_operand" "0"))))]
13371 "TARGET_USE_FANCY_MATH_387"
13373 [(set_attr "type" "fpspc")
13374 (set_attr "mode" "XF")
13375 (set_attr "athlon_decode" "direct")
13376 (set_attr "amdfam10_decode" "direct")
13377 (set_attr "bdver1_decode" "direct")])
13379 (define_insn "*rsqrtsf2_sse"
13380 [(set (match_operand:SF 0 "register_operand" "=x")
13381 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13384 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13385 [(set_attr "type" "sse")
13386 (set_attr "atom_sse_attr" "rcp")
13387 (set_attr "prefix" "maybe_vex")
13388 (set_attr "mode" "SF")])
13390 (define_expand "rsqrtsf2"
13391 [(set (match_operand:SF 0 "register_operand" "")
13392 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13396 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13400 (define_insn "*sqrt<mode>2_sse"
13401 [(set (match_operand:MODEF 0 "register_operand" "=x")
13403 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13404 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13405 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13406 [(set_attr "type" "sse")
13407 (set_attr "atom_sse_attr" "sqrt")
13408 (set_attr "prefix" "maybe_vex")
13409 (set_attr "mode" "<MODE>")
13410 (set_attr "athlon_decode" "*")
13411 (set_attr "amdfam10_decode" "*")
13412 (set_attr "bdver1_decode" "*")])
13414 (define_expand "sqrt<mode>2"
13415 [(set (match_operand:MODEF 0 "register_operand" "")
13417 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13418 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13419 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13421 if (<MODE>mode == SFmode
13423 && TARGET_RECIP_SQRT
13424 && !optimize_function_for_size_p (cfun)
13425 && flag_finite_math_only && !flag_trapping_math
13426 && flag_unsafe_math_optimizations)
13428 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13432 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13434 rtx op0 = gen_reg_rtx (XFmode);
13435 rtx op1 = force_reg (<MODE>mode, operands[1]);
13437 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13438 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13443 (define_insn "fpremxf4_i387"
13444 [(set (match_operand:XF 0 "register_operand" "=f")
13445 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13446 (match_operand:XF 3 "register_operand" "1")]
13448 (set (match_operand:XF 1 "register_operand" "=u")
13449 (unspec:XF [(match_dup 2) (match_dup 3)]
13451 (set (reg:CCFP FPSR_REG)
13452 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13454 "TARGET_USE_FANCY_MATH_387"
13456 [(set_attr "type" "fpspc")
13457 (set_attr "mode" "XF")])
13459 (define_expand "fmodxf3"
13460 [(use (match_operand:XF 0 "register_operand" ""))
13461 (use (match_operand:XF 1 "general_operand" ""))
13462 (use (match_operand:XF 2 "general_operand" ""))]
13463 "TARGET_USE_FANCY_MATH_387"
13465 rtx label = gen_label_rtx ();
13467 rtx op1 = gen_reg_rtx (XFmode);
13468 rtx op2 = gen_reg_rtx (XFmode);
13470 emit_move_insn (op2, operands[2]);
13471 emit_move_insn (op1, operands[1]);
13473 emit_label (label);
13474 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13475 ix86_emit_fp_unordered_jump (label);
13476 LABEL_NUSES (label) = 1;
13478 emit_move_insn (operands[0], op1);
13482 (define_expand "fmod<mode>3"
13483 [(use (match_operand:MODEF 0 "register_operand" ""))
13484 (use (match_operand:MODEF 1 "general_operand" ""))
13485 (use (match_operand:MODEF 2 "general_operand" ""))]
13486 "TARGET_USE_FANCY_MATH_387"
13488 rtx (*gen_truncxf) (rtx, rtx);
13490 rtx label = gen_label_rtx ();
13492 rtx op1 = gen_reg_rtx (XFmode);
13493 rtx op2 = gen_reg_rtx (XFmode);
13495 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13496 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13498 emit_label (label);
13499 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13500 ix86_emit_fp_unordered_jump (label);
13501 LABEL_NUSES (label) = 1;
13503 /* Truncate the result properly for strict SSE math. */
13504 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13505 && !TARGET_MIX_SSE_I387)
13506 gen_truncxf = gen_truncxf<mode>2;
13508 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13510 emit_insn (gen_truncxf (operands[0], op1));
13514 (define_insn "fprem1xf4_i387"
13515 [(set (match_operand:XF 0 "register_operand" "=f")
13516 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13517 (match_operand:XF 3 "register_operand" "1")]
13519 (set (match_operand:XF 1 "register_operand" "=u")
13520 (unspec:XF [(match_dup 2) (match_dup 3)]
13522 (set (reg:CCFP FPSR_REG)
13523 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13525 "TARGET_USE_FANCY_MATH_387"
13527 [(set_attr "type" "fpspc")
13528 (set_attr "mode" "XF")])
13530 (define_expand "remainderxf3"
13531 [(use (match_operand:XF 0 "register_operand" ""))
13532 (use (match_operand:XF 1 "general_operand" ""))
13533 (use (match_operand:XF 2 "general_operand" ""))]
13534 "TARGET_USE_FANCY_MATH_387"
13536 rtx label = gen_label_rtx ();
13538 rtx op1 = gen_reg_rtx (XFmode);
13539 rtx op2 = gen_reg_rtx (XFmode);
13541 emit_move_insn (op2, operands[2]);
13542 emit_move_insn (op1, operands[1]);
13544 emit_label (label);
13545 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13546 ix86_emit_fp_unordered_jump (label);
13547 LABEL_NUSES (label) = 1;
13549 emit_move_insn (operands[0], op1);
13553 (define_expand "remainder<mode>3"
13554 [(use (match_operand:MODEF 0 "register_operand" ""))
13555 (use (match_operand:MODEF 1 "general_operand" ""))
13556 (use (match_operand:MODEF 2 "general_operand" ""))]
13557 "TARGET_USE_FANCY_MATH_387"
13559 rtx (*gen_truncxf) (rtx, rtx);
13561 rtx label = gen_label_rtx ();
13563 rtx op1 = gen_reg_rtx (XFmode);
13564 rtx op2 = gen_reg_rtx (XFmode);
13566 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13567 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13569 emit_label (label);
13571 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13572 ix86_emit_fp_unordered_jump (label);
13573 LABEL_NUSES (label) = 1;
13575 /* Truncate the result properly for strict SSE math. */
13576 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13577 && !TARGET_MIX_SSE_I387)
13578 gen_truncxf = gen_truncxf<mode>2;
13580 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13582 emit_insn (gen_truncxf (operands[0], op1));
13586 (define_insn "*sinxf2_i387"
13587 [(set (match_operand:XF 0 "register_operand" "=f")
13588 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13589 "TARGET_USE_FANCY_MATH_387
13590 && flag_unsafe_math_optimizations"
13592 [(set_attr "type" "fpspc")
13593 (set_attr "mode" "XF")])
13595 (define_insn "*sin_extend<mode>xf2_i387"
13596 [(set (match_operand:XF 0 "register_operand" "=f")
13597 (unspec:XF [(float_extend:XF
13598 (match_operand:MODEF 1 "register_operand" "0"))]
13600 "TARGET_USE_FANCY_MATH_387
13601 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13602 || TARGET_MIX_SSE_I387)
13603 && flag_unsafe_math_optimizations"
13605 [(set_attr "type" "fpspc")
13606 (set_attr "mode" "XF")])
13608 (define_insn "*cosxf2_i387"
13609 [(set (match_operand:XF 0 "register_operand" "=f")
13610 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13611 "TARGET_USE_FANCY_MATH_387
13612 && flag_unsafe_math_optimizations"
13614 [(set_attr "type" "fpspc")
13615 (set_attr "mode" "XF")])
13617 (define_insn "*cos_extend<mode>xf2_i387"
13618 [(set (match_operand:XF 0 "register_operand" "=f")
13619 (unspec:XF [(float_extend:XF
13620 (match_operand:MODEF 1 "register_operand" "0"))]
13622 "TARGET_USE_FANCY_MATH_387
13623 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13624 || TARGET_MIX_SSE_I387)
13625 && flag_unsafe_math_optimizations"
13627 [(set_attr "type" "fpspc")
13628 (set_attr "mode" "XF")])
13630 ;; When sincos pattern is defined, sin and cos builtin functions will be
13631 ;; expanded to sincos pattern with one of its outputs left unused.
13632 ;; CSE pass will figure out if two sincos patterns can be combined,
13633 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13634 ;; depending on the unused output.
13636 (define_insn "sincosxf3"
13637 [(set (match_operand:XF 0 "register_operand" "=f")
13638 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13639 UNSPEC_SINCOS_COS))
13640 (set (match_operand:XF 1 "register_operand" "=u")
13641 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13642 "TARGET_USE_FANCY_MATH_387
13643 && flag_unsafe_math_optimizations"
13645 [(set_attr "type" "fpspc")
13646 (set_attr "mode" "XF")])
13649 [(set (match_operand:XF 0 "register_operand" "")
13650 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13651 UNSPEC_SINCOS_COS))
13652 (set (match_operand:XF 1 "register_operand" "")
13653 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13654 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13655 && can_create_pseudo_p ()"
13656 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13659 [(set (match_operand:XF 0 "register_operand" "")
13660 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13661 UNSPEC_SINCOS_COS))
13662 (set (match_operand:XF 1 "register_operand" "")
13663 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13664 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13665 && can_create_pseudo_p ()"
13666 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13668 (define_insn "sincos_extend<mode>xf3_i387"
13669 [(set (match_operand:XF 0 "register_operand" "=f")
13670 (unspec:XF [(float_extend:XF
13671 (match_operand:MODEF 2 "register_operand" "0"))]
13672 UNSPEC_SINCOS_COS))
13673 (set (match_operand:XF 1 "register_operand" "=u")
13674 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13675 "TARGET_USE_FANCY_MATH_387
13676 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13677 || TARGET_MIX_SSE_I387)
13678 && flag_unsafe_math_optimizations"
13680 [(set_attr "type" "fpspc")
13681 (set_attr "mode" "XF")])
13684 [(set (match_operand:XF 0 "register_operand" "")
13685 (unspec:XF [(float_extend:XF
13686 (match_operand:MODEF 2 "register_operand" ""))]
13687 UNSPEC_SINCOS_COS))
13688 (set (match_operand:XF 1 "register_operand" "")
13689 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13690 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13691 && can_create_pseudo_p ()"
13692 [(set (match_dup 1)
13693 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13696 [(set (match_operand:XF 0 "register_operand" "")
13697 (unspec:XF [(float_extend:XF
13698 (match_operand:MODEF 2 "register_operand" ""))]
13699 UNSPEC_SINCOS_COS))
13700 (set (match_operand:XF 1 "register_operand" "")
13701 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13702 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13703 && can_create_pseudo_p ()"
13704 [(set (match_dup 0)
13705 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13707 (define_expand "sincos<mode>3"
13708 [(use (match_operand:MODEF 0 "register_operand" ""))
13709 (use (match_operand:MODEF 1 "register_operand" ""))
13710 (use (match_operand:MODEF 2 "register_operand" ""))]
13711 "TARGET_USE_FANCY_MATH_387
13712 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13713 || TARGET_MIX_SSE_I387)
13714 && flag_unsafe_math_optimizations"
13716 rtx op0 = gen_reg_rtx (XFmode);
13717 rtx op1 = gen_reg_rtx (XFmode);
13719 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13720 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13721 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13725 (define_insn "fptanxf4_i387"
13726 [(set (match_operand:XF 0 "register_operand" "=f")
13727 (match_operand:XF 3 "const_double_operand" "F"))
13728 (set (match_operand:XF 1 "register_operand" "=u")
13729 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13731 "TARGET_USE_FANCY_MATH_387
13732 && flag_unsafe_math_optimizations
13733 && standard_80387_constant_p (operands[3]) == 2"
13735 [(set_attr "type" "fpspc")
13736 (set_attr "mode" "XF")])
13738 (define_insn "fptan_extend<mode>xf4_i387"
13739 [(set (match_operand:MODEF 0 "register_operand" "=f")
13740 (match_operand:MODEF 3 "const_double_operand" "F"))
13741 (set (match_operand:XF 1 "register_operand" "=u")
13742 (unspec:XF [(float_extend:XF
13743 (match_operand:MODEF 2 "register_operand" "0"))]
13745 "TARGET_USE_FANCY_MATH_387
13746 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13747 || TARGET_MIX_SSE_I387)
13748 && flag_unsafe_math_optimizations
13749 && standard_80387_constant_p (operands[3]) == 2"
13751 [(set_attr "type" "fpspc")
13752 (set_attr "mode" "XF")])
13754 (define_expand "tanxf2"
13755 [(use (match_operand:XF 0 "register_operand" ""))
13756 (use (match_operand:XF 1 "register_operand" ""))]
13757 "TARGET_USE_FANCY_MATH_387
13758 && flag_unsafe_math_optimizations"
13760 rtx one = gen_reg_rtx (XFmode);
13761 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13763 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13767 (define_expand "tan<mode>2"
13768 [(use (match_operand:MODEF 0 "register_operand" ""))
13769 (use (match_operand:MODEF 1 "register_operand" ""))]
13770 "TARGET_USE_FANCY_MATH_387
13771 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13772 || TARGET_MIX_SSE_I387)
13773 && flag_unsafe_math_optimizations"
13775 rtx op0 = gen_reg_rtx (XFmode);
13777 rtx one = gen_reg_rtx (<MODE>mode);
13778 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13780 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13781 operands[1], op2));
13782 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13786 (define_insn "*fpatanxf3_i387"
13787 [(set (match_operand:XF 0 "register_operand" "=f")
13788 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13789 (match_operand:XF 2 "register_operand" "u")]
13791 (clobber (match_scratch:XF 3 "=2"))]
13792 "TARGET_USE_FANCY_MATH_387
13793 && flag_unsafe_math_optimizations"
13795 [(set_attr "type" "fpspc")
13796 (set_attr "mode" "XF")])
13798 (define_insn "fpatan_extend<mode>xf3_i387"
13799 [(set (match_operand:XF 0 "register_operand" "=f")
13800 (unspec:XF [(float_extend:XF
13801 (match_operand:MODEF 1 "register_operand" "0"))
13803 (match_operand:MODEF 2 "register_operand" "u"))]
13805 (clobber (match_scratch:XF 3 "=2"))]
13806 "TARGET_USE_FANCY_MATH_387
13807 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13808 || TARGET_MIX_SSE_I387)
13809 && flag_unsafe_math_optimizations"
13811 [(set_attr "type" "fpspc")
13812 (set_attr "mode" "XF")])
13814 (define_expand "atan2xf3"
13815 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13816 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13817 (match_operand:XF 1 "register_operand" "")]
13819 (clobber (match_scratch:XF 3 ""))])]
13820 "TARGET_USE_FANCY_MATH_387
13821 && flag_unsafe_math_optimizations")
13823 (define_expand "atan2<mode>3"
13824 [(use (match_operand:MODEF 0 "register_operand" ""))
13825 (use (match_operand:MODEF 1 "register_operand" ""))
13826 (use (match_operand:MODEF 2 "register_operand" ""))]
13827 "TARGET_USE_FANCY_MATH_387
13828 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13829 || TARGET_MIX_SSE_I387)
13830 && flag_unsafe_math_optimizations"
13832 rtx op0 = gen_reg_rtx (XFmode);
13834 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13835 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13839 (define_expand "atanxf2"
13840 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13841 (unspec:XF [(match_dup 2)
13842 (match_operand:XF 1 "register_operand" "")]
13844 (clobber (match_scratch:XF 3 ""))])]
13845 "TARGET_USE_FANCY_MATH_387
13846 && flag_unsafe_math_optimizations"
13848 operands[2] = gen_reg_rtx (XFmode);
13849 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13852 (define_expand "atan<mode>2"
13853 [(use (match_operand:MODEF 0 "register_operand" ""))
13854 (use (match_operand:MODEF 1 "register_operand" ""))]
13855 "TARGET_USE_FANCY_MATH_387
13856 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13857 || TARGET_MIX_SSE_I387)
13858 && flag_unsafe_math_optimizations"
13860 rtx op0 = gen_reg_rtx (XFmode);
13862 rtx op2 = gen_reg_rtx (<MODE>mode);
13863 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13865 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13866 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13870 (define_expand "asinxf2"
13871 [(set (match_dup 2)
13872 (mult:XF (match_operand:XF 1 "register_operand" "")
13874 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13875 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13876 (parallel [(set (match_operand:XF 0 "register_operand" "")
13877 (unspec:XF [(match_dup 5) (match_dup 1)]
13879 (clobber (match_scratch:XF 6 ""))])]
13880 "TARGET_USE_FANCY_MATH_387
13881 && flag_unsafe_math_optimizations"
13885 if (optimize_insn_for_size_p ())
13888 for (i = 2; i < 6; i++)
13889 operands[i] = gen_reg_rtx (XFmode);
13891 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13894 (define_expand "asin<mode>2"
13895 [(use (match_operand:MODEF 0 "register_operand" ""))
13896 (use (match_operand:MODEF 1 "general_operand" ""))]
13897 "TARGET_USE_FANCY_MATH_387
13898 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13899 || TARGET_MIX_SSE_I387)
13900 && flag_unsafe_math_optimizations"
13902 rtx op0 = gen_reg_rtx (XFmode);
13903 rtx op1 = gen_reg_rtx (XFmode);
13905 if (optimize_insn_for_size_p ())
13908 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13909 emit_insn (gen_asinxf2 (op0, op1));
13910 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13914 (define_expand "acosxf2"
13915 [(set (match_dup 2)
13916 (mult:XF (match_operand:XF 1 "register_operand" "")
13918 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13919 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13920 (parallel [(set (match_operand:XF 0 "register_operand" "")
13921 (unspec:XF [(match_dup 1) (match_dup 5)]
13923 (clobber (match_scratch:XF 6 ""))])]
13924 "TARGET_USE_FANCY_MATH_387
13925 && flag_unsafe_math_optimizations"
13929 if (optimize_insn_for_size_p ())
13932 for (i = 2; i < 6; i++)
13933 operands[i] = gen_reg_rtx (XFmode);
13935 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13938 (define_expand "acos<mode>2"
13939 [(use (match_operand:MODEF 0 "register_operand" ""))
13940 (use (match_operand:MODEF 1 "general_operand" ""))]
13941 "TARGET_USE_FANCY_MATH_387
13942 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13943 || TARGET_MIX_SSE_I387)
13944 && flag_unsafe_math_optimizations"
13946 rtx op0 = gen_reg_rtx (XFmode);
13947 rtx op1 = gen_reg_rtx (XFmode);
13949 if (optimize_insn_for_size_p ())
13952 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13953 emit_insn (gen_acosxf2 (op0, op1));
13954 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13958 (define_insn "fyl2xxf3_i387"
13959 [(set (match_operand:XF 0 "register_operand" "=f")
13960 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13961 (match_operand:XF 2 "register_operand" "u")]
13963 (clobber (match_scratch:XF 3 "=2"))]
13964 "TARGET_USE_FANCY_MATH_387
13965 && flag_unsafe_math_optimizations"
13967 [(set_attr "type" "fpspc")
13968 (set_attr "mode" "XF")])
13970 (define_insn "fyl2x_extend<mode>xf3_i387"
13971 [(set (match_operand:XF 0 "register_operand" "=f")
13972 (unspec:XF [(float_extend:XF
13973 (match_operand:MODEF 1 "register_operand" "0"))
13974 (match_operand:XF 2 "register_operand" "u")]
13976 (clobber (match_scratch:XF 3 "=2"))]
13977 "TARGET_USE_FANCY_MATH_387
13978 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13979 || TARGET_MIX_SSE_I387)
13980 && flag_unsafe_math_optimizations"
13982 [(set_attr "type" "fpspc")
13983 (set_attr "mode" "XF")])
13985 (define_expand "logxf2"
13986 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13987 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13988 (match_dup 2)] UNSPEC_FYL2X))
13989 (clobber (match_scratch:XF 3 ""))])]
13990 "TARGET_USE_FANCY_MATH_387
13991 && flag_unsafe_math_optimizations"
13993 operands[2] = gen_reg_rtx (XFmode);
13994 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13997 (define_expand "log<mode>2"
13998 [(use (match_operand:MODEF 0 "register_operand" ""))
13999 (use (match_operand:MODEF 1 "register_operand" ""))]
14000 "TARGET_USE_FANCY_MATH_387
14001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14002 || TARGET_MIX_SSE_I387)
14003 && flag_unsafe_math_optimizations"
14005 rtx op0 = gen_reg_rtx (XFmode);
14007 rtx op2 = gen_reg_rtx (XFmode);
14008 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14010 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14011 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14015 (define_expand "log10xf2"
14016 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14017 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14018 (match_dup 2)] UNSPEC_FYL2X))
14019 (clobber (match_scratch:XF 3 ""))])]
14020 "TARGET_USE_FANCY_MATH_387
14021 && flag_unsafe_math_optimizations"
14023 operands[2] = gen_reg_rtx (XFmode);
14024 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14027 (define_expand "log10<mode>2"
14028 [(use (match_operand:MODEF 0 "register_operand" ""))
14029 (use (match_operand:MODEF 1 "register_operand" ""))]
14030 "TARGET_USE_FANCY_MATH_387
14031 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14032 || TARGET_MIX_SSE_I387)
14033 && flag_unsafe_math_optimizations"
14035 rtx op0 = gen_reg_rtx (XFmode);
14037 rtx op2 = gen_reg_rtx (XFmode);
14038 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14040 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14041 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14045 (define_expand "log2xf2"
14046 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14047 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14048 (match_dup 2)] UNSPEC_FYL2X))
14049 (clobber (match_scratch:XF 3 ""))])]
14050 "TARGET_USE_FANCY_MATH_387
14051 && flag_unsafe_math_optimizations"
14053 operands[2] = gen_reg_rtx (XFmode);
14054 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14057 (define_expand "log2<mode>2"
14058 [(use (match_operand:MODEF 0 "register_operand" ""))
14059 (use (match_operand:MODEF 1 "register_operand" ""))]
14060 "TARGET_USE_FANCY_MATH_387
14061 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14062 || TARGET_MIX_SSE_I387)
14063 && flag_unsafe_math_optimizations"
14065 rtx op0 = gen_reg_rtx (XFmode);
14067 rtx op2 = gen_reg_rtx (XFmode);
14068 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14070 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14071 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14075 (define_insn "fyl2xp1xf3_i387"
14076 [(set (match_operand:XF 0 "register_operand" "=f")
14077 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14078 (match_operand:XF 2 "register_operand" "u")]
14080 (clobber (match_scratch:XF 3 "=2"))]
14081 "TARGET_USE_FANCY_MATH_387
14082 && flag_unsafe_math_optimizations"
14084 [(set_attr "type" "fpspc")
14085 (set_attr "mode" "XF")])
14087 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14088 [(set (match_operand:XF 0 "register_operand" "=f")
14089 (unspec:XF [(float_extend:XF
14090 (match_operand:MODEF 1 "register_operand" "0"))
14091 (match_operand:XF 2 "register_operand" "u")]
14093 (clobber (match_scratch:XF 3 "=2"))]
14094 "TARGET_USE_FANCY_MATH_387
14095 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14096 || TARGET_MIX_SSE_I387)
14097 && flag_unsafe_math_optimizations"
14099 [(set_attr "type" "fpspc")
14100 (set_attr "mode" "XF")])
14102 (define_expand "log1pxf2"
14103 [(use (match_operand:XF 0 "register_operand" ""))
14104 (use (match_operand:XF 1 "register_operand" ""))]
14105 "TARGET_USE_FANCY_MATH_387
14106 && flag_unsafe_math_optimizations"
14108 if (optimize_insn_for_size_p ())
14111 ix86_emit_i387_log1p (operands[0], operands[1]);
14115 (define_expand "log1p<mode>2"
14116 [(use (match_operand:MODEF 0 "register_operand" ""))
14117 (use (match_operand:MODEF 1 "register_operand" ""))]
14118 "TARGET_USE_FANCY_MATH_387
14119 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14120 || TARGET_MIX_SSE_I387)
14121 && flag_unsafe_math_optimizations"
14125 if (optimize_insn_for_size_p ())
14128 op0 = gen_reg_rtx (XFmode);
14130 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14132 ix86_emit_i387_log1p (op0, operands[1]);
14133 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14137 (define_insn "fxtractxf3_i387"
14138 [(set (match_operand:XF 0 "register_operand" "=f")
14139 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14140 UNSPEC_XTRACT_FRACT))
14141 (set (match_operand:XF 1 "register_operand" "=u")
14142 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14143 "TARGET_USE_FANCY_MATH_387
14144 && flag_unsafe_math_optimizations"
14146 [(set_attr "type" "fpspc")
14147 (set_attr "mode" "XF")])
14149 (define_insn "fxtract_extend<mode>xf3_i387"
14150 [(set (match_operand:XF 0 "register_operand" "=f")
14151 (unspec:XF [(float_extend:XF
14152 (match_operand:MODEF 2 "register_operand" "0"))]
14153 UNSPEC_XTRACT_FRACT))
14154 (set (match_operand:XF 1 "register_operand" "=u")
14155 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14156 "TARGET_USE_FANCY_MATH_387
14157 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14158 || TARGET_MIX_SSE_I387)
14159 && flag_unsafe_math_optimizations"
14161 [(set_attr "type" "fpspc")
14162 (set_attr "mode" "XF")])
14164 (define_expand "logbxf2"
14165 [(parallel [(set (match_dup 2)
14166 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14167 UNSPEC_XTRACT_FRACT))
14168 (set (match_operand:XF 0 "register_operand" "")
14169 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14170 "TARGET_USE_FANCY_MATH_387
14171 && flag_unsafe_math_optimizations"
14172 "operands[2] = gen_reg_rtx (XFmode);")
14174 (define_expand "logb<mode>2"
14175 [(use (match_operand:MODEF 0 "register_operand" ""))
14176 (use (match_operand:MODEF 1 "register_operand" ""))]
14177 "TARGET_USE_FANCY_MATH_387
14178 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14179 || TARGET_MIX_SSE_I387)
14180 && flag_unsafe_math_optimizations"
14182 rtx op0 = gen_reg_rtx (XFmode);
14183 rtx op1 = gen_reg_rtx (XFmode);
14185 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14186 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14190 (define_expand "ilogbxf2"
14191 [(use (match_operand:SI 0 "register_operand" ""))
14192 (use (match_operand:XF 1 "register_operand" ""))]
14193 "TARGET_USE_FANCY_MATH_387
14194 && flag_unsafe_math_optimizations"
14198 if (optimize_insn_for_size_p ())
14201 op0 = gen_reg_rtx (XFmode);
14202 op1 = gen_reg_rtx (XFmode);
14204 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14205 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14209 (define_expand "ilogb<mode>2"
14210 [(use (match_operand:SI 0 "register_operand" ""))
14211 (use (match_operand:MODEF 1 "register_operand" ""))]
14212 "TARGET_USE_FANCY_MATH_387
14213 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14214 || TARGET_MIX_SSE_I387)
14215 && flag_unsafe_math_optimizations"
14219 if (optimize_insn_for_size_p ())
14222 op0 = gen_reg_rtx (XFmode);
14223 op1 = gen_reg_rtx (XFmode);
14225 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14226 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14230 (define_insn "*f2xm1xf2_i387"
14231 [(set (match_operand:XF 0 "register_operand" "=f")
14232 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14234 "TARGET_USE_FANCY_MATH_387
14235 && flag_unsafe_math_optimizations"
14237 [(set_attr "type" "fpspc")
14238 (set_attr "mode" "XF")])
14240 (define_insn "*fscalexf4_i387"
14241 [(set (match_operand:XF 0 "register_operand" "=f")
14242 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14243 (match_operand:XF 3 "register_operand" "1")]
14244 UNSPEC_FSCALE_FRACT))
14245 (set (match_operand:XF 1 "register_operand" "=u")
14246 (unspec:XF [(match_dup 2) (match_dup 3)]
14247 UNSPEC_FSCALE_EXP))]
14248 "TARGET_USE_FANCY_MATH_387
14249 && flag_unsafe_math_optimizations"
14251 [(set_attr "type" "fpspc")
14252 (set_attr "mode" "XF")])
14254 (define_expand "expNcorexf3"
14255 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14256 (match_operand:XF 2 "register_operand" "")))
14257 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14258 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14259 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14260 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14261 (parallel [(set (match_operand:XF 0 "register_operand" "")
14262 (unspec:XF [(match_dup 8) (match_dup 4)]
14263 UNSPEC_FSCALE_FRACT))
14265 (unspec:XF [(match_dup 8) (match_dup 4)]
14266 UNSPEC_FSCALE_EXP))])]
14267 "TARGET_USE_FANCY_MATH_387
14268 && flag_unsafe_math_optimizations"
14272 if (optimize_insn_for_size_p ())
14275 for (i = 3; i < 10; i++)
14276 operands[i] = gen_reg_rtx (XFmode);
14278 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14281 (define_expand "expxf2"
14282 [(use (match_operand:XF 0 "register_operand" ""))
14283 (use (match_operand:XF 1 "register_operand" ""))]
14284 "TARGET_USE_FANCY_MATH_387
14285 && flag_unsafe_math_optimizations"
14289 if (optimize_insn_for_size_p ())
14292 op2 = gen_reg_rtx (XFmode);
14293 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14295 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14299 (define_expand "exp<mode>2"
14300 [(use (match_operand:MODEF 0 "register_operand" ""))
14301 (use (match_operand:MODEF 1 "general_operand" ""))]
14302 "TARGET_USE_FANCY_MATH_387
14303 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14304 || TARGET_MIX_SSE_I387)
14305 && flag_unsafe_math_optimizations"
14309 if (optimize_insn_for_size_p ())
14312 op0 = gen_reg_rtx (XFmode);
14313 op1 = gen_reg_rtx (XFmode);
14315 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14316 emit_insn (gen_expxf2 (op0, op1));
14317 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14321 (define_expand "exp10xf2"
14322 [(use (match_operand:XF 0 "register_operand" ""))
14323 (use (match_operand:XF 1 "register_operand" ""))]
14324 "TARGET_USE_FANCY_MATH_387
14325 && flag_unsafe_math_optimizations"
14329 if (optimize_insn_for_size_p ())
14332 op2 = gen_reg_rtx (XFmode);
14333 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14335 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14339 (define_expand "exp10<mode>2"
14340 [(use (match_operand:MODEF 0 "register_operand" ""))
14341 (use (match_operand:MODEF 1 "general_operand" ""))]
14342 "TARGET_USE_FANCY_MATH_387
14343 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14344 || TARGET_MIX_SSE_I387)
14345 && flag_unsafe_math_optimizations"
14349 if (optimize_insn_for_size_p ())
14352 op0 = gen_reg_rtx (XFmode);
14353 op1 = gen_reg_rtx (XFmode);
14355 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14356 emit_insn (gen_exp10xf2 (op0, op1));
14357 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14361 (define_expand "exp2xf2"
14362 [(use (match_operand:XF 0 "register_operand" ""))
14363 (use (match_operand:XF 1 "register_operand" ""))]
14364 "TARGET_USE_FANCY_MATH_387
14365 && flag_unsafe_math_optimizations"
14369 if (optimize_insn_for_size_p ())
14372 op2 = gen_reg_rtx (XFmode);
14373 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14375 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14379 (define_expand "exp2<mode>2"
14380 [(use (match_operand:MODEF 0 "register_operand" ""))
14381 (use (match_operand:MODEF 1 "general_operand" ""))]
14382 "TARGET_USE_FANCY_MATH_387
14383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14384 || TARGET_MIX_SSE_I387)
14385 && flag_unsafe_math_optimizations"
14389 if (optimize_insn_for_size_p ())
14392 op0 = gen_reg_rtx (XFmode);
14393 op1 = gen_reg_rtx (XFmode);
14395 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14396 emit_insn (gen_exp2xf2 (op0, op1));
14397 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14401 (define_expand "expm1xf2"
14402 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14404 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14405 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14406 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14407 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14408 (parallel [(set (match_dup 7)
14409 (unspec:XF [(match_dup 6) (match_dup 4)]
14410 UNSPEC_FSCALE_FRACT))
14412 (unspec:XF [(match_dup 6) (match_dup 4)]
14413 UNSPEC_FSCALE_EXP))])
14414 (parallel [(set (match_dup 10)
14415 (unspec:XF [(match_dup 9) (match_dup 8)]
14416 UNSPEC_FSCALE_FRACT))
14417 (set (match_dup 11)
14418 (unspec:XF [(match_dup 9) (match_dup 8)]
14419 UNSPEC_FSCALE_EXP))])
14420 (set (match_dup 12) (minus:XF (match_dup 10)
14421 (float_extend:XF (match_dup 13))))
14422 (set (match_operand:XF 0 "register_operand" "")
14423 (plus:XF (match_dup 12) (match_dup 7)))]
14424 "TARGET_USE_FANCY_MATH_387
14425 && flag_unsafe_math_optimizations"
14429 if (optimize_insn_for_size_p ())
14432 for (i = 2; i < 13; i++)
14433 operands[i] = gen_reg_rtx (XFmode);
14436 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14438 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14441 (define_expand "expm1<mode>2"
14442 [(use (match_operand:MODEF 0 "register_operand" ""))
14443 (use (match_operand:MODEF 1 "general_operand" ""))]
14444 "TARGET_USE_FANCY_MATH_387
14445 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14446 || TARGET_MIX_SSE_I387)
14447 && flag_unsafe_math_optimizations"
14451 if (optimize_insn_for_size_p ())
14454 op0 = gen_reg_rtx (XFmode);
14455 op1 = gen_reg_rtx (XFmode);
14457 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14458 emit_insn (gen_expm1xf2 (op0, op1));
14459 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14463 (define_expand "ldexpxf3"
14464 [(set (match_dup 3)
14465 (float:XF (match_operand:SI 2 "register_operand" "")))
14466 (parallel [(set (match_operand:XF 0 " register_operand" "")
14467 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14469 UNSPEC_FSCALE_FRACT))
14471 (unspec:XF [(match_dup 1) (match_dup 3)]
14472 UNSPEC_FSCALE_EXP))])]
14473 "TARGET_USE_FANCY_MATH_387
14474 && flag_unsafe_math_optimizations"
14476 if (optimize_insn_for_size_p ())
14479 operands[3] = gen_reg_rtx (XFmode);
14480 operands[4] = gen_reg_rtx (XFmode);
14483 (define_expand "ldexp<mode>3"
14484 [(use (match_operand:MODEF 0 "register_operand" ""))
14485 (use (match_operand:MODEF 1 "general_operand" ""))
14486 (use (match_operand:SI 2 "register_operand" ""))]
14487 "TARGET_USE_FANCY_MATH_387
14488 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14489 || TARGET_MIX_SSE_I387)
14490 && flag_unsafe_math_optimizations"
14494 if (optimize_insn_for_size_p ())
14497 op0 = gen_reg_rtx (XFmode);
14498 op1 = gen_reg_rtx (XFmode);
14500 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14501 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14502 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14506 (define_expand "scalbxf3"
14507 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14508 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14509 (match_operand:XF 2 "register_operand" "")]
14510 UNSPEC_FSCALE_FRACT))
14512 (unspec:XF [(match_dup 1) (match_dup 2)]
14513 UNSPEC_FSCALE_EXP))])]
14514 "TARGET_USE_FANCY_MATH_387
14515 && flag_unsafe_math_optimizations"
14517 if (optimize_insn_for_size_p ())
14520 operands[3] = gen_reg_rtx (XFmode);
14523 (define_expand "scalb<mode>3"
14524 [(use (match_operand:MODEF 0 "register_operand" ""))
14525 (use (match_operand:MODEF 1 "general_operand" ""))
14526 (use (match_operand:MODEF 2 "general_operand" ""))]
14527 "TARGET_USE_FANCY_MATH_387
14528 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14529 || TARGET_MIX_SSE_I387)
14530 && flag_unsafe_math_optimizations"
14534 if (optimize_insn_for_size_p ())
14537 op0 = gen_reg_rtx (XFmode);
14538 op1 = gen_reg_rtx (XFmode);
14539 op2 = gen_reg_rtx (XFmode);
14541 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14542 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14543 emit_insn (gen_scalbxf3 (op0, op1, op2));
14544 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14548 (define_expand "significandxf2"
14549 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14550 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14551 UNSPEC_XTRACT_FRACT))
14553 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14554 "TARGET_USE_FANCY_MATH_387
14555 && flag_unsafe_math_optimizations"
14556 "operands[2] = gen_reg_rtx (XFmode);")
14558 (define_expand "significand<mode>2"
14559 [(use (match_operand:MODEF 0 "register_operand" ""))
14560 (use (match_operand:MODEF 1 "register_operand" ""))]
14561 "TARGET_USE_FANCY_MATH_387
14562 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14563 || TARGET_MIX_SSE_I387)
14564 && flag_unsafe_math_optimizations"
14566 rtx op0 = gen_reg_rtx (XFmode);
14567 rtx op1 = gen_reg_rtx (XFmode);
14569 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14570 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14575 (define_insn "sse4_1_round<mode>2"
14576 [(set (match_operand:MODEF 0 "register_operand" "=x")
14577 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14578 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14581 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14582 [(set_attr "type" "ssecvt")
14583 (set_attr "prefix_extra" "1")
14584 (set_attr "prefix" "maybe_vex")
14585 (set_attr "mode" "<MODE>")])
14587 (define_insn "rintxf2"
14588 [(set (match_operand:XF 0 "register_operand" "=f")
14589 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14591 "TARGET_USE_FANCY_MATH_387
14592 && flag_unsafe_math_optimizations"
14594 [(set_attr "type" "fpspc")
14595 (set_attr "mode" "XF")])
14597 (define_expand "rint<mode>2"
14598 [(use (match_operand:MODEF 0 "register_operand" ""))
14599 (use (match_operand:MODEF 1 "register_operand" ""))]
14600 "(TARGET_USE_FANCY_MATH_387
14601 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14602 || TARGET_MIX_SSE_I387)
14603 && flag_unsafe_math_optimizations)
14604 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14605 && !flag_trapping_math)"
14607 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14608 && !flag_trapping_math)
14611 emit_insn (gen_sse4_1_round<mode>2
14612 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14613 else if (optimize_insn_for_size_p ())
14616 ix86_expand_rint (operands[0], operands[1]);
14620 rtx op0 = gen_reg_rtx (XFmode);
14621 rtx op1 = gen_reg_rtx (XFmode);
14623 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14624 emit_insn (gen_rintxf2 (op0, op1));
14626 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14631 (define_expand "round<mode>2"
14632 [(match_operand:X87MODEF 0 "register_operand" "")
14633 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14634 "(TARGET_USE_FANCY_MATH_387
14635 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14636 || TARGET_MIX_SSE_I387)
14637 && flag_unsafe_math_optimizations)
14638 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14639 && !flag_trapping_math && !flag_rounding_math)"
14641 if (optimize_insn_for_size_p ())
14644 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14645 && !flag_trapping_math && !flag_rounding_math)
14649 operands[1] = force_reg (<MODE>mode, operands[1]);
14650 ix86_expand_round_sse4 (operands[0], operands[1]);
14652 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14653 ix86_expand_round (operands[0], operands[1]);
14655 ix86_expand_rounddf_32 (operands[0], operands[1]);
14659 operands[1] = force_reg (<MODE>mode, operands[1]);
14660 ix86_emit_i387_round (operands[0], operands[1]);
14665 (define_insn_and_split "*fistdi2_1"
14666 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14667 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14669 "TARGET_USE_FANCY_MATH_387
14670 && can_create_pseudo_p ()"
14675 if (memory_operand (operands[0], VOIDmode))
14676 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14679 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14680 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14685 [(set_attr "type" "fpspc")
14686 (set_attr "mode" "DI")])
14688 (define_insn "fistdi2"
14689 [(set (match_operand:DI 0 "memory_operand" "=m")
14690 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14692 (clobber (match_scratch:XF 2 "=&1f"))]
14693 "TARGET_USE_FANCY_MATH_387"
14694 "* return output_fix_trunc (insn, operands, false);"
14695 [(set_attr "type" "fpspc")
14696 (set_attr "mode" "DI")])
14698 (define_insn "fistdi2_with_temp"
14699 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14700 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14702 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14703 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14704 "TARGET_USE_FANCY_MATH_387"
14706 [(set_attr "type" "fpspc")
14707 (set_attr "mode" "DI")])
14710 [(set (match_operand:DI 0 "register_operand" "")
14711 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14713 (clobber (match_operand:DI 2 "memory_operand" ""))
14714 (clobber (match_scratch 3 ""))]
14716 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14717 (clobber (match_dup 3))])
14718 (set (match_dup 0) (match_dup 2))])
14721 [(set (match_operand:DI 0 "memory_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 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14728 (clobber (match_dup 3))])])
14730 (define_insn_and_split "*fist<mode>2_1"
14731 [(set (match_operand:SWI24 0 "register_operand" "")
14732 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14734 "TARGET_USE_FANCY_MATH_387
14735 && can_create_pseudo_p ()"
14740 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14741 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14745 [(set_attr "type" "fpspc")
14746 (set_attr "mode" "<MODE>")])
14748 (define_insn "fist<mode>2"
14749 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14750 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14752 "TARGET_USE_FANCY_MATH_387"
14753 "* return output_fix_trunc (insn, operands, false);"
14754 [(set_attr "type" "fpspc")
14755 (set_attr "mode" "<MODE>")])
14757 (define_insn "fist<mode>2_with_temp"
14758 [(set (match_operand:SWI24 0 "register_operand" "=r")
14759 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14761 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14762 "TARGET_USE_FANCY_MATH_387"
14764 [(set_attr "type" "fpspc")
14765 (set_attr "mode" "<MODE>")])
14768 [(set (match_operand:SWI24 0 "register_operand" "")
14769 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14771 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14773 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14774 (set (match_dup 0) (match_dup 2))])
14777 [(set (match_operand:SWI24 0 "memory_operand" "")
14778 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14780 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14782 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14784 (define_expand "lrintxf<mode>2"
14785 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14786 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14788 "TARGET_USE_FANCY_MATH_387")
14790 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14791 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14792 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14793 UNSPEC_FIX_NOTRUNC))]
14794 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14795 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14797 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14798 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14799 (match_operand:X87MODEF 1 "register_operand" "")]
14800 "(TARGET_USE_FANCY_MATH_387
14801 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14802 || TARGET_MIX_SSE_I387)
14803 && flag_unsafe_math_optimizations)
14804 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14805 && <SWI248x:MODE>mode != HImode
14806 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14807 && !flag_trapping_math && !flag_rounding_math)"
14809 if (optimize_insn_for_size_p ())
14812 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14813 && <SWI248x:MODE>mode != HImode
14814 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14815 && !flag_trapping_math && !flag_rounding_math)
14816 ix86_expand_lround (operands[0], operands[1]);
14818 ix86_emit_i387_round (operands[0], operands[1]);
14822 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14823 (define_insn_and_split "frndintxf2_floor"
14824 [(set (match_operand:XF 0 "register_operand" "")
14825 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14826 UNSPEC_FRNDINT_FLOOR))
14827 (clobber (reg:CC FLAGS_REG))]
14828 "TARGET_USE_FANCY_MATH_387
14829 && flag_unsafe_math_optimizations
14830 && can_create_pseudo_p ()"
14835 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14837 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14838 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14840 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14841 operands[2], operands[3]));
14844 [(set_attr "type" "frndint")
14845 (set_attr "i387_cw" "floor")
14846 (set_attr "mode" "XF")])
14848 (define_insn "frndintxf2_floor_i387"
14849 [(set (match_operand:XF 0 "register_operand" "=f")
14850 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14851 UNSPEC_FRNDINT_FLOOR))
14852 (use (match_operand:HI 2 "memory_operand" "m"))
14853 (use (match_operand:HI 3 "memory_operand" "m"))]
14854 "TARGET_USE_FANCY_MATH_387
14855 && flag_unsafe_math_optimizations"
14856 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14857 [(set_attr "type" "frndint")
14858 (set_attr "i387_cw" "floor")
14859 (set_attr "mode" "XF")])
14861 (define_expand "floorxf2"
14862 [(use (match_operand:XF 0 "register_operand" ""))
14863 (use (match_operand:XF 1 "register_operand" ""))]
14864 "TARGET_USE_FANCY_MATH_387
14865 && flag_unsafe_math_optimizations"
14867 if (optimize_insn_for_size_p ())
14869 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14873 (define_expand "floor<mode>2"
14874 [(use (match_operand:MODEF 0 "register_operand" ""))
14875 (use (match_operand:MODEF 1 "register_operand" ""))]
14876 "(TARGET_USE_FANCY_MATH_387
14877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14878 || TARGET_MIX_SSE_I387)
14879 && flag_unsafe_math_optimizations)
14880 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14881 && !flag_trapping_math)"
14883 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14884 && !flag_trapping_math)
14887 emit_insn (gen_sse4_1_round<mode>2
14888 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14889 else if (optimize_insn_for_size_p ())
14891 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14892 ix86_expand_floorceil (operands[0], operands[1], true);
14894 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14900 if (optimize_insn_for_size_p ())
14903 op0 = gen_reg_rtx (XFmode);
14904 op1 = gen_reg_rtx (XFmode);
14905 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14906 emit_insn (gen_frndintxf2_floor (op0, op1));
14908 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14913 (define_insn_and_split "*fist<mode>2_floor_1"
14914 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14915 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14916 UNSPEC_FIST_FLOOR))
14917 (clobber (reg:CC FLAGS_REG))]
14918 "TARGET_USE_FANCY_MATH_387
14919 && flag_unsafe_math_optimizations
14920 && can_create_pseudo_p ()"
14925 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14927 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14928 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14929 if (memory_operand (operands[0], VOIDmode))
14930 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14931 operands[2], operands[3]));
14934 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14935 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14936 operands[2], operands[3],
14941 [(set_attr "type" "fistp")
14942 (set_attr "i387_cw" "floor")
14943 (set_attr "mode" "<MODE>")])
14945 (define_insn "fistdi2_floor"
14946 [(set (match_operand:DI 0 "memory_operand" "=m")
14947 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14948 UNSPEC_FIST_FLOOR))
14949 (use (match_operand:HI 2 "memory_operand" "m"))
14950 (use (match_operand:HI 3 "memory_operand" "m"))
14951 (clobber (match_scratch:XF 4 "=&1f"))]
14952 "TARGET_USE_FANCY_MATH_387
14953 && flag_unsafe_math_optimizations"
14954 "* return output_fix_trunc (insn, operands, false);"
14955 [(set_attr "type" "fistp")
14956 (set_attr "i387_cw" "floor")
14957 (set_attr "mode" "DI")])
14959 (define_insn "fistdi2_floor_with_temp"
14960 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14961 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14962 UNSPEC_FIST_FLOOR))
14963 (use (match_operand:HI 2 "memory_operand" "m,m"))
14964 (use (match_operand:HI 3 "memory_operand" "m,m"))
14965 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14966 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14967 "TARGET_USE_FANCY_MATH_387
14968 && flag_unsafe_math_optimizations"
14970 [(set_attr "type" "fistp")
14971 (set_attr "i387_cw" "floor")
14972 (set_attr "mode" "DI")])
14975 [(set (match_operand:DI 0 "register_operand" "")
14976 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14977 UNSPEC_FIST_FLOOR))
14978 (use (match_operand:HI 2 "memory_operand" ""))
14979 (use (match_operand:HI 3 "memory_operand" ""))
14980 (clobber (match_operand:DI 4 "memory_operand" ""))
14981 (clobber (match_scratch 5 ""))]
14983 [(parallel [(set (match_dup 4)
14984 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14985 (use (match_dup 2))
14986 (use (match_dup 3))
14987 (clobber (match_dup 5))])
14988 (set (match_dup 0) (match_dup 4))])
14991 [(set (match_operand:DI 0 "memory_operand" "")
14992 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14993 UNSPEC_FIST_FLOOR))
14994 (use (match_operand:HI 2 "memory_operand" ""))
14995 (use (match_operand:HI 3 "memory_operand" ""))
14996 (clobber (match_operand:DI 4 "memory_operand" ""))
14997 (clobber (match_scratch 5 ""))]
14999 [(parallel [(set (match_dup 0)
15000 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15001 (use (match_dup 2))
15002 (use (match_dup 3))
15003 (clobber (match_dup 5))])])
15005 (define_insn "fist<mode>2_floor"
15006 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15007 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15008 UNSPEC_FIST_FLOOR))
15009 (use (match_operand:HI 2 "memory_operand" "m"))
15010 (use (match_operand:HI 3 "memory_operand" "m"))]
15011 "TARGET_USE_FANCY_MATH_387
15012 && flag_unsafe_math_optimizations"
15013 "* return output_fix_trunc (insn, operands, false);"
15014 [(set_attr "type" "fistp")
15015 (set_attr "i387_cw" "floor")
15016 (set_attr "mode" "<MODE>")])
15018 (define_insn "fist<mode>2_floor_with_temp"
15019 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15020 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15021 UNSPEC_FIST_FLOOR))
15022 (use (match_operand:HI 2 "memory_operand" "m,m"))
15023 (use (match_operand:HI 3 "memory_operand" "m,m"))
15024 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15025 "TARGET_USE_FANCY_MATH_387
15026 && flag_unsafe_math_optimizations"
15028 [(set_attr "type" "fistp")
15029 (set_attr "i387_cw" "floor")
15030 (set_attr "mode" "<MODE>")])
15033 [(set (match_operand:SWI24 0 "register_operand" "")
15034 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15035 UNSPEC_FIST_FLOOR))
15036 (use (match_operand:HI 2 "memory_operand" ""))
15037 (use (match_operand:HI 3 "memory_operand" ""))
15038 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15040 [(parallel [(set (match_dup 4)
15041 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15042 (use (match_dup 2))
15043 (use (match_dup 3))])
15044 (set (match_dup 0) (match_dup 4))])
15047 [(set (match_operand:SWI24 0 "memory_operand" "")
15048 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15049 UNSPEC_FIST_FLOOR))
15050 (use (match_operand:HI 2 "memory_operand" ""))
15051 (use (match_operand:HI 3 "memory_operand" ""))
15052 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15054 [(parallel [(set (match_dup 0)
15055 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15056 (use (match_dup 2))
15057 (use (match_dup 3))])])
15059 (define_expand "lfloorxf<mode>2"
15060 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15061 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15062 UNSPEC_FIST_FLOOR))
15063 (clobber (reg:CC FLAGS_REG))])]
15064 "TARGET_USE_FANCY_MATH_387
15065 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15066 && flag_unsafe_math_optimizations")
15068 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15069 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15070 (match_operand:MODEF 1 "register_operand" "")]
15071 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15072 && !flag_trapping_math"
15074 if (TARGET_64BIT && optimize_insn_for_size_p ())
15076 ix86_expand_lfloorceil (operands[0], operands[1], true);
15080 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15081 (define_insn_and_split "frndintxf2_ceil"
15082 [(set (match_operand:XF 0 "register_operand" "")
15083 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15084 UNSPEC_FRNDINT_CEIL))
15085 (clobber (reg:CC FLAGS_REG))]
15086 "TARGET_USE_FANCY_MATH_387
15087 && flag_unsafe_math_optimizations
15088 && can_create_pseudo_p ()"
15093 ix86_optimize_mode_switching[I387_CEIL] = 1;
15095 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15096 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15098 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15099 operands[2], operands[3]));
15102 [(set_attr "type" "frndint")
15103 (set_attr "i387_cw" "ceil")
15104 (set_attr "mode" "XF")])
15106 (define_insn "frndintxf2_ceil_i387"
15107 [(set (match_operand:XF 0 "register_operand" "=f")
15108 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15109 UNSPEC_FRNDINT_CEIL))
15110 (use (match_operand:HI 2 "memory_operand" "m"))
15111 (use (match_operand:HI 3 "memory_operand" "m"))]
15112 "TARGET_USE_FANCY_MATH_387
15113 && flag_unsafe_math_optimizations"
15114 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15115 [(set_attr "type" "frndint")
15116 (set_attr "i387_cw" "ceil")
15117 (set_attr "mode" "XF")])
15119 (define_expand "ceilxf2"
15120 [(use (match_operand:XF 0 "register_operand" ""))
15121 (use (match_operand:XF 1 "register_operand" ""))]
15122 "TARGET_USE_FANCY_MATH_387
15123 && flag_unsafe_math_optimizations"
15125 if (optimize_insn_for_size_p ())
15127 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15131 (define_expand "ceil<mode>2"
15132 [(use (match_operand:MODEF 0 "register_operand" ""))
15133 (use (match_operand:MODEF 1 "register_operand" ""))]
15134 "(TARGET_USE_FANCY_MATH_387
15135 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15136 || TARGET_MIX_SSE_I387)
15137 && flag_unsafe_math_optimizations)
15138 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15139 && !flag_trapping_math)"
15141 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15142 && !flag_trapping_math)
15145 emit_insn (gen_sse4_1_round<mode>2
15146 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15147 else if (optimize_insn_for_size_p ())
15149 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15150 ix86_expand_floorceil (operands[0], operands[1], false);
15152 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15158 if (optimize_insn_for_size_p ())
15161 op0 = gen_reg_rtx (XFmode);
15162 op1 = gen_reg_rtx (XFmode);
15163 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15164 emit_insn (gen_frndintxf2_ceil (op0, op1));
15166 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15171 (define_insn_and_split "*fist<mode>2_ceil_1"
15172 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15173 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15175 (clobber (reg:CC FLAGS_REG))]
15176 "TARGET_USE_FANCY_MATH_387
15177 && flag_unsafe_math_optimizations
15178 && can_create_pseudo_p ()"
15183 ix86_optimize_mode_switching[I387_CEIL] = 1;
15185 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15186 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15187 if (memory_operand (operands[0], VOIDmode))
15188 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15189 operands[2], operands[3]));
15192 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15193 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15194 operands[2], operands[3],
15199 [(set_attr "type" "fistp")
15200 (set_attr "i387_cw" "ceil")
15201 (set_attr "mode" "<MODE>")])
15203 (define_insn "fistdi2_ceil"
15204 [(set (match_operand:DI 0 "memory_operand" "=m")
15205 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15207 (use (match_operand:HI 2 "memory_operand" "m"))
15208 (use (match_operand:HI 3 "memory_operand" "m"))
15209 (clobber (match_scratch:XF 4 "=&1f"))]
15210 "TARGET_USE_FANCY_MATH_387
15211 && flag_unsafe_math_optimizations"
15212 "* return output_fix_trunc (insn, operands, false);"
15213 [(set_attr "type" "fistp")
15214 (set_attr "i387_cw" "ceil")
15215 (set_attr "mode" "DI")])
15217 (define_insn "fistdi2_ceil_with_temp"
15218 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15219 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15221 (use (match_operand:HI 2 "memory_operand" "m,m"))
15222 (use (match_operand:HI 3 "memory_operand" "m,m"))
15223 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15224 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15225 "TARGET_USE_FANCY_MATH_387
15226 && flag_unsafe_math_optimizations"
15228 [(set_attr "type" "fistp")
15229 (set_attr "i387_cw" "ceil")
15230 (set_attr "mode" "DI")])
15233 [(set (match_operand:DI 0 "register_operand" "")
15234 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15236 (use (match_operand:HI 2 "memory_operand" ""))
15237 (use (match_operand:HI 3 "memory_operand" ""))
15238 (clobber (match_operand:DI 4 "memory_operand" ""))
15239 (clobber (match_scratch 5 ""))]
15241 [(parallel [(set (match_dup 4)
15242 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15243 (use (match_dup 2))
15244 (use (match_dup 3))
15245 (clobber (match_dup 5))])
15246 (set (match_dup 0) (match_dup 4))])
15249 [(set (match_operand:DI 0 "memory_operand" "")
15250 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15252 (use (match_operand:HI 2 "memory_operand" ""))
15253 (use (match_operand:HI 3 "memory_operand" ""))
15254 (clobber (match_operand:DI 4 "memory_operand" ""))
15255 (clobber (match_scratch 5 ""))]
15257 [(parallel [(set (match_dup 0)
15258 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15259 (use (match_dup 2))
15260 (use (match_dup 3))
15261 (clobber (match_dup 5))])])
15263 (define_insn "fist<mode>2_ceil"
15264 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15265 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15267 (use (match_operand:HI 2 "memory_operand" "m"))
15268 (use (match_operand:HI 3 "memory_operand" "m"))]
15269 "TARGET_USE_FANCY_MATH_387
15270 && flag_unsafe_math_optimizations"
15271 "* return output_fix_trunc (insn, operands, false);"
15272 [(set_attr "type" "fistp")
15273 (set_attr "i387_cw" "ceil")
15274 (set_attr "mode" "<MODE>")])
15276 (define_insn "fist<mode>2_ceil_with_temp"
15277 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15278 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15280 (use (match_operand:HI 2 "memory_operand" "m,m"))
15281 (use (match_operand:HI 3 "memory_operand" "m,m"))
15282 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15283 "TARGET_USE_FANCY_MATH_387
15284 && flag_unsafe_math_optimizations"
15286 [(set_attr "type" "fistp")
15287 (set_attr "i387_cw" "ceil")
15288 (set_attr "mode" "<MODE>")])
15291 [(set (match_operand:SWI24 0 "register_operand" "")
15292 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15294 (use (match_operand:HI 2 "memory_operand" ""))
15295 (use (match_operand:HI 3 "memory_operand" ""))
15296 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15298 [(parallel [(set (match_dup 4)
15299 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15300 (use (match_dup 2))
15301 (use (match_dup 3))])
15302 (set (match_dup 0) (match_dup 4))])
15305 [(set (match_operand:SWI24 0 "memory_operand" "")
15306 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15308 (use (match_operand:HI 2 "memory_operand" ""))
15309 (use (match_operand:HI 3 "memory_operand" ""))
15310 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15312 [(parallel [(set (match_dup 0)
15313 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15314 (use (match_dup 2))
15315 (use (match_dup 3))])])
15317 (define_expand "lceilxf<mode>2"
15318 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15319 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15321 (clobber (reg:CC FLAGS_REG))])]
15322 "TARGET_USE_FANCY_MATH_387
15323 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15324 && flag_unsafe_math_optimizations")
15326 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15327 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15328 (match_operand:MODEF 1 "register_operand" "")]
15329 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15330 && !flag_trapping_math"
15332 ix86_expand_lfloorceil (operands[0], operands[1], false);
15336 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15337 (define_insn_and_split "frndintxf2_trunc"
15338 [(set (match_operand:XF 0 "register_operand" "")
15339 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15340 UNSPEC_FRNDINT_TRUNC))
15341 (clobber (reg:CC FLAGS_REG))]
15342 "TARGET_USE_FANCY_MATH_387
15343 && flag_unsafe_math_optimizations
15344 && can_create_pseudo_p ()"
15349 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15351 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15352 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15354 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15355 operands[2], operands[3]));
15358 [(set_attr "type" "frndint")
15359 (set_attr "i387_cw" "trunc")
15360 (set_attr "mode" "XF")])
15362 (define_insn "frndintxf2_trunc_i387"
15363 [(set (match_operand:XF 0 "register_operand" "=f")
15364 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15365 UNSPEC_FRNDINT_TRUNC))
15366 (use (match_operand:HI 2 "memory_operand" "m"))
15367 (use (match_operand:HI 3 "memory_operand" "m"))]
15368 "TARGET_USE_FANCY_MATH_387
15369 && flag_unsafe_math_optimizations"
15370 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15371 [(set_attr "type" "frndint")
15372 (set_attr "i387_cw" "trunc")
15373 (set_attr "mode" "XF")])
15375 (define_expand "btruncxf2"
15376 [(use (match_operand:XF 0 "register_operand" ""))
15377 (use (match_operand:XF 1 "register_operand" ""))]
15378 "TARGET_USE_FANCY_MATH_387
15379 && flag_unsafe_math_optimizations"
15381 if (optimize_insn_for_size_p ())
15383 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15387 (define_expand "btrunc<mode>2"
15388 [(use (match_operand:MODEF 0 "register_operand" ""))
15389 (use (match_operand:MODEF 1 "register_operand" ""))]
15390 "(TARGET_USE_FANCY_MATH_387
15391 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15392 || TARGET_MIX_SSE_I387)
15393 && flag_unsafe_math_optimizations)
15394 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15395 && !flag_trapping_math)"
15397 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15398 && !flag_trapping_math)
15401 emit_insn (gen_sse4_1_round<mode>2
15402 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15403 else if (optimize_insn_for_size_p ())
15405 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15406 ix86_expand_trunc (operands[0], operands[1]);
15408 ix86_expand_truncdf_32 (operands[0], operands[1]);
15414 if (optimize_insn_for_size_p ())
15417 op0 = gen_reg_rtx (XFmode);
15418 op1 = gen_reg_rtx (XFmode);
15419 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15420 emit_insn (gen_frndintxf2_trunc (op0, op1));
15422 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15427 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15428 (define_insn_and_split "frndintxf2_mask_pm"
15429 [(set (match_operand:XF 0 "register_operand" "")
15430 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15431 UNSPEC_FRNDINT_MASK_PM))
15432 (clobber (reg:CC FLAGS_REG))]
15433 "TARGET_USE_FANCY_MATH_387
15434 && flag_unsafe_math_optimizations
15435 && can_create_pseudo_p ()"
15440 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15442 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15443 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15445 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15446 operands[2], operands[3]));
15449 [(set_attr "type" "frndint")
15450 (set_attr "i387_cw" "mask_pm")
15451 (set_attr "mode" "XF")])
15453 (define_insn "frndintxf2_mask_pm_i387"
15454 [(set (match_operand:XF 0 "register_operand" "=f")
15455 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15456 UNSPEC_FRNDINT_MASK_PM))
15457 (use (match_operand:HI 2 "memory_operand" "m"))
15458 (use (match_operand:HI 3 "memory_operand" "m"))]
15459 "TARGET_USE_FANCY_MATH_387
15460 && flag_unsafe_math_optimizations"
15461 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15462 [(set_attr "type" "frndint")
15463 (set_attr "i387_cw" "mask_pm")
15464 (set_attr "mode" "XF")])
15466 (define_expand "nearbyintxf2"
15467 [(use (match_operand:XF 0 "register_operand" ""))
15468 (use (match_operand:XF 1 "register_operand" ""))]
15469 "TARGET_USE_FANCY_MATH_387
15470 && flag_unsafe_math_optimizations"
15472 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15476 (define_expand "nearbyint<mode>2"
15477 [(use (match_operand:MODEF 0 "register_operand" ""))
15478 (use (match_operand:MODEF 1 "register_operand" ""))]
15479 "TARGET_USE_FANCY_MATH_387
15480 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15481 || TARGET_MIX_SSE_I387)
15482 && flag_unsafe_math_optimizations"
15484 rtx op0 = gen_reg_rtx (XFmode);
15485 rtx op1 = gen_reg_rtx (XFmode);
15487 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15488 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15490 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15494 (define_insn "fxam<mode>2_i387"
15495 [(set (match_operand:HI 0 "register_operand" "=a")
15497 [(match_operand:X87MODEF 1 "register_operand" "f")]
15499 "TARGET_USE_FANCY_MATH_387"
15500 "fxam\n\tfnstsw\t%0"
15501 [(set_attr "type" "multi")
15502 (set_attr "length" "4")
15503 (set_attr "unit" "i387")
15504 (set_attr "mode" "<MODE>")])
15506 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15507 [(set (match_operand:HI 0 "register_operand" "")
15509 [(match_operand:MODEF 1 "memory_operand" "")]
15511 "TARGET_USE_FANCY_MATH_387
15512 && can_create_pseudo_p ()"
15515 [(set (match_dup 2)(match_dup 1))
15517 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15519 operands[2] = gen_reg_rtx (<MODE>mode);
15521 MEM_VOLATILE_P (operands[1]) = 1;
15523 [(set_attr "type" "multi")
15524 (set_attr "unit" "i387")
15525 (set_attr "mode" "<MODE>")])
15527 (define_expand "isinfxf2"
15528 [(use (match_operand:SI 0 "register_operand" ""))
15529 (use (match_operand:XF 1 "register_operand" ""))]
15530 "TARGET_USE_FANCY_MATH_387
15531 && TARGET_C99_FUNCTIONS"
15533 rtx mask = GEN_INT (0x45);
15534 rtx val = GEN_INT (0x05);
15538 rtx scratch = gen_reg_rtx (HImode);
15539 rtx res = gen_reg_rtx (QImode);
15541 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15543 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15544 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15545 cond = gen_rtx_fmt_ee (EQ, QImode,
15546 gen_rtx_REG (CCmode, FLAGS_REG),
15548 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15549 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15553 (define_expand "isinf<mode>2"
15554 [(use (match_operand:SI 0 "register_operand" ""))
15555 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15556 "TARGET_USE_FANCY_MATH_387
15557 && TARGET_C99_FUNCTIONS
15558 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15560 rtx mask = GEN_INT (0x45);
15561 rtx val = GEN_INT (0x05);
15565 rtx scratch = gen_reg_rtx (HImode);
15566 rtx res = gen_reg_rtx (QImode);
15568 /* Remove excess precision by forcing value through memory. */
15569 if (memory_operand (operands[1], VOIDmode))
15570 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15573 enum ix86_stack_slot slot = (virtuals_instantiated
15576 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15578 emit_move_insn (temp, operands[1]);
15579 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15582 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15583 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15584 cond = gen_rtx_fmt_ee (EQ, QImode,
15585 gen_rtx_REG (CCmode, FLAGS_REG),
15587 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15588 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15592 (define_expand "signbitxf2"
15593 [(use (match_operand:SI 0 "register_operand" ""))
15594 (use (match_operand:XF 1 "register_operand" ""))]
15595 "TARGET_USE_FANCY_MATH_387"
15597 rtx scratch = gen_reg_rtx (HImode);
15599 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15600 emit_insn (gen_andsi3 (operands[0],
15601 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15605 (define_insn "movmsk_df"
15606 [(set (match_operand:SI 0 "register_operand" "=r")
15608 [(match_operand:DF 1 "register_operand" "x")]
15610 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15611 "%vmovmskpd\t{%1, %0|%0, %1}"
15612 [(set_attr "type" "ssemov")
15613 (set_attr "prefix" "maybe_vex")
15614 (set_attr "mode" "DF")])
15616 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15617 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15618 (define_expand "signbitdf2"
15619 [(use (match_operand:SI 0 "register_operand" ""))
15620 (use (match_operand:DF 1 "register_operand" ""))]
15621 "TARGET_USE_FANCY_MATH_387
15622 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15624 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15626 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15627 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15631 rtx scratch = gen_reg_rtx (HImode);
15633 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15634 emit_insn (gen_andsi3 (operands[0],
15635 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15640 (define_expand "signbitsf2"
15641 [(use (match_operand:SI 0 "register_operand" ""))
15642 (use (match_operand:SF 1 "register_operand" ""))]
15643 "TARGET_USE_FANCY_MATH_387
15644 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15646 rtx scratch = gen_reg_rtx (HImode);
15648 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15649 emit_insn (gen_andsi3 (operands[0],
15650 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15654 ;; Block operation instructions
15657 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15660 [(set_attr "length" "1")
15661 (set_attr "length_immediate" "0")
15662 (set_attr "modrm" "0")])
15664 (define_expand "movmem<mode>"
15665 [(use (match_operand:BLK 0 "memory_operand" ""))
15666 (use (match_operand:BLK 1 "memory_operand" ""))
15667 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15668 (use (match_operand:SWI48 3 "const_int_operand" ""))
15669 (use (match_operand:SI 4 "const_int_operand" ""))
15670 (use (match_operand:SI 5 "const_int_operand" ""))]
15673 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15674 operands[4], operands[5]))
15680 ;; Most CPUs don't like single string operations
15681 ;; Handle this case here to simplify previous expander.
15683 (define_expand "strmov"
15684 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15685 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15686 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15687 (clobber (reg:CC FLAGS_REG))])
15688 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15689 (clobber (reg:CC FLAGS_REG))])]
15692 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15694 /* If .md ever supports :P for Pmode, these can be directly
15695 in the pattern above. */
15696 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15697 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15699 /* Can't use this if the user has appropriated esi or edi. */
15700 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15701 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15703 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15704 operands[2], operands[3],
15705 operands[5], operands[6]));
15709 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15712 (define_expand "strmov_singleop"
15713 [(parallel [(set (match_operand 1 "memory_operand" "")
15714 (match_operand 3 "memory_operand" ""))
15715 (set (match_operand 0 "register_operand" "")
15716 (match_operand 4 "" ""))
15717 (set (match_operand 2 "register_operand" "")
15718 (match_operand 5 "" ""))])]
15720 "ix86_current_function_needs_cld = 1;")
15722 (define_insn "*strmovdi_rex_1"
15723 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15724 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15725 (set (match_operand:DI 0 "register_operand" "=D")
15726 (plus:DI (match_dup 2)
15728 (set (match_operand:DI 1 "register_operand" "=S")
15729 (plus:DI (match_dup 3)
15732 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15734 [(set_attr "type" "str")
15735 (set_attr "memory" "both")
15736 (set_attr "mode" "DI")])
15738 (define_insn "*strmovsi_1"
15739 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15740 (mem:SI (match_operand:P 3 "register_operand" "1")))
15741 (set (match_operand:P 0 "register_operand" "=D")
15742 (plus:P (match_dup 2)
15744 (set (match_operand:P 1 "register_operand" "=S")
15745 (plus:P (match_dup 3)
15747 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15749 [(set_attr "type" "str")
15750 (set_attr "memory" "both")
15751 (set_attr "mode" "SI")])
15753 (define_insn "*strmovhi_1"
15754 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15755 (mem:HI (match_operand:P 3 "register_operand" "1")))
15756 (set (match_operand:P 0 "register_operand" "=D")
15757 (plus:P (match_dup 2)
15759 (set (match_operand:P 1 "register_operand" "=S")
15760 (plus:P (match_dup 3)
15762 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15764 [(set_attr "type" "str")
15765 (set_attr "memory" "both")
15766 (set_attr "mode" "HI")])
15768 (define_insn "*strmovqi_1"
15769 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15770 (mem:QI (match_operand:P 3 "register_operand" "1")))
15771 (set (match_operand:P 0 "register_operand" "=D")
15772 (plus:P (match_dup 2)
15774 (set (match_operand:P 1 "register_operand" "=S")
15775 (plus:P (match_dup 3)
15777 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15779 [(set_attr "type" "str")
15780 (set_attr "memory" "both")
15781 (set (attr "prefix_rex")
15783 (match_test "<P:MODE>mode == DImode")
15785 (const_string "*")))
15786 (set_attr "mode" "QI")])
15788 (define_expand "rep_mov"
15789 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15790 (set (match_operand 0 "register_operand" "")
15791 (match_operand 5 "" ""))
15792 (set (match_operand 2 "register_operand" "")
15793 (match_operand 6 "" ""))
15794 (set (match_operand 1 "memory_operand" "")
15795 (match_operand 3 "memory_operand" ""))
15796 (use (match_dup 4))])]
15798 "ix86_current_function_needs_cld = 1;")
15800 (define_insn "*rep_movdi_rex64"
15801 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15802 (set (match_operand:DI 0 "register_operand" "=D")
15803 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15805 (match_operand:DI 3 "register_operand" "0")))
15806 (set (match_operand:DI 1 "register_operand" "=S")
15807 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15808 (match_operand:DI 4 "register_operand" "1")))
15809 (set (mem:BLK (match_dup 3))
15810 (mem:BLK (match_dup 4)))
15811 (use (match_dup 5))]
15813 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15815 [(set_attr "type" "str")
15816 (set_attr "prefix_rep" "1")
15817 (set_attr "memory" "both")
15818 (set_attr "mode" "DI")])
15820 (define_insn "*rep_movsi"
15821 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15822 (set (match_operand:P 0 "register_operand" "=D")
15823 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15825 (match_operand:P 3 "register_operand" "0")))
15826 (set (match_operand:P 1 "register_operand" "=S")
15827 (plus:P (ashift:P (match_dup 5) (const_int 2))
15828 (match_operand:P 4 "register_operand" "1")))
15829 (set (mem:BLK (match_dup 3))
15830 (mem:BLK (match_dup 4)))
15831 (use (match_dup 5))]
15832 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15833 "rep{%;} movs{l|d}"
15834 [(set_attr "type" "str")
15835 (set_attr "prefix_rep" "1")
15836 (set_attr "memory" "both")
15837 (set_attr "mode" "SI")])
15839 (define_insn "*rep_movqi"
15840 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15841 (set (match_operand:P 0 "register_operand" "=D")
15842 (plus:P (match_operand:P 3 "register_operand" "0")
15843 (match_operand:P 5 "register_operand" "2")))
15844 (set (match_operand:P 1 "register_operand" "=S")
15845 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15846 (set (mem:BLK (match_dup 3))
15847 (mem:BLK (match_dup 4)))
15848 (use (match_dup 5))]
15849 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15851 [(set_attr "type" "str")
15852 (set_attr "prefix_rep" "1")
15853 (set_attr "memory" "both")
15854 (set_attr "mode" "QI")])
15856 (define_expand "setmem<mode>"
15857 [(use (match_operand:BLK 0 "memory_operand" ""))
15858 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15859 (use (match_operand:QI 2 "nonmemory_operand" ""))
15860 (use (match_operand 3 "const_int_operand" ""))
15861 (use (match_operand:SI 4 "const_int_operand" ""))
15862 (use (match_operand:SI 5 "const_int_operand" ""))]
15865 if (ix86_expand_setmem (operands[0], operands[1],
15866 operands[2], operands[3],
15867 operands[4], operands[5]))
15873 ;; Most CPUs don't like single string operations
15874 ;; Handle this case here to simplify previous expander.
15876 (define_expand "strset"
15877 [(set (match_operand 1 "memory_operand" "")
15878 (match_operand 2 "register_operand" ""))
15879 (parallel [(set (match_operand 0 "register_operand" "")
15881 (clobber (reg:CC FLAGS_REG))])]
15884 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15885 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15887 /* If .md ever supports :P for Pmode, this can be directly
15888 in the pattern above. */
15889 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15890 GEN_INT (GET_MODE_SIZE (GET_MODE
15892 /* Can't use this if the user has appropriated eax or edi. */
15893 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15894 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15896 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15902 (define_expand "strset_singleop"
15903 [(parallel [(set (match_operand 1 "memory_operand" "")
15904 (match_operand 2 "register_operand" ""))
15905 (set (match_operand 0 "register_operand" "")
15906 (match_operand 3 "" ""))])]
15908 "ix86_current_function_needs_cld = 1;")
15910 (define_insn "*strsetdi_rex_1"
15911 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15912 (match_operand:DI 2 "register_operand" "a"))
15913 (set (match_operand:DI 0 "register_operand" "=D")
15914 (plus:DI (match_dup 1)
15917 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15919 [(set_attr "type" "str")
15920 (set_attr "memory" "store")
15921 (set_attr "mode" "DI")])
15923 (define_insn "*strsetsi_1"
15924 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15925 (match_operand:SI 2 "register_operand" "a"))
15926 (set (match_operand:P 0 "register_operand" "=D")
15927 (plus:P (match_dup 1)
15929 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15931 [(set_attr "type" "str")
15932 (set_attr "memory" "store")
15933 (set_attr "mode" "SI")])
15935 (define_insn "*strsethi_1"
15936 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15937 (match_operand:HI 2 "register_operand" "a"))
15938 (set (match_operand:P 0 "register_operand" "=D")
15939 (plus:P (match_dup 1)
15941 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15943 [(set_attr "type" "str")
15944 (set_attr "memory" "store")
15945 (set_attr "mode" "HI")])
15947 (define_insn "*strsetqi_1"
15948 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15949 (match_operand:QI 2 "register_operand" "a"))
15950 (set (match_operand:P 0 "register_operand" "=D")
15951 (plus:P (match_dup 1)
15953 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15955 [(set_attr "type" "str")
15956 (set_attr "memory" "store")
15957 (set (attr "prefix_rex")
15959 (match_test "<P:MODE>mode == DImode")
15961 (const_string "*")))
15962 (set_attr "mode" "QI")])
15964 (define_expand "rep_stos"
15965 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15966 (set (match_operand 0 "register_operand" "")
15967 (match_operand 4 "" ""))
15968 (set (match_operand 2 "memory_operand" "") (const_int 0))
15969 (use (match_operand 3 "register_operand" ""))
15970 (use (match_dup 1))])]
15972 "ix86_current_function_needs_cld = 1;")
15974 (define_insn "*rep_stosdi_rex64"
15975 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15976 (set (match_operand:DI 0 "register_operand" "=D")
15977 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15979 (match_operand:DI 3 "register_operand" "0")))
15980 (set (mem:BLK (match_dup 3))
15982 (use (match_operand:DI 2 "register_operand" "a"))
15983 (use (match_dup 4))]
15985 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15987 [(set_attr "type" "str")
15988 (set_attr "prefix_rep" "1")
15989 (set_attr "memory" "store")
15990 (set_attr "mode" "DI")])
15992 (define_insn "*rep_stossi"
15993 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15994 (set (match_operand:P 0 "register_operand" "=D")
15995 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15997 (match_operand:P 3 "register_operand" "0")))
15998 (set (mem:BLK (match_dup 3))
16000 (use (match_operand:SI 2 "register_operand" "a"))
16001 (use (match_dup 4))]
16002 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16003 "rep{%;} stos{l|d}"
16004 [(set_attr "type" "str")
16005 (set_attr "prefix_rep" "1")
16006 (set_attr "memory" "store")
16007 (set_attr "mode" "SI")])
16009 (define_insn "*rep_stosqi"
16010 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16011 (set (match_operand:P 0 "register_operand" "=D")
16012 (plus:P (match_operand:P 3 "register_operand" "0")
16013 (match_operand:P 4 "register_operand" "1")))
16014 (set (mem:BLK (match_dup 3))
16016 (use (match_operand:QI 2 "register_operand" "a"))
16017 (use (match_dup 4))]
16018 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16020 [(set_attr "type" "str")
16021 (set_attr "prefix_rep" "1")
16022 (set_attr "memory" "store")
16023 (set (attr "prefix_rex")
16025 (match_test "<P:MODE>mode == DImode")
16027 (const_string "*")))
16028 (set_attr "mode" "QI")])
16030 (define_expand "cmpstrnsi"
16031 [(set (match_operand:SI 0 "register_operand" "")
16032 (compare:SI (match_operand:BLK 1 "general_operand" "")
16033 (match_operand:BLK 2 "general_operand" "")))
16034 (use (match_operand 3 "general_operand" ""))
16035 (use (match_operand 4 "immediate_operand" ""))]
16038 rtx addr1, addr2, out, outlow, count, countreg, align;
16040 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16043 /* Can't use this if the user has appropriated ecx, esi or edi. */
16044 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16049 out = gen_reg_rtx (SImode);
16051 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16052 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16053 if (addr1 != XEXP (operands[1], 0))
16054 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16055 if (addr2 != XEXP (operands[2], 0))
16056 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16058 count = operands[3];
16059 countreg = ix86_zero_extend_to_Pmode (count);
16061 /* %%% Iff we are testing strict equality, we can use known alignment
16062 to good advantage. This may be possible with combine, particularly
16063 once cc0 is dead. */
16064 align = operands[4];
16066 if (CONST_INT_P (count))
16068 if (INTVAL (count) == 0)
16070 emit_move_insn (operands[0], const0_rtx);
16073 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16074 operands[1], operands[2]));
16078 rtx (*gen_cmp) (rtx, rtx);
16080 gen_cmp = (TARGET_64BIT
16081 ? gen_cmpdi_1 : gen_cmpsi_1);
16083 emit_insn (gen_cmp (countreg, countreg));
16084 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16085 operands[1], operands[2]));
16088 outlow = gen_lowpart (QImode, out);
16089 emit_insn (gen_cmpintqi (outlow));
16090 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16092 if (operands[0] != out)
16093 emit_move_insn (operands[0], out);
16098 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16100 (define_expand "cmpintqi"
16101 [(set (match_dup 1)
16102 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16104 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16105 (parallel [(set (match_operand:QI 0 "register_operand" "")
16106 (minus:QI (match_dup 1)
16108 (clobber (reg:CC FLAGS_REG))])]
16111 operands[1] = gen_reg_rtx (QImode);
16112 operands[2] = gen_reg_rtx (QImode);
16115 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16116 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16118 (define_expand "cmpstrnqi_nz_1"
16119 [(parallel [(set (reg:CC FLAGS_REG)
16120 (compare:CC (match_operand 4 "memory_operand" "")
16121 (match_operand 5 "memory_operand" "")))
16122 (use (match_operand 2 "register_operand" ""))
16123 (use (match_operand:SI 3 "immediate_operand" ""))
16124 (clobber (match_operand 0 "register_operand" ""))
16125 (clobber (match_operand 1 "register_operand" ""))
16126 (clobber (match_dup 2))])]
16128 "ix86_current_function_needs_cld = 1;")
16130 (define_insn "*cmpstrnqi_nz_1"
16131 [(set (reg:CC FLAGS_REG)
16132 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16133 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16134 (use (match_operand:P 6 "register_operand" "2"))
16135 (use (match_operand:SI 3 "immediate_operand" "i"))
16136 (clobber (match_operand:P 0 "register_operand" "=S"))
16137 (clobber (match_operand:P 1 "register_operand" "=D"))
16138 (clobber (match_operand:P 2 "register_operand" "=c"))]
16139 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16141 [(set_attr "type" "str")
16142 (set_attr "mode" "QI")
16143 (set (attr "prefix_rex")
16145 (match_test "<P:MODE>mode == DImode")
16147 (const_string "*")))
16148 (set_attr "prefix_rep" "1")])
16150 ;; The same, but the count is not known to not be zero.
16152 (define_expand "cmpstrnqi_1"
16153 [(parallel [(set (reg:CC FLAGS_REG)
16154 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16156 (compare:CC (match_operand 4 "memory_operand" "")
16157 (match_operand 5 "memory_operand" ""))
16159 (use (match_operand:SI 3 "immediate_operand" ""))
16160 (use (reg:CC FLAGS_REG))
16161 (clobber (match_operand 0 "register_operand" ""))
16162 (clobber (match_operand 1 "register_operand" ""))
16163 (clobber (match_dup 2))])]
16165 "ix86_current_function_needs_cld = 1;")
16167 (define_insn "*cmpstrnqi_1"
16168 [(set (reg:CC FLAGS_REG)
16169 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16171 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16172 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16174 (use (match_operand:SI 3 "immediate_operand" "i"))
16175 (use (reg:CC FLAGS_REG))
16176 (clobber (match_operand:P 0 "register_operand" "=S"))
16177 (clobber (match_operand:P 1 "register_operand" "=D"))
16178 (clobber (match_operand:P 2 "register_operand" "=c"))]
16179 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16181 [(set_attr "type" "str")
16182 (set_attr "mode" "QI")
16183 (set (attr "prefix_rex")
16185 (match_test "<P:MODE>mode == DImode")
16187 (const_string "*")))
16188 (set_attr "prefix_rep" "1")])
16190 (define_expand "strlen<mode>"
16191 [(set (match_operand:P 0 "register_operand" "")
16192 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16193 (match_operand:QI 2 "immediate_operand" "")
16194 (match_operand 3 "immediate_operand" "")]
16198 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16204 (define_expand "strlenqi_1"
16205 [(parallel [(set (match_operand 0 "register_operand" "")
16206 (match_operand 2 "" ""))
16207 (clobber (match_operand 1 "register_operand" ""))
16208 (clobber (reg:CC FLAGS_REG))])]
16210 "ix86_current_function_needs_cld = 1;")
16212 (define_insn "*strlenqi_1"
16213 [(set (match_operand:P 0 "register_operand" "=&c")
16214 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16215 (match_operand:QI 2 "register_operand" "a")
16216 (match_operand:P 3 "immediate_operand" "i")
16217 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16218 (clobber (match_operand:P 1 "register_operand" "=D"))
16219 (clobber (reg:CC FLAGS_REG))]
16220 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16222 [(set_attr "type" "str")
16223 (set_attr "mode" "QI")
16224 (set (attr "prefix_rex")
16226 (match_test "<P:MODE>mode == DImode")
16228 (const_string "*")))
16229 (set_attr "prefix_rep" "1")])
16231 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16232 ;; handled in combine, but it is not currently up to the task.
16233 ;; When used for their truth value, the cmpstrn* expanders generate
16242 ;; The intermediate three instructions are unnecessary.
16244 ;; This one handles cmpstrn*_nz_1...
16247 (set (reg:CC FLAGS_REG)
16248 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16249 (mem:BLK (match_operand 5 "register_operand" ""))))
16250 (use (match_operand 6 "register_operand" ""))
16251 (use (match_operand:SI 3 "immediate_operand" ""))
16252 (clobber (match_operand 0 "register_operand" ""))
16253 (clobber (match_operand 1 "register_operand" ""))
16254 (clobber (match_operand 2 "register_operand" ""))])
16255 (set (match_operand:QI 7 "register_operand" "")
16256 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16257 (set (match_operand:QI 8 "register_operand" "")
16258 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16259 (set (reg FLAGS_REG)
16260 (compare (match_dup 7) (match_dup 8)))
16262 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16264 (set (reg:CC FLAGS_REG)
16265 (compare:CC (mem:BLK (match_dup 4))
16266 (mem:BLK (match_dup 5))))
16267 (use (match_dup 6))
16268 (use (match_dup 3))
16269 (clobber (match_dup 0))
16270 (clobber (match_dup 1))
16271 (clobber (match_dup 2))])])
16273 ;; ...and this one handles cmpstrn*_1.
16276 (set (reg:CC FLAGS_REG)
16277 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16279 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16280 (mem:BLK (match_operand 5 "register_operand" "")))
16282 (use (match_operand:SI 3 "immediate_operand" ""))
16283 (use (reg:CC FLAGS_REG))
16284 (clobber (match_operand 0 "register_operand" ""))
16285 (clobber (match_operand 1 "register_operand" ""))
16286 (clobber (match_operand 2 "register_operand" ""))])
16287 (set (match_operand:QI 7 "register_operand" "")
16288 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16289 (set (match_operand:QI 8 "register_operand" "")
16290 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16291 (set (reg FLAGS_REG)
16292 (compare (match_dup 7) (match_dup 8)))
16294 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16296 (set (reg:CC FLAGS_REG)
16297 (if_then_else:CC (ne (match_dup 6)
16299 (compare:CC (mem:BLK (match_dup 4))
16300 (mem:BLK (match_dup 5)))
16302 (use (match_dup 3))
16303 (use (reg:CC FLAGS_REG))
16304 (clobber (match_dup 0))
16305 (clobber (match_dup 1))
16306 (clobber (match_dup 2))])])
16308 ;; Conditional move instructions.
16310 (define_expand "mov<mode>cc"
16311 [(set (match_operand:SWIM 0 "register_operand" "")
16312 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16313 (match_operand:SWIM 2 "<general_operand>" "")
16314 (match_operand:SWIM 3 "<general_operand>" "")))]
16316 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16318 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16319 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16320 ;; So just document what we're doing explicitly.
16322 (define_expand "x86_mov<mode>cc_0_m1"
16324 [(set (match_operand:SWI48 0 "register_operand" "")
16325 (if_then_else:SWI48
16326 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16327 [(match_operand 1 "flags_reg_operand" "")
16331 (clobber (reg:CC FLAGS_REG))])])
16333 (define_insn "*x86_mov<mode>cc_0_m1"
16334 [(set (match_operand:SWI48 0 "register_operand" "=r")
16335 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16336 [(reg FLAGS_REG) (const_int 0)])
16339 (clobber (reg:CC FLAGS_REG))]
16341 "sbb{<imodesuffix>}\t%0, %0"
16342 ; Since we don't have the proper number of operands for an alu insn,
16343 ; fill in all the blanks.
16344 [(set_attr "type" "alu")
16345 (set_attr "use_carry" "1")
16346 (set_attr "pent_pair" "pu")
16347 (set_attr "memory" "none")
16348 (set_attr "imm_disp" "false")
16349 (set_attr "mode" "<MODE>")
16350 (set_attr "length_immediate" "0")])
16352 (define_insn "*x86_mov<mode>cc_0_m1_se"
16353 [(set (match_operand:SWI48 0 "register_operand" "=r")
16354 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16355 [(reg FLAGS_REG) (const_int 0)])
16358 (clobber (reg:CC FLAGS_REG))]
16360 "sbb{<imodesuffix>}\t%0, %0"
16361 [(set_attr "type" "alu")
16362 (set_attr "use_carry" "1")
16363 (set_attr "pent_pair" "pu")
16364 (set_attr "memory" "none")
16365 (set_attr "imm_disp" "false")
16366 (set_attr "mode" "<MODE>")
16367 (set_attr "length_immediate" "0")])
16369 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16370 [(set (match_operand:SWI48 0 "register_operand" "=r")
16371 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16372 [(reg FLAGS_REG) (const_int 0)])))
16373 (clobber (reg:CC FLAGS_REG))]
16375 "sbb{<imodesuffix>}\t%0, %0"
16376 [(set_attr "type" "alu")
16377 (set_attr "use_carry" "1")
16378 (set_attr "pent_pair" "pu")
16379 (set_attr "memory" "none")
16380 (set_attr "imm_disp" "false")
16381 (set_attr "mode" "<MODE>")
16382 (set_attr "length_immediate" "0")])
16384 (define_insn "*mov<mode>cc_noc"
16385 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16386 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16387 [(reg FLAGS_REG) (const_int 0)])
16388 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16389 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16390 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16392 cmov%O2%C1\t{%2, %0|%0, %2}
16393 cmov%O2%c1\t{%3, %0|%0, %3}"
16394 [(set_attr "type" "icmov")
16395 (set_attr "mode" "<MODE>")])
16397 (define_insn "*movqicc_noc"
16398 [(set (match_operand:QI 0 "register_operand" "=r,r")
16399 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16400 [(reg FLAGS_REG) (const_int 0)])
16401 (match_operand:QI 2 "register_operand" "r,0")
16402 (match_operand:QI 3 "register_operand" "0,r")))]
16403 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16405 [(set_attr "type" "icmov")
16406 (set_attr "mode" "QI")])
16409 [(set (match_operand 0 "register_operand")
16410 (if_then_else (match_operator 1 "ix86_comparison_operator"
16411 [(reg FLAGS_REG) (const_int 0)])
16412 (match_operand 2 "register_operand")
16413 (match_operand 3 "register_operand")))]
16414 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16415 && (GET_MODE (operands[0]) == QImode
16416 || GET_MODE (operands[0]) == HImode)
16417 && reload_completed"
16418 [(set (match_dup 0)
16419 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16421 operands[0] = gen_lowpart (SImode, operands[0]);
16422 operands[2] = gen_lowpart (SImode, operands[2]);
16423 operands[3] = gen_lowpart (SImode, operands[3]);
16426 (define_expand "mov<mode>cc"
16427 [(set (match_operand:X87MODEF 0 "register_operand" "")
16428 (if_then_else:X87MODEF
16429 (match_operand 1 "ix86_fp_comparison_operator" "")
16430 (match_operand:X87MODEF 2 "register_operand" "")
16431 (match_operand:X87MODEF 3 "register_operand" "")))]
16432 "(TARGET_80387 && TARGET_CMOVE)
16433 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16434 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16436 (define_insn "*movxfcc_1"
16437 [(set (match_operand:XF 0 "register_operand" "=f,f")
16438 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16439 [(reg FLAGS_REG) (const_int 0)])
16440 (match_operand:XF 2 "register_operand" "f,0")
16441 (match_operand:XF 3 "register_operand" "0,f")))]
16442 "TARGET_80387 && TARGET_CMOVE"
16444 fcmov%F1\t{%2, %0|%0, %2}
16445 fcmov%f1\t{%3, %0|%0, %3}"
16446 [(set_attr "type" "fcmov")
16447 (set_attr "mode" "XF")])
16449 (define_insn "*movdfcc_1_rex64"
16450 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16451 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16452 [(reg FLAGS_REG) (const_int 0)])
16453 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16454 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16455 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16456 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16458 fcmov%F1\t{%2, %0|%0, %2}
16459 fcmov%f1\t{%3, %0|%0, %3}
16460 cmov%O2%C1\t{%2, %0|%0, %2}
16461 cmov%O2%c1\t{%3, %0|%0, %3}"
16462 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16463 (set_attr "mode" "DF,DF,DI,DI")])
16465 (define_insn "*movdfcc_1"
16466 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16467 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16468 [(reg FLAGS_REG) (const_int 0)])
16469 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16470 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16471 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16472 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16474 fcmov%F1\t{%2, %0|%0, %2}
16475 fcmov%f1\t{%3, %0|%0, %3}
16478 [(set_attr "type" "fcmov,fcmov,multi,multi")
16479 (set_attr "mode" "DF,DF,DI,DI")])
16482 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16483 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16484 [(reg FLAGS_REG) (const_int 0)])
16485 (match_operand:DF 2 "nonimmediate_operand")
16486 (match_operand:DF 3 "nonimmediate_operand")))]
16487 "!TARGET_64BIT && reload_completed"
16488 [(set (match_dup 2)
16489 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16491 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16493 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16494 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16497 (define_insn "*movsfcc_1_387"
16498 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16499 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16500 [(reg FLAGS_REG) (const_int 0)])
16501 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16502 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16503 "TARGET_80387 && TARGET_CMOVE
16504 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16506 fcmov%F1\t{%2, %0|%0, %2}
16507 fcmov%f1\t{%3, %0|%0, %3}
16508 cmov%O2%C1\t{%2, %0|%0, %2}
16509 cmov%O2%c1\t{%3, %0|%0, %3}"
16510 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16511 (set_attr "mode" "SF,SF,SI,SI")])
16513 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16514 ;; the scalar versions to have only XMM registers as operands.
16516 ;; XOP conditional move
16517 (define_insn "*xop_pcmov_<mode>"
16518 [(set (match_operand:MODEF 0 "register_operand" "=x")
16519 (if_then_else:MODEF
16520 (match_operand:MODEF 1 "register_operand" "x")
16521 (match_operand:MODEF 2 "register_operand" "x")
16522 (match_operand:MODEF 3 "register_operand" "x")))]
16524 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16525 [(set_attr "type" "sse4arg")])
16527 ;; These versions of the min/max patterns are intentionally ignorant of
16528 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16529 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16530 ;; are undefined in this condition, we're certain this is correct.
16532 (define_insn "<code><mode>3"
16533 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16535 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16536 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16537 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16539 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16540 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16541 [(set_attr "isa" "noavx,avx")
16542 (set_attr "prefix" "orig,vex")
16543 (set_attr "type" "sseadd")
16544 (set_attr "mode" "<MODE>")])
16546 ;; These versions of the min/max patterns implement exactly the operations
16547 ;; min = (op1 < op2 ? op1 : op2)
16548 ;; max = (!(op1 < op2) ? op1 : op2)
16549 ;; Their operands are not commutative, and thus they may be used in the
16550 ;; presence of -0.0 and NaN.
16552 (define_insn "*ieee_smin<mode>3"
16553 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16555 [(match_operand:MODEF 1 "register_operand" "0,x")
16556 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16558 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16560 min<ssemodesuffix>\t{%2, %0|%0, %2}
16561 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16562 [(set_attr "isa" "noavx,avx")
16563 (set_attr "prefix" "orig,vex")
16564 (set_attr "type" "sseadd")
16565 (set_attr "mode" "<MODE>")])
16567 (define_insn "*ieee_smax<mode>3"
16568 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16570 [(match_operand:MODEF 1 "register_operand" "0,x")
16571 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16573 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16575 max<ssemodesuffix>\t{%2, %0|%0, %2}
16576 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16577 [(set_attr "isa" "noavx,avx")
16578 (set_attr "prefix" "orig,vex")
16579 (set_attr "type" "sseadd")
16580 (set_attr "mode" "<MODE>")])
16582 ;; Make two stack loads independent:
16584 ;; fld %st(0) -> fld bb
16585 ;; fmul bb fmul %st(1), %st
16587 ;; Actually we only match the last two instructions for simplicity.
16589 [(set (match_operand 0 "fp_register_operand" "")
16590 (match_operand 1 "fp_register_operand" ""))
16592 (match_operator 2 "binary_fp_operator"
16594 (match_operand 3 "memory_operand" "")]))]
16595 "REGNO (operands[0]) != REGNO (operands[1])"
16596 [(set (match_dup 0) (match_dup 3))
16597 (set (match_dup 0) (match_dup 4))]
16599 ;; The % modifier is not operational anymore in peephole2's, so we have to
16600 ;; swap the operands manually in the case of addition and multiplication.
16604 if (COMMUTATIVE_ARITH_P (operands[2]))
16605 op0 = operands[0], op1 = operands[1];
16607 op0 = operands[1], op1 = operands[0];
16609 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16610 GET_MODE (operands[2]),
16614 ;; Conditional addition patterns
16615 (define_expand "add<mode>cc"
16616 [(match_operand:SWI 0 "register_operand" "")
16617 (match_operand 1 "ordered_comparison_operator" "")
16618 (match_operand:SWI 2 "register_operand" "")
16619 (match_operand:SWI 3 "const_int_operand" "")]
16621 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16623 ;; Misc patterns (?)
16625 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16626 ;; Otherwise there will be nothing to keep
16628 ;; [(set (reg ebp) (reg esp))]
16629 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16630 ;; (clobber (eflags)]
16631 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16633 ;; in proper program order.
16635 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16636 [(set (match_operand:P 0 "register_operand" "=r,r")
16637 (plus:P (match_operand:P 1 "register_operand" "0,r")
16638 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16639 (clobber (reg:CC FLAGS_REG))
16640 (clobber (mem:BLK (scratch)))]
16643 switch (get_attr_type (insn))
16646 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16649 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16650 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16651 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16653 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16656 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16657 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16660 [(set (attr "type")
16661 (cond [(and (eq_attr "alternative" "0")
16662 (not (match_test "TARGET_OPT_AGU")))
16663 (const_string "alu")
16664 (match_operand:<MODE> 2 "const0_operand" "")
16665 (const_string "imov")
16667 (const_string "lea")))
16668 (set (attr "length_immediate")
16669 (cond [(eq_attr "type" "imov")
16671 (and (eq_attr "type" "alu")
16672 (match_operand 2 "const128_operand" ""))
16675 (const_string "*")))
16676 (set_attr "mode" "<MODE>")])
16678 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16679 [(set (match_operand:P 0 "register_operand" "=r")
16680 (minus:P (match_operand:P 1 "register_operand" "0")
16681 (match_operand:P 2 "register_operand" "r")))
16682 (clobber (reg:CC FLAGS_REG))
16683 (clobber (mem:BLK (scratch)))]
16685 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16686 [(set_attr "type" "alu")
16687 (set_attr "mode" "<MODE>")])
16689 (define_insn "allocate_stack_worker_probe_<mode>"
16690 [(set (match_operand:P 0 "register_operand" "=a")
16691 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16692 UNSPECV_STACK_PROBE))
16693 (clobber (reg:CC FLAGS_REG))]
16694 "ix86_target_stack_probe ()"
16695 "call\t___chkstk_ms"
16696 [(set_attr "type" "multi")
16697 (set_attr "length" "5")])
16699 (define_expand "allocate_stack"
16700 [(match_operand 0 "register_operand" "")
16701 (match_operand 1 "general_operand" "")]
16702 "ix86_target_stack_probe ()"
16706 #ifndef CHECK_STACK_LIMIT
16707 #define CHECK_STACK_LIMIT 0
16710 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16711 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16713 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16714 stack_pointer_rtx, 0, OPTAB_DIRECT);
16715 if (x != stack_pointer_rtx)
16716 emit_move_insn (stack_pointer_rtx, x);
16720 x = copy_to_mode_reg (Pmode, operands[1]);
16722 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16724 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16725 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16726 stack_pointer_rtx, 0, OPTAB_DIRECT);
16727 if (x != stack_pointer_rtx)
16728 emit_move_insn (stack_pointer_rtx, x);
16731 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16735 ;; Use IOR for stack probes, this is shorter.
16736 (define_expand "probe_stack"
16737 [(match_operand 0 "memory_operand" "")]
16740 rtx (*gen_ior3) (rtx, rtx, rtx);
16742 gen_ior3 = (GET_MODE (operands[0]) == DImode
16743 ? gen_iordi3 : gen_iorsi3);
16745 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16749 (define_insn "adjust_stack_and_probe<mode>"
16750 [(set (match_operand:P 0 "register_operand" "=r")
16751 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16752 UNSPECV_PROBE_STACK_RANGE))
16753 (set (reg:P SP_REG)
16754 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16755 (clobber (reg:CC FLAGS_REG))
16756 (clobber (mem:BLK (scratch)))]
16758 "* return output_adjust_stack_and_probe (operands[0]);"
16759 [(set_attr "type" "multi")])
16761 (define_insn "probe_stack_range<mode>"
16762 [(set (match_operand:P 0 "register_operand" "=r")
16763 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16764 (match_operand:P 2 "const_int_operand" "n")]
16765 UNSPECV_PROBE_STACK_RANGE))
16766 (clobber (reg:CC FLAGS_REG))]
16768 "* return output_probe_stack_range (operands[0], operands[2]);"
16769 [(set_attr "type" "multi")])
16771 (define_expand "builtin_setjmp_receiver"
16772 [(label_ref (match_operand 0 "" ""))]
16773 "!TARGET_64BIT && flag_pic"
16779 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16780 rtx label_rtx = gen_label_rtx ();
16781 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16782 xops[0] = xops[1] = picreg;
16783 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16784 ix86_expand_binary_operator (MINUS, SImode, xops);
16788 emit_insn (gen_set_got (pic_offset_table_rtx));
16792 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16795 [(set (match_operand 0 "register_operand" "")
16796 (match_operator 3 "promotable_binary_operator"
16797 [(match_operand 1 "register_operand" "")
16798 (match_operand 2 "aligned_operand" "")]))
16799 (clobber (reg:CC FLAGS_REG))]
16800 "! TARGET_PARTIAL_REG_STALL && reload_completed
16801 && ((GET_MODE (operands[0]) == HImode
16802 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16803 /* ??? next two lines just !satisfies_constraint_K (...) */
16804 || !CONST_INT_P (operands[2])
16805 || satisfies_constraint_K (operands[2])))
16806 || (GET_MODE (operands[0]) == QImode
16807 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16808 [(parallel [(set (match_dup 0)
16809 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16810 (clobber (reg:CC FLAGS_REG))])]
16812 operands[0] = gen_lowpart (SImode, operands[0]);
16813 operands[1] = gen_lowpart (SImode, operands[1]);
16814 if (GET_CODE (operands[3]) != ASHIFT)
16815 operands[2] = gen_lowpart (SImode, operands[2]);
16816 PUT_MODE (operands[3], SImode);
16819 ; Promote the QImode tests, as i386 has encoding of the AND
16820 ; instruction with 32-bit sign-extended immediate and thus the
16821 ; instruction size is unchanged, except in the %eax case for
16822 ; which it is increased by one byte, hence the ! optimize_size.
16824 [(set (match_operand 0 "flags_reg_operand" "")
16825 (match_operator 2 "compare_operator"
16826 [(and (match_operand 3 "aligned_operand" "")
16827 (match_operand 4 "const_int_operand" ""))
16829 (set (match_operand 1 "register_operand" "")
16830 (and (match_dup 3) (match_dup 4)))]
16831 "! TARGET_PARTIAL_REG_STALL && reload_completed
16832 && optimize_insn_for_speed_p ()
16833 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16834 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16835 /* Ensure that the operand will remain sign-extended immediate. */
16836 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16837 [(parallel [(set (match_dup 0)
16838 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16841 (and:SI (match_dup 3) (match_dup 4)))])]
16844 = gen_int_mode (INTVAL (operands[4])
16845 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16846 operands[1] = gen_lowpart (SImode, operands[1]);
16847 operands[3] = gen_lowpart (SImode, operands[3]);
16850 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16851 ; the TEST instruction with 32-bit sign-extended immediate and thus
16852 ; the instruction size would at least double, which is not what we
16853 ; want even with ! optimize_size.
16855 [(set (match_operand 0 "flags_reg_operand" "")
16856 (match_operator 1 "compare_operator"
16857 [(and (match_operand:HI 2 "aligned_operand" "")
16858 (match_operand:HI 3 "const_int_operand" ""))
16860 "! TARGET_PARTIAL_REG_STALL && reload_completed
16861 && ! TARGET_FAST_PREFIX
16862 && optimize_insn_for_speed_p ()
16863 /* Ensure that the operand will remain sign-extended immediate. */
16864 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16865 [(set (match_dup 0)
16866 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16870 = gen_int_mode (INTVAL (operands[3])
16871 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16872 operands[2] = gen_lowpart (SImode, operands[2]);
16876 [(set (match_operand 0 "register_operand" "")
16877 (neg (match_operand 1 "register_operand" "")))
16878 (clobber (reg:CC FLAGS_REG))]
16879 "! TARGET_PARTIAL_REG_STALL && reload_completed
16880 && (GET_MODE (operands[0]) == HImode
16881 || (GET_MODE (operands[0]) == QImode
16882 && (TARGET_PROMOTE_QImode
16883 || optimize_insn_for_size_p ())))"
16884 [(parallel [(set (match_dup 0)
16885 (neg:SI (match_dup 1)))
16886 (clobber (reg:CC FLAGS_REG))])]
16888 operands[0] = gen_lowpart (SImode, operands[0]);
16889 operands[1] = gen_lowpart (SImode, operands[1]);
16893 [(set (match_operand 0 "register_operand" "")
16894 (not (match_operand 1 "register_operand" "")))]
16895 "! TARGET_PARTIAL_REG_STALL && reload_completed
16896 && (GET_MODE (operands[0]) == HImode
16897 || (GET_MODE (operands[0]) == QImode
16898 && (TARGET_PROMOTE_QImode
16899 || optimize_insn_for_size_p ())))"
16900 [(set (match_dup 0)
16901 (not:SI (match_dup 1)))]
16903 operands[0] = gen_lowpart (SImode, operands[0]);
16904 operands[1] = gen_lowpart (SImode, operands[1]);
16907 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16908 ;; transform a complex memory operation into two memory to register operations.
16910 ;; Don't push memory operands
16912 [(set (match_operand:SWI 0 "push_operand" "")
16913 (match_operand:SWI 1 "memory_operand" ""))
16914 (match_scratch:SWI 2 "<r>")]
16915 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16916 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16917 [(set (match_dup 2) (match_dup 1))
16918 (set (match_dup 0) (match_dup 2))])
16920 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16923 [(set (match_operand:SF 0 "push_operand" "")
16924 (match_operand:SF 1 "memory_operand" ""))
16925 (match_scratch:SF 2 "r")]
16926 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16927 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16928 [(set (match_dup 2) (match_dup 1))
16929 (set (match_dup 0) (match_dup 2))])
16931 ;; Don't move an immediate directly to memory when the instruction
16934 [(match_scratch:SWI124 1 "<r>")
16935 (set (match_operand:SWI124 0 "memory_operand" "")
16937 "optimize_insn_for_speed_p ()
16938 && !TARGET_USE_MOV0
16939 && TARGET_SPLIT_LONG_MOVES
16940 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16941 && peep2_regno_dead_p (0, FLAGS_REG)"
16942 [(parallel [(set (match_dup 2) (const_int 0))
16943 (clobber (reg:CC FLAGS_REG))])
16944 (set (match_dup 0) (match_dup 1))]
16945 "operands[2] = gen_lowpart (SImode, operands[1]);")
16948 [(match_scratch:SWI124 2 "<r>")
16949 (set (match_operand:SWI124 0 "memory_operand" "")
16950 (match_operand:SWI124 1 "immediate_operand" ""))]
16951 "optimize_insn_for_speed_p ()
16952 && TARGET_SPLIT_LONG_MOVES
16953 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16954 [(set (match_dup 2) (match_dup 1))
16955 (set (match_dup 0) (match_dup 2))])
16957 ;; Don't compare memory with zero, load and use a test instead.
16959 [(set (match_operand 0 "flags_reg_operand" "")
16960 (match_operator 1 "compare_operator"
16961 [(match_operand:SI 2 "memory_operand" "")
16963 (match_scratch:SI 3 "r")]
16964 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16965 [(set (match_dup 3) (match_dup 2))
16966 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16968 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16969 ;; Don't split NOTs with a displacement operand, because resulting XOR
16970 ;; will not be pairable anyway.
16972 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16973 ;; represented using a modRM byte. The XOR replacement is long decoded,
16974 ;; so this split helps here as well.
16976 ;; Note: Can't do this as a regular split because we can't get proper
16977 ;; lifetime information then.
16980 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16981 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16982 "optimize_insn_for_speed_p ()
16983 && ((TARGET_NOT_UNPAIRABLE
16984 && (!MEM_P (operands[0])
16985 || !memory_displacement_operand (operands[0], <MODE>mode)))
16986 || (TARGET_NOT_VECTORMODE
16987 && long_memory_operand (operands[0], <MODE>mode)))
16988 && peep2_regno_dead_p (0, FLAGS_REG)"
16989 [(parallel [(set (match_dup 0)
16990 (xor:SWI124 (match_dup 1) (const_int -1)))
16991 (clobber (reg:CC FLAGS_REG))])])
16993 ;; Non pairable "test imm, reg" instructions can be translated to
16994 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16995 ;; byte opcode instead of two, have a short form for byte operands),
16996 ;; so do it for other CPUs as well. Given that the value was dead,
16997 ;; this should not create any new dependencies. Pass on the sub-word
16998 ;; versions if we're concerned about partial register stalls.
17001 [(set (match_operand 0 "flags_reg_operand" "")
17002 (match_operator 1 "compare_operator"
17003 [(and:SI (match_operand:SI 2 "register_operand" "")
17004 (match_operand:SI 3 "immediate_operand" ""))
17006 "ix86_match_ccmode (insn, CCNOmode)
17007 && (true_regnum (operands[2]) != AX_REG
17008 || satisfies_constraint_K (operands[3]))
17009 && peep2_reg_dead_p (1, operands[2])"
17011 [(set (match_dup 0)
17012 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17015 (and:SI (match_dup 2) (match_dup 3)))])])
17017 ;; We don't need to handle HImode case, because it will be promoted to SImode
17018 ;; on ! TARGET_PARTIAL_REG_STALL
17021 [(set (match_operand 0 "flags_reg_operand" "")
17022 (match_operator 1 "compare_operator"
17023 [(and:QI (match_operand:QI 2 "register_operand" "")
17024 (match_operand:QI 3 "immediate_operand" ""))
17026 "! TARGET_PARTIAL_REG_STALL
17027 && ix86_match_ccmode (insn, CCNOmode)
17028 && true_regnum (operands[2]) != AX_REG
17029 && peep2_reg_dead_p (1, operands[2])"
17031 [(set (match_dup 0)
17032 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17035 (and:QI (match_dup 2) (match_dup 3)))])])
17038 [(set (match_operand 0 "flags_reg_operand" "")
17039 (match_operator 1 "compare_operator"
17042 (match_operand 2 "ext_register_operand" "")
17045 (match_operand 3 "const_int_operand" ""))
17047 "! TARGET_PARTIAL_REG_STALL
17048 && ix86_match_ccmode (insn, CCNOmode)
17049 && true_regnum (operands[2]) != AX_REG
17050 && peep2_reg_dead_p (1, operands[2])"
17051 [(parallel [(set (match_dup 0)
17060 (set (zero_extract:SI (match_dup 2)
17068 (match_dup 3)))])])
17070 ;; Don't do logical operations with memory inputs.
17072 [(match_scratch:SI 2 "r")
17073 (parallel [(set (match_operand:SI 0 "register_operand" "")
17074 (match_operator:SI 3 "arith_or_logical_operator"
17076 (match_operand:SI 1 "memory_operand" "")]))
17077 (clobber (reg:CC FLAGS_REG))])]
17078 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17079 [(set (match_dup 2) (match_dup 1))
17080 (parallel [(set (match_dup 0)
17081 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17082 (clobber (reg:CC FLAGS_REG))])])
17085 [(match_scratch:SI 2 "r")
17086 (parallel [(set (match_operand:SI 0 "register_operand" "")
17087 (match_operator:SI 3 "arith_or_logical_operator"
17088 [(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 2) (match_dup 0)]))
17095 (clobber (reg:CC FLAGS_REG))])])
17097 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17098 ;; refers to the destination of the load!
17101 [(set (match_operand:SI 0 "register_operand" "")
17102 (match_operand:SI 1 "register_operand" ""))
17103 (parallel [(set (match_dup 0)
17104 (match_operator:SI 3 "commutative_operator"
17106 (match_operand:SI 2 "memory_operand" "")]))
17107 (clobber (reg:CC FLAGS_REG))])]
17108 "REGNO (operands[0]) != REGNO (operands[1])
17109 && GENERAL_REGNO_P (REGNO (operands[0]))
17110 && GENERAL_REGNO_P (REGNO (operands[1]))"
17111 [(set (match_dup 0) (match_dup 4))
17112 (parallel [(set (match_dup 0)
17113 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17114 (clobber (reg:CC FLAGS_REG))])]
17115 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17118 [(set (match_operand 0 "register_operand" "")
17119 (match_operand 1 "register_operand" ""))
17121 (match_operator 3 "commutative_operator"
17123 (match_operand 2 "memory_operand" "")]))]
17124 "REGNO (operands[0]) != REGNO (operands[1])
17125 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17126 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17127 [(set (match_dup 0) (match_dup 2))
17129 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17131 ; Don't do logical operations with memory outputs
17133 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17134 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17135 ; the same decoder scheduling characteristics as the original.
17138 [(match_scratch:SI 2 "r")
17139 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17140 (match_operator:SI 3 "arith_or_logical_operator"
17142 (match_operand:SI 1 "nonmemory_operand" "")]))
17143 (clobber (reg:CC FLAGS_REG))])]
17144 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17145 /* Do not split stack checking probes. */
17146 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17147 [(set (match_dup 2) (match_dup 0))
17148 (parallel [(set (match_dup 2)
17149 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17150 (clobber (reg:CC FLAGS_REG))])
17151 (set (match_dup 0) (match_dup 2))])
17154 [(match_scratch:SI 2 "r")
17155 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17156 (match_operator:SI 3 "arith_or_logical_operator"
17157 [(match_operand:SI 1 "nonmemory_operand" "")
17159 (clobber (reg:CC FLAGS_REG))])]
17160 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17161 /* Do not split stack checking probes. */
17162 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17163 [(set (match_dup 2) (match_dup 0))
17164 (parallel [(set (match_dup 2)
17165 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17166 (clobber (reg:CC FLAGS_REG))])
17167 (set (match_dup 0) (match_dup 2))])
17169 ;; Attempt to use arith or logical operations with memory outputs with
17170 ;; setting of flags.
17172 [(set (match_operand:SWI 0 "register_operand" "")
17173 (match_operand:SWI 1 "memory_operand" ""))
17174 (parallel [(set (match_dup 0)
17175 (match_operator:SWI 3 "plusminuslogic_operator"
17177 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17178 (clobber (reg:CC FLAGS_REG))])
17179 (set (match_dup 1) (match_dup 0))
17180 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17181 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17182 && peep2_reg_dead_p (4, operands[0])
17183 && !reg_overlap_mentioned_p (operands[0], operands[1])
17184 && (<MODE>mode != QImode
17185 || immediate_operand (operands[2], QImode)
17186 || q_regs_operand (operands[2], QImode))
17187 && ix86_match_ccmode (peep2_next_insn (3),
17188 (GET_CODE (operands[3]) == PLUS
17189 || GET_CODE (operands[3]) == MINUS)
17190 ? CCGOCmode : CCNOmode)"
17191 [(parallel [(set (match_dup 4) (match_dup 5))
17192 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17193 (match_dup 2)]))])]
17195 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17196 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17197 copy_rtx (operands[1]),
17198 copy_rtx (operands[2]));
17199 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17200 operands[5], const0_rtx);
17204 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17205 (match_operator:SWI 2 "plusminuslogic_operator"
17207 (match_operand:SWI 1 "memory_operand" "")]))
17208 (clobber (reg:CC FLAGS_REG))])
17209 (set (match_dup 1) (match_dup 0))
17210 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17211 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17212 && GET_CODE (operands[2]) != MINUS
17213 && peep2_reg_dead_p (3, operands[0])
17214 && !reg_overlap_mentioned_p (operands[0], operands[1])
17215 && ix86_match_ccmode (peep2_next_insn (2),
17216 GET_CODE (operands[2]) == PLUS
17217 ? CCGOCmode : CCNOmode)"
17218 [(parallel [(set (match_dup 3) (match_dup 4))
17219 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17220 (match_dup 0)]))])]
17222 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17223 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17224 copy_rtx (operands[1]),
17225 copy_rtx (operands[0]));
17226 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17227 operands[4], const0_rtx);
17231 [(set (match_operand:SWI12 0 "register_operand" "")
17232 (match_operand:SWI12 1 "memory_operand" ""))
17233 (parallel [(set (match_operand:SI 4 "register_operand" "")
17234 (match_operator:SI 3 "plusminuslogic_operator"
17236 (match_operand:SI 2 "nonmemory_operand" "")]))
17237 (clobber (reg:CC FLAGS_REG))])
17238 (set (match_dup 1) (match_dup 0))
17239 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17240 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17241 && REG_P (operands[0]) && REG_P (operands[4])
17242 && REGNO (operands[0]) == REGNO (operands[4])
17243 && peep2_reg_dead_p (4, operands[0])
17244 && (<MODE>mode != QImode
17245 || immediate_operand (operands[2], SImode)
17246 || q_regs_operand (operands[2], SImode))
17247 && !reg_overlap_mentioned_p (operands[0], operands[1])
17248 && ix86_match_ccmode (peep2_next_insn (3),
17249 (GET_CODE (operands[3]) == PLUS
17250 || GET_CODE (operands[3]) == MINUS)
17251 ? CCGOCmode : CCNOmode)"
17252 [(parallel [(set (match_dup 4) (match_dup 5))
17253 (set (match_dup 1) (match_dup 6))])]
17255 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17256 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17257 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17258 copy_rtx (operands[1]), operands[2]);
17259 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17260 operands[5], const0_rtx);
17261 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17262 copy_rtx (operands[1]),
17263 copy_rtx (operands[2]));
17266 ;; Attempt to always use XOR for zeroing registers.
17268 [(set (match_operand 0 "register_operand" "")
17269 (match_operand 1 "const0_operand" ""))]
17270 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17271 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17272 && GENERAL_REG_P (operands[0])
17273 && peep2_regno_dead_p (0, FLAGS_REG)"
17274 [(parallel [(set (match_dup 0) (const_int 0))
17275 (clobber (reg:CC FLAGS_REG))])]
17276 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17279 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17281 "(GET_MODE (operands[0]) == QImode
17282 || GET_MODE (operands[0]) == HImode)
17283 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17284 && peep2_regno_dead_p (0, FLAGS_REG)"
17285 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17286 (clobber (reg:CC FLAGS_REG))])])
17288 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17290 [(set (match_operand:SWI248 0 "register_operand" "")
17292 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17293 && peep2_regno_dead_p (0, FLAGS_REG)"
17294 [(parallel [(set (match_dup 0) (const_int -1))
17295 (clobber (reg:CC FLAGS_REG))])]
17297 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17298 operands[0] = gen_lowpart (SImode, operands[0]);
17301 ;; Attempt to convert simple lea to add/shift.
17302 ;; These can be created by move expanders.
17305 [(set (match_operand:SWI48 0 "register_operand" "")
17306 (plus:SWI48 (match_dup 0)
17307 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17308 "peep2_regno_dead_p (0, FLAGS_REG)"
17309 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17310 (clobber (reg:CC FLAGS_REG))])])
17313 [(set (match_operand:SI 0 "register_operand" "")
17314 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17315 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17317 && peep2_regno_dead_p (0, FLAGS_REG)
17318 && REGNO (operands[0]) == REGNO (operands[1])"
17319 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17320 (clobber (reg:CC FLAGS_REG))])]
17321 "operands[2] = gen_lowpart (SImode, operands[2]);")
17324 [(set (match_operand:SWI48 0 "register_operand" "")
17325 (mult:SWI48 (match_dup 0)
17326 (match_operand:SWI48 1 "const_int_operand" "")))]
17327 "exact_log2 (INTVAL (operands[1])) >= 0
17328 && peep2_regno_dead_p (0, FLAGS_REG)"
17329 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17330 (clobber (reg:CC FLAGS_REG))])]
17331 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17334 [(set (match_operand:SI 0 "register_operand" "")
17335 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17336 (match_operand:DI 2 "const_int_operand" "")) 0))]
17338 && exact_log2 (INTVAL (operands[2])) >= 0
17339 && REGNO (operands[0]) == REGNO (operands[1])
17340 && peep2_regno_dead_p (0, FLAGS_REG)"
17341 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17342 (clobber (reg:CC FLAGS_REG))])]
17343 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17345 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17346 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17347 ;; On many CPUs it is also faster, since special hardware to avoid esp
17348 ;; dependencies is present.
17350 ;; While some of these conversions may be done using splitters, we use
17351 ;; peepholes in order to allow combine_stack_adjustments pass to see
17352 ;; nonobfuscated RTL.
17354 ;; Convert prologue esp subtractions to push.
17355 ;; We need register to push. In order to keep verify_flow_info happy we have
17357 ;; - use scratch and clobber it in order to avoid dependencies
17358 ;; - use already live register
17359 ;; We can't use the second way right now, since there is no reliable way how to
17360 ;; verify that given register is live. First choice will also most likely in
17361 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17362 ;; call clobbered registers are dead. We may want to use base pointer as an
17363 ;; alternative when no register is available later.
17366 [(match_scratch:P 1 "r")
17367 (parallel [(set (reg:P SP_REG)
17368 (plus:P (reg:P SP_REG)
17369 (match_operand:P 0 "const_int_operand" "")))
17370 (clobber (reg:CC FLAGS_REG))
17371 (clobber (mem:BLK (scratch)))])]
17372 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17373 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17374 [(clobber (match_dup 1))
17375 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17376 (clobber (mem:BLK (scratch)))])])
17379 [(match_scratch:P 1 "r")
17380 (parallel [(set (reg:P SP_REG)
17381 (plus:P (reg:P SP_REG)
17382 (match_operand:P 0 "const_int_operand" "")))
17383 (clobber (reg:CC FLAGS_REG))
17384 (clobber (mem:BLK (scratch)))])]
17385 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17386 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17387 [(clobber (match_dup 1))
17388 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17389 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17390 (clobber (mem:BLK (scratch)))])])
17392 ;; Convert esp subtractions to push.
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 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17400 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17401 [(clobber (match_dup 1))
17402 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17405 [(match_scratch:P 1 "r")
17406 (parallel [(set (reg:P SP_REG)
17407 (plus:P (reg:P SP_REG)
17408 (match_operand:P 0 "const_int_operand" "")))
17409 (clobber (reg:CC FLAGS_REG))])]
17410 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17411 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17412 [(clobber (match_dup 1))
17413 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17414 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17416 ;; Convert epilogue deallocator to pop.
17418 [(match_scratch:P 1 "r")
17419 (parallel [(set (reg:P SP_REG)
17420 (plus:P (reg:P SP_REG)
17421 (match_operand:P 0 "const_int_operand" "")))
17422 (clobber (reg:CC FLAGS_REG))
17423 (clobber (mem:BLK (scratch)))])]
17424 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17425 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17426 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17427 (clobber (mem:BLK (scratch)))])])
17429 ;; Two pops case is tricky, since pop causes dependency
17430 ;; on destination register. We use two registers if available.
17432 [(match_scratch:P 1 "r")
17433 (match_scratch:P 2 "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_DOUBLE_POP || optimize_insn_for_size_p ())
17440 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17441 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17442 (clobber (mem:BLK (scratch)))])
17443 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17446 [(match_scratch:P 1 "r")
17447 (parallel [(set (reg:P SP_REG)
17448 (plus:P (reg:P SP_REG)
17449 (match_operand:P 0 "const_int_operand" "")))
17450 (clobber (reg:CC FLAGS_REG))
17451 (clobber (mem:BLK (scratch)))])]
17452 "optimize_insn_for_size_p ()
17453 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17454 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17455 (clobber (mem:BLK (scratch)))])
17456 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17458 ;; Convert esp additions to pop.
17460 [(match_scratch:P 1 "r")
17461 (parallel [(set (reg:P SP_REG)
17462 (plus:P (reg:P SP_REG)
17463 (match_operand:P 0 "const_int_operand" "")))
17464 (clobber (reg:CC FLAGS_REG))])]
17465 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17466 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17468 ;; Two pops case is tricky, since pop causes dependency
17469 ;; on destination register. We use two registers if available.
17471 [(match_scratch:P 1 "r")
17472 (match_scratch:P 2 "r")
17473 (parallel [(set (reg:P SP_REG)
17474 (plus:P (reg:P SP_REG)
17475 (match_operand:P 0 "const_int_operand" "")))
17476 (clobber (reg:CC FLAGS_REG))])]
17477 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17478 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17479 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17482 [(match_scratch:P 1 "r")
17483 (parallel [(set (reg:P SP_REG)
17484 (plus:P (reg:P SP_REG)
17485 (match_operand:P 0 "const_int_operand" "")))
17486 (clobber (reg:CC FLAGS_REG))])]
17487 "optimize_insn_for_size_p ()
17488 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17489 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17490 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17492 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17493 ;; required and register dies. Similarly for 128 to -128.
17495 [(set (match_operand 0 "flags_reg_operand" "")
17496 (match_operator 1 "compare_operator"
17497 [(match_operand 2 "register_operand" "")
17498 (match_operand 3 "const_int_operand" "")]))]
17499 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17500 && incdec_operand (operands[3], GET_MODE (operands[3])))
17501 || (!TARGET_FUSE_CMP_AND_BRANCH
17502 && INTVAL (operands[3]) == 128))
17503 && ix86_match_ccmode (insn, CCGCmode)
17504 && peep2_reg_dead_p (1, operands[2])"
17505 [(parallel [(set (match_dup 0)
17506 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17507 (clobber (match_dup 2))])])
17509 ;; Convert imul by three, five and nine into lea
17512 [(set (match_operand:SWI48 0 "register_operand" "")
17513 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17514 (match_operand:SWI48 2 "const359_operand" "")))
17515 (clobber (reg:CC FLAGS_REG))])]
17516 "!TARGET_PARTIAL_REG_STALL
17517 || <MODE>mode == SImode
17518 || optimize_function_for_size_p (cfun)"
17519 [(set (match_dup 0)
17520 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17522 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17526 [(set (match_operand:SWI48 0 "register_operand" "")
17527 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17528 (match_operand:SWI48 2 "const359_operand" "")))
17529 (clobber (reg:CC FLAGS_REG))])]
17530 "optimize_insn_for_speed_p ()
17531 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17532 [(set (match_dup 0) (match_dup 1))
17534 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17536 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17538 ;; imul $32bit_imm, mem, reg is vector decoded, while
17539 ;; imul $32bit_imm, reg, reg is direct decoded.
17541 [(match_scratch:SWI48 3 "r")
17542 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17543 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17544 (match_operand:SWI48 2 "immediate_operand" "")))
17545 (clobber (reg:CC FLAGS_REG))])]
17546 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17547 && !satisfies_constraint_K (operands[2])"
17548 [(set (match_dup 3) (match_dup 1))
17549 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17550 (clobber (reg:CC FLAGS_REG))])])
17553 [(match_scratch:SI 3 "r")
17554 (parallel [(set (match_operand:DI 0 "register_operand" "")
17556 (mult:SI (match_operand:SI 1 "memory_operand" "")
17557 (match_operand:SI 2 "immediate_operand" ""))))
17558 (clobber (reg:CC FLAGS_REG))])]
17560 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17561 && !satisfies_constraint_K (operands[2])"
17562 [(set (match_dup 3) (match_dup 1))
17563 (parallel [(set (match_dup 0)
17564 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17565 (clobber (reg:CC FLAGS_REG))])])
17567 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17568 ;; Convert it into imul reg, reg
17569 ;; It would be better to force assembler to encode instruction using long
17570 ;; immediate, but there is apparently no way to do so.
17572 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17574 (match_operand:SWI248 1 "nonimmediate_operand" "")
17575 (match_operand:SWI248 2 "const_int_operand" "")))
17576 (clobber (reg:CC FLAGS_REG))])
17577 (match_scratch:SWI248 3 "r")]
17578 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17579 && satisfies_constraint_K (operands[2])"
17580 [(set (match_dup 3) (match_dup 2))
17581 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17582 (clobber (reg:CC FLAGS_REG))])]
17584 if (!rtx_equal_p (operands[0], operands[1]))
17585 emit_move_insn (operands[0], operands[1]);
17588 ;; After splitting up read-modify operations, array accesses with memory
17589 ;; operands might end up in form:
17591 ;; movl 4(%esp), %edx
17593 ;; instead of pre-splitting:
17595 ;; addl 4(%esp), %eax
17597 ;; movl 4(%esp), %edx
17598 ;; leal (%edx,%eax,4), %eax
17601 [(match_scratch:P 5 "r")
17602 (parallel [(set (match_operand 0 "register_operand" "")
17603 (ashift (match_operand 1 "register_operand" "")
17604 (match_operand 2 "const_int_operand" "")))
17605 (clobber (reg:CC FLAGS_REG))])
17606 (parallel [(set (match_operand 3 "register_operand" "")
17607 (plus (match_dup 0)
17608 (match_operand 4 "x86_64_general_operand" "")))
17609 (clobber (reg:CC FLAGS_REG))])]
17610 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17611 /* Validate MODE for lea. */
17612 && ((!TARGET_PARTIAL_REG_STALL
17613 && (GET_MODE (operands[0]) == QImode
17614 || GET_MODE (operands[0]) == HImode))
17615 || GET_MODE (operands[0]) == SImode
17616 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17617 && (rtx_equal_p (operands[0], operands[3])
17618 || peep2_reg_dead_p (2, operands[0]))
17619 /* We reorder load and the shift. */
17620 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17621 [(set (match_dup 5) (match_dup 4))
17622 (set (match_dup 0) (match_dup 1))]
17624 enum machine_mode op1mode = GET_MODE (operands[1]);
17625 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17626 int scale = 1 << INTVAL (operands[2]);
17627 rtx index = gen_lowpart (Pmode, operands[1]);
17628 rtx base = gen_lowpart (Pmode, operands[5]);
17629 rtx dest = gen_lowpart (mode, operands[3]);
17631 operands[1] = gen_rtx_PLUS (Pmode, base,
17632 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17633 operands[5] = base;
17635 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17636 if (op1mode != Pmode)
17637 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17638 operands[0] = dest;
17641 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17642 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17643 ;; caught for use by garbage collectors and the like. Using an insn that
17644 ;; maps to SIGILL makes it more likely the program will rightfully die.
17645 ;; Keeping with tradition, "6" is in honor of #UD.
17646 (define_insn "trap"
17647 [(trap_if (const_int 1) (const_int 6))]
17649 { return ASM_SHORT "0x0b0f"; }
17650 [(set_attr "length" "2")])
17652 (define_expand "prefetch"
17653 [(prefetch (match_operand 0 "address_operand" "")
17654 (match_operand:SI 1 "const_int_operand" "")
17655 (match_operand:SI 2 "const_int_operand" ""))]
17656 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17658 int rw = INTVAL (operands[1]);
17659 int locality = INTVAL (operands[2]);
17661 gcc_assert (rw == 0 || rw == 1);
17662 gcc_assert (locality >= 0 && locality <= 3);
17663 gcc_assert (GET_MODE (operands[0]) == Pmode
17664 || GET_MODE (operands[0]) == VOIDmode);
17666 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17667 supported by SSE counterpart or the SSE prefetch is not available
17668 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17670 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17671 operands[2] = GEN_INT (3);
17673 operands[1] = const0_rtx;
17676 (define_insn "*prefetch_sse_<mode>"
17677 [(prefetch (match_operand:P 0 "address_operand" "p")
17679 (match_operand:SI 1 "const_int_operand" ""))]
17680 "TARGET_PREFETCH_SSE"
17682 static const char * const patterns[4] = {
17683 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17686 int locality = INTVAL (operands[1]);
17687 gcc_assert (locality >= 0 && locality <= 3);
17689 return patterns[locality];
17691 [(set_attr "type" "sse")
17692 (set_attr "atom_sse_attr" "prefetch")
17693 (set (attr "length_address")
17694 (symbol_ref "memory_address_length (operands[0])"))
17695 (set_attr "memory" "none")])
17697 (define_insn "*prefetch_3dnow_<mode>"
17698 [(prefetch (match_operand:P 0 "address_operand" "p")
17699 (match_operand:SI 1 "const_int_operand" "n")
17703 if (INTVAL (operands[1]) == 0)
17704 return "prefetch\t%a0";
17706 return "prefetchw\t%a0";
17708 [(set_attr "type" "mmx")
17709 (set (attr "length_address")
17710 (symbol_ref "memory_address_length (operands[0])"))
17711 (set_attr "memory" "none")])
17713 (define_expand "stack_protect_set"
17714 [(match_operand 0 "memory_operand" "")
17715 (match_operand 1 "memory_operand" "")]
17716 "!TARGET_HAS_BIONIC"
17718 rtx (*insn)(rtx, rtx);
17720 #ifdef TARGET_THREAD_SSP_OFFSET
17721 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17722 insn = (TARGET_LP64
17723 ? gen_stack_tls_protect_set_di
17724 : gen_stack_tls_protect_set_si);
17726 insn = (TARGET_LP64
17727 ? gen_stack_protect_set_di
17728 : gen_stack_protect_set_si);
17731 emit_insn (insn (operands[0], operands[1]));
17735 (define_insn "stack_protect_set_<mode>"
17736 [(set (match_operand:PTR 0 "memory_operand" "=m")
17737 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17739 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17740 (clobber (reg:CC FLAGS_REG))]
17741 "!TARGET_HAS_BIONIC"
17742 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17743 [(set_attr "type" "multi")])
17745 (define_insn "stack_tls_protect_set_<mode>"
17746 [(set (match_operand:PTR 0 "memory_operand" "=m")
17747 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17748 UNSPEC_SP_TLS_SET))
17749 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17750 (clobber (reg:CC FLAGS_REG))]
17752 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17753 [(set_attr "type" "multi")])
17755 (define_expand "stack_protect_test"
17756 [(match_operand 0 "memory_operand" "")
17757 (match_operand 1 "memory_operand" "")
17758 (match_operand 2 "" "")]
17759 "!TARGET_HAS_BIONIC"
17761 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17763 rtx (*insn)(rtx, rtx, rtx);
17765 #ifdef TARGET_THREAD_SSP_OFFSET
17766 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17767 insn = (TARGET_LP64
17768 ? gen_stack_tls_protect_test_di
17769 : gen_stack_tls_protect_test_si);
17771 insn = (TARGET_LP64
17772 ? gen_stack_protect_test_di
17773 : gen_stack_protect_test_si);
17776 emit_insn (insn (flags, operands[0], operands[1]));
17778 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17779 flags, const0_rtx, operands[2]));
17783 (define_insn "stack_protect_test_<mode>"
17784 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17785 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17786 (match_operand:PTR 2 "memory_operand" "m")]
17788 (clobber (match_scratch:PTR 3 "=&r"))]
17789 "!TARGET_HAS_BIONIC"
17790 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17791 [(set_attr "type" "multi")])
17793 (define_insn "stack_tls_protect_test_<mode>"
17794 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17795 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17796 (match_operand:PTR 2 "const_int_operand" "i")]
17797 UNSPEC_SP_TLS_TEST))
17798 (clobber (match_scratch:PTR 3 "=r"))]
17800 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17801 [(set_attr "type" "multi")])
17803 (define_insn "sse4_2_crc32<mode>"
17804 [(set (match_operand:SI 0 "register_operand" "=r")
17806 [(match_operand:SI 1 "register_operand" "0")
17807 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17809 "TARGET_SSE4_2 || TARGET_CRC32"
17810 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17811 [(set_attr "type" "sselog1")
17812 (set_attr "prefix_rep" "1")
17813 (set_attr "prefix_extra" "1")
17814 (set (attr "prefix_data16")
17815 (if_then_else (match_operand:HI 2 "" "")
17817 (const_string "*")))
17818 (set (attr "prefix_rex")
17819 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17821 (const_string "*")))
17822 (set_attr "mode" "SI")])
17824 (define_insn "sse4_2_crc32di"
17825 [(set (match_operand:DI 0 "register_operand" "=r")
17827 [(match_operand:DI 1 "register_operand" "0")
17828 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17830 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17831 "crc32{q}\t{%2, %0|%0, %2}"
17832 [(set_attr "type" "sselog1")
17833 (set_attr "prefix_rep" "1")
17834 (set_attr "prefix_extra" "1")
17835 (set_attr "mode" "DI")])
17837 (define_expand "rdpmc"
17838 [(match_operand:DI 0 "register_operand" "")
17839 (match_operand:SI 1 "register_operand" "")]
17842 rtx reg = gen_reg_rtx (DImode);
17845 /* Force operand 1 into ECX. */
17846 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17847 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17848 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17853 rtvec vec = rtvec_alloc (2);
17854 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17855 rtx upper = gen_reg_rtx (DImode);
17856 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17857 gen_rtvec (1, const0_rtx),
17859 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17860 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17862 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17863 NULL, 1, OPTAB_DIRECT);
17864 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17868 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17869 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17873 (define_insn "*rdpmc"
17874 [(set (match_operand:DI 0 "register_operand" "=A")
17875 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17879 [(set_attr "type" "other")
17880 (set_attr "length" "2")])
17882 (define_insn "*rdpmc_rex64"
17883 [(set (match_operand:DI 0 "register_operand" "=a")
17884 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17886 (set (match_operand:DI 1 "register_operand" "=d")
17887 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17890 [(set_attr "type" "other")
17891 (set_attr "length" "2")])
17893 (define_expand "rdtsc"
17894 [(set (match_operand:DI 0 "register_operand" "")
17895 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17900 rtvec vec = rtvec_alloc (2);
17901 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17902 rtx upper = gen_reg_rtx (DImode);
17903 rtx lower = gen_reg_rtx (DImode);
17904 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17905 gen_rtvec (1, const0_rtx),
17907 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17908 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17910 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17911 NULL, 1, OPTAB_DIRECT);
17912 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17914 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17919 (define_insn "*rdtsc"
17920 [(set (match_operand:DI 0 "register_operand" "=A")
17921 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17924 [(set_attr "type" "other")
17925 (set_attr "length" "2")])
17927 (define_insn "*rdtsc_rex64"
17928 [(set (match_operand:DI 0 "register_operand" "=a")
17929 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17930 (set (match_operand:DI 1 "register_operand" "=d")
17931 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17934 [(set_attr "type" "other")
17935 (set_attr "length" "2")])
17937 (define_expand "rdtscp"
17938 [(match_operand:DI 0 "register_operand" "")
17939 (match_operand:SI 1 "memory_operand" "")]
17942 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17943 gen_rtvec (1, const0_rtx),
17945 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17946 gen_rtvec (1, const0_rtx),
17948 rtx reg = gen_reg_rtx (DImode);
17949 rtx tmp = gen_reg_rtx (SImode);
17953 rtvec vec = rtvec_alloc (3);
17954 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17955 rtx upper = gen_reg_rtx (DImode);
17956 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17957 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17958 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17960 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17961 NULL, 1, OPTAB_DIRECT);
17962 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17967 rtvec vec = rtvec_alloc (2);
17968 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17969 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17970 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17973 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17974 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17978 (define_insn "*rdtscp"
17979 [(set (match_operand:DI 0 "register_operand" "=A")
17980 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17981 (set (match_operand:SI 1 "register_operand" "=c")
17982 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17985 [(set_attr "type" "other")
17986 (set_attr "length" "3")])
17988 (define_insn "*rdtscp_rex64"
17989 [(set (match_operand:DI 0 "register_operand" "=a")
17990 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17991 (set (match_operand:DI 1 "register_operand" "=d")
17992 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17993 (set (match_operand:SI 2 "register_operand" "=c")
17994 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17997 [(set_attr "type" "other")
17998 (set_attr "length" "3")])
18000 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18002 ;; LWP instructions
18004 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18006 (define_expand "lwp_llwpcb"
18007 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18008 UNSPECV_LLWP_INTRINSIC)]
18011 (define_insn "*lwp_llwpcb<mode>1"
18012 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18013 UNSPECV_LLWP_INTRINSIC)]
18016 [(set_attr "type" "lwp")
18017 (set_attr "mode" "<MODE>")
18018 (set_attr "length" "5")])
18020 (define_expand "lwp_slwpcb"
18021 [(set (match_operand 0 "register_operand" "=r")
18022 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18027 insn = (TARGET_64BIT
18029 : gen_lwp_slwpcbsi);
18031 emit_insn (insn (operands[0]));
18035 (define_insn "lwp_slwpcb<mode>"
18036 [(set (match_operand:P 0 "register_operand" "=r")
18037 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18040 [(set_attr "type" "lwp")
18041 (set_attr "mode" "<MODE>")
18042 (set_attr "length" "5")])
18044 (define_expand "lwp_lwpval<mode>3"
18045 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18046 (match_operand:SI 2 "nonimmediate_operand" "rm")
18047 (match_operand:SI 3 "const_int_operand" "i")]
18048 UNSPECV_LWPVAL_INTRINSIC)]
18050 ;; Avoid unused variable warning.
18051 "(void) operands[0];")
18053 (define_insn "*lwp_lwpval<mode>3_1"
18054 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18055 (match_operand:SI 1 "nonimmediate_operand" "rm")
18056 (match_operand:SI 2 "const_int_operand" "i")]
18057 UNSPECV_LWPVAL_INTRINSIC)]
18059 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18060 [(set_attr "type" "lwp")
18061 (set_attr "mode" "<MODE>")
18062 (set (attr "length")
18063 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18065 (define_expand "lwp_lwpins<mode>3"
18066 [(set (reg:CCC FLAGS_REG)
18067 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18068 (match_operand:SI 2 "nonimmediate_operand" "rm")
18069 (match_operand:SI 3 "const_int_operand" "i")]
18070 UNSPECV_LWPINS_INTRINSIC))
18071 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18072 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18075 (define_insn "*lwp_lwpins<mode>3_1"
18076 [(set (reg:CCC FLAGS_REG)
18077 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18078 (match_operand:SI 1 "nonimmediate_operand" "rm")
18079 (match_operand:SI 2 "const_int_operand" "i")]
18080 UNSPECV_LWPINS_INTRINSIC))]
18082 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18083 [(set_attr "type" "lwp")
18084 (set_attr "mode" "<MODE>")
18085 (set (attr "length")
18086 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18088 (define_insn "rdfsbase<mode>"
18089 [(set (match_operand:SWI48 0 "register_operand" "=r")
18090 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18091 "TARGET_64BIT && TARGET_FSGSBASE"
18093 [(set_attr "type" "other")
18094 (set_attr "prefix_extra" "2")])
18096 (define_insn "rdgsbase<mode>"
18097 [(set (match_operand:SWI48 0 "register_operand" "=r")
18098 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18099 "TARGET_64BIT && TARGET_FSGSBASE"
18101 [(set_attr "type" "other")
18102 (set_attr "prefix_extra" "2")])
18104 (define_insn "wrfsbase<mode>"
18105 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18107 "TARGET_64BIT && TARGET_FSGSBASE"
18109 [(set_attr "type" "other")
18110 (set_attr "prefix_extra" "2")])
18112 (define_insn "wrgsbase<mode>"
18113 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18115 "TARGET_64BIT && TARGET_FSGSBASE"
18117 [(set_attr "type" "other")
18118 (set_attr "prefix_extra" "2")])
18120 (define_insn "rdrand<mode>_1"
18121 [(set (match_operand:SWI248 0 "register_operand" "=r")
18122 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18123 (set (reg:CCC FLAGS_REG)
18124 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18127 [(set_attr "type" "other")
18128 (set_attr "prefix_extra" "1")])
18130 (define_expand "pause"
18131 [(set (match_dup 0)
18132 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18135 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18136 MEM_VOLATILE_P (operands[0]) = 1;
18139 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18140 ;; They have the same encoding.
18141 (define_insn "*pause"
18142 [(set (match_operand:BLK 0 "" "")
18143 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18146 [(set_attr "length" "2")
18147 (set_attr "memory" "unknown")])
18151 (include "sync.md")