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"))]
2603 "mov{b}\t{%b1, %h0|%h0, %b1}"
2604 [(set_attr "type" "imov")
2605 (set_attr "mode" "QI")])
2607 (define_insn "*movsi_insv_1"
2608 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2611 (match_operand:SI 1 "general_operand" "Qmn"))]
2613 "mov{b}\t{%b1, %h0|%h0, %b1}"
2614 [(set_attr "type" "imov")
2615 (set_attr "mode" "QI")])
2617 (define_insn "*movqi_insv_2"
2618 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2621 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2624 "mov{b}\t{%h1, %h0|%h0, %h1}"
2625 [(set_attr "type" "imov")
2626 (set_attr "mode" "QI")])
2628 ;; Floating point push instructions.
2630 (define_insn "*pushtf"
2631 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2632 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2635 /* This insn should be already split before reg-stack. */
2638 [(set_attr "type" "multi")
2639 (set_attr "unit" "sse,*,*")
2640 (set_attr "mode" "TF,SI,SI")])
2642 ;; %%% Kill this when call knows how to work this out.
2644 [(set (match_operand:TF 0 "push_operand" "")
2645 (match_operand:TF 1 "sse_reg_operand" ""))]
2646 "TARGET_SSE2 && reload_completed"
2647 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2648 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2650 (define_insn "*pushxf"
2651 [(set (match_operand:XF 0 "push_operand" "=<,<")
2652 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2653 "optimize_function_for_speed_p (cfun)"
2655 /* This insn should be already split before reg-stack. */
2658 [(set_attr "type" "multi")
2659 (set_attr "unit" "i387,*")
2660 (set_attr "mode" "XF,SI")])
2662 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references (assuming that any given constant is pushed
2666 ;; only once, but this ought to be handled elsewhere).
2668 (define_insn "*pushxf_nointeger"
2669 [(set (match_operand:XF 0 "push_operand" "=<,<")
2670 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2671 "optimize_function_for_size_p (cfun)"
2673 /* This insn should be already split before reg-stack. */
2676 [(set_attr "type" "multi")
2677 (set_attr "unit" "i387,*")
2678 (set_attr "mode" "XF,SI")])
2680 ;; %%% Kill this when call knows how to work this out.
2682 [(set (match_operand:XF 0 "push_operand" "")
2683 (match_operand:XF 1 "fp_register_operand" ""))]
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2686 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2687 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2689 (define_insn "*pushdf_rex64"
2690 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2691 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2694 /* This insn should be already split before reg-stack. */
2697 [(set_attr "type" "multi")
2698 (set_attr "unit" "i387,*,*")
2699 (set_attr "mode" "DF,DI,DF")])
2701 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2702 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2703 ;; On the average, pushdf using integers can be still shorter.
2705 (define_insn "*pushdf"
2706 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2707 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2710 /* This insn should be already split before reg-stack. */
2713 [(set_attr "isa" "*,*,sse2")
2714 (set_attr "type" "multi")
2715 (set_attr "unit" "i387,*,*")
2716 (set_attr "mode" "DF,DI,DF")])
2718 ;; %%% Kill this when call knows how to work this out.
2720 [(set (match_operand:DF 0 "push_operand" "")
2721 (match_operand:DF 1 "any_fp_register_operand" ""))]
2723 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2724 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2726 (define_insn "*pushsf_rex64"
2727 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2728 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2731 /* Anything else should be already split before reg-stack. */
2732 gcc_assert (which_alternative == 1);
2733 return "push{q}\t%q1";
2735 [(set_attr "type" "multi,push,multi")
2736 (set_attr "unit" "i387,*,*")
2737 (set_attr "mode" "SF,DI,SF")])
2739 (define_insn "*pushsf"
2740 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2741 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2744 /* Anything else should be already split before reg-stack. */
2745 gcc_assert (which_alternative == 1);
2746 return "push{l}\t%1";
2748 [(set_attr "type" "multi,push,multi")
2749 (set_attr "unit" "i387,*,*")
2750 (set_attr "mode" "SF,SI,SF")])
2752 ;; %%% Kill this when call knows how to work this out.
2754 [(set (match_operand:SF 0 "push_operand" "")
2755 (match_operand:SF 1 "any_fp_register_operand" ""))]
2757 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2758 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2759 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2762 [(set (match_operand:SF 0 "push_operand" "")
2763 (match_operand:SF 1 "memory_operand" ""))]
2765 && (operands[2] = find_constant_src (insn))"
2766 [(set (match_dup 0) (match_dup 2))])
2769 [(set (match_operand 0 "push_operand" "")
2770 (match_operand 1 "general_operand" ""))]
2772 && (GET_MODE (operands[0]) == TFmode
2773 || GET_MODE (operands[0]) == XFmode
2774 || GET_MODE (operands[0]) == DFmode)
2775 && !ANY_FP_REG_P (operands[1])"
2777 "ix86_split_long_move (operands); DONE;")
2779 ;; Floating point move instructions.
2781 (define_expand "movtf"
2782 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2783 (match_operand:TF 1 "nonimmediate_operand" ""))]
2786 ix86_expand_move (TFmode, operands);
2790 (define_expand "mov<mode>"
2791 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2792 (match_operand:X87MODEF 1 "general_operand" ""))]
2794 "ix86_expand_move (<MODE>mode, operands); DONE;")
2796 (define_insn "*movtf_internal"
2797 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2798 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2801 && (!can_create_pseudo_p ()
2802 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2803 || GET_CODE (operands[1]) != CONST_DOUBLE
2804 || (optimize_function_for_size_p (cfun)
2805 && standard_sse_constant_p (operands[1])
2806 && !memory_operand (operands[0], TFmode))
2807 || (!TARGET_MEMORY_MISMATCH_STALL
2808 && memory_operand (operands[0], TFmode)))"
2810 switch (which_alternative)
2814 /* Handle misaligned load/store since we
2815 don't have movmisaligntf pattern. */
2816 if (misaligned_operand (operands[0], TFmode)
2817 || misaligned_operand (operands[1], TFmode))
2819 if (get_attr_mode (insn) == MODE_V4SF)
2820 return "%vmovups\t{%1, %0|%0, %1}";
2822 return "%vmovdqu\t{%1, %0|%0, %1}";
2826 if (get_attr_mode (insn) == MODE_V4SF)
2827 return "%vmovaps\t{%1, %0|%0, %1}";
2829 return "%vmovdqa\t{%1, %0|%0, %1}";
2833 return standard_sse_constant_opcode (insn, operands[1]);
2843 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2844 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2846 (cond [(eq_attr "alternative" "0,2")
2848 (match_test "optimize_function_for_size_p (cfun)")
2849 (const_string "V4SF")
2850 (const_string "TI"))
2851 (eq_attr "alternative" "1")
2853 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2854 (match_test "optimize_function_for_size_p (cfun)"))
2855 (const_string "V4SF")
2856 (const_string "TI"))]
2857 (const_string "DI")))])
2859 ;; Possible store forwarding (partial memory) stall in alternative 4.
2860 (define_insn "*movxf_internal"
2861 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2862 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2863 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2864 && (!can_create_pseudo_p ()
2865 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2866 || GET_CODE (operands[1]) != CONST_DOUBLE
2867 || (optimize_function_for_size_p (cfun)
2868 && standard_80387_constant_p (operands[1]) > 0
2869 && !memory_operand (operands[0], XFmode))
2870 || (!TARGET_MEMORY_MISMATCH_STALL
2871 && memory_operand (operands[0], XFmode)))"
2873 switch (which_alternative)
2877 return output_387_reg_move (insn, operands);
2880 return standard_80387_constant_opcode (operands[1]);
2890 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891 (set_attr "mode" "XF,XF,XF,SI,SI")])
2893 (define_insn "*movdf_internal_rex64"
2894 [(set (match_operand:DF 0 "nonimmediate_operand"
2895 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2896 (match_operand:DF 1 "general_operand"
2897 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2898 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2899 && (!can_create_pseudo_p ()
2900 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901 || GET_CODE (operands[1]) != CONST_DOUBLE
2902 || (optimize_function_for_size_p (cfun)
2903 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2904 && standard_80387_constant_p (operands[1]) > 0)
2905 || (TARGET_SSE2 && TARGET_SSE_MATH
2906 && standard_sse_constant_p (operands[1]))))
2907 || memory_operand (operands[0], DFmode))"
2909 switch (which_alternative)
2913 return output_387_reg_move (insn, operands);
2916 return standard_80387_constant_opcode (operands[1]);
2920 return "mov{q}\t{%1, %0|%0, %1}";
2923 return "movabs{q}\t{%1, %0|%0, %1}";
2929 return standard_sse_constant_opcode (insn, operands[1]);
2934 switch (get_attr_mode (insn))
2937 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938 return "%vmovapd\t{%1, %0|%0, %1}";
2940 return "%vmovaps\t{%1, %0|%0, %1}";
2943 return "%vmovq\t{%1, %0|%0, %1}";
2945 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2946 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2947 return "%vmovsd\t{%1, %0|%0, %1}";
2949 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2951 return "%vmovlps\t{%1, %d0|%d0, %1}";
2958 /* Handle broken assemblers that require movd instead of movq. */
2959 return "%vmovd\t{%1, %0|%0, %1}";
2966 (cond [(eq_attr "alternative" "0,1,2")
2967 (const_string "fmov")
2968 (eq_attr "alternative" "3,4,5")
2969 (const_string "imov")
2970 (eq_attr "alternative" "6")
2971 (const_string "multi")
2972 (eq_attr "alternative" "7")
2973 (const_string "sselog1")
2975 (const_string "ssemov")))
2978 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2980 (const_string "*")))
2981 (set (attr "length_immediate")
2983 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2985 (const_string "*")))
2986 (set (attr "prefix")
2987 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2988 (const_string "orig")
2989 (const_string "maybe_vex")))
2990 (set (attr "prefix_data16")
2991 (if_then_else (eq_attr "mode" "V1DF")
2993 (const_string "*")))
2995 (cond [(eq_attr "alternative" "0,1,2")
2997 (eq_attr "alternative" "3,4,5,6,11,12")
3000 /* xorps is one byte shorter. */
3001 (eq_attr "alternative" "7")
3002 (cond [(match_test "optimize_function_for_size_p (cfun)")
3003 (const_string "V4SF")
3004 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3007 (const_string "V2DF"))
3009 /* For architectures resolving dependencies on
3010 whole SSE registers use APD move to break dependency
3011 chains, otherwise use short move to avoid extra work.
3013 movaps encodes one byte shorter. */
3014 (eq_attr "alternative" "8")
3016 [(match_test "optimize_function_for_size_p (cfun)")
3017 (const_string "V4SF")
3018 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3019 (const_string "V2DF")
3021 (const_string "DF"))
3022 /* For architectures resolving dependencies on register
3023 parts we may avoid extra work to zero out upper part
3025 (eq_attr "alternative" "9")
3027 (match_test "TARGET_SSE_SPLIT_REGS")
3028 (const_string "V1DF")
3029 (const_string "DF"))
3031 (const_string "DF")))])
3033 ;; Possible store forwarding (partial memory) stall in alternative 4.
3034 (define_insn "*movdf_internal"
3035 [(set (match_operand:DF 0 "nonimmediate_operand"
3036 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3037 (match_operand:DF 1 "general_operand"
3038 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3039 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3040 && (!can_create_pseudo_p ()
3041 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3042 || GET_CODE (operands[1]) != CONST_DOUBLE
3043 || (optimize_function_for_size_p (cfun)
3044 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3045 && standard_80387_constant_p (operands[1]) > 0)
3046 || (TARGET_SSE2 && TARGET_SSE_MATH
3047 && standard_sse_constant_p (operands[1])))
3048 && !memory_operand (operands[0], DFmode))
3049 || (!TARGET_MEMORY_MISMATCH_STALL
3050 && memory_operand (operands[0], DFmode)))"
3052 switch (which_alternative)
3056 return output_387_reg_move (insn, operands);
3059 return standard_80387_constant_opcode (operands[1]);
3067 return standard_sse_constant_opcode (insn, operands[1]);
3075 switch (get_attr_mode (insn))
3078 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3079 return "%vmovapd\t{%1, %0|%0, %1}";
3081 return "%vmovaps\t{%1, %0|%0, %1}";
3084 return "%vmovq\t{%1, %0|%0, %1}";
3086 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3087 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3088 return "%vmovsd\t{%1, %0|%0, %1}";
3090 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3092 return "%vmovlps\t{%1, %d0|%d0, %1}";
3102 (if_then_else (eq_attr "alternative" "5,6,7,8")
3103 (const_string "sse2")
3104 (const_string "*")))
3106 (cond [(eq_attr "alternative" "0,1,2")
3107 (const_string "fmov")
3108 (eq_attr "alternative" "3,4")
3109 (const_string "multi")
3110 (eq_attr "alternative" "5,9")
3111 (const_string "sselog1")
3113 (const_string "ssemov")))
3114 (set (attr "prefix")
3115 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3116 (const_string "orig")
3117 (const_string "maybe_vex")))
3118 (set (attr "prefix_data16")
3119 (if_then_else (eq_attr "mode" "V1DF")
3121 (const_string "*")))
3123 (cond [(eq_attr "alternative" "0,1,2")
3125 (eq_attr "alternative" "3,4")
3128 /* For SSE1, we have many fewer alternatives. */
3129 (not (match_test "TARGET_SSE2"))
3131 (eq_attr "alternative" "5,6,9,10")
3132 (const_string "V4SF")
3133 (const_string "V2SF"))
3135 /* xorps is one byte shorter. */
3136 (eq_attr "alternative" "5,9")
3137 (cond [(match_test "optimize_function_for_size_p (cfun)")
3138 (const_string "V4SF")
3139 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3142 (const_string "V2DF"))
3144 /* For architectures resolving dependencies on
3145 whole SSE registers use APD move to break dependency
3146 chains, otherwise use short move to avoid extra work.
3148 movaps encodes one byte shorter. */
3149 (eq_attr "alternative" "6,10")
3151 [(match_test "optimize_function_for_size_p (cfun)")
3152 (const_string "V4SF")
3153 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3154 (const_string "V2DF")
3156 (const_string "DF"))
3157 /* For architectures resolving dependencies on register
3158 parts we may avoid extra work to zero out upper part
3160 (eq_attr "alternative" "7,11")
3162 (match_test "TARGET_SSE_SPLIT_REGS")
3163 (const_string "V1DF")
3164 (const_string "DF"))
3166 (const_string "DF")))])
3168 (define_insn "*movsf_internal"
3169 [(set (match_operand:SF 0 "nonimmediate_operand"
3170 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3171 (match_operand:SF 1 "general_operand"
3172 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3173 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3174 && (!can_create_pseudo_p ()
3175 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3176 || GET_CODE (operands[1]) != CONST_DOUBLE
3177 || (optimize_function_for_size_p (cfun)
3178 && ((!TARGET_SSE_MATH
3179 && standard_80387_constant_p (operands[1]) > 0)
3181 && standard_sse_constant_p (operands[1]))))
3182 || memory_operand (operands[0], SFmode))"
3184 switch (which_alternative)
3188 return output_387_reg_move (insn, operands);
3191 return standard_80387_constant_opcode (operands[1]);
3195 return "mov{l}\t{%1, %0|%0, %1}";
3198 return standard_sse_constant_opcode (insn, operands[1]);
3201 if (get_attr_mode (insn) == MODE_V4SF)
3202 return "%vmovaps\t{%1, %0|%0, %1}";
3204 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3208 return "%vmovss\t{%1, %0|%0, %1}";
3214 return "movd\t{%1, %0|%0, %1}";
3217 return "movq\t{%1, %0|%0, %1}";
3221 return "%vmovd\t{%1, %0|%0, %1}";
3228 (cond [(eq_attr "alternative" "0,1,2")
3229 (const_string "fmov")
3230 (eq_attr "alternative" "3,4")
3231 (const_string "multi")
3232 (eq_attr "alternative" "5")
3233 (const_string "sselog1")
3234 (eq_attr "alternative" "9,10,11,14,15")
3235 (const_string "mmxmov")
3237 (const_string "ssemov")))
3238 (set (attr "prefix")
3239 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3240 (const_string "maybe_vex")
3241 (const_string "orig")))
3243 (cond [(eq_attr "alternative" "3,4,9,10")
3245 (eq_attr "alternative" "5")
3247 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3248 (match_test "TARGET_SSE2"))
3249 (not (match_test "optimize_function_for_size_p (cfun)")))
3251 (const_string "V4SF"))
3252 /* For architectures resolving dependencies on
3253 whole SSE registers use APS move to break dependency
3254 chains, otherwise use short move to avoid extra work.
3256 Do the same for architectures resolving dependencies on
3257 the parts. While in DF mode it is better to always handle
3258 just register parts, the SF mode is different due to lack
3259 of instructions to load just part of the register. It is
3260 better to maintain the whole registers in single format
3261 to avoid problems on using packed logical operations. */
3262 (eq_attr "alternative" "6")
3264 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3265 (match_test "TARGET_SSE_SPLIT_REGS"))
3266 (const_string "V4SF")
3267 (const_string "SF"))
3268 (eq_attr "alternative" "11")
3269 (const_string "DI")]
3270 (const_string "SF")))])
3273 [(set (match_operand 0 "any_fp_register_operand" "")
3274 (match_operand 1 "memory_operand" ""))]
3276 && (GET_MODE (operands[0]) == TFmode
3277 || GET_MODE (operands[0]) == XFmode
3278 || GET_MODE (operands[0]) == DFmode
3279 || GET_MODE (operands[0]) == SFmode)
3280 && (operands[2] = find_constant_src (insn))"
3281 [(set (match_dup 0) (match_dup 2))]
3283 rtx c = operands[2];
3284 int r = REGNO (operands[0]);
3286 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3287 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3292 [(set (match_operand 0 "any_fp_register_operand" "")
3293 (float_extend (match_operand 1 "memory_operand" "")))]
3295 && (GET_MODE (operands[0]) == TFmode
3296 || GET_MODE (operands[0]) == XFmode
3297 || GET_MODE (operands[0]) == DFmode)
3298 && (operands[2] = find_constant_src (insn))"
3299 [(set (match_dup 0) (match_dup 2))]
3301 rtx c = operands[2];
3302 int r = REGNO (operands[0]);
3304 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3305 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3309 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3311 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3312 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3314 && (standard_80387_constant_p (operands[1]) == 8
3315 || standard_80387_constant_p (operands[1]) == 9)"
3316 [(set (match_dup 0)(match_dup 1))
3318 (neg:X87MODEF (match_dup 0)))]
3322 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3323 if (real_isnegzero (&r))
3324 operands[1] = CONST0_RTX (<MODE>mode);
3326 operands[1] = CONST1_RTX (<MODE>mode);
3330 [(set (match_operand 0 "nonimmediate_operand" "")
3331 (match_operand 1 "general_operand" ""))]
3333 && (GET_MODE (operands[0]) == TFmode
3334 || GET_MODE (operands[0]) == XFmode
3335 || GET_MODE (operands[0]) == DFmode)
3336 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3338 "ix86_split_long_move (operands); DONE;")
3340 (define_insn "swapxf"
3341 [(set (match_operand:XF 0 "register_operand" "+f")
3342 (match_operand:XF 1 "register_operand" "+f"))
3347 if (STACK_TOP_P (operands[0]))
3352 [(set_attr "type" "fxch")
3353 (set_attr "mode" "XF")])
3355 (define_insn "*swap<mode>"
3356 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3357 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3360 "TARGET_80387 || reload_completed"
3362 if (STACK_TOP_P (operands[0]))
3367 [(set_attr "type" "fxch")
3368 (set_attr "mode" "<MODE>")])
3370 ;; Zero extension instructions
3372 (define_expand "zero_extendsidi2"
3373 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3374 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3379 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3384 (define_insn "*zero_extendsidi2_rex64"
3385 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3387 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3390 mov{l}\t{%1, %k0|%k0, %1}
3392 movd\t{%1, %0|%0, %1}
3393 movd\t{%1, %0|%0, %1}
3394 %vmovd\t{%1, %0|%0, %1}
3395 %vmovd\t{%1, %0|%0, %1}"
3396 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3397 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3398 (set_attr "prefix_0f" "0,*,*,*,*,*")
3399 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3402 [(set (match_operand:DI 0 "memory_operand" "")
3403 (zero_extend:DI (match_dup 0)))]
3405 [(set (match_dup 4) (const_int 0))]
3406 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3408 ;; %%% Kill me once multi-word ops are sane.
3409 (define_insn "zero_extendsidi2_1"
3410 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3412 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3413 (clobber (reg:CC FLAGS_REG))]
3419 movd\t{%1, %0|%0, %1}
3420 movd\t{%1, %0|%0, %1}
3421 %vmovd\t{%1, %0|%0, %1}
3422 %vmovd\t{%1, %0|%0, %1}"
3423 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3424 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3425 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3426 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3429 [(set (match_operand:DI 0 "register_operand" "")
3430 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3431 (clobber (reg:CC FLAGS_REG))]
3432 "!TARGET_64BIT && reload_completed
3433 && true_regnum (operands[0]) == true_regnum (operands[1])"
3434 [(set (match_dup 4) (const_int 0))]
3435 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3438 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3439 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3440 (clobber (reg:CC FLAGS_REG))]
3441 "!TARGET_64BIT && reload_completed
3442 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3443 [(set (match_dup 3) (match_dup 1))
3444 (set (match_dup 4) (const_int 0))]
3445 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3447 (define_insn "zero_extend<mode>di2"
3448 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3452 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3453 [(set_attr "type" "imovx")
3454 (set_attr "mode" "SI")])
3456 (define_expand "zero_extendhisi2"
3457 [(set (match_operand:SI 0 "register_operand" "")
3458 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3461 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3463 operands[1] = force_reg (HImode, operands[1]);
3464 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3469 (define_insn_and_split "zero_extendhisi2_and"
3470 [(set (match_operand:SI 0 "register_operand" "=r")
3471 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3472 (clobber (reg:CC FLAGS_REG))]
3473 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3475 "&& reload_completed"
3476 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3477 (clobber (reg:CC FLAGS_REG))])]
3479 [(set_attr "type" "alu1")
3480 (set_attr "mode" "SI")])
3482 (define_insn "*zero_extendhisi2_movzwl"
3483 [(set (match_operand:SI 0 "register_operand" "=r")
3484 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3485 "!TARGET_ZERO_EXTEND_WITH_AND
3486 || optimize_function_for_size_p (cfun)"
3487 "movz{wl|x}\t{%1, %0|%0, %1}"
3488 [(set_attr "type" "imovx")
3489 (set_attr "mode" "SI")])
3491 (define_expand "zero_extendqi<mode>2"
3493 [(set (match_operand:SWI24 0 "register_operand" "")
3494 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3495 (clobber (reg:CC FLAGS_REG))])])
3497 (define_insn "*zero_extendqi<mode>2_and"
3498 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3499 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3500 (clobber (reg:CC FLAGS_REG))]
3501 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3503 [(set_attr "type" "alu1")
3504 (set_attr "mode" "<MODE>")])
3506 ;; When source and destination does not overlap, clear destination
3507 ;; first and then do the movb
3509 [(set (match_operand:SWI24 0 "register_operand" "")
3510 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3511 (clobber (reg:CC FLAGS_REG))]
3513 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3514 && ANY_QI_REG_P (operands[0])
3515 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3516 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3517 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3519 operands[2] = gen_lowpart (QImode, operands[0]);
3520 ix86_expand_clear (operands[0]);
3523 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3524 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3525 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3526 (clobber (reg:CC FLAGS_REG))]
3527 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3529 [(set_attr "type" "imovx,alu1")
3530 (set_attr "mode" "<MODE>")])
3532 ;; For the movzbl case strip only the clobber
3534 [(set (match_operand:SWI24 0 "register_operand" "")
3535 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3536 (clobber (reg:CC FLAGS_REG))]
3538 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3539 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3541 (zero_extend:SWI24 (match_dup 1)))])
3543 ; zero extend to SImode to avoid partial register stalls
3544 (define_insn "*zero_extendqi<mode>2_movzbl"
3545 [(set (match_operand:SWI24 0 "register_operand" "=r")
3546 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3548 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3549 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3550 [(set_attr "type" "imovx")
3551 (set_attr "mode" "SI")])
3553 ;; Rest is handled by single and.
3555 [(set (match_operand:SWI24 0 "register_operand" "")
3556 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3557 (clobber (reg:CC FLAGS_REG))]
3559 && true_regnum (operands[0]) == true_regnum (operands[1])"
3560 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3561 (clobber (reg:CC FLAGS_REG))])])
3563 ;; Sign extension instructions
3565 (define_expand "extendsidi2"
3566 [(set (match_operand:DI 0 "register_operand" "")
3567 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3572 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3577 (define_insn "*extendsidi2_rex64"
3578 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3579 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3583 movs{lq|x}\t{%1, %0|%0, %1}"
3584 [(set_attr "type" "imovx")
3585 (set_attr "mode" "DI")
3586 (set_attr "prefix_0f" "0")
3587 (set_attr "modrm" "0,1")])
3589 (define_insn "extendsidi2_1"
3590 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3591 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3592 (clobber (reg:CC FLAGS_REG))
3593 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3597 ;; Extend to memory case when source register does die.
3599 [(set (match_operand:DI 0 "memory_operand" "")
3600 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3601 (clobber (reg:CC FLAGS_REG))
3602 (clobber (match_operand:SI 2 "register_operand" ""))]
3604 && dead_or_set_p (insn, operands[1])
3605 && !reg_mentioned_p (operands[1], operands[0]))"
3606 [(set (match_dup 3) (match_dup 1))
3607 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3608 (clobber (reg:CC FLAGS_REG))])
3609 (set (match_dup 4) (match_dup 1))]
3610 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3612 ;; Extend to memory case when source register does not die.
3614 [(set (match_operand:DI 0 "memory_operand" "")
3615 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3616 (clobber (reg:CC FLAGS_REG))
3617 (clobber (match_operand:SI 2 "register_operand" ""))]
3621 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3623 emit_move_insn (operands[3], operands[1]);
3625 /* Generate a cltd if possible and doing so it profitable. */
3626 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3627 && true_regnum (operands[1]) == AX_REG
3628 && true_regnum (operands[2]) == DX_REG)
3630 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3634 emit_move_insn (operands[2], operands[1]);
3635 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3637 emit_move_insn (operands[4], operands[2]);
3641 ;; Extend to register case. Optimize case where source and destination
3642 ;; registers match and cases where we can use cltd.
3644 [(set (match_operand:DI 0 "register_operand" "")
3645 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3646 (clobber (reg:CC FLAGS_REG))
3647 (clobber (match_scratch:SI 2 ""))]
3651 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3653 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3654 emit_move_insn (operands[3], operands[1]);
3656 /* Generate a cltd if possible and doing so it profitable. */
3657 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3658 && true_regnum (operands[3]) == AX_REG
3659 && true_regnum (operands[4]) == DX_REG)
3661 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3665 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3666 emit_move_insn (operands[4], operands[1]);
3668 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3672 (define_insn "extend<mode>di2"
3673 [(set (match_operand:DI 0 "register_operand" "=r")
3675 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3677 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3678 [(set_attr "type" "imovx")
3679 (set_attr "mode" "DI")])
3681 (define_insn "extendhisi2"
3682 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3683 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3686 switch (get_attr_prefix_0f (insn))
3689 return "{cwtl|cwde}";
3691 return "movs{wl|x}\t{%1, %0|%0, %1}";
3694 [(set_attr "type" "imovx")
3695 (set_attr "mode" "SI")
3696 (set (attr "prefix_0f")
3697 ;; movsx is short decodable while cwtl is vector decoded.
3698 (if_then_else (and (eq_attr "cpu" "!k6")
3699 (eq_attr "alternative" "0"))
3701 (const_string "1")))
3703 (if_then_else (eq_attr "prefix_0f" "0")
3705 (const_string "1")))])
3707 (define_insn "*extendhisi2_zext"
3708 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3711 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3714 switch (get_attr_prefix_0f (insn))
3717 return "{cwtl|cwde}";
3719 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3722 [(set_attr "type" "imovx")
3723 (set_attr "mode" "SI")
3724 (set (attr "prefix_0f")
3725 ;; movsx is short decodable while cwtl is vector decoded.
3726 (if_then_else (and (eq_attr "cpu" "!k6")
3727 (eq_attr "alternative" "0"))
3729 (const_string "1")))
3731 (if_then_else (eq_attr "prefix_0f" "0")
3733 (const_string "1")))])
3735 (define_insn "extendqisi2"
3736 [(set (match_operand:SI 0 "register_operand" "=r")
3737 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739 "movs{bl|x}\t{%1, %0|%0, %1}"
3740 [(set_attr "type" "imovx")
3741 (set_attr "mode" "SI")])
3743 (define_insn "*extendqisi2_zext"
3744 [(set (match_operand:DI 0 "register_operand" "=r")
3746 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3748 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3749 [(set_attr "type" "imovx")
3750 (set_attr "mode" "SI")])
3752 (define_insn "extendqihi2"
3753 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3754 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3757 switch (get_attr_prefix_0f (insn))
3760 return "{cbtw|cbw}";
3762 return "movs{bw|x}\t{%1, %0|%0, %1}";
3765 [(set_attr "type" "imovx")
3766 (set_attr "mode" "HI")
3767 (set (attr "prefix_0f")
3768 ;; movsx is short decodable while cwtl is vector decoded.
3769 (if_then_else (and (eq_attr "cpu" "!k6")
3770 (eq_attr "alternative" "0"))
3772 (const_string "1")))
3774 (if_then_else (eq_attr "prefix_0f" "0")
3776 (const_string "1")))])
3778 ;; Conversions between float and double.
3780 ;; These are all no-ops in the model used for the 80387.
3781 ;; So just emit moves.
3783 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3785 [(set (match_operand:DF 0 "push_operand" "")
3786 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3788 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3789 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3792 [(set (match_operand:XF 0 "push_operand" "")
3793 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3796 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3797 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3799 (define_expand "extendsfdf2"
3800 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3801 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3802 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3804 /* ??? Needed for compress_float_constant since all fp constants
3805 are TARGET_LEGITIMATE_CONSTANT_P. */
3806 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3808 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3809 && standard_80387_constant_p (operands[1]) > 0)
3811 operands[1] = simplify_const_unary_operation
3812 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3813 emit_move_insn_1 (operands[0], operands[1]);
3816 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3820 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3822 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3824 We do the conversion post reload to avoid producing of 128bit spills
3825 that might lead to ICE on 32bit target. The sequence unlikely combine
3828 [(set (match_operand:DF 0 "register_operand" "")
3830 (match_operand:SF 1 "nonimmediate_operand" "")))]
3831 "TARGET_USE_VECTOR_FP_CONVERTS
3832 && optimize_insn_for_speed_p ()
3833 && reload_completed && SSE_REG_P (operands[0])"
3838 (parallel [(const_int 0) (const_int 1)]))))]
3840 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3841 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3842 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3843 Try to avoid move when unpacking can be done in source. */
3844 if (REG_P (operands[1]))
3846 /* If it is unsafe to overwrite upper half of source, we need
3847 to move to destination and unpack there. */
3848 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3849 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3850 && true_regnum (operands[0]) != true_regnum (operands[1]))
3852 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3853 emit_move_insn (tmp, operands[1]);
3856 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3857 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3861 emit_insn (gen_vec_setv4sf_0 (operands[3],
3862 CONST0_RTX (V4SFmode), operands[1]));
3865 (define_insn "*extendsfdf2_mixed"
3866 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3868 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3869 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3871 switch (which_alternative)
3875 return output_387_reg_move (insn, operands);
3878 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3884 [(set_attr "type" "fmov,fmov,ssecvt")
3885 (set_attr "prefix" "orig,orig,maybe_vex")
3886 (set_attr "mode" "SF,XF,DF")])
3888 (define_insn "*extendsfdf2_sse"
3889 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3890 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3891 "TARGET_SSE2 && TARGET_SSE_MATH"
3892 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3893 [(set_attr "type" "ssecvt")
3894 (set_attr "prefix" "maybe_vex")
3895 (set_attr "mode" "DF")])
3897 (define_insn "*extendsfdf2_i387"
3898 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3899 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3901 "* return output_387_reg_move (insn, operands);"
3902 [(set_attr "type" "fmov")
3903 (set_attr "mode" "SF,XF")])
3905 (define_expand "extend<mode>xf2"
3906 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3907 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3910 /* ??? Needed for compress_float_constant since all fp constants
3911 are TARGET_LEGITIMATE_CONSTANT_P. */
3912 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3914 if (standard_80387_constant_p (operands[1]) > 0)
3916 operands[1] = simplify_const_unary_operation
3917 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3918 emit_move_insn_1 (operands[0], operands[1]);
3921 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3925 (define_insn "*extend<mode>xf2_i387"
3926 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3928 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3930 "* return output_387_reg_move (insn, operands);"
3931 [(set_attr "type" "fmov")
3932 (set_attr "mode" "<MODE>,XF")])
3934 ;; %%% This seems bad bad news.
3935 ;; This cannot output into an f-reg because there is no way to be sure
3936 ;; of truncating in that case. Otherwise this is just like a simple move
3937 ;; insn. So we pretend we can output to a reg in order to get better
3938 ;; register preferencing, but we really use a stack slot.
3940 ;; Conversion from DFmode to SFmode.
3942 (define_expand "truncdfsf2"
3943 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3945 (match_operand:DF 1 "nonimmediate_operand" "")))]
3946 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3948 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3950 else if (flag_unsafe_math_optimizations)
3954 enum ix86_stack_slot slot = (virtuals_instantiated
3957 rtx temp = assign_386_stack_local (SFmode, slot);
3958 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3963 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3965 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3967 We do the conversion post reload to avoid producing of 128bit spills
3968 that might lead to ICE on 32bit target. The sequence unlikely combine
3971 [(set (match_operand:SF 0 "register_operand" "")
3973 (match_operand:DF 1 "nonimmediate_operand" "")))]
3974 "TARGET_USE_VECTOR_FP_CONVERTS
3975 && optimize_insn_for_speed_p ()
3976 && reload_completed && SSE_REG_P (operands[0])"
3979 (float_truncate:V2SF
3983 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3984 operands[3] = CONST0_RTX (V2SFmode);
3985 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3986 /* Use movsd for loading from memory, unpcklpd for registers.
3987 Try to avoid move when unpacking can be done in source, or SSE3
3988 movddup is available. */
3989 if (REG_P (operands[1]))
3992 && true_regnum (operands[0]) != true_regnum (operands[1])
3993 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3994 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3996 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3997 emit_move_insn (tmp, operands[1]);
4000 else if (!TARGET_SSE3)
4001 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4002 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4005 emit_insn (gen_sse2_loadlpd (operands[4],
4006 CONST0_RTX (V2DFmode), operands[1]));
4009 (define_expand "truncdfsf2_with_temp"
4010 [(parallel [(set (match_operand:SF 0 "" "")
4011 (float_truncate:SF (match_operand:DF 1 "" "")))
4012 (clobber (match_operand:SF 2 "" ""))])])
4014 (define_insn "*truncdfsf_fast_mixed"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4017 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4018 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4020 switch (which_alternative)
4023 return output_387_reg_move (insn, operands);
4025 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4030 [(set_attr "type" "fmov,ssecvt")
4031 (set_attr "prefix" "orig,maybe_vex")
4032 (set_attr "mode" "SF")])
4034 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4035 ;; because nothing we do here is unsafe.
4036 (define_insn "*truncdfsf_fast_sse"
4037 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4039 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4040 "TARGET_SSE2 && TARGET_SSE_MATH"
4041 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4042 [(set_attr "type" "ssecvt")
4043 (set_attr "prefix" "maybe_vex")
4044 (set_attr "mode" "SF")])
4046 (define_insn "*truncdfsf_fast_i387"
4047 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4049 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4050 "TARGET_80387 && flag_unsafe_math_optimizations"
4051 "* return output_387_reg_move (insn, operands);"
4052 [(set_attr "type" "fmov")
4053 (set_attr "mode" "SF")])
4055 (define_insn "*truncdfsf_mixed"
4056 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4058 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4059 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4060 "TARGET_MIX_SSE_I387"
4062 switch (which_alternative)
4065 return output_387_reg_move (insn, operands);
4067 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4073 [(set_attr "isa" "*,sse2,*,*,*")
4074 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075 (set_attr "unit" "*,*,i387,i387,i387")
4076 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077 (set_attr "mode" "SF")])
4079 (define_insn "*truncdfsf_i387"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4082 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4086 switch (which_alternative)
4089 return output_387_reg_move (insn, operands);
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "unit" "*,i387,i387,i387")
4097 (set_attr "mode" "SF")])
4099 (define_insn "*truncdfsf2_i387_1"
4100 [(set (match_operand:SF 0 "memory_operand" "=m")
4102 (match_operand:DF 1 "register_operand" "f")))]
4104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105 && !TARGET_MIX_SSE_I387"
4106 "* return output_387_reg_move (insn, operands);"
4107 [(set_attr "type" "fmov")
4108 (set_attr "mode" "SF")])
4111 [(set (match_operand:SF 0 "register_operand" "")
4113 (match_operand:DF 1 "fp_register_operand" "")))
4114 (clobber (match_operand 2 "" ""))]
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 0) (match_dup 2))]
4118 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4120 ;; Conversion from XFmode to {SF,DF}mode
4122 (define_expand "truncxf<mode>2"
4123 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124 (float_truncate:MODEF
4125 (match_operand:XF 1 "register_operand" "")))
4126 (clobber (match_dup 2))])]
4129 if (flag_unsafe_math_optimizations)
4131 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133 if (reg != operands[0])
4134 emit_move_insn (operands[0], reg);
4139 enum ix86_stack_slot slot = (virtuals_instantiated
4142 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4146 (define_insn "*truncxfsf2_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4149 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4153 gcc_assert (!which_alternative);
4154 return output_387_reg_move (insn, operands);
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4160 (define_insn "*truncxfdf2_mixed"
4161 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4163 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4164 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4167 gcc_assert (!which_alternative);
4168 return output_387_reg_move (insn, operands);
4170 [(set_attr "isa" "*,*,sse2,*")
4171 (set_attr "type" "fmov,multi,multi,multi")
4172 (set_attr "unit" "*,i387,i387,i387")
4173 (set_attr "mode" "DF")])
4175 (define_insn "truncxf<mode>2_i387_noop"
4176 [(set (match_operand:MODEF 0 "register_operand" "=f")
4177 (float_truncate:MODEF
4178 (match_operand:XF 1 "register_operand" "f")))]
4179 "TARGET_80387 && flag_unsafe_math_optimizations"
4180 "* return output_387_reg_move (insn, operands);"
4181 [(set_attr "type" "fmov")
4182 (set_attr "mode" "<MODE>")])
4184 (define_insn "*truncxf<mode>2_i387"
4185 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4186 (float_truncate:MODEF
4187 (match_operand:XF 1 "register_operand" "f")))]
4189 "* return output_387_reg_move (insn, operands);"
4190 [(set_attr "type" "fmov")
4191 (set_attr "mode" "<MODE>")])
4194 [(set (match_operand:MODEF 0 "register_operand" "")
4195 (float_truncate:MODEF
4196 (match_operand:XF 1 "register_operand" "")))
4197 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4198 "TARGET_80387 && reload_completed"
4199 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4200 (set (match_dup 0) (match_dup 2))])
4203 [(set (match_operand:MODEF 0 "memory_operand" "")
4204 (float_truncate:MODEF
4205 (match_operand:XF 1 "register_operand" "")))
4206 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4208 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4210 ;; Signed conversion to DImode.
4212 (define_expand "fix_truncxfdi2"
4213 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4214 (fix:DI (match_operand:XF 1 "register_operand" "")))
4215 (clobber (reg:CC FLAGS_REG))])]
4220 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4225 (define_expand "fix_trunc<mode>di2"
4226 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4227 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4228 (clobber (reg:CC FLAGS_REG))])]
4229 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4232 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4234 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4237 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4239 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4240 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4241 if (out != operands[0])
4242 emit_move_insn (operands[0], out);
4247 ;; Signed conversion to SImode.
4249 (define_expand "fix_truncxfsi2"
4250 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4251 (fix:SI (match_operand:XF 1 "register_operand" "")))
4252 (clobber (reg:CC FLAGS_REG))])]
4257 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4262 (define_expand "fix_trunc<mode>si2"
4263 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4264 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4265 (clobber (reg:CC FLAGS_REG))])]
4266 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4269 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4271 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4274 if (SSE_FLOAT_MODE_P (<MODE>mode))
4276 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4277 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4278 if (out != operands[0])
4279 emit_move_insn (operands[0], out);
4284 ;; Signed conversion to HImode.
4286 (define_expand "fix_trunc<mode>hi2"
4287 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4288 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4289 (clobber (reg:CC FLAGS_REG))])]
4291 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4295 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4300 ;; Unsigned conversion to SImode.
4302 (define_expand "fixuns_trunc<mode>si2"
4304 [(set (match_operand:SI 0 "register_operand" "")
4306 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4308 (clobber (match_scratch:<ssevecmode> 3 ""))
4309 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4310 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4312 enum machine_mode mode = <MODE>mode;
4313 enum machine_mode vecmode = <ssevecmode>mode;
4314 REAL_VALUE_TYPE TWO31r;
4317 if (optimize_insn_for_size_p ())
4320 real_ldexp (&TWO31r, &dconst1, 31);
4321 two31 = const_double_from_real_value (TWO31r, mode);
4322 two31 = ix86_build_const_vector (vecmode, true, two31);
4323 operands[2] = force_reg (vecmode, two31);
4326 (define_insn_and_split "*fixuns_trunc<mode>_1"
4327 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4329 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4330 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4331 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4332 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4333 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4334 && optimize_function_for_speed_p (cfun)"
4336 "&& reload_completed"
4339 ix86_split_convert_uns_si_sse (operands);
4343 ;; Unsigned conversion to HImode.
4344 ;; Without these patterns, we'll try the unsigned SI conversion which
4345 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4347 (define_expand "fixuns_trunc<mode>hi2"
4349 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4350 (set (match_operand:HI 0 "nonimmediate_operand" "")
4351 (subreg:HI (match_dup 2) 0))]
4352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4353 "operands[2] = gen_reg_rtx (SImode);")
4355 ;; When SSE is available, it is always faster to use it!
4356 (define_insn "fix_trunc<mode>di_sse"
4357 [(set (match_operand:DI 0 "register_operand" "=r,r")
4358 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4359 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4360 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4361 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4362 [(set_attr "type" "sseicvt")
4363 (set_attr "prefix" "maybe_vex")
4364 (set_attr "prefix_rex" "1")
4365 (set_attr "mode" "<MODE>")
4366 (set_attr "athlon_decode" "double,vector")
4367 (set_attr "amdfam10_decode" "double,double")
4368 (set_attr "bdver1_decode" "double,double")])
4370 (define_insn "fix_trunc<mode>si_sse"
4371 [(set (match_operand:SI 0 "register_operand" "=r,r")
4372 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4373 "SSE_FLOAT_MODE_P (<MODE>mode)
4374 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4375 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4376 [(set_attr "type" "sseicvt")
4377 (set_attr "prefix" "maybe_vex")
4378 (set_attr "mode" "<MODE>")
4379 (set_attr "athlon_decode" "double,vector")
4380 (set_attr "amdfam10_decode" "double,double")
4381 (set_attr "bdver1_decode" "double,double")])
4383 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4385 [(set (match_operand:MODEF 0 "register_operand" "")
4386 (match_operand:MODEF 1 "memory_operand" ""))
4387 (set (match_operand:SWI48x 2 "register_operand" "")
4388 (fix:SWI48x (match_dup 0)))]
4389 "TARGET_SHORTEN_X87_SSE
4390 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4391 && peep2_reg_dead_p (2, operands[0])"
4392 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4394 ;; Avoid vector decoded forms of the instruction.
4396 [(match_scratch:DF 2 "x")
4397 (set (match_operand:SWI48x 0 "register_operand" "")
4398 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4399 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4400 [(set (match_dup 2) (match_dup 1))
4401 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4404 [(match_scratch:SF 2 "x")
4405 (set (match_operand:SWI48x 0 "register_operand" "")
4406 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4407 "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)))])
4411 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4412 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4413 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4414 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4416 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4417 && (TARGET_64BIT || <MODE>mode != DImode))
4419 && can_create_pseudo_p ()"
4424 if (memory_operand (operands[0], VOIDmode))
4425 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4428 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4429 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4435 [(set_attr "type" "fisttp")
4436 (set_attr "mode" "<MODE>")])
4438 (define_insn "fix_trunc<mode>_i387_fisttp"
4439 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4440 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4441 (clobber (match_scratch:XF 2 "=&1f"))]
4442 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4445 && (TARGET_64BIT || <MODE>mode != DImode))
4446 && TARGET_SSE_MATH)"
4447 "* return output_fix_trunc (insn, operands, true);"
4448 [(set_attr "type" "fisttp")
4449 (set_attr "mode" "<MODE>")])
4451 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4452 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4453 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4454 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4455 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4456 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4459 && (TARGET_64BIT || <MODE>mode != DImode))
4460 && TARGET_SSE_MATH)"
4462 [(set_attr "type" "fisttp")
4463 (set_attr "mode" "<MODE>")])
4466 [(set (match_operand:SWI248x 0 "register_operand" "")
4467 (fix:SWI248x (match_operand 1 "register_operand" "")))
4468 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4469 (clobber (match_scratch 3 ""))]
4471 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4472 (clobber (match_dup 3))])
4473 (set (match_dup 0) (match_dup 2))])
4476 [(set (match_operand:SWI248x 0 "memory_operand" "")
4477 (fix:SWI248x (match_operand 1 "register_operand" "")))
4478 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4479 (clobber (match_scratch 3 ""))]
4481 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4482 (clobber (match_dup 3))])])
4484 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4485 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4486 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4487 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4488 ;; function in i386.c.
4489 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4490 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4491 (fix:SWI248x (match_operand 1 "register_operand" "")))
4492 (clobber (reg:CC FLAGS_REG))]
4493 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4496 && (TARGET_64BIT || <MODE>mode != DImode))
4497 && can_create_pseudo_p ()"
4502 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4504 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4505 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4506 if (memory_operand (operands[0], VOIDmode))
4507 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4508 operands[2], operands[3]));
4511 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4512 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4513 operands[2], operands[3],
4518 [(set_attr "type" "fistp")
4519 (set_attr "i387_cw" "trunc")
4520 (set_attr "mode" "<MODE>")])
4522 (define_insn "fix_truncdi_i387"
4523 [(set (match_operand:DI 0 "memory_operand" "=m")
4524 (fix:DI (match_operand 1 "register_operand" "f")))
4525 (use (match_operand:HI 2 "memory_operand" "m"))
4526 (use (match_operand:HI 3 "memory_operand" "m"))
4527 (clobber (match_scratch:XF 4 "=&1f"))]
4528 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4531 "* return output_fix_trunc (insn, operands, false);"
4532 [(set_attr "type" "fistp")
4533 (set_attr "i387_cw" "trunc")
4534 (set_attr "mode" "DI")])
4536 (define_insn "fix_truncdi_i387_with_temp"
4537 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4538 (fix:DI (match_operand 1 "register_operand" "f,f")))
4539 (use (match_operand:HI 2 "memory_operand" "m,m"))
4540 (use (match_operand:HI 3 "memory_operand" "m,m"))
4541 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4542 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4543 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4545 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4547 [(set_attr "type" "fistp")
4548 (set_attr "i387_cw" "trunc")
4549 (set_attr "mode" "DI")])
4552 [(set (match_operand:DI 0 "register_operand" "")
4553 (fix:DI (match_operand 1 "register_operand" "")))
4554 (use (match_operand:HI 2 "memory_operand" ""))
4555 (use (match_operand:HI 3 "memory_operand" ""))
4556 (clobber (match_operand:DI 4 "memory_operand" ""))
4557 (clobber (match_scratch 5 ""))]
4559 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4562 (clobber (match_dup 5))])
4563 (set (match_dup 0) (match_dup 4))])
4566 [(set (match_operand:DI 0 "memory_operand" "")
4567 (fix:DI (match_operand 1 "register_operand" "")))
4568 (use (match_operand:HI 2 "memory_operand" ""))
4569 (use (match_operand:HI 3 "memory_operand" ""))
4570 (clobber (match_operand:DI 4 "memory_operand" ""))
4571 (clobber (match_scratch 5 ""))]
4573 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4576 (clobber (match_dup 5))])])
4578 (define_insn "fix_trunc<mode>_i387"
4579 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4580 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4581 (use (match_operand:HI 2 "memory_operand" "m"))
4582 (use (match_operand:HI 3 "memory_operand" "m"))]
4583 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4586 "* return output_fix_trunc (insn, operands, false);"
4587 [(set_attr "type" "fistp")
4588 (set_attr "i387_cw" "trunc")
4589 (set_attr "mode" "<MODE>")])
4591 (define_insn "fix_trunc<mode>_i387_with_temp"
4592 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4593 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4594 (use (match_operand:HI 2 "memory_operand" "m,m"))
4595 (use (match_operand:HI 3 "memory_operand" "m,m"))
4596 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4597 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4599 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4601 [(set_attr "type" "fistp")
4602 (set_attr "i387_cw" "trunc")
4603 (set_attr "mode" "<MODE>")])
4606 [(set (match_operand:SWI24 0 "register_operand" "")
4607 (fix:SWI24 (match_operand 1 "register_operand" "")))
4608 (use (match_operand:HI 2 "memory_operand" ""))
4609 (use (match_operand:HI 3 "memory_operand" ""))
4610 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4612 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4614 (use (match_dup 3))])
4615 (set (match_dup 0) (match_dup 4))])
4618 [(set (match_operand:SWI24 0 "memory_operand" "")
4619 (fix:SWI24 (match_operand 1 "register_operand" "")))
4620 (use (match_operand:HI 2 "memory_operand" ""))
4621 (use (match_operand:HI 3 "memory_operand" ""))
4622 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4624 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4626 (use (match_dup 3))])])
4628 (define_insn "x86_fnstcw_1"
4629 [(set (match_operand:HI 0 "memory_operand" "=m")
4630 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4633 [(set (attr "length")
4634 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4635 (set_attr "mode" "HI")
4636 (set_attr "unit" "i387")
4637 (set_attr "bdver1_decode" "vector")])
4639 (define_insn "x86_fldcw_1"
4640 [(set (reg:HI FPCR_REG)
4641 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4644 [(set (attr "length")
4645 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4646 (set_attr "mode" "HI")
4647 (set_attr "unit" "i387")
4648 (set_attr "athlon_decode" "vector")
4649 (set_attr "amdfam10_decode" "vector")
4650 (set_attr "bdver1_decode" "vector")])
4652 ;; Conversion between fixed point and floating point.
4654 ;; Even though we only accept memory inputs, the backend _really_
4655 ;; wants to be able to do this between registers.
4657 (define_expand "floathi<mode>2"
4658 [(set (match_operand:X87MODEF 0 "register_operand" "")
4659 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4662 || TARGET_MIX_SSE_I387)")
4664 ;; Pre-reload splitter to add memory clobber to the pattern.
4665 (define_insn_and_split "*floathi<mode>2_1"
4666 [(set (match_operand:X87MODEF 0 "register_operand" "")
4667 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4669 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4670 || TARGET_MIX_SSE_I387)
4671 && can_create_pseudo_p ()"
4674 [(parallel [(set (match_dup 0)
4675 (float:X87MODEF (match_dup 1)))
4676 (clobber (match_dup 2))])]
4677 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4679 (define_insn "*floathi<mode>2_i387_with_temp"
4680 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4681 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4682 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4684 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4685 || TARGET_MIX_SSE_I387)"
4687 [(set_attr "type" "fmov,multi")
4688 (set_attr "mode" "<MODE>")
4689 (set_attr "unit" "*,i387")
4690 (set_attr "fp_int_src" "true")])
4692 (define_insn "*floathi<mode>2_i387"
4693 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4694 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4697 || TARGET_MIX_SSE_I387)"
4699 [(set_attr "type" "fmov")
4700 (set_attr "mode" "<MODE>")
4701 (set_attr "fp_int_src" "true")])
4704 [(set (match_operand:X87MODEF 0 "register_operand" "")
4705 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4706 (clobber (match_operand:HI 2 "memory_operand" ""))]
4708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4709 || TARGET_MIX_SSE_I387)
4710 && reload_completed"
4711 [(set (match_dup 2) (match_dup 1))
4712 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4715 [(set (match_operand:X87MODEF 0 "register_operand" "")
4716 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4717 (clobber (match_operand:HI 2 "memory_operand" ""))]
4719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4720 || TARGET_MIX_SSE_I387)
4721 && reload_completed"
4722 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4724 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4725 [(set (match_operand:X87MODEF 0 "register_operand" "")
4727 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4729 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4730 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4732 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4733 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4734 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4736 rtx reg = gen_reg_rtx (XFmode);
4737 rtx (*insn)(rtx, rtx);
4739 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4741 if (<X87MODEF:MODE>mode == SFmode)
4742 insn = gen_truncxfsf2;
4743 else if (<X87MODEF:MODE>mode == DFmode)
4744 insn = gen_truncxfdf2;
4748 emit_insn (insn (operands[0], reg));
4753 ;; Pre-reload splitter to add memory clobber to the pattern.
4754 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4755 [(set (match_operand:X87MODEF 0 "register_operand" "")
4756 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4758 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4759 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4760 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4761 || TARGET_MIX_SSE_I387))
4762 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4763 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4764 && ((<SWI48x:MODE>mode == SImode
4765 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4766 && optimize_function_for_speed_p (cfun)
4767 && flag_trapping_math)
4768 || !(TARGET_INTER_UNIT_CONVERSIONS
4769 || optimize_function_for_size_p (cfun)))))
4770 && can_create_pseudo_p ()"
4773 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4774 (clobber (match_dup 2))])]
4776 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4778 /* Avoid store forwarding (partial memory) stall penalty
4779 by passing DImode value through XMM registers. */
4780 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4781 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4782 && optimize_function_for_speed_p (cfun))
4784 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4791 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4792 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4794 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4795 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4796 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4797 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4799 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4800 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4801 (set_attr "unit" "*,i387,*,*,*")
4802 (set_attr "athlon_decode" "*,*,double,direct,double")
4803 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4804 (set_attr "bdver1_decode" "*,*,double,direct,double")
4805 (set_attr "fp_int_src" "true")])
4807 (define_insn "*floatsi<mode>2_vector_mixed"
4808 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4809 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4810 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4811 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4815 [(set_attr "type" "fmov,sseicvt")
4816 (set_attr "mode" "<MODE>,<ssevecmode>")
4817 (set_attr "unit" "i387,*")
4818 (set_attr "athlon_decode" "*,direct")
4819 (set_attr "amdfam10_decode" "*,double")
4820 (set_attr "bdver1_decode" "*,direct")
4821 (set_attr "fp_int_src" "true")])
4823 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4824 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4826 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4827 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4828 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4829 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4831 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4832 (set_attr "mode" "<MODEF:MODE>")
4833 (set_attr "unit" "*,i387,*,*")
4834 (set_attr "athlon_decode" "*,*,double,direct")
4835 (set_attr "amdfam10_decode" "*,*,vector,double")
4836 (set_attr "bdver1_decode" "*,*,double,direct")
4837 (set_attr "fp_int_src" "true")])
4840 [(set (match_operand:MODEF 0 "register_operand" "")
4841 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4842 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4843 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4844 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4845 && TARGET_INTER_UNIT_CONVERSIONS
4847 && (SSE_REG_P (operands[0])
4848 || (GET_CODE (operands[0]) == SUBREG
4849 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4850 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4853 [(set (match_operand:MODEF 0 "register_operand" "")
4854 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4855 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4856 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4857 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4858 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4860 && (SSE_REG_P (operands[0])
4861 || (GET_CODE (operands[0]) == SUBREG
4862 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4863 [(set (match_dup 2) (match_dup 1))
4864 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4866 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4867 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4869 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4870 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4871 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4872 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4875 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4876 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4877 [(set_attr "type" "fmov,sseicvt,sseicvt")
4878 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4879 (set_attr "mode" "<MODEF:MODE>")
4880 (set (attr "prefix_rex")
4882 (and (eq_attr "prefix" "maybe_vex")
4883 (match_test "<SWI48x:MODE>mode == DImode"))
4885 (const_string "*")))
4886 (set_attr "unit" "i387,*,*")
4887 (set_attr "athlon_decode" "*,double,direct")
4888 (set_attr "amdfam10_decode" "*,vector,double")
4889 (set_attr "bdver1_decode" "*,double,direct")
4890 (set_attr "fp_int_src" "true")])
4892 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4893 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4895 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4896 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4897 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4898 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4901 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4902 [(set_attr "type" "fmov,sseicvt")
4903 (set_attr "prefix" "orig,maybe_vex")
4904 (set_attr "mode" "<MODEF:MODE>")
4905 (set (attr "prefix_rex")
4907 (and (eq_attr "prefix" "maybe_vex")
4908 (match_test "<SWI48x:MODE>mode == DImode"))
4910 (const_string "*")))
4911 (set_attr "athlon_decode" "*,direct")
4912 (set_attr "amdfam10_decode" "*,double")
4913 (set_attr "bdver1_decode" "*,direct")
4914 (set_attr "fp_int_src" "true")])
4916 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4917 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4919 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4920 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4921 "TARGET_SSE2 && TARGET_SSE_MATH
4922 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4924 [(set_attr "type" "sseicvt")
4925 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4926 (set_attr "athlon_decode" "double,direct,double")
4927 (set_attr "amdfam10_decode" "vector,double,double")
4928 (set_attr "bdver1_decode" "double,direct,double")
4929 (set_attr "fp_int_src" "true")])
4931 (define_insn "*floatsi<mode>2_vector_sse"
4932 [(set (match_operand:MODEF 0 "register_operand" "=x")
4933 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4934 "TARGET_SSE2 && TARGET_SSE_MATH
4935 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4937 [(set_attr "type" "sseicvt")
4938 (set_attr "mode" "<MODE>")
4939 (set_attr "athlon_decode" "direct")
4940 (set_attr "amdfam10_decode" "double")
4941 (set_attr "bdver1_decode" "direct")
4942 (set_attr "fp_int_src" "true")])
4945 [(set (match_operand:MODEF 0 "register_operand" "")
4946 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4947 (clobber (match_operand:SI 2 "memory_operand" ""))]
4948 "TARGET_SSE2 && TARGET_SSE_MATH
4949 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4951 && (SSE_REG_P (operands[0])
4952 || (GET_CODE (operands[0]) == SUBREG
4953 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4956 rtx op1 = operands[1];
4958 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4960 if (GET_CODE (op1) == SUBREG)
4961 op1 = SUBREG_REG (op1);
4963 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4965 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4966 emit_insn (gen_sse2_loadld (operands[4],
4967 CONST0_RTX (V4SImode), operands[1]));
4969 /* We can ignore possible trapping value in the
4970 high part of SSE register for non-trapping math. */
4971 else if (SSE_REG_P (op1) && !flag_trapping_math)
4972 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4975 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4976 emit_move_insn (operands[2], operands[1]);
4977 emit_insn (gen_sse2_loadld (operands[4],
4978 CONST0_RTX (V4SImode), operands[2]));
4980 if (<ssevecmode>mode == V4SFmode)
4981 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4983 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4988 [(set (match_operand:MODEF 0 "register_operand" "")
4989 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4990 (clobber (match_operand:SI 2 "memory_operand" ""))]
4991 "TARGET_SSE2 && TARGET_SSE_MATH
4992 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4994 && (SSE_REG_P (operands[0])
4995 || (GET_CODE (operands[0]) == SUBREG
4996 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4999 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5001 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5003 emit_insn (gen_sse2_loadld (operands[4],
5004 CONST0_RTX (V4SImode), operands[1]));
5005 if (<ssevecmode>mode == V4SFmode)
5006 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5008 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5013 [(set (match_operand:MODEF 0 "register_operand" "")
5014 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5015 "TARGET_SSE2 && TARGET_SSE_MATH
5016 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5018 && (SSE_REG_P (operands[0])
5019 || (GET_CODE (operands[0]) == SUBREG
5020 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5023 rtx op1 = operands[1];
5025 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5027 if (GET_CODE (op1) == SUBREG)
5028 op1 = SUBREG_REG (op1);
5030 if (GENERAL_REG_P (op1))
5032 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5033 if (TARGET_INTER_UNIT_MOVES)
5034 emit_insn (gen_sse2_loadld (operands[4],
5035 CONST0_RTX (V4SImode), operands[1]));
5038 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5040 emit_insn (gen_sse2_loadld (operands[4],
5041 CONST0_RTX (V4SImode), operands[5]));
5042 ix86_free_from_memory (GET_MODE (operands[1]));
5045 /* We can ignore possible trapping value in the
5046 high part of SSE register for non-trapping math. */
5047 else if (SSE_REG_P (op1) && !flag_trapping_math)
5048 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5051 if (<ssevecmode>mode == V4SFmode)
5052 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5054 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5059 [(set (match_operand:MODEF 0 "register_operand" "")
5060 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5061 "TARGET_SSE2 && TARGET_SSE_MATH
5062 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5064 && (SSE_REG_P (operands[0])
5065 || (GET_CODE (operands[0]) == SUBREG
5066 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5069 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5071 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5073 emit_insn (gen_sse2_loadld (operands[4],
5074 CONST0_RTX (V4SImode), operands[1]));
5075 if (<ssevecmode>mode == V4SFmode)
5076 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5078 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5082 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5083 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5085 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5086 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5087 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5088 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5090 [(set_attr "type" "sseicvt")
5091 (set_attr "mode" "<MODEF:MODE>")
5092 (set_attr "athlon_decode" "double,direct")
5093 (set_attr "amdfam10_decode" "vector,double")
5094 (set_attr "bdver1_decode" "double,direct")
5095 (set_attr "fp_int_src" "true")])
5097 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5098 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5100 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5101 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5102 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5103 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5104 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5105 [(set_attr "type" "sseicvt")
5106 (set_attr "prefix" "maybe_vex")
5107 (set_attr "mode" "<MODEF:MODE>")
5108 (set (attr "prefix_rex")
5110 (and (eq_attr "prefix" "maybe_vex")
5111 (match_test "<SWI48x:MODE>mode == DImode"))
5113 (const_string "*")))
5114 (set_attr "athlon_decode" "double,direct")
5115 (set_attr "amdfam10_decode" "vector,double")
5116 (set_attr "bdver1_decode" "double,direct")
5117 (set_attr "fp_int_src" "true")])
5120 [(set (match_operand:MODEF 0 "register_operand" "")
5121 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5122 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5123 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5124 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5125 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5127 && (SSE_REG_P (operands[0])
5128 || (GET_CODE (operands[0]) == SUBREG
5129 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5130 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5132 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5133 [(set (match_operand:MODEF 0 "register_operand" "=x")
5135 (match_operand:SWI48x 1 "memory_operand" "m")))]
5136 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5137 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5138 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5139 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5140 [(set_attr "type" "sseicvt")
5141 (set_attr "prefix" "maybe_vex")
5142 (set_attr "mode" "<MODEF:MODE>")
5143 (set (attr "prefix_rex")
5145 (and (eq_attr "prefix" "maybe_vex")
5146 (match_test "<SWI48x:MODE>mode == DImode"))
5148 (const_string "*")))
5149 (set_attr "athlon_decode" "direct")
5150 (set_attr "amdfam10_decode" "double")
5151 (set_attr "bdver1_decode" "direct")
5152 (set_attr "fp_int_src" "true")])
5155 [(set (match_operand:MODEF 0 "register_operand" "")
5156 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5157 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5158 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5159 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5160 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5162 && (SSE_REG_P (operands[0])
5163 || (GET_CODE (operands[0]) == SUBREG
5164 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5165 [(set (match_dup 2) (match_dup 1))
5166 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5169 [(set (match_operand:MODEF 0 "register_operand" "")
5170 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5171 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5172 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5173 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5175 && (SSE_REG_P (operands[0])
5176 || (GET_CODE (operands[0]) == SUBREG
5177 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5178 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5180 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5181 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5183 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5184 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5186 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5190 [(set_attr "type" "fmov,multi")
5191 (set_attr "mode" "<X87MODEF:MODE>")
5192 (set_attr "unit" "*,i387")
5193 (set_attr "fp_int_src" "true")])
5195 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5196 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5198 (match_operand:SWI48x 1 "memory_operand" "m")))]
5200 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5202 [(set_attr "type" "fmov")
5203 (set_attr "mode" "<X87MODEF:MODE>")
5204 (set_attr "fp_int_src" "true")])
5207 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5208 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5209 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5211 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5212 && reload_completed"
5213 [(set (match_dup 2) (match_dup 1))
5214 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5217 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5218 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5219 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5221 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5222 && reload_completed"
5223 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5225 ;; Avoid store forwarding (partial memory) stall penalty
5226 ;; by passing DImode value through XMM registers. */
5228 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5229 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5231 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5232 (clobber (match_scratch:V4SI 3 "=X,x"))
5233 (clobber (match_scratch:V4SI 4 "=X,x"))
5234 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5235 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5236 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5237 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5239 [(set_attr "type" "multi")
5240 (set_attr "mode" "<X87MODEF:MODE>")
5241 (set_attr "unit" "i387")
5242 (set_attr "fp_int_src" "true")])
5245 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5246 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5247 (clobber (match_scratch:V4SI 3 ""))
5248 (clobber (match_scratch:V4SI 4 ""))
5249 (clobber (match_operand:DI 2 "memory_operand" ""))]
5250 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5251 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5252 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5253 && reload_completed"
5254 [(set (match_dup 2) (match_dup 3))
5255 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5257 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5258 Assemble the 64-bit DImode value in an xmm register. */
5259 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5260 gen_rtx_SUBREG (SImode, operands[1], 0)));
5261 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5262 gen_rtx_SUBREG (SImode, operands[1], 4)));
5263 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5266 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5270 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5271 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5272 (clobber (match_scratch:V4SI 3 ""))
5273 (clobber (match_scratch:V4SI 4 ""))
5274 (clobber (match_operand:DI 2 "memory_operand" ""))]
5275 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5276 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5277 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5278 && reload_completed"
5279 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5281 ;; Avoid store forwarding (partial memory) stall penalty by extending
5282 ;; SImode value to DImode through XMM register instead of pushing two
5283 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5284 ;; targets benefit from this optimization. Also note that fild
5285 ;; loads from memory only.
5287 (define_insn "*floatunssi<mode>2_1"
5288 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5289 (unsigned_float:X87MODEF
5290 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5291 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5292 (clobber (match_scratch:SI 3 "=X,x"))]
5294 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5297 [(set_attr "type" "multi")
5298 (set_attr "mode" "<MODE>")])
5301 [(set (match_operand:X87MODEF 0 "register_operand" "")
5302 (unsigned_float:X87MODEF
5303 (match_operand:SI 1 "register_operand" "")))
5304 (clobber (match_operand:DI 2 "memory_operand" ""))
5305 (clobber (match_scratch:SI 3 ""))]
5307 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5309 && reload_completed"
5310 [(set (match_dup 2) (match_dup 1))
5312 (float:X87MODEF (match_dup 2)))]
5313 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5316 [(set (match_operand:X87MODEF 0 "register_operand" "")
5317 (unsigned_float:X87MODEF
5318 (match_operand:SI 1 "memory_operand" "")))
5319 (clobber (match_operand:DI 2 "memory_operand" ""))
5320 (clobber (match_scratch:SI 3 ""))]
5322 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5324 && reload_completed"
5325 [(set (match_dup 2) (match_dup 3))
5327 (float:X87MODEF (match_dup 2)))]
5329 emit_move_insn (operands[3], operands[1]);
5330 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5333 (define_expand "floatunssi<mode>2"
5335 [(set (match_operand:X87MODEF 0 "register_operand" "")
5336 (unsigned_float:X87MODEF
5337 (match_operand:SI 1 "nonimmediate_operand" "")))
5338 (clobber (match_dup 2))
5339 (clobber (match_scratch:SI 3 ""))])]
5341 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5343 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5345 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5347 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5352 enum ix86_stack_slot slot = (virtuals_instantiated
5355 operands[2] = assign_386_stack_local (DImode, slot);
5359 (define_expand "floatunsdisf2"
5360 [(use (match_operand:SF 0 "register_operand" ""))
5361 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5362 "TARGET_64BIT && TARGET_SSE_MATH"
5363 "x86_emit_floatuns (operands); DONE;")
5365 (define_expand "floatunsdidf2"
5366 [(use (match_operand:DF 0 "register_operand" ""))
5367 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5368 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5369 && TARGET_SSE2 && TARGET_SSE_MATH"
5372 x86_emit_floatuns (operands);
5374 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5378 ;; Load effective address instructions
5380 (define_insn_and_split "*lea<mode>"
5381 [(set (match_operand:SWI48 0 "register_operand" "=r")
5382 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5385 rtx addr = operands[1];
5387 if (GET_CODE (addr) == SUBREG)
5389 gcc_assert (TARGET_64BIT);
5390 gcc_assert (<MODE>mode == SImode);
5391 gcc_assert (GET_MODE (SUBREG_REG (addr)) == DImode);
5392 return "lea{l}\t{%E1, %0|%0, %E1}";
5394 else if (GET_CODE (addr) == ZERO_EXTEND
5395 || GET_CODE (addr) == AND)
5397 gcc_assert (TARGET_64BIT);
5398 gcc_assert (<MODE>mode == DImode);
5399 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5402 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5404 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5407 ix86_split_lea_for_addr (operands, <MODE>mode);
5410 [(set_attr "type" "lea")
5411 (set_attr "mode" "<MODE>")])
5415 (define_expand "add<mode>3"
5416 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5417 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5418 (match_operand:SDWIM 2 "<general_operand>" "")))]
5420 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5422 (define_insn_and_split "*add<dwi>3_doubleword"
5423 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5425 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5426 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5427 (clobber (reg:CC FLAGS_REG))]
5428 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5431 [(parallel [(set (reg:CC FLAGS_REG)
5432 (unspec:CC [(match_dup 1) (match_dup 2)]
5435 (plus:DWIH (match_dup 1) (match_dup 2)))])
5436 (parallel [(set (match_dup 3)
5440 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5442 (clobber (reg:CC FLAGS_REG))])]
5443 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5445 (define_insn "*add<mode>3_cc"
5446 [(set (reg:CC FLAGS_REG)
5448 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5449 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5451 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5452 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5453 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5454 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5455 [(set_attr "type" "alu")
5456 (set_attr "mode" "<MODE>")])
5458 (define_insn "addqi3_cc"
5459 [(set (reg:CC FLAGS_REG)
5461 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5462 (match_operand:QI 2 "general_operand" "qn,qm")]
5464 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5465 (plus:QI (match_dup 1) (match_dup 2)))]
5466 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5467 "add{b}\t{%2, %0|%0, %2}"
5468 [(set_attr "type" "alu")
5469 (set_attr "mode" "QI")])
5471 (define_insn "*add<mode>_1"
5472 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5474 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5475 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5476 (clobber (reg:CC FLAGS_REG))]
5477 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5479 switch (get_attr_type (insn))
5485 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5486 if (operands[2] == const1_rtx)
5487 return "inc{<imodesuffix>}\t%0";
5490 gcc_assert (operands[2] == constm1_rtx);
5491 return "dec{<imodesuffix>}\t%0";
5495 /* For most processors, ADD is faster than LEA. This alternative
5496 was added to use ADD as much as possible. */
5497 if (which_alternative == 2)
5500 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5503 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5504 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5505 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5507 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5511 (cond [(eq_attr "alternative" "3")
5512 (const_string "lea")
5513 (match_operand:SWI48 2 "incdec_operand" "")
5514 (const_string "incdec")
5516 (const_string "alu")))
5517 (set (attr "length_immediate")
5519 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5521 (const_string "*")))
5522 (set_attr "mode" "<MODE>")])
5524 ;; It may seem that nonimmediate operand is proper one for operand 1.
5525 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5526 ;; we take care in ix86_binary_operator_ok to not allow two memory
5527 ;; operands so proper swapping will be done in reload. This allow
5528 ;; patterns constructed from addsi_1 to match.
5530 (define_insn "addsi_1_zext"
5531 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5533 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5534 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5535 (clobber (reg:CC FLAGS_REG))]
5536 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5538 switch (get_attr_type (insn))
5544 if (operands[2] == const1_rtx)
5545 return "inc{l}\t%k0";
5548 gcc_assert (operands[2] == constm1_rtx);
5549 return "dec{l}\t%k0";
5553 /* For most processors, ADD is faster than LEA. This alternative
5554 was added to use ADD as much as possible. */
5555 if (which_alternative == 1)
5558 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5561 if (x86_maybe_negate_const_int (&operands[2], SImode))
5562 return "sub{l}\t{%2, %k0|%k0, %2}";
5564 return "add{l}\t{%2, %k0|%k0, %2}";
5568 (cond [(eq_attr "alternative" "2")
5569 (const_string "lea")
5570 (match_operand:SI 2 "incdec_operand" "")
5571 (const_string "incdec")
5573 (const_string "alu")))
5574 (set (attr "length_immediate")
5576 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5578 (const_string "*")))
5579 (set_attr "mode" "SI")])
5581 (define_insn "*addhi_1"
5582 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5583 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5584 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5585 (clobber (reg:CC FLAGS_REG))]
5586 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5588 switch (get_attr_type (insn))
5594 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5595 if (operands[2] == const1_rtx)
5596 return "inc{w}\t%0";
5599 gcc_assert (operands[2] == constm1_rtx);
5600 return "dec{w}\t%0";
5604 /* For most processors, ADD is faster than LEA. This alternative
5605 was added to use ADD as much as possible. */
5606 if (which_alternative == 2)
5609 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5612 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5613 if (x86_maybe_negate_const_int (&operands[2], HImode))
5614 return "sub{w}\t{%2, %0|%0, %2}";
5616 return "add{w}\t{%2, %0|%0, %2}";
5620 (cond [(eq_attr "alternative" "3")
5621 (const_string "lea")
5622 (match_operand:HI 2 "incdec_operand" "")
5623 (const_string "incdec")
5625 (const_string "alu")))
5626 (set (attr "length_immediate")
5628 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5630 (const_string "*")))
5631 (set_attr "mode" "HI,HI,HI,SI")])
5633 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5634 (define_insn "*addqi_1"
5635 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5636 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5637 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5638 (clobber (reg:CC FLAGS_REG))]
5639 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5641 bool widen = (which_alternative == 3 || which_alternative == 4);
5643 switch (get_attr_type (insn))
5649 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5650 if (operands[2] == const1_rtx)
5651 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5654 gcc_assert (operands[2] == constm1_rtx);
5655 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5659 /* For most processors, ADD is faster than LEA. These alternatives
5660 were added to use ADD as much as possible. */
5661 if (which_alternative == 2 || which_alternative == 4)
5664 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5667 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5668 if (x86_maybe_negate_const_int (&operands[2], QImode))
5671 return "sub{l}\t{%2, %k0|%k0, %2}";
5673 return "sub{b}\t{%2, %0|%0, %2}";
5676 return "add{l}\t{%k2, %k0|%k0, %k2}";
5678 return "add{b}\t{%2, %0|%0, %2}";
5682 (cond [(eq_attr "alternative" "5")
5683 (const_string "lea")
5684 (match_operand:QI 2 "incdec_operand" "")
5685 (const_string "incdec")
5687 (const_string "alu")))
5688 (set (attr "length_immediate")
5690 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5692 (const_string "*")))
5693 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5695 (define_insn "*addqi_1_slp"
5696 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5697 (plus:QI (match_dup 0)
5698 (match_operand:QI 1 "general_operand" "qn,qm")))
5699 (clobber (reg:CC FLAGS_REG))]
5700 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5701 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5703 switch (get_attr_type (insn))
5706 if (operands[1] == const1_rtx)
5707 return "inc{b}\t%0";
5710 gcc_assert (operands[1] == constm1_rtx);
5711 return "dec{b}\t%0";
5715 if (x86_maybe_negate_const_int (&operands[1], QImode))
5716 return "sub{b}\t{%1, %0|%0, %1}";
5718 return "add{b}\t{%1, %0|%0, %1}";
5722 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5723 (const_string "incdec")
5724 (const_string "alu1")))
5725 (set (attr "memory")
5726 (if_then_else (match_operand 1 "memory_operand" "")
5727 (const_string "load")
5728 (const_string "none")))
5729 (set_attr "mode" "QI")])
5731 ;; Split non destructive adds if we cannot use lea.
5733 [(set (match_operand:SWI48 0 "register_operand" "")
5734 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5735 (match_operand:SWI48 2 "nonmemory_operand" "")))
5736 (clobber (reg:CC FLAGS_REG))]
5737 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5738 [(set (match_dup 0) (match_dup 1))
5739 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5740 (clobber (reg:CC FLAGS_REG))])])
5742 ;; Convert add to the lea pattern to avoid flags dependency.
5744 [(set (match_operand:SWI 0 "register_operand" "")
5745 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5746 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5747 (clobber (reg:CC FLAGS_REG))]
5748 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5751 enum machine_mode mode = <MODE>mode;
5754 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5757 operands[0] = gen_lowpart (mode, operands[0]);
5758 operands[1] = gen_lowpart (mode, operands[1]);
5759 operands[2] = gen_lowpart (mode, operands[2]);
5762 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5764 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5768 ;; Convert add to the lea pattern to avoid flags dependency.
5770 [(set (match_operand:DI 0 "register_operand" "")
5772 (plus:SI (match_operand:SI 1 "register_operand" "")
5773 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5774 (clobber (reg:CC FLAGS_REG))]
5775 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5777 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5779 (define_insn "*add<mode>_2"
5780 [(set (reg FLAGS_REG)
5783 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5784 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5786 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5787 (plus:SWI (match_dup 1) (match_dup 2)))]
5788 "ix86_match_ccmode (insn, CCGOCmode)
5789 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5791 switch (get_attr_type (insn))
5794 if (operands[2] == const1_rtx)
5795 return "inc{<imodesuffix>}\t%0";
5798 gcc_assert (operands[2] == constm1_rtx);
5799 return "dec{<imodesuffix>}\t%0";
5803 if (which_alternative == 2)
5806 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5809 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5810 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5811 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5813 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5817 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5818 (const_string "incdec")
5819 (const_string "alu")))
5820 (set (attr "length_immediate")
5822 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5824 (const_string "*")))
5825 (set_attr "mode" "<MODE>")])
5827 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5828 (define_insn "*addsi_2_zext"
5829 [(set (reg FLAGS_REG)
5831 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5832 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5834 (set (match_operand:DI 0 "register_operand" "=r,r")
5835 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5836 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5837 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5839 switch (get_attr_type (insn))
5842 if (operands[2] == const1_rtx)
5843 return "inc{l}\t%k0";
5846 gcc_assert (operands[2] == constm1_rtx);
5847 return "dec{l}\t%k0";
5851 if (which_alternative == 1)
5854 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5857 if (x86_maybe_negate_const_int (&operands[2], SImode))
5858 return "sub{l}\t{%2, %k0|%k0, %2}";
5860 return "add{l}\t{%2, %k0|%k0, %2}";
5864 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5865 (const_string "incdec")
5866 (const_string "alu")))
5867 (set (attr "length_immediate")
5869 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5871 (const_string "*")))
5872 (set_attr "mode" "SI")])
5874 (define_insn "*add<mode>_3"
5875 [(set (reg FLAGS_REG)
5877 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5878 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5879 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5880 "ix86_match_ccmode (insn, CCZmode)
5881 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5883 switch (get_attr_type (insn))
5886 if (operands[2] == const1_rtx)
5887 return "inc{<imodesuffix>}\t%0";
5890 gcc_assert (operands[2] == constm1_rtx);
5891 return "dec{<imodesuffix>}\t%0";
5895 if (which_alternative == 1)
5898 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5901 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5902 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5903 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5905 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5909 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5910 (const_string "incdec")
5911 (const_string "alu")))
5912 (set (attr "length_immediate")
5914 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5916 (const_string "*")))
5917 (set_attr "mode" "<MODE>")])
5919 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5920 (define_insn "*addsi_3_zext"
5921 [(set (reg FLAGS_REG)
5923 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5924 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5925 (set (match_operand:DI 0 "register_operand" "=r,r")
5926 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5927 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5928 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5930 switch (get_attr_type (insn))
5933 if (operands[2] == const1_rtx)
5934 return "inc{l}\t%k0";
5937 gcc_assert (operands[2] == constm1_rtx);
5938 return "dec{l}\t%k0";
5942 if (which_alternative == 1)
5945 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5948 if (x86_maybe_negate_const_int (&operands[2], SImode))
5949 return "sub{l}\t{%2, %k0|%k0, %2}";
5951 return "add{l}\t{%2, %k0|%k0, %2}";
5955 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5956 (const_string "incdec")
5957 (const_string "alu")))
5958 (set (attr "length_immediate")
5960 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5962 (const_string "*")))
5963 (set_attr "mode" "SI")])
5965 ; For comparisons against 1, -1 and 128, we may generate better code
5966 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5967 ; is matched then. We can't accept general immediate, because for
5968 ; case of overflows, the result is messed up.
5969 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5970 ; only for comparisons not depending on it.
5972 (define_insn "*adddi_4"
5973 [(set (reg FLAGS_REG)
5975 (match_operand:DI 1 "nonimmediate_operand" "0")
5976 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5977 (clobber (match_scratch:DI 0 "=rm"))]
5979 && ix86_match_ccmode (insn, CCGCmode)"
5981 switch (get_attr_type (insn))
5984 if (operands[2] == constm1_rtx)
5985 return "inc{q}\t%0";
5988 gcc_assert (operands[2] == const1_rtx);
5989 return "dec{q}\t%0";
5993 if (x86_maybe_negate_const_int (&operands[2], DImode))
5994 return "add{q}\t{%2, %0|%0, %2}";
5996 return "sub{q}\t{%2, %0|%0, %2}";
6000 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6001 (const_string "incdec")
6002 (const_string "alu")))
6003 (set (attr "length_immediate")
6005 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6007 (const_string "*")))
6008 (set_attr "mode" "DI")])
6010 ; For comparisons against 1, -1 and 128, we may generate better code
6011 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6012 ; is matched then. We can't accept general immediate, because for
6013 ; case of overflows, the result is messed up.
6014 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6015 ; only for comparisons not depending on it.
6017 (define_insn "*add<mode>_4"
6018 [(set (reg FLAGS_REG)
6020 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6021 (match_operand:SWI124 2 "const_int_operand" "n")))
6022 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6023 "ix86_match_ccmode (insn, CCGCmode)"
6025 switch (get_attr_type (insn))
6028 if (operands[2] == constm1_rtx)
6029 return "inc{<imodesuffix>}\t%0";
6032 gcc_assert (operands[2] == const1_rtx);
6033 return "dec{<imodesuffix>}\t%0";
6037 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6038 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6040 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6044 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6045 (const_string "incdec")
6046 (const_string "alu")))
6047 (set (attr "length_immediate")
6049 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6051 (const_string "*")))
6052 (set_attr "mode" "<MODE>")])
6054 (define_insn "*add<mode>_5"
6055 [(set (reg FLAGS_REG)
6058 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6059 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6061 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6062 "ix86_match_ccmode (insn, CCGOCmode)
6063 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6065 switch (get_attr_type (insn))
6068 if (operands[2] == const1_rtx)
6069 return "inc{<imodesuffix>}\t%0";
6072 gcc_assert (operands[2] == constm1_rtx);
6073 return "dec{<imodesuffix>}\t%0";
6077 if (which_alternative == 1)
6080 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6083 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6084 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6085 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6087 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6091 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6092 (const_string "incdec")
6093 (const_string "alu")))
6094 (set (attr "length_immediate")
6096 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6098 (const_string "*")))
6099 (set_attr "mode" "<MODE>")])
6101 (define_insn "*addqi_ext_1_rex64"
6102 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6107 (match_operand 1 "ext_register_operand" "0")
6110 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6111 (clobber (reg:CC FLAGS_REG))]
6114 switch (get_attr_type (insn))
6117 if (operands[2] == const1_rtx)
6118 return "inc{b}\t%h0";
6121 gcc_assert (operands[2] == constm1_rtx);
6122 return "dec{b}\t%h0";
6126 return "add{b}\t{%2, %h0|%h0, %2}";
6130 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6131 (const_string "incdec")
6132 (const_string "alu")))
6133 (set_attr "modrm" "1")
6134 (set_attr "mode" "QI")])
6136 (define_insn "addqi_ext_1"
6137 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6142 (match_operand 1 "ext_register_operand" "0")
6145 (match_operand:QI 2 "general_operand" "Qmn")))
6146 (clobber (reg:CC FLAGS_REG))]
6149 switch (get_attr_type (insn))
6152 if (operands[2] == const1_rtx)
6153 return "inc{b}\t%h0";
6156 gcc_assert (operands[2] == constm1_rtx);
6157 return "dec{b}\t%h0";
6161 return "add{b}\t{%2, %h0|%h0, %2}";
6165 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6166 (const_string "incdec")
6167 (const_string "alu")))
6168 (set_attr "modrm" "1")
6169 (set_attr "mode" "QI")])
6171 (define_insn "*addqi_ext_2"
6172 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6177 (match_operand 1 "ext_register_operand" "%0")
6181 (match_operand 2 "ext_register_operand" "Q")
6184 (clobber (reg:CC FLAGS_REG))]
6186 "add{b}\t{%h2, %h0|%h0, %h2}"
6187 [(set_attr "type" "alu")
6188 (set_attr "mode" "QI")])
6190 ;; The lea patterns for modes less than 32 bits need to be matched by
6191 ;; several insns converted to real lea by splitters.
6193 (define_insn_and_split "*lea_general_1"
6194 [(set (match_operand 0 "register_operand" "=r")
6195 (plus (plus (match_operand 1 "index_register_operand" "l")
6196 (match_operand 2 "register_operand" "r"))
6197 (match_operand 3 "immediate_operand" "i")))]
6198 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6199 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6200 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6201 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6202 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6203 || GET_MODE (operands[3]) == VOIDmode)"
6205 "&& reload_completed"
6208 enum machine_mode mode = SImode;
6211 operands[0] = gen_lowpart (mode, operands[0]);
6212 operands[1] = gen_lowpart (mode, operands[1]);
6213 operands[2] = gen_lowpart (mode, operands[2]);
6214 operands[3] = gen_lowpart (mode, operands[3]);
6216 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6219 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6222 [(set_attr "type" "lea")
6223 (set_attr "mode" "SI")])
6225 (define_insn_and_split "*lea_general_2"
6226 [(set (match_operand 0 "register_operand" "=r")
6227 (plus (mult (match_operand 1 "index_register_operand" "l")
6228 (match_operand 2 "const248_operand" "n"))
6229 (match_operand 3 "nonmemory_operand" "ri")))]
6230 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6231 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6232 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6233 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6234 || GET_MODE (operands[3]) == VOIDmode)"
6236 "&& reload_completed"
6239 enum machine_mode mode = SImode;
6242 operands[0] = gen_lowpart (mode, operands[0]);
6243 operands[1] = gen_lowpart (mode, operands[1]);
6244 operands[3] = gen_lowpart (mode, operands[3]);
6246 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6249 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6252 [(set_attr "type" "lea")
6253 (set_attr "mode" "SI")])
6255 (define_insn_and_split "*lea_general_3"
6256 [(set (match_operand 0 "register_operand" "=r")
6257 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6258 (match_operand 2 "const248_operand" "n"))
6259 (match_operand 3 "register_operand" "r"))
6260 (match_operand 4 "immediate_operand" "i")))]
6261 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6262 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6263 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6264 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6266 "&& reload_completed"
6269 enum machine_mode mode = SImode;
6272 operands[0] = gen_lowpart (mode, operands[0]);
6273 operands[1] = gen_lowpart (mode, operands[1]);
6274 operands[3] = gen_lowpart (mode, operands[3]);
6275 operands[4] = gen_lowpart (mode, operands[4]);
6277 pat = gen_rtx_PLUS (mode,
6279 gen_rtx_MULT (mode, operands[1],
6284 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6287 [(set_attr "type" "lea")
6288 (set_attr "mode" "SI")])
6290 (define_insn_and_split "*lea_general_4"
6291 [(set (match_operand 0 "register_operand" "=r")
6293 (match_operand 1 "index_register_operand" "l")
6294 (match_operand 2 "const_int_operand" "n"))
6295 (match_operand 3 "const_int_operand" "n")))]
6296 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6297 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6298 || GET_MODE (operands[0]) == SImode
6299 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6300 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6301 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6302 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6303 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6305 "&& reload_completed"
6308 enum machine_mode mode = GET_MODE (operands[0]);
6311 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6314 operands[0] = gen_lowpart (mode, operands[0]);
6315 operands[1] = gen_lowpart (mode, operands[1]);
6318 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6320 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6321 INTVAL (operands[3]));
6323 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6326 [(set_attr "type" "lea")
6328 (if_then_else (match_operand:DI 0 "" "")
6330 (const_string "SI")))])
6332 ;; Subtract instructions
6334 (define_expand "sub<mode>3"
6335 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6336 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6337 (match_operand:SDWIM 2 "<general_operand>" "")))]
6339 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6341 (define_insn_and_split "*sub<dwi>3_doubleword"
6342 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6344 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6345 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6346 (clobber (reg:CC FLAGS_REG))]
6347 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6350 [(parallel [(set (reg:CC FLAGS_REG)
6351 (compare:CC (match_dup 1) (match_dup 2)))
6353 (minus:DWIH (match_dup 1) (match_dup 2)))])
6354 (parallel [(set (match_dup 3)
6358 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6360 (clobber (reg:CC FLAGS_REG))])]
6361 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6363 (define_insn "*sub<mode>_1"
6364 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6366 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6367 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6368 (clobber (reg:CC FLAGS_REG))]
6369 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6370 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6371 [(set_attr "type" "alu")
6372 (set_attr "mode" "<MODE>")])
6374 (define_insn "*subsi_1_zext"
6375 [(set (match_operand:DI 0 "register_operand" "=r")
6377 (minus:SI (match_operand:SI 1 "register_operand" "0")
6378 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6379 (clobber (reg:CC FLAGS_REG))]
6380 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6381 "sub{l}\t{%2, %k0|%k0, %2}"
6382 [(set_attr "type" "alu")
6383 (set_attr "mode" "SI")])
6385 (define_insn "*subqi_1_slp"
6386 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6387 (minus:QI (match_dup 0)
6388 (match_operand:QI 1 "general_operand" "qn,qm")))
6389 (clobber (reg:CC FLAGS_REG))]
6390 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6391 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6392 "sub{b}\t{%1, %0|%0, %1}"
6393 [(set_attr "type" "alu1")
6394 (set_attr "mode" "QI")])
6396 (define_insn "*sub<mode>_2"
6397 [(set (reg FLAGS_REG)
6400 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6401 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6403 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6404 (minus:SWI (match_dup 1) (match_dup 2)))]
6405 "ix86_match_ccmode (insn, CCGOCmode)
6406 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6407 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6408 [(set_attr "type" "alu")
6409 (set_attr "mode" "<MODE>")])
6411 (define_insn "*subsi_2_zext"
6412 [(set (reg FLAGS_REG)
6414 (minus:SI (match_operand:SI 1 "register_operand" "0")
6415 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6417 (set (match_operand:DI 0 "register_operand" "=r")
6419 (minus:SI (match_dup 1)
6421 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6422 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6423 "sub{l}\t{%2, %k0|%k0, %2}"
6424 [(set_attr "type" "alu")
6425 (set_attr "mode" "SI")])
6427 (define_insn "*sub<mode>_3"
6428 [(set (reg FLAGS_REG)
6429 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6430 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6431 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6432 (minus:SWI (match_dup 1) (match_dup 2)))]
6433 "ix86_match_ccmode (insn, CCmode)
6434 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6435 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6436 [(set_attr "type" "alu")
6437 (set_attr "mode" "<MODE>")])
6439 (define_insn "*subsi_3_zext"
6440 [(set (reg FLAGS_REG)
6441 (compare (match_operand:SI 1 "register_operand" "0")
6442 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6443 (set (match_operand:DI 0 "register_operand" "=r")
6445 (minus:SI (match_dup 1)
6447 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6448 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6449 "sub{l}\t{%2, %1|%1, %2}"
6450 [(set_attr "type" "alu")
6451 (set_attr "mode" "SI")])
6453 ;; Add with carry and subtract with borrow
6455 (define_expand "<plusminus_insn><mode>3_carry"
6457 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6459 (match_operand:SWI 1 "nonimmediate_operand" "")
6460 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6461 [(match_operand 3 "flags_reg_operand" "")
6463 (match_operand:SWI 2 "<general_operand>" ""))))
6464 (clobber (reg:CC FLAGS_REG))])]
6465 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6467 (define_insn "*<plusminus_insn><mode>3_carry"
6468 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6470 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6472 (match_operator 3 "ix86_carry_flag_operator"
6473 [(reg FLAGS_REG) (const_int 0)])
6474 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6475 (clobber (reg:CC FLAGS_REG))]
6476 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6477 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6478 [(set_attr "type" "alu")
6479 (set_attr "use_carry" "1")
6480 (set_attr "pent_pair" "pu")
6481 (set_attr "mode" "<MODE>")])
6483 (define_insn "*addsi3_carry_zext"
6484 [(set (match_operand:DI 0 "register_operand" "=r")
6486 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6487 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6488 [(reg FLAGS_REG) (const_int 0)])
6489 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6490 (clobber (reg:CC FLAGS_REG))]
6491 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6492 "adc{l}\t{%2, %k0|%k0, %2}"
6493 [(set_attr "type" "alu")
6494 (set_attr "use_carry" "1")
6495 (set_attr "pent_pair" "pu")
6496 (set_attr "mode" "SI")])
6498 (define_insn "*subsi3_carry_zext"
6499 [(set (match_operand:DI 0 "register_operand" "=r")
6501 (minus:SI (match_operand:SI 1 "register_operand" "0")
6502 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6503 [(reg FLAGS_REG) (const_int 0)])
6504 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6505 (clobber (reg:CC FLAGS_REG))]
6506 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6507 "sbb{l}\t{%2, %k0|%k0, %2}"
6508 [(set_attr "type" "alu")
6509 (set_attr "pent_pair" "pu")
6510 (set_attr "mode" "SI")])
6512 ;; Overflow setting add and subtract instructions
6514 (define_insn "*add<mode>3_cconly_overflow"
6515 [(set (reg:CCC FLAGS_REG)
6518 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6519 (match_operand:SWI 2 "<general_operand>" "<g>"))
6521 (clobber (match_scratch:SWI 0 "=<r>"))]
6522 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6523 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6524 [(set_attr "type" "alu")
6525 (set_attr "mode" "<MODE>")])
6527 (define_insn "*sub<mode>3_cconly_overflow"
6528 [(set (reg:CCC FLAGS_REG)
6531 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6532 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6535 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6536 [(set_attr "type" "icmp")
6537 (set_attr "mode" "<MODE>")])
6539 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6540 [(set (reg:CCC FLAGS_REG)
6543 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6544 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6546 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6547 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6548 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6549 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6550 [(set_attr "type" "alu")
6551 (set_attr "mode" "<MODE>")])
6553 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6554 [(set (reg:CCC FLAGS_REG)
6557 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6558 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6560 (set (match_operand:DI 0 "register_operand" "=r")
6561 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6562 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6563 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6564 [(set_attr "type" "alu")
6565 (set_attr "mode" "SI")])
6567 ;; The patterns that match these are at the end of this file.
6569 (define_expand "<plusminus_insn>xf3"
6570 [(set (match_operand:XF 0 "register_operand" "")
6572 (match_operand:XF 1 "register_operand" "")
6573 (match_operand:XF 2 "register_operand" "")))]
6576 (define_expand "<plusminus_insn><mode>3"
6577 [(set (match_operand:MODEF 0 "register_operand" "")
6579 (match_operand:MODEF 1 "register_operand" "")
6580 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6581 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6582 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6584 ;; Multiply instructions
6586 (define_expand "mul<mode>3"
6587 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6589 (match_operand:SWIM248 1 "register_operand" "")
6590 (match_operand:SWIM248 2 "<general_operand>" "")))
6591 (clobber (reg:CC FLAGS_REG))])])
6593 (define_expand "mulqi3"
6594 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6596 (match_operand:QI 1 "register_operand" "")
6597 (match_operand:QI 2 "nonimmediate_operand" "")))
6598 (clobber (reg:CC FLAGS_REG))])]
6599 "TARGET_QIMODE_MATH")
6602 ;; IMUL reg32/64, reg32/64, imm8 Direct
6603 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6604 ;; IMUL reg32/64, reg32/64, imm32 Direct
6605 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6606 ;; IMUL reg32/64, reg32/64 Direct
6607 ;; IMUL reg32/64, mem32/64 Direct
6609 ;; On BDVER1, all above IMULs use DirectPath
6611 (define_insn "*mul<mode>3_1"
6612 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6614 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6615 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6616 (clobber (reg:CC FLAGS_REG))]
6617 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6619 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6620 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6621 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6622 [(set_attr "type" "imul")
6623 (set_attr "prefix_0f" "0,0,1")
6624 (set (attr "athlon_decode")
6625 (cond [(eq_attr "cpu" "athlon")
6626 (const_string "vector")
6627 (eq_attr "alternative" "1")
6628 (const_string "vector")
6629 (and (eq_attr "alternative" "2")
6630 (match_operand 1 "memory_operand" ""))
6631 (const_string "vector")]
6632 (const_string "direct")))
6633 (set (attr "amdfam10_decode")
6634 (cond [(and (eq_attr "alternative" "0,1")
6635 (match_operand 1 "memory_operand" ""))
6636 (const_string "vector")]
6637 (const_string "direct")))
6638 (set_attr "bdver1_decode" "direct")
6639 (set_attr "mode" "<MODE>")])
6641 (define_insn "*mulsi3_1_zext"
6642 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6644 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6645 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6646 (clobber (reg:CC FLAGS_REG))]
6648 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6650 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6651 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6652 imul{l}\t{%2, %k0|%k0, %2}"
6653 [(set_attr "type" "imul")
6654 (set_attr "prefix_0f" "0,0,1")
6655 (set (attr "athlon_decode")
6656 (cond [(eq_attr "cpu" "athlon")
6657 (const_string "vector")
6658 (eq_attr "alternative" "1")
6659 (const_string "vector")
6660 (and (eq_attr "alternative" "2")
6661 (match_operand 1 "memory_operand" ""))
6662 (const_string "vector")]
6663 (const_string "direct")))
6664 (set (attr "amdfam10_decode")
6665 (cond [(and (eq_attr "alternative" "0,1")
6666 (match_operand 1 "memory_operand" ""))
6667 (const_string "vector")]
6668 (const_string "direct")))
6669 (set_attr "bdver1_decode" "direct")
6670 (set_attr "mode" "SI")])
6673 ;; IMUL reg16, reg16, imm8 VectorPath
6674 ;; IMUL reg16, mem16, imm8 VectorPath
6675 ;; IMUL reg16, reg16, imm16 VectorPath
6676 ;; IMUL reg16, mem16, imm16 VectorPath
6677 ;; IMUL reg16, reg16 Direct
6678 ;; IMUL reg16, mem16 Direct
6680 ;; On BDVER1, all HI MULs use DoublePath
6682 (define_insn "*mulhi3_1"
6683 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6684 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6685 (match_operand:HI 2 "general_operand" "K,n,mr")))
6686 (clobber (reg:CC FLAGS_REG))]
6688 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6690 imul{w}\t{%2, %1, %0|%0, %1, %2}
6691 imul{w}\t{%2, %1, %0|%0, %1, %2}
6692 imul{w}\t{%2, %0|%0, %2}"
6693 [(set_attr "type" "imul")
6694 (set_attr "prefix_0f" "0,0,1")
6695 (set (attr "athlon_decode")
6696 (cond [(eq_attr "cpu" "athlon")
6697 (const_string "vector")
6698 (eq_attr "alternative" "1,2")
6699 (const_string "vector")]
6700 (const_string "direct")))
6701 (set (attr "amdfam10_decode")
6702 (cond [(eq_attr "alternative" "0,1")
6703 (const_string "vector")]
6704 (const_string "direct")))
6705 (set_attr "bdver1_decode" "double")
6706 (set_attr "mode" "HI")])
6708 ;;On AMDFAM10 and BDVER1
6712 (define_insn "*mulqi3_1"
6713 [(set (match_operand:QI 0 "register_operand" "=a")
6714 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6715 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6716 (clobber (reg:CC FLAGS_REG))]
6718 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6720 [(set_attr "type" "imul")
6721 (set_attr "length_immediate" "0")
6722 (set (attr "athlon_decode")
6723 (if_then_else (eq_attr "cpu" "athlon")
6724 (const_string "vector")
6725 (const_string "direct")))
6726 (set_attr "amdfam10_decode" "direct")
6727 (set_attr "bdver1_decode" "direct")
6728 (set_attr "mode" "QI")])
6730 (define_expand "<u>mul<mode><dwi>3"
6731 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6734 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6736 (match_operand:DWIH 2 "register_operand" ""))))
6737 (clobber (reg:CC FLAGS_REG))])])
6739 (define_expand "<u>mulqihi3"
6740 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6743 (match_operand:QI 1 "nonimmediate_operand" ""))
6745 (match_operand:QI 2 "register_operand" ""))))
6746 (clobber (reg:CC FLAGS_REG))])]
6747 "TARGET_QIMODE_MATH")
6749 (define_insn "*bmi2_umulditi3_1"
6750 [(set (match_operand:DI 0 "register_operand" "=r")
6752 (match_operand:DI 2 "nonimmediate_operand" "%d")
6753 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6754 (set (match_operand:DI 1 "register_operand" "=r")
6757 (mult:TI (zero_extend:TI (match_dup 2))
6758 (zero_extend:TI (match_dup 3)))
6760 "TARGET_64BIT && TARGET_BMI2
6761 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6762 "mulx\t{%3, %0, %1|%1, %0, %3}"
6763 [(set_attr "type" "imulx")
6764 (set_attr "prefix" "vex")
6765 (set_attr "mode" "DI")])
6767 (define_insn "*bmi2_umulsidi3_1"
6768 [(set (match_operand:SI 0 "register_operand" "=r")
6770 (match_operand:SI 2 "nonimmediate_operand" "%d")
6771 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6772 (set (match_operand:SI 1 "register_operand" "=r")
6775 (mult:DI (zero_extend:DI (match_dup 2))
6776 (zero_extend:DI (match_dup 3)))
6778 "!TARGET_64BIT && TARGET_BMI2
6779 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6780 "mulx\t{%3, %0, %1|%1, %0, %3}"
6781 [(set_attr "type" "imulx")
6782 (set_attr "prefix" "vex")
6783 (set_attr "mode" "SI")])
6785 (define_insn "*umul<mode><dwi>3_1"
6786 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6789 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6791 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6792 (clobber (reg:CC FLAGS_REG))]
6793 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6795 mul{<imodesuffix>}\t%2
6797 [(set_attr "isa" "*,bmi2")
6798 (set_attr "type" "imul,imulx")
6799 (set_attr "length_immediate" "0,*")
6800 (set (attr "athlon_decode")
6801 (cond [(eq_attr "alternative" "0")
6802 (if_then_else (eq_attr "cpu" "athlon")
6803 (const_string "vector")
6804 (const_string "double"))]
6805 (const_string "*")))
6806 (set_attr "amdfam10_decode" "double,*")
6807 (set_attr "bdver1_decode" "direct,*")
6808 (set_attr "prefix" "orig,vex")
6809 (set_attr "mode" "<MODE>")])
6811 ;; Convert mul to the mulx pattern to avoid flags dependency.
6813 [(set (match_operand:<DWI> 0 "register_operand" "")
6816 (match_operand:DWIH 1 "register_operand" ""))
6818 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6819 (clobber (reg:CC FLAGS_REG))]
6820 "TARGET_BMI2 && reload_completed
6821 && true_regnum (operands[1]) == DX_REG"
6822 [(parallel [(set (match_dup 3)
6823 (mult:DWIH (match_dup 1) (match_dup 2)))
6827 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6828 (zero_extend:<DWI> (match_dup 2)))
6831 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6833 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6836 (define_insn "*mul<mode><dwi>3_1"
6837 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6840 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6842 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6843 (clobber (reg:CC FLAGS_REG))]
6844 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6845 "imul{<imodesuffix>}\t%2"
6846 [(set_attr "type" "imul")
6847 (set_attr "length_immediate" "0")
6848 (set (attr "athlon_decode")
6849 (if_then_else (eq_attr "cpu" "athlon")
6850 (const_string "vector")
6851 (const_string "double")))
6852 (set_attr "amdfam10_decode" "double")
6853 (set_attr "bdver1_decode" "direct")
6854 (set_attr "mode" "<MODE>")])
6856 (define_insn "*<u>mulqihi3_1"
6857 [(set (match_operand:HI 0 "register_operand" "=a")
6860 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6862 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6863 (clobber (reg:CC FLAGS_REG))]
6865 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6866 "<sgnprefix>mul{b}\t%2"
6867 [(set_attr "type" "imul")
6868 (set_attr "length_immediate" "0")
6869 (set (attr "athlon_decode")
6870 (if_then_else (eq_attr "cpu" "athlon")
6871 (const_string "vector")
6872 (const_string "direct")))
6873 (set_attr "amdfam10_decode" "direct")
6874 (set_attr "bdver1_decode" "direct")
6875 (set_attr "mode" "QI")])
6877 (define_expand "<s>mul<mode>3_highpart"
6878 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6883 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6885 (match_operand:SWI48 2 "register_operand" "")))
6887 (clobber (match_scratch:SWI48 3 ""))
6888 (clobber (reg:CC FLAGS_REG))])]
6890 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6892 (define_insn "*<s>muldi3_highpart_1"
6893 [(set (match_operand:DI 0 "register_operand" "=d")
6898 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6900 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6902 (clobber (match_scratch:DI 3 "=1"))
6903 (clobber (reg:CC FLAGS_REG))]
6905 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6906 "<sgnprefix>mul{q}\t%2"
6907 [(set_attr "type" "imul")
6908 (set_attr "length_immediate" "0")
6909 (set (attr "athlon_decode")
6910 (if_then_else (eq_attr "cpu" "athlon")
6911 (const_string "vector")
6912 (const_string "double")))
6913 (set_attr "amdfam10_decode" "double")
6914 (set_attr "bdver1_decode" "direct")
6915 (set_attr "mode" "DI")])
6917 (define_insn "*<s>mulsi3_highpart_1"
6918 [(set (match_operand:SI 0 "register_operand" "=d")
6923 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6925 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6927 (clobber (match_scratch:SI 3 "=1"))
6928 (clobber (reg:CC FLAGS_REG))]
6929 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6930 "<sgnprefix>mul{l}\t%2"
6931 [(set_attr "type" "imul")
6932 (set_attr "length_immediate" "0")
6933 (set (attr "athlon_decode")
6934 (if_then_else (eq_attr "cpu" "athlon")
6935 (const_string "vector")
6936 (const_string "double")))
6937 (set_attr "amdfam10_decode" "double")
6938 (set_attr "bdver1_decode" "direct")
6939 (set_attr "mode" "SI")])
6941 (define_insn "*<s>mulsi3_highpart_zext"
6942 [(set (match_operand:DI 0 "register_operand" "=d")
6943 (zero_extend:DI (truncate:SI
6945 (mult:DI (any_extend:DI
6946 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6948 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6950 (clobber (match_scratch:SI 3 "=1"))
6951 (clobber (reg:CC FLAGS_REG))]
6953 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6954 "<sgnprefix>mul{l}\t%2"
6955 [(set_attr "type" "imul")
6956 (set_attr "length_immediate" "0")
6957 (set (attr "athlon_decode")
6958 (if_then_else (eq_attr "cpu" "athlon")
6959 (const_string "vector")
6960 (const_string "double")))
6961 (set_attr "amdfam10_decode" "double")
6962 (set_attr "bdver1_decode" "direct")
6963 (set_attr "mode" "SI")])
6965 ;; The patterns that match these are at the end of this file.
6967 (define_expand "mulxf3"
6968 [(set (match_operand:XF 0 "register_operand" "")
6969 (mult:XF (match_operand:XF 1 "register_operand" "")
6970 (match_operand:XF 2 "register_operand" "")))]
6973 (define_expand "mul<mode>3"
6974 [(set (match_operand:MODEF 0 "register_operand" "")
6975 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6976 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6977 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6978 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6980 ;; Divide instructions
6982 ;; The patterns that match these are at the end of this file.
6984 (define_expand "divxf3"
6985 [(set (match_operand:XF 0 "register_operand" "")
6986 (div:XF (match_operand:XF 1 "register_operand" "")
6987 (match_operand:XF 2 "register_operand" "")))]
6990 (define_expand "divdf3"
6991 [(set (match_operand:DF 0 "register_operand" "")
6992 (div:DF (match_operand:DF 1 "register_operand" "")
6993 (match_operand:DF 2 "nonimmediate_operand" "")))]
6994 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6995 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6997 (define_expand "divsf3"
6998 [(set (match_operand:SF 0 "register_operand" "")
6999 (div:SF (match_operand:SF 1 "register_operand" "")
7000 (match_operand:SF 2 "nonimmediate_operand" "")))]
7001 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7006 && optimize_insn_for_speed_p ()
7007 && flag_finite_math_only && !flag_trapping_math
7008 && flag_unsafe_math_optimizations)
7010 ix86_emit_swdivsf (operands[0], operands[1],
7011 operands[2], SFmode);
7016 ;; Divmod instructions.
7018 (define_expand "divmod<mode>4"
7019 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7021 (match_operand:SWIM248 1 "register_operand" "")
7022 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7023 (set (match_operand:SWIM248 3 "register_operand" "")
7024 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7025 (clobber (reg:CC FLAGS_REG))])])
7027 ;; Split with 8bit unsigned divide:
7028 ;; if (dividend an divisor are in [0-255])
7029 ;; use 8bit unsigned integer divide
7031 ;; use original integer divide
7033 [(set (match_operand:SWI48 0 "register_operand" "")
7034 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7035 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7036 (set (match_operand:SWI48 1 "register_operand" "")
7037 (mod:SWI48 (match_dup 2) (match_dup 3)))
7038 (clobber (reg:CC FLAGS_REG))]
7039 "TARGET_USE_8BIT_IDIV
7040 && TARGET_QIMODE_MATH
7041 && can_create_pseudo_p ()
7042 && !optimize_insn_for_size_p ()"
7044 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7046 (define_insn_and_split "divmod<mode>4_1"
7047 [(set (match_operand:SWI48 0 "register_operand" "=a")
7048 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7049 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7050 (set (match_operand:SWI48 1 "register_operand" "=&d")
7051 (mod:SWI48 (match_dup 2) (match_dup 3)))
7052 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7053 (clobber (reg:CC FLAGS_REG))]
7057 [(parallel [(set (match_dup 1)
7058 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7059 (clobber (reg:CC FLAGS_REG))])
7060 (parallel [(set (match_dup 0)
7061 (div:SWI48 (match_dup 2) (match_dup 3)))
7063 (mod:SWI48 (match_dup 2) (match_dup 3)))
7065 (clobber (reg:CC FLAGS_REG))])]
7067 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7069 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7070 operands[4] = operands[2];
7073 /* Avoid use of cltd in favor of a mov+shift. */
7074 emit_move_insn (operands[1], operands[2]);
7075 operands[4] = operands[1];
7078 [(set_attr "type" "multi")
7079 (set_attr "mode" "<MODE>")])
7081 (define_insn_and_split "*divmod<mode>4"
7082 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7083 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7084 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7085 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7086 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7087 (clobber (reg:CC FLAGS_REG))]
7091 [(parallel [(set (match_dup 1)
7092 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7093 (clobber (reg:CC FLAGS_REG))])
7094 (parallel [(set (match_dup 0)
7095 (div:SWIM248 (match_dup 2) (match_dup 3)))
7097 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7099 (clobber (reg:CC FLAGS_REG))])]
7101 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7103 if (<MODE>mode != HImode
7104 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7105 operands[4] = operands[2];
7108 /* Avoid use of cltd in favor of a mov+shift. */
7109 emit_move_insn (operands[1], operands[2]);
7110 operands[4] = operands[1];
7113 [(set_attr "type" "multi")
7114 (set_attr "mode" "<MODE>")])
7116 (define_insn "*divmod<mode>4_noext"
7117 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7118 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7119 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7120 (set (match_operand:SWIM248 1 "register_operand" "=d")
7121 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7122 (use (match_operand:SWIM248 4 "register_operand" "1"))
7123 (clobber (reg:CC FLAGS_REG))]
7125 "idiv{<imodesuffix>}\t%3"
7126 [(set_attr "type" "idiv")
7127 (set_attr "mode" "<MODE>")])
7129 (define_expand "divmodqi4"
7130 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7132 (match_operand:QI 1 "register_operand" "")
7133 (match_operand:QI 2 "nonimmediate_operand" "")))
7134 (set (match_operand:QI 3 "register_operand" "")
7135 (mod:QI (match_dup 1) (match_dup 2)))
7136 (clobber (reg:CC FLAGS_REG))])]
7137 "TARGET_QIMODE_MATH"
7142 tmp0 = gen_reg_rtx (HImode);
7143 tmp1 = gen_reg_rtx (HImode);
7145 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7147 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7148 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7150 /* Extract remainder from AH. */
7151 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7152 insn = emit_move_insn (operands[3], tmp1);
7154 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7155 set_unique_reg_note (insn, REG_EQUAL, mod);
7157 /* Extract quotient from AL. */
7158 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7160 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7161 set_unique_reg_note (insn, REG_EQUAL, div);
7166 ;; Divide AX by r/m8, with result stored in
7169 ;; Change div/mod to HImode and extend the second argument to HImode
7170 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7171 ;; combine may fail.
7172 (define_insn "divmodhiqi3"
7173 [(set (match_operand:HI 0 "register_operand" "=a")
7178 (mod:HI (match_operand:HI 1 "register_operand" "0")
7180 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7184 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7185 (clobber (reg:CC FLAGS_REG))]
7186 "TARGET_QIMODE_MATH"
7188 [(set_attr "type" "idiv")
7189 (set_attr "mode" "QI")])
7191 (define_expand "udivmod<mode>4"
7192 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7194 (match_operand:SWIM248 1 "register_operand" "")
7195 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7196 (set (match_operand:SWIM248 3 "register_operand" "")
7197 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7198 (clobber (reg:CC FLAGS_REG))])])
7200 ;; Split with 8bit unsigned divide:
7201 ;; if (dividend an divisor are in [0-255])
7202 ;; use 8bit unsigned integer divide
7204 ;; use original integer divide
7206 [(set (match_operand:SWI48 0 "register_operand" "")
7207 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7208 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7209 (set (match_operand:SWI48 1 "register_operand" "")
7210 (umod:SWI48 (match_dup 2) (match_dup 3)))
7211 (clobber (reg:CC FLAGS_REG))]
7212 "TARGET_USE_8BIT_IDIV
7213 && TARGET_QIMODE_MATH
7214 && can_create_pseudo_p ()
7215 && !optimize_insn_for_size_p ()"
7217 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7219 (define_insn_and_split "udivmod<mode>4_1"
7220 [(set (match_operand:SWI48 0 "register_operand" "=a")
7221 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7222 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7223 (set (match_operand:SWI48 1 "register_operand" "=&d")
7224 (umod:SWI48 (match_dup 2) (match_dup 3)))
7225 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7226 (clobber (reg:CC FLAGS_REG))]
7230 [(set (match_dup 1) (const_int 0))
7231 (parallel [(set (match_dup 0)
7232 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7234 (umod:SWI48 (match_dup 2) (match_dup 3)))
7236 (clobber (reg:CC FLAGS_REG))])]
7238 [(set_attr "type" "multi")
7239 (set_attr "mode" "<MODE>")])
7241 (define_insn_and_split "*udivmod<mode>4"
7242 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7243 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7244 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7245 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7246 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7247 (clobber (reg:CC FLAGS_REG))]
7251 [(set (match_dup 1) (const_int 0))
7252 (parallel [(set (match_dup 0)
7253 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7255 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7257 (clobber (reg:CC FLAGS_REG))])]
7259 [(set_attr "type" "multi")
7260 (set_attr "mode" "<MODE>")])
7262 (define_insn "*udivmod<mode>4_noext"
7263 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7264 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7265 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7266 (set (match_operand:SWIM248 1 "register_operand" "=d")
7267 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7268 (use (match_operand:SWIM248 4 "register_operand" "1"))
7269 (clobber (reg:CC FLAGS_REG))]
7271 "div{<imodesuffix>}\t%3"
7272 [(set_attr "type" "idiv")
7273 (set_attr "mode" "<MODE>")])
7275 (define_expand "udivmodqi4"
7276 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7278 (match_operand:QI 1 "register_operand" "")
7279 (match_operand:QI 2 "nonimmediate_operand" "")))
7280 (set (match_operand:QI 3 "register_operand" "")
7281 (umod:QI (match_dup 1) (match_dup 2)))
7282 (clobber (reg:CC FLAGS_REG))])]
7283 "TARGET_QIMODE_MATH"
7288 tmp0 = gen_reg_rtx (HImode);
7289 tmp1 = gen_reg_rtx (HImode);
7291 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7293 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7294 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7296 /* Extract remainder from AH. */
7297 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7298 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7299 insn = emit_move_insn (operands[3], tmp1);
7301 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7302 set_unique_reg_note (insn, REG_EQUAL, mod);
7304 /* Extract quotient from AL. */
7305 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7307 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7308 set_unique_reg_note (insn, REG_EQUAL, div);
7313 (define_insn "udivmodhiqi3"
7314 [(set (match_operand:HI 0 "register_operand" "=a")
7319 (mod:HI (match_operand:HI 1 "register_operand" "0")
7321 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7325 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7326 (clobber (reg:CC FLAGS_REG))]
7327 "TARGET_QIMODE_MATH"
7329 [(set_attr "type" "idiv")
7330 (set_attr "mode" "QI")])
7332 ;; We cannot use div/idiv for double division, because it causes
7333 ;; "division by zero" on the overflow and that's not what we expect
7334 ;; from truncate. Because true (non truncating) double division is
7335 ;; never generated, we can't create this insn anyway.
7338 ; [(set (match_operand:SI 0 "register_operand" "=a")
7340 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7342 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7343 ; (set (match_operand:SI 3 "register_operand" "=d")
7345 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7346 ; (clobber (reg:CC FLAGS_REG))]
7348 ; "div{l}\t{%2, %0|%0, %2}"
7349 ; [(set_attr "type" "idiv")])
7351 ;;- Logical AND instructions
7353 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7354 ;; Note that this excludes ah.
7356 (define_expand "testsi_ccno_1"
7357 [(set (reg:CCNO FLAGS_REG)
7359 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7360 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7363 (define_expand "testqi_ccz_1"
7364 [(set (reg:CCZ FLAGS_REG)
7365 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7366 (match_operand:QI 1 "nonmemory_operand" ""))
7369 (define_expand "testdi_ccno_1"
7370 [(set (reg:CCNO FLAGS_REG)
7372 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7373 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7375 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7377 (define_insn "*testdi_1"
7378 [(set (reg FLAGS_REG)
7381 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7382 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7384 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7385 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7387 test{l}\t{%k1, %k0|%k0, %k1}
7388 test{l}\t{%k1, %k0|%k0, %k1}
7389 test{q}\t{%1, %0|%0, %1}
7390 test{q}\t{%1, %0|%0, %1}
7391 test{q}\t{%1, %0|%0, %1}"
7392 [(set_attr "type" "test")
7393 (set_attr "modrm" "0,1,0,1,1")
7394 (set_attr "mode" "SI,SI,DI,DI,DI")])
7396 (define_insn "*testqi_1_maybe_si"
7397 [(set (reg FLAGS_REG)
7400 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7401 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7403 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7404 && ix86_match_ccmode (insn,
7405 CONST_INT_P (operands[1])
7406 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7408 if (which_alternative == 3)
7410 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7411 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7412 return "test{l}\t{%1, %k0|%k0, %1}";
7414 return "test{b}\t{%1, %0|%0, %1}";
7416 [(set_attr "type" "test")
7417 (set_attr "modrm" "0,1,1,1")
7418 (set_attr "mode" "QI,QI,QI,SI")
7419 (set_attr "pent_pair" "uv,np,uv,np")])
7421 (define_insn "*test<mode>_1"
7422 [(set (reg FLAGS_REG)
7425 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7426 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7428 "ix86_match_ccmode (insn, CCNOmode)
7429 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7430 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7431 [(set_attr "type" "test")
7432 (set_attr "modrm" "0,1,1")
7433 (set_attr "mode" "<MODE>")
7434 (set_attr "pent_pair" "uv,np,uv")])
7436 (define_expand "testqi_ext_ccno_0"
7437 [(set (reg:CCNO FLAGS_REG)
7441 (match_operand 0 "ext_register_operand" "")
7444 (match_operand 1 "const_int_operand" ""))
7447 (define_insn "*testqi_ext_0"
7448 [(set (reg FLAGS_REG)
7452 (match_operand 0 "ext_register_operand" "Q")
7455 (match_operand 1 "const_int_operand" "n"))
7457 "ix86_match_ccmode (insn, CCNOmode)"
7458 "test{b}\t{%1, %h0|%h0, %1}"
7459 [(set_attr "type" "test")
7460 (set_attr "mode" "QI")
7461 (set_attr "length_immediate" "1")
7462 (set_attr "modrm" "1")
7463 (set_attr "pent_pair" "np")])
7465 (define_insn "*testqi_ext_1_rex64"
7466 [(set (reg FLAGS_REG)
7470 (match_operand 0 "ext_register_operand" "Q")
7474 (match_operand:QI 1 "register_operand" "Q")))
7476 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7477 "test{b}\t{%1, %h0|%h0, %1}"
7478 [(set_attr "type" "test")
7479 (set_attr "mode" "QI")])
7481 (define_insn "*testqi_ext_1"
7482 [(set (reg FLAGS_REG)
7486 (match_operand 0 "ext_register_operand" "Q")
7490 (match_operand:QI 1 "general_operand" "Qm")))
7492 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7493 "test{b}\t{%1, %h0|%h0, %1}"
7494 [(set_attr "type" "test")
7495 (set_attr "mode" "QI")])
7497 (define_insn "*testqi_ext_2"
7498 [(set (reg FLAGS_REG)
7502 (match_operand 0 "ext_register_operand" "Q")
7506 (match_operand 1 "ext_register_operand" "Q")
7510 "ix86_match_ccmode (insn, CCNOmode)"
7511 "test{b}\t{%h1, %h0|%h0, %h1}"
7512 [(set_attr "type" "test")
7513 (set_attr "mode" "QI")])
7515 (define_insn "*testqi_ext_3_rex64"
7516 [(set (reg FLAGS_REG)
7517 (compare (zero_extract:DI
7518 (match_operand 0 "nonimmediate_operand" "rm")
7519 (match_operand:DI 1 "const_int_operand" "")
7520 (match_operand:DI 2 "const_int_operand" ""))
7523 && ix86_match_ccmode (insn, CCNOmode)
7524 && INTVAL (operands[1]) > 0
7525 && INTVAL (operands[2]) >= 0
7526 /* Ensure that resulting mask is zero or sign extended operand. */
7527 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7528 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7529 && INTVAL (operands[1]) > 32))
7530 && (GET_MODE (operands[0]) == SImode
7531 || GET_MODE (operands[0]) == DImode
7532 || GET_MODE (operands[0]) == HImode
7533 || GET_MODE (operands[0]) == QImode)"
7536 ;; Combine likes to form bit extractions for some tests. Humor it.
7537 (define_insn "*testqi_ext_3"
7538 [(set (reg FLAGS_REG)
7539 (compare (zero_extract:SI
7540 (match_operand 0 "nonimmediate_operand" "rm")
7541 (match_operand:SI 1 "const_int_operand" "")
7542 (match_operand:SI 2 "const_int_operand" ""))
7544 "ix86_match_ccmode (insn, CCNOmode)
7545 && INTVAL (operands[1]) > 0
7546 && INTVAL (operands[2]) >= 0
7547 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7548 && (GET_MODE (operands[0]) == SImode
7549 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7550 || GET_MODE (operands[0]) == HImode
7551 || GET_MODE (operands[0]) == QImode)"
7555 [(set (match_operand 0 "flags_reg_operand" "")
7556 (match_operator 1 "compare_operator"
7558 (match_operand 2 "nonimmediate_operand" "")
7559 (match_operand 3 "const_int_operand" "")
7560 (match_operand 4 "const_int_operand" ""))
7562 "ix86_match_ccmode (insn, CCNOmode)"
7563 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7565 rtx val = operands[2];
7566 HOST_WIDE_INT len = INTVAL (operands[3]);
7567 HOST_WIDE_INT pos = INTVAL (operands[4]);
7569 enum machine_mode mode, submode;
7571 mode = GET_MODE (val);
7574 /* ??? Combine likes to put non-volatile mem extractions in QImode
7575 no matter the size of the test. So find a mode that works. */
7576 if (! MEM_VOLATILE_P (val))
7578 mode = smallest_mode_for_size (pos + len, MODE_INT);
7579 val = adjust_address (val, mode, 0);
7582 else if (GET_CODE (val) == SUBREG
7583 && (submode = GET_MODE (SUBREG_REG (val)),
7584 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7585 && pos + len <= GET_MODE_BITSIZE (submode)
7586 && GET_MODE_CLASS (submode) == MODE_INT)
7588 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7590 val = SUBREG_REG (val);
7592 else if (mode == HImode && pos + len <= 8)
7594 /* Small HImode tests can be converted to QImode. */
7596 val = gen_lowpart (QImode, val);
7599 if (len == HOST_BITS_PER_WIDE_INT)
7602 mask = ((HOST_WIDE_INT)1 << len) - 1;
7605 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7608 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7609 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7610 ;; this is relatively important trick.
7611 ;; Do the conversion only post-reload to avoid limiting of the register class
7614 [(set (match_operand 0 "flags_reg_operand" "")
7615 (match_operator 1 "compare_operator"
7616 [(and (match_operand 2 "register_operand" "")
7617 (match_operand 3 "const_int_operand" ""))
7620 && QI_REG_P (operands[2])
7621 && GET_MODE (operands[2]) != QImode
7622 && ((ix86_match_ccmode (insn, CCZmode)
7623 && !(INTVAL (operands[3]) & ~(255 << 8)))
7624 || (ix86_match_ccmode (insn, CCNOmode)
7625 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7628 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7632 operands[2] = gen_lowpart (SImode, operands[2]);
7633 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7637 [(set (match_operand 0 "flags_reg_operand" "")
7638 (match_operator 1 "compare_operator"
7639 [(and (match_operand 2 "nonimmediate_operand" "")
7640 (match_operand 3 "const_int_operand" ""))
7643 && GET_MODE (operands[2]) != QImode
7644 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7645 && ((ix86_match_ccmode (insn, CCZmode)
7646 && !(INTVAL (operands[3]) & ~255))
7647 || (ix86_match_ccmode (insn, CCNOmode)
7648 && !(INTVAL (operands[3]) & ~127)))"
7650 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7653 operands[2] = gen_lowpart (QImode, operands[2]);
7654 operands[3] = gen_lowpart (QImode, operands[3]);
7657 ;; %%% This used to optimize known byte-wide and operations to memory,
7658 ;; and sometimes to QImode registers. If this is considered useful,
7659 ;; it should be done with splitters.
7661 (define_expand "and<mode>3"
7662 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7663 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7664 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7667 if (<MODE>mode == DImode
7668 && GET_CODE (operands[2]) == CONST_INT
7669 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7670 && REG_P (operands[1]))
7671 emit_insn (gen_zero_extendsidi2 (operands[0],
7672 gen_lowpart (SImode, operands[1])));
7674 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7678 (define_insn "*anddi_1"
7679 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7681 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7682 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7683 (clobber (reg:CC FLAGS_REG))]
7684 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7686 switch (get_attr_type (insn))
7690 enum machine_mode mode;
7692 gcc_assert (CONST_INT_P (operands[2]));
7693 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7695 else if (INTVAL (operands[2]) == 0xffff)
7699 gcc_assert (INTVAL (operands[2]) == 0xff);
7703 operands[1] = gen_lowpart (mode, operands[1]);
7705 return "mov{l}\t{%1, %k0|%k0, %1}";
7706 else if (mode == HImode)
7707 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7709 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7713 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7714 if (get_attr_mode (insn) == MODE_SI)
7715 return "and{l}\t{%k2, %k0|%k0, %k2}";
7717 return "and{q}\t{%2, %0|%0, %2}";
7720 [(set_attr "type" "alu,alu,alu,imovx")
7721 (set_attr "length_immediate" "*,*,*,0")
7722 (set (attr "prefix_rex")
7724 (and (eq_attr "type" "imovx")
7725 (and (match_test "INTVAL (operands[2]) == 0xff")
7726 (match_operand 1 "ext_QIreg_operand" "")))
7728 (const_string "*")))
7729 (set_attr "mode" "SI,DI,DI,SI")])
7731 (define_insn "*andsi_1"
7732 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7733 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7734 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7735 (clobber (reg:CC FLAGS_REG))]
7736 "ix86_binary_operator_ok (AND, SImode, operands)"
7738 switch (get_attr_type (insn))
7742 enum machine_mode mode;
7744 gcc_assert (CONST_INT_P (operands[2]));
7745 if (INTVAL (operands[2]) == 0xffff)
7749 gcc_assert (INTVAL (operands[2]) == 0xff);
7753 operands[1] = gen_lowpart (mode, operands[1]);
7755 return "movz{wl|x}\t{%1, %0|%0, %1}";
7757 return "movz{bl|x}\t{%1, %0|%0, %1}";
7761 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7762 return "and{l}\t{%2, %0|%0, %2}";
7765 [(set_attr "type" "alu,alu,imovx")
7766 (set (attr "prefix_rex")
7768 (and (eq_attr "type" "imovx")
7769 (and (match_test "INTVAL (operands[2]) == 0xff")
7770 (match_operand 1 "ext_QIreg_operand" "")))
7772 (const_string "*")))
7773 (set_attr "length_immediate" "*,*,0")
7774 (set_attr "mode" "SI")])
7776 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7777 (define_insn "*andsi_1_zext"
7778 [(set (match_operand:DI 0 "register_operand" "=r")
7780 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7781 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7782 (clobber (reg:CC FLAGS_REG))]
7783 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7784 "and{l}\t{%2, %k0|%k0, %2}"
7785 [(set_attr "type" "alu")
7786 (set_attr "mode" "SI")])
7788 (define_insn "*andhi_1"
7789 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7790 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7791 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7792 (clobber (reg:CC FLAGS_REG))]
7793 "ix86_binary_operator_ok (AND, HImode, operands)"
7795 switch (get_attr_type (insn))
7798 gcc_assert (CONST_INT_P (operands[2]));
7799 gcc_assert (INTVAL (operands[2]) == 0xff);
7800 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7803 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7805 return "and{w}\t{%2, %0|%0, %2}";
7808 [(set_attr "type" "alu,alu,imovx")
7809 (set_attr "length_immediate" "*,*,0")
7810 (set (attr "prefix_rex")
7812 (and (eq_attr "type" "imovx")
7813 (match_operand 1 "ext_QIreg_operand" ""))
7815 (const_string "*")))
7816 (set_attr "mode" "HI,HI,SI")])
7818 ;; %%% Potential partial reg stall on alternative 2. What to do?
7819 (define_insn "*andqi_1"
7820 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7821 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7822 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7823 (clobber (reg:CC FLAGS_REG))]
7824 "ix86_binary_operator_ok (AND, QImode, operands)"
7826 and{b}\t{%2, %0|%0, %2}
7827 and{b}\t{%2, %0|%0, %2}
7828 and{l}\t{%k2, %k0|%k0, %k2}"
7829 [(set_attr "type" "alu")
7830 (set_attr "mode" "QI,QI,SI")])
7832 (define_insn "*andqi_1_slp"
7833 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7834 (and:QI (match_dup 0)
7835 (match_operand:QI 1 "general_operand" "qn,qmn")))
7836 (clobber (reg:CC FLAGS_REG))]
7837 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7838 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7839 "and{b}\t{%1, %0|%0, %1}"
7840 [(set_attr "type" "alu1")
7841 (set_attr "mode" "QI")])
7844 [(set (match_operand 0 "register_operand" "")
7846 (const_int -65536)))
7847 (clobber (reg:CC FLAGS_REG))]
7848 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7849 || optimize_function_for_size_p (cfun)"
7850 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7851 "operands[1] = gen_lowpart (HImode, operands[0]);")
7854 [(set (match_operand 0 "ext_register_operand" "")
7857 (clobber (reg:CC FLAGS_REG))]
7858 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7859 && reload_completed"
7860 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7861 "operands[1] = gen_lowpart (QImode, operands[0]);")
7864 [(set (match_operand 0 "ext_register_operand" "")
7866 (const_int -65281)))
7867 (clobber (reg:CC FLAGS_REG))]
7868 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7869 && reload_completed"
7870 [(parallel [(set (zero_extract:SI (match_dup 0)
7874 (zero_extract:SI (match_dup 0)
7877 (zero_extract:SI (match_dup 0)
7880 (clobber (reg:CC FLAGS_REG))])]
7881 "operands[0] = gen_lowpart (SImode, operands[0]);")
7883 (define_insn "*anddi_2"
7884 [(set (reg FLAGS_REG)
7887 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7888 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7890 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7891 (and:DI (match_dup 1) (match_dup 2)))]
7892 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7893 && ix86_binary_operator_ok (AND, DImode, operands)"
7895 and{l}\t{%k2, %k0|%k0, %k2}
7896 and{q}\t{%2, %0|%0, %2}
7897 and{q}\t{%2, %0|%0, %2}"
7898 [(set_attr "type" "alu")
7899 (set_attr "mode" "SI,DI,DI")])
7901 (define_insn "*andqi_2_maybe_si"
7902 [(set (reg FLAGS_REG)
7904 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7905 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7907 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7908 (and:QI (match_dup 1) (match_dup 2)))]
7909 "ix86_binary_operator_ok (AND, QImode, operands)
7910 && ix86_match_ccmode (insn,
7911 CONST_INT_P (operands[2])
7912 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7914 if (which_alternative == 2)
7916 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7917 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7918 return "and{l}\t{%2, %k0|%k0, %2}";
7920 return "and{b}\t{%2, %0|%0, %2}";
7922 [(set_attr "type" "alu")
7923 (set_attr "mode" "QI,QI,SI")])
7925 (define_insn "*and<mode>_2"
7926 [(set (reg FLAGS_REG)
7927 (compare (and:SWI124
7928 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7929 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7931 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7932 (and:SWI124 (match_dup 1) (match_dup 2)))]
7933 "ix86_match_ccmode (insn, CCNOmode)
7934 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7935 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7936 [(set_attr "type" "alu")
7937 (set_attr "mode" "<MODE>")])
7939 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7940 (define_insn "*andsi_2_zext"
7941 [(set (reg FLAGS_REG)
7943 (match_operand:SI 1 "nonimmediate_operand" "%0")
7944 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7946 (set (match_operand:DI 0 "register_operand" "=r")
7947 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7948 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7949 && ix86_binary_operator_ok (AND, SImode, operands)"
7950 "and{l}\t{%2, %k0|%k0, %2}"
7951 [(set_attr "type" "alu")
7952 (set_attr "mode" "SI")])
7954 (define_insn "*andqi_2_slp"
7955 [(set (reg FLAGS_REG)
7957 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7958 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7960 (set (strict_low_part (match_dup 0))
7961 (and:QI (match_dup 0) (match_dup 1)))]
7962 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7963 && ix86_match_ccmode (insn, CCNOmode)
7964 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7965 "and{b}\t{%1, %0|%0, %1}"
7966 [(set_attr "type" "alu1")
7967 (set_attr "mode" "QI")])
7969 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7970 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7971 ;; for a QImode operand, which of course failed.
7972 (define_insn "andqi_ext_0"
7973 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7978 (match_operand 1 "ext_register_operand" "0")
7981 (match_operand 2 "const_int_operand" "n")))
7982 (clobber (reg:CC FLAGS_REG))]
7984 "and{b}\t{%2, %h0|%h0, %2}"
7985 [(set_attr "type" "alu")
7986 (set_attr "length_immediate" "1")
7987 (set_attr "modrm" "1")
7988 (set_attr "mode" "QI")])
7990 ;; Generated by peephole translating test to and. This shows up
7991 ;; often in fp comparisons.
7992 (define_insn "*andqi_ext_0_cc"
7993 [(set (reg FLAGS_REG)
7997 (match_operand 1 "ext_register_operand" "0")
8000 (match_operand 2 "const_int_operand" "n"))
8002 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8011 "ix86_match_ccmode (insn, CCNOmode)"
8012 "and{b}\t{%2, %h0|%h0, %2}"
8013 [(set_attr "type" "alu")
8014 (set_attr "length_immediate" "1")
8015 (set_attr "modrm" "1")
8016 (set_attr "mode" "QI")])
8018 (define_insn "*andqi_ext_1_rex64"
8019 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8024 (match_operand 1 "ext_register_operand" "0")
8028 (match_operand 2 "ext_register_operand" "Q"))))
8029 (clobber (reg:CC FLAGS_REG))]
8031 "and{b}\t{%2, %h0|%h0, %2}"
8032 [(set_attr "type" "alu")
8033 (set_attr "length_immediate" "0")
8034 (set_attr "mode" "QI")])
8036 (define_insn "*andqi_ext_1"
8037 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8042 (match_operand 1 "ext_register_operand" "0")
8046 (match_operand:QI 2 "general_operand" "Qm"))))
8047 (clobber (reg:CC FLAGS_REG))]
8049 "and{b}\t{%2, %h0|%h0, %2}"
8050 [(set_attr "type" "alu")
8051 (set_attr "length_immediate" "0")
8052 (set_attr "mode" "QI")])
8054 (define_insn "*andqi_ext_2"
8055 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8060 (match_operand 1 "ext_register_operand" "%0")
8064 (match_operand 2 "ext_register_operand" "Q")
8067 (clobber (reg:CC FLAGS_REG))]
8069 "and{b}\t{%h2, %h0|%h0, %h2}"
8070 [(set_attr "type" "alu")
8071 (set_attr "length_immediate" "0")
8072 (set_attr "mode" "QI")])
8074 ;; Convert wide AND instructions with immediate operand to shorter QImode
8075 ;; equivalents when possible.
8076 ;; Don't do the splitting with memory operands, since it introduces risk
8077 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8078 ;; for size, but that can (should?) be handled by generic code instead.
8080 [(set (match_operand 0 "register_operand" "")
8081 (and (match_operand 1 "register_operand" "")
8082 (match_operand 2 "const_int_operand" "")))
8083 (clobber (reg:CC FLAGS_REG))]
8085 && QI_REG_P (operands[0])
8086 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8087 && !(~INTVAL (operands[2]) & ~(255 << 8))
8088 && GET_MODE (operands[0]) != QImode"
8089 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8090 (and:SI (zero_extract:SI (match_dup 1)
8091 (const_int 8) (const_int 8))
8093 (clobber (reg:CC FLAGS_REG))])]
8095 operands[0] = gen_lowpart (SImode, operands[0]);
8096 operands[1] = gen_lowpart (SImode, operands[1]);
8097 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8100 ;; Since AND can be encoded with sign extended immediate, this is only
8101 ;; profitable when 7th bit is not set.
8103 [(set (match_operand 0 "register_operand" "")
8104 (and (match_operand 1 "general_operand" "")
8105 (match_operand 2 "const_int_operand" "")))
8106 (clobber (reg:CC FLAGS_REG))]
8108 && ANY_QI_REG_P (operands[0])
8109 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8110 && !(~INTVAL (operands[2]) & ~255)
8111 && !(INTVAL (operands[2]) & 128)
8112 && GET_MODE (operands[0]) != QImode"
8113 [(parallel [(set (strict_low_part (match_dup 0))
8114 (and:QI (match_dup 1)
8116 (clobber (reg:CC FLAGS_REG))])]
8118 operands[0] = gen_lowpart (QImode, operands[0]);
8119 operands[1] = gen_lowpart (QImode, operands[1]);
8120 operands[2] = gen_lowpart (QImode, operands[2]);
8123 ;; Logical inclusive and exclusive OR instructions
8125 ;; %%% This used to optimize known byte-wide and operations to memory.
8126 ;; If this is considered useful, it should be done with splitters.
8128 (define_expand "<code><mode>3"
8129 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8130 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8131 (match_operand:SWIM 2 "<general_operand>" "")))]
8133 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8135 (define_insn "*<code><mode>_1"
8136 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8138 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8139 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8140 (clobber (reg:CC FLAGS_REG))]
8141 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8142 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8143 [(set_attr "type" "alu")
8144 (set_attr "mode" "<MODE>")])
8146 ;; %%% Potential partial reg stall on alternative 2. What to do?
8147 (define_insn "*<code>qi_1"
8148 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8149 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8150 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8151 (clobber (reg:CC FLAGS_REG))]
8152 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8154 <logic>{b}\t{%2, %0|%0, %2}
8155 <logic>{b}\t{%2, %0|%0, %2}
8156 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8157 [(set_attr "type" "alu")
8158 (set_attr "mode" "QI,QI,SI")])
8160 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8161 (define_insn "*<code>si_1_zext"
8162 [(set (match_operand:DI 0 "register_operand" "=r")
8164 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8165 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8166 (clobber (reg:CC FLAGS_REG))]
8167 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8168 "<logic>{l}\t{%2, %k0|%k0, %2}"
8169 [(set_attr "type" "alu")
8170 (set_attr "mode" "SI")])
8172 (define_insn "*<code>si_1_zext_imm"
8173 [(set (match_operand:DI 0 "register_operand" "=r")
8175 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8176 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8177 (clobber (reg:CC FLAGS_REG))]
8178 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8179 "<logic>{l}\t{%2, %k0|%k0, %2}"
8180 [(set_attr "type" "alu")
8181 (set_attr "mode" "SI")])
8183 (define_insn "*<code>qi_1_slp"
8184 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8185 (any_or:QI (match_dup 0)
8186 (match_operand:QI 1 "general_operand" "qmn,qn")))
8187 (clobber (reg:CC FLAGS_REG))]
8188 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8189 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8190 "<logic>{b}\t{%1, %0|%0, %1}"
8191 [(set_attr "type" "alu1")
8192 (set_attr "mode" "QI")])
8194 (define_insn "*<code><mode>_2"
8195 [(set (reg FLAGS_REG)
8196 (compare (any_or:SWI
8197 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8198 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8200 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8201 (any_or:SWI (match_dup 1) (match_dup 2)))]
8202 "ix86_match_ccmode (insn, CCNOmode)
8203 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8204 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8205 [(set_attr "type" "alu")
8206 (set_attr "mode" "<MODE>")])
8208 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8209 ;; ??? Special case for immediate operand is missing - it is tricky.
8210 (define_insn "*<code>si_2_zext"
8211 [(set (reg FLAGS_REG)
8212 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8213 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8215 (set (match_operand:DI 0 "register_operand" "=r")
8216 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8217 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8218 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8219 "<logic>{l}\t{%2, %k0|%k0, %2}"
8220 [(set_attr "type" "alu")
8221 (set_attr "mode" "SI")])
8223 (define_insn "*<code>si_2_zext_imm"
8224 [(set (reg FLAGS_REG)
8226 (match_operand:SI 1 "nonimmediate_operand" "%0")
8227 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8229 (set (match_operand:DI 0 "register_operand" "=r")
8230 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8231 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8232 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8233 "<logic>{l}\t{%2, %k0|%k0, %2}"
8234 [(set_attr "type" "alu")
8235 (set_attr "mode" "SI")])
8237 (define_insn "*<code>qi_2_slp"
8238 [(set (reg FLAGS_REG)
8239 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8240 (match_operand:QI 1 "general_operand" "qmn,qn"))
8242 (set (strict_low_part (match_dup 0))
8243 (any_or:QI (match_dup 0) (match_dup 1)))]
8244 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8245 && ix86_match_ccmode (insn, CCNOmode)
8246 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8247 "<logic>{b}\t{%1, %0|%0, %1}"
8248 [(set_attr "type" "alu1")
8249 (set_attr "mode" "QI")])
8251 (define_insn "*<code><mode>_3"
8252 [(set (reg FLAGS_REG)
8253 (compare (any_or:SWI
8254 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8255 (match_operand:SWI 2 "<general_operand>" "<g>"))
8257 (clobber (match_scratch:SWI 0 "=<r>"))]
8258 "ix86_match_ccmode (insn, CCNOmode)
8259 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8260 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8261 [(set_attr "type" "alu")
8262 (set_attr "mode" "<MODE>")])
8264 (define_insn "*<code>qi_ext_0"
8265 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8270 (match_operand 1 "ext_register_operand" "0")
8273 (match_operand 2 "const_int_operand" "n")))
8274 (clobber (reg:CC FLAGS_REG))]
8275 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8276 "<logic>{b}\t{%2, %h0|%h0, %2}"
8277 [(set_attr "type" "alu")
8278 (set_attr "length_immediate" "1")
8279 (set_attr "modrm" "1")
8280 (set_attr "mode" "QI")])
8282 (define_insn "*<code>qi_ext_1_rex64"
8283 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8288 (match_operand 1 "ext_register_operand" "0")
8292 (match_operand 2 "ext_register_operand" "Q"))))
8293 (clobber (reg:CC FLAGS_REG))]
8295 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8296 "<logic>{b}\t{%2, %h0|%h0, %2}"
8297 [(set_attr "type" "alu")
8298 (set_attr "length_immediate" "0")
8299 (set_attr "mode" "QI")])
8301 (define_insn "*<code>qi_ext_1"
8302 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8307 (match_operand 1 "ext_register_operand" "0")
8311 (match_operand:QI 2 "general_operand" "Qm"))))
8312 (clobber (reg:CC FLAGS_REG))]
8314 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8315 "<logic>{b}\t{%2, %h0|%h0, %2}"
8316 [(set_attr "type" "alu")
8317 (set_attr "length_immediate" "0")
8318 (set_attr "mode" "QI")])
8320 (define_insn "*<code>qi_ext_2"
8321 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8325 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8328 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8331 (clobber (reg:CC FLAGS_REG))]
8332 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8333 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8334 [(set_attr "type" "alu")
8335 (set_attr "length_immediate" "0")
8336 (set_attr "mode" "QI")])
8339 [(set (match_operand 0 "register_operand" "")
8340 (any_or (match_operand 1 "register_operand" "")
8341 (match_operand 2 "const_int_operand" "")))
8342 (clobber (reg:CC FLAGS_REG))]
8344 && QI_REG_P (operands[0])
8345 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8346 && !(INTVAL (operands[2]) & ~(255 << 8))
8347 && GET_MODE (operands[0]) != QImode"
8348 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8349 (any_or:SI (zero_extract:SI (match_dup 1)
8350 (const_int 8) (const_int 8))
8352 (clobber (reg:CC FLAGS_REG))])]
8354 operands[0] = gen_lowpart (SImode, operands[0]);
8355 operands[1] = gen_lowpart (SImode, operands[1]);
8356 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8359 ;; Since OR can be encoded with sign extended immediate, this is only
8360 ;; profitable when 7th bit is set.
8362 [(set (match_operand 0 "register_operand" "")
8363 (any_or (match_operand 1 "general_operand" "")
8364 (match_operand 2 "const_int_operand" "")))
8365 (clobber (reg:CC FLAGS_REG))]
8367 && ANY_QI_REG_P (operands[0])
8368 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8369 && !(INTVAL (operands[2]) & ~255)
8370 && (INTVAL (operands[2]) & 128)
8371 && GET_MODE (operands[0]) != QImode"
8372 [(parallel [(set (strict_low_part (match_dup 0))
8373 (any_or:QI (match_dup 1)
8375 (clobber (reg:CC FLAGS_REG))])]
8377 operands[0] = gen_lowpart (QImode, operands[0]);
8378 operands[1] = gen_lowpart (QImode, operands[1]);
8379 operands[2] = gen_lowpart (QImode, operands[2]);
8382 (define_expand "xorqi_cc_ext_1"
8384 (set (reg:CCNO FLAGS_REG)
8388 (match_operand 1 "ext_register_operand" "")
8391 (match_operand:QI 2 "general_operand" ""))
8393 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8403 (define_insn "*xorqi_cc_ext_1_rex64"
8404 [(set (reg FLAGS_REG)
8408 (match_operand 1 "ext_register_operand" "0")
8411 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8413 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8422 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8423 "xor{b}\t{%2, %h0|%h0, %2}"
8424 [(set_attr "type" "alu")
8425 (set_attr "modrm" "1")
8426 (set_attr "mode" "QI")])
8428 (define_insn "*xorqi_cc_ext_1"
8429 [(set (reg FLAGS_REG)
8433 (match_operand 1 "ext_register_operand" "0")
8436 (match_operand:QI 2 "general_operand" "qmn"))
8438 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8447 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8448 "xor{b}\t{%2, %h0|%h0, %2}"
8449 [(set_attr "type" "alu")
8450 (set_attr "modrm" "1")
8451 (set_attr "mode" "QI")])
8453 ;; Negation instructions
8455 (define_expand "neg<mode>2"
8456 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8457 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8459 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8461 (define_insn_and_split "*neg<dwi>2_doubleword"
8462 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8463 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8464 (clobber (reg:CC FLAGS_REG))]
8465 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8469 [(set (reg:CCZ FLAGS_REG)
8470 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8471 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8474 (plus:DWIH (match_dup 3)
8475 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8477 (clobber (reg:CC FLAGS_REG))])
8480 (neg:DWIH (match_dup 2)))
8481 (clobber (reg:CC FLAGS_REG))])]
8482 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8484 (define_insn "*neg<mode>2_1"
8485 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8486 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8487 (clobber (reg:CC FLAGS_REG))]
8488 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8489 "neg{<imodesuffix>}\t%0"
8490 [(set_attr "type" "negnot")
8491 (set_attr "mode" "<MODE>")])
8493 ;; Combine is quite creative about this pattern.
8494 (define_insn "*negsi2_1_zext"
8495 [(set (match_operand:DI 0 "register_operand" "=r")
8497 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8500 (clobber (reg:CC FLAGS_REG))]
8501 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8503 [(set_attr "type" "negnot")
8504 (set_attr "mode" "SI")])
8506 ;; The problem with neg is that it does not perform (compare x 0),
8507 ;; it really performs (compare 0 x), which leaves us with the zero
8508 ;; flag being the only useful item.
8510 (define_insn "*neg<mode>2_cmpz"
8511 [(set (reg:CCZ FLAGS_REG)
8513 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8515 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8516 (neg:SWI (match_dup 1)))]
8517 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8518 "neg{<imodesuffix>}\t%0"
8519 [(set_attr "type" "negnot")
8520 (set_attr "mode" "<MODE>")])
8522 (define_insn "*negsi2_cmpz_zext"
8523 [(set (reg:CCZ FLAGS_REG)
8527 (match_operand:DI 1 "register_operand" "0")
8531 (set (match_operand:DI 0 "register_operand" "=r")
8532 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8535 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8537 [(set_attr "type" "negnot")
8538 (set_attr "mode" "SI")])
8540 ;; Changing of sign for FP values is doable using integer unit too.
8542 (define_expand "<code><mode>2"
8543 [(set (match_operand:X87MODEF 0 "register_operand" "")
8544 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8545 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8546 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8548 (define_insn "*absneg<mode>2_mixed"
8549 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8550 (match_operator:MODEF 3 "absneg_operator"
8551 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8552 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8553 (clobber (reg:CC FLAGS_REG))]
8554 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8557 (define_insn "*absneg<mode>2_sse"
8558 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8559 (match_operator:MODEF 3 "absneg_operator"
8560 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8561 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8562 (clobber (reg:CC FLAGS_REG))]
8563 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8566 (define_insn "*absneg<mode>2_i387"
8567 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8568 (match_operator:X87MODEF 3 "absneg_operator"
8569 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8570 (use (match_operand 2 "" ""))
8571 (clobber (reg:CC FLAGS_REG))]
8572 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8575 (define_expand "<code>tf2"
8576 [(set (match_operand:TF 0 "register_operand" "")
8577 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8579 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8581 (define_insn "*absnegtf2_sse"
8582 [(set (match_operand:TF 0 "register_operand" "=x,x")
8583 (match_operator:TF 3 "absneg_operator"
8584 [(match_operand:TF 1 "register_operand" "0,x")]))
8585 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8586 (clobber (reg:CC FLAGS_REG))]
8590 ;; Splitters for fp abs and neg.
8593 [(set (match_operand 0 "fp_register_operand" "")
8594 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8595 (use (match_operand 2 "" ""))
8596 (clobber (reg:CC FLAGS_REG))]
8598 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8601 [(set (match_operand 0 "register_operand" "")
8602 (match_operator 3 "absneg_operator"
8603 [(match_operand 1 "register_operand" "")]))
8604 (use (match_operand 2 "nonimmediate_operand" ""))
8605 (clobber (reg:CC FLAGS_REG))]
8606 "reload_completed && SSE_REG_P (operands[0])"
8607 [(set (match_dup 0) (match_dup 3))]
8609 enum machine_mode mode = GET_MODE (operands[0]);
8610 enum machine_mode vmode = GET_MODE (operands[2]);
8613 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8614 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8615 if (operands_match_p (operands[0], operands[2]))
8618 operands[1] = operands[2];
8621 if (GET_CODE (operands[3]) == ABS)
8622 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8624 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8629 [(set (match_operand:SF 0 "register_operand" "")
8630 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8631 (use (match_operand:V4SF 2 "" ""))
8632 (clobber (reg:CC FLAGS_REG))]
8634 [(parallel [(set (match_dup 0) (match_dup 1))
8635 (clobber (reg:CC FLAGS_REG))])]
8638 operands[0] = gen_lowpart (SImode, operands[0]);
8639 if (GET_CODE (operands[1]) == ABS)
8641 tmp = gen_int_mode (0x7fffffff, SImode);
8642 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8646 tmp = gen_int_mode (0x80000000, SImode);
8647 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8653 [(set (match_operand:DF 0 "register_operand" "")
8654 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8655 (use (match_operand 2 "" ""))
8656 (clobber (reg:CC FLAGS_REG))]
8658 [(parallel [(set (match_dup 0) (match_dup 1))
8659 (clobber (reg:CC FLAGS_REG))])]
8664 tmp = gen_lowpart (DImode, operands[0]);
8665 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8668 if (GET_CODE (operands[1]) == ABS)
8671 tmp = gen_rtx_NOT (DImode, tmp);
8675 operands[0] = gen_highpart (SImode, operands[0]);
8676 if (GET_CODE (operands[1]) == ABS)
8678 tmp = gen_int_mode (0x7fffffff, SImode);
8679 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8683 tmp = gen_int_mode (0x80000000, SImode);
8684 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8691 [(set (match_operand:XF 0 "register_operand" "")
8692 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8693 (use (match_operand 2 "" ""))
8694 (clobber (reg:CC FLAGS_REG))]
8696 [(parallel [(set (match_dup 0) (match_dup 1))
8697 (clobber (reg:CC FLAGS_REG))])]
8700 operands[0] = gen_rtx_REG (SImode,
8701 true_regnum (operands[0])
8702 + (TARGET_64BIT ? 1 : 2));
8703 if (GET_CODE (operands[1]) == ABS)
8705 tmp = GEN_INT (0x7fff);
8706 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8710 tmp = GEN_INT (0x8000);
8711 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8716 ;; Conditionalize these after reload. If they match before reload, we
8717 ;; lose the clobber and ability to use integer instructions.
8719 (define_insn "*<code><mode>2_1"
8720 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8721 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8723 && (reload_completed
8724 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8725 "f<absneg_mnemonic>"
8726 [(set_attr "type" "fsgn")
8727 (set_attr "mode" "<MODE>")])
8729 (define_insn "*<code>extendsfdf2"
8730 [(set (match_operand:DF 0 "register_operand" "=f")
8731 (absneg:DF (float_extend:DF
8732 (match_operand:SF 1 "register_operand" "0"))))]
8733 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8734 "f<absneg_mnemonic>"
8735 [(set_attr "type" "fsgn")
8736 (set_attr "mode" "DF")])
8738 (define_insn "*<code>extendsfxf2"
8739 [(set (match_operand:XF 0 "register_operand" "=f")
8740 (absneg:XF (float_extend:XF
8741 (match_operand:SF 1 "register_operand" "0"))))]
8743 "f<absneg_mnemonic>"
8744 [(set_attr "type" "fsgn")
8745 (set_attr "mode" "XF")])
8747 (define_insn "*<code>extenddfxf2"
8748 [(set (match_operand:XF 0 "register_operand" "=f")
8749 (absneg:XF (float_extend:XF
8750 (match_operand:DF 1 "register_operand" "0"))))]
8752 "f<absneg_mnemonic>"
8753 [(set_attr "type" "fsgn")
8754 (set_attr "mode" "XF")])
8756 ;; Copysign instructions
8758 (define_mode_iterator CSGNMODE [SF DF TF])
8759 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8761 (define_expand "copysign<mode>3"
8762 [(match_operand:CSGNMODE 0 "register_operand" "")
8763 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8764 (match_operand:CSGNMODE 2 "register_operand" "")]
8765 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8766 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8767 "ix86_expand_copysign (operands); DONE;")
8769 (define_insn_and_split "copysign<mode>3_const"
8770 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8772 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8773 (match_operand:CSGNMODE 2 "register_operand" "0")
8774 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8776 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8777 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8779 "&& reload_completed"
8781 "ix86_split_copysign_const (operands); DONE;")
8783 (define_insn "copysign<mode>3_var"
8784 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8786 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8787 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8788 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8789 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8791 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8792 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8793 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8797 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8799 [(match_operand:CSGNMODE 2 "register_operand" "")
8800 (match_operand:CSGNMODE 3 "register_operand" "")
8801 (match_operand:<CSGNVMODE> 4 "" "")
8802 (match_operand:<CSGNVMODE> 5 "" "")]
8804 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8805 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8806 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8807 && reload_completed"
8809 "ix86_split_copysign_var (operands); DONE;")
8811 ;; One complement instructions
8813 (define_expand "one_cmpl<mode>2"
8814 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8815 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8817 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8819 (define_insn "*one_cmpl<mode>2_1"
8820 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8821 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8822 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8823 "not{<imodesuffix>}\t%0"
8824 [(set_attr "type" "negnot")
8825 (set_attr "mode" "<MODE>")])
8827 ;; %%% Potential partial reg stall on alternative 1. What to do?
8828 (define_insn "*one_cmplqi2_1"
8829 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8830 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8831 "ix86_unary_operator_ok (NOT, QImode, operands)"
8835 [(set_attr "type" "negnot")
8836 (set_attr "mode" "QI,SI")])
8838 ;; ??? Currently never generated - xor is used instead.
8839 (define_insn "*one_cmplsi2_1_zext"
8840 [(set (match_operand:DI 0 "register_operand" "=r")
8842 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8843 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8845 [(set_attr "type" "negnot")
8846 (set_attr "mode" "SI")])
8848 (define_insn "*one_cmpl<mode>2_2"
8849 [(set (reg FLAGS_REG)
8850 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8852 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8853 (not:SWI (match_dup 1)))]
8854 "ix86_match_ccmode (insn, CCNOmode)
8855 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8857 [(set_attr "type" "alu1")
8858 (set_attr "mode" "<MODE>")])
8861 [(set (match_operand 0 "flags_reg_operand" "")
8862 (match_operator 2 "compare_operator"
8863 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8865 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8866 (not:SWI (match_dup 3)))]
8867 "ix86_match_ccmode (insn, CCNOmode)"
8868 [(parallel [(set (match_dup 0)
8869 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8872 (xor:SWI (match_dup 3) (const_int -1)))])])
8874 ;; ??? Currently never generated - xor is used instead.
8875 (define_insn "*one_cmplsi2_2_zext"
8876 [(set (reg FLAGS_REG)
8877 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8879 (set (match_operand:DI 0 "register_operand" "=r")
8880 (zero_extend:DI (not:SI (match_dup 1))))]
8881 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8882 && ix86_unary_operator_ok (NOT, SImode, operands)"
8884 [(set_attr "type" "alu1")
8885 (set_attr "mode" "SI")])
8888 [(set (match_operand 0 "flags_reg_operand" "")
8889 (match_operator 2 "compare_operator"
8890 [(not:SI (match_operand:SI 3 "register_operand" ""))
8892 (set (match_operand:DI 1 "register_operand" "")
8893 (zero_extend:DI (not:SI (match_dup 3))))]
8894 "ix86_match_ccmode (insn, CCNOmode)"
8895 [(parallel [(set (match_dup 0)
8896 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8899 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8901 ;; Shift instructions
8903 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8904 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8905 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8906 ;; from the assembler input.
8908 ;; This instruction shifts the target reg/mem as usual, but instead of
8909 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8910 ;; is a left shift double, bits are taken from the high order bits of
8911 ;; reg, else if the insn is a shift right double, bits are taken from the
8912 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8913 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8915 ;; Since sh[lr]d does not change the `reg' operand, that is done
8916 ;; separately, making all shifts emit pairs of shift double and normal
8917 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8918 ;; support a 63 bit shift, each shift where the count is in a reg expands
8919 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8921 ;; If the shift count is a constant, we need never emit more than one
8922 ;; shift pair, instead using moves and sign extension for counts greater
8925 (define_expand "ashl<mode>3"
8926 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8927 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8928 (match_operand:QI 2 "nonmemory_operand" "")))]
8930 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8932 (define_insn "*ashl<mode>3_doubleword"
8933 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8934 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8935 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8936 (clobber (reg:CC FLAGS_REG))]
8939 [(set_attr "type" "multi")])
8942 [(set (match_operand:DWI 0 "register_operand" "")
8943 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8944 (match_operand:QI 2 "nonmemory_operand" "")))
8945 (clobber (reg:CC FLAGS_REG))]
8946 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8948 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8950 ;; By default we don't ask for a scratch register, because when DWImode
8951 ;; values are manipulated, registers are already at a premium. But if
8952 ;; we have one handy, we won't turn it away.
8955 [(match_scratch:DWIH 3 "r")
8956 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8958 (match_operand:<DWI> 1 "nonmemory_operand" "")
8959 (match_operand:QI 2 "nonmemory_operand" "")))
8960 (clobber (reg:CC FLAGS_REG))])
8964 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8966 (define_insn "x86_64_shld"
8967 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8968 (ior:DI (ashift:DI (match_dup 0)
8969 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8970 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8971 (minus:QI (const_int 64) (match_dup 2)))))
8972 (clobber (reg:CC FLAGS_REG))]
8974 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8975 [(set_attr "type" "ishift")
8976 (set_attr "prefix_0f" "1")
8977 (set_attr "mode" "DI")
8978 (set_attr "athlon_decode" "vector")
8979 (set_attr "amdfam10_decode" "vector")
8980 (set_attr "bdver1_decode" "vector")])
8982 (define_insn "x86_shld"
8983 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8984 (ior:SI (ashift:SI (match_dup 0)
8985 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8986 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8987 (minus:QI (const_int 32) (match_dup 2)))))
8988 (clobber (reg:CC FLAGS_REG))]
8990 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8991 [(set_attr "type" "ishift")
8992 (set_attr "prefix_0f" "1")
8993 (set_attr "mode" "SI")
8994 (set_attr "pent_pair" "np")
8995 (set_attr "athlon_decode" "vector")
8996 (set_attr "amdfam10_decode" "vector")
8997 (set_attr "bdver1_decode" "vector")])
8999 (define_expand "x86_shift<mode>_adj_1"
9000 [(set (reg:CCZ FLAGS_REG)
9001 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9004 (set (match_operand:SWI48 0 "register_operand" "")
9005 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9006 (match_operand:SWI48 1 "register_operand" "")
9009 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9010 (match_operand:SWI48 3 "register_operand" "")
9013 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9015 (define_expand "x86_shift<mode>_adj_2"
9016 [(use (match_operand:SWI48 0 "register_operand" ""))
9017 (use (match_operand:SWI48 1 "register_operand" ""))
9018 (use (match_operand:QI 2 "register_operand" ""))]
9021 rtx label = gen_label_rtx ();
9024 emit_insn (gen_testqi_ccz_1 (operands[2],
9025 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9027 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9028 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9029 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9030 gen_rtx_LABEL_REF (VOIDmode, label),
9032 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9033 JUMP_LABEL (tmp) = label;
9035 emit_move_insn (operands[0], operands[1]);
9036 ix86_expand_clear (operands[1]);
9039 LABEL_NUSES (label) = 1;
9044 ;; Avoid useless masking of count operand.
9045 (define_insn_and_split "*ashl<mode>3_mask"
9046 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9048 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9051 (match_operand:SI 2 "nonimmediate_operand" "c")
9052 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9053 (clobber (reg:CC FLAGS_REG))]
9054 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9055 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9056 == GET_MODE_BITSIZE (<MODE>mode)-1"
9059 [(parallel [(set (match_dup 0)
9060 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9061 (clobber (reg:CC FLAGS_REG))])]
9063 if (can_create_pseudo_p ())
9064 operands [2] = force_reg (SImode, operands[2]);
9066 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9068 [(set_attr "type" "ishift")
9069 (set_attr "mode" "<MODE>")])
9071 (define_insn "*bmi2_ashl<mode>3_1"
9072 [(set (match_operand:SWI48 0 "register_operand" "=r")
9073 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9074 (match_operand:SWI48 2 "register_operand" "r")))]
9076 "shlx\t{%2, %1, %0|%0, %1, %2}"
9077 [(set_attr "type" "ishiftx")
9078 (set_attr "mode" "<MODE>")])
9080 (define_insn "*ashl<mode>3_1"
9081 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9082 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9083 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9084 (clobber (reg:CC FLAGS_REG))]
9085 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9087 switch (get_attr_type (insn))
9094 gcc_assert (operands[2] == const1_rtx);
9095 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9096 return "add{<imodesuffix>}\t%0, %0";
9099 if (operands[2] == const1_rtx
9100 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9101 return "sal{<imodesuffix>}\t%0";
9103 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9106 [(set_attr "isa" "*,*,bmi2")
9108 (cond [(eq_attr "alternative" "1")
9109 (const_string "lea")
9110 (eq_attr "alternative" "2")
9111 (const_string "ishiftx")
9112 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9113 (match_operand 0 "register_operand" ""))
9114 (match_operand 2 "const1_operand" ""))
9115 (const_string "alu")
9117 (const_string "ishift")))
9118 (set (attr "length_immediate")
9120 (ior (eq_attr "type" "alu")
9121 (and (eq_attr "type" "ishift")
9122 (and (match_operand 2 "const1_operand" "")
9123 (ior (match_test "TARGET_SHIFT1")
9124 (match_test "optimize_function_for_size_p (cfun)")))))
9126 (const_string "*")))
9127 (set_attr "mode" "<MODE>")])
9129 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9131 [(set (match_operand:SWI48 0 "register_operand" "")
9132 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9133 (match_operand:QI 2 "register_operand" "")))
9134 (clobber (reg:CC FLAGS_REG))]
9135 "TARGET_BMI2 && reload_completed"
9137 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9138 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9140 (define_insn "*bmi2_ashlsi3_1_zext"
9141 [(set (match_operand:DI 0 "register_operand" "=r")
9143 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9144 (match_operand:SI 2 "register_operand" "r"))))]
9145 "TARGET_64BIT && TARGET_BMI2"
9146 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9147 [(set_attr "type" "ishiftx")
9148 (set_attr "mode" "SI")])
9150 (define_insn "*ashlsi3_1_zext"
9151 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9153 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9154 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9155 (clobber (reg:CC FLAGS_REG))]
9156 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9158 switch (get_attr_type (insn))
9165 gcc_assert (operands[2] == const1_rtx);
9166 return "add{l}\t%k0, %k0";
9169 if (operands[2] == const1_rtx
9170 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9171 return "sal{l}\t%k0";
9173 return "sal{l}\t{%2, %k0|%k0, %2}";
9176 [(set_attr "isa" "*,*,bmi2")
9178 (cond [(eq_attr "alternative" "1")
9179 (const_string "lea")
9180 (eq_attr "alternative" "2")
9181 (const_string "ishiftx")
9182 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9183 (match_operand 2 "const1_operand" ""))
9184 (const_string "alu")
9186 (const_string "ishift")))
9187 (set (attr "length_immediate")
9189 (ior (eq_attr "type" "alu")
9190 (and (eq_attr "type" "ishift")
9191 (and (match_operand 2 "const1_operand" "")
9192 (ior (match_test "TARGET_SHIFT1")
9193 (match_test "optimize_function_for_size_p (cfun)")))))
9195 (const_string "*")))
9196 (set_attr "mode" "SI")])
9198 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9200 [(set (match_operand:DI 0 "register_operand" "")
9202 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9203 (match_operand:QI 2 "register_operand" ""))))
9204 (clobber (reg:CC FLAGS_REG))]
9205 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9207 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9208 "operands[2] = gen_lowpart (SImode, operands[2]);")
9210 (define_insn "*ashlhi3_1"
9211 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9212 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9213 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9214 (clobber (reg:CC FLAGS_REG))]
9215 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9217 switch (get_attr_type (insn))
9223 gcc_assert (operands[2] == const1_rtx);
9224 return "add{w}\t%0, %0";
9227 if (operands[2] == const1_rtx
9228 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9229 return "sal{w}\t%0";
9231 return "sal{w}\t{%2, %0|%0, %2}";
9235 (cond [(eq_attr "alternative" "1")
9236 (const_string "lea")
9237 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9238 (match_operand 0 "register_operand" ""))
9239 (match_operand 2 "const1_operand" ""))
9240 (const_string "alu")
9242 (const_string "ishift")))
9243 (set (attr "length_immediate")
9245 (ior (eq_attr "type" "alu")
9246 (and (eq_attr "type" "ishift")
9247 (and (match_operand 2 "const1_operand" "")
9248 (ior (match_test "TARGET_SHIFT1")
9249 (match_test "optimize_function_for_size_p (cfun)")))))
9251 (const_string "*")))
9252 (set_attr "mode" "HI,SI")])
9254 ;; %%% Potential partial reg stall on alternative 1. What to do?
9255 (define_insn "*ashlqi3_1"
9256 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9257 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9258 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9259 (clobber (reg:CC FLAGS_REG))]
9260 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9262 switch (get_attr_type (insn))
9268 gcc_assert (operands[2] == const1_rtx);
9269 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9270 return "add{l}\t%k0, %k0";
9272 return "add{b}\t%0, %0";
9275 if (operands[2] == const1_rtx
9276 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9278 if (get_attr_mode (insn) == MODE_SI)
9279 return "sal{l}\t%k0";
9281 return "sal{b}\t%0";
9285 if (get_attr_mode (insn) == MODE_SI)
9286 return "sal{l}\t{%2, %k0|%k0, %2}";
9288 return "sal{b}\t{%2, %0|%0, %2}";
9293 (cond [(eq_attr "alternative" "2")
9294 (const_string "lea")
9295 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9296 (match_operand 0 "register_operand" ""))
9297 (match_operand 2 "const1_operand" ""))
9298 (const_string "alu")
9300 (const_string "ishift")))
9301 (set (attr "length_immediate")
9303 (ior (eq_attr "type" "alu")
9304 (and (eq_attr "type" "ishift")
9305 (and (match_operand 2 "const1_operand" "")
9306 (ior (match_test "TARGET_SHIFT1")
9307 (match_test "optimize_function_for_size_p (cfun)")))))
9309 (const_string "*")))
9310 (set_attr "mode" "QI,SI,SI")])
9312 (define_insn "*ashlqi3_1_slp"
9313 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9314 (ashift:QI (match_dup 0)
9315 (match_operand:QI 1 "nonmemory_operand" "cI")))
9316 (clobber (reg:CC FLAGS_REG))]
9317 "(optimize_function_for_size_p (cfun)
9318 || !TARGET_PARTIAL_FLAG_REG_STALL
9319 || (operands[1] == const1_rtx
9321 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9323 switch (get_attr_type (insn))
9326 gcc_assert (operands[1] == const1_rtx);
9327 return "add{b}\t%0, %0";
9330 if (operands[1] == const1_rtx
9331 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9332 return "sal{b}\t%0";
9334 return "sal{b}\t{%1, %0|%0, %1}";
9338 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9339 (match_operand 0 "register_operand" ""))
9340 (match_operand 1 "const1_operand" ""))
9341 (const_string "alu")
9343 (const_string "ishift1")))
9344 (set (attr "length_immediate")
9346 (ior (eq_attr "type" "alu")
9347 (and (eq_attr "type" "ishift1")
9348 (and (match_operand 1 "const1_operand" "")
9349 (ior (match_test "TARGET_SHIFT1")
9350 (match_test "optimize_function_for_size_p (cfun)")))))
9352 (const_string "*")))
9353 (set_attr "mode" "QI")])
9355 ;; Convert ashift to the lea pattern to avoid flags dependency.
9357 [(set (match_operand 0 "register_operand" "")
9358 (ashift (match_operand 1 "index_register_operand" "")
9359 (match_operand:QI 2 "const_int_operand" "")))
9360 (clobber (reg:CC FLAGS_REG))]
9361 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9363 && true_regnum (operands[0]) != true_regnum (operands[1])"
9366 enum machine_mode mode = GET_MODE (operands[0]);
9369 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9372 operands[0] = gen_lowpart (mode, operands[0]);
9373 operands[1] = gen_lowpart (mode, operands[1]);
9376 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9378 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9380 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9384 ;; Convert ashift to the lea pattern to avoid flags dependency.
9386 [(set (match_operand:DI 0 "register_operand" "")
9388 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9389 (match_operand:QI 2 "const_int_operand" ""))))
9390 (clobber (reg:CC FLAGS_REG))]
9391 "TARGET_64BIT && reload_completed
9392 && true_regnum (operands[0]) != true_regnum (operands[1])"
9394 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9396 operands[1] = gen_lowpart (DImode, operands[1]);
9397 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9400 ;; This pattern can't accept a variable shift count, since shifts by
9401 ;; zero don't affect the flags. We assume that shifts by constant
9402 ;; zero are optimized away.
9403 (define_insn "*ashl<mode>3_cmp"
9404 [(set (reg FLAGS_REG)
9406 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9407 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9409 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9410 (ashift:SWI (match_dup 1) (match_dup 2)))]
9411 "(optimize_function_for_size_p (cfun)
9412 || !TARGET_PARTIAL_FLAG_REG_STALL
9413 || (operands[2] == const1_rtx
9415 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9416 && ix86_match_ccmode (insn, CCGOCmode)
9417 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9419 switch (get_attr_type (insn))
9422 gcc_assert (operands[2] == const1_rtx);
9423 return "add{<imodesuffix>}\t%0, %0";
9426 if (operands[2] == const1_rtx
9427 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9428 return "sal{<imodesuffix>}\t%0";
9430 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9434 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9435 (match_operand 0 "register_operand" ""))
9436 (match_operand 2 "const1_operand" ""))
9437 (const_string "alu")
9439 (const_string "ishift")))
9440 (set (attr "length_immediate")
9442 (ior (eq_attr "type" "alu")
9443 (and (eq_attr "type" "ishift")
9444 (and (match_operand 2 "const1_operand" "")
9445 (ior (match_test "TARGET_SHIFT1")
9446 (match_test "optimize_function_for_size_p (cfun)")))))
9448 (const_string "*")))
9449 (set_attr "mode" "<MODE>")])
9451 (define_insn "*ashlsi3_cmp_zext"
9452 [(set (reg FLAGS_REG)
9454 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9455 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9457 (set (match_operand:DI 0 "register_operand" "=r")
9458 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9460 && (optimize_function_for_size_p (cfun)
9461 || !TARGET_PARTIAL_FLAG_REG_STALL
9462 || (operands[2] == const1_rtx
9464 || TARGET_DOUBLE_WITH_ADD)))
9465 && ix86_match_ccmode (insn, CCGOCmode)
9466 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9468 switch (get_attr_type (insn))
9471 gcc_assert (operands[2] == const1_rtx);
9472 return "add{l}\t%k0, %k0";
9475 if (operands[2] == const1_rtx
9476 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9477 return "sal{l}\t%k0";
9479 return "sal{l}\t{%2, %k0|%k0, %2}";
9483 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9484 (match_operand 2 "const1_operand" ""))
9485 (const_string "alu")
9487 (const_string "ishift")))
9488 (set (attr "length_immediate")
9490 (ior (eq_attr "type" "alu")
9491 (and (eq_attr "type" "ishift")
9492 (and (match_operand 2 "const1_operand" "")
9493 (ior (match_test "TARGET_SHIFT1")
9494 (match_test "optimize_function_for_size_p (cfun)")))))
9496 (const_string "*")))
9497 (set_attr "mode" "SI")])
9499 (define_insn "*ashl<mode>3_cconly"
9500 [(set (reg FLAGS_REG)
9502 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9503 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9505 (clobber (match_scratch:SWI 0 "=<r>"))]
9506 "(optimize_function_for_size_p (cfun)
9507 || !TARGET_PARTIAL_FLAG_REG_STALL
9508 || (operands[2] == const1_rtx
9510 || TARGET_DOUBLE_WITH_ADD)))
9511 && ix86_match_ccmode (insn, CCGOCmode)"
9513 switch (get_attr_type (insn))
9516 gcc_assert (operands[2] == const1_rtx);
9517 return "add{<imodesuffix>}\t%0, %0";
9520 if (operands[2] == const1_rtx
9521 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9522 return "sal{<imodesuffix>}\t%0";
9524 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9528 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9529 (match_operand 0 "register_operand" ""))
9530 (match_operand 2 "const1_operand" ""))
9531 (const_string "alu")
9533 (const_string "ishift")))
9534 (set (attr "length_immediate")
9536 (ior (eq_attr "type" "alu")
9537 (and (eq_attr "type" "ishift")
9538 (and (match_operand 2 "const1_operand" "")
9539 (ior (match_test "TARGET_SHIFT1")
9540 (match_test "optimize_function_for_size_p (cfun)")))))
9542 (const_string "*")))
9543 (set_attr "mode" "<MODE>")])
9545 ;; See comment above `ashl<mode>3' about how this works.
9547 (define_expand "<shift_insn><mode>3"
9548 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9549 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9550 (match_operand:QI 2 "nonmemory_operand" "")))]
9552 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9554 ;; Avoid useless masking of count operand.
9555 (define_insn_and_split "*<shift_insn><mode>3_mask"
9556 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9558 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9561 (match_operand:SI 2 "nonimmediate_operand" "c")
9562 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9563 (clobber (reg:CC FLAGS_REG))]
9564 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9565 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9566 == GET_MODE_BITSIZE (<MODE>mode)-1"
9569 [(parallel [(set (match_dup 0)
9570 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9571 (clobber (reg:CC FLAGS_REG))])]
9573 if (can_create_pseudo_p ())
9574 operands [2] = force_reg (SImode, operands[2]);
9576 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9578 [(set_attr "type" "ishift")
9579 (set_attr "mode" "<MODE>")])
9581 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9582 [(set (match_operand:DWI 0 "register_operand" "=r")
9583 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9584 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9585 (clobber (reg:CC FLAGS_REG))]
9588 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9590 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9591 [(set_attr "type" "multi")])
9593 ;; By default we don't ask for a scratch register, because when DWImode
9594 ;; values are manipulated, registers are already at a premium. But if
9595 ;; we have one handy, we won't turn it away.
9598 [(match_scratch:DWIH 3 "r")
9599 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9601 (match_operand:<DWI> 1 "register_operand" "")
9602 (match_operand:QI 2 "nonmemory_operand" "")))
9603 (clobber (reg:CC FLAGS_REG))])
9607 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9609 (define_insn "x86_64_shrd"
9610 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9611 (ior:DI (ashiftrt:DI (match_dup 0)
9612 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9613 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9614 (minus:QI (const_int 64) (match_dup 2)))))
9615 (clobber (reg:CC FLAGS_REG))]
9617 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9618 [(set_attr "type" "ishift")
9619 (set_attr "prefix_0f" "1")
9620 (set_attr "mode" "DI")
9621 (set_attr "athlon_decode" "vector")
9622 (set_attr "amdfam10_decode" "vector")
9623 (set_attr "bdver1_decode" "vector")])
9625 (define_insn "x86_shrd"
9626 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9627 (ior:SI (ashiftrt:SI (match_dup 0)
9628 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9629 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9630 (minus:QI (const_int 32) (match_dup 2)))))
9631 (clobber (reg:CC FLAGS_REG))]
9633 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9634 [(set_attr "type" "ishift")
9635 (set_attr "prefix_0f" "1")
9636 (set_attr "mode" "SI")
9637 (set_attr "pent_pair" "np")
9638 (set_attr "athlon_decode" "vector")
9639 (set_attr "amdfam10_decode" "vector")
9640 (set_attr "bdver1_decode" "vector")])
9642 (define_insn "ashrdi3_cvt"
9643 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9644 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9645 (match_operand:QI 2 "const_int_operand" "")))
9646 (clobber (reg:CC FLAGS_REG))]
9647 "TARGET_64BIT && INTVAL (operands[2]) == 63
9648 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9649 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9652 sar{q}\t{%2, %0|%0, %2}"
9653 [(set_attr "type" "imovx,ishift")
9654 (set_attr "prefix_0f" "0,*")
9655 (set_attr "length_immediate" "0,*")
9656 (set_attr "modrm" "0,1")
9657 (set_attr "mode" "DI")])
9659 (define_insn "ashrsi3_cvt"
9660 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9661 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9662 (match_operand:QI 2 "const_int_operand" "")))
9663 (clobber (reg:CC FLAGS_REG))]
9664 "INTVAL (operands[2]) == 31
9665 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9666 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9669 sar{l}\t{%2, %0|%0, %2}"
9670 [(set_attr "type" "imovx,ishift")
9671 (set_attr "prefix_0f" "0,*")
9672 (set_attr "length_immediate" "0,*")
9673 (set_attr "modrm" "0,1")
9674 (set_attr "mode" "SI")])
9676 (define_insn "*ashrsi3_cvt_zext"
9677 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9679 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9680 (match_operand:QI 2 "const_int_operand" ""))))
9681 (clobber (reg:CC FLAGS_REG))]
9682 "TARGET_64BIT && INTVAL (operands[2]) == 31
9683 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9684 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9687 sar{l}\t{%2, %k0|%k0, %2}"
9688 [(set_attr "type" "imovx,ishift")
9689 (set_attr "prefix_0f" "0,*")
9690 (set_attr "length_immediate" "0,*")
9691 (set_attr "modrm" "0,1")
9692 (set_attr "mode" "SI")])
9694 (define_expand "x86_shift<mode>_adj_3"
9695 [(use (match_operand:SWI48 0 "register_operand" ""))
9696 (use (match_operand:SWI48 1 "register_operand" ""))
9697 (use (match_operand:QI 2 "register_operand" ""))]
9700 rtx label = gen_label_rtx ();
9703 emit_insn (gen_testqi_ccz_1 (operands[2],
9704 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9706 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9707 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9708 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9709 gen_rtx_LABEL_REF (VOIDmode, label),
9711 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9712 JUMP_LABEL (tmp) = label;
9714 emit_move_insn (operands[0], operands[1]);
9715 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9716 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9718 LABEL_NUSES (label) = 1;
9723 (define_insn "*bmi2_<shift_insn><mode>3_1"
9724 [(set (match_operand:SWI48 0 "register_operand" "=r")
9725 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9726 (match_operand:SWI48 2 "register_operand" "r")))]
9728 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9729 [(set_attr "type" "ishiftx")
9730 (set_attr "mode" "<MODE>")])
9732 (define_insn "*<shift_insn><mode>3_1"
9733 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9735 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9736 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9737 (clobber (reg:CC FLAGS_REG))]
9738 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9740 switch (get_attr_type (insn))
9746 if (operands[2] == const1_rtx
9747 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9748 return "<shift>{<imodesuffix>}\t%0";
9750 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9753 [(set_attr "isa" "*,bmi2")
9754 (set_attr "type" "ishift,ishiftx")
9755 (set (attr "length_immediate")
9757 (and (match_operand 2 "const1_operand" "")
9758 (ior (match_test "TARGET_SHIFT1")
9759 (match_test "optimize_function_for_size_p (cfun)")))
9761 (const_string "*")))
9762 (set_attr "mode" "<MODE>")])
9764 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9766 [(set (match_operand:SWI48 0 "register_operand" "")
9767 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9768 (match_operand:QI 2 "register_operand" "")))
9769 (clobber (reg:CC FLAGS_REG))]
9770 "TARGET_BMI2 && reload_completed"
9772 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9773 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9775 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9776 [(set (match_operand:DI 0 "register_operand" "=r")
9778 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9779 (match_operand:SI 2 "register_operand" "r"))))]
9780 "TARGET_64BIT && TARGET_BMI2"
9781 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9782 [(set_attr "type" "ishiftx")
9783 (set_attr "mode" "SI")])
9785 (define_insn "*<shift_insn>si3_1_zext"
9786 [(set (match_operand:DI 0 "register_operand" "=r,r")
9788 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9789 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9790 (clobber (reg:CC FLAGS_REG))]
9791 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9793 switch (get_attr_type (insn))
9799 if (operands[2] == const1_rtx
9800 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9801 return "<shift>{l}\t%k0";
9803 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9806 [(set_attr "isa" "*,bmi2")
9807 (set_attr "type" "ishift,ishiftx")
9808 (set (attr "length_immediate")
9810 (and (match_operand 2 "const1_operand" "")
9811 (ior (match_test "TARGET_SHIFT1")
9812 (match_test "optimize_function_for_size_p (cfun)")))
9814 (const_string "*")))
9815 (set_attr "mode" "SI")])
9817 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9819 [(set (match_operand:DI 0 "register_operand" "")
9821 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9822 (match_operand:QI 2 "register_operand" ""))))
9823 (clobber (reg:CC FLAGS_REG))]
9824 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9826 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9827 "operands[2] = gen_lowpart (SImode, operands[2]);")
9829 (define_insn "*<shift_insn><mode>3_1"
9830 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9832 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9833 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9834 (clobber (reg:CC FLAGS_REG))]
9835 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9837 if (operands[2] == const1_rtx
9838 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9839 return "<shift>{<imodesuffix>}\t%0";
9841 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9843 [(set_attr "type" "ishift")
9844 (set (attr "length_immediate")
9846 (and (match_operand 2 "const1_operand" "")
9847 (ior (match_test "TARGET_SHIFT1")
9848 (match_test "optimize_function_for_size_p (cfun)")))
9850 (const_string "*")))
9851 (set_attr "mode" "<MODE>")])
9853 (define_insn "*<shift_insn>qi3_1_slp"
9854 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9855 (any_shiftrt:QI (match_dup 0)
9856 (match_operand:QI 1 "nonmemory_operand" "cI")))
9857 (clobber (reg:CC FLAGS_REG))]
9858 "(optimize_function_for_size_p (cfun)
9859 || !TARGET_PARTIAL_REG_STALL
9860 || (operands[1] == const1_rtx
9863 if (operands[1] == const1_rtx
9864 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9865 return "<shift>{b}\t%0";
9867 return "<shift>{b}\t{%1, %0|%0, %1}";
9869 [(set_attr "type" "ishift1")
9870 (set (attr "length_immediate")
9872 (and (match_operand 1 "const1_operand" "")
9873 (ior (match_test "TARGET_SHIFT1")
9874 (match_test "optimize_function_for_size_p (cfun)")))
9876 (const_string "*")))
9877 (set_attr "mode" "QI")])
9879 ;; This pattern can't accept a variable shift count, since shifts by
9880 ;; zero don't affect the flags. We assume that shifts by constant
9881 ;; zero are optimized away.
9882 (define_insn "*<shift_insn><mode>3_cmp"
9883 [(set (reg FLAGS_REG)
9886 (match_operand:SWI 1 "nonimmediate_operand" "0")
9887 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9889 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9890 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9891 "(optimize_function_for_size_p (cfun)
9892 || !TARGET_PARTIAL_FLAG_REG_STALL
9893 || (operands[2] == const1_rtx
9895 && ix86_match_ccmode (insn, CCGOCmode)
9896 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9898 if (operands[2] == const1_rtx
9899 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9900 return "<shift>{<imodesuffix>}\t%0";
9902 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9904 [(set_attr "type" "ishift")
9905 (set (attr "length_immediate")
9907 (and (match_operand 2 "const1_operand" "")
9908 (ior (match_test "TARGET_SHIFT1")
9909 (match_test "optimize_function_for_size_p (cfun)")))
9911 (const_string "*")))
9912 (set_attr "mode" "<MODE>")])
9914 (define_insn "*<shift_insn>si3_cmp_zext"
9915 [(set (reg FLAGS_REG)
9917 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9918 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9920 (set (match_operand:DI 0 "register_operand" "=r")
9921 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9923 && (optimize_function_for_size_p (cfun)
9924 || !TARGET_PARTIAL_FLAG_REG_STALL
9925 || (operands[2] == const1_rtx
9927 && ix86_match_ccmode (insn, CCGOCmode)
9928 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9930 if (operands[2] == const1_rtx
9931 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9932 return "<shift>{l}\t%k0";
9934 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9936 [(set_attr "type" "ishift")
9937 (set (attr "length_immediate")
9939 (and (match_operand 2 "const1_operand" "")
9940 (ior (match_test "TARGET_SHIFT1")
9941 (match_test "optimize_function_for_size_p (cfun)")))
9943 (const_string "*")))
9944 (set_attr "mode" "SI")])
9946 (define_insn "*<shift_insn><mode>3_cconly"
9947 [(set (reg FLAGS_REG)
9950 (match_operand:SWI 1 "register_operand" "0")
9951 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9953 (clobber (match_scratch:SWI 0 "=<r>"))]
9954 "(optimize_function_for_size_p (cfun)
9955 || !TARGET_PARTIAL_FLAG_REG_STALL
9956 || (operands[2] == const1_rtx
9958 && ix86_match_ccmode (insn, CCGOCmode)"
9960 if (operands[2] == const1_rtx
9961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9962 return "<shift>{<imodesuffix>}\t%0";
9964 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9966 [(set_attr "type" "ishift")
9967 (set (attr "length_immediate")
9969 (and (match_operand 2 "const1_operand" "")
9970 (ior (match_test "TARGET_SHIFT1")
9971 (match_test "optimize_function_for_size_p (cfun)")))
9973 (const_string "*")))
9974 (set_attr "mode" "<MODE>")])
9976 ;; Rotate instructions
9978 (define_expand "<rotate_insn>ti3"
9979 [(set (match_operand:TI 0 "register_operand" "")
9980 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9981 (match_operand:QI 2 "nonmemory_operand" "")))]
9984 if (const_1_to_63_operand (operands[2], VOIDmode))
9985 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9986 (operands[0], operands[1], operands[2]));
9993 (define_expand "<rotate_insn>di3"
9994 [(set (match_operand:DI 0 "shiftdi_operand" "")
9995 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9996 (match_operand:QI 2 "nonmemory_operand" "")))]
10000 ix86_expand_binary_operator (<CODE>, DImode, operands);
10001 else if (const_1_to_31_operand (operands[2], VOIDmode))
10002 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10003 (operands[0], operands[1], operands[2]));
10010 (define_expand "<rotate_insn><mode>3"
10011 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10012 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10013 (match_operand:QI 2 "nonmemory_operand" "")))]
10015 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10017 ;; Avoid useless masking of count operand.
10018 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10019 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10021 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10024 (match_operand:SI 2 "nonimmediate_operand" "c")
10025 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10026 (clobber (reg:CC FLAGS_REG))]
10027 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10028 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10029 == GET_MODE_BITSIZE (<MODE>mode)-1"
10032 [(parallel [(set (match_dup 0)
10033 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10034 (clobber (reg:CC FLAGS_REG))])]
10036 if (can_create_pseudo_p ())
10037 operands [2] = force_reg (SImode, operands[2]);
10039 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10041 [(set_attr "type" "rotate")
10042 (set_attr "mode" "<MODE>")])
10044 ;; Implement rotation using two double-precision
10045 ;; shift instructions and a scratch register.
10047 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10048 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10049 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10050 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10051 (clobber (reg:CC FLAGS_REG))
10052 (clobber (match_scratch:DWIH 3 "=&r"))]
10056 [(set (match_dup 3) (match_dup 4))
10058 [(set (match_dup 4)
10059 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10060 (lshiftrt:DWIH (match_dup 5)
10061 (minus:QI (match_dup 6) (match_dup 2)))))
10062 (clobber (reg:CC FLAGS_REG))])
10064 [(set (match_dup 5)
10065 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10066 (lshiftrt:DWIH (match_dup 3)
10067 (minus:QI (match_dup 6) (match_dup 2)))))
10068 (clobber (reg:CC FLAGS_REG))])]
10070 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10072 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10075 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10076 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10077 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10078 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10079 (clobber (reg:CC FLAGS_REG))
10080 (clobber (match_scratch:DWIH 3 "=&r"))]
10084 [(set (match_dup 3) (match_dup 4))
10086 [(set (match_dup 4)
10087 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10088 (ashift:DWIH (match_dup 5)
10089 (minus:QI (match_dup 6) (match_dup 2)))))
10090 (clobber (reg:CC FLAGS_REG))])
10092 [(set (match_dup 5)
10093 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10094 (ashift:DWIH (match_dup 3)
10095 (minus:QI (match_dup 6) (match_dup 2)))))
10096 (clobber (reg:CC FLAGS_REG))])]
10098 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10100 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10103 (define_insn "*bmi2_rorx<mode>3_1"
10104 [(set (match_operand:SWI48 0 "register_operand" "=r")
10105 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10106 (match_operand:QI 2 "immediate_operand" "<S>")))]
10108 "rorx\t{%2, %1, %0|%0, %1, %2}"
10109 [(set_attr "type" "rotatex")
10110 (set_attr "mode" "<MODE>")])
10112 (define_insn "*<rotate_insn><mode>3_1"
10113 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10115 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10116 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10117 (clobber (reg:CC FLAGS_REG))]
10118 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10120 switch (get_attr_type (insn))
10126 if (operands[2] == const1_rtx
10127 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10128 return "<rotate>{<imodesuffix>}\t%0";
10130 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10133 [(set_attr "isa" "*,bmi2")
10134 (set_attr "type" "rotate,rotatex")
10135 (set (attr "length_immediate")
10137 (and (eq_attr "type" "rotate")
10138 (and (match_operand 2 "const1_operand" "")
10139 (ior (match_test "TARGET_SHIFT1")
10140 (match_test "optimize_function_for_size_p (cfun)"))))
10142 (const_string "*")))
10143 (set_attr "mode" "<MODE>")])
10145 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10147 [(set (match_operand:SWI48 0 "register_operand" "")
10148 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10149 (match_operand:QI 2 "immediate_operand" "")))
10150 (clobber (reg:CC FLAGS_REG))]
10151 "TARGET_BMI2 && reload_completed"
10152 [(set (match_dup 0)
10153 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10156 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10160 [(set (match_operand:SWI48 0 "register_operand" "")
10161 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10162 (match_operand:QI 2 "immediate_operand" "")))
10163 (clobber (reg:CC FLAGS_REG))]
10164 "TARGET_BMI2 && reload_completed"
10165 [(set (match_dup 0)
10166 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10168 (define_insn "*bmi2_rorxsi3_1_zext"
10169 [(set (match_operand:DI 0 "register_operand" "=r")
10171 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10172 (match_operand:QI 2 "immediate_operand" "I"))))]
10173 "TARGET_64BIT && TARGET_BMI2"
10174 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10175 [(set_attr "type" "rotatex")
10176 (set_attr "mode" "SI")])
10178 (define_insn "*<rotate_insn>si3_1_zext"
10179 [(set (match_operand:DI 0 "register_operand" "=r,r")
10181 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10182 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10183 (clobber (reg:CC FLAGS_REG))]
10184 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10186 switch (get_attr_type (insn))
10192 if (operands[2] == const1_rtx
10193 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10194 return "<rotate>{l}\t%k0";
10196 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10199 [(set_attr "isa" "*,bmi2")
10200 (set_attr "type" "rotate,rotatex")
10201 (set (attr "length_immediate")
10203 (and (eq_attr "type" "rotate")
10204 (and (match_operand 2 "const1_operand" "")
10205 (ior (match_test "TARGET_SHIFT1")
10206 (match_test "optimize_function_for_size_p (cfun)"))))
10208 (const_string "*")))
10209 (set_attr "mode" "SI")])
10211 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10213 [(set (match_operand:DI 0 "register_operand" "")
10215 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10216 (match_operand:QI 2 "immediate_operand" ""))))
10217 (clobber (reg:CC FLAGS_REG))]
10218 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10219 [(set (match_dup 0)
10220 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10223 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10227 [(set (match_operand:DI 0 "register_operand" "")
10229 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10230 (match_operand:QI 2 "immediate_operand" ""))))
10231 (clobber (reg:CC FLAGS_REG))]
10232 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10233 [(set (match_dup 0)
10234 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10236 (define_insn "*<rotate_insn><mode>3_1"
10237 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10238 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10239 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10240 (clobber (reg:CC FLAGS_REG))]
10241 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10243 if (operands[2] == const1_rtx
10244 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10245 return "<rotate>{<imodesuffix>}\t%0";
10247 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10249 [(set_attr "type" "rotate")
10250 (set (attr "length_immediate")
10252 (and (match_operand 2 "const1_operand" "")
10253 (ior (match_test "TARGET_SHIFT1")
10254 (match_test "optimize_function_for_size_p (cfun)")))
10256 (const_string "*")))
10257 (set_attr "mode" "<MODE>")])
10259 (define_insn "*<rotate_insn>qi3_1_slp"
10260 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10261 (any_rotate:QI (match_dup 0)
10262 (match_operand:QI 1 "nonmemory_operand" "cI")))
10263 (clobber (reg:CC FLAGS_REG))]
10264 "(optimize_function_for_size_p (cfun)
10265 || !TARGET_PARTIAL_REG_STALL
10266 || (operands[1] == const1_rtx
10267 && TARGET_SHIFT1))"
10269 if (operands[1] == const1_rtx
10270 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10271 return "<rotate>{b}\t%0";
10273 return "<rotate>{b}\t{%1, %0|%0, %1}";
10275 [(set_attr "type" "rotate1")
10276 (set (attr "length_immediate")
10278 (and (match_operand 1 "const1_operand" "")
10279 (ior (match_test "TARGET_SHIFT1")
10280 (match_test "optimize_function_for_size_p (cfun)")))
10282 (const_string "*")))
10283 (set_attr "mode" "QI")])
10286 [(set (match_operand:HI 0 "register_operand" "")
10287 (any_rotate:HI (match_dup 0) (const_int 8)))
10288 (clobber (reg:CC FLAGS_REG))]
10290 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10291 [(parallel [(set (strict_low_part (match_dup 0))
10292 (bswap:HI (match_dup 0)))
10293 (clobber (reg:CC FLAGS_REG))])])
10295 ;; Bit set / bit test instructions
10297 (define_expand "extv"
10298 [(set (match_operand:SI 0 "register_operand" "")
10299 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10300 (match_operand:SI 2 "const8_operand" "")
10301 (match_operand:SI 3 "const8_operand" "")))]
10304 /* Handle extractions from %ah et al. */
10305 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10308 /* From mips.md: extract_bit_field doesn't verify that our source
10309 matches the predicate, so check it again here. */
10310 if (! ext_register_operand (operands[1], VOIDmode))
10314 (define_expand "extzv"
10315 [(set (match_operand:SI 0 "register_operand" "")
10316 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10317 (match_operand:SI 2 "const8_operand" "")
10318 (match_operand:SI 3 "const8_operand" "")))]
10321 /* Handle extractions from %ah et al. */
10322 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10325 /* From mips.md: extract_bit_field doesn't verify that our source
10326 matches the predicate, so check it again here. */
10327 if (! ext_register_operand (operands[1], VOIDmode))
10331 (define_expand "insv"
10332 [(set (zero_extract (match_operand 0 "register_operand" "")
10333 (match_operand 1 "const_int_operand" "")
10334 (match_operand 2 "const_int_operand" ""))
10335 (match_operand 3 "register_operand" ""))]
10338 rtx (*gen_mov_insv_1) (rtx, rtx);
10340 if (ix86_expand_pinsr (operands))
10343 /* Handle insertions to %ah et al. */
10344 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10347 /* From mips.md: insert_bit_field doesn't verify that our source
10348 matches the predicate, so check it again here. */
10349 if (! ext_register_operand (operands[0], VOIDmode))
10352 gen_mov_insv_1 = (TARGET_64BIT
10353 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10355 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10359 ;; %%% bts, btr, btc, bt.
10360 ;; In general these instructions are *slow* when applied to memory,
10361 ;; since they enforce atomic operation. When applied to registers,
10362 ;; it depends on the cpu implementation. They're never faster than
10363 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10364 ;; no point. But in 64-bit, we can't hold the relevant immediates
10365 ;; within the instruction itself, so operating on bits in the high
10366 ;; 32-bits of a register becomes easier.
10368 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10369 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10370 ;; negdf respectively, so they can never be disabled entirely.
10372 (define_insn "*btsq"
10373 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10375 (match_operand:DI 1 "const_0_to_63_operand" ""))
10377 (clobber (reg:CC FLAGS_REG))]
10378 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10379 "bts{q}\t{%1, %0|%0, %1}"
10380 [(set_attr "type" "alu1")
10381 (set_attr "prefix_0f" "1")
10382 (set_attr "mode" "DI")])
10384 (define_insn "*btrq"
10385 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10387 (match_operand:DI 1 "const_0_to_63_operand" ""))
10389 (clobber (reg:CC FLAGS_REG))]
10390 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10391 "btr{q}\t{%1, %0|%0, %1}"
10392 [(set_attr "type" "alu1")
10393 (set_attr "prefix_0f" "1")
10394 (set_attr "mode" "DI")])
10396 (define_insn "*btcq"
10397 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10399 (match_operand:DI 1 "const_0_to_63_operand" ""))
10400 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10401 (clobber (reg:CC FLAGS_REG))]
10402 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10403 "btc{q}\t{%1, %0|%0, %1}"
10404 [(set_attr "type" "alu1")
10405 (set_attr "prefix_0f" "1")
10406 (set_attr "mode" "DI")])
10408 ;; Allow Nocona to avoid these instructions if a register is available.
10411 [(match_scratch:DI 2 "r")
10412 (parallel [(set (zero_extract:DI
10413 (match_operand:DI 0 "register_operand" "")
10415 (match_operand:DI 1 "const_0_to_63_operand" ""))
10417 (clobber (reg:CC FLAGS_REG))])]
10418 "TARGET_64BIT && !TARGET_USE_BT"
10421 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10424 if (HOST_BITS_PER_WIDE_INT >= 64)
10425 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10426 else if (i < HOST_BITS_PER_WIDE_INT)
10427 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10429 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10431 op1 = immed_double_const (lo, hi, DImode);
10434 emit_move_insn (operands[2], op1);
10438 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10443 [(match_scratch:DI 2 "r")
10444 (parallel [(set (zero_extract:DI
10445 (match_operand:DI 0 "register_operand" "")
10447 (match_operand:DI 1 "const_0_to_63_operand" ""))
10449 (clobber (reg:CC FLAGS_REG))])]
10450 "TARGET_64BIT && !TARGET_USE_BT"
10453 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10456 if (HOST_BITS_PER_WIDE_INT >= 64)
10457 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10458 else if (i < HOST_BITS_PER_WIDE_INT)
10459 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10461 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10463 op1 = immed_double_const (~lo, ~hi, DImode);
10466 emit_move_insn (operands[2], op1);
10470 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10475 [(match_scratch:DI 2 "r")
10476 (parallel [(set (zero_extract:DI
10477 (match_operand:DI 0 "register_operand" "")
10479 (match_operand:DI 1 "const_0_to_63_operand" ""))
10480 (not:DI (zero_extract:DI
10481 (match_dup 0) (const_int 1) (match_dup 1))))
10482 (clobber (reg:CC FLAGS_REG))])]
10483 "TARGET_64BIT && !TARGET_USE_BT"
10486 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10489 if (HOST_BITS_PER_WIDE_INT >= 64)
10490 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10491 else if (i < HOST_BITS_PER_WIDE_INT)
10492 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10494 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10496 op1 = immed_double_const (lo, hi, DImode);
10499 emit_move_insn (operands[2], op1);
10503 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10507 (define_insn "*bt<mode>"
10508 [(set (reg:CCC FLAGS_REG)
10510 (zero_extract:SWI48
10511 (match_operand:SWI48 0 "register_operand" "r")
10513 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10515 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10516 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10517 [(set_attr "type" "alu1")
10518 (set_attr "prefix_0f" "1")
10519 (set_attr "mode" "<MODE>")])
10521 ;; Store-flag instructions.
10523 ;; For all sCOND expanders, also expand the compare or test insn that
10524 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10526 (define_insn_and_split "*setcc_di_1"
10527 [(set (match_operand:DI 0 "register_operand" "=q")
10528 (match_operator:DI 1 "ix86_comparison_operator"
10529 [(reg FLAGS_REG) (const_int 0)]))]
10530 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10532 "&& reload_completed"
10533 [(set (match_dup 2) (match_dup 1))
10534 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10536 PUT_MODE (operands[1], QImode);
10537 operands[2] = gen_lowpart (QImode, operands[0]);
10540 (define_insn_and_split "*setcc_si_1_and"
10541 [(set (match_operand:SI 0 "register_operand" "=q")
10542 (match_operator:SI 1 "ix86_comparison_operator"
10543 [(reg FLAGS_REG) (const_int 0)]))
10544 (clobber (reg:CC FLAGS_REG))]
10545 "!TARGET_PARTIAL_REG_STALL
10546 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10548 "&& reload_completed"
10549 [(set (match_dup 2) (match_dup 1))
10550 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10551 (clobber (reg:CC FLAGS_REG))])]
10553 PUT_MODE (operands[1], QImode);
10554 operands[2] = gen_lowpart (QImode, operands[0]);
10557 (define_insn_and_split "*setcc_si_1_movzbl"
10558 [(set (match_operand:SI 0 "register_operand" "=q")
10559 (match_operator:SI 1 "ix86_comparison_operator"
10560 [(reg FLAGS_REG) (const_int 0)]))]
10561 "!TARGET_PARTIAL_REG_STALL
10562 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10564 "&& reload_completed"
10565 [(set (match_dup 2) (match_dup 1))
10566 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10568 PUT_MODE (operands[1], QImode);
10569 operands[2] = gen_lowpart (QImode, operands[0]);
10572 (define_insn "*setcc_qi"
10573 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10574 (match_operator:QI 1 "ix86_comparison_operator"
10575 [(reg FLAGS_REG) (const_int 0)]))]
10578 [(set_attr "type" "setcc")
10579 (set_attr "mode" "QI")])
10581 (define_insn "*setcc_qi_slp"
10582 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10583 (match_operator:QI 1 "ix86_comparison_operator"
10584 [(reg FLAGS_REG) (const_int 0)]))]
10587 [(set_attr "type" "setcc")
10588 (set_attr "mode" "QI")])
10590 ;; In general it is not safe to assume too much about CCmode registers,
10591 ;; so simplify-rtx stops when it sees a second one. Under certain
10592 ;; conditions this is safe on x86, so help combine not create
10599 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10600 (ne:QI (match_operator 1 "ix86_comparison_operator"
10601 [(reg FLAGS_REG) (const_int 0)])
10604 [(set (match_dup 0) (match_dup 1))]
10605 "PUT_MODE (operands[1], QImode);")
10608 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10609 (ne:QI (match_operator 1 "ix86_comparison_operator"
10610 [(reg FLAGS_REG) (const_int 0)])
10613 [(set (match_dup 0) (match_dup 1))]
10614 "PUT_MODE (operands[1], QImode);")
10617 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10618 (eq:QI (match_operator 1 "ix86_comparison_operator"
10619 [(reg FLAGS_REG) (const_int 0)])
10622 [(set (match_dup 0) (match_dup 1))]
10624 rtx new_op1 = copy_rtx (operands[1]);
10625 operands[1] = new_op1;
10626 PUT_MODE (new_op1, QImode);
10627 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10628 GET_MODE (XEXP (new_op1, 0))));
10630 /* Make sure that (a) the CCmode we have for the flags is strong
10631 enough for the reversed compare or (b) we have a valid FP compare. */
10632 if (! ix86_comparison_operator (new_op1, VOIDmode))
10637 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10638 (eq:QI (match_operator 1 "ix86_comparison_operator"
10639 [(reg FLAGS_REG) (const_int 0)])
10642 [(set (match_dup 0) (match_dup 1))]
10644 rtx new_op1 = copy_rtx (operands[1]);
10645 operands[1] = new_op1;
10646 PUT_MODE (new_op1, QImode);
10647 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10648 GET_MODE (XEXP (new_op1, 0))));
10650 /* Make sure that (a) the CCmode we have for the flags is strong
10651 enough for the reversed compare or (b) we have a valid FP compare. */
10652 if (! ix86_comparison_operator (new_op1, VOIDmode))
10656 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10657 ;; subsequent logical operations are used to imitate conditional moves.
10658 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10661 (define_insn "setcc_<mode>_sse"
10662 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10663 (match_operator:MODEF 3 "sse_comparison_operator"
10664 [(match_operand:MODEF 1 "register_operand" "0,x")
10665 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10666 "SSE_FLOAT_MODE_P (<MODE>mode)"
10668 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10669 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10670 [(set_attr "isa" "noavx,avx")
10671 (set_attr "type" "ssecmp")
10672 (set_attr "length_immediate" "1")
10673 (set_attr "prefix" "orig,vex")
10674 (set_attr "mode" "<MODE>")])
10676 ;; Basic conditional jump instructions.
10677 ;; We ignore the overflow flag for signed branch instructions.
10679 (define_insn "*jcc_1"
10681 (if_then_else (match_operator 1 "ix86_comparison_operator"
10682 [(reg FLAGS_REG) (const_int 0)])
10683 (label_ref (match_operand 0 "" ""))
10687 [(set_attr "type" "ibr")
10688 (set_attr "modrm" "0")
10689 (set (attr "length")
10690 (if_then_else (and (ge (minus (match_dup 0) (pc))
10692 (lt (minus (match_dup 0) (pc))
10697 (define_insn "*jcc_2"
10699 (if_then_else (match_operator 1 "ix86_comparison_operator"
10700 [(reg FLAGS_REG) (const_int 0)])
10702 (label_ref (match_operand 0 "" ""))))]
10705 [(set_attr "type" "ibr")
10706 (set_attr "modrm" "0")
10707 (set (attr "length")
10708 (if_then_else (and (ge (minus (match_dup 0) (pc))
10710 (lt (minus (match_dup 0) (pc))
10715 ;; In general it is not safe to assume too much about CCmode registers,
10716 ;; so simplify-rtx stops when it sees a second one. Under certain
10717 ;; conditions this is safe on x86, so help combine not create
10725 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10726 [(reg FLAGS_REG) (const_int 0)])
10728 (label_ref (match_operand 1 "" ""))
10732 (if_then_else (match_dup 0)
10733 (label_ref (match_dup 1))
10735 "PUT_MODE (operands[0], VOIDmode);")
10739 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10740 [(reg FLAGS_REG) (const_int 0)])
10742 (label_ref (match_operand 1 "" ""))
10746 (if_then_else (match_dup 0)
10747 (label_ref (match_dup 1))
10750 rtx new_op0 = copy_rtx (operands[0]);
10751 operands[0] = new_op0;
10752 PUT_MODE (new_op0, VOIDmode);
10753 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10754 GET_MODE (XEXP (new_op0, 0))));
10756 /* Make sure that (a) the CCmode we have for the flags is strong
10757 enough for the reversed compare or (b) we have a valid FP compare. */
10758 if (! ix86_comparison_operator (new_op0, VOIDmode))
10762 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10763 ;; pass generates from shift insn with QImode operand. Actually, the mode
10764 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10765 ;; appropriate modulo of the bit offset value.
10767 (define_insn_and_split "*jcc_bt<mode>"
10769 (if_then_else (match_operator 0 "bt_comparison_operator"
10770 [(zero_extract:SWI48
10771 (match_operand:SWI48 1 "register_operand" "r")
10774 (match_operand:QI 2 "register_operand" "r")))
10776 (label_ref (match_operand 3 "" ""))
10778 (clobber (reg:CC FLAGS_REG))]
10779 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10782 [(set (reg:CCC FLAGS_REG)
10784 (zero_extract:SWI48
10790 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10791 (label_ref (match_dup 3))
10794 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10796 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10799 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10800 ;; also for DImode, this is what combine produces.
10801 (define_insn_and_split "*jcc_bt<mode>_mask"
10803 (if_then_else (match_operator 0 "bt_comparison_operator"
10804 [(zero_extract:SWI48
10805 (match_operand:SWI48 1 "register_operand" "r")
10808 (match_operand:SI 2 "register_operand" "r")
10809 (match_operand:SI 3 "const_int_operand" "n")))])
10810 (label_ref (match_operand 4 "" ""))
10812 (clobber (reg:CC FLAGS_REG))]
10813 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10814 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10815 == GET_MODE_BITSIZE (<MODE>mode)-1"
10818 [(set (reg:CCC FLAGS_REG)
10820 (zero_extract:SWI48
10826 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10827 (label_ref (match_dup 4))
10830 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10832 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10835 (define_insn_and_split "*jcc_btsi_1"
10837 (if_then_else (match_operator 0 "bt_comparison_operator"
10840 (match_operand:SI 1 "register_operand" "r")
10841 (match_operand:QI 2 "register_operand" "r"))
10844 (label_ref (match_operand 3 "" ""))
10846 (clobber (reg:CC FLAGS_REG))]
10847 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10850 [(set (reg:CCC FLAGS_REG)
10858 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10859 (label_ref (match_dup 3))
10862 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10864 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10867 ;; avoid useless masking of bit offset operand
10868 (define_insn_and_split "*jcc_btsi_mask_1"
10871 (match_operator 0 "bt_comparison_operator"
10874 (match_operand:SI 1 "register_operand" "r")
10877 (match_operand:SI 2 "register_operand" "r")
10878 (match_operand:SI 3 "const_int_operand" "n")) 0))
10881 (label_ref (match_operand 4 "" ""))
10883 (clobber (reg:CC FLAGS_REG))]
10884 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10885 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10888 [(set (reg:CCC FLAGS_REG)
10896 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10897 (label_ref (match_dup 4))
10899 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10901 ;; Define combination compare-and-branch fp compare instructions to help
10904 (define_insn "*fp_jcc_1_387"
10906 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10907 [(match_operand 1 "register_operand" "f")
10908 (match_operand 2 "nonimmediate_operand" "fm")])
10909 (label_ref (match_operand 3 "" ""))
10911 (clobber (reg:CCFP FPSR_REG))
10912 (clobber (reg:CCFP FLAGS_REG))
10913 (clobber (match_scratch:HI 4 "=a"))]
10915 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10916 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10917 && SELECT_CC_MODE (GET_CODE (operands[0]),
10918 operands[1], operands[2]) == CCFPmode
10922 (define_insn "*fp_jcc_1r_387"
10924 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10925 [(match_operand 1 "register_operand" "f")
10926 (match_operand 2 "nonimmediate_operand" "fm")])
10928 (label_ref (match_operand 3 "" ""))))
10929 (clobber (reg:CCFP FPSR_REG))
10930 (clobber (reg:CCFP FLAGS_REG))
10931 (clobber (match_scratch:HI 4 "=a"))]
10933 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10934 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10935 && SELECT_CC_MODE (GET_CODE (operands[0]),
10936 operands[1], operands[2]) == CCFPmode
10940 (define_insn "*fp_jcc_2_387"
10942 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10943 [(match_operand 1 "register_operand" "f")
10944 (match_operand 2 "register_operand" "f")])
10945 (label_ref (match_operand 3 "" ""))
10947 (clobber (reg:CCFP FPSR_REG))
10948 (clobber (reg:CCFP FLAGS_REG))
10949 (clobber (match_scratch:HI 4 "=a"))]
10950 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10951 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10955 (define_insn "*fp_jcc_2r_387"
10957 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10958 [(match_operand 1 "register_operand" "f")
10959 (match_operand 2 "register_operand" "f")])
10961 (label_ref (match_operand 3 "" ""))))
10962 (clobber (reg:CCFP FPSR_REG))
10963 (clobber (reg:CCFP FLAGS_REG))
10964 (clobber (match_scratch:HI 4 "=a"))]
10965 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10966 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10970 (define_insn "*fp_jcc_3_387"
10972 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10973 [(match_operand 1 "register_operand" "f")
10974 (match_operand 2 "const0_operand" "")])
10975 (label_ref (match_operand 3 "" ""))
10977 (clobber (reg:CCFP FPSR_REG))
10978 (clobber (reg:CCFP FLAGS_REG))
10979 (clobber (match_scratch:HI 4 "=a"))]
10980 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10981 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10982 && SELECT_CC_MODE (GET_CODE (operands[0]),
10983 operands[1], operands[2]) == CCFPmode
10989 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10990 [(match_operand 1 "register_operand" "")
10991 (match_operand 2 "nonimmediate_operand" "")])
10992 (match_operand 3 "" "")
10993 (match_operand 4 "" "")))
10994 (clobber (reg:CCFP FPSR_REG))
10995 (clobber (reg:CCFP FLAGS_REG))]
10999 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11000 operands[3], operands[4], NULL_RTX, NULL_RTX);
11006 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11007 [(match_operand 1 "register_operand" "")
11008 (match_operand 2 "general_operand" "")])
11009 (match_operand 3 "" "")
11010 (match_operand 4 "" "")))
11011 (clobber (reg:CCFP FPSR_REG))
11012 (clobber (reg:CCFP FLAGS_REG))
11013 (clobber (match_scratch:HI 5 "=a"))]
11017 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11018 operands[3], operands[4], operands[5], NULL_RTX);
11022 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11023 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11024 ;; with a precedence over other operators and is always put in the first
11025 ;; place. Swap condition and operands to match ficom instruction.
11027 (define_insn "*fp_jcc_4_<mode>_387"
11030 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11031 [(match_operator 1 "float_operator"
11032 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11033 (match_operand 3 "register_operand" "f,f")])
11034 (label_ref (match_operand 4 "" ""))
11036 (clobber (reg:CCFP FPSR_REG))
11037 (clobber (reg:CCFP FLAGS_REG))
11038 (clobber (match_scratch:HI 5 "=a,a"))]
11039 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11040 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11041 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11042 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11049 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11050 [(match_operator 1 "float_operator"
11051 [(match_operand:SWI24 2 "memory_operand" "")])
11052 (match_operand 3 "register_operand" "")])
11053 (match_operand 4 "" "")
11054 (match_operand 5 "" "")))
11055 (clobber (reg:CCFP FPSR_REG))
11056 (clobber (reg:CCFP FLAGS_REG))
11057 (clobber (match_scratch:HI 6 "=a"))]
11061 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11063 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11064 operands[3], operands[7],
11065 operands[4], operands[5], operands[6], NULL_RTX);
11069 ;; %%% Kill this when reload knows how to do it.
11073 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11074 [(match_operator 1 "float_operator"
11075 [(match_operand:SWI24 2 "register_operand" "")])
11076 (match_operand 3 "register_operand" "")])
11077 (match_operand 4 "" "")
11078 (match_operand 5 "" "")))
11079 (clobber (reg:CCFP FPSR_REG))
11080 (clobber (reg:CCFP FLAGS_REG))
11081 (clobber (match_scratch:HI 6 "=a"))]
11085 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11086 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11088 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11089 operands[3], operands[7],
11090 operands[4], operands[5], operands[6], operands[2]);
11094 ;; Unconditional and other jump instructions
11096 (define_insn "jump"
11098 (label_ref (match_operand 0 "" "")))]
11101 [(set_attr "type" "ibr")
11102 (set (attr "length")
11103 (if_then_else (and (ge (minus (match_dup 0) (pc))
11105 (lt (minus (match_dup 0) (pc))
11109 (set_attr "modrm" "0")])
11111 (define_expand "indirect_jump"
11112 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11114 (define_insn "*indirect_jump"
11115 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11118 [(set_attr "type" "ibr")
11119 (set_attr "length_immediate" "0")])
11121 (define_expand "tablejump"
11122 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11123 (use (label_ref (match_operand 1 "" "")))])]
11126 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11127 relative. Convert the relative address to an absolute address. */
11131 enum rtx_code code;
11133 /* We can't use @GOTOFF for text labels on VxWorks;
11134 see gotoff_operand. */
11135 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11139 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11141 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11145 op1 = pic_offset_table_rtx;
11150 op0 = pic_offset_table_rtx;
11154 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11157 else if (TARGET_X32)
11158 operands[0] = convert_memory_address (Pmode, operands[0]);
11161 (define_insn "*tablejump_1"
11162 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11163 (use (label_ref (match_operand 1 "" "")))]
11166 [(set_attr "type" "ibr")
11167 (set_attr "length_immediate" "0")])
11169 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11172 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11173 (set (match_operand:QI 1 "register_operand" "")
11174 (match_operator:QI 2 "ix86_comparison_operator"
11175 [(reg FLAGS_REG) (const_int 0)]))
11176 (set (match_operand 3 "q_regs_operand" "")
11177 (zero_extend (match_dup 1)))]
11178 "(peep2_reg_dead_p (3, operands[1])
11179 || operands_match_p (operands[1], operands[3]))
11180 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11181 [(set (match_dup 4) (match_dup 0))
11182 (set (strict_low_part (match_dup 5))
11185 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11186 operands[5] = gen_lowpart (QImode, operands[3]);
11187 ix86_expand_clear (operands[3]);
11190 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11193 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11194 (set (match_operand:QI 1 "register_operand" "")
11195 (match_operator:QI 2 "ix86_comparison_operator"
11196 [(reg FLAGS_REG) (const_int 0)]))
11197 (parallel [(set (match_operand 3 "q_regs_operand" "")
11198 (zero_extend (match_dup 1)))
11199 (clobber (reg:CC FLAGS_REG))])]
11200 "(peep2_reg_dead_p (3, operands[1])
11201 || operands_match_p (operands[1], operands[3]))
11202 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11203 [(set (match_dup 4) (match_dup 0))
11204 (set (strict_low_part (match_dup 5))
11207 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11208 operands[5] = gen_lowpart (QImode, operands[3]);
11209 ix86_expand_clear (operands[3]);
11212 ;; Call instructions.
11214 ;; The predicates normally associated with named expanders are not properly
11215 ;; checked for calls. This is a bug in the generic code, but it isn't that
11216 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11218 ;; P6 processors will jump to the address after the decrement when %esp
11219 ;; is used as a call operand, so they will execute return address as a code.
11220 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11222 ;; Register constraint for call instruction.
11223 (define_mode_attr c [(SI "l") (DI "r")])
11225 ;; Call subroutine returning no value.
11227 (define_expand "call"
11228 [(call (match_operand:QI 0 "" "")
11229 (match_operand 1 "" ""))
11230 (use (match_operand 2 "" ""))]
11233 ix86_expand_call (NULL, operands[0], operands[1],
11234 operands[2], NULL, false);
11238 (define_expand "sibcall"
11239 [(call (match_operand:QI 0 "" "")
11240 (match_operand 1 "" ""))
11241 (use (match_operand 2 "" ""))]
11244 ix86_expand_call (NULL, operands[0], operands[1],
11245 operands[2], NULL, true);
11249 (define_insn_and_split "*call_vzeroupper"
11250 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11251 (match_operand 1 "" ""))
11252 (unspec [(match_operand 2 "const_int_operand" "")]
11253 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11254 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11256 "&& reload_completed"
11258 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11259 [(set_attr "type" "call")])
11261 (define_insn "*call"
11262 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11263 (match_operand 1 "" ""))]
11264 "!SIBLING_CALL_P (insn)"
11265 "* return ix86_output_call_insn (insn, operands[0]);"
11266 [(set_attr "type" "call")])
11268 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11269 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11270 (match_operand 1 "" ""))
11271 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11272 (clobber (reg:TI XMM6_REG))
11273 (clobber (reg:TI XMM7_REG))
11274 (clobber (reg:TI XMM8_REG))
11275 (clobber (reg:TI XMM9_REG))
11276 (clobber (reg:TI XMM10_REG))
11277 (clobber (reg:TI XMM11_REG))
11278 (clobber (reg:TI XMM12_REG))
11279 (clobber (reg:TI XMM13_REG))
11280 (clobber (reg:TI XMM14_REG))
11281 (clobber (reg:TI XMM15_REG))
11282 (clobber (reg:DI SI_REG))
11283 (clobber (reg:DI DI_REG))
11284 (unspec [(match_operand 2 "const_int_operand" "")]
11285 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11286 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11288 "&& reload_completed"
11290 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11291 [(set_attr "type" "call")])
11293 (define_insn "*call_rex64_ms_sysv"
11294 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11295 (match_operand 1 "" ""))
11296 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11297 (clobber (reg:TI XMM6_REG))
11298 (clobber (reg:TI XMM7_REG))
11299 (clobber (reg:TI XMM8_REG))
11300 (clobber (reg:TI XMM9_REG))
11301 (clobber (reg:TI XMM10_REG))
11302 (clobber (reg:TI XMM11_REG))
11303 (clobber (reg:TI XMM12_REG))
11304 (clobber (reg:TI XMM13_REG))
11305 (clobber (reg:TI XMM14_REG))
11306 (clobber (reg:TI XMM15_REG))
11307 (clobber (reg:DI SI_REG))
11308 (clobber (reg:DI DI_REG))]
11309 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11310 "* return ix86_output_call_insn (insn, operands[0]);"
11311 [(set_attr "type" "call")])
11313 (define_insn_and_split "*sibcall_vzeroupper"
11314 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11315 (match_operand 1 "" ""))
11316 (unspec [(match_operand 2 "const_int_operand" "")]
11317 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11318 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11320 "&& reload_completed"
11322 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11323 [(set_attr "type" "call")])
11325 (define_insn "*sibcall"
11326 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11327 (match_operand 1 "" ""))]
11328 "SIBLING_CALL_P (insn)"
11329 "* return ix86_output_call_insn (insn, operands[0]);"
11330 [(set_attr "type" "call")])
11332 (define_expand "call_pop"
11333 [(parallel [(call (match_operand:QI 0 "" "")
11334 (match_operand:SI 1 "" ""))
11335 (set (reg:SI SP_REG)
11336 (plus:SI (reg:SI SP_REG)
11337 (match_operand:SI 3 "" "")))])]
11340 ix86_expand_call (NULL, operands[0], operands[1],
11341 operands[2], operands[3], false);
11345 (define_insn_and_split "*call_pop_vzeroupper"
11346 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11347 (match_operand:SI 1 "" ""))
11348 (set (reg:SI SP_REG)
11349 (plus:SI (reg:SI SP_REG)
11350 (match_operand:SI 2 "immediate_operand" "i")))
11351 (unspec [(match_operand 3 "const_int_operand" "")]
11352 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11353 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11355 "&& reload_completed"
11357 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11358 [(set_attr "type" "call")])
11360 (define_insn "*call_pop"
11361 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11362 (match_operand 1 "" ""))
11363 (set (reg:SI SP_REG)
11364 (plus:SI (reg:SI SP_REG)
11365 (match_operand:SI 2 "immediate_operand" "i")))]
11366 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11367 "* return ix86_output_call_insn (insn, operands[0]);"
11368 [(set_attr "type" "call")])
11370 (define_insn_and_split "*sibcall_pop_vzeroupper"
11371 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11372 (match_operand 1 "" ""))
11373 (set (reg:SI SP_REG)
11374 (plus:SI (reg:SI SP_REG)
11375 (match_operand:SI 2 "immediate_operand" "i")))
11376 (unspec [(match_operand 3 "const_int_operand" "")]
11377 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11378 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11380 "&& reload_completed"
11382 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11383 [(set_attr "type" "call")])
11385 (define_insn "*sibcall_pop"
11386 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11387 (match_operand 1 "" ""))
11388 (set (reg:SI SP_REG)
11389 (plus:SI (reg:SI SP_REG)
11390 (match_operand:SI 2 "immediate_operand" "i")))]
11391 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11392 "* return ix86_output_call_insn (insn, operands[0]);"
11393 [(set_attr "type" "call")])
11395 ;; Call subroutine, returning value in operand 0
11397 (define_expand "call_value"
11398 [(set (match_operand 0 "" "")
11399 (call (match_operand:QI 1 "" "")
11400 (match_operand 2 "" "")))
11401 (use (match_operand 3 "" ""))]
11404 ix86_expand_call (operands[0], operands[1], operands[2],
11405 operands[3], NULL, false);
11409 (define_expand "sibcall_value"
11410 [(set (match_operand 0 "" "")
11411 (call (match_operand:QI 1 "" "")
11412 (match_operand 2 "" "")))
11413 (use (match_operand 3 "" ""))]
11416 ix86_expand_call (operands[0], operands[1], operands[2],
11417 operands[3], NULL, true);
11421 (define_insn_and_split "*call_value_vzeroupper"
11422 [(set (match_operand 0 "" "")
11423 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11424 (match_operand 2 "" "")))
11425 (unspec [(match_operand 3 "const_int_operand" "")]
11426 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11427 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11429 "&& reload_completed"
11431 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11432 [(set_attr "type" "callv")])
11434 (define_insn "*call_value"
11435 [(set (match_operand 0 "" "")
11436 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11437 (match_operand 2 "" "")))]
11438 "!SIBLING_CALL_P (insn)"
11439 "* return ix86_output_call_insn (insn, operands[1]);"
11440 [(set_attr "type" "callv")])
11442 (define_insn_and_split "*sibcall_value_vzeroupper"
11443 [(set (match_operand 0 "" "")
11444 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11445 (match_operand 2 "" "")))
11446 (unspec [(match_operand 3 "const_int_operand" "")]
11447 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11448 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11450 "&& reload_completed"
11452 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11453 [(set_attr "type" "callv")])
11455 (define_insn "*sibcall_value"
11456 [(set (match_operand 0 "" "")
11457 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11458 (match_operand 2 "" "")))]
11459 "SIBLING_CALL_P (insn)"
11460 "* return ix86_output_call_insn (insn, operands[1]);"
11461 [(set_attr "type" "callv")])
11463 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11464 [(set (match_operand 0 "" "")
11465 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11466 (match_operand 2 "" "")))
11467 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11468 (clobber (reg:TI XMM6_REG))
11469 (clobber (reg:TI XMM7_REG))
11470 (clobber (reg:TI XMM8_REG))
11471 (clobber (reg:TI XMM9_REG))
11472 (clobber (reg:TI XMM10_REG))
11473 (clobber (reg:TI XMM11_REG))
11474 (clobber (reg:TI XMM12_REG))
11475 (clobber (reg:TI XMM13_REG))
11476 (clobber (reg:TI XMM14_REG))
11477 (clobber (reg:TI XMM15_REG))
11478 (clobber (reg:DI SI_REG))
11479 (clobber (reg:DI DI_REG))
11480 (unspec [(match_operand 3 "const_int_operand" "")]
11481 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11482 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11484 "&& reload_completed"
11486 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11487 [(set_attr "type" "callv")])
11489 (define_insn "*call_value_rex64_ms_sysv"
11490 [(set (match_operand 0 "" "")
11491 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11492 (match_operand 2 "" "")))
11493 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11494 (clobber (reg:TI XMM6_REG))
11495 (clobber (reg:TI XMM7_REG))
11496 (clobber (reg:TI XMM8_REG))
11497 (clobber (reg:TI XMM9_REG))
11498 (clobber (reg:TI XMM10_REG))
11499 (clobber (reg:TI XMM11_REG))
11500 (clobber (reg:TI XMM12_REG))
11501 (clobber (reg:TI XMM13_REG))
11502 (clobber (reg:TI XMM14_REG))
11503 (clobber (reg:TI XMM15_REG))
11504 (clobber (reg:DI SI_REG))
11505 (clobber (reg:DI DI_REG))]
11506 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11507 "* return ix86_output_call_insn (insn, operands[1]);"
11508 [(set_attr "type" "callv")])
11510 (define_expand "call_value_pop"
11511 [(parallel [(set (match_operand 0 "" "")
11512 (call (match_operand:QI 1 "" "")
11513 (match_operand:SI 2 "" "")))
11514 (set (reg:SI SP_REG)
11515 (plus:SI (reg:SI SP_REG)
11516 (match_operand:SI 4 "" "")))])]
11519 ix86_expand_call (operands[0], operands[1], operands[2],
11520 operands[3], operands[4], false);
11524 (define_insn_and_split "*call_value_pop_vzeroupper"
11525 [(set (match_operand 0 "" "")
11526 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11527 (match_operand 2 "" "")))
11528 (set (reg:SI SP_REG)
11529 (plus:SI (reg:SI SP_REG)
11530 (match_operand:SI 3 "immediate_operand" "i")))
11531 (unspec [(match_operand 4 "const_int_operand" "")]
11532 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11533 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11535 "&& reload_completed"
11537 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11538 [(set_attr "type" "callv")])
11540 (define_insn "*call_value_pop"
11541 [(set (match_operand 0 "" "")
11542 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11543 (match_operand 2 "" "")))
11544 (set (reg:SI SP_REG)
11545 (plus:SI (reg:SI SP_REG)
11546 (match_operand:SI 3 "immediate_operand" "i")))]
11547 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11548 "* return ix86_output_call_insn (insn, operands[1]);"
11549 [(set_attr "type" "callv")])
11551 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11552 [(set (match_operand 0 "" "")
11553 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11554 (match_operand 2 "" "")))
11555 (set (reg:SI SP_REG)
11556 (plus:SI (reg:SI SP_REG)
11557 (match_operand:SI 3 "immediate_operand" "i")))
11558 (unspec [(match_operand 4 "const_int_operand" "")]
11559 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11560 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11562 "&& reload_completed"
11564 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11565 [(set_attr "type" "callv")])
11567 (define_insn "*sibcall_value_pop"
11568 [(set (match_operand 0 "" "")
11569 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11570 (match_operand 2 "" "")))
11571 (set (reg:SI SP_REG)
11572 (plus:SI (reg:SI SP_REG)
11573 (match_operand:SI 3 "immediate_operand" "i")))]
11574 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11575 "* return ix86_output_call_insn (insn, operands[1]);"
11576 [(set_attr "type" "callv")])
11578 ;; Call subroutine returning any type.
11580 (define_expand "untyped_call"
11581 [(parallel [(call (match_operand 0 "" "")
11583 (match_operand 1 "" "")
11584 (match_operand 2 "" "")])]
11589 /* In order to give reg-stack an easier job in validating two
11590 coprocessor registers as containing a possible return value,
11591 simply pretend the untyped call returns a complex long double
11594 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11595 and should have the default ABI. */
11597 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11598 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11599 operands[0], const0_rtx,
11600 GEN_INT ((TARGET_64BIT
11601 ? (ix86_abi == SYSV_ABI
11602 ? X86_64_SSE_REGPARM_MAX
11603 : X86_64_MS_SSE_REGPARM_MAX)
11604 : X86_32_SSE_REGPARM_MAX)
11608 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11610 rtx set = XVECEXP (operands[2], 0, i);
11611 emit_move_insn (SET_DEST (set), SET_SRC (set));
11614 /* The optimizer does not know that the call sets the function value
11615 registers we stored in the result block. We avoid problems by
11616 claiming that all hard registers are used and clobbered at this
11618 emit_insn (gen_blockage ());
11623 ;; Prologue and epilogue instructions
11625 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11626 ;; all of memory. This blocks insns from being moved across this point.
11628 (define_insn "blockage"
11629 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11632 [(set_attr "length" "0")])
11634 ;; Do not schedule instructions accessing memory across this point.
11636 (define_expand "memory_blockage"
11637 [(set (match_dup 0)
11638 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11641 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11642 MEM_VOLATILE_P (operands[0]) = 1;
11645 (define_insn "*memory_blockage"
11646 [(set (match_operand:BLK 0 "" "")
11647 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11650 [(set_attr "length" "0")])
11652 ;; As USE insns aren't meaningful after reload, this is used instead
11653 ;; to prevent deleting instructions setting registers for PIC code
11654 (define_insn "prologue_use"
11655 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11658 [(set_attr "length" "0")])
11660 ;; Insn emitted into the body of a function to return from a function.
11661 ;; This is only done if the function's epilogue is known to be simple.
11662 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11664 (define_expand "return"
11666 "ix86_can_use_return_insn_p ()"
11668 ix86_maybe_emit_epilogue_vzeroupper ();
11669 if (crtl->args.pops_args)
11671 rtx popc = GEN_INT (crtl->args.pops_args);
11672 emit_jump_insn (gen_simple_return_pop_internal (popc));
11677 ;; We need to disable this for TARGET_SEH, as otherwise
11678 ;; shrink-wrapped prologue gets enabled too. This might exceed
11679 ;; the maximum size of prologue in unwind information.
11681 (define_expand "simple_return"
11685 ix86_maybe_emit_epilogue_vzeroupper ();
11686 if (crtl->args.pops_args)
11688 rtx popc = GEN_INT (crtl->args.pops_args);
11689 emit_jump_insn (gen_simple_return_pop_internal (popc));
11694 (define_insn "simple_return_internal"
11698 [(set_attr "length" "1")
11699 (set_attr "atom_unit" "jeu")
11700 (set_attr "length_immediate" "0")
11701 (set_attr "modrm" "0")])
11703 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11704 ;; instruction Athlon and K8 have.
11706 (define_insn "simple_return_internal_long"
11708 (unspec [(const_int 0)] UNSPEC_REP)]
11711 [(set_attr "length" "2")
11712 (set_attr "atom_unit" "jeu")
11713 (set_attr "length_immediate" "0")
11714 (set_attr "prefix_rep" "1")
11715 (set_attr "modrm" "0")])
11717 (define_insn "simple_return_pop_internal"
11719 (use (match_operand:SI 0 "const_int_operand" ""))]
11722 [(set_attr "length" "3")
11723 (set_attr "atom_unit" "jeu")
11724 (set_attr "length_immediate" "2")
11725 (set_attr "modrm" "0")])
11727 (define_insn "simple_return_indirect_internal"
11729 (use (match_operand:SI 0 "register_operand" "r"))]
11732 [(set_attr "type" "ibr")
11733 (set_attr "length_immediate" "0")])
11739 [(set_attr "length" "1")
11740 (set_attr "length_immediate" "0")
11741 (set_attr "modrm" "0")])
11743 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11744 (define_insn "nops"
11745 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11749 int num = INTVAL (operands[0]);
11751 gcc_assert (num >= 1 && num <= 8);
11754 fputs ("\tnop\n", asm_out_file);
11758 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11759 (set_attr "length_immediate" "0")
11760 (set_attr "modrm" "0")])
11762 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11763 ;; branch prediction penalty for the third jump in a 16-byte
11767 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11770 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11771 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11773 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11774 The align insn is used to avoid 3 jump instructions in the row to improve
11775 branch prediction and the benefits hardly outweigh the cost of extra 8
11776 nops on the average inserted by full alignment pseudo operation. */
11780 [(set_attr "length" "16")])
11782 (define_expand "prologue"
11785 "ix86_expand_prologue (); DONE;")
11787 (define_insn "set_got"
11788 [(set (match_operand:SI 0 "register_operand" "=r")
11789 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11790 (clobber (reg:CC FLAGS_REG))]
11792 "* return output_set_got (operands[0], NULL_RTX);"
11793 [(set_attr "type" "multi")
11794 (set_attr "length" "12")])
11796 (define_insn "set_got_labelled"
11797 [(set (match_operand:SI 0 "register_operand" "=r")
11798 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11800 (clobber (reg:CC FLAGS_REG))]
11802 "* return output_set_got (operands[0], operands[1]);"
11803 [(set_attr "type" "multi")
11804 (set_attr "length" "12")])
11806 (define_insn "set_got_rex64"
11807 [(set (match_operand:DI 0 "register_operand" "=r")
11808 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11810 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11811 [(set_attr "type" "lea")
11812 (set_attr "length_address" "4")
11813 (set_attr "mode" "DI")])
11815 (define_insn "set_rip_rex64"
11816 [(set (match_operand:DI 0 "register_operand" "=r")
11817 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11819 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11820 [(set_attr "type" "lea")
11821 (set_attr "length_address" "4")
11822 (set_attr "mode" "DI")])
11824 (define_insn "set_got_offset_rex64"
11825 [(set (match_operand:DI 0 "register_operand" "=r")
11827 [(label_ref (match_operand 1 "" ""))]
11828 UNSPEC_SET_GOT_OFFSET))]
11830 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11831 [(set_attr "type" "imov")
11832 (set_attr "length_immediate" "0")
11833 (set_attr "length_address" "8")
11834 (set_attr "mode" "DI")])
11836 (define_expand "epilogue"
11839 "ix86_expand_epilogue (1); DONE;")
11841 (define_expand "sibcall_epilogue"
11844 "ix86_expand_epilogue (0); DONE;")
11846 (define_expand "eh_return"
11847 [(use (match_operand 0 "register_operand" ""))]
11850 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11852 /* Tricky bit: we write the address of the handler to which we will
11853 be returning into someone else's stack frame, one word below the
11854 stack address we wish to restore. */
11855 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11856 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11857 tmp = gen_rtx_MEM (Pmode, tmp);
11858 emit_move_insn (tmp, ra);
11860 emit_jump_insn (gen_eh_return_internal ());
11865 (define_insn_and_split "eh_return_internal"
11869 "epilogue_completed"
11871 "ix86_expand_epilogue (2); DONE;")
11873 (define_insn "leave"
11874 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11875 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11876 (clobber (mem:BLK (scratch)))]
11879 [(set_attr "type" "leave")])
11881 (define_insn "leave_rex64"
11882 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11883 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11884 (clobber (mem:BLK (scratch)))]
11887 [(set_attr "type" "leave")])
11889 ;; Handle -fsplit-stack.
11891 (define_expand "split_stack_prologue"
11895 ix86_expand_split_stack_prologue ();
11899 ;; In order to support the call/return predictor, we use a return
11900 ;; instruction which the middle-end doesn't see.
11901 (define_insn "split_stack_return"
11902 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11903 UNSPECV_SPLIT_STACK_RETURN)]
11906 if (operands[0] == const0_rtx)
11911 [(set_attr "atom_unit" "jeu")
11912 (set_attr "modrm" "0")
11913 (set (attr "length")
11914 (if_then_else (match_operand:SI 0 "const0_operand" "")
11917 (set (attr "length_immediate")
11918 (if_then_else (match_operand:SI 0 "const0_operand" "")
11922 ;; If there are operand 0 bytes available on the stack, jump to
11925 (define_expand "split_stack_space_check"
11926 [(set (pc) (if_then_else
11927 (ltu (minus (reg SP_REG)
11928 (match_operand 0 "register_operand" ""))
11929 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11930 (label_ref (match_operand 1 "" ""))
11934 rtx reg, size, limit;
11936 reg = gen_reg_rtx (Pmode);
11937 size = force_reg (Pmode, operands[0]);
11938 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11939 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11940 UNSPEC_STACK_CHECK);
11941 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11942 ix86_expand_branch (GEU, reg, limit, operands[1]);
11947 ;; Bit manipulation instructions.
11949 (define_expand "ffs<mode>2"
11950 [(set (match_dup 2) (const_int -1))
11951 (parallel [(set (reg:CCZ FLAGS_REG)
11953 (match_operand:SWI48 1 "nonimmediate_operand" "")
11955 (set (match_operand:SWI48 0 "register_operand" "")
11956 (ctz:SWI48 (match_dup 1)))])
11957 (set (match_dup 0) (if_then_else:SWI48
11958 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11961 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11962 (clobber (reg:CC FLAGS_REG))])]
11965 if (<MODE>mode == SImode && !TARGET_CMOVE)
11967 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11970 operands[2] = gen_reg_rtx (<MODE>mode);
11973 (define_insn_and_split "ffssi2_no_cmove"
11974 [(set (match_operand:SI 0 "register_operand" "=r")
11975 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11976 (clobber (match_scratch:SI 2 "=&q"))
11977 (clobber (reg:CC FLAGS_REG))]
11980 "&& reload_completed"
11981 [(parallel [(set (reg:CCZ FLAGS_REG)
11982 (compare:CCZ (match_dup 1) (const_int 0)))
11983 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11984 (set (strict_low_part (match_dup 3))
11985 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11986 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11987 (clobber (reg:CC FLAGS_REG))])
11988 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11989 (clobber (reg:CC FLAGS_REG))])
11990 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11991 (clobber (reg:CC FLAGS_REG))])]
11993 operands[3] = gen_lowpart (QImode, operands[2]);
11994 ix86_expand_clear (operands[2]);
11997 (define_insn "*ffs<mode>_1"
11998 [(set (reg:CCZ FLAGS_REG)
11999 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12001 (set (match_operand:SWI48 0 "register_operand" "=r")
12002 (ctz:SWI48 (match_dup 1)))]
12004 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12005 [(set_attr "type" "alu1")
12006 (set_attr "prefix_0f" "1")
12007 (set_attr "mode" "<MODE>")])
12009 (define_insn "ctz<mode>2"
12010 [(set (match_operand:SWI248 0 "register_operand" "=r")
12011 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12012 (clobber (reg:CC FLAGS_REG))]
12016 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12018 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12020 [(set_attr "type" "alu1")
12021 (set_attr "prefix_0f" "1")
12022 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12023 (set_attr "mode" "<MODE>")])
12025 (define_expand "clz<mode>2"
12027 [(set (match_operand:SWI248 0 "register_operand" "")
12030 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12031 (clobber (reg:CC FLAGS_REG))])
12033 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12034 (clobber (reg:CC FLAGS_REG))])]
12039 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12042 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12045 (define_insn "clz<mode>2_lzcnt"
12046 [(set (match_operand:SWI248 0 "register_operand" "=r")
12047 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12048 (clobber (reg:CC FLAGS_REG))]
12050 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12051 [(set_attr "prefix_rep" "1")
12052 (set_attr "type" "bitmanip")
12053 (set_attr "mode" "<MODE>")])
12055 ;; BMI instructions.
12056 (define_insn "*bmi_andn_<mode>"
12057 [(set (match_operand:SWI48 0 "register_operand" "=r")
12060 (match_operand:SWI48 1 "register_operand" "r"))
12061 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12062 (clobber (reg:CC FLAGS_REG))]
12064 "andn\t{%2, %1, %0|%0, %1, %2}"
12065 [(set_attr "type" "bitmanip")
12066 (set_attr "mode" "<MODE>")])
12068 (define_insn "bmi_bextr_<mode>"
12069 [(set (match_operand:SWI48 0 "register_operand" "=r")
12070 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12071 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12073 (clobber (reg:CC FLAGS_REG))]
12075 "bextr\t{%2, %1, %0|%0, %1, %2}"
12076 [(set_attr "type" "bitmanip")
12077 (set_attr "mode" "<MODE>")])
12079 (define_insn "*bmi_blsi_<mode>"
12080 [(set (match_operand:SWI48 0 "register_operand" "=r")
12083 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12085 (clobber (reg:CC FLAGS_REG))]
12087 "blsi\t{%1, %0|%0, %1}"
12088 [(set_attr "type" "bitmanip")
12089 (set_attr "mode" "<MODE>")])
12091 (define_insn "*bmi_blsmsk_<mode>"
12092 [(set (match_operand:SWI48 0 "register_operand" "=r")
12095 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12098 (clobber (reg:CC FLAGS_REG))]
12100 "blsmsk\t{%1, %0|%0, %1}"
12101 [(set_attr "type" "bitmanip")
12102 (set_attr "mode" "<MODE>")])
12104 (define_insn "*bmi_blsr_<mode>"
12105 [(set (match_operand:SWI48 0 "register_operand" "=r")
12108 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12111 (clobber (reg:CC FLAGS_REG))]
12113 "blsr\t{%1, %0|%0, %1}"
12114 [(set_attr "type" "bitmanip")
12115 (set_attr "mode" "<MODE>")])
12117 ;; BMI2 instructions.
12118 (define_insn "bmi2_bzhi_<mode>3"
12119 [(set (match_operand:SWI48 0 "register_operand" "=r")
12120 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12121 (lshiftrt:SWI48 (const_int -1)
12122 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12123 (clobber (reg:CC FLAGS_REG))]
12125 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12126 [(set_attr "type" "bitmanip")
12127 (set_attr "prefix" "vex")
12128 (set_attr "mode" "<MODE>")])
12130 (define_insn "bmi2_pdep_<mode>3"
12131 [(set (match_operand:SWI48 0 "register_operand" "=r")
12132 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12133 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12136 "pdep\t{%2, %1, %0|%0, %1, %2}"
12137 [(set_attr "type" "bitmanip")
12138 (set_attr "prefix" "vex")
12139 (set_attr "mode" "<MODE>")])
12141 (define_insn "bmi2_pext_<mode>3"
12142 [(set (match_operand:SWI48 0 "register_operand" "=r")
12143 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12144 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12147 "pext\t{%2, %1, %0|%0, %1, %2}"
12148 [(set_attr "type" "bitmanip")
12149 (set_attr "prefix" "vex")
12150 (set_attr "mode" "<MODE>")])
12152 ;; TBM instructions.
12153 (define_insn "tbm_bextri_<mode>"
12154 [(set (match_operand:SWI48 0 "register_operand" "=r")
12155 (zero_extract:SWI48
12156 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12157 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12158 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12159 (clobber (reg:CC FLAGS_REG))]
12162 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12163 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12165 [(set_attr "type" "bitmanip")
12166 (set_attr "mode" "<MODE>")])
12168 (define_insn "*tbm_blcfill_<mode>"
12169 [(set (match_operand:SWI48 0 "register_operand" "=r")
12172 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12175 (clobber (reg:CC FLAGS_REG))]
12177 "blcfill\t{%1, %0|%0, %1}"
12178 [(set_attr "type" "bitmanip")
12179 (set_attr "mode" "<MODE>")])
12181 (define_insn "*tbm_blci_<mode>"
12182 [(set (match_operand:SWI48 0 "register_operand" "=r")
12186 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12189 (clobber (reg:CC FLAGS_REG))]
12191 "blci\t{%1, %0|%0, %1}"
12192 [(set_attr "type" "bitmanip")
12193 (set_attr "mode" "<MODE>")])
12195 (define_insn "*tbm_blcic_<mode>"
12196 [(set (match_operand:SWI48 0 "register_operand" "=r")
12199 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12203 (clobber (reg:CC FLAGS_REG))]
12205 "blcic\t{%1, %0|%0, %1}"
12206 [(set_attr "type" "bitmanip")
12207 (set_attr "mode" "<MODE>")])
12209 (define_insn "*tbm_blcmsk_<mode>"
12210 [(set (match_operand:SWI48 0 "register_operand" "=r")
12213 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12216 (clobber (reg:CC FLAGS_REG))]
12218 "blcmsk\t{%1, %0|%0, %1}"
12219 [(set_attr "type" "bitmanip")
12220 (set_attr "mode" "<MODE>")])
12222 (define_insn "*tbm_blcs_<mode>"
12223 [(set (match_operand:SWI48 0 "register_operand" "=r")
12226 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12229 (clobber (reg:CC FLAGS_REG))]
12231 "blcs\t{%1, %0|%0, %1}"
12232 [(set_attr "type" "bitmanip")
12233 (set_attr "mode" "<MODE>")])
12235 (define_insn "*tbm_blsfill_<mode>"
12236 [(set (match_operand:SWI48 0 "register_operand" "=r")
12239 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12242 (clobber (reg:CC FLAGS_REG))]
12244 "blsfill\t{%1, %0|%0, %1}"
12245 [(set_attr "type" "bitmanip")
12246 (set_attr "mode" "<MODE>")])
12248 (define_insn "*tbm_blsic_<mode>"
12249 [(set (match_operand:SWI48 0 "register_operand" "=r")
12252 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12256 (clobber (reg:CC FLAGS_REG))]
12258 "blsic\t{%1, %0|%0, %1}"
12259 [(set_attr "type" "bitmanip")
12260 (set_attr "mode" "<MODE>")])
12262 (define_insn "*tbm_t1mskc_<mode>"
12263 [(set (match_operand:SWI48 0 "register_operand" "=r")
12266 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12270 (clobber (reg:CC FLAGS_REG))]
12272 "t1mskc\t{%1, %0|%0, %1}"
12273 [(set_attr "type" "bitmanip")
12274 (set_attr "mode" "<MODE>")])
12276 (define_insn "*tbm_tzmsk_<mode>"
12277 [(set (match_operand:SWI48 0 "register_operand" "=r")
12280 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12284 (clobber (reg:CC FLAGS_REG))]
12286 "tzmsk\t{%1, %0|%0, %1}"
12287 [(set_attr "type" "bitmanip")
12288 (set_attr "mode" "<MODE>")])
12290 (define_insn "bsr_rex64"
12291 [(set (match_operand:DI 0 "register_operand" "=r")
12292 (minus:DI (const_int 63)
12293 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12294 (clobber (reg:CC FLAGS_REG))]
12296 "bsr{q}\t{%1, %0|%0, %1}"
12297 [(set_attr "type" "alu1")
12298 (set_attr "prefix_0f" "1")
12299 (set_attr "mode" "DI")])
12302 [(set (match_operand:SI 0 "register_operand" "=r")
12303 (minus:SI (const_int 31)
12304 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12305 (clobber (reg:CC FLAGS_REG))]
12307 "bsr{l}\t{%1, %0|%0, %1}"
12308 [(set_attr "type" "alu1")
12309 (set_attr "prefix_0f" "1")
12310 (set_attr "mode" "SI")])
12312 (define_insn "*bsrhi"
12313 [(set (match_operand:HI 0 "register_operand" "=r")
12314 (minus:HI (const_int 15)
12315 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12316 (clobber (reg:CC FLAGS_REG))]
12318 "bsr{w}\t{%1, %0|%0, %1}"
12319 [(set_attr "type" "alu1")
12320 (set_attr "prefix_0f" "1")
12321 (set_attr "mode" "HI")])
12323 (define_insn "popcount<mode>2"
12324 [(set (match_operand:SWI248 0 "register_operand" "=r")
12326 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12327 (clobber (reg:CC FLAGS_REG))]
12331 return "popcnt\t{%1, %0|%0, %1}";
12333 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12336 [(set_attr "prefix_rep" "1")
12337 (set_attr "type" "bitmanip")
12338 (set_attr "mode" "<MODE>")])
12340 (define_insn "*popcount<mode>2_cmp"
12341 [(set (reg FLAGS_REG)
12344 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12346 (set (match_operand:SWI248 0 "register_operand" "=r")
12347 (popcount:SWI248 (match_dup 1)))]
12348 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12351 return "popcnt\t{%1, %0|%0, %1}";
12353 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12356 [(set_attr "prefix_rep" "1")
12357 (set_attr "type" "bitmanip")
12358 (set_attr "mode" "<MODE>")])
12360 (define_insn "*popcountsi2_cmp_zext"
12361 [(set (reg FLAGS_REG)
12363 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12365 (set (match_operand:DI 0 "register_operand" "=r")
12366 (zero_extend:DI(popcount:SI (match_dup 1))))]
12367 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12370 return "popcnt\t{%1, %0|%0, %1}";
12372 return "popcnt{l}\t{%1, %0|%0, %1}";
12375 [(set_attr "prefix_rep" "1")
12376 (set_attr "type" "bitmanip")
12377 (set_attr "mode" "SI")])
12379 (define_expand "bswap<mode>2"
12380 [(set (match_operand:SWI48 0 "register_operand" "")
12381 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12384 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12386 rtx x = operands[0];
12388 emit_move_insn (x, operands[1]);
12389 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12390 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12391 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12396 (define_insn "*bswap<mode>2_movbe"
12397 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12398 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12400 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12403 movbe\t{%1, %0|%0, %1}
12404 movbe\t{%1, %0|%0, %1}"
12405 [(set_attr "type" "bitmanip,imov,imov")
12406 (set_attr "modrm" "0,1,1")
12407 (set_attr "prefix_0f" "*,1,1")
12408 (set_attr "prefix_extra" "*,1,1")
12409 (set_attr "mode" "<MODE>")])
12411 (define_insn "*bswap<mode>2_1"
12412 [(set (match_operand:SWI48 0 "register_operand" "=r")
12413 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12416 [(set_attr "type" "bitmanip")
12417 (set_attr "modrm" "0")
12418 (set_attr "mode" "<MODE>")])
12420 (define_insn "*bswaphi_lowpart_1"
12421 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12422 (bswap:HI (match_dup 0)))
12423 (clobber (reg:CC FLAGS_REG))]
12424 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12426 xchg{b}\t{%h0, %b0|%b0, %h0}
12427 rol{w}\t{$8, %0|%0, 8}"
12428 [(set_attr "length" "2,4")
12429 (set_attr "mode" "QI,HI")])
12431 (define_insn "bswaphi_lowpart"
12432 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12433 (bswap:HI (match_dup 0)))
12434 (clobber (reg:CC FLAGS_REG))]
12436 "rol{w}\t{$8, %0|%0, 8}"
12437 [(set_attr "length" "4")
12438 (set_attr "mode" "HI")])
12440 (define_expand "paritydi2"
12441 [(set (match_operand:DI 0 "register_operand" "")
12442 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12445 rtx scratch = gen_reg_rtx (QImode);
12448 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12449 NULL_RTX, operands[1]));
12451 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12452 gen_rtx_REG (CCmode, FLAGS_REG),
12454 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12457 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12460 rtx tmp = gen_reg_rtx (SImode);
12462 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12463 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12468 (define_expand "paritysi2"
12469 [(set (match_operand:SI 0 "register_operand" "")
12470 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12473 rtx scratch = gen_reg_rtx (QImode);
12476 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12478 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12479 gen_rtx_REG (CCmode, FLAGS_REG),
12481 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12483 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12487 (define_insn_and_split "paritydi2_cmp"
12488 [(set (reg:CC FLAGS_REG)
12489 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12491 (clobber (match_scratch:DI 0 "=r"))
12492 (clobber (match_scratch:SI 1 "=&r"))
12493 (clobber (match_scratch:HI 2 "=Q"))]
12496 "&& reload_completed"
12498 [(set (match_dup 1)
12499 (xor:SI (match_dup 1) (match_dup 4)))
12500 (clobber (reg:CC FLAGS_REG))])
12502 [(set (reg:CC FLAGS_REG)
12503 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12504 (clobber (match_dup 1))
12505 (clobber (match_dup 2))])]
12507 operands[4] = gen_lowpart (SImode, operands[3]);
12511 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12512 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12515 operands[1] = gen_highpart (SImode, operands[3]);
12518 (define_insn_and_split "paritysi2_cmp"
12519 [(set (reg:CC FLAGS_REG)
12520 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12522 (clobber (match_scratch:SI 0 "=r"))
12523 (clobber (match_scratch:HI 1 "=&Q"))]
12526 "&& reload_completed"
12528 [(set (match_dup 1)
12529 (xor:HI (match_dup 1) (match_dup 3)))
12530 (clobber (reg:CC FLAGS_REG))])
12532 [(set (reg:CC FLAGS_REG)
12533 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12534 (clobber (match_dup 1))])]
12536 operands[3] = gen_lowpart (HImode, operands[2]);
12538 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12539 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12542 (define_insn "*parityhi2_cmp"
12543 [(set (reg:CC FLAGS_REG)
12544 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12546 (clobber (match_scratch:HI 0 "=Q"))]
12548 "xor{b}\t{%h0, %b0|%b0, %h0}"
12549 [(set_attr "length" "2")
12550 (set_attr "mode" "HI")])
12553 ;; Thread-local storage patterns for ELF.
12555 ;; Note that these code sequences must appear exactly as shown
12556 ;; in order to allow linker relaxation.
12558 (define_insn "*tls_global_dynamic_32_gnu"
12559 [(set (match_operand:SI 0 "register_operand" "=a")
12561 [(match_operand:SI 1 "register_operand" "b")
12562 (match_operand:SI 2 "tls_symbolic_operand" "")
12563 (match_operand:SI 3 "constant_call_address_operand" "z")]
12565 (clobber (match_scratch:SI 4 "=d"))
12566 (clobber (match_scratch:SI 5 "=c"))
12567 (clobber (reg:CC FLAGS_REG))]
12568 "!TARGET_64BIT && TARGET_GNU_TLS"
12571 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12572 if (TARGET_SUN_TLS)
12573 #ifdef HAVE_AS_IX86_TLSGDPLT
12574 return "call\t%a2@tlsgdplt";
12576 return "call\t%p3@plt";
12578 return "call\t%P3";
12580 [(set_attr "type" "multi")
12581 (set_attr "length" "12")])
12583 (define_expand "tls_global_dynamic_32"
12585 [(set (match_operand:SI 0 "register_operand" "")
12586 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12587 (match_operand:SI 1 "tls_symbolic_operand" "")
12588 (match_operand:SI 3 "constant_call_address_operand" "")]
12590 (clobber (match_scratch:SI 4 ""))
12591 (clobber (match_scratch:SI 5 ""))
12592 (clobber (reg:CC FLAGS_REG))])])
12594 (define_insn "*tls_global_dynamic_64"
12595 [(set (match_operand:DI 0 "register_operand" "=a")
12597 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12598 (match_operand:DI 3 "" "")))
12599 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12604 fputs (ASM_BYTE "0x66\n", asm_out_file);
12606 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12607 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12608 fputs ("\trex64\n", asm_out_file);
12609 if (TARGET_SUN_TLS)
12610 return "call\t%p2@plt";
12611 return "call\t%P2";
12613 [(set_attr "type" "multi")
12614 (set (attr "length")
12615 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12617 (define_expand "tls_global_dynamic_64"
12619 [(set (match_operand:DI 0 "register_operand" "")
12621 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12623 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12626 (define_insn "*tls_local_dynamic_base_32_gnu"
12627 [(set (match_operand:SI 0 "register_operand" "=a")
12629 [(match_operand:SI 1 "register_operand" "b")
12630 (match_operand:SI 2 "constant_call_address_operand" "z")]
12631 UNSPEC_TLS_LD_BASE))
12632 (clobber (match_scratch:SI 3 "=d"))
12633 (clobber (match_scratch:SI 4 "=c"))
12634 (clobber (reg:CC FLAGS_REG))]
12635 "!TARGET_64BIT && TARGET_GNU_TLS"
12638 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12639 if (TARGET_SUN_TLS)
12640 #ifdef HAVE_AS_IX86_TLSLDMPLT
12641 return "call\t%&@tlsldmplt";
12643 return "call\t%p2@plt";
12645 return "call\t%P2";
12647 [(set_attr "type" "multi")
12648 (set_attr "length" "11")])
12650 (define_expand "tls_local_dynamic_base_32"
12652 [(set (match_operand:SI 0 "register_operand" "")
12654 [(match_operand:SI 1 "register_operand" "")
12655 (match_operand:SI 2 "constant_call_address_operand" "")]
12656 UNSPEC_TLS_LD_BASE))
12657 (clobber (match_scratch:SI 3 ""))
12658 (clobber (match_scratch:SI 4 ""))
12659 (clobber (reg:CC FLAGS_REG))])])
12661 (define_insn "*tls_local_dynamic_base_64"
12662 [(set (match_operand:DI 0 "register_operand" "=a")
12664 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12665 (match_operand:DI 2 "" "")))
12666 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12670 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12671 if (TARGET_SUN_TLS)
12672 return "call\t%p1@plt";
12673 return "call\t%P1";
12675 [(set_attr "type" "multi")
12676 (set_attr "length" "12")])
12678 (define_expand "tls_local_dynamic_base_64"
12680 [(set (match_operand:DI 0 "register_operand" "")
12682 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12684 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12686 ;; Local dynamic of a single variable is a lose. Show combine how
12687 ;; to convert that back to global dynamic.
12689 (define_insn_and_split "*tls_local_dynamic_32_once"
12690 [(set (match_operand:SI 0 "register_operand" "=a")
12692 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12693 (match_operand:SI 2 "constant_call_address_operand" "z")]
12694 UNSPEC_TLS_LD_BASE)
12695 (const:SI (unspec:SI
12696 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12698 (clobber (match_scratch:SI 4 "=d"))
12699 (clobber (match_scratch:SI 5 "=c"))
12700 (clobber (reg:CC FLAGS_REG))]
12705 [(set (match_dup 0)
12706 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12708 (clobber (match_dup 4))
12709 (clobber (match_dup 5))
12710 (clobber (reg:CC FLAGS_REG))])])
12712 ;; Segment register for the thread base ptr load
12713 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12715 ;; Load and add the thread base pointer from %<tp_seg>:0.
12716 (define_insn "*load_tp_x32"
12717 [(set (match_operand:SI 0 "register_operand" "=r")
12718 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12720 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12721 [(set_attr "type" "imov")
12722 (set_attr "modrm" "0")
12723 (set_attr "length" "7")
12724 (set_attr "memory" "load")
12725 (set_attr "imm_disp" "false")])
12727 (define_insn "*load_tp_x32_zext"
12728 [(set (match_operand:DI 0 "register_operand" "=r")
12729 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12731 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12732 [(set_attr "type" "imov")
12733 (set_attr "modrm" "0")
12734 (set_attr "length" "7")
12735 (set_attr "memory" "load")
12736 (set_attr "imm_disp" "false")])
12738 (define_insn "*load_tp_<mode>"
12739 [(set (match_operand:P 0 "register_operand" "=r")
12740 (unspec:P [(const_int 0)] UNSPEC_TP))]
12742 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12743 [(set_attr "type" "imov")
12744 (set_attr "modrm" "0")
12745 (set_attr "length" "7")
12746 (set_attr "memory" "load")
12747 (set_attr "imm_disp" "false")])
12749 (define_insn "*add_tp_x32"
12750 [(set (match_operand:SI 0 "register_operand" "=r")
12751 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12752 (match_operand:SI 1 "register_operand" "0")))
12753 (clobber (reg:CC FLAGS_REG))]
12755 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12756 [(set_attr "type" "alu")
12757 (set_attr "modrm" "0")
12758 (set_attr "length" "7")
12759 (set_attr "memory" "load")
12760 (set_attr "imm_disp" "false")])
12762 (define_insn "*add_tp_x32_zext"
12763 [(set (match_operand:DI 0 "register_operand" "=r")
12765 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12766 (match_operand:SI 1 "register_operand" "0"))))
12767 (clobber (reg:CC FLAGS_REG))]
12769 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12770 [(set_attr "type" "alu")
12771 (set_attr "modrm" "0")
12772 (set_attr "length" "7")
12773 (set_attr "memory" "load")
12774 (set_attr "imm_disp" "false")])
12776 (define_insn "*add_tp_<mode>"
12777 [(set (match_operand:P 0 "register_operand" "=r")
12778 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12779 (match_operand:P 1 "register_operand" "0")))
12780 (clobber (reg:CC FLAGS_REG))]
12782 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12783 [(set_attr "type" "alu")
12784 (set_attr "modrm" "0")
12785 (set_attr "length" "7")
12786 (set_attr "memory" "load")
12787 (set_attr "imm_disp" "false")])
12789 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12790 ;; %rax as destination of the initial executable code sequence.
12791 (define_insn "tls_initial_exec_64_sun"
12792 [(set (match_operand:DI 0 "register_operand" "=a")
12794 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12795 UNSPEC_TLS_IE_SUN))
12796 (clobber (reg:CC FLAGS_REG))]
12797 "TARGET_64BIT && TARGET_SUN_TLS"
12800 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12801 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12803 [(set_attr "type" "multi")])
12805 ;; GNU2 TLS patterns can be split.
12807 (define_expand "tls_dynamic_gnu2_32"
12808 [(set (match_dup 3)
12809 (plus:SI (match_operand:SI 2 "register_operand" "")
12811 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12814 [(set (match_operand:SI 0 "register_operand" "")
12815 (unspec:SI [(match_dup 1) (match_dup 3)
12816 (match_dup 2) (reg:SI SP_REG)]
12818 (clobber (reg:CC FLAGS_REG))])]
12819 "!TARGET_64BIT && TARGET_GNU2_TLS"
12821 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12822 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12825 (define_insn "*tls_dynamic_gnu2_lea_32"
12826 [(set (match_operand:SI 0 "register_operand" "=r")
12827 (plus:SI (match_operand:SI 1 "register_operand" "b")
12829 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12830 UNSPEC_TLSDESC))))]
12831 "!TARGET_64BIT && TARGET_GNU2_TLS"
12832 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12833 [(set_attr "type" "lea")
12834 (set_attr "mode" "SI")
12835 (set_attr "length" "6")
12836 (set_attr "length_address" "4")])
12838 (define_insn "*tls_dynamic_gnu2_call_32"
12839 [(set (match_operand:SI 0 "register_operand" "=a")
12840 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12841 (match_operand:SI 2 "register_operand" "0")
12842 ;; we have to make sure %ebx still points to the GOT
12843 (match_operand:SI 3 "register_operand" "b")
12846 (clobber (reg:CC FLAGS_REG))]
12847 "!TARGET_64BIT && TARGET_GNU2_TLS"
12848 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12849 [(set_attr "type" "call")
12850 (set_attr "length" "2")
12851 (set_attr "length_address" "0")])
12853 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12854 [(set (match_operand:SI 0 "register_operand" "=&a")
12856 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12857 (match_operand:SI 4 "" "")
12858 (match_operand:SI 2 "register_operand" "b")
12861 (const:SI (unspec:SI
12862 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12864 (clobber (reg:CC FLAGS_REG))]
12865 "!TARGET_64BIT && TARGET_GNU2_TLS"
12868 [(set (match_dup 0) (match_dup 5))]
12870 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12871 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12874 (define_expand "tls_dynamic_gnu2_64"
12875 [(set (match_dup 2)
12876 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12879 [(set (match_operand:DI 0 "register_operand" "")
12880 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12882 (clobber (reg:CC FLAGS_REG))])]
12883 "TARGET_64BIT && TARGET_GNU2_TLS"
12885 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12886 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12889 (define_insn "*tls_dynamic_gnu2_lea_64"
12890 [(set (match_operand:DI 0 "register_operand" "=r")
12891 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12893 "TARGET_64BIT && TARGET_GNU2_TLS"
12894 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12895 [(set_attr "type" "lea")
12896 (set_attr "mode" "DI")
12897 (set_attr "length" "7")
12898 (set_attr "length_address" "4")])
12900 (define_insn "*tls_dynamic_gnu2_call_64"
12901 [(set (match_operand:DI 0 "register_operand" "=a")
12902 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12903 (match_operand:DI 2 "register_operand" "0")
12906 (clobber (reg:CC FLAGS_REG))]
12907 "TARGET_64BIT && TARGET_GNU2_TLS"
12908 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12909 [(set_attr "type" "call")
12910 (set_attr "length" "2")
12911 (set_attr "length_address" "0")])
12913 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12914 [(set (match_operand:DI 0 "register_operand" "=&a")
12916 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12917 (match_operand:DI 3 "" "")
12920 (const:DI (unspec:DI
12921 [(match_operand 1 "tls_symbolic_operand" "")]
12923 (clobber (reg:CC FLAGS_REG))]
12924 "TARGET_64BIT && TARGET_GNU2_TLS"
12927 [(set (match_dup 0) (match_dup 4))]
12929 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12930 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12933 ;; These patterns match the binary 387 instructions for addM3, subM3,
12934 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12935 ;; SFmode. The first is the normal insn, the second the same insn but
12936 ;; with one operand a conversion, and the third the same insn but with
12937 ;; the other operand a conversion. The conversion may be SFmode or
12938 ;; SImode if the target mode DFmode, but only SImode if the target mode
12941 ;; Gcc is slightly more smart about handling normal two address instructions
12942 ;; so use special patterns for add and mull.
12944 (define_insn "*fop_<mode>_comm_mixed"
12945 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12946 (match_operator:MODEF 3 "binary_fp_operator"
12947 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12948 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12949 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12950 && COMMUTATIVE_ARITH_P (operands[3])
12951 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12952 "* return output_387_binary_op (insn, operands);"
12953 [(set (attr "type")
12954 (if_then_else (eq_attr "alternative" "1,2")
12955 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12956 (const_string "ssemul")
12957 (const_string "sseadd"))
12958 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12959 (const_string "fmul")
12960 (const_string "fop"))))
12961 (set_attr "isa" "*,noavx,avx")
12962 (set_attr "prefix" "orig,orig,vex")
12963 (set_attr "mode" "<MODE>")])
12965 (define_insn "*fop_<mode>_comm_sse"
12966 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12967 (match_operator:MODEF 3 "binary_fp_operator"
12968 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12969 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12970 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12971 && COMMUTATIVE_ARITH_P (operands[3])
12972 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12973 "* return output_387_binary_op (insn, operands);"
12974 [(set (attr "type")
12975 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12976 (const_string "ssemul")
12977 (const_string "sseadd")))
12978 (set_attr "isa" "noavx,avx")
12979 (set_attr "prefix" "orig,vex")
12980 (set_attr "mode" "<MODE>")])
12982 (define_insn "*fop_<mode>_comm_i387"
12983 [(set (match_operand:MODEF 0 "register_operand" "=f")
12984 (match_operator:MODEF 3 "binary_fp_operator"
12985 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12986 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12987 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12988 && COMMUTATIVE_ARITH_P (operands[3])
12989 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12990 "* return output_387_binary_op (insn, operands);"
12991 [(set (attr "type")
12992 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12993 (const_string "fmul")
12994 (const_string "fop")))
12995 (set_attr "mode" "<MODE>")])
12997 (define_insn "*fop_<mode>_1_mixed"
12998 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12999 (match_operator:MODEF 3 "binary_fp_operator"
13000 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13001 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13002 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13003 && !COMMUTATIVE_ARITH_P (operands[3])
13004 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13005 "* return output_387_binary_op (insn, operands);"
13006 [(set (attr "type")
13007 (cond [(and (eq_attr "alternative" "2,3")
13008 (match_operand:MODEF 3 "mult_operator" ""))
13009 (const_string "ssemul")
13010 (and (eq_attr "alternative" "2,3")
13011 (match_operand:MODEF 3 "div_operator" ""))
13012 (const_string "ssediv")
13013 (eq_attr "alternative" "2,3")
13014 (const_string "sseadd")
13015 (match_operand:MODEF 3 "mult_operator" "")
13016 (const_string "fmul")
13017 (match_operand:MODEF 3 "div_operator" "")
13018 (const_string "fdiv")
13020 (const_string "fop")))
13021 (set_attr "isa" "*,*,noavx,avx")
13022 (set_attr "prefix" "orig,orig,orig,vex")
13023 (set_attr "mode" "<MODE>")])
13025 (define_insn "*rcpsf2_sse"
13026 [(set (match_operand:SF 0 "register_operand" "=x")
13027 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13030 "%vrcpss\t{%1, %d0|%d0, %1}"
13031 [(set_attr "type" "sse")
13032 (set_attr "atom_sse_attr" "rcp")
13033 (set_attr "prefix" "maybe_vex")
13034 (set_attr "mode" "SF")])
13036 (define_insn "*fop_<mode>_1_sse"
13037 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13038 (match_operator:MODEF 3 "binary_fp_operator"
13039 [(match_operand:MODEF 1 "register_operand" "0,x")
13040 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13041 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13042 && !COMMUTATIVE_ARITH_P (operands[3])"
13043 "* return output_387_binary_op (insn, operands);"
13044 [(set (attr "type")
13045 (cond [(match_operand:MODEF 3 "mult_operator" "")
13046 (const_string "ssemul")
13047 (match_operand:MODEF 3 "div_operator" "")
13048 (const_string "ssediv")
13050 (const_string "sseadd")))
13051 (set_attr "isa" "noavx,avx")
13052 (set_attr "prefix" "orig,vex")
13053 (set_attr "mode" "<MODE>")])
13055 ;; This pattern is not fully shadowed by the pattern above.
13056 (define_insn "*fop_<mode>_1_i387"
13057 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13058 (match_operator:MODEF 3 "binary_fp_operator"
13059 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13060 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13061 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13062 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13063 && !COMMUTATIVE_ARITH_P (operands[3])
13064 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13065 "* return output_387_binary_op (insn, operands);"
13066 [(set (attr "type")
13067 (cond [(match_operand:MODEF 3 "mult_operator" "")
13068 (const_string "fmul")
13069 (match_operand:MODEF 3 "div_operator" "")
13070 (const_string "fdiv")
13072 (const_string "fop")))
13073 (set_attr "mode" "<MODE>")])
13075 ;; ??? Add SSE splitters for these!
13076 (define_insn "*fop_<MODEF:mode>_2_i387"
13077 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13078 (match_operator:MODEF 3 "binary_fp_operator"
13080 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13081 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13082 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13083 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13084 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13085 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13086 [(set (attr "type")
13087 (cond [(match_operand:MODEF 3 "mult_operator" "")
13088 (const_string "fmul")
13089 (match_operand:MODEF 3 "div_operator" "")
13090 (const_string "fdiv")
13092 (const_string "fop")))
13093 (set_attr "fp_int_src" "true")
13094 (set_attr "mode" "<SWI24:MODE>")])
13096 (define_insn "*fop_<MODEF:mode>_3_i387"
13097 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13098 (match_operator:MODEF 3 "binary_fp_operator"
13099 [(match_operand:MODEF 1 "register_operand" "0,0")
13101 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13102 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13103 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13104 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13105 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13106 [(set (attr "type")
13107 (cond [(match_operand:MODEF 3 "mult_operator" "")
13108 (const_string "fmul")
13109 (match_operand:MODEF 3 "div_operator" "")
13110 (const_string "fdiv")
13112 (const_string "fop")))
13113 (set_attr "fp_int_src" "true")
13114 (set_attr "mode" "<MODE>")])
13116 (define_insn "*fop_df_4_i387"
13117 [(set (match_operand:DF 0 "register_operand" "=f,f")
13118 (match_operator:DF 3 "binary_fp_operator"
13120 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13121 (match_operand:DF 2 "register_operand" "0,f")]))]
13122 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13123 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13124 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13125 "* return output_387_binary_op (insn, operands);"
13126 [(set (attr "type")
13127 (cond [(match_operand:DF 3 "mult_operator" "")
13128 (const_string "fmul")
13129 (match_operand:DF 3 "div_operator" "")
13130 (const_string "fdiv")
13132 (const_string "fop")))
13133 (set_attr "mode" "SF")])
13135 (define_insn "*fop_df_5_i387"
13136 [(set (match_operand:DF 0 "register_operand" "=f,f")
13137 (match_operator:DF 3 "binary_fp_operator"
13138 [(match_operand:DF 1 "register_operand" "0,f")
13140 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13141 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13142 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13143 "* return output_387_binary_op (insn, operands);"
13144 [(set (attr "type")
13145 (cond [(match_operand:DF 3 "mult_operator" "")
13146 (const_string "fmul")
13147 (match_operand:DF 3 "div_operator" "")
13148 (const_string "fdiv")
13150 (const_string "fop")))
13151 (set_attr "mode" "SF")])
13153 (define_insn "*fop_df_6_i387"
13154 [(set (match_operand:DF 0 "register_operand" "=f,f")
13155 (match_operator:DF 3 "binary_fp_operator"
13157 (match_operand:SF 1 "register_operand" "0,f"))
13159 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13160 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13161 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13162 "* return output_387_binary_op (insn, operands);"
13163 [(set (attr "type")
13164 (cond [(match_operand:DF 3 "mult_operator" "")
13165 (const_string "fmul")
13166 (match_operand:DF 3 "div_operator" "")
13167 (const_string "fdiv")
13169 (const_string "fop")))
13170 (set_attr "mode" "SF")])
13172 (define_insn "*fop_xf_comm_i387"
13173 [(set (match_operand:XF 0 "register_operand" "=f")
13174 (match_operator:XF 3 "binary_fp_operator"
13175 [(match_operand:XF 1 "register_operand" "%0")
13176 (match_operand:XF 2 "register_operand" "f")]))]
13178 && COMMUTATIVE_ARITH_P (operands[3])"
13179 "* return output_387_binary_op (insn, operands);"
13180 [(set (attr "type")
13181 (if_then_else (match_operand:XF 3 "mult_operator" "")
13182 (const_string "fmul")
13183 (const_string "fop")))
13184 (set_attr "mode" "XF")])
13186 (define_insn "*fop_xf_1_i387"
13187 [(set (match_operand:XF 0 "register_operand" "=f,f")
13188 (match_operator:XF 3 "binary_fp_operator"
13189 [(match_operand:XF 1 "register_operand" "0,f")
13190 (match_operand:XF 2 "register_operand" "f,0")]))]
13192 && !COMMUTATIVE_ARITH_P (operands[3])"
13193 "* return output_387_binary_op (insn, operands);"
13194 [(set (attr "type")
13195 (cond [(match_operand:XF 3 "mult_operator" "")
13196 (const_string "fmul")
13197 (match_operand:XF 3 "div_operator" "")
13198 (const_string "fdiv")
13200 (const_string "fop")))
13201 (set_attr "mode" "XF")])
13203 (define_insn "*fop_xf_2_i387"
13204 [(set (match_operand:XF 0 "register_operand" "=f,f")
13205 (match_operator:XF 3 "binary_fp_operator"
13207 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13208 (match_operand:XF 2 "register_operand" "0,0")]))]
13209 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13210 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13211 [(set (attr "type")
13212 (cond [(match_operand:XF 3 "mult_operator" "")
13213 (const_string "fmul")
13214 (match_operand:XF 3 "div_operator" "")
13215 (const_string "fdiv")
13217 (const_string "fop")))
13218 (set_attr "fp_int_src" "true")
13219 (set_attr "mode" "<MODE>")])
13221 (define_insn "*fop_xf_3_i387"
13222 [(set (match_operand:XF 0 "register_operand" "=f,f")
13223 (match_operator:XF 3 "binary_fp_operator"
13224 [(match_operand:XF 1 "register_operand" "0,0")
13226 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13227 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13228 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13229 [(set (attr "type")
13230 (cond [(match_operand:XF 3 "mult_operator" "")
13231 (const_string "fmul")
13232 (match_operand:XF 3 "div_operator" "")
13233 (const_string "fdiv")
13235 (const_string "fop")))
13236 (set_attr "fp_int_src" "true")
13237 (set_attr "mode" "<MODE>")])
13239 (define_insn "*fop_xf_4_i387"
13240 [(set (match_operand:XF 0 "register_operand" "=f,f")
13241 (match_operator:XF 3 "binary_fp_operator"
13243 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13244 (match_operand:XF 2 "register_operand" "0,f")]))]
13246 "* return output_387_binary_op (insn, operands);"
13247 [(set (attr "type")
13248 (cond [(match_operand:XF 3 "mult_operator" "")
13249 (const_string "fmul")
13250 (match_operand:XF 3 "div_operator" "")
13251 (const_string "fdiv")
13253 (const_string "fop")))
13254 (set_attr "mode" "<MODE>")])
13256 (define_insn "*fop_xf_5_i387"
13257 [(set (match_operand:XF 0 "register_operand" "=f,f")
13258 (match_operator:XF 3 "binary_fp_operator"
13259 [(match_operand:XF 1 "register_operand" "0,f")
13261 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13263 "* return output_387_binary_op (insn, operands);"
13264 [(set (attr "type")
13265 (cond [(match_operand:XF 3 "mult_operator" "")
13266 (const_string "fmul")
13267 (match_operand:XF 3 "div_operator" "")
13268 (const_string "fdiv")
13270 (const_string "fop")))
13271 (set_attr "mode" "<MODE>")])
13273 (define_insn "*fop_xf_6_i387"
13274 [(set (match_operand:XF 0 "register_operand" "=f,f")
13275 (match_operator:XF 3 "binary_fp_operator"
13277 (match_operand:MODEF 1 "register_operand" "0,f"))
13279 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13281 "* return output_387_binary_op (insn, operands);"
13282 [(set (attr "type")
13283 (cond [(match_operand:XF 3 "mult_operator" "")
13284 (const_string "fmul")
13285 (match_operand:XF 3 "div_operator" "")
13286 (const_string "fdiv")
13288 (const_string "fop")))
13289 (set_attr "mode" "<MODE>")])
13292 [(set (match_operand 0 "register_operand" "")
13293 (match_operator 3 "binary_fp_operator"
13294 [(float (match_operand:SWI24 1 "register_operand" ""))
13295 (match_operand 2 "register_operand" "")]))]
13297 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13298 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13301 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13302 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13303 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13304 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13305 GET_MODE (operands[3]),
13308 ix86_free_from_memory (GET_MODE (operands[1]));
13313 [(set (match_operand 0 "register_operand" "")
13314 (match_operator 3 "binary_fp_operator"
13315 [(match_operand 1 "register_operand" "")
13316 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13318 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13319 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13322 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13323 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13324 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13325 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13326 GET_MODE (operands[3]),
13329 ix86_free_from_memory (GET_MODE (operands[2]));
13333 ;; FPU special functions.
13335 ;; This pattern implements a no-op XFmode truncation for
13336 ;; all fancy i386 XFmode math functions.
13338 (define_insn "truncxf<mode>2_i387_noop_unspec"
13339 [(set (match_operand:MODEF 0 "register_operand" "=f")
13340 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13341 UNSPEC_TRUNC_NOOP))]
13342 "TARGET_USE_FANCY_MATH_387"
13343 "* return output_387_reg_move (insn, operands);"
13344 [(set_attr "type" "fmov")
13345 (set_attr "mode" "<MODE>")])
13347 (define_insn "sqrtxf2"
13348 [(set (match_operand:XF 0 "register_operand" "=f")
13349 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13350 "TARGET_USE_FANCY_MATH_387"
13352 [(set_attr "type" "fpspc")
13353 (set_attr "mode" "XF")
13354 (set_attr "athlon_decode" "direct")
13355 (set_attr "amdfam10_decode" "direct")
13356 (set_attr "bdver1_decode" "direct")])
13358 (define_insn "sqrt_extend<mode>xf2_i387"
13359 [(set (match_operand:XF 0 "register_operand" "=f")
13362 (match_operand:MODEF 1 "register_operand" "0"))))]
13363 "TARGET_USE_FANCY_MATH_387"
13365 [(set_attr "type" "fpspc")
13366 (set_attr "mode" "XF")
13367 (set_attr "athlon_decode" "direct")
13368 (set_attr "amdfam10_decode" "direct")
13369 (set_attr "bdver1_decode" "direct")])
13371 (define_insn "*rsqrtsf2_sse"
13372 [(set (match_operand:SF 0 "register_operand" "=x")
13373 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13376 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13377 [(set_attr "type" "sse")
13378 (set_attr "atom_sse_attr" "rcp")
13379 (set_attr "prefix" "maybe_vex")
13380 (set_attr "mode" "SF")])
13382 (define_expand "rsqrtsf2"
13383 [(set (match_operand:SF 0 "register_operand" "")
13384 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13388 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13392 (define_insn "*sqrt<mode>2_sse"
13393 [(set (match_operand:MODEF 0 "register_operand" "=x")
13395 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13396 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13397 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13398 [(set_attr "type" "sse")
13399 (set_attr "atom_sse_attr" "sqrt")
13400 (set_attr "prefix" "maybe_vex")
13401 (set_attr "mode" "<MODE>")
13402 (set_attr "athlon_decode" "*")
13403 (set_attr "amdfam10_decode" "*")
13404 (set_attr "bdver1_decode" "*")])
13406 (define_expand "sqrt<mode>2"
13407 [(set (match_operand:MODEF 0 "register_operand" "")
13409 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13410 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13411 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13413 if (<MODE>mode == SFmode
13415 && TARGET_RECIP_SQRT
13416 && !optimize_function_for_size_p (cfun)
13417 && flag_finite_math_only && !flag_trapping_math
13418 && flag_unsafe_math_optimizations)
13420 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13424 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13426 rtx op0 = gen_reg_rtx (XFmode);
13427 rtx op1 = force_reg (<MODE>mode, operands[1]);
13429 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13430 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13435 (define_insn "fpremxf4_i387"
13436 [(set (match_operand:XF 0 "register_operand" "=f")
13437 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13438 (match_operand:XF 3 "register_operand" "1")]
13440 (set (match_operand:XF 1 "register_operand" "=u")
13441 (unspec:XF [(match_dup 2) (match_dup 3)]
13443 (set (reg:CCFP FPSR_REG)
13444 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13446 "TARGET_USE_FANCY_MATH_387"
13448 [(set_attr "type" "fpspc")
13449 (set_attr "mode" "XF")])
13451 (define_expand "fmodxf3"
13452 [(use (match_operand:XF 0 "register_operand" ""))
13453 (use (match_operand:XF 1 "general_operand" ""))
13454 (use (match_operand:XF 2 "general_operand" ""))]
13455 "TARGET_USE_FANCY_MATH_387"
13457 rtx label = gen_label_rtx ();
13459 rtx op1 = gen_reg_rtx (XFmode);
13460 rtx op2 = gen_reg_rtx (XFmode);
13462 emit_move_insn (op2, operands[2]);
13463 emit_move_insn (op1, operands[1]);
13465 emit_label (label);
13466 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13467 ix86_emit_fp_unordered_jump (label);
13468 LABEL_NUSES (label) = 1;
13470 emit_move_insn (operands[0], op1);
13474 (define_expand "fmod<mode>3"
13475 [(use (match_operand:MODEF 0 "register_operand" ""))
13476 (use (match_operand:MODEF 1 "general_operand" ""))
13477 (use (match_operand:MODEF 2 "general_operand" ""))]
13478 "TARGET_USE_FANCY_MATH_387"
13480 rtx (*gen_truncxf) (rtx, rtx);
13482 rtx label = gen_label_rtx ();
13484 rtx op1 = gen_reg_rtx (XFmode);
13485 rtx op2 = gen_reg_rtx (XFmode);
13487 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13488 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13490 emit_label (label);
13491 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13492 ix86_emit_fp_unordered_jump (label);
13493 LABEL_NUSES (label) = 1;
13495 /* Truncate the result properly for strict SSE math. */
13496 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13497 && !TARGET_MIX_SSE_I387)
13498 gen_truncxf = gen_truncxf<mode>2;
13500 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13502 emit_insn (gen_truncxf (operands[0], op1));
13506 (define_insn "fprem1xf4_i387"
13507 [(set (match_operand:XF 0 "register_operand" "=f")
13508 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13509 (match_operand:XF 3 "register_operand" "1")]
13511 (set (match_operand:XF 1 "register_operand" "=u")
13512 (unspec:XF [(match_dup 2) (match_dup 3)]
13514 (set (reg:CCFP FPSR_REG)
13515 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13517 "TARGET_USE_FANCY_MATH_387"
13519 [(set_attr "type" "fpspc")
13520 (set_attr "mode" "XF")])
13522 (define_expand "remainderxf3"
13523 [(use (match_operand:XF 0 "register_operand" ""))
13524 (use (match_operand:XF 1 "general_operand" ""))
13525 (use (match_operand:XF 2 "general_operand" ""))]
13526 "TARGET_USE_FANCY_MATH_387"
13528 rtx label = gen_label_rtx ();
13530 rtx op1 = gen_reg_rtx (XFmode);
13531 rtx op2 = gen_reg_rtx (XFmode);
13533 emit_move_insn (op2, operands[2]);
13534 emit_move_insn (op1, operands[1]);
13536 emit_label (label);
13537 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13538 ix86_emit_fp_unordered_jump (label);
13539 LABEL_NUSES (label) = 1;
13541 emit_move_insn (operands[0], op1);
13545 (define_expand "remainder<mode>3"
13546 [(use (match_operand:MODEF 0 "register_operand" ""))
13547 (use (match_operand:MODEF 1 "general_operand" ""))
13548 (use (match_operand:MODEF 2 "general_operand" ""))]
13549 "TARGET_USE_FANCY_MATH_387"
13551 rtx (*gen_truncxf) (rtx, rtx);
13553 rtx label = gen_label_rtx ();
13555 rtx op1 = gen_reg_rtx (XFmode);
13556 rtx op2 = gen_reg_rtx (XFmode);
13558 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13559 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13561 emit_label (label);
13563 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13564 ix86_emit_fp_unordered_jump (label);
13565 LABEL_NUSES (label) = 1;
13567 /* Truncate the result properly for strict SSE math. */
13568 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13569 && !TARGET_MIX_SSE_I387)
13570 gen_truncxf = gen_truncxf<mode>2;
13572 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13574 emit_insn (gen_truncxf (operands[0], op1));
13578 (define_insn "*sinxf2_i387"
13579 [(set (match_operand:XF 0 "register_operand" "=f")
13580 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13581 "TARGET_USE_FANCY_MATH_387
13582 && flag_unsafe_math_optimizations"
13584 [(set_attr "type" "fpspc")
13585 (set_attr "mode" "XF")])
13587 (define_insn "*sin_extend<mode>xf2_i387"
13588 [(set (match_operand:XF 0 "register_operand" "=f")
13589 (unspec:XF [(float_extend:XF
13590 (match_operand:MODEF 1 "register_operand" "0"))]
13592 "TARGET_USE_FANCY_MATH_387
13593 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13594 || TARGET_MIX_SSE_I387)
13595 && flag_unsafe_math_optimizations"
13597 [(set_attr "type" "fpspc")
13598 (set_attr "mode" "XF")])
13600 (define_insn "*cosxf2_i387"
13601 [(set (match_operand:XF 0 "register_operand" "=f")
13602 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13603 "TARGET_USE_FANCY_MATH_387
13604 && flag_unsafe_math_optimizations"
13606 [(set_attr "type" "fpspc")
13607 (set_attr "mode" "XF")])
13609 (define_insn "*cos_extend<mode>xf2_i387"
13610 [(set (match_operand:XF 0 "register_operand" "=f")
13611 (unspec:XF [(float_extend:XF
13612 (match_operand:MODEF 1 "register_operand" "0"))]
13614 "TARGET_USE_FANCY_MATH_387
13615 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13616 || TARGET_MIX_SSE_I387)
13617 && flag_unsafe_math_optimizations"
13619 [(set_attr "type" "fpspc")
13620 (set_attr "mode" "XF")])
13622 ;; When sincos pattern is defined, sin and cos builtin functions will be
13623 ;; expanded to sincos pattern with one of its outputs left unused.
13624 ;; CSE pass will figure out if two sincos patterns can be combined,
13625 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13626 ;; depending on the unused output.
13628 (define_insn "sincosxf3"
13629 [(set (match_operand:XF 0 "register_operand" "=f")
13630 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13631 UNSPEC_SINCOS_COS))
13632 (set (match_operand:XF 1 "register_operand" "=u")
13633 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13634 "TARGET_USE_FANCY_MATH_387
13635 && flag_unsafe_math_optimizations"
13637 [(set_attr "type" "fpspc")
13638 (set_attr "mode" "XF")])
13641 [(set (match_operand:XF 0 "register_operand" "")
13642 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13643 UNSPEC_SINCOS_COS))
13644 (set (match_operand:XF 1 "register_operand" "")
13645 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13646 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13647 && can_create_pseudo_p ()"
13648 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13651 [(set (match_operand:XF 0 "register_operand" "")
13652 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13653 UNSPEC_SINCOS_COS))
13654 (set (match_operand:XF 1 "register_operand" "")
13655 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13656 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13657 && can_create_pseudo_p ()"
13658 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13660 (define_insn "sincos_extend<mode>xf3_i387"
13661 [(set (match_operand:XF 0 "register_operand" "=f")
13662 (unspec:XF [(float_extend:XF
13663 (match_operand:MODEF 2 "register_operand" "0"))]
13664 UNSPEC_SINCOS_COS))
13665 (set (match_operand:XF 1 "register_operand" "=u")
13666 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13667 "TARGET_USE_FANCY_MATH_387
13668 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13669 || TARGET_MIX_SSE_I387)
13670 && flag_unsafe_math_optimizations"
13672 [(set_attr "type" "fpspc")
13673 (set_attr "mode" "XF")])
13676 [(set (match_operand:XF 0 "register_operand" "")
13677 (unspec:XF [(float_extend:XF
13678 (match_operand:MODEF 2 "register_operand" ""))]
13679 UNSPEC_SINCOS_COS))
13680 (set (match_operand:XF 1 "register_operand" "")
13681 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13682 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13683 && can_create_pseudo_p ()"
13684 [(set (match_dup 1)
13685 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13688 [(set (match_operand:XF 0 "register_operand" "")
13689 (unspec:XF [(float_extend:XF
13690 (match_operand:MODEF 2 "register_operand" ""))]
13691 UNSPEC_SINCOS_COS))
13692 (set (match_operand:XF 1 "register_operand" "")
13693 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13694 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13695 && can_create_pseudo_p ()"
13696 [(set (match_dup 0)
13697 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13699 (define_expand "sincos<mode>3"
13700 [(use (match_operand:MODEF 0 "register_operand" ""))
13701 (use (match_operand:MODEF 1 "register_operand" ""))
13702 (use (match_operand:MODEF 2 "register_operand" ""))]
13703 "TARGET_USE_FANCY_MATH_387
13704 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13705 || TARGET_MIX_SSE_I387)
13706 && flag_unsafe_math_optimizations"
13708 rtx op0 = gen_reg_rtx (XFmode);
13709 rtx op1 = gen_reg_rtx (XFmode);
13711 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13712 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13713 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13717 (define_insn "fptanxf4_i387"
13718 [(set (match_operand:XF 0 "register_operand" "=f")
13719 (match_operand:XF 3 "const_double_operand" "F"))
13720 (set (match_operand:XF 1 "register_operand" "=u")
13721 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13723 "TARGET_USE_FANCY_MATH_387
13724 && flag_unsafe_math_optimizations
13725 && standard_80387_constant_p (operands[3]) == 2"
13727 [(set_attr "type" "fpspc")
13728 (set_attr "mode" "XF")])
13730 (define_insn "fptan_extend<mode>xf4_i387"
13731 [(set (match_operand:MODEF 0 "register_operand" "=f")
13732 (match_operand:MODEF 3 "const_double_operand" "F"))
13733 (set (match_operand:XF 1 "register_operand" "=u")
13734 (unspec:XF [(float_extend:XF
13735 (match_operand:MODEF 2 "register_operand" "0"))]
13737 "TARGET_USE_FANCY_MATH_387
13738 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13739 || TARGET_MIX_SSE_I387)
13740 && flag_unsafe_math_optimizations
13741 && standard_80387_constant_p (operands[3]) == 2"
13743 [(set_attr "type" "fpspc")
13744 (set_attr "mode" "XF")])
13746 (define_expand "tanxf2"
13747 [(use (match_operand:XF 0 "register_operand" ""))
13748 (use (match_operand:XF 1 "register_operand" ""))]
13749 "TARGET_USE_FANCY_MATH_387
13750 && flag_unsafe_math_optimizations"
13752 rtx one = gen_reg_rtx (XFmode);
13753 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13755 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13759 (define_expand "tan<mode>2"
13760 [(use (match_operand:MODEF 0 "register_operand" ""))
13761 (use (match_operand:MODEF 1 "register_operand" ""))]
13762 "TARGET_USE_FANCY_MATH_387
13763 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13764 || TARGET_MIX_SSE_I387)
13765 && flag_unsafe_math_optimizations"
13767 rtx op0 = gen_reg_rtx (XFmode);
13769 rtx one = gen_reg_rtx (<MODE>mode);
13770 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13772 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13773 operands[1], op2));
13774 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13778 (define_insn "*fpatanxf3_i387"
13779 [(set (match_operand:XF 0 "register_operand" "=f")
13780 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13781 (match_operand:XF 2 "register_operand" "u")]
13783 (clobber (match_scratch:XF 3 "=2"))]
13784 "TARGET_USE_FANCY_MATH_387
13785 && flag_unsafe_math_optimizations"
13787 [(set_attr "type" "fpspc")
13788 (set_attr "mode" "XF")])
13790 (define_insn "fpatan_extend<mode>xf3_i387"
13791 [(set (match_operand:XF 0 "register_operand" "=f")
13792 (unspec:XF [(float_extend:XF
13793 (match_operand:MODEF 1 "register_operand" "0"))
13795 (match_operand:MODEF 2 "register_operand" "u"))]
13797 (clobber (match_scratch:XF 3 "=2"))]
13798 "TARGET_USE_FANCY_MATH_387
13799 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13800 || TARGET_MIX_SSE_I387)
13801 && flag_unsafe_math_optimizations"
13803 [(set_attr "type" "fpspc")
13804 (set_attr "mode" "XF")])
13806 (define_expand "atan2xf3"
13807 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13808 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13809 (match_operand:XF 1 "register_operand" "")]
13811 (clobber (match_scratch:XF 3 ""))])]
13812 "TARGET_USE_FANCY_MATH_387
13813 && flag_unsafe_math_optimizations")
13815 (define_expand "atan2<mode>3"
13816 [(use (match_operand:MODEF 0 "register_operand" ""))
13817 (use (match_operand:MODEF 1 "register_operand" ""))
13818 (use (match_operand:MODEF 2 "register_operand" ""))]
13819 "TARGET_USE_FANCY_MATH_387
13820 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13821 || TARGET_MIX_SSE_I387)
13822 && flag_unsafe_math_optimizations"
13824 rtx op0 = gen_reg_rtx (XFmode);
13826 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13827 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13831 (define_expand "atanxf2"
13832 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13833 (unspec:XF [(match_dup 2)
13834 (match_operand:XF 1 "register_operand" "")]
13836 (clobber (match_scratch:XF 3 ""))])]
13837 "TARGET_USE_FANCY_MATH_387
13838 && flag_unsafe_math_optimizations"
13840 operands[2] = gen_reg_rtx (XFmode);
13841 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13844 (define_expand "atan<mode>2"
13845 [(use (match_operand:MODEF 0 "register_operand" ""))
13846 (use (match_operand:MODEF 1 "register_operand" ""))]
13847 "TARGET_USE_FANCY_MATH_387
13848 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13849 || TARGET_MIX_SSE_I387)
13850 && flag_unsafe_math_optimizations"
13852 rtx op0 = gen_reg_rtx (XFmode);
13854 rtx op2 = gen_reg_rtx (<MODE>mode);
13855 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13857 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13858 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13862 (define_expand "asinxf2"
13863 [(set (match_dup 2)
13864 (mult:XF (match_operand:XF 1 "register_operand" "")
13866 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13867 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13868 (parallel [(set (match_operand:XF 0 "register_operand" "")
13869 (unspec:XF [(match_dup 5) (match_dup 1)]
13871 (clobber (match_scratch:XF 6 ""))])]
13872 "TARGET_USE_FANCY_MATH_387
13873 && flag_unsafe_math_optimizations"
13877 if (optimize_insn_for_size_p ())
13880 for (i = 2; i < 6; i++)
13881 operands[i] = gen_reg_rtx (XFmode);
13883 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13886 (define_expand "asin<mode>2"
13887 [(use (match_operand:MODEF 0 "register_operand" ""))
13888 (use (match_operand:MODEF 1 "general_operand" ""))]
13889 "TARGET_USE_FANCY_MATH_387
13890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13891 || TARGET_MIX_SSE_I387)
13892 && flag_unsafe_math_optimizations"
13894 rtx op0 = gen_reg_rtx (XFmode);
13895 rtx op1 = gen_reg_rtx (XFmode);
13897 if (optimize_insn_for_size_p ())
13900 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13901 emit_insn (gen_asinxf2 (op0, op1));
13902 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13906 (define_expand "acosxf2"
13907 [(set (match_dup 2)
13908 (mult:XF (match_operand:XF 1 "register_operand" "")
13910 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13911 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13912 (parallel [(set (match_operand:XF 0 "register_operand" "")
13913 (unspec:XF [(match_dup 1) (match_dup 5)]
13915 (clobber (match_scratch:XF 6 ""))])]
13916 "TARGET_USE_FANCY_MATH_387
13917 && flag_unsafe_math_optimizations"
13921 if (optimize_insn_for_size_p ())
13924 for (i = 2; i < 6; i++)
13925 operands[i] = gen_reg_rtx (XFmode);
13927 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13930 (define_expand "acos<mode>2"
13931 [(use (match_operand:MODEF 0 "register_operand" ""))
13932 (use (match_operand:MODEF 1 "general_operand" ""))]
13933 "TARGET_USE_FANCY_MATH_387
13934 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13935 || TARGET_MIX_SSE_I387)
13936 && flag_unsafe_math_optimizations"
13938 rtx op0 = gen_reg_rtx (XFmode);
13939 rtx op1 = gen_reg_rtx (XFmode);
13941 if (optimize_insn_for_size_p ())
13944 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13945 emit_insn (gen_acosxf2 (op0, op1));
13946 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13950 (define_insn "fyl2xxf3_i387"
13951 [(set (match_operand:XF 0 "register_operand" "=f")
13952 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13953 (match_operand:XF 2 "register_operand" "u")]
13955 (clobber (match_scratch:XF 3 "=2"))]
13956 "TARGET_USE_FANCY_MATH_387
13957 && flag_unsafe_math_optimizations"
13959 [(set_attr "type" "fpspc")
13960 (set_attr "mode" "XF")])
13962 (define_insn "fyl2x_extend<mode>xf3_i387"
13963 [(set (match_operand:XF 0 "register_operand" "=f")
13964 (unspec:XF [(float_extend:XF
13965 (match_operand:MODEF 1 "register_operand" "0"))
13966 (match_operand:XF 2 "register_operand" "u")]
13968 (clobber (match_scratch:XF 3 "=2"))]
13969 "TARGET_USE_FANCY_MATH_387
13970 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13971 || TARGET_MIX_SSE_I387)
13972 && flag_unsafe_math_optimizations"
13974 [(set_attr "type" "fpspc")
13975 (set_attr "mode" "XF")])
13977 (define_expand "logxf2"
13978 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13979 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13980 (match_dup 2)] UNSPEC_FYL2X))
13981 (clobber (match_scratch:XF 3 ""))])]
13982 "TARGET_USE_FANCY_MATH_387
13983 && flag_unsafe_math_optimizations"
13985 operands[2] = gen_reg_rtx (XFmode);
13986 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13989 (define_expand "log<mode>2"
13990 [(use (match_operand:MODEF 0 "register_operand" ""))
13991 (use (match_operand:MODEF 1 "register_operand" ""))]
13992 "TARGET_USE_FANCY_MATH_387
13993 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13994 || TARGET_MIX_SSE_I387)
13995 && flag_unsafe_math_optimizations"
13997 rtx op0 = gen_reg_rtx (XFmode);
13999 rtx op2 = gen_reg_rtx (XFmode);
14000 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14002 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14003 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14007 (define_expand "log10xf2"
14008 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14009 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14010 (match_dup 2)] UNSPEC_FYL2X))
14011 (clobber (match_scratch:XF 3 ""))])]
14012 "TARGET_USE_FANCY_MATH_387
14013 && flag_unsafe_math_optimizations"
14015 operands[2] = gen_reg_rtx (XFmode);
14016 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14019 (define_expand "log10<mode>2"
14020 [(use (match_operand:MODEF 0 "register_operand" ""))
14021 (use (match_operand:MODEF 1 "register_operand" ""))]
14022 "TARGET_USE_FANCY_MATH_387
14023 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14024 || TARGET_MIX_SSE_I387)
14025 && flag_unsafe_math_optimizations"
14027 rtx op0 = gen_reg_rtx (XFmode);
14029 rtx op2 = gen_reg_rtx (XFmode);
14030 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14032 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14033 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14037 (define_expand "log2xf2"
14038 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14039 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14040 (match_dup 2)] UNSPEC_FYL2X))
14041 (clobber (match_scratch:XF 3 ""))])]
14042 "TARGET_USE_FANCY_MATH_387
14043 && flag_unsafe_math_optimizations"
14045 operands[2] = gen_reg_rtx (XFmode);
14046 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14049 (define_expand "log2<mode>2"
14050 [(use (match_operand:MODEF 0 "register_operand" ""))
14051 (use (match_operand:MODEF 1 "register_operand" ""))]
14052 "TARGET_USE_FANCY_MATH_387
14053 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14054 || TARGET_MIX_SSE_I387)
14055 && flag_unsafe_math_optimizations"
14057 rtx op0 = gen_reg_rtx (XFmode);
14059 rtx op2 = gen_reg_rtx (XFmode);
14060 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14062 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14063 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14067 (define_insn "fyl2xp1xf3_i387"
14068 [(set (match_operand:XF 0 "register_operand" "=f")
14069 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14070 (match_operand:XF 2 "register_operand" "u")]
14072 (clobber (match_scratch:XF 3 "=2"))]
14073 "TARGET_USE_FANCY_MATH_387
14074 && flag_unsafe_math_optimizations"
14076 [(set_attr "type" "fpspc")
14077 (set_attr "mode" "XF")])
14079 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14080 [(set (match_operand:XF 0 "register_operand" "=f")
14081 (unspec:XF [(float_extend:XF
14082 (match_operand:MODEF 1 "register_operand" "0"))
14083 (match_operand:XF 2 "register_operand" "u")]
14085 (clobber (match_scratch:XF 3 "=2"))]
14086 "TARGET_USE_FANCY_MATH_387
14087 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14088 || TARGET_MIX_SSE_I387)
14089 && flag_unsafe_math_optimizations"
14091 [(set_attr "type" "fpspc")
14092 (set_attr "mode" "XF")])
14094 (define_expand "log1pxf2"
14095 [(use (match_operand:XF 0 "register_operand" ""))
14096 (use (match_operand:XF 1 "register_operand" ""))]
14097 "TARGET_USE_FANCY_MATH_387
14098 && flag_unsafe_math_optimizations"
14100 if (optimize_insn_for_size_p ())
14103 ix86_emit_i387_log1p (operands[0], operands[1]);
14107 (define_expand "log1p<mode>2"
14108 [(use (match_operand:MODEF 0 "register_operand" ""))
14109 (use (match_operand:MODEF 1 "register_operand" ""))]
14110 "TARGET_USE_FANCY_MATH_387
14111 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14112 || TARGET_MIX_SSE_I387)
14113 && flag_unsafe_math_optimizations"
14117 if (optimize_insn_for_size_p ())
14120 op0 = gen_reg_rtx (XFmode);
14122 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14124 ix86_emit_i387_log1p (op0, operands[1]);
14125 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14129 (define_insn "fxtractxf3_i387"
14130 [(set (match_operand:XF 0 "register_operand" "=f")
14131 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14132 UNSPEC_XTRACT_FRACT))
14133 (set (match_operand:XF 1 "register_operand" "=u")
14134 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14135 "TARGET_USE_FANCY_MATH_387
14136 && flag_unsafe_math_optimizations"
14138 [(set_attr "type" "fpspc")
14139 (set_attr "mode" "XF")])
14141 (define_insn "fxtract_extend<mode>xf3_i387"
14142 [(set (match_operand:XF 0 "register_operand" "=f")
14143 (unspec:XF [(float_extend:XF
14144 (match_operand:MODEF 2 "register_operand" "0"))]
14145 UNSPEC_XTRACT_FRACT))
14146 (set (match_operand:XF 1 "register_operand" "=u")
14147 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14148 "TARGET_USE_FANCY_MATH_387
14149 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14150 || TARGET_MIX_SSE_I387)
14151 && flag_unsafe_math_optimizations"
14153 [(set_attr "type" "fpspc")
14154 (set_attr "mode" "XF")])
14156 (define_expand "logbxf2"
14157 [(parallel [(set (match_dup 2)
14158 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14159 UNSPEC_XTRACT_FRACT))
14160 (set (match_operand:XF 0 "register_operand" "")
14161 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14162 "TARGET_USE_FANCY_MATH_387
14163 && flag_unsafe_math_optimizations"
14164 "operands[2] = gen_reg_rtx (XFmode);")
14166 (define_expand "logb<mode>2"
14167 [(use (match_operand:MODEF 0 "register_operand" ""))
14168 (use (match_operand:MODEF 1 "register_operand" ""))]
14169 "TARGET_USE_FANCY_MATH_387
14170 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14171 || TARGET_MIX_SSE_I387)
14172 && flag_unsafe_math_optimizations"
14174 rtx op0 = gen_reg_rtx (XFmode);
14175 rtx op1 = gen_reg_rtx (XFmode);
14177 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14178 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14182 (define_expand "ilogbxf2"
14183 [(use (match_operand:SI 0 "register_operand" ""))
14184 (use (match_operand:XF 1 "register_operand" ""))]
14185 "TARGET_USE_FANCY_MATH_387
14186 && flag_unsafe_math_optimizations"
14190 if (optimize_insn_for_size_p ())
14193 op0 = gen_reg_rtx (XFmode);
14194 op1 = gen_reg_rtx (XFmode);
14196 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14197 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14201 (define_expand "ilogb<mode>2"
14202 [(use (match_operand:SI 0 "register_operand" ""))
14203 (use (match_operand:MODEF 1 "register_operand" ""))]
14204 "TARGET_USE_FANCY_MATH_387
14205 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14206 || TARGET_MIX_SSE_I387)
14207 && flag_unsafe_math_optimizations"
14211 if (optimize_insn_for_size_p ())
14214 op0 = gen_reg_rtx (XFmode);
14215 op1 = gen_reg_rtx (XFmode);
14217 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14218 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14222 (define_insn "*f2xm1xf2_i387"
14223 [(set (match_operand:XF 0 "register_operand" "=f")
14224 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14226 "TARGET_USE_FANCY_MATH_387
14227 && flag_unsafe_math_optimizations"
14229 [(set_attr "type" "fpspc")
14230 (set_attr "mode" "XF")])
14232 (define_insn "*fscalexf4_i387"
14233 [(set (match_operand:XF 0 "register_operand" "=f")
14234 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14235 (match_operand:XF 3 "register_operand" "1")]
14236 UNSPEC_FSCALE_FRACT))
14237 (set (match_operand:XF 1 "register_operand" "=u")
14238 (unspec:XF [(match_dup 2) (match_dup 3)]
14239 UNSPEC_FSCALE_EXP))]
14240 "TARGET_USE_FANCY_MATH_387
14241 && flag_unsafe_math_optimizations"
14243 [(set_attr "type" "fpspc")
14244 (set_attr "mode" "XF")])
14246 (define_expand "expNcorexf3"
14247 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14248 (match_operand:XF 2 "register_operand" "")))
14249 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14250 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14251 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14252 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14253 (parallel [(set (match_operand:XF 0 "register_operand" "")
14254 (unspec:XF [(match_dup 8) (match_dup 4)]
14255 UNSPEC_FSCALE_FRACT))
14257 (unspec:XF [(match_dup 8) (match_dup 4)]
14258 UNSPEC_FSCALE_EXP))])]
14259 "TARGET_USE_FANCY_MATH_387
14260 && flag_unsafe_math_optimizations"
14264 if (optimize_insn_for_size_p ())
14267 for (i = 3; i < 10; i++)
14268 operands[i] = gen_reg_rtx (XFmode);
14270 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14273 (define_expand "expxf2"
14274 [(use (match_operand:XF 0 "register_operand" ""))
14275 (use (match_operand:XF 1 "register_operand" ""))]
14276 "TARGET_USE_FANCY_MATH_387
14277 && flag_unsafe_math_optimizations"
14281 if (optimize_insn_for_size_p ())
14284 op2 = gen_reg_rtx (XFmode);
14285 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14287 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14291 (define_expand "exp<mode>2"
14292 [(use (match_operand:MODEF 0 "register_operand" ""))
14293 (use (match_operand:MODEF 1 "general_operand" ""))]
14294 "TARGET_USE_FANCY_MATH_387
14295 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14296 || TARGET_MIX_SSE_I387)
14297 && flag_unsafe_math_optimizations"
14301 if (optimize_insn_for_size_p ())
14304 op0 = gen_reg_rtx (XFmode);
14305 op1 = gen_reg_rtx (XFmode);
14307 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14308 emit_insn (gen_expxf2 (op0, op1));
14309 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14313 (define_expand "exp10xf2"
14314 [(use (match_operand:XF 0 "register_operand" ""))
14315 (use (match_operand:XF 1 "register_operand" ""))]
14316 "TARGET_USE_FANCY_MATH_387
14317 && flag_unsafe_math_optimizations"
14321 if (optimize_insn_for_size_p ())
14324 op2 = gen_reg_rtx (XFmode);
14325 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14327 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14331 (define_expand "exp10<mode>2"
14332 [(use (match_operand:MODEF 0 "register_operand" ""))
14333 (use (match_operand:MODEF 1 "general_operand" ""))]
14334 "TARGET_USE_FANCY_MATH_387
14335 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14336 || TARGET_MIX_SSE_I387)
14337 && flag_unsafe_math_optimizations"
14341 if (optimize_insn_for_size_p ())
14344 op0 = gen_reg_rtx (XFmode);
14345 op1 = gen_reg_rtx (XFmode);
14347 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14348 emit_insn (gen_exp10xf2 (op0, op1));
14349 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14353 (define_expand "exp2xf2"
14354 [(use (match_operand:XF 0 "register_operand" ""))
14355 (use (match_operand:XF 1 "register_operand" ""))]
14356 "TARGET_USE_FANCY_MATH_387
14357 && flag_unsafe_math_optimizations"
14361 if (optimize_insn_for_size_p ())
14364 op2 = gen_reg_rtx (XFmode);
14365 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14367 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14371 (define_expand "exp2<mode>2"
14372 [(use (match_operand:MODEF 0 "register_operand" ""))
14373 (use (match_operand:MODEF 1 "general_operand" ""))]
14374 "TARGET_USE_FANCY_MATH_387
14375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14376 || TARGET_MIX_SSE_I387)
14377 && flag_unsafe_math_optimizations"
14381 if (optimize_insn_for_size_p ())
14384 op0 = gen_reg_rtx (XFmode);
14385 op1 = gen_reg_rtx (XFmode);
14387 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14388 emit_insn (gen_exp2xf2 (op0, op1));
14389 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14393 (define_expand "expm1xf2"
14394 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14396 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14397 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14398 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14399 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14400 (parallel [(set (match_dup 7)
14401 (unspec:XF [(match_dup 6) (match_dup 4)]
14402 UNSPEC_FSCALE_FRACT))
14404 (unspec:XF [(match_dup 6) (match_dup 4)]
14405 UNSPEC_FSCALE_EXP))])
14406 (parallel [(set (match_dup 10)
14407 (unspec:XF [(match_dup 9) (match_dup 8)]
14408 UNSPEC_FSCALE_FRACT))
14409 (set (match_dup 11)
14410 (unspec:XF [(match_dup 9) (match_dup 8)]
14411 UNSPEC_FSCALE_EXP))])
14412 (set (match_dup 12) (minus:XF (match_dup 10)
14413 (float_extend:XF (match_dup 13))))
14414 (set (match_operand:XF 0 "register_operand" "")
14415 (plus:XF (match_dup 12) (match_dup 7)))]
14416 "TARGET_USE_FANCY_MATH_387
14417 && flag_unsafe_math_optimizations"
14421 if (optimize_insn_for_size_p ())
14424 for (i = 2; i < 13; i++)
14425 operands[i] = gen_reg_rtx (XFmode);
14428 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14430 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14433 (define_expand "expm1<mode>2"
14434 [(use (match_operand:MODEF 0 "register_operand" ""))
14435 (use (match_operand:MODEF 1 "general_operand" ""))]
14436 "TARGET_USE_FANCY_MATH_387
14437 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14438 || TARGET_MIX_SSE_I387)
14439 && flag_unsafe_math_optimizations"
14443 if (optimize_insn_for_size_p ())
14446 op0 = gen_reg_rtx (XFmode);
14447 op1 = gen_reg_rtx (XFmode);
14449 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14450 emit_insn (gen_expm1xf2 (op0, op1));
14451 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14455 (define_expand "ldexpxf3"
14456 [(set (match_dup 3)
14457 (float:XF (match_operand:SI 2 "register_operand" "")))
14458 (parallel [(set (match_operand:XF 0 " register_operand" "")
14459 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14461 UNSPEC_FSCALE_FRACT))
14463 (unspec:XF [(match_dup 1) (match_dup 3)]
14464 UNSPEC_FSCALE_EXP))])]
14465 "TARGET_USE_FANCY_MATH_387
14466 && flag_unsafe_math_optimizations"
14468 if (optimize_insn_for_size_p ())
14471 operands[3] = gen_reg_rtx (XFmode);
14472 operands[4] = gen_reg_rtx (XFmode);
14475 (define_expand "ldexp<mode>3"
14476 [(use (match_operand:MODEF 0 "register_operand" ""))
14477 (use (match_operand:MODEF 1 "general_operand" ""))
14478 (use (match_operand:SI 2 "register_operand" ""))]
14479 "TARGET_USE_FANCY_MATH_387
14480 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14481 || TARGET_MIX_SSE_I387)
14482 && flag_unsafe_math_optimizations"
14486 if (optimize_insn_for_size_p ())
14489 op0 = gen_reg_rtx (XFmode);
14490 op1 = gen_reg_rtx (XFmode);
14492 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14493 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14494 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14498 (define_expand "scalbxf3"
14499 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14500 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14501 (match_operand:XF 2 "register_operand" "")]
14502 UNSPEC_FSCALE_FRACT))
14504 (unspec:XF [(match_dup 1) (match_dup 2)]
14505 UNSPEC_FSCALE_EXP))])]
14506 "TARGET_USE_FANCY_MATH_387
14507 && flag_unsafe_math_optimizations"
14509 if (optimize_insn_for_size_p ())
14512 operands[3] = gen_reg_rtx (XFmode);
14515 (define_expand "scalb<mode>3"
14516 [(use (match_operand:MODEF 0 "register_operand" ""))
14517 (use (match_operand:MODEF 1 "general_operand" ""))
14518 (use (match_operand:MODEF 2 "general_operand" ""))]
14519 "TARGET_USE_FANCY_MATH_387
14520 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14521 || TARGET_MIX_SSE_I387)
14522 && flag_unsafe_math_optimizations"
14526 if (optimize_insn_for_size_p ())
14529 op0 = gen_reg_rtx (XFmode);
14530 op1 = gen_reg_rtx (XFmode);
14531 op2 = gen_reg_rtx (XFmode);
14533 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14534 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14535 emit_insn (gen_scalbxf3 (op0, op1, op2));
14536 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14540 (define_expand "significandxf2"
14541 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14542 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14543 UNSPEC_XTRACT_FRACT))
14545 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14546 "TARGET_USE_FANCY_MATH_387
14547 && flag_unsafe_math_optimizations"
14548 "operands[2] = gen_reg_rtx (XFmode);")
14550 (define_expand "significand<mode>2"
14551 [(use (match_operand:MODEF 0 "register_operand" ""))
14552 (use (match_operand:MODEF 1 "register_operand" ""))]
14553 "TARGET_USE_FANCY_MATH_387
14554 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14555 || TARGET_MIX_SSE_I387)
14556 && flag_unsafe_math_optimizations"
14558 rtx op0 = gen_reg_rtx (XFmode);
14559 rtx op1 = gen_reg_rtx (XFmode);
14561 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14562 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14567 (define_insn "sse4_1_round<mode>2"
14568 [(set (match_operand:MODEF 0 "register_operand" "=x")
14569 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14570 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14573 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14574 [(set_attr "type" "ssecvt")
14575 (set_attr "prefix_extra" "1")
14576 (set_attr "prefix" "maybe_vex")
14577 (set_attr "mode" "<MODE>")])
14579 (define_insn "rintxf2"
14580 [(set (match_operand:XF 0 "register_operand" "=f")
14581 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14583 "TARGET_USE_FANCY_MATH_387
14584 && flag_unsafe_math_optimizations"
14586 [(set_attr "type" "fpspc")
14587 (set_attr "mode" "XF")])
14589 (define_expand "rint<mode>2"
14590 [(use (match_operand:MODEF 0 "register_operand" ""))
14591 (use (match_operand:MODEF 1 "register_operand" ""))]
14592 "(TARGET_USE_FANCY_MATH_387
14593 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14594 || TARGET_MIX_SSE_I387)
14595 && flag_unsafe_math_optimizations)
14596 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14597 && !flag_trapping_math)"
14599 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14600 && !flag_trapping_math)
14603 emit_insn (gen_sse4_1_round<mode>2
14604 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14605 else if (optimize_insn_for_size_p ())
14608 ix86_expand_rint (operands[0], operands[1]);
14612 rtx op0 = gen_reg_rtx (XFmode);
14613 rtx op1 = gen_reg_rtx (XFmode);
14615 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14616 emit_insn (gen_rintxf2 (op0, op1));
14618 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14623 (define_expand "round<mode>2"
14624 [(match_operand:X87MODEF 0 "register_operand" "")
14625 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14626 "(TARGET_USE_FANCY_MATH_387
14627 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14628 || TARGET_MIX_SSE_I387)
14629 && flag_unsafe_math_optimizations)
14630 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14631 && !flag_trapping_math && !flag_rounding_math)"
14633 if (optimize_insn_for_size_p ())
14636 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14637 && !flag_trapping_math && !flag_rounding_math)
14641 operands[1] = force_reg (<MODE>mode, operands[1]);
14642 ix86_expand_round_sse4 (operands[0], operands[1]);
14644 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14645 ix86_expand_round (operands[0], operands[1]);
14647 ix86_expand_rounddf_32 (operands[0], operands[1]);
14651 operands[1] = force_reg (<MODE>mode, operands[1]);
14652 ix86_emit_i387_round (operands[0], operands[1]);
14657 (define_insn_and_split "*fistdi2_1"
14658 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14659 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14661 "TARGET_USE_FANCY_MATH_387
14662 && can_create_pseudo_p ()"
14667 if (memory_operand (operands[0], VOIDmode))
14668 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14671 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14672 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14677 [(set_attr "type" "fpspc")
14678 (set_attr "mode" "DI")])
14680 (define_insn "fistdi2"
14681 [(set (match_operand:DI 0 "memory_operand" "=m")
14682 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14684 (clobber (match_scratch:XF 2 "=&1f"))]
14685 "TARGET_USE_FANCY_MATH_387"
14686 "* return output_fix_trunc (insn, operands, false);"
14687 [(set_attr "type" "fpspc")
14688 (set_attr "mode" "DI")])
14690 (define_insn "fistdi2_with_temp"
14691 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14692 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14694 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14695 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14696 "TARGET_USE_FANCY_MATH_387"
14698 [(set_attr "type" "fpspc")
14699 (set_attr "mode" "DI")])
14702 [(set (match_operand:DI 0 "register_operand" "")
14703 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14705 (clobber (match_operand:DI 2 "memory_operand" ""))
14706 (clobber (match_scratch 3 ""))]
14708 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14709 (clobber (match_dup 3))])
14710 (set (match_dup 0) (match_dup 2))])
14713 [(set (match_operand:DI 0 "memory_operand" "")
14714 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14716 (clobber (match_operand:DI 2 "memory_operand" ""))
14717 (clobber (match_scratch 3 ""))]
14719 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14720 (clobber (match_dup 3))])])
14722 (define_insn_and_split "*fist<mode>2_1"
14723 [(set (match_operand:SWI24 0 "register_operand" "")
14724 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14726 "TARGET_USE_FANCY_MATH_387
14727 && can_create_pseudo_p ()"
14732 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14733 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14737 [(set_attr "type" "fpspc")
14738 (set_attr "mode" "<MODE>")])
14740 (define_insn "fist<mode>2"
14741 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14742 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14744 "TARGET_USE_FANCY_MATH_387"
14745 "* return output_fix_trunc (insn, operands, false);"
14746 [(set_attr "type" "fpspc")
14747 (set_attr "mode" "<MODE>")])
14749 (define_insn "fist<mode>2_with_temp"
14750 [(set (match_operand:SWI24 0 "register_operand" "=r")
14751 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14753 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14754 "TARGET_USE_FANCY_MATH_387"
14756 [(set_attr "type" "fpspc")
14757 (set_attr "mode" "<MODE>")])
14760 [(set (match_operand:SWI24 0 "register_operand" "")
14761 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14763 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14765 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14766 (set (match_dup 0) (match_dup 2))])
14769 [(set (match_operand:SWI24 0 "memory_operand" "")
14770 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14772 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14774 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14776 (define_expand "lrintxf<mode>2"
14777 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14778 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14780 "TARGET_USE_FANCY_MATH_387")
14782 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14783 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14784 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14785 UNSPEC_FIX_NOTRUNC))]
14786 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14787 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14789 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14790 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14791 (match_operand:X87MODEF 1 "register_operand" "")]
14792 "(TARGET_USE_FANCY_MATH_387
14793 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14794 || TARGET_MIX_SSE_I387)
14795 && flag_unsafe_math_optimizations)
14796 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14797 && <SWI248x:MODE>mode != HImode
14798 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14799 && !flag_trapping_math && !flag_rounding_math)"
14801 if (optimize_insn_for_size_p ())
14804 if (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)
14808 ix86_expand_lround (operands[0], operands[1]);
14810 ix86_emit_i387_round (operands[0], operands[1]);
14814 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14815 (define_insn_and_split "frndintxf2_floor"
14816 [(set (match_operand:XF 0 "register_operand" "")
14817 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14818 UNSPEC_FRNDINT_FLOOR))
14819 (clobber (reg:CC FLAGS_REG))]
14820 "TARGET_USE_FANCY_MATH_387
14821 && flag_unsafe_math_optimizations
14822 && can_create_pseudo_p ()"
14827 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14829 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14830 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14832 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14833 operands[2], operands[3]));
14836 [(set_attr "type" "frndint")
14837 (set_attr "i387_cw" "floor")
14838 (set_attr "mode" "XF")])
14840 (define_insn "frndintxf2_floor_i387"
14841 [(set (match_operand:XF 0 "register_operand" "=f")
14842 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14843 UNSPEC_FRNDINT_FLOOR))
14844 (use (match_operand:HI 2 "memory_operand" "m"))
14845 (use (match_operand:HI 3 "memory_operand" "m"))]
14846 "TARGET_USE_FANCY_MATH_387
14847 && flag_unsafe_math_optimizations"
14848 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14849 [(set_attr "type" "frndint")
14850 (set_attr "i387_cw" "floor")
14851 (set_attr "mode" "XF")])
14853 (define_expand "floorxf2"
14854 [(use (match_operand:XF 0 "register_operand" ""))
14855 (use (match_operand:XF 1 "register_operand" ""))]
14856 "TARGET_USE_FANCY_MATH_387
14857 && flag_unsafe_math_optimizations"
14859 if (optimize_insn_for_size_p ())
14861 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14865 (define_expand "floor<mode>2"
14866 [(use (match_operand:MODEF 0 "register_operand" ""))
14867 (use (match_operand:MODEF 1 "register_operand" ""))]
14868 "(TARGET_USE_FANCY_MATH_387
14869 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14870 || TARGET_MIX_SSE_I387)
14871 && flag_unsafe_math_optimizations)
14872 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14873 && !flag_trapping_math)"
14875 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14876 && !flag_trapping_math)
14879 emit_insn (gen_sse4_1_round<mode>2
14880 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14881 else if (optimize_insn_for_size_p ())
14883 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14884 ix86_expand_floorceil (operands[0], operands[1], true);
14886 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14892 if (optimize_insn_for_size_p ())
14895 op0 = gen_reg_rtx (XFmode);
14896 op1 = gen_reg_rtx (XFmode);
14897 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14898 emit_insn (gen_frndintxf2_floor (op0, op1));
14900 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14905 (define_insn_and_split "*fist<mode>2_floor_1"
14906 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14907 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14908 UNSPEC_FIST_FLOOR))
14909 (clobber (reg:CC FLAGS_REG))]
14910 "TARGET_USE_FANCY_MATH_387
14911 && flag_unsafe_math_optimizations
14912 && can_create_pseudo_p ()"
14917 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14919 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14920 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14921 if (memory_operand (operands[0], VOIDmode))
14922 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14923 operands[2], operands[3]));
14926 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14927 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14928 operands[2], operands[3],
14933 [(set_attr "type" "fistp")
14934 (set_attr "i387_cw" "floor")
14935 (set_attr "mode" "<MODE>")])
14937 (define_insn "fistdi2_floor"
14938 [(set (match_operand:DI 0 "memory_operand" "=m")
14939 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14940 UNSPEC_FIST_FLOOR))
14941 (use (match_operand:HI 2 "memory_operand" "m"))
14942 (use (match_operand:HI 3 "memory_operand" "m"))
14943 (clobber (match_scratch:XF 4 "=&1f"))]
14944 "TARGET_USE_FANCY_MATH_387
14945 && flag_unsafe_math_optimizations"
14946 "* return output_fix_trunc (insn, operands, false);"
14947 [(set_attr "type" "fistp")
14948 (set_attr "i387_cw" "floor")
14949 (set_attr "mode" "DI")])
14951 (define_insn "fistdi2_floor_with_temp"
14952 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14953 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14954 UNSPEC_FIST_FLOOR))
14955 (use (match_operand:HI 2 "memory_operand" "m,m"))
14956 (use (match_operand:HI 3 "memory_operand" "m,m"))
14957 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14958 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14959 "TARGET_USE_FANCY_MATH_387
14960 && flag_unsafe_math_optimizations"
14962 [(set_attr "type" "fistp")
14963 (set_attr "i387_cw" "floor")
14964 (set_attr "mode" "DI")])
14967 [(set (match_operand:DI 0 "register_operand" "")
14968 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14969 UNSPEC_FIST_FLOOR))
14970 (use (match_operand:HI 2 "memory_operand" ""))
14971 (use (match_operand:HI 3 "memory_operand" ""))
14972 (clobber (match_operand:DI 4 "memory_operand" ""))
14973 (clobber (match_scratch 5 ""))]
14975 [(parallel [(set (match_dup 4)
14976 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14977 (use (match_dup 2))
14978 (use (match_dup 3))
14979 (clobber (match_dup 5))])
14980 (set (match_dup 0) (match_dup 4))])
14983 [(set (match_operand:DI 0 "memory_operand" "")
14984 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14985 UNSPEC_FIST_FLOOR))
14986 (use (match_operand:HI 2 "memory_operand" ""))
14987 (use (match_operand:HI 3 "memory_operand" ""))
14988 (clobber (match_operand:DI 4 "memory_operand" ""))
14989 (clobber (match_scratch 5 ""))]
14991 [(parallel [(set (match_dup 0)
14992 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14993 (use (match_dup 2))
14994 (use (match_dup 3))
14995 (clobber (match_dup 5))])])
14997 (define_insn "fist<mode>2_floor"
14998 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14999 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15000 UNSPEC_FIST_FLOOR))
15001 (use (match_operand:HI 2 "memory_operand" "m"))
15002 (use (match_operand:HI 3 "memory_operand" "m"))]
15003 "TARGET_USE_FANCY_MATH_387
15004 && flag_unsafe_math_optimizations"
15005 "* return output_fix_trunc (insn, operands, false);"
15006 [(set_attr "type" "fistp")
15007 (set_attr "i387_cw" "floor")
15008 (set_attr "mode" "<MODE>")])
15010 (define_insn "fist<mode>2_floor_with_temp"
15011 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15012 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15013 UNSPEC_FIST_FLOOR))
15014 (use (match_operand:HI 2 "memory_operand" "m,m"))
15015 (use (match_operand:HI 3 "memory_operand" "m,m"))
15016 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15017 "TARGET_USE_FANCY_MATH_387
15018 && flag_unsafe_math_optimizations"
15020 [(set_attr "type" "fistp")
15021 (set_attr "i387_cw" "floor")
15022 (set_attr "mode" "<MODE>")])
15025 [(set (match_operand:SWI24 0 "register_operand" "")
15026 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15027 UNSPEC_FIST_FLOOR))
15028 (use (match_operand:HI 2 "memory_operand" ""))
15029 (use (match_operand:HI 3 "memory_operand" ""))
15030 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15032 [(parallel [(set (match_dup 4)
15033 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15034 (use (match_dup 2))
15035 (use (match_dup 3))])
15036 (set (match_dup 0) (match_dup 4))])
15039 [(set (match_operand:SWI24 0 "memory_operand" "")
15040 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15041 UNSPEC_FIST_FLOOR))
15042 (use (match_operand:HI 2 "memory_operand" ""))
15043 (use (match_operand:HI 3 "memory_operand" ""))
15044 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15046 [(parallel [(set (match_dup 0)
15047 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15048 (use (match_dup 2))
15049 (use (match_dup 3))])])
15051 (define_expand "lfloorxf<mode>2"
15052 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15053 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15054 UNSPEC_FIST_FLOOR))
15055 (clobber (reg:CC FLAGS_REG))])]
15056 "TARGET_USE_FANCY_MATH_387
15057 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15058 && flag_unsafe_math_optimizations")
15060 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15061 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15062 (match_operand:MODEF 1 "register_operand" "")]
15063 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15064 && !flag_trapping_math"
15066 if (TARGET_64BIT && optimize_insn_for_size_p ())
15068 ix86_expand_lfloorceil (operands[0], operands[1], true);
15072 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15073 (define_insn_and_split "frndintxf2_ceil"
15074 [(set (match_operand:XF 0 "register_operand" "")
15075 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15076 UNSPEC_FRNDINT_CEIL))
15077 (clobber (reg:CC FLAGS_REG))]
15078 "TARGET_USE_FANCY_MATH_387
15079 && flag_unsafe_math_optimizations
15080 && can_create_pseudo_p ()"
15085 ix86_optimize_mode_switching[I387_CEIL] = 1;
15087 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15088 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15090 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15091 operands[2], operands[3]));
15094 [(set_attr "type" "frndint")
15095 (set_attr "i387_cw" "ceil")
15096 (set_attr "mode" "XF")])
15098 (define_insn "frndintxf2_ceil_i387"
15099 [(set (match_operand:XF 0 "register_operand" "=f")
15100 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15101 UNSPEC_FRNDINT_CEIL))
15102 (use (match_operand:HI 2 "memory_operand" "m"))
15103 (use (match_operand:HI 3 "memory_operand" "m"))]
15104 "TARGET_USE_FANCY_MATH_387
15105 && flag_unsafe_math_optimizations"
15106 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15107 [(set_attr "type" "frndint")
15108 (set_attr "i387_cw" "ceil")
15109 (set_attr "mode" "XF")])
15111 (define_expand "ceilxf2"
15112 [(use (match_operand:XF 0 "register_operand" ""))
15113 (use (match_operand:XF 1 "register_operand" ""))]
15114 "TARGET_USE_FANCY_MATH_387
15115 && flag_unsafe_math_optimizations"
15117 if (optimize_insn_for_size_p ())
15119 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15123 (define_expand "ceil<mode>2"
15124 [(use (match_operand:MODEF 0 "register_operand" ""))
15125 (use (match_operand:MODEF 1 "register_operand" ""))]
15126 "(TARGET_USE_FANCY_MATH_387
15127 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15128 || TARGET_MIX_SSE_I387)
15129 && flag_unsafe_math_optimizations)
15130 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15131 && !flag_trapping_math)"
15133 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15134 && !flag_trapping_math)
15137 emit_insn (gen_sse4_1_round<mode>2
15138 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15139 else if (optimize_insn_for_size_p ())
15141 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15142 ix86_expand_floorceil (operands[0], operands[1], false);
15144 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15150 if (optimize_insn_for_size_p ())
15153 op0 = gen_reg_rtx (XFmode);
15154 op1 = gen_reg_rtx (XFmode);
15155 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15156 emit_insn (gen_frndintxf2_ceil (op0, op1));
15158 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15163 (define_insn_and_split "*fist<mode>2_ceil_1"
15164 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15165 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15167 (clobber (reg:CC FLAGS_REG))]
15168 "TARGET_USE_FANCY_MATH_387
15169 && flag_unsafe_math_optimizations
15170 && can_create_pseudo_p ()"
15175 ix86_optimize_mode_switching[I387_CEIL] = 1;
15177 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15178 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15179 if (memory_operand (operands[0], VOIDmode))
15180 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15181 operands[2], operands[3]));
15184 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15185 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15186 operands[2], operands[3],
15191 [(set_attr "type" "fistp")
15192 (set_attr "i387_cw" "ceil")
15193 (set_attr "mode" "<MODE>")])
15195 (define_insn "fistdi2_ceil"
15196 [(set (match_operand:DI 0 "memory_operand" "=m")
15197 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15199 (use (match_operand:HI 2 "memory_operand" "m"))
15200 (use (match_operand:HI 3 "memory_operand" "m"))
15201 (clobber (match_scratch:XF 4 "=&1f"))]
15202 "TARGET_USE_FANCY_MATH_387
15203 && flag_unsafe_math_optimizations"
15204 "* return output_fix_trunc (insn, operands, false);"
15205 [(set_attr "type" "fistp")
15206 (set_attr "i387_cw" "ceil")
15207 (set_attr "mode" "DI")])
15209 (define_insn "fistdi2_ceil_with_temp"
15210 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15211 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15213 (use (match_operand:HI 2 "memory_operand" "m,m"))
15214 (use (match_operand:HI 3 "memory_operand" "m,m"))
15215 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15216 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15217 "TARGET_USE_FANCY_MATH_387
15218 && flag_unsafe_math_optimizations"
15220 [(set_attr "type" "fistp")
15221 (set_attr "i387_cw" "ceil")
15222 (set_attr "mode" "DI")])
15225 [(set (match_operand:DI 0 "register_operand" "")
15226 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15228 (use (match_operand:HI 2 "memory_operand" ""))
15229 (use (match_operand:HI 3 "memory_operand" ""))
15230 (clobber (match_operand:DI 4 "memory_operand" ""))
15231 (clobber (match_scratch 5 ""))]
15233 [(parallel [(set (match_dup 4)
15234 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15235 (use (match_dup 2))
15236 (use (match_dup 3))
15237 (clobber (match_dup 5))])
15238 (set (match_dup 0) (match_dup 4))])
15241 [(set (match_operand:DI 0 "memory_operand" "")
15242 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15244 (use (match_operand:HI 2 "memory_operand" ""))
15245 (use (match_operand:HI 3 "memory_operand" ""))
15246 (clobber (match_operand:DI 4 "memory_operand" ""))
15247 (clobber (match_scratch 5 ""))]
15249 [(parallel [(set (match_dup 0)
15250 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15251 (use (match_dup 2))
15252 (use (match_dup 3))
15253 (clobber (match_dup 5))])])
15255 (define_insn "fist<mode>2_ceil"
15256 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15257 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15259 (use (match_operand:HI 2 "memory_operand" "m"))
15260 (use (match_operand:HI 3 "memory_operand" "m"))]
15261 "TARGET_USE_FANCY_MATH_387
15262 && flag_unsafe_math_optimizations"
15263 "* return output_fix_trunc (insn, operands, false);"
15264 [(set_attr "type" "fistp")
15265 (set_attr "i387_cw" "ceil")
15266 (set_attr "mode" "<MODE>")])
15268 (define_insn "fist<mode>2_ceil_with_temp"
15269 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15270 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15272 (use (match_operand:HI 2 "memory_operand" "m,m"))
15273 (use (match_operand:HI 3 "memory_operand" "m,m"))
15274 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15275 "TARGET_USE_FANCY_MATH_387
15276 && flag_unsafe_math_optimizations"
15278 [(set_attr "type" "fistp")
15279 (set_attr "i387_cw" "ceil")
15280 (set_attr "mode" "<MODE>")])
15283 [(set (match_operand:SWI24 0 "register_operand" "")
15284 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15286 (use (match_operand:HI 2 "memory_operand" ""))
15287 (use (match_operand:HI 3 "memory_operand" ""))
15288 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15290 [(parallel [(set (match_dup 4)
15291 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15292 (use (match_dup 2))
15293 (use (match_dup 3))])
15294 (set (match_dup 0) (match_dup 4))])
15297 [(set (match_operand:SWI24 0 "memory_operand" "")
15298 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15300 (use (match_operand:HI 2 "memory_operand" ""))
15301 (use (match_operand:HI 3 "memory_operand" ""))
15302 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15304 [(parallel [(set (match_dup 0)
15305 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15306 (use (match_dup 2))
15307 (use (match_dup 3))])])
15309 (define_expand "lceilxf<mode>2"
15310 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15311 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15313 (clobber (reg:CC FLAGS_REG))])]
15314 "TARGET_USE_FANCY_MATH_387
15315 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15316 && flag_unsafe_math_optimizations")
15318 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15319 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15320 (match_operand:MODEF 1 "register_operand" "")]
15321 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15322 && !flag_trapping_math"
15324 ix86_expand_lfloorceil (operands[0], operands[1], false);
15328 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15329 (define_insn_and_split "frndintxf2_trunc"
15330 [(set (match_operand:XF 0 "register_operand" "")
15331 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15332 UNSPEC_FRNDINT_TRUNC))
15333 (clobber (reg:CC FLAGS_REG))]
15334 "TARGET_USE_FANCY_MATH_387
15335 && flag_unsafe_math_optimizations
15336 && can_create_pseudo_p ()"
15341 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15343 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15344 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15346 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15347 operands[2], operands[3]));
15350 [(set_attr "type" "frndint")
15351 (set_attr "i387_cw" "trunc")
15352 (set_attr "mode" "XF")])
15354 (define_insn "frndintxf2_trunc_i387"
15355 [(set (match_operand:XF 0 "register_operand" "=f")
15356 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15357 UNSPEC_FRNDINT_TRUNC))
15358 (use (match_operand:HI 2 "memory_operand" "m"))
15359 (use (match_operand:HI 3 "memory_operand" "m"))]
15360 "TARGET_USE_FANCY_MATH_387
15361 && flag_unsafe_math_optimizations"
15362 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15363 [(set_attr "type" "frndint")
15364 (set_attr "i387_cw" "trunc")
15365 (set_attr "mode" "XF")])
15367 (define_expand "btruncxf2"
15368 [(use (match_operand:XF 0 "register_operand" ""))
15369 (use (match_operand:XF 1 "register_operand" ""))]
15370 "TARGET_USE_FANCY_MATH_387
15371 && flag_unsafe_math_optimizations"
15373 if (optimize_insn_for_size_p ())
15375 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15379 (define_expand "btrunc<mode>2"
15380 [(use (match_operand:MODEF 0 "register_operand" ""))
15381 (use (match_operand:MODEF 1 "register_operand" ""))]
15382 "(TARGET_USE_FANCY_MATH_387
15383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15384 || TARGET_MIX_SSE_I387)
15385 && flag_unsafe_math_optimizations)
15386 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15387 && !flag_trapping_math)"
15389 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15390 && !flag_trapping_math)
15393 emit_insn (gen_sse4_1_round<mode>2
15394 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15395 else if (optimize_insn_for_size_p ())
15397 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15398 ix86_expand_trunc (operands[0], operands[1]);
15400 ix86_expand_truncdf_32 (operands[0], operands[1]);
15406 if (optimize_insn_for_size_p ())
15409 op0 = gen_reg_rtx (XFmode);
15410 op1 = gen_reg_rtx (XFmode);
15411 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15412 emit_insn (gen_frndintxf2_trunc (op0, op1));
15414 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15419 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15420 (define_insn_and_split "frndintxf2_mask_pm"
15421 [(set (match_operand:XF 0 "register_operand" "")
15422 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15423 UNSPEC_FRNDINT_MASK_PM))
15424 (clobber (reg:CC FLAGS_REG))]
15425 "TARGET_USE_FANCY_MATH_387
15426 && flag_unsafe_math_optimizations
15427 && can_create_pseudo_p ()"
15432 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15434 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15435 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15437 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15438 operands[2], operands[3]));
15441 [(set_attr "type" "frndint")
15442 (set_attr "i387_cw" "mask_pm")
15443 (set_attr "mode" "XF")])
15445 (define_insn "frndintxf2_mask_pm_i387"
15446 [(set (match_operand:XF 0 "register_operand" "=f")
15447 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15448 UNSPEC_FRNDINT_MASK_PM))
15449 (use (match_operand:HI 2 "memory_operand" "m"))
15450 (use (match_operand:HI 3 "memory_operand" "m"))]
15451 "TARGET_USE_FANCY_MATH_387
15452 && flag_unsafe_math_optimizations"
15453 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15454 [(set_attr "type" "frndint")
15455 (set_attr "i387_cw" "mask_pm")
15456 (set_attr "mode" "XF")])
15458 (define_expand "nearbyintxf2"
15459 [(use (match_operand:XF 0 "register_operand" ""))
15460 (use (match_operand:XF 1 "register_operand" ""))]
15461 "TARGET_USE_FANCY_MATH_387
15462 && flag_unsafe_math_optimizations"
15464 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15468 (define_expand "nearbyint<mode>2"
15469 [(use (match_operand:MODEF 0 "register_operand" ""))
15470 (use (match_operand:MODEF 1 "register_operand" ""))]
15471 "TARGET_USE_FANCY_MATH_387
15472 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15473 || TARGET_MIX_SSE_I387)
15474 && flag_unsafe_math_optimizations"
15476 rtx op0 = gen_reg_rtx (XFmode);
15477 rtx op1 = gen_reg_rtx (XFmode);
15479 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15480 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15482 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15486 (define_insn "fxam<mode>2_i387"
15487 [(set (match_operand:HI 0 "register_operand" "=a")
15489 [(match_operand:X87MODEF 1 "register_operand" "f")]
15491 "TARGET_USE_FANCY_MATH_387"
15492 "fxam\n\tfnstsw\t%0"
15493 [(set_attr "type" "multi")
15494 (set_attr "length" "4")
15495 (set_attr "unit" "i387")
15496 (set_attr "mode" "<MODE>")])
15498 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15499 [(set (match_operand:HI 0 "register_operand" "")
15501 [(match_operand:MODEF 1 "memory_operand" "")]
15503 "TARGET_USE_FANCY_MATH_387
15504 && can_create_pseudo_p ()"
15507 [(set (match_dup 2)(match_dup 1))
15509 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15511 operands[2] = gen_reg_rtx (<MODE>mode);
15513 MEM_VOLATILE_P (operands[1]) = 1;
15515 [(set_attr "type" "multi")
15516 (set_attr "unit" "i387")
15517 (set_attr "mode" "<MODE>")])
15519 (define_expand "isinfxf2"
15520 [(use (match_operand:SI 0 "register_operand" ""))
15521 (use (match_operand:XF 1 "register_operand" ""))]
15522 "TARGET_USE_FANCY_MATH_387
15523 && TARGET_C99_FUNCTIONS"
15525 rtx mask = GEN_INT (0x45);
15526 rtx val = GEN_INT (0x05);
15530 rtx scratch = gen_reg_rtx (HImode);
15531 rtx res = gen_reg_rtx (QImode);
15533 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15535 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15536 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15537 cond = gen_rtx_fmt_ee (EQ, QImode,
15538 gen_rtx_REG (CCmode, FLAGS_REG),
15540 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15541 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15545 (define_expand "isinf<mode>2"
15546 [(use (match_operand:SI 0 "register_operand" ""))
15547 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15548 "TARGET_USE_FANCY_MATH_387
15549 && TARGET_C99_FUNCTIONS
15550 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15552 rtx mask = GEN_INT (0x45);
15553 rtx val = GEN_INT (0x05);
15557 rtx scratch = gen_reg_rtx (HImode);
15558 rtx res = gen_reg_rtx (QImode);
15560 /* Remove excess precision by forcing value through memory. */
15561 if (memory_operand (operands[1], VOIDmode))
15562 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15565 enum ix86_stack_slot slot = (virtuals_instantiated
15568 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15570 emit_move_insn (temp, operands[1]);
15571 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15574 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15575 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15576 cond = gen_rtx_fmt_ee (EQ, QImode,
15577 gen_rtx_REG (CCmode, FLAGS_REG),
15579 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15580 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15584 (define_expand "signbitxf2"
15585 [(use (match_operand:SI 0 "register_operand" ""))
15586 (use (match_operand:XF 1 "register_operand" ""))]
15587 "TARGET_USE_FANCY_MATH_387"
15589 rtx scratch = gen_reg_rtx (HImode);
15591 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15592 emit_insn (gen_andsi3 (operands[0],
15593 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15597 (define_insn "movmsk_df"
15598 [(set (match_operand:SI 0 "register_operand" "=r")
15600 [(match_operand:DF 1 "register_operand" "x")]
15602 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15603 "%vmovmskpd\t{%1, %0|%0, %1}"
15604 [(set_attr "type" "ssemov")
15605 (set_attr "prefix" "maybe_vex")
15606 (set_attr "mode" "DF")])
15608 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15609 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15610 (define_expand "signbitdf2"
15611 [(use (match_operand:SI 0 "register_operand" ""))
15612 (use (match_operand:DF 1 "register_operand" ""))]
15613 "TARGET_USE_FANCY_MATH_387
15614 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15616 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15618 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15619 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15623 rtx scratch = gen_reg_rtx (HImode);
15625 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15626 emit_insn (gen_andsi3 (operands[0],
15627 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15632 (define_expand "signbitsf2"
15633 [(use (match_operand:SI 0 "register_operand" ""))
15634 (use (match_operand:SF 1 "register_operand" ""))]
15635 "TARGET_USE_FANCY_MATH_387
15636 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15638 rtx scratch = gen_reg_rtx (HImode);
15640 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15641 emit_insn (gen_andsi3 (operands[0],
15642 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15646 ;; Block operation instructions
15649 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15652 [(set_attr "length" "1")
15653 (set_attr "length_immediate" "0")
15654 (set_attr "modrm" "0")])
15656 (define_expand "movmem<mode>"
15657 [(use (match_operand:BLK 0 "memory_operand" ""))
15658 (use (match_operand:BLK 1 "memory_operand" ""))
15659 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15660 (use (match_operand:SWI48 3 "const_int_operand" ""))
15661 (use (match_operand:SI 4 "const_int_operand" ""))
15662 (use (match_operand:SI 5 "const_int_operand" ""))]
15665 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15666 operands[4], operands[5]))
15672 ;; Most CPUs don't like single string operations
15673 ;; Handle this case here to simplify previous expander.
15675 (define_expand "strmov"
15676 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15677 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15678 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15679 (clobber (reg:CC FLAGS_REG))])
15680 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15681 (clobber (reg:CC FLAGS_REG))])]
15684 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15686 /* If .md ever supports :P for Pmode, these can be directly
15687 in the pattern above. */
15688 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15689 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15691 /* Can't use this if the user has appropriated esi or edi. */
15692 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15693 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15695 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15696 operands[2], operands[3],
15697 operands[5], operands[6]));
15701 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15704 (define_expand "strmov_singleop"
15705 [(parallel [(set (match_operand 1 "memory_operand" "")
15706 (match_operand 3 "memory_operand" ""))
15707 (set (match_operand 0 "register_operand" "")
15708 (match_operand 4 "" ""))
15709 (set (match_operand 2 "register_operand" "")
15710 (match_operand 5 "" ""))])]
15712 "ix86_current_function_needs_cld = 1;")
15714 (define_insn "*strmovdi_rex_1"
15715 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15716 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15717 (set (match_operand:DI 0 "register_operand" "=D")
15718 (plus:DI (match_dup 2)
15720 (set (match_operand:DI 1 "register_operand" "=S")
15721 (plus:DI (match_dup 3)
15724 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15726 [(set_attr "type" "str")
15727 (set_attr "memory" "both")
15728 (set_attr "mode" "DI")])
15730 (define_insn "*strmovsi_1"
15731 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15732 (mem:SI (match_operand:P 3 "register_operand" "1")))
15733 (set (match_operand:P 0 "register_operand" "=D")
15734 (plus:P (match_dup 2)
15736 (set (match_operand:P 1 "register_operand" "=S")
15737 (plus:P (match_dup 3)
15739 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15741 [(set_attr "type" "str")
15742 (set_attr "memory" "both")
15743 (set_attr "mode" "SI")])
15745 (define_insn "*strmovhi_1"
15746 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15747 (mem:HI (match_operand:P 3 "register_operand" "1")))
15748 (set (match_operand:P 0 "register_operand" "=D")
15749 (plus:P (match_dup 2)
15751 (set (match_operand:P 1 "register_operand" "=S")
15752 (plus:P (match_dup 3)
15754 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15756 [(set_attr "type" "str")
15757 (set_attr "memory" "both")
15758 (set_attr "mode" "HI")])
15760 (define_insn "*strmovqi_1"
15761 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15762 (mem:QI (match_operand:P 3 "register_operand" "1")))
15763 (set (match_operand:P 0 "register_operand" "=D")
15764 (plus:P (match_dup 2)
15766 (set (match_operand:P 1 "register_operand" "=S")
15767 (plus:P (match_dup 3)
15769 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15771 [(set_attr "type" "str")
15772 (set_attr "memory" "both")
15773 (set (attr "prefix_rex")
15775 (match_test "<P:MODE>mode == DImode")
15777 (const_string "*")))
15778 (set_attr "mode" "QI")])
15780 (define_expand "rep_mov"
15781 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15782 (set (match_operand 0 "register_operand" "")
15783 (match_operand 5 "" ""))
15784 (set (match_operand 2 "register_operand" "")
15785 (match_operand 6 "" ""))
15786 (set (match_operand 1 "memory_operand" "")
15787 (match_operand 3 "memory_operand" ""))
15788 (use (match_dup 4))])]
15790 "ix86_current_function_needs_cld = 1;")
15792 (define_insn "*rep_movdi_rex64"
15793 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15794 (set (match_operand:DI 0 "register_operand" "=D")
15795 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15797 (match_operand:DI 3 "register_operand" "0")))
15798 (set (match_operand:DI 1 "register_operand" "=S")
15799 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15800 (match_operand:DI 4 "register_operand" "1")))
15801 (set (mem:BLK (match_dup 3))
15802 (mem:BLK (match_dup 4)))
15803 (use (match_dup 5))]
15805 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15807 [(set_attr "type" "str")
15808 (set_attr "prefix_rep" "1")
15809 (set_attr "memory" "both")
15810 (set_attr "mode" "DI")])
15812 (define_insn "*rep_movsi"
15813 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15814 (set (match_operand:P 0 "register_operand" "=D")
15815 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15817 (match_operand:P 3 "register_operand" "0")))
15818 (set (match_operand:P 1 "register_operand" "=S")
15819 (plus:P (ashift:P (match_dup 5) (const_int 2))
15820 (match_operand:P 4 "register_operand" "1")))
15821 (set (mem:BLK (match_dup 3))
15822 (mem:BLK (match_dup 4)))
15823 (use (match_dup 5))]
15824 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15825 "rep{%;} movs{l|d}"
15826 [(set_attr "type" "str")
15827 (set_attr "prefix_rep" "1")
15828 (set_attr "memory" "both")
15829 (set_attr "mode" "SI")])
15831 (define_insn "*rep_movqi"
15832 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15833 (set (match_operand:P 0 "register_operand" "=D")
15834 (plus:P (match_operand:P 3 "register_operand" "0")
15835 (match_operand:P 5 "register_operand" "2")))
15836 (set (match_operand:P 1 "register_operand" "=S")
15837 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15838 (set (mem:BLK (match_dup 3))
15839 (mem:BLK (match_dup 4)))
15840 (use (match_dup 5))]
15841 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15843 [(set_attr "type" "str")
15844 (set_attr "prefix_rep" "1")
15845 (set_attr "memory" "both")
15846 (set_attr "mode" "QI")])
15848 (define_expand "setmem<mode>"
15849 [(use (match_operand:BLK 0 "memory_operand" ""))
15850 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15851 (use (match_operand:QI 2 "nonmemory_operand" ""))
15852 (use (match_operand 3 "const_int_operand" ""))
15853 (use (match_operand:SI 4 "const_int_operand" ""))
15854 (use (match_operand:SI 5 "const_int_operand" ""))]
15857 if (ix86_expand_setmem (operands[0], operands[1],
15858 operands[2], operands[3],
15859 operands[4], operands[5]))
15865 ;; Most CPUs don't like single string operations
15866 ;; Handle this case here to simplify previous expander.
15868 (define_expand "strset"
15869 [(set (match_operand 1 "memory_operand" "")
15870 (match_operand 2 "register_operand" ""))
15871 (parallel [(set (match_operand 0 "register_operand" "")
15873 (clobber (reg:CC FLAGS_REG))])]
15876 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15877 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15879 /* If .md ever supports :P for Pmode, this can be directly
15880 in the pattern above. */
15881 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15882 GEN_INT (GET_MODE_SIZE (GET_MODE
15884 /* Can't use this if the user has appropriated eax or edi. */
15885 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15886 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15888 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15894 (define_expand "strset_singleop"
15895 [(parallel [(set (match_operand 1 "memory_operand" "")
15896 (match_operand 2 "register_operand" ""))
15897 (set (match_operand 0 "register_operand" "")
15898 (match_operand 3 "" ""))])]
15900 "ix86_current_function_needs_cld = 1;")
15902 (define_insn "*strsetdi_rex_1"
15903 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15904 (match_operand:DI 2 "register_operand" "a"))
15905 (set (match_operand:DI 0 "register_operand" "=D")
15906 (plus:DI (match_dup 1)
15909 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15911 [(set_attr "type" "str")
15912 (set_attr "memory" "store")
15913 (set_attr "mode" "DI")])
15915 (define_insn "*strsetsi_1"
15916 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15917 (match_operand:SI 2 "register_operand" "a"))
15918 (set (match_operand:P 0 "register_operand" "=D")
15919 (plus:P (match_dup 1)
15921 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15923 [(set_attr "type" "str")
15924 (set_attr "memory" "store")
15925 (set_attr "mode" "SI")])
15927 (define_insn "*strsethi_1"
15928 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15929 (match_operand:HI 2 "register_operand" "a"))
15930 (set (match_operand:P 0 "register_operand" "=D")
15931 (plus:P (match_dup 1)
15933 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15935 [(set_attr "type" "str")
15936 (set_attr "memory" "store")
15937 (set_attr "mode" "HI")])
15939 (define_insn "*strsetqi_1"
15940 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15941 (match_operand:QI 2 "register_operand" "a"))
15942 (set (match_operand:P 0 "register_operand" "=D")
15943 (plus:P (match_dup 1)
15945 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15947 [(set_attr "type" "str")
15948 (set_attr "memory" "store")
15949 (set (attr "prefix_rex")
15951 (match_test "<P:MODE>mode == DImode")
15953 (const_string "*")))
15954 (set_attr "mode" "QI")])
15956 (define_expand "rep_stos"
15957 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15958 (set (match_operand 0 "register_operand" "")
15959 (match_operand 4 "" ""))
15960 (set (match_operand 2 "memory_operand" "") (const_int 0))
15961 (use (match_operand 3 "register_operand" ""))
15962 (use (match_dup 1))])]
15964 "ix86_current_function_needs_cld = 1;")
15966 (define_insn "*rep_stosdi_rex64"
15967 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15968 (set (match_operand:DI 0 "register_operand" "=D")
15969 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15971 (match_operand:DI 3 "register_operand" "0")))
15972 (set (mem:BLK (match_dup 3))
15974 (use (match_operand:DI 2 "register_operand" "a"))
15975 (use (match_dup 4))]
15977 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15979 [(set_attr "type" "str")
15980 (set_attr "prefix_rep" "1")
15981 (set_attr "memory" "store")
15982 (set_attr "mode" "DI")])
15984 (define_insn "*rep_stossi"
15985 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15986 (set (match_operand:P 0 "register_operand" "=D")
15987 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15989 (match_operand:P 3 "register_operand" "0")))
15990 (set (mem:BLK (match_dup 3))
15992 (use (match_operand:SI 2 "register_operand" "a"))
15993 (use (match_dup 4))]
15994 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15995 "rep{%;} stos{l|d}"
15996 [(set_attr "type" "str")
15997 (set_attr "prefix_rep" "1")
15998 (set_attr "memory" "store")
15999 (set_attr "mode" "SI")])
16001 (define_insn "*rep_stosqi"
16002 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16003 (set (match_operand:P 0 "register_operand" "=D")
16004 (plus:P (match_operand:P 3 "register_operand" "0")
16005 (match_operand:P 4 "register_operand" "1")))
16006 (set (mem:BLK (match_dup 3))
16008 (use (match_operand:QI 2 "register_operand" "a"))
16009 (use (match_dup 4))]
16010 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16012 [(set_attr "type" "str")
16013 (set_attr "prefix_rep" "1")
16014 (set_attr "memory" "store")
16015 (set (attr "prefix_rex")
16017 (match_test "<P:MODE>mode == DImode")
16019 (const_string "*")))
16020 (set_attr "mode" "QI")])
16022 (define_expand "cmpstrnsi"
16023 [(set (match_operand:SI 0 "register_operand" "")
16024 (compare:SI (match_operand:BLK 1 "general_operand" "")
16025 (match_operand:BLK 2 "general_operand" "")))
16026 (use (match_operand 3 "general_operand" ""))
16027 (use (match_operand 4 "immediate_operand" ""))]
16030 rtx addr1, addr2, out, outlow, count, countreg, align;
16032 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16035 /* Can't use this if the user has appropriated ecx, esi or edi. */
16036 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16041 out = gen_reg_rtx (SImode);
16043 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16044 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16045 if (addr1 != XEXP (operands[1], 0))
16046 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16047 if (addr2 != XEXP (operands[2], 0))
16048 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16050 count = operands[3];
16051 countreg = ix86_zero_extend_to_Pmode (count);
16053 /* %%% Iff we are testing strict equality, we can use known alignment
16054 to good advantage. This may be possible with combine, particularly
16055 once cc0 is dead. */
16056 align = operands[4];
16058 if (CONST_INT_P (count))
16060 if (INTVAL (count) == 0)
16062 emit_move_insn (operands[0], const0_rtx);
16065 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16066 operands[1], operands[2]));
16070 rtx (*gen_cmp) (rtx, rtx);
16072 gen_cmp = (TARGET_64BIT
16073 ? gen_cmpdi_1 : gen_cmpsi_1);
16075 emit_insn (gen_cmp (countreg, countreg));
16076 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16077 operands[1], operands[2]));
16080 outlow = gen_lowpart (QImode, out);
16081 emit_insn (gen_cmpintqi (outlow));
16082 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16084 if (operands[0] != out)
16085 emit_move_insn (operands[0], out);
16090 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16092 (define_expand "cmpintqi"
16093 [(set (match_dup 1)
16094 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16096 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16097 (parallel [(set (match_operand:QI 0 "register_operand" "")
16098 (minus:QI (match_dup 1)
16100 (clobber (reg:CC FLAGS_REG))])]
16103 operands[1] = gen_reg_rtx (QImode);
16104 operands[2] = gen_reg_rtx (QImode);
16107 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16108 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16110 (define_expand "cmpstrnqi_nz_1"
16111 [(parallel [(set (reg:CC FLAGS_REG)
16112 (compare:CC (match_operand 4 "memory_operand" "")
16113 (match_operand 5 "memory_operand" "")))
16114 (use (match_operand 2 "register_operand" ""))
16115 (use (match_operand:SI 3 "immediate_operand" ""))
16116 (clobber (match_operand 0 "register_operand" ""))
16117 (clobber (match_operand 1 "register_operand" ""))
16118 (clobber (match_dup 2))])]
16120 "ix86_current_function_needs_cld = 1;")
16122 (define_insn "*cmpstrnqi_nz_1"
16123 [(set (reg:CC FLAGS_REG)
16124 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16125 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16126 (use (match_operand:P 6 "register_operand" "2"))
16127 (use (match_operand:SI 3 "immediate_operand" "i"))
16128 (clobber (match_operand:P 0 "register_operand" "=S"))
16129 (clobber (match_operand:P 1 "register_operand" "=D"))
16130 (clobber (match_operand:P 2 "register_operand" "=c"))]
16131 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16133 [(set_attr "type" "str")
16134 (set_attr "mode" "QI")
16135 (set (attr "prefix_rex")
16137 (match_test "<P:MODE>mode == DImode")
16139 (const_string "*")))
16140 (set_attr "prefix_rep" "1")])
16142 ;; The same, but the count is not known to not be zero.
16144 (define_expand "cmpstrnqi_1"
16145 [(parallel [(set (reg:CC FLAGS_REG)
16146 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16148 (compare:CC (match_operand 4 "memory_operand" "")
16149 (match_operand 5 "memory_operand" ""))
16151 (use (match_operand:SI 3 "immediate_operand" ""))
16152 (use (reg:CC FLAGS_REG))
16153 (clobber (match_operand 0 "register_operand" ""))
16154 (clobber (match_operand 1 "register_operand" ""))
16155 (clobber (match_dup 2))])]
16157 "ix86_current_function_needs_cld = 1;")
16159 (define_insn "*cmpstrnqi_1"
16160 [(set (reg:CC FLAGS_REG)
16161 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16163 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16164 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16166 (use (match_operand:SI 3 "immediate_operand" "i"))
16167 (use (reg:CC FLAGS_REG))
16168 (clobber (match_operand:P 0 "register_operand" "=S"))
16169 (clobber (match_operand:P 1 "register_operand" "=D"))
16170 (clobber (match_operand:P 2 "register_operand" "=c"))]
16171 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16173 [(set_attr "type" "str")
16174 (set_attr "mode" "QI")
16175 (set (attr "prefix_rex")
16177 (match_test "<P:MODE>mode == DImode")
16179 (const_string "*")))
16180 (set_attr "prefix_rep" "1")])
16182 (define_expand "strlen<mode>"
16183 [(set (match_operand:P 0 "register_operand" "")
16184 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16185 (match_operand:QI 2 "immediate_operand" "")
16186 (match_operand 3 "immediate_operand" "")]
16190 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16196 (define_expand "strlenqi_1"
16197 [(parallel [(set (match_operand 0 "register_operand" "")
16198 (match_operand 2 "" ""))
16199 (clobber (match_operand 1 "register_operand" ""))
16200 (clobber (reg:CC FLAGS_REG))])]
16202 "ix86_current_function_needs_cld = 1;")
16204 (define_insn "*strlenqi_1"
16205 [(set (match_operand:P 0 "register_operand" "=&c")
16206 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16207 (match_operand:QI 2 "register_operand" "a")
16208 (match_operand:P 3 "immediate_operand" "i")
16209 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16210 (clobber (match_operand:P 1 "register_operand" "=D"))
16211 (clobber (reg:CC FLAGS_REG))]
16212 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16214 [(set_attr "type" "str")
16215 (set_attr "mode" "QI")
16216 (set (attr "prefix_rex")
16218 (match_test "<P:MODE>mode == DImode")
16220 (const_string "*")))
16221 (set_attr "prefix_rep" "1")])
16223 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16224 ;; handled in combine, but it is not currently up to the task.
16225 ;; When used for their truth value, the cmpstrn* expanders generate
16234 ;; The intermediate three instructions are unnecessary.
16236 ;; This one handles cmpstrn*_nz_1...
16239 (set (reg:CC FLAGS_REG)
16240 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16241 (mem:BLK (match_operand 5 "register_operand" ""))))
16242 (use (match_operand 6 "register_operand" ""))
16243 (use (match_operand:SI 3 "immediate_operand" ""))
16244 (clobber (match_operand 0 "register_operand" ""))
16245 (clobber (match_operand 1 "register_operand" ""))
16246 (clobber (match_operand 2 "register_operand" ""))])
16247 (set (match_operand:QI 7 "register_operand" "")
16248 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16249 (set (match_operand:QI 8 "register_operand" "")
16250 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16251 (set (reg FLAGS_REG)
16252 (compare (match_dup 7) (match_dup 8)))
16254 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16256 (set (reg:CC FLAGS_REG)
16257 (compare:CC (mem:BLK (match_dup 4))
16258 (mem:BLK (match_dup 5))))
16259 (use (match_dup 6))
16260 (use (match_dup 3))
16261 (clobber (match_dup 0))
16262 (clobber (match_dup 1))
16263 (clobber (match_dup 2))])])
16265 ;; ...and this one handles cmpstrn*_1.
16268 (set (reg:CC FLAGS_REG)
16269 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16271 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16272 (mem:BLK (match_operand 5 "register_operand" "")))
16274 (use (match_operand:SI 3 "immediate_operand" ""))
16275 (use (reg:CC FLAGS_REG))
16276 (clobber (match_operand 0 "register_operand" ""))
16277 (clobber (match_operand 1 "register_operand" ""))
16278 (clobber (match_operand 2 "register_operand" ""))])
16279 (set (match_operand:QI 7 "register_operand" "")
16280 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16281 (set (match_operand:QI 8 "register_operand" "")
16282 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16283 (set (reg FLAGS_REG)
16284 (compare (match_dup 7) (match_dup 8)))
16286 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16288 (set (reg:CC FLAGS_REG)
16289 (if_then_else:CC (ne (match_dup 6)
16291 (compare:CC (mem:BLK (match_dup 4))
16292 (mem:BLK (match_dup 5)))
16294 (use (match_dup 3))
16295 (use (reg:CC FLAGS_REG))
16296 (clobber (match_dup 0))
16297 (clobber (match_dup 1))
16298 (clobber (match_dup 2))])])
16300 ;; Conditional move instructions.
16302 (define_expand "mov<mode>cc"
16303 [(set (match_operand:SWIM 0 "register_operand" "")
16304 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16305 (match_operand:SWIM 2 "<general_operand>" "")
16306 (match_operand:SWIM 3 "<general_operand>" "")))]
16308 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16310 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16311 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16312 ;; So just document what we're doing explicitly.
16314 (define_expand "x86_mov<mode>cc_0_m1"
16316 [(set (match_operand:SWI48 0 "register_operand" "")
16317 (if_then_else:SWI48
16318 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16319 [(match_operand 1 "flags_reg_operand" "")
16323 (clobber (reg:CC FLAGS_REG))])])
16325 (define_insn "*x86_mov<mode>cc_0_m1"
16326 [(set (match_operand:SWI48 0 "register_operand" "=r")
16327 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16328 [(reg FLAGS_REG) (const_int 0)])
16331 (clobber (reg:CC FLAGS_REG))]
16333 "sbb{<imodesuffix>}\t%0, %0"
16334 ; Since we don't have the proper number of operands for an alu insn,
16335 ; fill in all the blanks.
16336 [(set_attr "type" "alu")
16337 (set_attr "use_carry" "1")
16338 (set_attr "pent_pair" "pu")
16339 (set_attr "memory" "none")
16340 (set_attr "imm_disp" "false")
16341 (set_attr "mode" "<MODE>")
16342 (set_attr "length_immediate" "0")])
16344 (define_insn "*x86_mov<mode>cc_0_m1_se"
16345 [(set (match_operand:SWI48 0 "register_operand" "=r")
16346 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16347 [(reg FLAGS_REG) (const_int 0)])
16350 (clobber (reg:CC FLAGS_REG))]
16352 "sbb{<imodesuffix>}\t%0, %0"
16353 [(set_attr "type" "alu")
16354 (set_attr "use_carry" "1")
16355 (set_attr "pent_pair" "pu")
16356 (set_attr "memory" "none")
16357 (set_attr "imm_disp" "false")
16358 (set_attr "mode" "<MODE>")
16359 (set_attr "length_immediate" "0")])
16361 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16362 [(set (match_operand:SWI48 0 "register_operand" "=r")
16363 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16364 [(reg FLAGS_REG) (const_int 0)])))
16365 (clobber (reg:CC FLAGS_REG))]
16367 "sbb{<imodesuffix>}\t%0, %0"
16368 [(set_attr "type" "alu")
16369 (set_attr "use_carry" "1")
16370 (set_attr "pent_pair" "pu")
16371 (set_attr "memory" "none")
16372 (set_attr "imm_disp" "false")
16373 (set_attr "mode" "<MODE>")
16374 (set_attr "length_immediate" "0")])
16376 (define_insn "*mov<mode>cc_noc"
16377 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16378 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16379 [(reg FLAGS_REG) (const_int 0)])
16380 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16381 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16382 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16384 cmov%O2%C1\t{%2, %0|%0, %2}
16385 cmov%O2%c1\t{%3, %0|%0, %3}"
16386 [(set_attr "type" "icmov")
16387 (set_attr "mode" "<MODE>")])
16389 (define_insn "*movqicc_noc"
16390 [(set (match_operand:QI 0 "register_operand" "=r,r")
16391 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16392 [(reg FLAGS_REG) (const_int 0)])
16393 (match_operand:QI 2 "register_operand" "r,0")
16394 (match_operand:QI 3 "register_operand" "0,r")))]
16395 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16397 [(set_attr "type" "icmov")
16398 (set_attr "mode" "QI")])
16401 [(set (match_operand 0 "register_operand")
16402 (if_then_else (match_operator 1 "ix86_comparison_operator"
16403 [(reg FLAGS_REG) (const_int 0)])
16404 (match_operand 2 "register_operand")
16405 (match_operand 3 "register_operand")))]
16406 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16407 && (GET_MODE (operands[0]) == QImode
16408 || GET_MODE (operands[0]) == HImode)
16409 && reload_completed"
16410 [(set (match_dup 0)
16411 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16413 operands[0] = gen_lowpart (SImode, operands[0]);
16414 operands[2] = gen_lowpart (SImode, operands[2]);
16415 operands[3] = gen_lowpart (SImode, operands[3]);
16418 (define_expand "mov<mode>cc"
16419 [(set (match_operand:X87MODEF 0 "register_operand" "")
16420 (if_then_else:X87MODEF
16421 (match_operand 1 "ix86_fp_comparison_operator" "")
16422 (match_operand:X87MODEF 2 "register_operand" "")
16423 (match_operand:X87MODEF 3 "register_operand" "")))]
16424 "(TARGET_80387 && TARGET_CMOVE)
16425 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16426 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16428 (define_insn "*movxfcc_1"
16429 [(set (match_operand:XF 0 "register_operand" "=f,f")
16430 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16431 [(reg FLAGS_REG) (const_int 0)])
16432 (match_operand:XF 2 "register_operand" "f,0")
16433 (match_operand:XF 3 "register_operand" "0,f")))]
16434 "TARGET_80387 && TARGET_CMOVE"
16436 fcmov%F1\t{%2, %0|%0, %2}
16437 fcmov%f1\t{%3, %0|%0, %3}"
16438 [(set_attr "type" "fcmov")
16439 (set_attr "mode" "XF")])
16441 (define_insn "*movdfcc_1_rex64"
16442 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16443 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16444 [(reg FLAGS_REG) (const_int 0)])
16445 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16446 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16447 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16448 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16450 fcmov%F1\t{%2, %0|%0, %2}
16451 fcmov%f1\t{%3, %0|%0, %3}
16452 cmov%O2%C1\t{%2, %0|%0, %2}
16453 cmov%O2%c1\t{%3, %0|%0, %3}"
16454 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16455 (set_attr "mode" "DF,DF,DI,DI")])
16457 (define_insn "*movdfcc_1"
16458 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16459 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16460 [(reg FLAGS_REG) (const_int 0)])
16461 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16462 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16463 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16464 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16466 fcmov%F1\t{%2, %0|%0, %2}
16467 fcmov%f1\t{%3, %0|%0, %3}
16470 [(set_attr "type" "fcmov,fcmov,multi,multi")
16471 (set_attr "mode" "DF,DF,DI,DI")])
16474 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16475 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16476 [(reg FLAGS_REG) (const_int 0)])
16477 (match_operand:DF 2 "nonimmediate_operand")
16478 (match_operand:DF 3 "nonimmediate_operand")))]
16479 "!TARGET_64BIT && reload_completed"
16480 [(set (match_dup 2)
16481 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16483 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16485 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16486 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16489 (define_insn "*movsfcc_1_387"
16490 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16491 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16492 [(reg FLAGS_REG) (const_int 0)])
16493 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16494 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16495 "TARGET_80387 && TARGET_CMOVE
16496 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16498 fcmov%F1\t{%2, %0|%0, %2}
16499 fcmov%f1\t{%3, %0|%0, %3}
16500 cmov%O2%C1\t{%2, %0|%0, %2}
16501 cmov%O2%c1\t{%3, %0|%0, %3}"
16502 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16503 (set_attr "mode" "SF,SF,SI,SI")])
16505 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16506 ;; the scalar versions to have only XMM registers as operands.
16508 ;; XOP conditional move
16509 (define_insn "*xop_pcmov_<mode>"
16510 [(set (match_operand:MODEF 0 "register_operand" "=x")
16511 (if_then_else:MODEF
16512 (match_operand:MODEF 1 "register_operand" "x")
16513 (match_operand:MODEF 2 "register_operand" "x")
16514 (match_operand:MODEF 3 "register_operand" "x")))]
16516 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16517 [(set_attr "type" "sse4arg")])
16519 ;; These versions of the min/max patterns are intentionally ignorant of
16520 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16521 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16522 ;; are undefined in this condition, we're certain this is correct.
16524 (define_insn "<code><mode>3"
16525 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16527 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16528 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16529 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16531 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16532 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16533 [(set_attr "isa" "noavx,avx")
16534 (set_attr "prefix" "orig,vex")
16535 (set_attr "type" "sseadd")
16536 (set_attr "mode" "<MODE>")])
16538 ;; These versions of the min/max patterns implement exactly the operations
16539 ;; min = (op1 < op2 ? op1 : op2)
16540 ;; max = (!(op1 < op2) ? op1 : op2)
16541 ;; Their operands are not commutative, and thus they may be used in the
16542 ;; presence of -0.0 and NaN.
16544 (define_insn "*ieee_smin<mode>3"
16545 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16547 [(match_operand:MODEF 1 "register_operand" "0,x")
16548 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16550 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16552 min<ssemodesuffix>\t{%2, %0|%0, %2}
16553 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16554 [(set_attr "isa" "noavx,avx")
16555 (set_attr "prefix" "orig,vex")
16556 (set_attr "type" "sseadd")
16557 (set_attr "mode" "<MODE>")])
16559 (define_insn "*ieee_smax<mode>3"
16560 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16562 [(match_operand:MODEF 1 "register_operand" "0,x")
16563 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16565 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16567 max<ssemodesuffix>\t{%2, %0|%0, %2}
16568 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16569 [(set_attr "isa" "noavx,avx")
16570 (set_attr "prefix" "orig,vex")
16571 (set_attr "type" "sseadd")
16572 (set_attr "mode" "<MODE>")])
16574 ;; Make two stack loads independent:
16576 ;; fld %st(0) -> fld bb
16577 ;; fmul bb fmul %st(1), %st
16579 ;; Actually we only match the last two instructions for simplicity.
16581 [(set (match_operand 0 "fp_register_operand" "")
16582 (match_operand 1 "fp_register_operand" ""))
16584 (match_operator 2 "binary_fp_operator"
16586 (match_operand 3 "memory_operand" "")]))]
16587 "REGNO (operands[0]) != REGNO (operands[1])"
16588 [(set (match_dup 0) (match_dup 3))
16589 (set (match_dup 0) (match_dup 4))]
16591 ;; The % modifier is not operational anymore in peephole2's, so we have to
16592 ;; swap the operands manually in the case of addition and multiplication.
16596 if (COMMUTATIVE_ARITH_P (operands[2]))
16597 op0 = operands[0], op1 = operands[1];
16599 op0 = operands[1], op1 = operands[0];
16601 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16602 GET_MODE (operands[2]),
16606 ;; Conditional addition patterns
16607 (define_expand "add<mode>cc"
16608 [(match_operand:SWI 0 "register_operand" "")
16609 (match_operand 1 "ordered_comparison_operator" "")
16610 (match_operand:SWI 2 "register_operand" "")
16611 (match_operand:SWI 3 "const_int_operand" "")]
16613 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16615 ;; Misc patterns (?)
16617 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16618 ;; Otherwise there will be nothing to keep
16620 ;; [(set (reg ebp) (reg esp))]
16621 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16622 ;; (clobber (eflags)]
16623 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16625 ;; in proper program order.
16627 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16628 [(set (match_operand:P 0 "register_operand" "=r,r")
16629 (plus:P (match_operand:P 1 "register_operand" "0,r")
16630 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16631 (clobber (reg:CC FLAGS_REG))
16632 (clobber (mem:BLK (scratch)))]
16635 switch (get_attr_type (insn))
16638 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16641 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16642 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16643 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16645 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16648 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16649 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16652 [(set (attr "type")
16653 (cond [(and (eq_attr "alternative" "0")
16654 (not (match_test "TARGET_OPT_AGU")))
16655 (const_string "alu")
16656 (match_operand:<MODE> 2 "const0_operand" "")
16657 (const_string "imov")
16659 (const_string "lea")))
16660 (set (attr "length_immediate")
16661 (cond [(eq_attr "type" "imov")
16663 (and (eq_attr "type" "alu")
16664 (match_operand 2 "const128_operand" ""))
16667 (const_string "*")))
16668 (set_attr "mode" "<MODE>")])
16670 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16671 [(set (match_operand:P 0 "register_operand" "=r")
16672 (minus:P (match_operand:P 1 "register_operand" "0")
16673 (match_operand:P 2 "register_operand" "r")))
16674 (clobber (reg:CC FLAGS_REG))
16675 (clobber (mem:BLK (scratch)))]
16677 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16678 [(set_attr "type" "alu")
16679 (set_attr "mode" "<MODE>")])
16681 (define_insn "allocate_stack_worker_probe_<mode>"
16682 [(set (match_operand:P 0 "register_operand" "=a")
16683 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16684 UNSPECV_STACK_PROBE))
16685 (clobber (reg:CC FLAGS_REG))]
16686 "ix86_target_stack_probe ()"
16687 "call\t___chkstk_ms"
16688 [(set_attr "type" "multi")
16689 (set_attr "length" "5")])
16691 (define_expand "allocate_stack"
16692 [(match_operand 0 "register_operand" "")
16693 (match_operand 1 "general_operand" "")]
16694 "ix86_target_stack_probe ()"
16698 #ifndef CHECK_STACK_LIMIT
16699 #define CHECK_STACK_LIMIT 0
16702 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16703 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16705 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16706 stack_pointer_rtx, 0, OPTAB_DIRECT);
16707 if (x != stack_pointer_rtx)
16708 emit_move_insn (stack_pointer_rtx, x);
16712 x = copy_to_mode_reg (Pmode, operands[1]);
16714 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16716 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16717 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16718 stack_pointer_rtx, 0, OPTAB_DIRECT);
16719 if (x != stack_pointer_rtx)
16720 emit_move_insn (stack_pointer_rtx, x);
16723 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16727 ;; Use IOR for stack probes, this is shorter.
16728 (define_expand "probe_stack"
16729 [(match_operand 0 "memory_operand" "")]
16732 rtx (*gen_ior3) (rtx, rtx, rtx);
16734 gen_ior3 = (GET_MODE (operands[0]) == DImode
16735 ? gen_iordi3 : gen_iorsi3);
16737 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16741 (define_insn "adjust_stack_and_probe<mode>"
16742 [(set (match_operand:P 0 "register_operand" "=r")
16743 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16744 UNSPECV_PROBE_STACK_RANGE))
16745 (set (reg:P SP_REG)
16746 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16747 (clobber (reg:CC FLAGS_REG))
16748 (clobber (mem:BLK (scratch)))]
16750 "* return output_adjust_stack_and_probe (operands[0]);"
16751 [(set_attr "type" "multi")])
16753 (define_insn "probe_stack_range<mode>"
16754 [(set (match_operand:P 0 "register_operand" "=r")
16755 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16756 (match_operand:P 2 "const_int_operand" "n")]
16757 UNSPECV_PROBE_STACK_RANGE))
16758 (clobber (reg:CC FLAGS_REG))]
16760 "* return output_probe_stack_range (operands[0], operands[2]);"
16761 [(set_attr "type" "multi")])
16763 (define_expand "builtin_setjmp_receiver"
16764 [(label_ref (match_operand 0 "" ""))]
16765 "!TARGET_64BIT && flag_pic"
16771 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16772 rtx label_rtx = gen_label_rtx ();
16773 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16774 xops[0] = xops[1] = picreg;
16775 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16776 ix86_expand_binary_operator (MINUS, SImode, xops);
16780 emit_insn (gen_set_got (pic_offset_table_rtx));
16784 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16787 [(set (match_operand 0 "register_operand" "")
16788 (match_operator 3 "promotable_binary_operator"
16789 [(match_operand 1 "register_operand" "")
16790 (match_operand 2 "aligned_operand" "")]))
16791 (clobber (reg:CC FLAGS_REG))]
16792 "! TARGET_PARTIAL_REG_STALL && reload_completed
16793 && ((GET_MODE (operands[0]) == HImode
16794 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16795 /* ??? next two lines just !satisfies_constraint_K (...) */
16796 || !CONST_INT_P (operands[2])
16797 || satisfies_constraint_K (operands[2])))
16798 || (GET_MODE (operands[0]) == QImode
16799 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16800 [(parallel [(set (match_dup 0)
16801 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16802 (clobber (reg:CC FLAGS_REG))])]
16804 operands[0] = gen_lowpart (SImode, operands[0]);
16805 operands[1] = gen_lowpart (SImode, operands[1]);
16806 if (GET_CODE (operands[3]) != ASHIFT)
16807 operands[2] = gen_lowpart (SImode, operands[2]);
16808 PUT_MODE (operands[3], SImode);
16811 ; Promote the QImode tests, as i386 has encoding of the AND
16812 ; instruction with 32-bit sign-extended immediate and thus the
16813 ; instruction size is unchanged, except in the %eax case for
16814 ; which it is increased by one byte, hence the ! optimize_size.
16816 [(set (match_operand 0 "flags_reg_operand" "")
16817 (match_operator 2 "compare_operator"
16818 [(and (match_operand 3 "aligned_operand" "")
16819 (match_operand 4 "const_int_operand" ""))
16821 (set (match_operand 1 "register_operand" "")
16822 (and (match_dup 3) (match_dup 4)))]
16823 "! TARGET_PARTIAL_REG_STALL && reload_completed
16824 && optimize_insn_for_speed_p ()
16825 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16826 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16827 /* Ensure that the operand will remain sign-extended immediate. */
16828 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16829 [(parallel [(set (match_dup 0)
16830 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16833 (and:SI (match_dup 3) (match_dup 4)))])]
16836 = gen_int_mode (INTVAL (operands[4])
16837 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16838 operands[1] = gen_lowpart (SImode, operands[1]);
16839 operands[3] = gen_lowpart (SImode, operands[3]);
16842 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16843 ; the TEST instruction with 32-bit sign-extended immediate and thus
16844 ; the instruction size would at least double, which is not what we
16845 ; want even with ! optimize_size.
16847 [(set (match_operand 0 "flags_reg_operand" "")
16848 (match_operator 1 "compare_operator"
16849 [(and (match_operand:HI 2 "aligned_operand" "")
16850 (match_operand:HI 3 "const_int_operand" ""))
16852 "! TARGET_PARTIAL_REG_STALL && reload_completed
16853 && ! TARGET_FAST_PREFIX
16854 && optimize_insn_for_speed_p ()
16855 /* Ensure that the operand will remain sign-extended immediate. */
16856 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16857 [(set (match_dup 0)
16858 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16862 = gen_int_mode (INTVAL (operands[3])
16863 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16864 operands[2] = gen_lowpart (SImode, operands[2]);
16868 [(set (match_operand 0 "register_operand" "")
16869 (neg (match_operand 1 "register_operand" "")))
16870 (clobber (reg:CC FLAGS_REG))]
16871 "! TARGET_PARTIAL_REG_STALL && reload_completed
16872 && (GET_MODE (operands[0]) == HImode
16873 || (GET_MODE (operands[0]) == QImode
16874 && (TARGET_PROMOTE_QImode
16875 || optimize_insn_for_size_p ())))"
16876 [(parallel [(set (match_dup 0)
16877 (neg:SI (match_dup 1)))
16878 (clobber (reg:CC FLAGS_REG))])]
16880 operands[0] = gen_lowpart (SImode, operands[0]);
16881 operands[1] = gen_lowpart (SImode, operands[1]);
16885 [(set (match_operand 0 "register_operand" "")
16886 (not (match_operand 1 "register_operand" "")))]
16887 "! TARGET_PARTIAL_REG_STALL && reload_completed
16888 && (GET_MODE (operands[0]) == HImode
16889 || (GET_MODE (operands[0]) == QImode
16890 && (TARGET_PROMOTE_QImode
16891 || optimize_insn_for_size_p ())))"
16892 [(set (match_dup 0)
16893 (not:SI (match_dup 1)))]
16895 operands[0] = gen_lowpart (SImode, operands[0]);
16896 operands[1] = gen_lowpart (SImode, operands[1]);
16899 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16900 ;; transform a complex memory operation into two memory to register operations.
16902 ;; Don't push memory operands
16904 [(set (match_operand:SWI 0 "push_operand" "")
16905 (match_operand:SWI 1 "memory_operand" ""))
16906 (match_scratch:SWI 2 "<r>")]
16907 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16908 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16909 [(set (match_dup 2) (match_dup 1))
16910 (set (match_dup 0) (match_dup 2))])
16912 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16915 [(set (match_operand:SF 0 "push_operand" "")
16916 (match_operand:SF 1 "memory_operand" ""))
16917 (match_scratch:SF 2 "r")]
16918 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16919 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16920 [(set (match_dup 2) (match_dup 1))
16921 (set (match_dup 0) (match_dup 2))])
16923 ;; Don't move an immediate directly to memory when the instruction
16926 [(match_scratch:SWI124 1 "<r>")
16927 (set (match_operand:SWI124 0 "memory_operand" "")
16929 "optimize_insn_for_speed_p ()
16930 && !TARGET_USE_MOV0
16931 && TARGET_SPLIT_LONG_MOVES
16932 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16933 && peep2_regno_dead_p (0, FLAGS_REG)"
16934 [(parallel [(set (match_dup 2) (const_int 0))
16935 (clobber (reg:CC FLAGS_REG))])
16936 (set (match_dup 0) (match_dup 1))]
16937 "operands[2] = gen_lowpart (SImode, operands[1]);")
16940 [(match_scratch:SWI124 2 "<r>")
16941 (set (match_operand:SWI124 0 "memory_operand" "")
16942 (match_operand:SWI124 1 "immediate_operand" ""))]
16943 "optimize_insn_for_speed_p ()
16944 && TARGET_SPLIT_LONG_MOVES
16945 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16946 [(set (match_dup 2) (match_dup 1))
16947 (set (match_dup 0) (match_dup 2))])
16949 ;; Don't compare memory with zero, load and use a test instead.
16951 [(set (match_operand 0 "flags_reg_operand" "")
16952 (match_operator 1 "compare_operator"
16953 [(match_operand:SI 2 "memory_operand" "")
16955 (match_scratch:SI 3 "r")]
16956 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16957 [(set (match_dup 3) (match_dup 2))
16958 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16960 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16961 ;; Don't split NOTs with a displacement operand, because resulting XOR
16962 ;; will not be pairable anyway.
16964 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16965 ;; represented using a modRM byte. The XOR replacement is long decoded,
16966 ;; so this split helps here as well.
16968 ;; Note: Can't do this as a regular split because we can't get proper
16969 ;; lifetime information then.
16972 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16973 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16974 "optimize_insn_for_speed_p ()
16975 && ((TARGET_NOT_UNPAIRABLE
16976 && (!MEM_P (operands[0])
16977 || !memory_displacement_operand (operands[0], <MODE>mode)))
16978 || (TARGET_NOT_VECTORMODE
16979 && long_memory_operand (operands[0], <MODE>mode)))
16980 && peep2_regno_dead_p (0, FLAGS_REG)"
16981 [(parallel [(set (match_dup 0)
16982 (xor:SWI124 (match_dup 1) (const_int -1)))
16983 (clobber (reg:CC FLAGS_REG))])])
16985 ;; Non pairable "test imm, reg" instructions can be translated to
16986 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16987 ;; byte opcode instead of two, have a short form for byte operands),
16988 ;; so do it for other CPUs as well. Given that the value was dead,
16989 ;; this should not create any new dependencies. Pass on the sub-word
16990 ;; versions if we're concerned about partial register stalls.
16993 [(set (match_operand 0 "flags_reg_operand" "")
16994 (match_operator 1 "compare_operator"
16995 [(and:SI (match_operand:SI 2 "register_operand" "")
16996 (match_operand:SI 3 "immediate_operand" ""))
16998 "ix86_match_ccmode (insn, CCNOmode)
16999 && (true_regnum (operands[2]) != AX_REG
17000 || satisfies_constraint_K (operands[3]))
17001 && peep2_reg_dead_p (1, operands[2])"
17003 [(set (match_dup 0)
17004 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17007 (and:SI (match_dup 2) (match_dup 3)))])])
17009 ;; We don't need to handle HImode case, because it will be promoted to SImode
17010 ;; on ! TARGET_PARTIAL_REG_STALL
17013 [(set (match_operand 0 "flags_reg_operand" "")
17014 (match_operator 1 "compare_operator"
17015 [(and:QI (match_operand:QI 2 "register_operand" "")
17016 (match_operand:QI 3 "immediate_operand" ""))
17018 "! TARGET_PARTIAL_REG_STALL
17019 && ix86_match_ccmode (insn, CCNOmode)
17020 && true_regnum (operands[2]) != AX_REG
17021 && peep2_reg_dead_p (1, operands[2])"
17023 [(set (match_dup 0)
17024 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17027 (and:QI (match_dup 2) (match_dup 3)))])])
17030 [(set (match_operand 0 "flags_reg_operand" "")
17031 (match_operator 1 "compare_operator"
17034 (match_operand 2 "ext_register_operand" "")
17037 (match_operand 3 "const_int_operand" ""))
17039 "! TARGET_PARTIAL_REG_STALL
17040 && ix86_match_ccmode (insn, CCNOmode)
17041 && true_regnum (operands[2]) != AX_REG
17042 && peep2_reg_dead_p (1, operands[2])"
17043 [(parallel [(set (match_dup 0)
17052 (set (zero_extract:SI (match_dup 2)
17060 (match_dup 3)))])])
17062 ;; Don't do logical operations with memory inputs.
17064 [(match_scratch:SI 2 "r")
17065 (parallel [(set (match_operand:SI 0 "register_operand" "")
17066 (match_operator:SI 3 "arith_or_logical_operator"
17068 (match_operand:SI 1 "memory_operand" "")]))
17069 (clobber (reg:CC FLAGS_REG))])]
17070 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17071 [(set (match_dup 2) (match_dup 1))
17072 (parallel [(set (match_dup 0)
17073 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17074 (clobber (reg:CC FLAGS_REG))])])
17077 [(match_scratch:SI 2 "r")
17078 (parallel [(set (match_operand:SI 0 "register_operand" "")
17079 (match_operator:SI 3 "arith_or_logical_operator"
17080 [(match_operand:SI 1 "memory_operand" "")
17082 (clobber (reg:CC FLAGS_REG))])]
17083 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17084 [(set (match_dup 2) (match_dup 1))
17085 (parallel [(set (match_dup 0)
17086 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17087 (clobber (reg:CC FLAGS_REG))])])
17089 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17090 ;; refers to the destination of the load!
17093 [(set (match_operand:SI 0 "register_operand" "")
17094 (match_operand:SI 1 "register_operand" ""))
17095 (parallel [(set (match_dup 0)
17096 (match_operator:SI 3 "commutative_operator"
17098 (match_operand:SI 2 "memory_operand" "")]))
17099 (clobber (reg:CC FLAGS_REG))])]
17100 "REGNO (operands[0]) != REGNO (operands[1])
17101 && GENERAL_REGNO_P (REGNO (operands[0]))
17102 && GENERAL_REGNO_P (REGNO (operands[1]))"
17103 [(set (match_dup 0) (match_dup 4))
17104 (parallel [(set (match_dup 0)
17105 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17106 (clobber (reg:CC FLAGS_REG))])]
17107 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17110 [(set (match_operand 0 "register_operand" "")
17111 (match_operand 1 "register_operand" ""))
17113 (match_operator 3 "commutative_operator"
17115 (match_operand 2 "memory_operand" "")]))]
17116 "REGNO (operands[0]) != REGNO (operands[1])
17117 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17118 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17119 [(set (match_dup 0) (match_dup 2))
17121 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17123 ; Don't do logical operations with memory outputs
17125 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17126 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17127 ; the same decoder scheduling characteristics as the original.
17130 [(match_scratch:SI 2 "r")
17131 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17132 (match_operator:SI 3 "arith_or_logical_operator"
17134 (match_operand:SI 1 "nonmemory_operand" "")]))
17135 (clobber (reg:CC FLAGS_REG))])]
17136 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17137 /* Do not split stack checking probes. */
17138 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17139 [(set (match_dup 2) (match_dup 0))
17140 (parallel [(set (match_dup 2)
17141 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17142 (clobber (reg:CC FLAGS_REG))])
17143 (set (match_dup 0) (match_dup 2))])
17146 [(match_scratch:SI 2 "r")
17147 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17148 (match_operator:SI 3 "arith_or_logical_operator"
17149 [(match_operand:SI 1 "nonmemory_operand" "")
17151 (clobber (reg:CC FLAGS_REG))])]
17152 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17153 /* Do not split stack checking probes. */
17154 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17155 [(set (match_dup 2) (match_dup 0))
17156 (parallel [(set (match_dup 2)
17157 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17158 (clobber (reg:CC FLAGS_REG))])
17159 (set (match_dup 0) (match_dup 2))])
17161 ;; Attempt to use arith or logical operations with memory outputs with
17162 ;; setting of flags.
17164 [(set (match_operand:SWI 0 "register_operand" "")
17165 (match_operand:SWI 1 "memory_operand" ""))
17166 (parallel [(set (match_dup 0)
17167 (match_operator:SWI 3 "plusminuslogic_operator"
17169 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17170 (clobber (reg:CC FLAGS_REG))])
17171 (set (match_dup 1) (match_dup 0))
17172 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17173 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17174 && peep2_reg_dead_p (4, operands[0])
17175 && !reg_overlap_mentioned_p (operands[0], operands[1])
17176 && (<MODE>mode != QImode
17177 || immediate_operand (operands[2], QImode)
17178 || q_regs_operand (operands[2], QImode))
17179 && ix86_match_ccmode (peep2_next_insn (3),
17180 (GET_CODE (operands[3]) == PLUS
17181 || GET_CODE (operands[3]) == MINUS)
17182 ? CCGOCmode : CCNOmode)"
17183 [(parallel [(set (match_dup 4) (match_dup 5))
17184 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17185 (match_dup 2)]))])]
17187 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17188 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17189 copy_rtx (operands[1]),
17190 copy_rtx (operands[2]));
17191 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17192 operands[5], const0_rtx);
17196 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17197 (match_operator:SWI 2 "plusminuslogic_operator"
17199 (match_operand:SWI 1 "memory_operand" "")]))
17200 (clobber (reg:CC FLAGS_REG))])
17201 (set (match_dup 1) (match_dup 0))
17202 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17203 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17204 && GET_CODE (operands[2]) != MINUS
17205 && peep2_reg_dead_p (3, operands[0])
17206 && !reg_overlap_mentioned_p (operands[0], operands[1])
17207 && ix86_match_ccmode (peep2_next_insn (2),
17208 GET_CODE (operands[2]) == PLUS
17209 ? CCGOCmode : CCNOmode)"
17210 [(parallel [(set (match_dup 3) (match_dup 4))
17211 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17212 (match_dup 0)]))])]
17214 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17215 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17216 copy_rtx (operands[1]),
17217 copy_rtx (operands[0]));
17218 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17219 operands[4], const0_rtx);
17223 [(set (match_operand:SWI12 0 "register_operand" "")
17224 (match_operand:SWI12 1 "memory_operand" ""))
17225 (parallel [(set (match_operand:SI 4 "register_operand" "")
17226 (match_operator:SI 3 "plusminuslogic_operator"
17228 (match_operand:SI 2 "nonmemory_operand" "")]))
17229 (clobber (reg:CC FLAGS_REG))])
17230 (set (match_dup 1) (match_dup 0))
17231 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17232 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17233 && REG_P (operands[0]) && REG_P (operands[4])
17234 && REGNO (operands[0]) == REGNO (operands[4])
17235 && peep2_reg_dead_p (4, operands[0])
17236 && (<MODE>mode != QImode
17237 || immediate_operand (operands[2], SImode)
17238 || q_regs_operand (operands[2], SImode))
17239 && !reg_overlap_mentioned_p (operands[0], operands[1])
17240 && ix86_match_ccmode (peep2_next_insn (3),
17241 (GET_CODE (operands[3]) == PLUS
17242 || GET_CODE (operands[3]) == MINUS)
17243 ? CCGOCmode : CCNOmode)"
17244 [(parallel [(set (match_dup 4) (match_dup 5))
17245 (set (match_dup 1) (match_dup 6))])]
17247 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17248 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17249 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17250 copy_rtx (operands[1]), operands[2]);
17251 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17252 operands[5], const0_rtx);
17253 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17254 copy_rtx (operands[1]),
17255 copy_rtx (operands[2]));
17258 ;; Attempt to always use XOR for zeroing registers.
17260 [(set (match_operand 0 "register_operand" "")
17261 (match_operand 1 "const0_operand" ""))]
17262 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17263 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17264 && GENERAL_REG_P (operands[0])
17265 && peep2_regno_dead_p (0, FLAGS_REG)"
17266 [(parallel [(set (match_dup 0) (const_int 0))
17267 (clobber (reg:CC FLAGS_REG))])]
17268 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17271 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17273 "(GET_MODE (operands[0]) == QImode
17274 || GET_MODE (operands[0]) == HImode)
17275 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17276 && peep2_regno_dead_p (0, FLAGS_REG)"
17277 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17278 (clobber (reg:CC FLAGS_REG))])])
17280 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17282 [(set (match_operand:SWI248 0 "register_operand" "")
17284 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17285 && peep2_regno_dead_p (0, FLAGS_REG)"
17286 [(parallel [(set (match_dup 0) (const_int -1))
17287 (clobber (reg:CC FLAGS_REG))])]
17289 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17290 operands[0] = gen_lowpart (SImode, operands[0]);
17293 ;; Attempt to convert simple lea to add/shift.
17294 ;; These can be created by move expanders.
17297 [(set (match_operand:SWI48 0 "register_operand" "")
17298 (plus:SWI48 (match_dup 0)
17299 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17300 "peep2_regno_dead_p (0, FLAGS_REG)"
17301 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17302 (clobber (reg:CC FLAGS_REG))])])
17305 [(set (match_operand:SI 0 "register_operand" "")
17306 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17307 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17309 && peep2_regno_dead_p (0, FLAGS_REG)
17310 && REGNO (operands[0]) == REGNO (operands[1])"
17311 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17312 (clobber (reg:CC FLAGS_REG))])]
17313 "operands[2] = gen_lowpart (SImode, operands[2]);")
17316 [(set (match_operand:SWI48 0 "register_operand" "")
17317 (mult:SWI48 (match_dup 0)
17318 (match_operand:SWI48 1 "const_int_operand" "")))]
17319 "exact_log2 (INTVAL (operands[1])) >= 0
17320 && peep2_regno_dead_p (0, FLAGS_REG)"
17321 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17322 (clobber (reg:CC FLAGS_REG))])]
17323 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17326 [(set (match_operand:SI 0 "register_operand" "")
17327 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17328 (match_operand:DI 2 "const_int_operand" "")) 0))]
17330 && exact_log2 (INTVAL (operands[2])) >= 0
17331 && REGNO (operands[0]) == REGNO (operands[1])
17332 && peep2_regno_dead_p (0, FLAGS_REG)"
17333 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17334 (clobber (reg:CC FLAGS_REG))])]
17335 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17337 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17338 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17339 ;; On many CPUs it is also faster, since special hardware to avoid esp
17340 ;; dependencies is present.
17342 ;; While some of these conversions may be done using splitters, we use
17343 ;; peepholes in order to allow combine_stack_adjustments pass to see
17344 ;; nonobfuscated RTL.
17346 ;; Convert prologue esp subtractions to push.
17347 ;; We need register to push. In order to keep verify_flow_info happy we have
17349 ;; - use scratch and clobber it in order to avoid dependencies
17350 ;; - use already live register
17351 ;; We can't use the second way right now, since there is no reliable way how to
17352 ;; verify that given register is live. First choice will also most likely in
17353 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17354 ;; call clobbered registers are dead. We may want to use base pointer as an
17355 ;; alternative when no register is available later.
17358 [(match_scratch:P 1 "r")
17359 (parallel [(set (reg:P SP_REG)
17360 (plus:P (reg:P SP_REG)
17361 (match_operand:P 0 "const_int_operand" "")))
17362 (clobber (reg:CC FLAGS_REG))
17363 (clobber (mem:BLK (scratch)))])]
17364 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17365 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17366 [(clobber (match_dup 1))
17367 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17368 (clobber (mem:BLK (scratch)))])])
17371 [(match_scratch:P 1 "r")
17372 (parallel [(set (reg:P SP_REG)
17373 (plus:P (reg:P SP_REG)
17374 (match_operand:P 0 "const_int_operand" "")))
17375 (clobber (reg:CC FLAGS_REG))
17376 (clobber (mem:BLK (scratch)))])]
17377 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17378 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17379 [(clobber (match_dup 1))
17380 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17381 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17382 (clobber (mem:BLK (scratch)))])])
17384 ;; Convert esp subtractions to push.
17386 [(match_scratch:P 1 "r")
17387 (parallel [(set (reg:P SP_REG)
17388 (plus:P (reg:P SP_REG)
17389 (match_operand:P 0 "const_int_operand" "")))
17390 (clobber (reg:CC FLAGS_REG))])]
17391 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17392 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17393 [(clobber (match_dup 1))
17394 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17397 [(match_scratch:P 1 "r")
17398 (parallel [(set (reg:P SP_REG)
17399 (plus:P (reg:P SP_REG)
17400 (match_operand:P 0 "const_int_operand" "")))
17401 (clobber (reg:CC FLAGS_REG))])]
17402 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17403 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17404 [(clobber (match_dup 1))
17405 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17406 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17408 ;; Convert epilogue deallocator to pop.
17410 [(match_scratch:P 1 "r")
17411 (parallel [(set (reg:P SP_REG)
17412 (plus:P (reg:P SP_REG)
17413 (match_operand:P 0 "const_int_operand" "")))
17414 (clobber (reg:CC FLAGS_REG))
17415 (clobber (mem:BLK (scratch)))])]
17416 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17417 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17418 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17419 (clobber (mem:BLK (scratch)))])])
17421 ;; Two pops case is tricky, since pop causes dependency
17422 ;; on destination register. We use two registers if available.
17424 [(match_scratch:P 1 "r")
17425 (match_scratch:P 2 "r")
17426 (parallel [(set (reg:P SP_REG)
17427 (plus:P (reg:P SP_REG)
17428 (match_operand:P 0 "const_int_operand" "")))
17429 (clobber (reg:CC FLAGS_REG))
17430 (clobber (mem:BLK (scratch)))])]
17431 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17432 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17433 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17434 (clobber (mem:BLK (scratch)))])
17435 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17438 [(match_scratch:P 1 "r")
17439 (parallel [(set (reg:P SP_REG)
17440 (plus:P (reg:P SP_REG)
17441 (match_operand:P 0 "const_int_operand" "")))
17442 (clobber (reg:CC FLAGS_REG))
17443 (clobber (mem:BLK (scratch)))])]
17444 "optimize_insn_for_size_p ()
17445 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17446 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17447 (clobber (mem:BLK (scratch)))])
17448 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17450 ;; Convert esp additions to pop.
17452 [(match_scratch:P 1 "r")
17453 (parallel [(set (reg:P SP_REG)
17454 (plus:P (reg:P SP_REG)
17455 (match_operand:P 0 "const_int_operand" "")))
17456 (clobber (reg:CC FLAGS_REG))])]
17457 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17458 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17460 ;; Two pops case is tricky, since pop causes dependency
17461 ;; on destination register. We use two registers if available.
17463 [(match_scratch:P 1 "r")
17464 (match_scratch:P 2 "r")
17465 (parallel [(set (reg:P SP_REG)
17466 (plus:P (reg:P SP_REG)
17467 (match_operand:P 0 "const_int_operand" "")))
17468 (clobber (reg:CC FLAGS_REG))])]
17469 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17470 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17471 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17474 [(match_scratch:P 1 "r")
17475 (parallel [(set (reg:P SP_REG)
17476 (plus:P (reg:P SP_REG)
17477 (match_operand:P 0 "const_int_operand" "")))
17478 (clobber (reg:CC FLAGS_REG))])]
17479 "optimize_insn_for_size_p ()
17480 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17481 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17482 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17484 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17485 ;; required and register dies. Similarly for 128 to -128.
17487 [(set (match_operand 0 "flags_reg_operand" "")
17488 (match_operator 1 "compare_operator"
17489 [(match_operand 2 "register_operand" "")
17490 (match_operand 3 "const_int_operand" "")]))]
17491 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17492 && incdec_operand (operands[3], GET_MODE (operands[3])))
17493 || (!TARGET_FUSE_CMP_AND_BRANCH
17494 && INTVAL (operands[3]) == 128))
17495 && ix86_match_ccmode (insn, CCGCmode)
17496 && peep2_reg_dead_p (1, operands[2])"
17497 [(parallel [(set (match_dup 0)
17498 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17499 (clobber (match_dup 2))])])
17501 ;; Convert imul by three, five and nine into lea
17504 [(set (match_operand:SWI48 0 "register_operand" "")
17505 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17506 (match_operand:SWI48 2 "const359_operand" "")))
17507 (clobber (reg:CC FLAGS_REG))])]
17508 "!TARGET_PARTIAL_REG_STALL
17509 || <MODE>mode == SImode
17510 || optimize_function_for_size_p (cfun)"
17511 [(set (match_dup 0)
17512 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17514 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17518 [(set (match_operand:SWI48 0 "register_operand" "")
17519 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17520 (match_operand:SWI48 2 "const359_operand" "")))
17521 (clobber (reg:CC FLAGS_REG))])]
17522 "optimize_insn_for_speed_p ()
17523 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17524 [(set (match_dup 0) (match_dup 1))
17526 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17528 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17530 ;; imul $32bit_imm, mem, reg is vector decoded, while
17531 ;; imul $32bit_imm, reg, reg is direct decoded.
17533 [(match_scratch:SWI48 3 "r")
17534 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17535 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17536 (match_operand:SWI48 2 "immediate_operand" "")))
17537 (clobber (reg:CC FLAGS_REG))])]
17538 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17539 && !satisfies_constraint_K (operands[2])"
17540 [(set (match_dup 3) (match_dup 1))
17541 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17542 (clobber (reg:CC FLAGS_REG))])])
17545 [(match_scratch:SI 3 "r")
17546 (parallel [(set (match_operand:DI 0 "register_operand" "")
17548 (mult:SI (match_operand:SI 1 "memory_operand" "")
17549 (match_operand:SI 2 "immediate_operand" ""))))
17550 (clobber (reg:CC FLAGS_REG))])]
17552 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17553 && !satisfies_constraint_K (operands[2])"
17554 [(set (match_dup 3) (match_dup 1))
17555 (parallel [(set (match_dup 0)
17556 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17557 (clobber (reg:CC FLAGS_REG))])])
17559 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17560 ;; Convert it into imul reg, reg
17561 ;; It would be better to force assembler to encode instruction using long
17562 ;; immediate, but there is apparently no way to do so.
17564 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17566 (match_operand:SWI248 1 "nonimmediate_operand" "")
17567 (match_operand:SWI248 2 "const_int_operand" "")))
17568 (clobber (reg:CC FLAGS_REG))])
17569 (match_scratch:SWI248 3 "r")]
17570 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17571 && satisfies_constraint_K (operands[2])"
17572 [(set (match_dup 3) (match_dup 2))
17573 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17574 (clobber (reg:CC FLAGS_REG))])]
17576 if (!rtx_equal_p (operands[0], operands[1]))
17577 emit_move_insn (operands[0], operands[1]);
17580 ;; After splitting up read-modify operations, array accesses with memory
17581 ;; operands might end up in form:
17583 ;; movl 4(%esp), %edx
17585 ;; instead of pre-splitting:
17587 ;; addl 4(%esp), %eax
17589 ;; movl 4(%esp), %edx
17590 ;; leal (%edx,%eax,4), %eax
17593 [(match_scratch:P 5 "r")
17594 (parallel [(set (match_operand 0 "register_operand" "")
17595 (ashift (match_operand 1 "register_operand" "")
17596 (match_operand 2 "const_int_operand" "")))
17597 (clobber (reg:CC FLAGS_REG))])
17598 (parallel [(set (match_operand 3 "register_operand" "")
17599 (plus (match_dup 0)
17600 (match_operand 4 "x86_64_general_operand" "")))
17601 (clobber (reg:CC FLAGS_REG))])]
17602 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17603 /* Validate MODE for lea. */
17604 && ((!TARGET_PARTIAL_REG_STALL
17605 && (GET_MODE (operands[0]) == QImode
17606 || GET_MODE (operands[0]) == HImode))
17607 || GET_MODE (operands[0]) == SImode
17608 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17609 && (rtx_equal_p (operands[0], operands[3])
17610 || peep2_reg_dead_p (2, operands[0]))
17611 /* We reorder load and the shift. */
17612 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17613 [(set (match_dup 5) (match_dup 4))
17614 (set (match_dup 0) (match_dup 1))]
17616 enum machine_mode op1mode = GET_MODE (operands[1]);
17617 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17618 int scale = 1 << INTVAL (operands[2]);
17619 rtx index = gen_lowpart (Pmode, operands[1]);
17620 rtx base = gen_lowpart (Pmode, operands[5]);
17621 rtx dest = gen_lowpart (mode, operands[3]);
17623 operands[1] = gen_rtx_PLUS (Pmode, base,
17624 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17625 operands[5] = base;
17627 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17628 if (op1mode != Pmode)
17629 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17630 operands[0] = dest;
17633 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17634 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17635 ;; caught for use by garbage collectors and the like. Using an insn that
17636 ;; maps to SIGILL makes it more likely the program will rightfully die.
17637 ;; Keeping with tradition, "6" is in honor of #UD.
17638 (define_insn "trap"
17639 [(trap_if (const_int 1) (const_int 6))]
17641 { return ASM_SHORT "0x0b0f"; }
17642 [(set_attr "length" "2")])
17644 (define_expand "prefetch"
17645 [(prefetch (match_operand 0 "address_operand" "")
17646 (match_operand:SI 1 "const_int_operand" "")
17647 (match_operand:SI 2 "const_int_operand" ""))]
17648 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17650 int rw = INTVAL (operands[1]);
17651 int locality = INTVAL (operands[2]);
17653 gcc_assert (rw == 0 || rw == 1);
17654 gcc_assert (locality >= 0 && locality <= 3);
17655 gcc_assert (GET_MODE (operands[0]) == Pmode
17656 || GET_MODE (operands[0]) == VOIDmode);
17658 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17659 supported by SSE counterpart or the SSE prefetch is not available
17660 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17662 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17663 operands[2] = GEN_INT (3);
17665 operands[1] = const0_rtx;
17668 (define_insn "*prefetch_sse_<mode>"
17669 [(prefetch (match_operand:P 0 "address_operand" "p")
17671 (match_operand:SI 1 "const_int_operand" ""))]
17672 "TARGET_PREFETCH_SSE"
17674 static const char * const patterns[4] = {
17675 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17678 int locality = INTVAL (operands[1]);
17679 gcc_assert (locality >= 0 && locality <= 3);
17681 return patterns[locality];
17683 [(set_attr "type" "sse")
17684 (set_attr "atom_sse_attr" "prefetch")
17685 (set (attr "length_address")
17686 (symbol_ref "memory_address_length (operands[0])"))
17687 (set_attr "memory" "none")])
17689 (define_insn "*prefetch_3dnow_<mode>"
17690 [(prefetch (match_operand:P 0 "address_operand" "p")
17691 (match_operand:SI 1 "const_int_operand" "n")
17695 if (INTVAL (operands[1]) == 0)
17696 return "prefetch\t%a0";
17698 return "prefetchw\t%a0";
17700 [(set_attr "type" "mmx")
17701 (set (attr "length_address")
17702 (symbol_ref "memory_address_length (operands[0])"))
17703 (set_attr "memory" "none")])
17705 (define_expand "stack_protect_set"
17706 [(match_operand 0 "memory_operand" "")
17707 (match_operand 1 "memory_operand" "")]
17710 rtx (*insn)(rtx, rtx);
17712 #ifdef TARGET_THREAD_SSP_OFFSET
17713 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17714 insn = (TARGET_LP64
17715 ? gen_stack_tls_protect_set_di
17716 : gen_stack_tls_protect_set_si);
17718 insn = (TARGET_LP64
17719 ? gen_stack_protect_set_di
17720 : gen_stack_protect_set_si);
17723 emit_insn (insn (operands[0], operands[1]));
17727 (define_insn "stack_protect_set_<mode>"
17728 [(set (match_operand:PTR 0 "memory_operand" "=m")
17729 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17731 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17732 (clobber (reg:CC FLAGS_REG))]
17734 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17735 [(set_attr "type" "multi")])
17737 (define_insn "stack_tls_protect_set_<mode>"
17738 [(set (match_operand:PTR 0 "memory_operand" "=m")
17739 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17740 UNSPEC_SP_TLS_SET))
17741 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17742 (clobber (reg:CC FLAGS_REG))]
17744 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17745 [(set_attr "type" "multi")])
17747 (define_expand "stack_protect_test"
17748 [(match_operand 0 "memory_operand" "")
17749 (match_operand 1 "memory_operand" "")
17750 (match_operand 2 "" "")]
17753 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17755 rtx (*insn)(rtx, rtx, rtx);
17757 #ifdef TARGET_THREAD_SSP_OFFSET
17758 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17759 insn = (TARGET_LP64
17760 ? gen_stack_tls_protect_test_di
17761 : gen_stack_tls_protect_test_si);
17763 insn = (TARGET_LP64
17764 ? gen_stack_protect_test_di
17765 : gen_stack_protect_test_si);
17768 emit_insn (insn (flags, operands[0], operands[1]));
17770 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17771 flags, const0_rtx, operands[2]));
17775 (define_insn "stack_protect_test_<mode>"
17776 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17777 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17778 (match_operand:PTR 2 "memory_operand" "m")]
17780 (clobber (match_scratch:PTR 3 "=&r"))]
17782 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17783 [(set_attr "type" "multi")])
17785 (define_insn "stack_tls_protect_test_<mode>"
17786 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17787 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17788 (match_operand:PTR 2 "const_int_operand" "i")]
17789 UNSPEC_SP_TLS_TEST))
17790 (clobber (match_scratch:PTR 3 "=r"))]
17792 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17793 [(set_attr "type" "multi")])
17795 (define_insn "sse4_2_crc32<mode>"
17796 [(set (match_operand:SI 0 "register_operand" "=r")
17798 [(match_operand:SI 1 "register_operand" "0")
17799 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17801 "TARGET_SSE4_2 || TARGET_CRC32"
17802 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17803 [(set_attr "type" "sselog1")
17804 (set_attr "prefix_rep" "1")
17805 (set_attr "prefix_extra" "1")
17806 (set (attr "prefix_data16")
17807 (if_then_else (match_operand:HI 2 "" "")
17809 (const_string "*")))
17810 (set (attr "prefix_rex")
17811 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17813 (const_string "*")))
17814 (set_attr "mode" "SI")])
17816 (define_insn "sse4_2_crc32di"
17817 [(set (match_operand:DI 0 "register_operand" "=r")
17819 [(match_operand:DI 1 "register_operand" "0")
17820 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17822 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17823 "crc32{q}\t{%2, %0|%0, %2}"
17824 [(set_attr "type" "sselog1")
17825 (set_attr "prefix_rep" "1")
17826 (set_attr "prefix_extra" "1")
17827 (set_attr "mode" "DI")])
17829 (define_expand "rdpmc"
17830 [(match_operand:DI 0 "register_operand" "")
17831 (match_operand:SI 1 "register_operand" "")]
17834 rtx reg = gen_reg_rtx (DImode);
17837 /* Force operand 1 into ECX. */
17838 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17839 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17840 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17845 rtvec vec = rtvec_alloc (2);
17846 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17847 rtx upper = gen_reg_rtx (DImode);
17848 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17849 gen_rtvec (1, const0_rtx),
17851 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17852 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17854 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17855 NULL, 1, OPTAB_DIRECT);
17856 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17860 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17861 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17865 (define_insn "*rdpmc"
17866 [(set (match_operand:DI 0 "register_operand" "=A")
17867 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17871 [(set_attr "type" "other")
17872 (set_attr "length" "2")])
17874 (define_insn "*rdpmc_rex64"
17875 [(set (match_operand:DI 0 "register_operand" "=a")
17876 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17878 (set (match_operand:DI 1 "register_operand" "=d")
17879 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17882 [(set_attr "type" "other")
17883 (set_attr "length" "2")])
17885 (define_expand "rdtsc"
17886 [(set (match_operand:DI 0 "register_operand" "")
17887 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17892 rtvec vec = rtvec_alloc (2);
17893 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17894 rtx upper = gen_reg_rtx (DImode);
17895 rtx lower = gen_reg_rtx (DImode);
17896 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17897 gen_rtvec (1, const0_rtx),
17899 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17900 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17902 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17903 NULL, 1, OPTAB_DIRECT);
17904 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17906 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17911 (define_insn "*rdtsc"
17912 [(set (match_operand:DI 0 "register_operand" "=A")
17913 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17916 [(set_attr "type" "other")
17917 (set_attr "length" "2")])
17919 (define_insn "*rdtsc_rex64"
17920 [(set (match_operand:DI 0 "register_operand" "=a")
17921 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17922 (set (match_operand:DI 1 "register_operand" "=d")
17923 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17926 [(set_attr "type" "other")
17927 (set_attr "length" "2")])
17929 (define_expand "rdtscp"
17930 [(match_operand:DI 0 "register_operand" "")
17931 (match_operand:SI 1 "memory_operand" "")]
17934 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17935 gen_rtvec (1, const0_rtx),
17937 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17938 gen_rtvec (1, const0_rtx),
17940 rtx reg = gen_reg_rtx (DImode);
17941 rtx tmp = gen_reg_rtx (SImode);
17945 rtvec vec = rtvec_alloc (3);
17946 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17947 rtx upper = gen_reg_rtx (DImode);
17948 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17949 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17950 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17952 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17953 NULL, 1, OPTAB_DIRECT);
17954 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17959 rtvec vec = rtvec_alloc (2);
17960 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17961 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17962 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17965 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17966 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17970 (define_insn "*rdtscp"
17971 [(set (match_operand:DI 0 "register_operand" "=A")
17972 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17973 (set (match_operand:SI 1 "register_operand" "=c")
17974 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17977 [(set_attr "type" "other")
17978 (set_attr "length" "3")])
17980 (define_insn "*rdtscp_rex64"
17981 [(set (match_operand:DI 0 "register_operand" "=a")
17982 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17983 (set (match_operand:DI 1 "register_operand" "=d")
17984 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17985 (set (match_operand:SI 2 "register_operand" "=c")
17986 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17989 [(set_attr "type" "other")
17990 (set_attr "length" "3")])
17992 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17994 ;; LWP instructions
17996 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17998 (define_expand "lwp_llwpcb"
17999 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18000 UNSPECV_LLWP_INTRINSIC)]
18003 (define_insn "*lwp_llwpcb<mode>1"
18004 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18005 UNSPECV_LLWP_INTRINSIC)]
18008 [(set_attr "type" "lwp")
18009 (set_attr "mode" "<MODE>")
18010 (set_attr "length" "5")])
18012 (define_expand "lwp_slwpcb"
18013 [(set (match_operand 0 "register_operand" "=r")
18014 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18019 insn = (TARGET_64BIT
18021 : gen_lwp_slwpcbsi);
18023 emit_insn (insn (operands[0]));
18027 (define_insn "lwp_slwpcb<mode>"
18028 [(set (match_operand:P 0 "register_operand" "=r")
18029 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18032 [(set_attr "type" "lwp")
18033 (set_attr "mode" "<MODE>")
18034 (set_attr "length" "5")])
18036 (define_expand "lwp_lwpval<mode>3"
18037 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18038 (match_operand:SI 2 "nonimmediate_operand" "rm")
18039 (match_operand:SI 3 "const_int_operand" "i")]
18040 UNSPECV_LWPVAL_INTRINSIC)]
18042 ;; Avoid unused variable warning.
18043 "(void) operands[0];")
18045 (define_insn "*lwp_lwpval<mode>3_1"
18046 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18047 (match_operand:SI 1 "nonimmediate_operand" "rm")
18048 (match_operand:SI 2 "const_int_operand" "i")]
18049 UNSPECV_LWPVAL_INTRINSIC)]
18051 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18052 [(set_attr "type" "lwp")
18053 (set_attr "mode" "<MODE>")
18054 (set (attr "length")
18055 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18057 (define_expand "lwp_lwpins<mode>3"
18058 [(set (reg:CCC FLAGS_REG)
18059 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18060 (match_operand:SI 2 "nonimmediate_operand" "rm")
18061 (match_operand:SI 3 "const_int_operand" "i")]
18062 UNSPECV_LWPINS_INTRINSIC))
18063 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18064 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18067 (define_insn "*lwp_lwpins<mode>3_1"
18068 [(set (reg:CCC FLAGS_REG)
18069 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18070 (match_operand:SI 1 "nonimmediate_operand" "rm")
18071 (match_operand:SI 2 "const_int_operand" "i")]
18072 UNSPECV_LWPINS_INTRINSIC))]
18074 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18075 [(set_attr "type" "lwp")
18076 (set_attr "mode" "<MODE>")
18077 (set (attr "length")
18078 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18080 (define_insn "rdfsbase<mode>"
18081 [(set (match_operand:SWI48 0 "register_operand" "=r")
18082 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18083 "TARGET_64BIT && TARGET_FSGSBASE"
18085 [(set_attr "type" "other")
18086 (set_attr "prefix_extra" "2")])
18088 (define_insn "rdgsbase<mode>"
18089 [(set (match_operand:SWI48 0 "register_operand" "=r")
18090 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18091 "TARGET_64BIT && TARGET_FSGSBASE"
18093 [(set_attr "type" "other")
18094 (set_attr "prefix_extra" "2")])
18096 (define_insn "wrfsbase<mode>"
18097 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18099 "TARGET_64BIT && TARGET_FSGSBASE"
18101 [(set_attr "type" "other")
18102 (set_attr "prefix_extra" "2")])
18104 (define_insn "wrgsbase<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 "rdrand<mode>_1"
18113 [(set (match_operand:SWI248 0 "register_operand" "=r")
18114 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18115 (set (reg:CCC FLAGS_REG)
18116 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18119 [(set_attr "type" "other")
18120 (set_attr "prefix_extra" "1")])
18122 (define_expand "pause"
18123 [(set (match_dup 0)
18124 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18127 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18128 MEM_VOLATILE_P (operands[0]) = 1;
18131 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18132 ;; They have the same encoding.
18133 (define_insn "*pause"
18134 [(set (match_operand:BLK 0 "" "")
18135 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18138 [(set_attr "length" "2")
18139 (set_attr "memory" "unknown")])
18143 (include "sync.md")