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,
633 (const_string "base"))
635 (define_attr "enabled" ""
636 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
637 (eq_attr "isa" "sse2_noavx")
638 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
639 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
640 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
641 (eq_attr "isa" "sse4_noavx")
642 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
643 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
644 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
645 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
646 (eq_attr "isa" "fma4") (symbol_ref "TARGET_FMA4")
647 (eq_attr "isa" "fma") (symbol_ref "TARGET_FMA")
651 ;; Describe a user's asm statement.
652 (define_asm_attributes
653 [(set_attr "length" "128")
654 (set_attr "type" "multi")])
656 (define_code_iterator plusminus [plus minus])
658 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
660 ;; Base name for define_insn
661 (define_code_attr plusminus_insn
662 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
663 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
665 ;; Base name for insn mnemonic.
666 (define_code_attr plusminus_mnemonic
667 [(plus "add") (ss_plus "adds") (us_plus "addus")
668 (minus "sub") (ss_minus "subs") (us_minus "subus")])
669 (define_code_attr plusminus_carry_mnemonic
670 [(plus "adc") (minus "sbb")])
672 ;; Mark commutative operators as such in constraints.
673 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
674 (minus "") (ss_minus "") (us_minus "")])
676 ;; Mapping of max and min
677 (define_code_iterator maxmin [smax smin umax umin])
679 ;; Mapping of signed max and min
680 (define_code_iterator smaxmin [smax smin])
682 ;; Mapping of unsigned max and min
683 (define_code_iterator umaxmin [umax umin])
685 ;; Base name for integer and FP insn mnemonic
686 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
687 (umax "maxu") (umin "minu")])
688 (define_code_attr maxmin_float [(smax "max") (smin "min")])
690 ;; Mapping of logic operators
691 (define_code_iterator any_logic [and ior xor])
692 (define_code_iterator any_or [ior xor])
694 ;; Base name for insn mnemonic.
695 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
697 ;; Mapping of logic-shift operators
698 (define_code_iterator any_lshift [ashift lshiftrt])
700 ;; Mapping of shift-right operators
701 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
703 ;; Base name for define_insn
704 (define_code_attr shift_insn
705 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
707 ;; Base name for insn mnemonic.
708 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
709 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
711 ;; Mapping of rotate operators
712 (define_code_iterator any_rotate [rotate rotatert])
714 ;; Base name for define_insn
715 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
717 ;; Base name for insn mnemonic.
718 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
720 ;; Mapping of abs neg operators
721 (define_code_iterator absneg [abs neg])
723 ;; Base name for x87 insn mnemonic.
724 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
726 ;; Used in signed and unsigned widening multiplications.
727 (define_code_iterator any_extend [sign_extend zero_extend])
729 ;; Prefix for insn menmonic.
730 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
732 ;; Prefix for define_insn
733 (define_code_attr u [(sign_extend "") (zero_extend "u")])
734 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
736 ;; All integer modes.
737 (define_mode_iterator SWI1248x [QI HI SI DI])
739 ;; All integer modes without QImode.
740 (define_mode_iterator SWI248x [HI SI DI])
742 ;; All integer modes without QImode and HImode.
743 (define_mode_iterator SWI48x [SI DI])
745 ;; All integer modes without SImode and DImode.
746 (define_mode_iterator SWI12 [QI HI])
748 ;; All integer modes without DImode.
749 (define_mode_iterator SWI124 [QI HI SI])
751 ;; All integer modes without QImode and DImode.
752 (define_mode_iterator SWI24 [HI SI])
754 ;; Single word integer modes.
755 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
757 ;; Single word integer modes without QImode.
758 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
760 ;; Single word integer modes without QImode and HImode.
761 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
763 ;; All math-dependant single and double word integer modes.
764 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
765 (HI "TARGET_HIMODE_MATH")
766 SI DI (TI "TARGET_64BIT")])
768 ;; Math-dependant single word integer modes.
769 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
770 (HI "TARGET_HIMODE_MATH")
771 SI (DI "TARGET_64BIT")])
773 ;; Math-dependant integer modes without DImode.
774 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
775 (HI "TARGET_HIMODE_MATH")
778 ;; Math-dependant single word integer modes without QImode.
779 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
780 SI (DI "TARGET_64BIT")])
782 ;; Double word integer modes.
783 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
784 (TI "TARGET_64BIT")])
786 ;; Double word integer modes as mode attribute.
787 (define_mode_attr DWI [(SI "DI") (DI "TI")])
788 (define_mode_attr dwi [(SI "di") (DI "ti")])
790 ;; Half mode for double word integer modes.
791 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
792 (DI "TARGET_64BIT")])
794 ;; Instruction suffix for integer modes.
795 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
797 ;; Pointer size prefix for integer modes (Intel asm dialect)
798 (define_mode_attr iptrsize [(QI "BYTE")
803 ;; Register class for integer modes.
804 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
806 ;; Immediate operand constraint for integer modes.
807 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
809 ;; General operand constraint for word modes.
810 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
812 ;; Immediate operand constraint for double integer modes.
813 (define_mode_attr di [(SI "nF") (DI "e")])
815 ;; Immediate operand constraint for shifts.
816 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
818 ;; General operand predicate for integer modes.
819 (define_mode_attr general_operand
820 [(QI "general_operand")
821 (HI "general_operand")
822 (SI "x86_64_general_operand")
823 (DI "x86_64_general_operand")
824 (TI "x86_64_general_operand")])
826 ;; General sign/zero extend operand predicate for integer modes.
827 (define_mode_attr general_szext_operand
828 [(QI "general_operand")
829 (HI "general_operand")
830 (SI "x86_64_szext_general_operand")
831 (DI "x86_64_szext_general_operand")])
833 ;; Immediate operand predicate for integer modes.
834 (define_mode_attr immediate_operand
835 [(QI "immediate_operand")
836 (HI "immediate_operand")
837 (SI "x86_64_immediate_operand")
838 (DI "x86_64_immediate_operand")])
840 ;; Nonmemory operand predicate for integer modes.
841 (define_mode_attr nonmemory_operand
842 [(QI "nonmemory_operand")
843 (HI "nonmemory_operand")
844 (SI "x86_64_nonmemory_operand")
845 (DI "x86_64_nonmemory_operand")])
847 ;; Operand predicate for shifts.
848 (define_mode_attr shift_operand
849 [(QI "nonimmediate_operand")
850 (HI "nonimmediate_operand")
851 (SI "nonimmediate_operand")
852 (DI "shiftdi_operand")
853 (TI "register_operand")])
855 ;; Operand predicate for shift argument.
856 (define_mode_attr shift_immediate_operand
857 [(QI "const_1_to_31_operand")
858 (HI "const_1_to_31_operand")
859 (SI "const_1_to_31_operand")
860 (DI "const_1_to_63_operand")])
862 ;; Input operand predicate for arithmetic left shifts.
863 (define_mode_attr ashl_input_operand
864 [(QI "nonimmediate_operand")
865 (HI "nonimmediate_operand")
866 (SI "nonimmediate_operand")
867 (DI "ashldi_input_operand")
868 (TI "reg_or_pm1_operand")])
870 ;; SSE and x87 SFmode and DFmode floating point modes
871 (define_mode_iterator MODEF [SF DF])
873 ;; All x87 floating point modes
874 (define_mode_iterator X87MODEF [SF DF XF])
876 ;; SSE instruction suffix for various modes
877 (define_mode_attr ssemodesuffix
879 (V8SF "ps") (V4DF "pd")
880 (V4SF "ps") (V2DF "pd")
881 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
882 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
884 ;; SSE vector suffix for floating point modes
885 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
887 ;; SSE vector mode corresponding to a scalar mode
888 (define_mode_attr ssevecmode
889 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
891 ;; Instruction suffix for REX 64bit operators.
892 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
894 ;; This mode iterator allows :P to be used for patterns that operate on
895 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
896 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
898 ;; This mode iterator allows :PTR to be used for patterns that operate on
899 ;; ptr_mode sized quantities.
900 (define_mode_iterator PTR
901 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
903 ;; Scheduling descriptions
905 (include "pentium.md")
908 (include "athlon.md")
909 (include "bdver1.md")
915 ;; Operand and operator predicates and constraints
917 (include "predicates.md")
918 (include "constraints.md")
921 ;; Compare and branch/compare and store instructions.
923 (define_expand "cbranch<mode>4"
924 [(set (reg:CC FLAGS_REG)
925 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
926 (match_operand:SDWIM 2 "<general_operand>" "")))
927 (set (pc) (if_then_else
928 (match_operator 0 "ordered_comparison_operator"
929 [(reg:CC FLAGS_REG) (const_int 0)])
930 (label_ref (match_operand 3 "" ""))
934 if (MEM_P (operands[1]) && MEM_P (operands[2]))
935 operands[1] = force_reg (<MODE>mode, operands[1]);
936 ix86_expand_branch (GET_CODE (operands[0]),
937 operands[1], operands[2], operands[3]);
941 (define_expand "cstore<mode>4"
942 [(set (reg:CC FLAGS_REG)
943 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
944 (match_operand:SWIM 3 "<general_operand>" "")))
945 (set (match_operand:QI 0 "register_operand" "")
946 (match_operator 1 "ordered_comparison_operator"
947 [(reg:CC FLAGS_REG) (const_int 0)]))]
950 if (MEM_P (operands[2]) && MEM_P (operands[3]))
951 operands[2] = force_reg (<MODE>mode, operands[2]);
952 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
953 operands[2], operands[3]);
957 (define_expand "cmp<mode>_1"
958 [(set (reg:CC FLAGS_REG)
959 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
960 (match_operand:SWI48 1 "<general_operand>" "")))])
962 (define_insn "*cmp<mode>_ccno_1"
963 [(set (reg FLAGS_REG)
964 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
965 (match_operand:SWI 1 "const0_operand" "")))]
966 "ix86_match_ccmode (insn, CCNOmode)"
968 test{<imodesuffix>}\t%0, %0
969 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
970 [(set_attr "type" "test,icmp")
971 (set_attr "length_immediate" "0,1")
972 (set_attr "mode" "<MODE>")])
974 (define_insn "*cmp<mode>_1"
975 [(set (reg FLAGS_REG)
976 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
977 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
978 "ix86_match_ccmode (insn, CCmode)"
979 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
980 [(set_attr "type" "icmp")
981 (set_attr "mode" "<MODE>")])
983 (define_insn "*cmp<mode>_minus_1"
984 [(set (reg FLAGS_REG)
986 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
987 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
989 "ix86_match_ccmode (insn, CCGOCmode)"
990 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
991 [(set_attr "type" "icmp")
992 (set_attr "mode" "<MODE>")])
994 (define_insn "*cmpqi_ext_1"
995 [(set (reg FLAGS_REG)
997 (match_operand:QI 0 "general_operand" "Qm")
1000 (match_operand 1 "ext_register_operand" "Q")
1002 (const_int 8)) 0)))]
1003 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1004 "cmp{b}\t{%h1, %0|%0, %h1}"
1005 [(set_attr "type" "icmp")
1006 (set_attr "mode" "QI")])
1008 (define_insn "*cmpqi_ext_1_rex64"
1009 [(set (reg FLAGS_REG)
1011 (match_operand:QI 0 "register_operand" "Q")
1014 (match_operand 1 "ext_register_operand" "Q")
1016 (const_int 8)) 0)))]
1017 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1018 "cmp{b}\t{%h1, %0|%0, %h1}"
1019 [(set_attr "type" "icmp")
1020 (set_attr "mode" "QI")])
1022 (define_insn "*cmpqi_ext_2"
1023 [(set (reg FLAGS_REG)
1027 (match_operand 0 "ext_register_operand" "Q")
1030 (match_operand:QI 1 "const0_operand" "")))]
1031 "ix86_match_ccmode (insn, CCNOmode)"
1033 [(set_attr "type" "test")
1034 (set_attr "length_immediate" "0")
1035 (set_attr "mode" "QI")])
1037 (define_expand "cmpqi_ext_3"
1038 [(set (reg:CC FLAGS_REG)
1042 (match_operand 0 "ext_register_operand" "")
1045 (match_operand:QI 1 "immediate_operand" "")))])
1047 (define_insn "*cmpqi_ext_3_insn"
1048 [(set (reg FLAGS_REG)
1052 (match_operand 0 "ext_register_operand" "Q")
1055 (match_operand:QI 1 "general_operand" "Qmn")))]
1056 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1057 "cmp{b}\t{%1, %h0|%h0, %1}"
1058 [(set_attr "type" "icmp")
1059 (set_attr "modrm" "1")
1060 (set_attr "mode" "QI")])
1062 (define_insn "*cmpqi_ext_3_insn_rex64"
1063 [(set (reg FLAGS_REG)
1067 (match_operand 0 "ext_register_operand" "Q")
1070 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1071 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1072 "cmp{b}\t{%1, %h0|%h0, %1}"
1073 [(set_attr "type" "icmp")
1074 (set_attr "modrm" "1")
1075 (set_attr "mode" "QI")])
1077 (define_insn "*cmpqi_ext_4"
1078 [(set (reg FLAGS_REG)
1082 (match_operand 0 "ext_register_operand" "Q")
1087 (match_operand 1 "ext_register_operand" "Q")
1089 (const_int 8)) 0)))]
1090 "ix86_match_ccmode (insn, CCmode)"
1091 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1092 [(set_attr "type" "icmp")
1093 (set_attr "mode" "QI")])
1095 ;; These implement float point compares.
1096 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1097 ;; which would allow mix and match FP modes on the compares. Which is what
1098 ;; the old patterns did, but with many more of them.
1100 (define_expand "cbranchxf4"
1101 [(set (reg:CC FLAGS_REG)
1102 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1103 (match_operand:XF 2 "nonmemory_operand" "")))
1104 (set (pc) (if_then_else
1105 (match_operator 0 "ix86_fp_comparison_operator"
1108 (label_ref (match_operand 3 "" ""))
1112 ix86_expand_branch (GET_CODE (operands[0]),
1113 operands[1], operands[2], operands[3]);
1117 (define_expand "cstorexf4"
1118 [(set (reg:CC FLAGS_REG)
1119 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1120 (match_operand:XF 3 "nonmemory_operand" "")))
1121 (set (match_operand:QI 0 "register_operand" "")
1122 (match_operator 1 "ix86_fp_comparison_operator"
1127 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1128 operands[2], operands[3]);
1132 (define_expand "cbranch<mode>4"
1133 [(set (reg:CC FLAGS_REG)
1134 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1135 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1136 (set (pc) (if_then_else
1137 (match_operator 0 "ix86_fp_comparison_operator"
1140 (label_ref (match_operand 3 "" ""))
1142 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1144 ix86_expand_branch (GET_CODE (operands[0]),
1145 operands[1], operands[2], operands[3]);
1149 (define_expand "cstore<mode>4"
1150 [(set (reg:CC FLAGS_REG)
1151 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1152 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1153 (set (match_operand:QI 0 "register_operand" "")
1154 (match_operator 1 "ix86_fp_comparison_operator"
1157 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1159 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1160 operands[2], operands[3]);
1164 (define_expand "cbranchcc4"
1165 [(set (pc) (if_then_else
1166 (match_operator 0 "comparison_operator"
1167 [(match_operand 1 "flags_reg_operand" "")
1168 (match_operand 2 "const0_operand" "")])
1169 (label_ref (match_operand 3 "" ""))
1173 ix86_expand_branch (GET_CODE (operands[0]),
1174 operands[1], operands[2], operands[3]);
1178 (define_expand "cstorecc4"
1179 [(set (match_operand:QI 0 "register_operand" "")
1180 (match_operator 1 "comparison_operator"
1181 [(match_operand 2 "flags_reg_operand" "")
1182 (match_operand 3 "const0_operand" "")]))]
1185 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1186 operands[2], operands[3]);
1191 ;; FP compares, step 1:
1192 ;; Set the FP condition codes.
1194 ;; CCFPmode compare with exceptions
1195 ;; CCFPUmode compare with no exceptions
1197 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1198 ;; used to manage the reg stack popping would not be preserved.
1200 (define_insn "*cmpfp_0"
1201 [(set (match_operand:HI 0 "register_operand" "=a")
1204 (match_operand 1 "register_operand" "f")
1205 (match_operand 2 "const0_operand" ""))]
1207 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1208 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1209 "* return output_fp_compare (insn, operands, false, false);"
1210 [(set_attr "type" "multi")
1211 (set_attr "unit" "i387")
1213 (cond [(match_operand:SF 1 "" "")
1215 (match_operand:DF 1 "" "")
1218 (const_string "XF")))])
1220 (define_insn_and_split "*cmpfp_0_cc"
1221 [(set (reg:CCFP FLAGS_REG)
1223 (match_operand 1 "register_operand" "f")
1224 (match_operand 2 "const0_operand" "")))
1225 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1226 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1227 && TARGET_SAHF && !TARGET_CMOVE
1228 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1230 "&& reload_completed"
1233 [(compare:CCFP (match_dup 1)(match_dup 2))]
1235 (set (reg:CC FLAGS_REG)
1236 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1238 [(set_attr "type" "multi")
1239 (set_attr "unit" "i387")
1241 (cond [(match_operand:SF 1 "" "")
1243 (match_operand:DF 1 "" "")
1246 (const_string "XF")))])
1248 (define_insn "*cmpfp_xf"
1249 [(set (match_operand:HI 0 "register_operand" "=a")
1252 (match_operand:XF 1 "register_operand" "f")
1253 (match_operand:XF 2 "register_operand" "f"))]
1256 "* return output_fp_compare (insn, operands, false, false);"
1257 [(set_attr "type" "multi")
1258 (set_attr "unit" "i387")
1259 (set_attr "mode" "XF")])
1261 (define_insn_and_split "*cmpfp_xf_cc"
1262 [(set (reg:CCFP FLAGS_REG)
1264 (match_operand:XF 1 "register_operand" "f")
1265 (match_operand:XF 2 "register_operand" "f")))
1266 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1268 && TARGET_SAHF && !TARGET_CMOVE"
1270 "&& reload_completed"
1273 [(compare:CCFP (match_dup 1)(match_dup 2))]
1275 (set (reg:CC FLAGS_REG)
1276 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1278 [(set_attr "type" "multi")
1279 (set_attr "unit" "i387")
1280 (set_attr "mode" "XF")])
1282 (define_insn "*cmpfp_<mode>"
1283 [(set (match_operand:HI 0 "register_operand" "=a")
1286 (match_operand:MODEF 1 "register_operand" "f")
1287 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1290 "* return output_fp_compare (insn, operands, false, false);"
1291 [(set_attr "type" "multi")
1292 (set_attr "unit" "i387")
1293 (set_attr "mode" "<MODE>")])
1295 (define_insn_and_split "*cmpfp_<mode>_cc"
1296 [(set (reg:CCFP FLAGS_REG)
1298 (match_operand:MODEF 1 "register_operand" "f")
1299 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1300 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1302 && TARGET_SAHF && !TARGET_CMOVE"
1304 "&& reload_completed"
1307 [(compare:CCFP (match_dup 1)(match_dup 2))]
1309 (set (reg:CC FLAGS_REG)
1310 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1312 [(set_attr "type" "multi")
1313 (set_attr "unit" "i387")
1314 (set_attr "mode" "<MODE>")])
1316 (define_insn "*cmpfp_u"
1317 [(set (match_operand:HI 0 "register_operand" "=a")
1320 (match_operand 1 "register_operand" "f")
1321 (match_operand 2 "register_operand" "f"))]
1323 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1324 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1325 "* return output_fp_compare (insn, operands, false, true);"
1326 [(set_attr "type" "multi")
1327 (set_attr "unit" "i387")
1329 (cond [(match_operand:SF 1 "" "")
1331 (match_operand:DF 1 "" "")
1334 (const_string "XF")))])
1336 (define_insn_and_split "*cmpfp_u_cc"
1337 [(set (reg:CCFPU FLAGS_REG)
1339 (match_operand 1 "register_operand" "f")
1340 (match_operand 2 "register_operand" "f")))
1341 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1342 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1343 && TARGET_SAHF && !TARGET_CMOVE
1344 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1346 "&& reload_completed"
1349 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1351 (set (reg:CC FLAGS_REG)
1352 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1354 [(set_attr "type" "multi")
1355 (set_attr "unit" "i387")
1357 (cond [(match_operand:SF 1 "" "")
1359 (match_operand:DF 1 "" "")
1362 (const_string "XF")))])
1364 (define_insn "*cmpfp_<mode>"
1365 [(set (match_operand:HI 0 "register_operand" "=a")
1368 (match_operand 1 "register_operand" "f")
1369 (match_operator 3 "float_operator"
1370 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1372 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1373 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1374 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1375 "* return output_fp_compare (insn, operands, false, false);"
1376 [(set_attr "type" "multi")
1377 (set_attr "unit" "i387")
1378 (set_attr "fp_int_src" "true")
1379 (set_attr "mode" "<MODE>")])
1381 (define_insn_and_split "*cmpfp_<mode>_cc"
1382 [(set (reg:CCFP FLAGS_REG)
1384 (match_operand 1 "register_operand" "f")
1385 (match_operator 3 "float_operator"
1386 [(match_operand:SWI24 2 "memory_operand" "m")])))
1387 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1388 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1389 && TARGET_SAHF && !TARGET_CMOVE
1390 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1391 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1393 "&& reload_completed"
1398 (match_op_dup 3 [(match_dup 2)]))]
1400 (set (reg:CC FLAGS_REG)
1401 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1403 [(set_attr "type" "multi")
1404 (set_attr "unit" "i387")
1405 (set_attr "fp_int_src" "true")
1406 (set_attr "mode" "<MODE>")])
1408 ;; FP compares, step 2
1409 ;; Move the fpsw to ax.
1411 (define_insn "x86_fnstsw_1"
1412 [(set (match_operand:HI 0 "register_operand" "=a")
1413 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1416 [(set (attr "length")
1417 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1418 (set_attr "mode" "SI")
1419 (set_attr "unit" "i387")])
1421 ;; FP compares, step 3
1422 ;; Get ax into flags, general case.
1424 (define_insn "x86_sahf_1"
1425 [(set (reg:CC FLAGS_REG)
1426 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1430 #ifndef HAVE_AS_IX86_SAHF
1432 return ASM_BYTE "0x9e";
1437 [(set_attr "length" "1")
1438 (set_attr "athlon_decode" "vector")
1439 (set_attr "amdfam10_decode" "direct")
1440 (set_attr "bdver1_decode" "direct")
1441 (set_attr "mode" "SI")])
1443 ;; Pentium Pro can do steps 1 through 3 in one go.
1444 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1445 ;; (these i387 instructions set flags directly)
1446 (define_insn "*cmpfp_i_mixed"
1447 [(set (reg:CCFP FLAGS_REG)
1448 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1449 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1450 "TARGET_MIX_SSE_I387
1451 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1452 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1453 "* return output_fp_compare (insn, operands, true, false);"
1454 [(set_attr "type" "fcmp,ssecomi")
1455 (set_attr "prefix" "orig,maybe_vex")
1457 (if_then_else (match_operand:SF 1 "" "")
1459 (const_string "DF")))
1460 (set (attr "prefix_rep")
1461 (if_then_else (eq_attr "type" "ssecomi")
1463 (const_string "*")))
1464 (set (attr "prefix_data16")
1465 (cond [(eq_attr "type" "fcmp")
1467 (eq_attr "mode" "DF")
1470 (const_string "0")))
1471 (set_attr "athlon_decode" "vector")
1472 (set_attr "amdfam10_decode" "direct")
1473 (set_attr "bdver1_decode" "double")])
1475 (define_insn "*cmpfp_i_sse"
1476 [(set (reg:CCFP FLAGS_REG)
1477 (compare:CCFP (match_operand 0 "register_operand" "x")
1478 (match_operand 1 "nonimmediate_operand" "xm")))]
1480 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1481 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1482 "* return output_fp_compare (insn, operands, true, false);"
1483 [(set_attr "type" "ssecomi")
1484 (set_attr "prefix" "maybe_vex")
1486 (if_then_else (match_operand:SF 1 "" "")
1488 (const_string "DF")))
1489 (set_attr "prefix_rep" "0")
1490 (set (attr "prefix_data16")
1491 (if_then_else (eq_attr "mode" "DF")
1493 (const_string "0")))
1494 (set_attr "athlon_decode" "vector")
1495 (set_attr "amdfam10_decode" "direct")
1496 (set_attr "bdver1_decode" "double")])
1498 (define_insn "*cmpfp_i_i387"
1499 [(set (reg:CCFP FLAGS_REG)
1500 (compare:CCFP (match_operand 0 "register_operand" "f")
1501 (match_operand 1 "register_operand" "f")))]
1502 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1504 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1505 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1506 "* return output_fp_compare (insn, operands, true, false);"
1507 [(set_attr "type" "fcmp")
1509 (cond [(match_operand:SF 1 "" "")
1511 (match_operand:DF 1 "" "")
1514 (const_string "XF")))
1515 (set_attr "athlon_decode" "vector")
1516 (set_attr "amdfam10_decode" "direct")
1517 (set_attr "bdver1_decode" "double")])
1519 (define_insn "*cmpfp_iu_mixed"
1520 [(set (reg:CCFPU FLAGS_REG)
1521 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1522 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1523 "TARGET_MIX_SSE_I387
1524 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1525 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1526 "* return output_fp_compare (insn, operands, true, true);"
1527 [(set_attr "type" "fcmp,ssecomi")
1528 (set_attr "prefix" "orig,maybe_vex")
1530 (if_then_else (match_operand:SF 1 "" "")
1532 (const_string "DF")))
1533 (set (attr "prefix_rep")
1534 (if_then_else (eq_attr "type" "ssecomi")
1536 (const_string "*")))
1537 (set (attr "prefix_data16")
1538 (cond [(eq_attr "type" "fcmp")
1540 (eq_attr "mode" "DF")
1543 (const_string "0")))
1544 (set_attr "athlon_decode" "vector")
1545 (set_attr "amdfam10_decode" "direct")
1546 (set_attr "bdver1_decode" "double")])
1548 (define_insn "*cmpfp_iu_sse"
1549 [(set (reg:CCFPU FLAGS_REG)
1550 (compare:CCFPU (match_operand 0 "register_operand" "x")
1551 (match_operand 1 "nonimmediate_operand" "xm")))]
1553 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1554 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1555 "* return output_fp_compare (insn, operands, true, true);"
1556 [(set_attr "type" "ssecomi")
1557 (set_attr "prefix" "maybe_vex")
1559 (if_then_else (match_operand:SF 1 "" "")
1561 (const_string "DF")))
1562 (set_attr "prefix_rep" "0")
1563 (set (attr "prefix_data16")
1564 (if_then_else (eq_attr "mode" "DF")
1566 (const_string "0")))
1567 (set_attr "athlon_decode" "vector")
1568 (set_attr "amdfam10_decode" "direct")
1569 (set_attr "bdver1_decode" "double")])
1571 (define_insn "*cmpfp_iu_387"
1572 [(set (reg:CCFPU FLAGS_REG)
1573 (compare:CCFPU (match_operand 0 "register_operand" "f")
1574 (match_operand 1 "register_operand" "f")))]
1575 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1577 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1578 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1579 "* return output_fp_compare (insn, operands, true, true);"
1580 [(set_attr "type" "fcmp")
1582 (cond [(match_operand:SF 1 "" "")
1584 (match_operand:DF 1 "" "")
1587 (const_string "XF")))
1588 (set_attr "athlon_decode" "vector")
1589 (set_attr "amdfam10_decode" "direct")
1590 (set_attr "bdver1_decode" "direct")])
1592 ;; Push/pop instructions.
1594 (define_insn "*push<mode>2"
1595 [(set (match_operand:DWI 0 "push_operand" "=<")
1596 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1599 [(set_attr "type" "multi")
1600 (set_attr "mode" "<MODE>")])
1603 [(set (match_operand:TI 0 "push_operand" "")
1604 (match_operand:TI 1 "general_operand" ""))]
1605 "TARGET_64BIT && reload_completed
1606 && !SSE_REG_P (operands[1])"
1608 "ix86_split_long_move (operands); DONE;")
1610 (define_insn "*pushdi2_rex64"
1611 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1612 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1617 [(set_attr "type" "push,multi")
1618 (set_attr "mode" "DI")])
1620 ;; Convert impossible pushes of immediate to existing instructions.
1621 ;; First try to get scratch register and go through it. In case this
1622 ;; fails, push sign extended lower part first and then overwrite
1623 ;; upper part by 32bit move.
1625 [(match_scratch:DI 2 "r")
1626 (set (match_operand:DI 0 "push_operand" "")
1627 (match_operand:DI 1 "immediate_operand" ""))]
1628 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1629 && !x86_64_immediate_operand (operands[1], DImode)"
1630 [(set (match_dup 2) (match_dup 1))
1631 (set (match_dup 0) (match_dup 2))])
1633 ;; We need to define this as both peepholer and splitter for case
1634 ;; peephole2 pass is not run.
1635 ;; "&& 1" is needed to keep it from matching the previous pattern.
1637 [(set (match_operand:DI 0 "push_operand" "")
1638 (match_operand:DI 1 "immediate_operand" ""))]
1639 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1640 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1641 [(set (match_dup 0) (match_dup 1))
1642 (set (match_dup 2) (match_dup 3))]
1644 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1646 operands[1] = gen_lowpart (DImode, operands[2]);
1647 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1652 [(set (match_operand:DI 0 "push_operand" "")
1653 (match_operand:DI 1 "immediate_operand" ""))]
1654 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1655 ? epilogue_completed : reload_completed)
1656 && !symbolic_operand (operands[1], DImode)
1657 && !x86_64_immediate_operand (operands[1], DImode)"
1658 [(set (match_dup 0) (match_dup 1))
1659 (set (match_dup 2) (match_dup 3))]
1661 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1663 operands[1] = gen_lowpart (DImode, operands[2]);
1664 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1669 [(set (match_operand:DI 0 "push_operand" "")
1670 (match_operand:DI 1 "general_operand" ""))]
1671 "!TARGET_64BIT && reload_completed
1672 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1674 "ix86_split_long_move (operands); DONE;")
1676 (define_insn "*pushsi2"
1677 [(set (match_operand:SI 0 "push_operand" "=<")
1678 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1681 [(set_attr "type" "push")
1682 (set_attr "mode" "SI")])
1684 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1685 ;; "push a byte/word". But actually we use pushl, which has the effect
1686 ;; of rounding the amount pushed up to a word.
1688 ;; For TARGET_64BIT we always round up to 8 bytes.
1689 (define_insn "*push<mode>2_rex64"
1690 [(set (match_operand:SWI124 0 "push_operand" "=X")
1691 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1694 [(set_attr "type" "push")
1695 (set_attr "mode" "DI")])
1697 (define_insn "*push<mode>2"
1698 [(set (match_operand:SWI12 0 "push_operand" "=X")
1699 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1702 [(set_attr "type" "push")
1703 (set_attr "mode" "SI")])
1705 (define_insn "*push<mode>2_prologue"
1706 [(set (match_operand:P 0 "push_operand" "=<")
1707 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1708 (clobber (mem:BLK (scratch)))]
1710 "push{<imodesuffix>}\t%1"
1711 [(set_attr "type" "push")
1712 (set_attr "mode" "<MODE>")])
1714 (define_insn "*pop<mode>1"
1715 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1716 (match_operand:P 1 "pop_operand" ">"))]
1718 "pop{<imodesuffix>}\t%0"
1719 [(set_attr "type" "pop")
1720 (set_attr "mode" "<MODE>")])
1722 (define_insn "*pop<mode>1_epilogue"
1723 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1724 (match_operand:P 1 "pop_operand" ">"))
1725 (clobber (mem:BLK (scratch)))]
1727 "pop{<imodesuffix>}\t%0"
1728 [(set_attr "type" "pop")
1729 (set_attr "mode" "<MODE>")])
1731 ;; Move instructions.
1733 (define_expand "movoi"
1734 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1735 (match_operand:OI 1 "general_operand" ""))]
1737 "ix86_expand_move (OImode, operands); DONE;")
1739 (define_expand "movti"
1740 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1741 (match_operand:TI 1 "nonimmediate_operand" ""))]
1742 "TARGET_64BIT || TARGET_SSE"
1745 ix86_expand_move (TImode, operands);
1746 else if (push_operand (operands[0], TImode))
1747 ix86_expand_push (TImode, operands[1]);
1749 ix86_expand_vector_move (TImode, operands);
1753 ;; This expands to what emit_move_complex would generate if we didn't
1754 ;; have a movti pattern. Having this avoids problems with reload on
1755 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1756 ;; to have around all the time.
1757 (define_expand "movcdi"
1758 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1759 (match_operand:CDI 1 "general_operand" ""))]
1762 if (push_operand (operands[0], CDImode))
1763 emit_move_complex_push (CDImode, operands[0], operands[1]);
1765 emit_move_complex_parts (operands[0], operands[1]);
1769 (define_expand "mov<mode>"
1770 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1771 (match_operand:SWI1248x 1 "general_operand" ""))]
1773 "ix86_expand_move (<MODE>mode, operands); DONE;")
1775 (define_insn "*mov<mode>_xor"
1776 [(set (match_operand:SWI48 0 "register_operand" "=r")
1777 (match_operand:SWI48 1 "const0_operand" ""))
1778 (clobber (reg:CC FLAGS_REG))]
1781 [(set_attr "type" "alu1")
1782 (set_attr "mode" "SI")
1783 (set_attr "length_immediate" "0")])
1785 (define_insn "*mov<mode>_or"
1786 [(set (match_operand:SWI48 0 "register_operand" "=r")
1787 (match_operand:SWI48 1 "const_int_operand" ""))
1788 (clobber (reg:CC FLAGS_REG))]
1790 && operands[1] == constm1_rtx"
1791 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1792 [(set_attr "type" "alu1")
1793 (set_attr "mode" "<MODE>")
1794 (set_attr "length_immediate" "1")])
1796 (define_insn "*movoi_internal_avx"
1797 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1798 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1799 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1801 switch (which_alternative)
1804 return standard_sse_constant_opcode (insn, operands[1]);
1807 if (misaligned_operand (operands[0], OImode)
1808 || misaligned_operand (operands[1], OImode))
1809 return "vmovdqu\t{%1, %0|%0, %1}";
1811 return "vmovdqa\t{%1, %0|%0, %1}";
1816 [(set_attr "type" "sselog1,ssemov,ssemov")
1817 (set_attr "prefix" "vex")
1818 (set_attr "mode" "OI")])
1820 (define_insn "*movti_internal_rex64"
1821 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1822 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1823 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1825 switch (which_alternative)
1831 return standard_sse_constant_opcode (insn, operands[1]);
1834 /* TDmode values are passed as TImode on the stack. Moving them
1835 to stack may result in unaligned memory access. */
1836 if (misaligned_operand (operands[0], TImode)
1837 || misaligned_operand (operands[1], TImode))
1839 if (get_attr_mode (insn) == MODE_V4SF)
1840 return "%vmovups\t{%1, %0|%0, %1}";
1842 return "%vmovdqu\t{%1, %0|%0, %1}";
1846 if (get_attr_mode (insn) == MODE_V4SF)
1847 return "%vmovaps\t{%1, %0|%0, %1}";
1849 return "%vmovdqa\t{%1, %0|%0, %1}";
1855 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1856 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1858 (cond [(eq_attr "alternative" "2,3")
1860 (match_test "optimize_function_for_size_p (cfun)")
1861 (const_string "V4SF")
1862 (const_string "TI"))
1863 (eq_attr "alternative" "4")
1865 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1866 (match_test "optimize_function_for_size_p (cfun)"))
1867 (const_string "V4SF")
1868 (const_string "TI"))]
1869 (const_string "DI")))])
1872 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1873 (match_operand:TI 1 "general_operand" ""))]
1875 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1877 "ix86_split_long_move (operands); DONE;")
1879 (define_insn "*movti_internal_sse"
1880 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1881 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1882 "TARGET_SSE && !TARGET_64BIT
1883 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1885 switch (which_alternative)
1888 return standard_sse_constant_opcode (insn, operands[1]);
1891 /* TDmode values are passed as TImode on the stack. Moving them
1892 to stack may result in unaligned memory access. */
1893 if (misaligned_operand (operands[0], TImode)
1894 || misaligned_operand (operands[1], TImode))
1896 if (get_attr_mode (insn) == MODE_V4SF)
1897 return "%vmovups\t{%1, %0|%0, %1}";
1899 return "%vmovdqu\t{%1, %0|%0, %1}";
1903 if (get_attr_mode (insn) == MODE_V4SF)
1904 return "%vmovaps\t{%1, %0|%0, %1}";
1906 return "%vmovdqa\t{%1, %0|%0, %1}";
1912 [(set_attr "type" "sselog1,ssemov,ssemov")
1913 (set_attr "prefix" "maybe_vex")
1915 (cond [(ior (not (match_test "TARGET_SSE2"))
1916 (match_test "optimize_function_for_size_p (cfun)"))
1917 (const_string "V4SF")
1918 (and (eq_attr "alternative" "2")
1919 (match_test "TARGET_SSE_TYPELESS_STORES"))
1920 (const_string "V4SF")]
1921 (const_string "TI")))])
1923 (define_insn "*movdi_internal_rex64"
1924 [(set (match_operand:DI 0 "nonimmediate_operand"
1925 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1926 (match_operand:DI 1 "general_operand"
1927 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1928 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1930 switch (get_attr_type (insn))
1933 if (SSE_REG_P (operands[0]))
1934 return "movq2dq\t{%1, %0|%0, %1}";
1936 return "movdq2q\t{%1, %0|%0, %1}";
1939 if (get_attr_mode (insn) == MODE_TI)
1940 return "%vmovdqa\t{%1, %0|%0, %1}";
1941 /* Handle broken assemblers that require movd instead of movq. */
1942 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1943 return "%vmovd\t{%1, %0|%0, %1}";
1945 return "%vmovq\t{%1, %0|%0, %1}";
1948 /* Handle broken assemblers that require movd instead of movq. */
1949 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1950 return "movd\t{%1, %0|%0, %1}";
1952 return "movq\t{%1, %0|%0, %1}";
1955 return standard_sse_constant_opcode (insn, operands[1]);
1958 return "pxor\t%0, %0";
1964 return "lea{q}\t{%E1, %0|%0, %E1}";
1967 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1968 if (get_attr_mode (insn) == MODE_SI)
1969 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1970 else if (which_alternative == 2)
1971 return "movabs{q}\t{%1, %0|%0, %1}";
1972 else if (ix86_use_lea_for_mov (insn, operands))
1973 return "lea{q}\t{%E1, %0|%0, %E1}";
1975 return "mov{q}\t{%1, %0|%0, %1}";
1979 (cond [(eq_attr "alternative" "4")
1980 (const_string "multi")
1981 (eq_attr "alternative" "5")
1982 (const_string "mmx")
1983 (eq_attr "alternative" "6,7,8,9")
1984 (const_string "mmxmov")
1985 (eq_attr "alternative" "10")
1986 (const_string "sselog1")
1987 (eq_attr "alternative" "11,12,13,14,15")
1988 (const_string "ssemov")
1989 (eq_attr "alternative" "16,17")
1990 (const_string "ssecvt")
1991 (match_operand 1 "pic_32bit_operand" "")
1992 (const_string "lea")
1994 (const_string "imov")))
1997 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1999 (const_string "*")))
2000 (set (attr "length_immediate")
2002 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2004 (const_string "*")))
2005 (set (attr "prefix_rex")
2006 (if_then_else (eq_attr "alternative" "8,9")
2008 (const_string "*")))
2009 (set (attr "prefix_data16")
2010 (if_then_else (eq_attr "alternative" "11")
2012 (const_string "*")))
2013 (set (attr "prefix")
2014 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2015 (const_string "maybe_vex")
2016 (const_string "orig")))
2017 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2019 ;; Reload patterns to support multi-word load/store
2020 ;; with non-offsetable address.
2021 (define_expand "reload_noff_store"
2022 [(parallel [(match_operand 0 "memory_operand" "=m")
2023 (match_operand 1 "register_operand" "r")
2024 (match_operand:DI 2 "register_operand" "=&r")])]
2027 rtx mem = operands[0];
2028 rtx addr = XEXP (mem, 0);
2030 emit_move_insn (operands[2], addr);
2031 mem = replace_equiv_address_nv (mem, operands[2]);
2033 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2037 (define_expand "reload_noff_load"
2038 [(parallel [(match_operand 0 "register_operand" "=r")
2039 (match_operand 1 "memory_operand" "m")
2040 (match_operand:DI 2 "register_operand" "=r")])]
2043 rtx mem = operands[1];
2044 rtx addr = XEXP (mem, 0);
2046 emit_move_insn (operands[2], addr);
2047 mem = replace_equiv_address_nv (mem, operands[2]);
2049 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2053 ;; Convert impossible stores of immediate to existing instructions.
2054 ;; First try to get scratch register and go through it. In case this
2055 ;; fails, move by 32bit parts.
2057 [(match_scratch:DI 2 "r")
2058 (set (match_operand:DI 0 "memory_operand" "")
2059 (match_operand:DI 1 "immediate_operand" ""))]
2060 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2061 && !x86_64_immediate_operand (operands[1], DImode)"
2062 [(set (match_dup 2) (match_dup 1))
2063 (set (match_dup 0) (match_dup 2))])
2065 ;; We need to define this as both peepholer and splitter for case
2066 ;; peephole2 pass is not run.
2067 ;; "&& 1" is needed to keep it from matching the previous pattern.
2069 [(set (match_operand:DI 0 "memory_operand" "")
2070 (match_operand:DI 1 "immediate_operand" ""))]
2071 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2072 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2073 [(set (match_dup 2) (match_dup 3))
2074 (set (match_dup 4) (match_dup 5))]
2075 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2078 [(set (match_operand:DI 0 "memory_operand" "")
2079 (match_operand:DI 1 "immediate_operand" ""))]
2080 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2081 ? epilogue_completed : reload_completed)
2082 && !symbolic_operand (operands[1], DImode)
2083 && !x86_64_immediate_operand (operands[1], DImode)"
2084 [(set (match_dup 2) (match_dup 3))
2085 (set (match_dup 4) (match_dup 5))]
2086 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2088 (define_insn "*movdi_internal"
2089 [(set (match_operand:DI 0 "nonimmediate_operand"
2090 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2091 (match_operand:DI 1 "general_operand"
2092 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2093 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2095 switch (get_attr_type (insn))
2098 if (SSE_REG_P (operands[0]))
2099 return "movq2dq\t{%1, %0|%0, %1}";
2101 return "movdq2q\t{%1, %0|%0, %1}";
2104 switch (get_attr_mode (insn))
2107 return "%vmovdqa\t{%1, %0|%0, %1}";
2109 return "%vmovq\t{%1, %0|%0, %1}";
2111 return "movaps\t{%1, %0|%0, %1}";
2113 return "movlps\t{%1, %0|%0, %1}";
2119 return "movq\t{%1, %0|%0, %1}";
2122 return standard_sse_constant_opcode (insn, operands[1]);
2125 return "pxor\t%0, %0";
2135 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2136 (const_string "sse2")
2137 (eq_attr "alternative" "9,10,11,12")
2138 (const_string "noavx")
2140 (const_string "*")))
2142 (cond [(eq_attr "alternative" "0,1")
2143 (const_string "multi")
2144 (eq_attr "alternative" "2")
2145 (const_string "mmx")
2146 (eq_attr "alternative" "3,4")
2147 (const_string "mmxmov")
2148 (eq_attr "alternative" "5,9")
2149 (const_string "sselog1")
2150 (eq_attr "alternative" "13,14")
2151 (const_string "ssecvt")
2153 (const_string "ssemov")))
2154 (set (attr "prefix")
2155 (if_then_else (eq_attr "alternative" "5,6,7,8")
2156 (const_string "maybe_vex")
2157 (const_string "orig")))
2158 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2161 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2162 (match_operand:DI 1 "general_operand" ""))]
2163 "!TARGET_64BIT && reload_completed
2164 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2165 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2167 "ix86_split_long_move (operands); DONE;")
2169 (define_insn "*movsi_internal"
2170 [(set (match_operand:SI 0 "nonimmediate_operand"
2171 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2172 (match_operand:SI 1 "general_operand"
2173 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2174 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2176 switch (get_attr_type (insn))
2179 return standard_sse_constant_opcode (insn, operands[1]);
2182 switch (get_attr_mode (insn))
2185 return "%vmovdqa\t{%1, %0|%0, %1}";
2187 return "%vmovaps\t{%1, %0|%0, %1}";
2189 return "%vmovd\t{%1, %0|%0, %1}";
2191 return "%vmovss\t{%1, %0|%0, %1}";
2197 return "pxor\t%0, %0";
2200 if (get_attr_mode (insn) == MODE_DI)
2201 return "movq\t{%1, %0|%0, %1}";
2202 return "movd\t{%1, %0|%0, %1}";
2205 return "lea{l}\t{%E1, %0|%0, %E1}";
2208 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2209 if (ix86_use_lea_for_mov (insn, operands))
2210 return "lea{l}\t{%E1, %0|%0, %E1}";
2212 return "mov{l}\t{%1, %0|%0, %1}";
2216 (cond [(eq_attr "alternative" "2")
2217 (const_string "mmx")
2218 (eq_attr "alternative" "3,4,5")
2219 (const_string "mmxmov")
2220 (eq_attr "alternative" "6")
2221 (const_string "sselog1")
2222 (eq_attr "alternative" "7,8,9,10,11")
2223 (const_string "ssemov")
2224 (match_operand 1 "pic_32bit_operand" "")
2225 (const_string "lea")
2227 (const_string "imov")))
2228 (set (attr "prefix")
2229 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2230 (const_string "orig")
2231 (const_string "maybe_vex")))
2232 (set (attr "prefix_data16")
2233 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2235 (const_string "*")))
2237 (cond [(eq_attr "alternative" "2,3")
2239 (eq_attr "alternative" "6,7")
2241 (not (match_test "TARGET_SSE2"))
2242 (const_string "V4SF")
2243 (const_string "TI"))
2244 (and (eq_attr "alternative" "8,9,10,11")
2245 (not (match_test "TARGET_SSE2")))
2248 (const_string "SI")))])
2250 (define_insn "*movhi_internal"
2251 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2252 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2253 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2255 switch (get_attr_type (insn))
2258 /* movzwl is faster than movw on p2 due to partial word stalls,
2259 though not as fast as an aligned movl. */
2260 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2262 if (get_attr_mode (insn) == MODE_SI)
2263 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2265 return "mov{w}\t{%1, %0|%0, %1}";
2269 (cond [(match_test "optimize_function_for_size_p (cfun)")
2270 (const_string "imov")
2271 (and (eq_attr "alternative" "0")
2272 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2273 (not (match_test "TARGET_HIMODE_MATH"))))
2274 (const_string "imov")
2275 (and (eq_attr "alternative" "1,2")
2276 (match_operand:HI 1 "aligned_operand" ""))
2277 (const_string "imov")
2278 (and (match_test "TARGET_MOVX")
2279 (eq_attr "alternative" "0,2"))
2280 (const_string "imovx")
2282 (const_string "imov")))
2284 (cond [(eq_attr "type" "imovx")
2286 (and (eq_attr "alternative" "1,2")
2287 (match_operand:HI 1 "aligned_operand" ""))
2289 (and (eq_attr "alternative" "0")
2290 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2291 (not (match_test "TARGET_HIMODE_MATH"))))
2294 (const_string "HI")))])
2296 ;; Situation is quite tricky about when to choose full sized (SImode) move
2297 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2298 ;; partial register dependency machines (such as AMD Athlon), where QImode
2299 ;; moves issue extra dependency and for partial register stalls machines
2300 ;; that don't use QImode patterns (and QImode move cause stall on the next
2303 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2304 ;; register stall machines with, where we use QImode instructions, since
2305 ;; partial register stall can be caused there. Then we use movzx.
2306 (define_insn "*movqi_internal"
2307 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2308 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2309 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2311 switch (get_attr_type (insn))
2314 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2315 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2317 if (get_attr_mode (insn) == MODE_SI)
2318 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2320 return "mov{b}\t{%1, %0|%0, %1}";
2324 (cond [(and (eq_attr "alternative" "5")
2325 (not (match_operand:QI 1 "aligned_operand" "")))
2326 (const_string "imovx")
2327 (match_test "optimize_function_for_size_p (cfun)")
2328 (const_string "imov")
2329 (and (eq_attr "alternative" "3")
2330 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2331 (not (match_test "TARGET_QIMODE_MATH"))))
2332 (const_string "imov")
2333 (eq_attr "alternative" "3,5")
2334 (const_string "imovx")
2335 (and (match_test "TARGET_MOVX")
2336 (eq_attr "alternative" "2"))
2337 (const_string "imovx")
2339 (const_string "imov")))
2341 (cond [(eq_attr "alternative" "3,4,5")
2343 (eq_attr "alternative" "6")
2345 (eq_attr "type" "imovx")
2347 (and (eq_attr "type" "imov")
2348 (and (eq_attr "alternative" "0,1")
2349 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2350 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2351 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2353 ;; Avoid partial register stalls when not using QImode arithmetic
2354 (and (eq_attr "type" "imov")
2355 (and (eq_attr "alternative" "0,1")
2356 (and (match_test "TARGET_PARTIAL_REG_STALL")
2357 (not (match_test "TARGET_QIMODE_MATH")))))
2360 (const_string "QI")))])
2362 ;; Stores and loads of ax to arbitrary constant address.
2363 ;; We fake an second form of instruction to force reload to load address
2364 ;; into register when rax is not available
2365 (define_insn "*movabs<mode>_1"
2366 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2367 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2368 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2370 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2371 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2372 [(set_attr "type" "imov")
2373 (set_attr "modrm" "0,*")
2374 (set_attr "length_address" "8,0")
2375 (set_attr "length_immediate" "0,*")
2376 (set_attr "memory" "store")
2377 (set_attr "mode" "<MODE>")])
2379 (define_insn "*movabs<mode>_2"
2380 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2381 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2382 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2384 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2385 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2386 [(set_attr "type" "imov")
2387 (set_attr "modrm" "0,*")
2388 (set_attr "length_address" "8,0")
2389 (set_attr "length_immediate" "0")
2390 (set_attr "memory" "load")
2391 (set_attr "mode" "<MODE>")])
2393 (define_insn "*swap<mode>"
2394 [(set (match_operand:SWI48 0 "register_operand" "+r")
2395 (match_operand:SWI48 1 "register_operand" "+r"))
2399 "xchg{<imodesuffix>}\t%1, %0"
2400 [(set_attr "type" "imov")
2401 (set_attr "mode" "<MODE>")
2402 (set_attr "pent_pair" "np")
2403 (set_attr "athlon_decode" "vector")
2404 (set_attr "amdfam10_decode" "double")
2405 (set_attr "bdver1_decode" "double")])
2407 (define_insn "*swap<mode>_1"
2408 [(set (match_operand:SWI12 0 "register_operand" "+r")
2409 (match_operand:SWI12 1 "register_operand" "+r"))
2412 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2414 [(set_attr "type" "imov")
2415 (set_attr "mode" "SI")
2416 (set_attr "pent_pair" "np")
2417 (set_attr "athlon_decode" "vector")
2418 (set_attr "amdfam10_decode" "double")
2419 (set_attr "bdver1_decode" "double")])
2421 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2422 ;; is disabled for AMDFAM10
2423 (define_insn "*swap<mode>_2"
2424 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2425 (match_operand:SWI12 1 "register_operand" "+<r>"))
2428 "TARGET_PARTIAL_REG_STALL"
2429 "xchg{<imodesuffix>}\t%1, %0"
2430 [(set_attr "type" "imov")
2431 (set_attr "mode" "<MODE>")
2432 (set_attr "pent_pair" "np")
2433 (set_attr "athlon_decode" "vector")])
2435 (define_expand "movstrict<mode>"
2436 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2437 (match_operand:SWI12 1 "general_operand" ""))]
2440 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2442 if (GET_CODE (operands[0]) == SUBREG
2443 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2445 /* Don't generate memory->memory moves, go through a register */
2446 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2447 operands[1] = force_reg (<MODE>mode, operands[1]);
2450 (define_insn "*movstrict<mode>_1"
2451 [(set (strict_low_part
2452 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2453 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2454 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2455 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2456 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2457 [(set_attr "type" "imov")
2458 (set_attr "mode" "<MODE>")])
2460 (define_insn "*movstrict<mode>_xor"
2461 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2462 (match_operand:SWI12 1 "const0_operand" ""))
2463 (clobber (reg:CC FLAGS_REG))]
2465 "xor{<imodesuffix>}\t%0, %0"
2466 [(set_attr "type" "alu1")
2467 (set_attr "mode" "<MODE>")
2468 (set_attr "length_immediate" "0")])
2470 (define_insn "*mov<mode>_extv_1"
2471 [(set (match_operand:SWI24 0 "register_operand" "=R")
2472 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2476 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2477 [(set_attr "type" "imovx")
2478 (set_attr "mode" "SI")])
2480 (define_insn "*movqi_extv_1_rex64"
2481 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2482 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2487 switch (get_attr_type (insn))
2490 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2492 return "mov{b}\t{%h1, %0|%0, %h1}";
2496 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2497 (match_test "TARGET_MOVX"))
2498 (const_string "imovx")
2499 (const_string "imov")))
2501 (if_then_else (eq_attr "type" "imovx")
2503 (const_string "QI")))])
2505 (define_insn "*movqi_extv_1"
2506 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2507 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2512 switch (get_attr_type (insn))
2515 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2517 return "mov{b}\t{%h1, %0|%0, %h1}";
2521 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2522 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2523 (match_test "TARGET_MOVX")))
2524 (const_string "imovx")
2525 (const_string "imov")))
2527 (if_then_else (eq_attr "type" "imovx")
2529 (const_string "QI")))])
2531 (define_insn "*mov<mode>_extzv_1"
2532 [(set (match_operand:SWI48 0 "register_operand" "=R")
2533 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2537 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2538 [(set_attr "type" "imovx")
2539 (set_attr "mode" "SI")])
2541 (define_insn "*movqi_extzv_2_rex64"
2542 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2544 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2549 switch (get_attr_type (insn))
2552 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2554 return "mov{b}\t{%h1, %0|%0, %h1}";
2558 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2559 (match_test "TARGET_MOVX"))
2560 (const_string "imovx")
2561 (const_string "imov")))
2563 (if_then_else (eq_attr "type" "imovx")
2565 (const_string "QI")))])
2567 (define_insn "*movqi_extzv_2"
2568 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2570 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2575 switch (get_attr_type (insn))
2578 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2580 return "mov{b}\t{%h1, %0|%0, %h1}";
2584 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2585 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2586 (match_test "TARGET_MOVX")))
2587 (const_string "imovx")
2588 (const_string "imov")))
2590 (if_then_else (eq_attr "type" "imovx")
2592 (const_string "QI")))])
2594 (define_expand "mov<mode>_insv_1"
2595 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2598 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2600 (define_insn "*mov<mode>_insv_1_rex64"
2601 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2604 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2607 if (CONST_INT_P (operands[1]))
2608 operands[1] = simplify_gen_subreg (QImode, operands[1], <MODE>mode, 0);
2609 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2611 [(set_attr "type" "imov")
2612 (set_attr "mode" "QI")])
2614 (define_insn "*movsi_insv_1"
2615 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2618 (match_operand:SI 1 "general_operand" "Qmn"))]
2621 if (CONST_INT_P (operands[1]))
2622 operands[1] = simplify_gen_subreg (QImode, operands[1], SImode, 0);
2623 return "mov{b}\t{%b1, %h0|%h0, %b1}";
2625 [(set_attr "type" "imov")
2626 (set_attr "mode" "QI")])
2628 (define_insn "*movqi_insv_2"
2629 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2632 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2635 "mov{b}\t{%h1, %h0|%h0, %h1}"
2636 [(set_attr "type" "imov")
2637 (set_attr "mode" "QI")])
2639 ;; Floating point push instructions.
2641 (define_insn "*pushtf"
2642 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2643 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2646 /* This insn should be already split before reg-stack. */
2649 [(set_attr "type" "multi")
2650 (set_attr "unit" "sse,*,*")
2651 (set_attr "mode" "TF,SI,SI")])
2653 ;; %%% Kill this when call knows how to work this out.
2655 [(set (match_operand:TF 0 "push_operand" "")
2656 (match_operand:TF 1 "sse_reg_operand" ""))]
2657 "TARGET_SSE2 && reload_completed"
2658 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2659 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2661 (define_insn "*pushxf"
2662 [(set (match_operand:XF 0 "push_operand" "=<,<")
2663 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2664 "optimize_function_for_speed_p (cfun)"
2666 /* This insn should be already split before reg-stack. */
2669 [(set_attr "type" "multi")
2670 (set_attr "unit" "i387,*")
2671 (set_attr "mode" "XF,SI")])
2673 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2674 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2675 ;; Pushing using integer instructions is longer except for constants
2676 ;; and direct memory references (assuming that any given constant is pushed
2677 ;; only once, but this ought to be handled elsewhere).
2679 (define_insn "*pushxf_nointeger"
2680 [(set (match_operand:XF 0 "push_operand" "=<,<")
2681 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2682 "optimize_function_for_size_p (cfun)"
2684 /* This insn should be already split before reg-stack. */
2687 [(set_attr "type" "multi")
2688 (set_attr "unit" "i387,*")
2689 (set_attr "mode" "XF,SI")])
2691 ;; %%% Kill this when call knows how to work this out.
2693 [(set (match_operand:XF 0 "push_operand" "")
2694 (match_operand:XF 1 "fp_register_operand" ""))]
2696 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2697 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2698 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2700 (define_insn "*pushdf_rex64"
2701 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2702 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2705 /* This insn should be already split before reg-stack. */
2708 [(set_attr "type" "multi")
2709 (set_attr "unit" "i387,*,*")
2710 (set_attr "mode" "DF,DI,DF")])
2712 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2713 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2714 ;; On the average, pushdf using integers can be still shorter.
2716 (define_insn "*pushdf"
2717 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2718 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2721 /* This insn should be already split before reg-stack. */
2724 [(set_attr "isa" "*,*,sse2")
2725 (set_attr "type" "multi")
2726 (set_attr "unit" "i387,*,*")
2727 (set_attr "mode" "DF,DI,DF")])
2729 ;; %%% Kill this when call knows how to work this out.
2731 [(set (match_operand:DF 0 "push_operand" "")
2732 (match_operand:DF 1 "any_fp_register_operand" ""))]
2734 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2735 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2737 (define_insn "*pushsf_rex64"
2738 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2739 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2742 /* Anything else should be already split before reg-stack. */
2743 gcc_assert (which_alternative == 1);
2744 return "push{q}\t%q1";
2746 [(set_attr "type" "multi,push,multi")
2747 (set_attr "unit" "i387,*,*")
2748 (set_attr "mode" "SF,DI,SF")])
2750 (define_insn "*pushsf"
2751 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2752 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2755 /* Anything else should be already split before reg-stack. */
2756 gcc_assert (which_alternative == 1);
2757 return "push{l}\t%1";
2759 [(set_attr "type" "multi,push,multi")
2760 (set_attr "unit" "i387,*,*")
2761 (set_attr "mode" "SF,SI,SF")])
2763 ;; %%% Kill this when call knows how to work this out.
2765 [(set (match_operand:SF 0 "push_operand" "")
2766 (match_operand:SF 1 "any_fp_register_operand" ""))]
2768 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2769 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2770 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2773 [(set (match_operand:SF 0 "push_operand" "")
2774 (match_operand:SF 1 "memory_operand" ""))]
2776 && (operands[2] = find_constant_src (insn))"
2777 [(set (match_dup 0) (match_dup 2))])
2780 [(set (match_operand 0 "push_operand" "")
2781 (match_operand 1 "general_operand" ""))]
2783 && (GET_MODE (operands[0]) == TFmode
2784 || GET_MODE (operands[0]) == XFmode
2785 || GET_MODE (operands[0]) == DFmode)
2786 && !ANY_FP_REG_P (operands[1])"
2788 "ix86_split_long_move (operands); DONE;")
2790 ;; Floating point move instructions.
2792 (define_expand "movtf"
2793 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2794 (match_operand:TF 1 "nonimmediate_operand" ""))]
2797 ix86_expand_move (TFmode, operands);
2801 (define_expand "mov<mode>"
2802 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2803 (match_operand:X87MODEF 1 "general_operand" ""))]
2805 "ix86_expand_move (<MODE>mode, operands); DONE;")
2807 (define_insn "*movtf_internal"
2808 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2809 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2811 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2812 && (!can_create_pseudo_p ()
2813 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2814 || GET_CODE (operands[1]) != CONST_DOUBLE
2815 || (optimize_function_for_size_p (cfun)
2816 && standard_sse_constant_p (operands[1])
2817 && !memory_operand (operands[0], TFmode))
2818 || (!TARGET_MEMORY_MISMATCH_STALL
2819 && memory_operand (operands[0], TFmode)))"
2821 switch (which_alternative)
2825 /* Handle misaligned load/store since we
2826 don't have movmisaligntf pattern. */
2827 if (misaligned_operand (operands[0], TFmode)
2828 || misaligned_operand (operands[1], TFmode))
2830 if (get_attr_mode (insn) == MODE_V4SF)
2831 return "%vmovups\t{%1, %0|%0, %1}";
2833 return "%vmovdqu\t{%1, %0|%0, %1}";
2837 if (get_attr_mode (insn) == MODE_V4SF)
2838 return "%vmovaps\t{%1, %0|%0, %1}";
2840 return "%vmovdqa\t{%1, %0|%0, %1}";
2844 return standard_sse_constant_opcode (insn, operands[1]);
2854 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2855 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2857 (cond [(eq_attr "alternative" "0,2")
2859 (match_test "optimize_function_for_size_p (cfun)")
2860 (const_string "V4SF")
2861 (const_string "TI"))
2862 (eq_attr "alternative" "1")
2864 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2865 (match_test "optimize_function_for_size_p (cfun)"))
2866 (const_string "V4SF")
2867 (const_string "TI"))]
2868 (const_string "DI")))])
2870 ;; Possible store forwarding (partial memory) stall in alternative 4.
2871 (define_insn "*movxf_internal"
2872 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2873 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2874 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2875 && (!can_create_pseudo_p ()
2876 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2877 || GET_CODE (operands[1]) != CONST_DOUBLE
2878 || (optimize_function_for_size_p (cfun)
2879 && standard_80387_constant_p (operands[1]) > 0
2880 && !memory_operand (operands[0], XFmode))
2881 || (!TARGET_MEMORY_MISMATCH_STALL
2882 && memory_operand (operands[0], XFmode)))"
2884 switch (which_alternative)
2888 return output_387_reg_move (insn, operands);
2891 return standard_80387_constant_opcode (operands[1]);
2901 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2902 (set_attr "mode" "XF,XF,XF,SI,SI")])
2904 (define_insn "*movdf_internal_rex64"
2905 [(set (match_operand:DF 0 "nonimmediate_operand"
2906 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2907 (match_operand:DF 1 "general_operand"
2908 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2909 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2910 && (!can_create_pseudo_p ()
2911 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2912 || GET_CODE (operands[1]) != CONST_DOUBLE
2913 || (optimize_function_for_size_p (cfun)
2914 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2915 && standard_80387_constant_p (operands[1]) > 0)
2916 || (TARGET_SSE2 && TARGET_SSE_MATH
2917 && standard_sse_constant_p (operands[1]))))
2918 || memory_operand (operands[0], DFmode))"
2920 switch (which_alternative)
2924 return output_387_reg_move (insn, operands);
2927 return standard_80387_constant_opcode (operands[1]);
2931 return "mov{q}\t{%1, %0|%0, %1}";
2934 return "movabs{q}\t{%1, %0|%0, %1}";
2940 return standard_sse_constant_opcode (insn, operands[1]);
2945 switch (get_attr_mode (insn))
2948 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2949 return "%vmovapd\t{%1, %0|%0, %1}";
2951 return "%vmovaps\t{%1, %0|%0, %1}";
2954 return "%vmovq\t{%1, %0|%0, %1}";
2956 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2957 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2958 return "%vmovsd\t{%1, %0|%0, %1}";
2960 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2962 return "%vmovlps\t{%1, %d0|%d0, %1}";
2969 /* Handle broken assemblers that require movd instead of movq. */
2970 return "%vmovd\t{%1, %0|%0, %1}";
2977 (cond [(eq_attr "alternative" "0,1,2")
2978 (const_string "fmov")
2979 (eq_attr "alternative" "3,4,5")
2980 (const_string "imov")
2981 (eq_attr "alternative" "6")
2982 (const_string "multi")
2983 (eq_attr "alternative" "7")
2984 (const_string "sselog1")
2986 (const_string "ssemov")))
2989 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2991 (const_string "*")))
2992 (set (attr "length_immediate")
2994 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2996 (const_string "*")))
2997 (set (attr "prefix")
2998 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2999 (const_string "orig")
3000 (const_string "maybe_vex")))
3001 (set (attr "prefix_data16")
3002 (if_then_else (eq_attr "mode" "V1DF")
3004 (const_string "*")))
3006 (cond [(eq_attr "alternative" "0,1,2")
3008 (eq_attr "alternative" "3,4,5,6,11,12")
3011 /* xorps is one byte shorter. */
3012 (eq_attr "alternative" "7")
3013 (cond [(match_test "optimize_function_for_size_p (cfun)")
3014 (const_string "V4SF")
3015 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3018 (const_string "V2DF"))
3020 /* For architectures resolving dependencies on
3021 whole SSE registers use APD move to break dependency
3022 chains, otherwise use short move to avoid extra work.
3024 movaps encodes one byte shorter. */
3025 (eq_attr "alternative" "8")
3027 [(match_test "optimize_function_for_size_p (cfun)")
3028 (const_string "V4SF")
3029 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3030 (const_string "V2DF")
3032 (const_string "DF"))
3033 /* For architectures resolving dependencies on register
3034 parts we may avoid extra work to zero out upper part
3036 (eq_attr "alternative" "9")
3038 (match_test "TARGET_SSE_SPLIT_REGS")
3039 (const_string "V1DF")
3040 (const_string "DF"))
3042 (const_string "DF")))])
3044 ;; Possible store forwarding (partial memory) stall in alternative 4.
3045 (define_insn "*movdf_internal"
3046 [(set (match_operand:DF 0 "nonimmediate_operand"
3047 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3048 (match_operand:DF 1 "general_operand"
3049 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3050 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3051 && (!can_create_pseudo_p ()
3052 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3053 || GET_CODE (operands[1]) != CONST_DOUBLE
3054 || (optimize_function_for_size_p (cfun)
3055 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3056 && standard_80387_constant_p (operands[1]) > 0)
3057 || (TARGET_SSE2 && TARGET_SSE_MATH
3058 && standard_sse_constant_p (operands[1])))
3059 && !memory_operand (operands[0], DFmode))
3060 || (!TARGET_MEMORY_MISMATCH_STALL
3061 && memory_operand (operands[0], DFmode)))"
3063 switch (which_alternative)
3067 return output_387_reg_move (insn, operands);
3070 return standard_80387_constant_opcode (operands[1]);
3078 return standard_sse_constant_opcode (insn, operands[1]);
3086 switch (get_attr_mode (insn))
3089 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3090 return "%vmovapd\t{%1, %0|%0, %1}";
3092 return "%vmovaps\t{%1, %0|%0, %1}";
3095 return "%vmovq\t{%1, %0|%0, %1}";
3097 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3098 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3099 return "%vmovsd\t{%1, %0|%0, %1}";
3101 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3103 return "%vmovlps\t{%1, %d0|%d0, %1}";
3113 (if_then_else (eq_attr "alternative" "5,6,7,8")
3114 (const_string "sse2")
3115 (const_string "*")))
3117 (cond [(eq_attr "alternative" "0,1,2")
3118 (const_string "fmov")
3119 (eq_attr "alternative" "3,4")
3120 (const_string "multi")
3121 (eq_attr "alternative" "5,9")
3122 (const_string "sselog1")
3124 (const_string "ssemov")))
3125 (set (attr "prefix")
3126 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3127 (const_string "orig")
3128 (const_string "maybe_vex")))
3129 (set (attr "prefix_data16")
3130 (if_then_else (eq_attr "mode" "V1DF")
3132 (const_string "*")))
3134 (cond [(eq_attr "alternative" "0,1,2")
3136 (eq_attr "alternative" "3,4")
3139 /* For SSE1, we have many fewer alternatives. */
3140 (not (match_test "TARGET_SSE2"))
3142 (eq_attr "alternative" "5,6,9,10")
3143 (const_string "V4SF")
3144 (const_string "V2SF"))
3146 /* xorps is one byte shorter. */
3147 (eq_attr "alternative" "5,9")
3148 (cond [(match_test "optimize_function_for_size_p (cfun)")
3149 (const_string "V4SF")
3150 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3153 (const_string "V2DF"))
3155 /* For architectures resolving dependencies on
3156 whole SSE registers use APD move to break dependency
3157 chains, otherwise use short move to avoid extra work.
3159 movaps encodes one byte shorter. */
3160 (eq_attr "alternative" "6,10")
3162 [(match_test "optimize_function_for_size_p (cfun)")
3163 (const_string "V4SF")
3164 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3165 (const_string "V2DF")
3167 (const_string "DF"))
3168 /* For architectures resolving dependencies on register
3169 parts we may avoid extra work to zero out upper part
3171 (eq_attr "alternative" "7,11")
3173 (match_test "TARGET_SSE_SPLIT_REGS")
3174 (const_string "V1DF")
3175 (const_string "DF"))
3177 (const_string "DF")))])
3179 (define_insn "*movsf_internal"
3180 [(set (match_operand:SF 0 "nonimmediate_operand"
3181 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3182 (match_operand:SF 1 "general_operand"
3183 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3184 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3185 && (!can_create_pseudo_p ()
3186 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3187 || GET_CODE (operands[1]) != CONST_DOUBLE
3188 || (optimize_function_for_size_p (cfun)
3189 && ((!TARGET_SSE_MATH
3190 && standard_80387_constant_p (operands[1]) > 0)
3192 && standard_sse_constant_p (operands[1]))))
3193 || memory_operand (operands[0], SFmode))"
3195 switch (which_alternative)
3199 return output_387_reg_move (insn, operands);
3202 return standard_80387_constant_opcode (operands[1]);
3206 return "mov{l}\t{%1, %0|%0, %1}";
3209 return standard_sse_constant_opcode (insn, operands[1]);
3212 if (get_attr_mode (insn) == MODE_V4SF)
3213 return "%vmovaps\t{%1, %0|%0, %1}";
3215 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3219 return "%vmovss\t{%1, %0|%0, %1}";
3225 return "movd\t{%1, %0|%0, %1}";
3228 return "movq\t{%1, %0|%0, %1}";
3232 return "%vmovd\t{%1, %0|%0, %1}";
3239 (cond [(eq_attr "alternative" "0,1,2")
3240 (const_string "fmov")
3241 (eq_attr "alternative" "3,4")
3242 (const_string "multi")
3243 (eq_attr "alternative" "5")
3244 (const_string "sselog1")
3245 (eq_attr "alternative" "9,10,11,14,15")
3246 (const_string "mmxmov")
3248 (const_string "ssemov")))
3249 (set (attr "prefix")
3250 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3251 (const_string "maybe_vex")
3252 (const_string "orig")))
3254 (cond [(eq_attr "alternative" "3,4,9,10")
3256 (eq_attr "alternative" "5")
3258 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3259 (match_test "TARGET_SSE2"))
3260 (not (match_test "optimize_function_for_size_p (cfun)")))
3262 (const_string "V4SF"))
3263 /* For architectures resolving dependencies on
3264 whole SSE registers use APS move to break dependency
3265 chains, otherwise use short move to avoid extra work.
3267 Do the same for architectures resolving dependencies on
3268 the parts. While in DF mode it is better to always handle
3269 just register parts, the SF mode is different due to lack
3270 of instructions to load just part of the register. It is
3271 better to maintain the whole registers in single format
3272 to avoid problems on using packed logical operations. */
3273 (eq_attr "alternative" "6")
3275 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3276 (match_test "TARGET_SSE_SPLIT_REGS"))
3277 (const_string "V4SF")
3278 (const_string "SF"))
3279 (eq_attr "alternative" "11")
3280 (const_string "DI")]
3281 (const_string "SF")))])
3284 [(set (match_operand 0 "any_fp_register_operand" "")
3285 (match_operand 1 "memory_operand" ""))]
3287 && (GET_MODE (operands[0]) == TFmode
3288 || GET_MODE (operands[0]) == XFmode
3289 || GET_MODE (operands[0]) == DFmode
3290 || GET_MODE (operands[0]) == SFmode)
3291 && (operands[2] = find_constant_src (insn))"
3292 [(set (match_dup 0) (match_dup 2))]
3294 rtx c = operands[2];
3295 int r = REGNO (operands[0]);
3297 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3298 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3303 [(set (match_operand 0 "any_fp_register_operand" "")
3304 (float_extend (match_operand 1 "memory_operand" "")))]
3306 && (GET_MODE (operands[0]) == TFmode
3307 || GET_MODE (operands[0]) == XFmode
3308 || GET_MODE (operands[0]) == DFmode)
3309 && (operands[2] = find_constant_src (insn))"
3310 [(set (match_dup 0) (match_dup 2))]
3312 rtx c = operands[2];
3313 int r = REGNO (operands[0]);
3315 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3316 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3320 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3322 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3323 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3325 && (standard_80387_constant_p (operands[1]) == 8
3326 || standard_80387_constant_p (operands[1]) == 9)"
3327 [(set (match_dup 0)(match_dup 1))
3329 (neg:X87MODEF (match_dup 0)))]
3333 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3334 if (real_isnegzero (&r))
3335 operands[1] = CONST0_RTX (<MODE>mode);
3337 operands[1] = CONST1_RTX (<MODE>mode);
3341 [(set (match_operand 0 "nonimmediate_operand" "")
3342 (match_operand 1 "general_operand" ""))]
3344 && (GET_MODE (operands[0]) == TFmode
3345 || GET_MODE (operands[0]) == XFmode
3346 || GET_MODE (operands[0]) == DFmode)
3347 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3349 "ix86_split_long_move (operands); DONE;")
3351 (define_insn "swapxf"
3352 [(set (match_operand:XF 0 "register_operand" "+f")
3353 (match_operand:XF 1 "register_operand" "+f"))
3358 if (STACK_TOP_P (operands[0]))
3363 [(set_attr "type" "fxch")
3364 (set_attr "mode" "XF")])
3366 (define_insn "*swap<mode>"
3367 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3368 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3371 "TARGET_80387 || reload_completed"
3373 if (STACK_TOP_P (operands[0]))
3378 [(set_attr "type" "fxch")
3379 (set_attr "mode" "<MODE>")])
3381 ;; Zero extension instructions
3383 (define_expand "zero_extendsidi2"
3384 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3385 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3390 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3395 (define_insn "*zero_extendsidi2_rex64"
3396 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3398 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3401 mov{l}\t{%1, %k0|%k0, %1}
3403 movd\t{%1, %0|%0, %1}
3404 movd\t{%1, %0|%0, %1}
3405 %vmovd\t{%1, %0|%0, %1}
3406 %vmovd\t{%1, %0|%0, %1}"
3407 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3408 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3409 (set_attr "prefix_0f" "0,*,*,*,*,*")
3410 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3413 [(set (match_operand:DI 0 "memory_operand" "")
3414 (zero_extend:DI (match_dup 0)))]
3416 [(set (match_dup 4) (const_int 0))]
3417 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3419 ;; %%% Kill me once multi-word ops are sane.
3420 (define_insn "zero_extendsidi2_1"
3421 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3423 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3424 (clobber (reg:CC FLAGS_REG))]
3430 movd\t{%1, %0|%0, %1}
3431 movd\t{%1, %0|%0, %1}
3432 %vmovd\t{%1, %0|%0, %1}
3433 %vmovd\t{%1, %0|%0, %1}"
3434 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3435 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3436 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3437 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3440 [(set (match_operand:DI 0 "register_operand" "")
3441 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3442 (clobber (reg:CC FLAGS_REG))]
3443 "!TARGET_64BIT && reload_completed
3444 && true_regnum (operands[0]) == true_regnum (operands[1])"
3445 [(set (match_dup 4) (const_int 0))]
3446 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3449 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3450 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3451 (clobber (reg:CC FLAGS_REG))]
3452 "!TARGET_64BIT && reload_completed
3453 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3454 [(set (match_dup 3) (match_dup 1))
3455 (set (match_dup 4) (const_int 0))]
3456 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3458 (define_insn "zero_extend<mode>di2"
3459 [(set (match_operand:DI 0 "register_operand" "=r")
3461 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3463 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3464 [(set_attr "type" "imovx")
3465 (set_attr "mode" "SI")])
3467 (define_expand "zero_extendhisi2"
3468 [(set (match_operand:SI 0 "register_operand" "")
3469 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3472 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3474 operands[1] = force_reg (HImode, operands[1]);
3475 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3480 (define_insn_and_split "zero_extendhisi2_and"
3481 [(set (match_operand:SI 0 "register_operand" "=r")
3482 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3483 (clobber (reg:CC FLAGS_REG))]
3484 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3486 "&& reload_completed"
3487 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3488 (clobber (reg:CC FLAGS_REG))])]
3490 [(set_attr "type" "alu1")
3491 (set_attr "mode" "SI")])
3493 (define_insn "*zero_extendhisi2_movzwl"
3494 [(set (match_operand:SI 0 "register_operand" "=r")
3495 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3496 "!TARGET_ZERO_EXTEND_WITH_AND
3497 || optimize_function_for_size_p (cfun)"
3498 "movz{wl|x}\t{%1, %0|%0, %1}"
3499 [(set_attr "type" "imovx")
3500 (set_attr "mode" "SI")])
3502 (define_expand "zero_extendqi<mode>2"
3504 [(set (match_operand:SWI24 0 "register_operand" "")
3505 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3506 (clobber (reg:CC FLAGS_REG))])])
3508 (define_insn "*zero_extendqi<mode>2_and"
3509 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3510 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3511 (clobber (reg:CC FLAGS_REG))]
3512 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3514 [(set_attr "type" "alu1")
3515 (set_attr "mode" "<MODE>")])
3517 ;; When source and destination does not overlap, clear destination
3518 ;; first and then do the movb
3520 [(set (match_operand:SWI24 0 "register_operand" "")
3521 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3522 (clobber (reg:CC FLAGS_REG))]
3524 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3525 && ANY_QI_REG_P (operands[0])
3526 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3527 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3528 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3530 operands[2] = gen_lowpart (QImode, operands[0]);
3531 ix86_expand_clear (operands[0]);
3534 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3535 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3536 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3537 (clobber (reg:CC FLAGS_REG))]
3538 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3540 [(set_attr "type" "imovx,alu1")
3541 (set_attr "mode" "<MODE>")])
3543 ;; For the movzbl case strip only the clobber
3545 [(set (match_operand:SWI24 0 "register_operand" "")
3546 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3547 (clobber (reg:CC FLAGS_REG))]
3549 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3550 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3552 (zero_extend:SWI24 (match_dup 1)))])
3554 ; zero extend to SImode to avoid partial register stalls
3555 (define_insn "*zero_extendqi<mode>2_movzbl"
3556 [(set (match_operand:SWI24 0 "register_operand" "=r")
3557 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3559 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3560 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3561 [(set_attr "type" "imovx")
3562 (set_attr "mode" "SI")])
3564 ;; Rest is handled by single and.
3566 [(set (match_operand:SWI24 0 "register_operand" "")
3567 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3568 (clobber (reg:CC FLAGS_REG))]
3570 && true_regnum (operands[0]) == true_regnum (operands[1])"
3571 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3572 (clobber (reg:CC FLAGS_REG))])])
3574 ;; Sign extension instructions
3576 (define_expand "extendsidi2"
3577 [(set (match_operand:DI 0 "register_operand" "")
3578 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3583 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3588 (define_insn "*extendsidi2_rex64"
3589 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3590 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3594 movs{lq|x}\t{%1, %0|%0, %1}"
3595 [(set_attr "type" "imovx")
3596 (set_attr "mode" "DI")
3597 (set_attr "prefix_0f" "0")
3598 (set_attr "modrm" "0,1")])
3600 (define_insn "extendsidi2_1"
3601 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3602 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3603 (clobber (reg:CC FLAGS_REG))
3604 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3608 ;; Extend to memory case when source register does die.
3610 [(set (match_operand:DI 0 "memory_operand" "")
3611 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3612 (clobber (reg:CC FLAGS_REG))
3613 (clobber (match_operand:SI 2 "register_operand" ""))]
3615 && dead_or_set_p (insn, operands[1])
3616 && !reg_mentioned_p (operands[1], operands[0]))"
3617 [(set (match_dup 3) (match_dup 1))
3618 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3619 (clobber (reg:CC FLAGS_REG))])
3620 (set (match_dup 4) (match_dup 1))]
3621 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3623 ;; Extend to memory case when source register does not die.
3625 [(set (match_operand:DI 0 "memory_operand" "")
3626 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3627 (clobber (reg:CC FLAGS_REG))
3628 (clobber (match_operand:SI 2 "register_operand" ""))]
3632 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3634 emit_move_insn (operands[3], operands[1]);
3636 /* Generate a cltd if possible and doing so it profitable. */
3637 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3638 && true_regnum (operands[1]) == AX_REG
3639 && true_regnum (operands[2]) == DX_REG)
3641 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3645 emit_move_insn (operands[2], operands[1]);
3646 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3648 emit_move_insn (operands[4], operands[2]);
3652 ;; Extend to register case. Optimize case where source and destination
3653 ;; registers match and cases where we can use cltd.
3655 [(set (match_operand:DI 0 "register_operand" "")
3656 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3657 (clobber (reg:CC FLAGS_REG))
3658 (clobber (match_scratch:SI 2 ""))]
3662 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3664 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3665 emit_move_insn (operands[3], operands[1]);
3667 /* Generate a cltd if possible and doing so it profitable. */
3668 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3669 && true_regnum (operands[3]) == AX_REG
3670 && true_regnum (operands[4]) == DX_REG)
3672 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3676 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3677 emit_move_insn (operands[4], operands[1]);
3679 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3683 (define_insn "extend<mode>di2"
3684 [(set (match_operand:DI 0 "register_operand" "=r")
3686 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3688 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3689 [(set_attr "type" "imovx")
3690 (set_attr "mode" "DI")])
3692 (define_insn "extendhisi2"
3693 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3694 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3697 switch (get_attr_prefix_0f (insn))
3700 return "{cwtl|cwde}";
3702 return "movs{wl|x}\t{%1, %0|%0, %1}";
3705 [(set_attr "type" "imovx")
3706 (set_attr "mode" "SI")
3707 (set (attr "prefix_0f")
3708 ;; movsx is short decodable while cwtl is vector decoded.
3709 (if_then_else (and (eq_attr "cpu" "!k6")
3710 (eq_attr "alternative" "0"))
3712 (const_string "1")))
3714 (if_then_else (eq_attr "prefix_0f" "0")
3716 (const_string "1")))])
3718 (define_insn "*extendhisi2_zext"
3719 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3722 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3725 switch (get_attr_prefix_0f (insn))
3728 return "{cwtl|cwde}";
3730 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3733 [(set_attr "type" "imovx")
3734 (set_attr "mode" "SI")
3735 (set (attr "prefix_0f")
3736 ;; movsx is short decodable while cwtl is vector decoded.
3737 (if_then_else (and (eq_attr "cpu" "!k6")
3738 (eq_attr "alternative" "0"))
3740 (const_string "1")))
3742 (if_then_else (eq_attr "prefix_0f" "0")
3744 (const_string "1")))])
3746 (define_insn "extendqisi2"
3747 [(set (match_operand:SI 0 "register_operand" "=r")
3748 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3750 "movs{bl|x}\t{%1, %0|%0, %1}"
3751 [(set_attr "type" "imovx")
3752 (set_attr "mode" "SI")])
3754 (define_insn "*extendqisi2_zext"
3755 [(set (match_operand:DI 0 "register_operand" "=r")
3757 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3759 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3760 [(set_attr "type" "imovx")
3761 (set_attr "mode" "SI")])
3763 (define_insn "extendqihi2"
3764 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3765 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3768 switch (get_attr_prefix_0f (insn))
3771 return "{cbtw|cbw}";
3773 return "movs{bw|x}\t{%1, %0|%0, %1}";
3776 [(set_attr "type" "imovx")
3777 (set_attr "mode" "HI")
3778 (set (attr "prefix_0f")
3779 ;; movsx is short decodable while cwtl is vector decoded.
3780 (if_then_else (and (eq_attr "cpu" "!k6")
3781 (eq_attr "alternative" "0"))
3783 (const_string "1")))
3785 (if_then_else (eq_attr "prefix_0f" "0")
3787 (const_string "1")))])
3789 ;; Conversions between float and double.
3791 ;; These are all no-ops in the model used for the 80387.
3792 ;; So just emit moves.
3794 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3796 [(set (match_operand:DF 0 "push_operand" "")
3797 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3799 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3800 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3803 [(set (match_operand:XF 0 "push_operand" "")
3804 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3806 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3807 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3808 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3810 (define_expand "extendsfdf2"
3811 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3812 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3813 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3815 /* ??? Needed for compress_float_constant since all fp constants
3816 are TARGET_LEGITIMATE_CONSTANT_P. */
3817 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3819 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3820 && standard_80387_constant_p (operands[1]) > 0)
3822 operands[1] = simplify_const_unary_operation
3823 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3824 emit_move_insn_1 (operands[0], operands[1]);
3827 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3831 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3833 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3835 We do the conversion post reload to avoid producing of 128bit spills
3836 that might lead to ICE on 32bit target. The sequence unlikely combine
3839 [(set (match_operand:DF 0 "register_operand" "")
3841 (match_operand:SF 1 "nonimmediate_operand" "")))]
3842 "TARGET_USE_VECTOR_FP_CONVERTS
3843 && optimize_insn_for_speed_p ()
3844 && reload_completed && SSE_REG_P (operands[0])"
3849 (parallel [(const_int 0) (const_int 1)]))))]
3851 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3852 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3853 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3854 Try to avoid move when unpacking can be done in source. */
3855 if (REG_P (operands[1]))
3857 /* If it is unsafe to overwrite upper half of source, we need
3858 to move to destination and unpack there. */
3859 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3860 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3861 && true_regnum (operands[0]) != true_regnum (operands[1]))
3863 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3864 emit_move_insn (tmp, operands[1]);
3867 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3868 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3872 emit_insn (gen_vec_setv4sf_0 (operands[3],
3873 CONST0_RTX (V4SFmode), operands[1]));
3876 (define_insn "*extendsfdf2_mixed"
3877 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3879 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3880 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3882 switch (which_alternative)
3886 return output_387_reg_move (insn, operands);
3889 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3895 [(set_attr "type" "fmov,fmov,ssecvt")
3896 (set_attr "prefix" "orig,orig,maybe_vex")
3897 (set_attr "mode" "SF,XF,DF")])
3899 (define_insn "*extendsfdf2_sse"
3900 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3901 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3902 "TARGET_SSE2 && TARGET_SSE_MATH"
3903 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3904 [(set_attr "type" "ssecvt")
3905 (set_attr "prefix" "maybe_vex")
3906 (set_attr "mode" "DF")])
3908 (define_insn "*extendsfdf2_i387"
3909 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3910 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3912 "* return output_387_reg_move (insn, operands);"
3913 [(set_attr "type" "fmov")
3914 (set_attr "mode" "SF,XF")])
3916 (define_expand "extend<mode>xf2"
3917 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3918 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3921 /* ??? Needed for compress_float_constant since all fp constants
3922 are TARGET_LEGITIMATE_CONSTANT_P. */
3923 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3925 if (standard_80387_constant_p (operands[1]) > 0)
3927 operands[1] = simplify_const_unary_operation
3928 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3929 emit_move_insn_1 (operands[0], operands[1]);
3932 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3936 (define_insn "*extend<mode>xf2_i387"
3937 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3939 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3941 "* return output_387_reg_move (insn, operands);"
3942 [(set_attr "type" "fmov")
3943 (set_attr "mode" "<MODE>,XF")])
3945 ;; %%% This seems bad bad news.
3946 ;; This cannot output into an f-reg because there is no way to be sure
3947 ;; of truncating in that case. Otherwise this is just like a simple move
3948 ;; insn. So we pretend we can output to a reg in order to get better
3949 ;; register preferencing, but we really use a stack slot.
3951 ;; Conversion from DFmode to SFmode.
3953 (define_expand "truncdfsf2"
3954 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3956 (match_operand:DF 1 "nonimmediate_operand" "")))]
3957 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3959 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3961 else if (flag_unsafe_math_optimizations)
3965 rtx temp = assign_386_stack_local (SFmode, SLOT_TEMP);
3966 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3971 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3973 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3975 We do the conversion post reload to avoid producing of 128bit spills
3976 that might lead to ICE on 32bit target. The sequence unlikely combine
3979 [(set (match_operand:SF 0 "register_operand" "")
3981 (match_operand:DF 1 "nonimmediate_operand" "")))]
3982 "TARGET_USE_VECTOR_FP_CONVERTS
3983 && optimize_insn_for_speed_p ()
3984 && reload_completed && SSE_REG_P (operands[0])"
3987 (float_truncate:V2SF
3991 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3992 operands[3] = CONST0_RTX (V2SFmode);
3993 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3994 /* Use movsd for loading from memory, unpcklpd for registers.
3995 Try to avoid move when unpacking can be done in source, or SSE3
3996 movddup is available. */
3997 if (REG_P (operands[1]))
4000 && true_regnum (operands[0]) != true_regnum (operands[1])
4001 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4002 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4004 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4005 emit_move_insn (tmp, operands[1]);
4008 else if (!TARGET_SSE3)
4009 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4010 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4013 emit_insn (gen_sse2_loadlpd (operands[4],
4014 CONST0_RTX (V2DFmode), operands[1]));
4017 (define_expand "truncdfsf2_with_temp"
4018 [(parallel [(set (match_operand:SF 0 "" "")
4019 (float_truncate:SF (match_operand:DF 1 "" "")))
4020 (clobber (match_operand:SF 2 "" ""))])])
4022 (define_insn "*truncdfsf_fast_mixed"
4023 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4025 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4026 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4028 switch (which_alternative)
4031 return output_387_reg_move (insn, operands);
4033 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4038 [(set_attr "type" "fmov,ssecvt")
4039 (set_attr "prefix" "orig,maybe_vex")
4040 (set_attr "mode" "SF")])
4042 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4043 ;; because nothing we do here is unsafe.
4044 (define_insn "*truncdfsf_fast_sse"
4045 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4047 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4048 "TARGET_SSE2 && TARGET_SSE_MATH"
4049 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4050 [(set_attr "type" "ssecvt")
4051 (set_attr "prefix" "maybe_vex")
4052 (set_attr "mode" "SF")])
4054 (define_insn "*truncdfsf_fast_i387"
4055 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4057 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4058 "TARGET_80387 && flag_unsafe_math_optimizations"
4059 "* return output_387_reg_move (insn, operands);"
4060 [(set_attr "type" "fmov")
4061 (set_attr "mode" "SF")])
4063 (define_insn "*truncdfsf_mixed"
4064 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4066 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4067 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4068 "TARGET_MIX_SSE_I387"
4070 switch (which_alternative)
4073 return output_387_reg_move (insn, operands);
4075 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4081 [(set_attr "isa" "*,sse2,*,*,*")
4082 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4083 (set_attr "unit" "*,*,i387,i387,i387")
4084 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4085 (set_attr "mode" "SF")])
4087 (define_insn "*truncdfsf_i387"
4088 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4090 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4091 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4094 switch (which_alternative)
4097 return output_387_reg_move (insn, operands);
4103 [(set_attr "type" "fmov,multi,multi,multi")
4104 (set_attr "unit" "*,i387,i387,i387")
4105 (set_attr "mode" "SF")])
4107 (define_insn "*truncdfsf2_i387_1"
4108 [(set (match_operand:SF 0 "memory_operand" "=m")
4110 (match_operand:DF 1 "register_operand" "f")))]
4112 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4113 && !TARGET_MIX_SSE_I387"
4114 "* return output_387_reg_move (insn, operands);"
4115 [(set_attr "type" "fmov")
4116 (set_attr "mode" "SF")])
4119 [(set (match_operand:SF 0 "register_operand" "")
4121 (match_operand:DF 1 "fp_register_operand" "")))
4122 (clobber (match_operand 2 "" ""))]
4124 [(set (match_dup 2) (match_dup 1))
4125 (set (match_dup 0) (match_dup 2))]
4126 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4128 ;; Conversion from XFmode to {SF,DF}mode
4130 (define_expand "truncxf<mode>2"
4131 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4132 (float_truncate:MODEF
4133 (match_operand:XF 1 "register_operand" "")))
4134 (clobber (match_dup 2))])]
4137 if (flag_unsafe_math_optimizations)
4139 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4140 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4141 if (reg != operands[0])
4142 emit_move_insn (operands[0], reg);
4146 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4149 (define_insn "*truncxfsf2_mixed"
4150 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4152 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4153 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4156 gcc_assert (!which_alternative);
4157 return output_387_reg_move (insn, operands);
4159 [(set_attr "type" "fmov,multi,multi,multi")
4160 (set_attr "unit" "*,i387,i387,i387")
4161 (set_attr "mode" "SF")])
4163 (define_insn "*truncxfdf2_mixed"
4164 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4166 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4167 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4170 gcc_assert (!which_alternative);
4171 return output_387_reg_move (insn, operands);
4173 [(set_attr "isa" "*,*,sse2,*")
4174 (set_attr "type" "fmov,multi,multi,multi")
4175 (set_attr "unit" "*,i387,i387,i387")
4176 (set_attr "mode" "DF")])
4178 (define_insn "truncxf<mode>2_i387_noop"
4179 [(set (match_operand:MODEF 0 "register_operand" "=f")
4180 (float_truncate:MODEF
4181 (match_operand:XF 1 "register_operand" "f")))]
4182 "TARGET_80387 && flag_unsafe_math_optimizations"
4183 "* return output_387_reg_move (insn, operands);"
4184 [(set_attr "type" "fmov")
4185 (set_attr "mode" "<MODE>")])
4187 (define_insn "*truncxf<mode>2_i387"
4188 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4189 (float_truncate:MODEF
4190 (match_operand:XF 1 "register_operand" "f")))]
4192 "* return output_387_reg_move (insn, operands);"
4193 [(set_attr "type" "fmov")
4194 (set_attr "mode" "<MODE>")])
4197 [(set (match_operand:MODEF 0 "register_operand" "")
4198 (float_truncate:MODEF
4199 (match_operand:XF 1 "register_operand" "")))
4200 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4201 "TARGET_80387 && reload_completed"
4202 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4203 (set (match_dup 0) (match_dup 2))])
4206 [(set (match_operand:MODEF 0 "memory_operand" "")
4207 (float_truncate:MODEF
4208 (match_operand:XF 1 "register_operand" "")))
4209 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4211 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4213 ;; Signed conversion to DImode.
4215 (define_expand "fix_truncxfdi2"
4216 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4217 (fix:DI (match_operand:XF 1 "register_operand" "")))
4218 (clobber (reg:CC FLAGS_REG))])]
4223 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4228 (define_expand "fix_trunc<mode>di2"
4229 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4230 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4231 (clobber (reg:CC FLAGS_REG))])]
4232 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4235 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4237 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4240 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4242 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4243 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4244 if (out != operands[0])
4245 emit_move_insn (operands[0], out);
4250 ;; Signed conversion to SImode.
4252 (define_expand "fix_truncxfsi2"
4253 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4254 (fix:SI (match_operand:XF 1 "register_operand" "")))
4255 (clobber (reg:CC FLAGS_REG))])]
4260 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4265 (define_expand "fix_trunc<mode>si2"
4266 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4267 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4268 (clobber (reg:CC FLAGS_REG))])]
4269 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4272 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4274 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4277 if (SSE_FLOAT_MODE_P (<MODE>mode))
4279 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4280 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4281 if (out != operands[0])
4282 emit_move_insn (operands[0], out);
4287 ;; Signed conversion to HImode.
4289 (define_expand "fix_trunc<mode>hi2"
4290 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4291 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4292 (clobber (reg:CC FLAGS_REG))])]
4294 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4298 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4303 ;; Unsigned conversion to SImode.
4305 (define_expand "fixuns_trunc<mode>si2"
4307 [(set (match_operand:SI 0 "register_operand" "")
4309 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4311 (clobber (match_scratch:<ssevecmode> 3 ""))
4312 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4313 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4315 enum machine_mode mode = <MODE>mode;
4316 enum machine_mode vecmode = <ssevecmode>mode;
4317 REAL_VALUE_TYPE TWO31r;
4320 if (optimize_insn_for_size_p ())
4323 real_ldexp (&TWO31r, &dconst1, 31);
4324 two31 = const_double_from_real_value (TWO31r, mode);
4325 two31 = ix86_build_const_vector (vecmode, true, two31);
4326 operands[2] = force_reg (vecmode, two31);
4329 (define_insn_and_split "*fixuns_trunc<mode>_1"
4330 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4332 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4333 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4334 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4335 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4336 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4337 && optimize_function_for_speed_p (cfun)"
4339 "&& reload_completed"
4342 ix86_split_convert_uns_si_sse (operands);
4346 ;; Unsigned conversion to HImode.
4347 ;; Without these patterns, we'll try the unsigned SI conversion which
4348 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4350 (define_expand "fixuns_trunc<mode>hi2"
4352 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4353 (set (match_operand:HI 0 "nonimmediate_operand" "")
4354 (subreg:HI (match_dup 2) 0))]
4355 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4356 "operands[2] = gen_reg_rtx (SImode);")
4358 ;; When SSE is available, it is always faster to use it!
4359 (define_insn "fix_trunc<mode>di_sse"
4360 [(set (match_operand:DI 0 "register_operand" "=r,r")
4361 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4362 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4363 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4364 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4365 [(set_attr "type" "sseicvt")
4366 (set_attr "prefix" "maybe_vex")
4367 (set_attr "prefix_rex" "1")
4368 (set_attr "mode" "<MODE>")
4369 (set_attr "athlon_decode" "double,vector")
4370 (set_attr "amdfam10_decode" "double,double")
4371 (set_attr "bdver1_decode" "double,double")])
4373 (define_insn "fix_trunc<mode>si_sse"
4374 [(set (match_operand:SI 0 "register_operand" "=r,r")
4375 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4376 "SSE_FLOAT_MODE_P (<MODE>mode)
4377 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4378 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4379 [(set_attr "type" "sseicvt")
4380 (set_attr "prefix" "maybe_vex")
4381 (set_attr "mode" "<MODE>")
4382 (set_attr "athlon_decode" "double,vector")
4383 (set_attr "amdfam10_decode" "double,double")
4384 (set_attr "bdver1_decode" "double,double")])
4386 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4388 [(set (match_operand:MODEF 0 "register_operand" "")
4389 (match_operand:MODEF 1 "memory_operand" ""))
4390 (set (match_operand:SWI48x 2 "register_operand" "")
4391 (fix:SWI48x (match_dup 0)))]
4392 "TARGET_SHORTEN_X87_SSE
4393 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4394 && peep2_reg_dead_p (2, operands[0])"
4395 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4397 ;; Avoid vector decoded forms of the instruction.
4399 [(match_scratch:DF 2 "x")
4400 (set (match_operand:SWI48x 0 "register_operand" "")
4401 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4402 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4403 [(set (match_dup 2) (match_dup 1))
4404 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4407 [(match_scratch:SF 2 "x")
4408 (set (match_operand:SWI48x 0 "register_operand" "")
4409 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4410 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4411 [(set (match_dup 2) (match_dup 1))
4412 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4414 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4415 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4416 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4417 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4419 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4420 && (TARGET_64BIT || <MODE>mode != DImode))
4422 && can_create_pseudo_p ()"
4427 if (memory_operand (operands[0], VOIDmode))
4428 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4431 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4432 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4438 [(set_attr "type" "fisttp")
4439 (set_attr "mode" "<MODE>")])
4441 (define_insn "fix_trunc<mode>_i387_fisttp"
4442 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4443 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4444 (clobber (match_scratch:XF 2 "=&1f"))]
4445 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4447 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4448 && (TARGET_64BIT || <MODE>mode != DImode))
4449 && TARGET_SSE_MATH)"
4450 "* return output_fix_trunc (insn, operands, true);"
4451 [(set_attr "type" "fisttp")
4452 (set_attr "mode" "<MODE>")])
4454 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4455 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4456 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4457 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4458 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4459 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4461 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4462 && (TARGET_64BIT || <MODE>mode != DImode))
4463 && TARGET_SSE_MATH)"
4465 [(set_attr "type" "fisttp")
4466 (set_attr "mode" "<MODE>")])
4469 [(set (match_operand:SWI248x 0 "register_operand" "")
4470 (fix:SWI248x (match_operand 1 "register_operand" "")))
4471 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4472 (clobber (match_scratch 3 ""))]
4474 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4475 (clobber (match_dup 3))])
4476 (set (match_dup 0) (match_dup 2))])
4479 [(set (match_operand:SWI248x 0 "memory_operand" "")
4480 (fix:SWI248x (match_operand 1 "register_operand" "")))
4481 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4482 (clobber (match_scratch 3 ""))]
4484 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4485 (clobber (match_dup 3))])])
4487 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4488 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4489 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4490 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4491 ;; function in i386.c.
4492 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4493 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4494 (fix:SWI248x (match_operand 1 "register_operand" "")))
4495 (clobber (reg:CC FLAGS_REG))]
4496 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4498 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4499 && (TARGET_64BIT || <MODE>mode != DImode))
4500 && can_create_pseudo_p ()"
4505 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4507 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4508 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4509 if (memory_operand (operands[0], VOIDmode))
4510 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4511 operands[2], operands[3]));
4514 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4515 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4516 operands[2], operands[3],
4521 [(set_attr "type" "fistp")
4522 (set_attr "i387_cw" "trunc")
4523 (set_attr "mode" "<MODE>")])
4525 (define_insn "fix_truncdi_i387"
4526 [(set (match_operand:DI 0 "memory_operand" "=m")
4527 (fix:DI (match_operand 1 "register_operand" "f")))
4528 (use (match_operand:HI 2 "memory_operand" "m"))
4529 (use (match_operand:HI 3 "memory_operand" "m"))
4530 (clobber (match_scratch:XF 4 "=&1f"))]
4531 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4533 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4534 "* return output_fix_trunc (insn, operands, false);"
4535 [(set_attr "type" "fistp")
4536 (set_attr "i387_cw" "trunc")
4537 (set_attr "mode" "DI")])
4539 (define_insn "fix_truncdi_i387_with_temp"
4540 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4541 (fix:DI (match_operand 1 "register_operand" "f,f")))
4542 (use (match_operand:HI 2 "memory_operand" "m,m"))
4543 (use (match_operand:HI 3 "memory_operand" "m,m"))
4544 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4545 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4546 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4548 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4550 [(set_attr "type" "fistp")
4551 (set_attr "i387_cw" "trunc")
4552 (set_attr "mode" "DI")])
4555 [(set (match_operand:DI 0 "register_operand" "")
4556 (fix:DI (match_operand 1 "register_operand" "")))
4557 (use (match_operand:HI 2 "memory_operand" ""))
4558 (use (match_operand:HI 3 "memory_operand" ""))
4559 (clobber (match_operand:DI 4 "memory_operand" ""))
4560 (clobber (match_scratch 5 ""))]
4562 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4565 (clobber (match_dup 5))])
4566 (set (match_dup 0) (match_dup 4))])
4569 [(set (match_operand:DI 0 "memory_operand" "")
4570 (fix:DI (match_operand 1 "register_operand" "")))
4571 (use (match_operand:HI 2 "memory_operand" ""))
4572 (use (match_operand:HI 3 "memory_operand" ""))
4573 (clobber (match_operand:DI 4 "memory_operand" ""))
4574 (clobber (match_scratch 5 ""))]
4576 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4579 (clobber (match_dup 5))])])
4581 (define_insn "fix_trunc<mode>_i387"
4582 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4583 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4584 (use (match_operand:HI 2 "memory_operand" "m"))
4585 (use (match_operand:HI 3 "memory_operand" "m"))]
4586 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4588 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4589 "* return output_fix_trunc (insn, operands, false);"
4590 [(set_attr "type" "fistp")
4591 (set_attr "i387_cw" "trunc")
4592 (set_attr "mode" "<MODE>")])
4594 (define_insn "fix_trunc<mode>_i387_with_temp"
4595 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4596 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4597 (use (match_operand:HI 2 "memory_operand" "m,m"))
4598 (use (match_operand:HI 3 "memory_operand" "m,m"))
4599 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4600 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4602 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4604 [(set_attr "type" "fistp")
4605 (set_attr "i387_cw" "trunc")
4606 (set_attr "mode" "<MODE>")])
4609 [(set (match_operand:SWI24 0 "register_operand" "")
4610 (fix:SWI24 (match_operand 1 "register_operand" "")))
4611 (use (match_operand:HI 2 "memory_operand" ""))
4612 (use (match_operand:HI 3 "memory_operand" ""))
4613 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4615 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4617 (use (match_dup 3))])
4618 (set (match_dup 0) (match_dup 4))])
4621 [(set (match_operand:SWI24 0 "memory_operand" "")
4622 (fix:SWI24 (match_operand 1 "register_operand" "")))
4623 (use (match_operand:HI 2 "memory_operand" ""))
4624 (use (match_operand:HI 3 "memory_operand" ""))
4625 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4627 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4629 (use (match_dup 3))])])
4631 (define_insn "x86_fnstcw_1"
4632 [(set (match_operand:HI 0 "memory_operand" "=m")
4633 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4636 [(set (attr "length")
4637 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4638 (set_attr "mode" "HI")
4639 (set_attr "unit" "i387")
4640 (set_attr "bdver1_decode" "vector")])
4642 (define_insn "x86_fldcw_1"
4643 [(set (reg:HI FPCR_REG)
4644 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4647 [(set (attr "length")
4648 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4649 (set_attr "mode" "HI")
4650 (set_attr "unit" "i387")
4651 (set_attr "athlon_decode" "vector")
4652 (set_attr "amdfam10_decode" "vector")
4653 (set_attr "bdver1_decode" "vector")])
4655 ;; Conversion between fixed point and floating point.
4657 ;; Even though we only accept memory inputs, the backend _really_
4658 ;; wants to be able to do this between registers.
4660 (define_expand "floathi<mode>2"
4661 [(set (match_operand:X87MODEF 0 "register_operand" "")
4662 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4664 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4665 || TARGET_MIX_SSE_I387)")
4667 ;; Pre-reload splitter to add memory clobber to the pattern.
4668 (define_insn_and_split "*floathi<mode>2_1"
4669 [(set (match_operand:X87MODEF 0 "register_operand" "")
4670 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4673 || TARGET_MIX_SSE_I387)
4674 && can_create_pseudo_p ()"
4677 [(parallel [(set (match_dup 0)
4678 (float:X87MODEF (match_dup 1)))
4679 (clobber (match_dup 2))])]
4680 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4682 (define_insn "*floathi<mode>2_i387_with_temp"
4683 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4684 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4685 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4687 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4688 || TARGET_MIX_SSE_I387)"
4690 [(set_attr "type" "fmov,multi")
4691 (set_attr "mode" "<MODE>")
4692 (set_attr "unit" "*,i387")
4693 (set_attr "fp_int_src" "true")])
4695 (define_insn "*floathi<mode>2_i387"
4696 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4697 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4699 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4700 || TARGET_MIX_SSE_I387)"
4702 [(set_attr "type" "fmov")
4703 (set_attr "mode" "<MODE>")
4704 (set_attr "fp_int_src" "true")])
4707 [(set (match_operand:X87MODEF 0 "register_operand" "")
4708 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4709 (clobber (match_operand:HI 2 "memory_operand" ""))]
4711 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4712 || TARGET_MIX_SSE_I387)
4713 && reload_completed"
4714 [(set (match_dup 2) (match_dup 1))
4715 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4718 [(set (match_operand:X87MODEF 0 "register_operand" "")
4719 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4720 (clobber (match_operand:HI 2 "memory_operand" ""))]
4722 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4723 || TARGET_MIX_SSE_I387)
4724 && reload_completed"
4725 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4727 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4728 [(set (match_operand:X87MODEF 0 "register_operand" "")
4730 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4732 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4733 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4735 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4736 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4737 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4739 rtx reg = gen_reg_rtx (XFmode);
4740 rtx (*insn)(rtx, rtx);
4742 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4744 if (<X87MODEF:MODE>mode == SFmode)
4745 insn = gen_truncxfsf2;
4746 else if (<X87MODEF:MODE>mode == DFmode)
4747 insn = gen_truncxfdf2;
4751 emit_insn (insn (operands[0], reg));
4756 ;; Pre-reload splitter to add memory clobber to the pattern.
4757 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4758 [(set (match_operand:X87MODEF 0 "register_operand" "")
4759 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4761 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4762 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4763 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4764 || TARGET_MIX_SSE_I387))
4765 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4766 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4767 && ((<SWI48x:MODE>mode == SImode
4768 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4769 && optimize_function_for_speed_p (cfun)
4770 && flag_trapping_math)
4771 || !(TARGET_INTER_UNIT_CONVERSIONS
4772 || optimize_function_for_size_p (cfun)))))
4773 && can_create_pseudo_p ()"
4776 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4777 (clobber (match_dup 2))])]
4779 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4781 /* Avoid store forwarding (partial memory) stall penalty
4782 by passing DImode value through XMM registers. */
4783 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4784 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4785 && optimize_function_for_speed_p (cfun))
4787 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4794 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4795 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4797 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4798 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4799 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4800 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4802 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4803 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4804 (set_attr "unit" "*,i387,*,*,*")
4805 (set_attr "athlon_decode" "*,*,double,direct,double")
4806 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4807 (set_attr "bdver1_decode" "*,*,double,direct,double")
4808 (set_attr "fp_int_src" "true")])
4810 (define_insn "*floatsi<mode>2_vector_mixed"
4811 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4812 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4813 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4814 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4818 [(set_attr "type" "fmov,sseicvt")
4819 (set_attr "mode" "<MODE>,<ssevecmode>")
4820 (set_attr "unit" "i387,*")
4821 (set_attr "athlon_decode" "*,direct")
4822 (set_attr "amdfam10_decode" "*,double")
4823 (set_attr "bdver1_decode" "*,direct")
4824 (set_attr "fp_int_src" "true")])
4826 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4827 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4829 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4830 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4831 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4832 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4834 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4835 (set_attr "mode" "<MODEF:MODE>")
4836 (set_attr "unit" "*,i387,*,*")
4837 (set_attr "athlon_decode" "*,*,double,direct")
4838 (set_attr "amdfam10_decode" "*,*,vector,double")
4839 (set_attr "bdver1_decode" "*,*,double,direct")
4840 (set_attr "fp_int_src" "true")])
4843 [(set (match_operand:MODEF 0 "register_operand" "")
4844 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4845 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4846 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4847 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4848 && TARGET_INTER_UNIT_CONVERSIONS
4850 && (SSE_REG_P (operands[0])
4851 || (GET_CODE (operands[0]) == SUBREG
4852 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4853 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4856 [(set (match_operand:MODEF 0 "register_operand" "")
4857 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4858 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4859 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4860 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4861 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4863 && (SSE_REG_P (operands[0])
4864 || (GET_CODE (operands[0]) == SUBREG
4865 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4866 [(set (match_dup 2) (match_dup 1))
4867 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4869 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4870 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4872 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4873 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4874 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4875 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4878 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4879 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4880 [(set_attr "type" "fmov,sseicvt,sseicvt")
4881 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4882 (set_attr "mode" "<MODEF:MODE>")
4883 (set (attr "prefix_rex")
4885 (and (eq_attr "prefix" "maybe_vex")
4886 (match_test "<SWI48x:MODE>mode == DImode"))
4888 (const_string "*")))
4889 (set_attr "unit" "i387,*,*")
4890 (set_attr "athlon_decode" "*,double,direct")
4891 (set_attr "amdfam10_decode" "*,vector,double")
4892 (set_attr "bdver1_decode" "*,double,direct")
4893 (set_attr "fp_int_src" "true")])
4895 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4896 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4898 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4899 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4900 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4901 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4904 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4905 [(set_attr "type" "fmov,sseicvt")
4906 (set_attr "prefix" "orig,maybe_vex")
4907 (set_attr "mode" "<MODEF:MODE>")
4908 (set (attr "prefix_rex")
4910 (and (eq_attr "prefix" "maybe_vex")
4911 (match_test "<SWI48x:MODE>mode == DImode"))
4913 (const_string "*")))
4914 (set_attr "athlon_decode" "*,direct")
4915 (set_attr "amdfam10_decode" "*,double")
4916 (set_attr "bdver1_decode" "*,direct")
4917 (set_attr "fp_int_src" "true")])
4919 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4920 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4922 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4923 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4924 "TARGET_SSE2 && TARGET_SSE_MATH
4925 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4927 [(set_attr "type" "sseicvt")
4928 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4929 (set_attr "athlon_decode" "double,direct,double")
4930 (set_attr "amdfam10_decode" "vector,double,double")
4931 (set_attr "bdver1_decode" "double,direct,double")
4932 (set_attr "fp_int_src" "true")])
4934 (define_insn "*floatsi<mode>2_vector_sse"
4935 [(set (match_operand:MODEF 0 "register_operand" "=x")
4936 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4937 "TARGET_SSE2 && TARGET_SSE_MATH
4938 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4940 [(set_attr "type" "sseicvt")
4941 (set_attr "mode" "<MODE>")
4942 (set_attr "athlon_decode" "direct")
4943 (set_attr "amdfam10_decode" "double")
4944 (set_attr "bdver1_decode" "direct")
4945 (set_attr "fp_int_src" "true")])
4948 [(set (match_operand:MODEF 0 "register_operand" "")
4949 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4950 (clobber (match_operand:SI 2 "memory_operand" ""))]
4951 "TARGET_SSE2 && TARGET_SSE_MATH
4952 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4954 && (SSE_REG_P (operands[0])
4955 || (GET_CODE (operands[0]) == SUBREG
4956 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4959 rtx op1 = operands[1];
4961 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4963 if (GET_CODE (op1) == SUBREG)
4964 op1 = SUBREG_REG (op1);
4966 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4968 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4969 emit_insn (gen_sse2_loadld (operands[4],
4970 CONST0_RTX (V4SImode), operands[1]));
4972 /* We can ignore possible trapping value in the
4973 high part of SSE register for non-trapping math. */
4974 else if (SSE_REG_P (op1) && !flag_trapping_math)
4975 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4978 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4979 emit_move_insn (operands[2], operands[1]);
4980 emit_insn (gen_sse2_loadld (operands[4],
4981 CONST0_RTX (V4SImode), operands[2]));
4983 if (<ssevecmode>mode == V4SFmode)
4984 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4986 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4991 [(set (match_operand:MODEF 0 "register_operand" "")
4992 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4993 (clobber (match_operand:SI 2 "memory_operand" ""))]
4994 "TARGET_SSE2 && TARGET_SSE_MATH
4995 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4997 && (SSE_REG_P (operands[0])
4998 || (GET_CODE (operands[0]) == SUBREG
4999 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5002 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5004 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5006 emit_insn (gen_sse2_loadld (operands[4],
5007 CONST0_RTX (V4SImode), operands[1]));
5008 if (<ssevecmode>mode == V4SFmode)
5009 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5011 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5016 [(set (match_operand:MODEF 0 "register_operand" "")
5017 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5018 "TARGET_SSE2 && TARGET_SSE_MATH
5019 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5021 && (SSE_REG_P (operands[0])
5022 || (GET_CODE (operands[0]) == SUBREG
5023 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5026 rtx op1 = operands[1];
5028 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5030 if (GET_CODE (op1) == SUBREG)
5031 op1 = SUBREG_REG (op1);
5033 if (GENERAL_REG_P (op1))
5035 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5036 if (TARGET_INTER_UNIT_MOVES)
5037 emit_insn (gen_sse2_loadld (operands[4],
5038 CONST0_RTX (V4SImode), operands[1]));
5041 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5043 emit_insn (gen_sse2_loadld (operands[4],
5044 CONST0_RTX (V4SImode), operands[5]));
5045 ix86_free_from_memory (GET_MODE (operands[1]));
5048 /* We can ignore possible trapping value in the
5049 high part of SSE register for non-trapping math. */
5050 else if (SSE_REG_P (op1) && !flag_trapping_math)
5051 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5054 if (<ssevecmode>mode == V4SFmode)
5055 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5057 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5062 [(set (match_operand:MODEF 0 "register_operand" "")
5063 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5064 "TARGET_SSE2 && TARGET_SSE_MATH
5065 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5067 && (SSE_REG_P (operands[0])
5068 || (GET_CODE (operands[0]) == SUBREG
5069 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5072 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5074 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5076 emit_insn (gen_sse2_loadld (operands[4],
5077 CONST0_RTX (V4SImode), operands[1]));
5078 if (<ssevecmode>mode == V4SFmode)
5079 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5081 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5085 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5086 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5088 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5089 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5090 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5091 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5093 [(set_attr "type" "sseicvt")
5094 (set_attr "mode" "<MODEF:MODE>")
5095 (set_attr "athlon_decode" "double,direct")
5096 (set_attr "amdfam10_decode" "vector,double")
5097 (set_attr "bdver1_decode" "double,direct")
5098 (set_attr "fp_int_src" "true")])
5100 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5101 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5103 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5104 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5105 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5106 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5107 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5108 [(set_attr "type" "sseicvt")
5109 (set_attr "prefix" "maybe_vex")
5110 (set_attr "mode" "<MODEF:MODE>")
5111 (set (attr "prefix_rex")
5113 (and (eq_attr "prefix" "maybe_vex")
5114 (match_test "<SWI48x:MODE>mode == DImode"))
5116 (const_string "*")))
5117 (set_attr "athlon_decode" "double,direct")
5118 (set_attr "amdfam10_decode" "vector,double")
5119 (set_attr "bdver1_decode" "double,direct")
5120 (set_attr "fp_int_src" "true")])
5123 [(set (match_operand:MODEF 0 "register_operand" "")
5124 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5125 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5126 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5127 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5128 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5130 && (SSE_REG_P (operands[0])
5131 || (GET_CODE (operands[0]) == SUBREG
5132 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5133 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5135 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5136 [(set (match_operand:MODEF 0 "register_operand" "=x")
5138 (match_operand:SWI48x 1 "memory_operand" "m")))]
5139 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5140 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5141 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5142 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5143 [(set_attr "type" "sseicvt")
5144 (set_attr "prefix" "maybe_vex")
5145 (set_attr "mode" "<MODEF:MODE>")
5146 (set (attr "prefix_rex")
5148 (and (eq_attr "prefix" "maybe_vex")
5149 (match_test "<SWI48x:MODE>mode == DImode"))
5151 (const_string "*")))
5152 (set_attr "athlon_decode" "direct")
5153 (set_attr "amdfam10_decode" "double")
5154 (set_attr "bdver1_decode" "direct")
5155 (set_attr "fp_int_src" "true")])
5158 [(set (match_operand:MODEF 0 "register_operand" "")
5159 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5160 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5161 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5162 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5163 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5165 && (SSE_REG_P (operands[0])
5166 || (GET_CODE (operands[0]) == SUBREG
5167 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5168 [(set (match_dup 2) (match_dup 1))
5169 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5172 [(set (match_operand:MODEF 0 "register_operand" "")
5173 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5174 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5175 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5176 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5178 && (SSE_REG_P (operands[0])
5179 || (GET_CODE (operands[0]) == SUBREG
5180 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5181 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5183 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5184 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5186 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5187 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5189 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5193 [(set_attr "type" "fmov,multi")
5194 (set_attr "mode" "<X87MODEF:MODE>")
5195 (set_attr "unit" "*,i387")
5196 (set_attr "fp_int_src" "true")])
5198 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5199 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5201 (match_operand:SWI48x 1 "memory_operand" "m")))]
5203 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5205 [(set_attr "type" "fmov")
5206 (set_attr "mode" "<X87MODEF:MODE>")
5207 (set_attr "fp_int_src" "true")])
5210 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5211 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5212 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5214 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5215 && reload_completed"
5216 [(set (match_dup 2) (match_dup 1))
5217 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5220 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5221 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5222 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5224 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5225 && reload_completed"
5226 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5228 ;; Avoid store forwarding (partial memory) stall penalty
5229 ;; by passing DImode value through XMM registers. */
5231 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5232 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5234 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5235 (clobber (match_scratch:V4SI 3 "=X,x"))
5236 (clobber (match_scratch:V4SI 4 "=X,x"))
5237 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5238 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5239 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5240 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5242 [(set_attr "type" "multi")
5243 (set_attr "mode" "<X87MODEF:MODE>")
5244 (set_attr "unit" "i387")
5245 (set_attr "fp_int_src" "true")])
5248 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5249 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5250 (clobber (match_scratch:V4SI 3 ""))
5251 (clobber (match_scratch:V4SI 4 ""))
5252 (clobber (match_operand:DI 2 "memory_operand" ""))]
5253 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5254 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5255 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5256 && reload_completed"
5257 [(set (match_dup 2) (match_dup 3))
5258 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5260 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5261 Assemble the 64-bit DImode value in an xmm register. */
5262 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5263 gen_rtx_SUBREG (SImode, operands[1], 0)));
5264 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5265 gen_rtx_SUBREG (SImode, operands[1], 4)));
5266 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5269 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5273 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5274 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5275 (clobber (match_scratch:V4SI 3 ""))
5276 (clobber (match_scratch:V4SI 4 ""))
5277 (clobber (match_operand:DI 2 "memory_operand" ""))]
5278 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5279 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5280 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5281 && reload_completed"
5282 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5284 ;; Avoid store forwarding (partial memory) stall penalty by extending
5285 ;; SImode value to DImode through XMM register instead of pushing two
5286 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5287 ;; targets benefit from this optimization. Also note that fild
5288 ;; loads from memory only.
5290 (define_insn "*floatunssi<mode>2_1"
5291 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5292 (unsigned_float:X87MODEF
5293 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5294 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5295 (clobber (match_scratch:SI 3 "=X,x"))]
5297 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5300 [(set_attr "type" "multi")
5301 (set_attr "mode" "<MODE>")])
5304 [(set (match_operand:X87MODEF 0 "register_operand" "")
5305 (unsigned_float:X87MODEF
5306 (match_operand:SI 1 "register_operand" "")))
5307 (clobber (match_operand:DI 2 "memory_operand" ""))
5308 (clobber (match_scratch:SI 3 ""))]
5310 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5312 && reload_completed"
5313 [(set (match_dup 2) (match_dup 1))
5315 (float:X87MODEF (match_dup 2)))]
5316 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5319 [(set (match_operand:X87MODEF 0 "register_operand" "")
5320 (unsigned_float:X87MODEF
5321 (match_operand:SI 1 "memory_operand" "")))
5322 (clobber (match_operand:DI 2 "memory_operand" ""))
5323 (clobber (match_scratch:SI 3 ""))]
5325 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5327 && reload_completed"
5328 [(set (match_dup 2) (match_dup 3))
5330 (float:X87MODEF (match_dup 2)))]
5332 emit_move_insn (operands[3], operands[1]);
5333 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5336 (define_expand "floatunssi<mode>2"
5338 [(set (match_operand:X87MODEF 0 "register_operand" "")
5339 (unsigned_float:X87MODEF
5340 (match_operand:SI 1 "nonimmediate_operand" "")))
5341 (clobber (match_dup 2))
5342 (clobber (match_scratch:SI 3 ""))])]
5344 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5346 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5348 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5350 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5354 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
5357 (define_expand "floatunsdisf2"
5358 [(use (match_operand:SF 0 "register_operand" ""))
5359 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5360 "TARGET_64BIT && TARGET_SSE_MATH"
5361 "x86_emit_floatuns (operands); DONE;")
5363 (define_expand "floatunsdidf2"
5364 [(use (match_operand:DF 0 "register_operand" ""))
5365 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5366 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5367 && TARGET_SSE2 && TARGET_SSE_MATH"
5370 x86_emit_floatuns (operands);
5372 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5376 ;; Load effective address instructions
5378 (define_insn_and_split "*lea<mode>"
5379 [(set (match_operand:SWI48 0 "register_operand" "=r")
5380 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5383 rtx addr = operands[1];
5385 if (SImode_address_operand (addr, VOIDmode))
5387 gcc_assert (TARGET_64BIT);
5388 return "lea{l}\t{%E1, %k0|%k0, %E1}";
5391 return "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}";
5393 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5396 ix86_split_lea_for_addr (operands, <MODE>mode);
5399 [(set_attr "type" "lea")
5402 (match_operand 1 "SImode_address_operand")
5404 (const_string "<MODE>")))])
5408 (define_expand "add<mode>3"
5409 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5410 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5411 (match_operand:SDWIM 2 "<general_operand>" "")))]
5413 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5415 (define_insn_and_split "*add<dwi>3_doubleword"
5416 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5418 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5419 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5420 (clobber (reg:CC FLAGS_REG))]
5421 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5424 [(parallel [(set (reg:CC FLAGS_REG)
5425 (unspec:CC [(match_dup 1) (match_dup 2)]
5428 (plus:DWIH (match_dup 1) (match_dup 2)))])
5429 (parallel [(set (match_dup 3)
5433 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5435 (clobber (reg:CC FLAGS_REG))])]
5436 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5438 (define_insn "*add<mode>3_cc"
5439 [(set (reg:CC FLAGS_REG)
5441 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5442 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5444 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5445 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5446 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5447 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5448 [(set_attr "type" "alu")
5449 (set_attr "mode" "<MODE>")])
5451 (define_insn "addqi3_cc"
5452 [(set (reg:CC FLAGS_REG)
5454 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5455 (match_operand:QI 2 "general_operand" "qn,qm")]
5457 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5458 (plus:QI (match_dup 1) (match_dup 2)))]
5459 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5460 "add{b}\t{%2, %0|%0, %2}"
5461 [(set_attr "type" "alu")
5462 (set_attr "mode" "QI")])
5464 (define_insn "*add<mode>_1"
5465 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5467 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5468 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5469 (clobber (reg:CC FLAGS_REG))]
5470 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5472 switch (get_attr_type (insn))
5478 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5479 if (operands[2] == const1_rtx)
5480 return "inc{<imodesuffix>}\t%0";
5483 gcc_assert (operands[2] == constm1_rtx);
5484 return "dec{<imodesuffix>}\t%0";
5488 /* For most processors, ADD is faster than LEA. This alternative
5489 was added to use ADD as much as possible. */
5490 if (which_alternative == 2)
5493 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5496 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5497 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5498 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5500 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5504 (cond [(eq_attr "alternative" "3")
5505 (const_string "lea")
5506 (match_operand:SWI48 2 "incdec_operand" "")
5507 (const_string "incdec")
5509 (const_string "alu")))
5510 (set (attr "length_immediate")
5512 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5514 (const_string "*")))
5515 (set_attr "mode" "<MODE>")])
5517 ;; It may seem that nonimmediate operand is proper one for operand 1.
5518 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5519 ;; we take care in ix86_binary_operator_ok to not allow two memory
5520 ;; operands so proper swapping will be done in reload. This allow
5521 ;; patterns constructed from addsi_1 to match.
5523 (define_insn "addsi_1_zext"
5524 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5526 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5527 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5528 (clobber (reg:CC FLAGS_REG))]
5529 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5531 switch (get_attr_type (insn))
5537 if (operands[2] == const1_rtx)
5538 return "inc{l}\t%k0";
5541 gcc_assert (operands[2] == constm1_rtx);
5542 return "dec{l}\t%k0";
5546 /* For most processors, ADD is faster than LEA. This alternative
5547 was added to use ADD as much as possible. */
5548 if (which_alternative == 1)
5551 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5554 if (x86_maybe_negate_const_int (&operands[2], SImode))
5555 return "sub{l}\t{%2, %k0|%k0, %2}";
5557 return "add{l}\t{%2, %k0|%k0, %2}";
5561 (cond [(eq_attr "alternative" "2")
5562 (const_string "lea")
5563 (match_operand:SI 2 "incdec_operand" "")
5564 (const_string "incdec")
5566 (const_string "alu")))
5567 (set (attr "length_immediate")
5569 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5571 (const_string "*")))
5572 (set_attr "mode" "SI")])
5574 (define_insn "*addhi_1"
5575 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5576 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5577 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5578 (clobber (reg:CC FLAGS_REG))]
5579 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5581 switch (get_attr_type (insn))
5587 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5588 if (operands[2] == const1_rtx)
5589 return "inc{w}\t%0";
5592 gcc_assert (operands[2] == constm1_rtx);
5593 return "dec{w}\t%0";
5597 /* For most processors, ADD is faster than LEA. This alternative
5598 was added to use ADD as much as possible. */
5599 if (which_alternative == 2)
5602 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5605 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5606 if (x86_maybe_negate_const_int (&operands[2], HImode))
5607 return "sub{w}\t{%2, %0|%0, %2}";
5609 return "add{w}\t{%2, %0|%0, %2}";
5613 (cond [(eq_attr "alternative" "3")
5614 (const_string "lea")
5615 (match_operand:HI 2 "incdec_operand" "")
5616 (const_string "incdec")
5618 (const_string "alu")))
5619 (set (attr "length_immediate")
5621 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5623 (const_string "*")))
5624 (set_attr "mode" "HI,HI,HI,SI")])
5626 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5627 (define_insn "*addqi_1"
5628 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5629 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5630 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5631 (clobber (reg:CC FLAGS_REG))]
5632 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5634 bool widen = (which_alternative == 3 || which_alternative == 4);
5636 switch (get_attr_type (insn))
5642 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5643 if (operands[2] == const1_rtx)
5644 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5647 gcc_assert (operands[2] == constm1_rtx);
5648 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5652 /* For most processors, ADD is faster than LEA. These alternatives
5653 were added to use ADD as much as possible. */
5654 if (which_alternative == 2 || which_alternative == 4)
5657 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5660 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5661 if (x86_maybe_negate_const_int (&operands[2], QImode))
5664 return "sub{l}\t{%2, %k0|%k0, %2}";
5666 return "sub{b}\t{%2, %0|%0, %2}";
5669 return "add{l}\t{%k2, %k0|%k0, %k2}";
5671 return "add{b}\t{%2, %0|%0, %2}";
5675 (cond [(eq_attr "alternative" "5")
5676 (const_string "lea")
5677 (match_operand:QI 2 "incdec_operand" "")
5678 (const_string "incdec")
5680 (const_string "alu")))
5681 (set (attr "length_immediate")
5683 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5685 (const_string "*")))
5686 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5688 (define_insn "*addqi_1_slp"
5689 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5690 (plus:QI (match_dup 0)
5691 (match_operand:QI 1 "general_operand" "qn,qm")))
5692 (clobber (reg:CC FLAGS_REG))]
5693 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5694 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5696 switch (get_attr_type (insn))
5699 if (operands[1] == const1_rtx)
5700 return "inc{b}\t%0";
5703 gcc_assert (operands[1] == constm1_rtx);
5704 return "dec{b}\t%0";
5708 if (x86_maybe_negate_const_int (&operands[1], QImode))
5709 return "sub{b}\t{%1, %0|%0, %1}";
5711 return "add{b}\t{%1, %0|%0, %1}";
5715 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5716 (const_string "incdec")
5717 (const_string "alu1")))
5718 (set (attr "memory")
5719 (if_then_else (match_operand 1 "memory_operand" "")
5720 (const_string "load")
5721 (const_string "none")))
5722 (set_attr "mode" "QI")])
5724 ;; Split non destructive adds if we cannot use lea.
5726 [(set (match_operand:SWI48 0 "register_operand" "")
5727 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5728 (match_operand:SWI48 2 "nonmemory_operand" "")))
5729 (clobber (reg:CC FLAGS_REG))]
5730 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5731 [(set (match_dup 0) (match_dup 1))
5732 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5733 (clobber (reg:CC FLAGS_REG))])])
5735 ;; Convert add to the lea pattern to avoid flags dependency.
5737 [(set (match_operand:SWI 0 "register_operand" "")
5738 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5739 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5740 (clobber (reg:CC FLAGS_REG))]
5741 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5744 enum machine_mode mode = <MODE>mode;
5747 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5750 operands[0] = gen_lowpart (mode, operands[0]);
5751 operands[1] = gen_lowpart (mode, operands[1]);
5752 operands[2] = gen_lowpart (mode, operands[2]);
5755 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5757 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5761 ;; Convert add to the lea pattern to avoid flags dependency.
5763 [(set (match_operand:DI 0 "register_operand" "")
5765 (plus:SI (match_operand:SI 1 "register_operand" "")
5766 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5770 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5772 (define_insn "*add<mode>_2"
5773 [(set (reg FLAGS_REG)
5776 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5777 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5779 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5780 (plus:SWI (match_dup 1) (match_dup 2)))]
5781 "ix86_match_ccmode (insn, CCGOCmode)
5782 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5784 switch (get_attr_type (insn))
5787 if (operands[2] == const1_rtx)
5788 return "inc{<imodesuffix>}\t%0";
5791 gcc_assert (operands[2] == constm1_rtx);
5792 return "dec{<imodesuffix>}\t%0";
5796 if (which_alternative == 2)
5799 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5802 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5803 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5804 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5806 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5810 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5811 (const_string "incdec")
5812 (const_string "alu")))
5813 (set (attr "length_immediate")
5815 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5817 (const_string "*")))
5818 (set_attr "mode" "<MODE>")])
5820 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5821 (define_insn "*addsi_2_zext"
5822 [(set (reg FLAGS_REG)
5824 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5825 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5827 (set (match_operand:DI 0 "register_operand" "=r,r")
5828 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5829 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5830 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5832 switch (get_attr_type (insn))
5835 if (operands[2] == const1_rtx)
5836 return "inc{l}\t%k0";
5839 gcc_assert (operands[2] == constm1_rtx);
5840 return "dec{l}\t%k0";
5844 if (which_alternative == 1)
5847 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5850 if (x86_maybe_negate_const_int (&operands[2], SImode))
5851 return "sub{l}\t{%2, %k0|%k0, %2}";
5853 return "add{l}\t{%2, %k0|%k0, %2}";
5857 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5858 (const_string "incdec")
5859 (const_string "alu")))
5860 (set (attr "length_immediate")
5862 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5864 (const_string "*")))
5865 (set_attr "mode" "SI")])
5867 (define_insn "*add<mode>_3"
5868 [(set (reg FLAGS_REG)
5870 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5871 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5872 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5873 "ix86_match_ccmode (insn, CCZmode)
5874 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5876 switch (get_attr_type (insn))
5879 if (operands[2] == const1_rtx)
5880 return "inc{<imodesuffix>}\t%0";
5883 gcc_assert (operands[2] == constm1_rtx);
5884 return "dec{<imodesuffix>}\t%0";
5888 if (which_alternative == 1)
5891 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5894 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5895 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5896 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5898 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5902 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5903 (const_string "incdec")
5904 (const_string "alu")))
5905 (set (attr "length_immediate")
5907 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5909 (const_string "*")))
5910 (set_attr "mode" "<MODE>")])
5912 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5913 (define_insn "*addsi_3_zext"
5914 [(set (reg FLAGS_REG)
5916 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5917 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5918 (set (match_operand:DI 0 "register_operand" "=r,r")
5919 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5920 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5921 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5923 switch (get_attr_type (insn))
5926 if (operands[2] == const1_rtx)
5927 return "inc{l}\t%k0";
5930 gcc_assert (operands[2] == constm1_rtx);
5931 return "dec{l}\t%k0";
5935 if (which_alternative == 1)
5938 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5941 if (x86_maybe_negate_const_int (&operands[2], SImode))
5942 return "sub{l}\t{%2, %k0|%k0, %2}";
5944 return "add{l}\t{%2, %k0|%k0, %2}";
5948 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5949 (const_string "incdec")
5950 (const_string "alu")))
5951 (set (attr "length_immediate")
5953 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5955 (const_string "*")))
5956 (set_attr "mode" "SI")])
5958 ; For comparisons against 1, -1 and 128, we may generate better code
5959 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5960 ; is matched then. We can't accept general immediate, because for
5961 ; case of overflows, the result is messed up.
5962 ; Also carry flag is reversed compared to cmp, so this conversion is valid
5963 ; only for comparisons not depending on it.
5965 (define_insn "*adddi_4"
5966 [(set (reg FLAGS_REG)
5968 (match_operand:DI 1 "nonimmediate_operand" "0")
5969 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
5970 (clobber (match_scratch:DI 0 "=rm"))]
5972 && ix86_match_ccmode (insn, CCGCmode)"
5974 switch (get_attr_type (insn))
5977 if (operands[2] == constm1_rtx)
5978 return "inc{q}\t%0";
5981 gcc_assert (operands[2] == const1_rtx);
5982 return "dec{q}\t%0";
5986 if (x86_maybe_negate_const_int (&operands[2], DImode))
5987 return "add{q}\t{%2, %0|%0, %2}";
5989 return "sub{q}\t{%2, %0|%0, %2}";
5993 (if_then_else (match_operand:DI 2 "incdec_operand" "")
5994 (const_string "incdec")
5995 (const_string "alu")))
5996 (set (attr "length_immediate")
5998 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6000 (const_string "*")))
6001 (set_attr "mode" "DI")])
6003 ; For comparisons against 1, -1 and 128, we may generate better code
6004 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6005 ; is matched then. We can't accept general immediate, because for
6006 ; case of overflows, the result is messed up.
6007 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6008 ; only for comparisons not depending on it.
6010 (define_insn "*add<mode>_4"
6011 [(set (reg FLAGS_REG)
6013 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6014 (match_operand:SWI124 2 "const_int_operand" "n")))
6015 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6016 "ix86_match_ccmode (insn, CCGCmode)"
6018 switch (get_attr_type (insn))
6021 if (operands[2] == constm1_rtx)
6022 return "inc{<imodesuffix>}\t%0";
6025 gcc_assert (operands[2] == const1_rtx);
6026 return "dec{<imodesuffix>}\t%0";
6030 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6031 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6033 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6037 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6038 (const_string "incdec")
6039 (const_string "alu")))
6040 (set (attr "length_immediate")
6042 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6044 (const_string "*")))
6045 (set_attr "mode" "<MODE>")])
6047 (define_insn "*add<mode>_5"
6048 [(set (reg FLAGS_REG)
6051 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6052 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6054 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6055 "ix86_match_ccmode (insn, CCGOCmode)
6056 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6058 switch (get_attr_type (insn))
6061 if (operands[2] == const1_rtx)
6062 return "inc{<imodesuffix>}\t%0";
6065 gcc_assert (operands[2] == constm1_rtx);
6066 return "dec{<imodesuffix>}\t%0";
6070 if (which_alternative == 1)
6073 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6076 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6077 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6078 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6080 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6084 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6085 (const_string "incdec")
6086 (const_string "alu")))
6087 (set (attr "length_immediate")
6089 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6091 (const_string "*")))
6092 (set_attr "mode" "<MODE>")])
6094 (define_insn "*addqi_ext_1_rex64"
6095 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6100 (match_operand 1 "ext_register_operand" "0")
6103 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6104 (clobber (reg:CC FLAGS_REG))]
6107 switch (get_attr_type (insn))
6110 if (operands[2] == const1_rtx)
6111 return "inc{b}\t%h0";
6114 gcc_assert (operands[2] == constm1_rtx);
6115 return "dec{b}\t%h0";
6119 return "add{b}\t{%2, %h0|%h0, %2}";
6123 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6124 (const_string "incdec")
6125 (const_string "alu")))
6126 (set_attr "modrm" "1")
6127 (set_attr "mode" "QI")])
6129 (define_insn "addqi_ext_1"
6130 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6135 (match_operand 1 "ext_register_operand" "0")
6138 (match_operand:QI 2 "general_operand" "Qmn")))
6139 (clobber (reg:CC FLAGS_REG))]
6142 switch (get_attr_type (insn))
6145 if (operands[2] == const1_rtx)
6146 return "inc{b}\t%h0";
6149 gcc_assert (operands[2] == constm1_rtx);
6150 return "dec{b}\t%h0";
6154 return "add{b}\t{%2, %h0|%h0, %2}";
6158 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6159 (const_string "incdec")
6160 (const_string "alu")))
6161 (set_attr "modrm" "1")
6162 (set_attr "mode" "QI")])
6164 (define_insn "*addqi_ext_2"
6165 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6170 (match_operand 1 "ext_register_operand" "%0")
6174 (match_operand 2 "ext_register_operand" "Q")
6177 (clobber (reg:CC FLAGS_REG))]
6179 "add{b}\t{%h2, %h0|%h0, %h2}"
6180 [(set_attr "type" "alu")
6181 (set_attr "mode" "QI")])
6183 ;; The lea patterns for modes less than 32 bits need to be matched by
6184 ;; several insns converted to real lea by splitters.
6186 (define_insn_and_split "*lea_general_1"
6187 [(set (match_operand 0 "register_operand" "=r")
6188 (plus (plus (match_operand 1 "index_register_operand" "l")
6189 (match_operand 2 "register_operand" "r"))
6190 (match_operand 3 "immediate_operand" "i")))]
6191 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6192 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6193 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6194 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6195 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6196 || GET_MODE (operands[3]) == VOIDmode)"
6198 "&& reload_completed"
6201 enum machine_mode mode = SImode;
6204 operands[0] = gen_lowpart (mode, operands[0]);
6205 operands[1] = gen_lowpart (mode, operands[1]);
6206 operands[2] = gen_lowpart (mode, operands[2]);
6207 operands[3] = gen_lowpart (mode, operands[3]);
6209 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6212 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6215 [(set_attr "type" "lea")
6216 (set_attr "mode" "SI")])
6218 (define_insn_and_split "*lea_general_2"
6219 [(set (match_operand 0 "register_operand" "=r")
6220 (plus (mult (match_operand 1 "index_register_operand" "l")
6221 (match_operand 2 "const248_operand" "n"))
6222 (match_operand 3 "nonmemory_operand" "ri")))]
6223 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6224 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6225 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6226 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6227 || GET_MODE (operands[3]) == VOIDmode)"
6229 "&& reload_completed"
6232 enum machine_mode mode = SImode;
6235 operands[0] = gen_lowpart (mode, operands[0]);
6236 operands[1] = gen_lowpart (mode, operands[1]);
6237 operands[3] = gen_lowpart (mode, operands[3]);
6239 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6242 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6245 [(set_attr "type" "lea")
6246 (set_attr "mode" "SI")])
6248 (define_insn_and_split "*lea_general_3"
6249 [(set (match_operand 0 "register_operand" "=r")
6250 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6251 (match_operand 2 "const248_operand" "n"))
6252 (match_operand 3 "register_operand" "r"))
6253 (match_operand 4 "immediate_operand" "i")))]
6254 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6255 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6256 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6257 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6259 "&& reload_completed"
6262 enum machine_mode mode = SImode;
6265 operands[0] = gen_lowpart (mode, operands[0]);
6266 operands[1] = gen_lowpart (mode, operands[1]);
6267 operands[3] = gen_lowpart (mode, operands[3]);
6268 operands[4] = gen_lowpart (mode, operands[4]);
6270 pat = gen_rtx_PLUS (mode,
6272 gen_rtx_MULT (mode, operands[1],
6277 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6280 [(set_attr "type" "lea")
6281 (set_attr "mode" "SI")])
6283 (define_insn_and_split "*lea_general_4"
6284 [(set (match_operand 0 "register_operand" "=r")
6286 (match_operand 1 "index_register_operand" "l")
6287 (match_operand 2 "const_int_operand" "n"))
6288 (match_operand 3 "const_int_operand" "n")))]
6289 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6290 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6291 || GET_MODE (operands[0]) == SImode
6292 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6293 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6294 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6295 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6296 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6298 "&& reload_completed"
6301 enum machine_mode mode = GET_MODE (operands[0]);
6304 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6307 operands[0] = gen_lowpart (mode, operands[0]);
6308 operands[1] = gen_lowpart (mode, operands[1]);
6311 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6313 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6314 INTVAL (operands[3]));
6316 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6319 [(set_attr "type" "lea")
6321 (if_then_else (match_operand:DI 0 "" "")
6323 (const_string "SI")))])
6325 ;; Subtract instructions
6327 (define_expand "sub<mode>3"
6328 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6329 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6330 (match_operand:SDWIM 2 "<general_operand>" "")))]
6332 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6334 (define_insn_and_split "*sub<dwi>3_doubleword"
6335 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6337 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6338 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6339 (clobber (reg:CC FLAGS_REG))]
6340 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6343 [(parallel [(set (reg:CC FLAGS_REG)
6344 (compare:CC (match_dup 1) (match_dup 2)))
6346 (minus:DWIH (match_dup 1) (match_dup 2)))])
6347 (parallel [(set (match_dup 3)
6351 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6353 (clobber (reg:CC FLAGS_REG))])]
6354 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6356 (define_insn "*sub<mode>_1"
6357 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6359 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6360 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6361 (clobber (reg:CC FLAGS_REG))]
6362 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6363 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6364 [(set_attr "type" "alu")
6365 (set_attr "mode" "<MODE>")])
6367 (define_insn "*subsi_1_zext"
6368 [(set (match_operand:DI 0 "register_operand" "=r")
6370 (minus:SI (match_operand:SI 1 "register_operand" "0")
6371 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6372 (clobber (reg:CC FLAGS_REG))]
6373 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6374 "sub{l}\t{%2, %k0|%k0, %2}"
6375 [(set_attr "type" "alu")
6376 (set_attr "mode" "SI")])
6378 (define_insn "*subqi_1_slp"
6379 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6380 (minus:QI (match_dup 0)
6381 (match_operand:QI 1 "general_operand" "qn,qm")))
6382 (clobber (reg:CC FLAGS_REG))]
6383 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6384 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6385 "sub{b}\t{%1, %0|%0, %1}"
6386 [(set_attr "type" "alu1")
6387 (set_attr "mode" "QI")])
6389 (define_insn "*sub<mode>_2"
6390 [(set (reg FLAGS_REG)
6393 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6394 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6396 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6397 (minus:SWI (match_dup 1) (match_dup 2)))]
6398 "ix86_match_ccmode (insn, CCGOCmode)
6399 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6400 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6401 [(set_attr "type" "alu")
6402 (set_attr "mode" "<MODE>")])
6404 (define_insn "*subsi_2_zext"
6405 [(set (reg FLAGS_REG)
6407 (minus:SI (match_operand:SI 1 "register_operand" "0")
6408 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6410 (set (match_operand:DI 0 "register_operand" "=r")
6412 (minus:SI (match_dup 1)
6414 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6415 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6416 "sub{l}\t{%2, %k0|%k0, %2}"
6417 [(set_attr "type" "alu")
6418 (set_attr "mode" "SI")])
6420 (define_insn "*sub<mode>_3"
6421 [(set (reg FLAGS_REG)
6422 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6423 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6424 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6425 (minus:SWI (match_dup 1) (match_dup 2)))]
6426 "ix86_match_ccmode (insn, CCmode)
6427 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6428 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6429 [(set_attr "type" "alu")
6430 (set_attr "mode" "<MODE>")])
6432 (define_insn "*subsi_3_zext"
6433 [(set (reg FLAGS_REG)
6434 (compare (match_operand:SI 1 "register_operand" "0")
6435 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6436 (set (match_operand:DI 0 "register_operand" "=r")
6438 (minus:SI (match_dup 1)
6440 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6441 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6442 "sub{l}\t{%2, %1|%1, %2}"
6443 [(set_attr "type" "alu")
6444 (set_attr "mode" "SI")])
6446 ;; Add with carry and subtract with borrow
6448 (define_expand "<plusminus_insn><mode>3_carry"
6450 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6452 (match_operand:SWI 1 "nonimmediate_operand" "")
6453 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6454 [(match_operand 3 "flags_reg_operand" "")
6456 (match_operand:SWI 2 "<general_operand>" ""))))
6457 (clobber (reg:CC FLAGS_REG))])]
6458 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6460 (define_insn "*<plusminus_insn><mode>3_carry"
6461 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6463 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6465 (match_operator 3 "ix86_carry_flag_operator"
6466 [(reg FLAGS_REG) (const_int 0)])
6467 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6468 (clobber (reg:CC FLAGS_REG))]
6469 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6470 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6471 [(set_attr "type" "alu")
6472 (set_attr "use_carry" "1")
6473 (set_attr "pent_pair" "pu")
6474 (set_attr "mode" "<MODE>")])
6476 (define_insn "*addsi3_carry_zext"
6477 [(set (match_operand:DI 0 "register_operand" "=r")
6479 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6480 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6481 [(reg FLAGS_REG) (const_int 0)])
6482 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6483 (clobber (reg:CC FLAGS_REG))]
6484 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6485 "adc{l}\t{%2, %k0|%k0, %2}"
6486 [(set_attr "type" "alu")
6487 (set_attr "use_carry" "1")
6488 (set_attr "pent_pair" "pu")
6489 (set_attr "mode" "SI")])
6491 (define_insn "*subsi3_carry_zext"
6492 [(set (match_operand:DI 0 "register_operand" "=r")
6494 (minus:SI (match_operand:SI 1 "register_operand" "0")
6495 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6496 [(reg FLAGS_REG) (const_int 0)])
6497 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6498 (clobber (reg:CC FLAGS_REG))]
6499 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6500 "sbb{l}\t{%2, %k0|%k0, %2}"
6501 [(set_attr "type" "alu")
6502 (set_attr "pent_pair" "pu")
6503 (set_attr "mode" "SI")])
6505 ;; Overflow setting add and subtract instructions
6507 (define_insn "*add<mode>3_cconly_overflow"
6508 [(set (reg:CCC FLAGS_REG)
6511 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6512 (match_operand:SWI 2 "<general_operand>" "<g>"))
6514 (clobber (match_scratch:SWI 0 "=<r>"))]
6515 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6516 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6517 [(set_attr "type" "alu")
6518 (set_attr "mode" "<MODE>")])
6520 (define_insn "*sub<mode>3_cconly_overflow"
6521 [(set (reg:CCC FLAGS_REG)
6524 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6525 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6528 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6529 [(set_attr "type" "icmp")
6530 (set_attr "mode" "<MODE>")])
6532 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6533 [(set (reg:CCC FLAGS_REG)
6536 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6537 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6539 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6540 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6541 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6542 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6543 [(set_attr "type" "alu")
6544 (set_attr "mode" "<MODE>")])
6546 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6547 [(set (reg:CCC FLAGS_REG)
6550 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6551 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6553 (set (match_operand:DI 0 "register_operand" "=r")
6554 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6555 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6556 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6557 [(set_attr "type" "alu")
6558 (set_attr "mode" "SI")])
6560 ;; The patterns that match these are at the end of this file.
6562 (define_expand "<plusminus_insn>xf3"
6563 [(set (match_operand:XF 0 "register_operand" "")
6565 (match_operand:XF 1 "register_operand" "")
6566 (match_operand:XF 2 "register_operand" "")))]
6569 (define_expand "<plusminus_insn><mode>3"
6570 [(set (match_operand:MODEF 0 "register_operand" "")
6572 (match_operand:MODEF 1 "register_operand" "")
6573 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6574 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6575 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6577 ;; Multiply instructions
6579 (define_expand "mul<mode>3"
6580 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6582 (match_operand:SWIM248 1 "register_operand" "")
6583 (match_operand:SWIM248 2 "<general_operand>" "")))
6584 (clobber (reg:CC FLAGS_REG))])])
6586 (define_expand "mulqi3"
6587 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6589 (match_operand:QI 1 "register_operand" "")
6590 (match_operand:QI 2 "nonimmediate_operand" "")))
6591 (clobber (reg:CC FLAGS_REG))])]
6592 "TARGET_QIMODE_MATH")
6595 ;; IMUL reg32/64, reg32/64, imm8 Direct
6596 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6597 ;; IMUL reg32/64, reg32/64, imm32 Direct
6598 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6599 ;; IMUL reg32/64, reg32/64 Direct
6600 ;; IMUL reg32/64, mem32/64 Direct
6602 ;; On BDVER1, all above IMULs use DirectPath
6604 (define_insn "*mul<mode>3_1"
6605 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6607 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6608 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6609 (clobber (reg:CC FLAGS_REG))]
6610 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6612 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6613 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6614 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6615 [(set_attr "type" "imul")
6616 (set_attr "prefix_0f" "0,0,1")
6617 (set (attr "athlon_decode")
6618 (cond [(eq_attr "cpu" "athlon")
6619 (const_string "vector")
6620 (eq_attr "alternative" "1")
6621 (const_string "vector")
6622 (and (eq_attr "alternative" "2")
6623 (match_operand 1 "memory_operand" ""))
6624 (const_string "vector")]
6625 (const_string "direct")))
6626 (set (attr "amdfam10_decode")
6627 (cond [(and (eq_attr "alternative" "0,1")
6628 (match_operand 1 "memory_operand" ""))
6629 (const_string "vector")]
6630 (const_string "direct")))
6631 (set_attr "bdver1_decode" "direct")
6632 (set_attr "mode" "<MODE>")])
6634 (define_insn "*mulsi3_1_zext"
6635 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6637 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6638 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6639 (clobber (reg:CC FLAGS_REG))]
6641 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6643 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6644 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6645 imul{l}\t{%2, %k0|%k0, %2}"
6646 [(set_attr "type" "imul")
6647 (set_attr "prefix_0f" "0,0,1")
6648 (set (attr "athlon_decode")
6649 (cond [(eq_attr "cpu" "athlon")
6650 (const_string "vector")
6651 (eq_attr "alternative" "1")
6652 (const_string "vector")
6653 (and (eq_attr "alternative" "2")
6654 (match_operand 1 "memory_operand" ""))
6655 (const_string "vector")]
6656 (const_string "direct")))
6657 (set (attr "amdfam10_decode")
6658 (cond [(and (eq_attr "alternative" "0,1")
6659 (match_operand 1 "memory_operand" ""))
6660 (const_string "vector")]
6661 (const_string "direct")))
6662 (set_attr "bdver1_decode" "direct")
6663 (set_attr "mode" "SI")])
6666 ;; IMUL reg16, reg16, imm8 VectorPath
6667 ;; IMUL reg16, mem16, imm8 VectorPath
6668 ;; IMUL reg16, reg16, imm16 VectorPath
6669 ;; IMUL reg16, mem16, imm16 VectorPath
6670 ;; IMUL reg16, reg16 Direct
6671 ;; IMUL reg16, mem16 Direct
6673 ;; On BDVER1, all HI MULs use DoublePath
6675 (define_insn "*mulhi3_1"
6676 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6677 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6678 (match_operand:HI 2 "general_operand" "K,n,mr")))
6679 (clobber (reg:CC FLAGS_REG))]
6681 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6683 imul{w}\t{%2, %1, %0|%0, %1, %2}
6684 imul{w}\t{%2, %1, %0|%0, %1, %2}
6685 imul{w}\t{%2, %0|%0, %2}"
6686 [(set_attr "type" "imul")
6687 (set_attr "prefix_0f" "0,0,1")
6688 (set (attr "athlon_decode")
6689 (cond [(eq_attr "cpu" "athlon")
6690 (const_string "vector")
6691 (eq_attr "alternative" "1,2")
6692 (const_string "vector")]
6693 (const_string "direct")))
6694 (set (attr "amdfam10_decode")
6695 (cond [(eq_attr "alternative" "0,1")
6696 (const_string "vector")]
6697 (const_string "direct")))
6698 (set_attr "bdver1_decode" "double")
6699 (set_attr "mode" "HI")])
6701 ;;On AMDFAM10 and BDVER1
6705 (define_insn "*mulqi3_1"
6706 [(set (match_operand:QI 0 "register_operand" "=a")
6707 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6708 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6709 (clobber (reg:CC FLAGS_REG))]
6711 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6713 [(set_attr "type" "imul")
6714 (set_attr "length_immediate" "0")
6715 (set (attr "athlon_decode")
6716 (if_then_else (eq_attr "cpu" "athlon")
6717 (const_string "vector")
6718 (const_string "direct")))
6719 (set_attr "amdfam10_decode" "direct")
6720 (set_attr "bdver1_decode" "direct")
6721 (set_attr "mode" "QI")])
6723 (define_expand "<u>mul<mode><dwi>3"
6724 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6727 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6729 (match_operand:DWIH 2 "register_operand" ""))))
6730 (clobber (reg:CC FLAGS_REG))])])
6732 (define_expand "<u>mulqihi3"
6733 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6736 (match_operand:QI 1 "nonimmediate_operand" ""))
6738 (match_operand:QI 2 "register_operand" ""))))
6739 (clobber (reg:CC FLAGS_REG))])]
6740 "TARGET_QIMODE_MATH")
6742 (define_insn "*bmi2_umulditi3_1"
6743 [(set (match_operand:DI 0 "register_operand" "=r")
6745 (match_operand:DI 2 "nonimmediate_operand" "%d")
6746 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6747 (set (match_operand:DI 1 "register_operand" "=r")
6750 (mult:TI (zero_extend:TI (match_dup 2))
6751 (zero_extend:TI (match_dup 3)))
6753 "TARGET_64BIT && TARGET_BMI2
6754 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6755 "mulx\t{%3, %0, %1|%1, %0, %3}"
6756 [(set_attr "type" "imulx")
6757 (set_attr "prefix" "vex")
6758 (set_attr "mode" "DI")])
6760 (define_insn "*bmi2_umulsidi3_1"
6761 [(set (match_operand:SI 0 "register_operand" "=r")
6763 (match_operand:SI 2 "nonimmediate_operand" "%d")
6764 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6765 (set (match_operand:SI 1 "register_operand" "=r")
6768 (mult:DI (zero_extend:DI (match_dup 2))
6769 (zero_extend:DI (match_dup 3)))
6771 "!TARGET_64BIT && TARGET_BMI2
6772 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6773 "mulx\t{%3, %0, %1|%1, %0, %3}"
6774 [(set_attr "type" "imulx")
6775 (set_attr "prefix" "vex")
6776 (set_attr "mode" "SI")])
6778 (define_insn "*umul<mode><dwi>3_1"
6779 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6782 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6784 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6785 (clobber (reg:CC FLAGS_REG))]
6786 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6788 mul{<imodesuffix>}\t%2
6790 [(set_attr "isa" "*,bmi2")
6791 (set_attr "type" "imul,imulx")
6792 (set_attr "length_immediate" "0,*")
6793 (set (attr "athlon_decode")
6794 (cond [(eq_attr "alternative" "0")
6795 (if_then_else (eq_attr "cpu" "athlon")
6796 (const_string "vector")
6797 (const_string "double"))]
6798 (const_string "*")))
6799 (set_attr "amdfam10_decode" "double,*")
6800 (set_attr "bdver1_decode" "direct,*")
6801 (set_attr "prefix" "orig,vex")
6802 (set_attr "mode" "<MODE>")])
6804 ;; Convert mul to the mulx pattern to avoid flags dependency.
6806 [(set (match_operand:<DWI> 0 "register_operand" "")
6809 (match_operand:DWIH 1 "register_operand" ""))
6811 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6812 (clobber (reg:CC FLAGS_REG))]
6813 "TARGET_BMI2 && reload_completed
6814 && true_regnum (operands[1]) == DX_REG"
6815 [(parallel [(set (match_dup 3)
6816 (mult:DWIH (match_dup 1) (match_dup 2)))
6820 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6821 (zero_extend:<DWI> (match_dup 2)))
6824 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6826 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6829 (define_insn "*mul<mode><dwi>3_1"
6830 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6833 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6835 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6836 (clobber (reg:CC FLAGS_REG))]
6837 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6838 "imul{<imodesuffix>}\t%2"
6839 [(set_attr "type" "imul")
6840 (set_attr "length_immediate" "0")
6841 (set (attr "athlon_decode")
6842 (if_then_else (eq_attr "cpu" "athlon")
6843 (const_string "vector")
6844 (const_string "double")))
6845 (set_attr "amdfam10_decode" "double")
6846 (set_attr "bdver1_decode" "direct")
6847 (set_attr "mode" "<MODE>")])
6849 (define_insn "*<u>mulqihi3_1"
6850 [(set (match_operand:HI 0 "register_operand" "=a")
6853 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6855 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6856 (clobber (reg:CC FLAGS_REG))]
6858 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6859 "<sgnprefix>mul{b}\t%2"
6860 [(set_attr "type" "imul")
6861 (set_attr "length_immediate" "0")
6862 (set (attr "athlon_decode")
6863 (if_then_else (eq_attr "cpu" "athlon")
6864 (const_string "vector")
6865 (const_string "direct")))
6866 (set_attr "amdfam10_decode" "direct")
6867 (set_attr "bdver1_decode" "direct")
6868 (set_attr "mode" "QI")])
6870 (define_expand "<s>mul<mode>3_highpart"
6871 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6876 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6878 (match_operand:SWI48 2 "register_operand" "")))
6880 (clobber (match_scratch:SWI48 3 ""))
6881 (clobber (reg:CC FLAGS_REG))])]
6883 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6885 (define_insn "*<s>muldi3_highpart_1"
6886 [(set (match_operand:DI 0 "register_operand" "=d")
6891 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6893 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6895 (clobber (match_scratch:DI 3 "=1"))
6896 (clobber (reg:CC FLAGS_REG))]
6898 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6899 "<sgnprefix>mul{q}\t%2"
6900 [(set_attr "type" "imul")
6901 (set_attr "length_immediate" "0")
6902 (set (attr "athlon_decode")
6903 (if_then_else (eq_attr "cpu" "athlon")
6904 (const_string "vector")
6905 (const_string "double")))
6906 (set_attr "amdfam10_decode" "double")
6907 (set_attr "bdver1_decode" "direct")
6908 (set_attr "mode" "DI")])
6910 (define_insn "*<s>mulsi3_highpart_1"
6911 [(set (match_operand:SI 0 "register_operand" "=d")
6916 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6918 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6920 (clobber (match_scratch:SI 3 "=1"))
6921 (clobber (reg:CC FLAGS_REG))]
6922 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6923 "<sgnprefix>mul{l}\t%2"
6924 [(set_attr "type" "imul")
6925 (set_attr "length_immediate" "0")
6926 (set (attr "athlon_decode")
6927 (if_then_else (eq_attr "cpu" "athlon")
6928 (const_string "vector")
6929 (const_string "double")))
6930 (set_attr "amdfam10_decode" "double")
6931 (set_attr "bdver1_decode" "direct")
6932 (set_attr "mode" "SI")])
6934 (define_insn "*<s>mulsi3_highpart_zext"
6935 [(set (match_operand:DI 0 "register_operand" "=d")
6936 (zero_extend:DI (truncate:SI
6938 (mult:DI (any_extend:DI
6939 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6941 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6943 (clobber (match_scratch:SI 3 "=1"))
6944 (clobber (reg:CC FLAGS_REG))]
6946 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6947 "<sgnprefix>mul{l}\t%2"
6948 [(set_attr "type" "imul")
6949 (set_attr "length_immediate" "0")
6950 (set (attr "athlon_decode")
6951 (if_then_else (eq_attr "cpu" "athlon")
6952 (const_string "vector")
6953 (const_string "double")))
6954 (set_attr "amdfam10_decode" "double")
6955 (set_attr "bdver1_decode" "direct")
6956 (set_attr "mode" "SI")])
6958 ;; The patterns that match these are at the end of this file.
6960 (define_expand "mulxf3"
6961 [(set (match_operand:XF 0 "register_operand" "")
6962 (mult:XF (match_operand:XF 1 "register_operand" "")
6963 (match_operand:XF 2 "register_operand" "")))]
6966 (define_expand "mul<mode>3"
6967 [(set (match_operand:MODEF 0 "register_operand" "")
6968 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
6969 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6970 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6971 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6973 ;; Divide instructions
6975 ;; The patterns that match these are at the end of this file.
6977 (define_expand "divxf3"
6978 [(set (match_operand:XF 0 "register_operand" "")
6979 (div:XF (match_operand:XF 1 "register_operand" "")
6980 (match_operand:XF 2 "register_operand" "")))]
6983 (define_expand "divdf3"
6984 [(set (match_operand:DF 0 "register_operand" "")
6985 (div:DF (match_operand:DF 1 "register_operand" "")
6986 (match_operand:DF 2 "nonimmediate_operand" "")))]
6987 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
6988 || (TARGET_SSE2 && TARGET_SSE_MATH)")
6990 (define_expand "divsf3"
6991 [(set (match_operand:SF 0 "register_operand" "")
6992 (div:SF (match_operand:SF 1 "register_operand" "")
6993 (match_operand:SF 2 "nonimmediate_operand" "")))]
6994 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
6999 && optimize_insn_for_speed_p ()
7000 && flag_finite_math_only && !flag_trapping_math
7001 && flag_unsafe_math_optimizations)
7003 ix86_emit_swdivsf (operands[0], operands[1],
7004 operands[2], SFmode);
7009 ;; Divmod instructions.
7011 (define_expand "divmod<mode>4"
7012 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7014 (match_operand:SWIM248 1 "register_operand" "")
7015 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7016 (set (match_operand:SWIM248 3 "register_operand" "")
7017 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7018 (clobber (reg:CC FLAGS_REG))])])
7020 ;; Split with 8bit unsigned divide:
7021 ;; if (dividend an divisor are in [0-255])
7022 ;; use 8bit unsigned integer divide
7024 ;; use original integer divide
7026 [(set (match_operand:SWI48 0 "register_operand" "")
7027 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7028 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7029 (set (match_operand:SWI48 1 "register_operand" "")
7030 (mod:SWI48 (match_dup 2) (match_dup 3)))
7031 (clobber (reg:CC FLAGS_REG))]
7032 "TARGET_USE_8BIT_IDIV
7033 && TARGET_QIMODE_MATH
7034 && can_create_pseudo_p ()
7035 && !optimize_insn_for_size_p ()"
7037 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7039 (define_insn_and_split "divmod<mode>4_1"
7040 [(set (match_operand:SWI48 0 "register_operand" "=a")
7041 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7042 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7043 (set (match_operand:SWI48 1 "register_operand" "=&d")
7044 (mod:SWI48 (match_dup 2) (match_dup 3)))
7045 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7046 (clobber (reg:CC FLAGS_REG))]
7050 [(parallel [(set (match_dup 1)
7051 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7052 (clobber (reg:CC FLAGS_REG))])
7053 (parallel [(set (match_dup 0)
7054 (div:SWI48 (match_dup 2) (match_dup 3)))
7056 (mod:SWI48 (match_dup 2) (match_dup 3)))
7058 (clobber (reg:CC FLAGS_REG))])]
7060 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7062 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7063 operands[4] = operands[2];
7066 /* Avoid use of cltd in favor of a mov+shift. */
7067 emit_move_insn (operands[1], operands[2]);
7068 operands[4] = operands[1];
7071 [(set_attr "type" "multi")
7072 (set_attr "mode" "<MODE>")])
7074 (define_insn_and_split "*divmod<mode>4"
7075 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7076 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7077 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7078 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7079 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7080 (clobber (reg:CC FLAGS_REG))]
7084 [(parallel [(set (match_dup 1)
7085 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7086 (clobber (reg:CC FLAGS_REG))])
7087 (parallel [(set (match_dup 0)
7088 (div:SWIM248 (match_dup 2) (match_dup 3)))
7090 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7092 (clobber (reg:CC FLAGS_REG))])]
7094 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7096 if (<MODE>mode != HImode
7097 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7098 operands[4] = operands[2];
7101 /* Avoid use of cltd in favor of a mov+shift. */
7102 emit_move_insn (operands[1], operands[2]);
7103 operands[4] = operands[1];
7106 [(set_attr "type" "multi")
7107 (set_attr "mode" "<MODE>")])
7109 (define_insn "*divmod<mode>4_noext"
7110 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7111 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7112 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7113 (set (match_operand:SWIM248 1 "register_operand" "=d")
7114 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7115 (use (match_operand:SWIM248 4 "register_operand" "1"))
7116 (clobber (reg:CC FLAGS_REG))]
7118 "idiv{<imodesuffix>}\t%3"
7119 [(set_attr "type" "idiv")
7120 (set_attr "mode" "<MODE>")])
7122 (define_expand "divmodqi4"
7123 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7125 (match_operand:QI 1 "register_operand" "")
7126 (match_operand:QI 2 "nonimmediate_operand" "")))
7127 (set (match_operand:QI 3 "register_operand" "")
7128 (mod:QI (match_dup 1) (match_dup 2)))
7129 (clobber (reg:CC FLAGS_REG))])]
7130 "TARGET_QIMODE_MATH"
7135 tmp0 = gen_reg_rtx (HImode);
7136 tmp1 = gen_reg_rtx (HImode);
7138 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7140 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7141 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7143 /* Extract remainder from AH. */
7144 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7145 insn = emit_move_insn (operands[3], tmp1);
7147 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7148 set_unique_reg_note (insn, REG_EQUAL, mod);
7150 /* Extract quotient from AL. */
7151 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7153 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7154 set_unique_reg_note (insn, REG_EQUAL, div);
7159 ;; Divide AX by r/m8, with result stored in
7162 ;; Change div/mod to HImode and extend the second argument to HImode
7163 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7164 ;; combine may fail.
7165 (define_insn "divmodhiqi3"
7166 [(set (match_operand:HI 0 "register_operand" "=a")
7171 (mod:HI (match_operand:HI 1 "register_operand" "0")
7173 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7177 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7178 (clobber (reg:CC FLAGS_REG))]
7179 "TARGET_QIMODE_MATH"
7181 [(set_attr "type" "idiv")
7182 (set_attr "mode" "QI")])
7184 (define_expand "udivmod<mode>4"
7185 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7187 (match_operand:SWIM248 1 "register_operand" "")
7188 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7189 (set (match_operand:SWIM248 3 "register_operand" "")
7190 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7191 (clobber (reg:CC FLAGS_REG))])])
7193 ;; Split with 8bit unsigned divide:
7194 ;; if (dividend an divisor are in [0-255])
7195 ;; use 8bit unsigned integer divide
7197 ;; use original integer divide
7199 [(set (match_operand:SWI48 0 "register_operand" "")
7200 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7201 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7202 (set (match_operand:SWI48 1 "register_operand" "")
7203 (umod:SWI48 (match_dup 2) (match_dup 3)))
7204 (clobber (reg:CC FLAGS_REG))]
7205 "TARGET_USE_8BIT_IDIV
7206 && TARGET_QIMODE_MATH
7207 && can_create_pseudo_p ()
7208 && !optimize_insn_for_size_p ()"
7210 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7212 (define_insn_and_split "udivmod<mode>4_1"
7213 [(set (match_operand:SWI48 0 "register_operand" "=a")
7214 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7215 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7216 (set (match_operand:SWI48 1 "register_operand" "=&d")
7217 (umod:SWI48 (match_dup 2) (match_dup 3)))
7218 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7219 (clobber (reg:CC FLAGS_REG))]
7223 [(set (match_dup 1) (const_int 0))
7224 (parallel [(set (match_dup 0)
7225 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7227 (umod:SWI48 (match_dup 2) (match_dup 3)))
7229 (clobber (reg:CC FLAGS_REG))])]
7231 [(set_attr "type" "multi")
7232 (set_attr "mode" "<MODE>")])
7234 (define_insn_and_split "*udivmod<mode>4"
7235 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7236 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7237 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7238 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7239 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7240 (clobber (reg:CC FLAGS_REG))]
7244 [(set (match_dup 1) (const_int 0))
7245 (parallel [(set (match_dup 0)
7246 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7248 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7250 (clobber (reg:CC FLAGS_REG))])]
7252 [(set_attr "type" "multi")
7253 (set_attr "mode" "<MODE>")])
7255 (define_insn "*udivmod<mode>4_noext"
7256 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7257 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7258 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7259 (set (match_operand:SWIM248 1 "register_operand" "=d")
7260 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7261 (use (match_operand:SWIM248 4 "register_operand" "1"))
7262 (clobber (reg:CC FLAGS_REG))]
7264 "div{<imodesuffix>}\t%3"
7265 [(set_attr "type" "idiv")
7266 (set_attr "mode" "<MODE>")])
7268 (define_expand "udivmodqi4"
7269 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7271 (match_operand:QI 1 "register_operand" "")
7272 (match_operand:QI 2 "nonimmediate_operand" "")))
7273 (set (match_operand:QI 3 "register_operand" "")
7274 (umod:QI (match_dup 1) (match_dup 2)))
7275 (clobber (reg:CC FLAGS_REG))])]
7276 "TARGET_QIMODE_MATH"
7281 tmp0 = gen_reg_rtx (HImode);
7282 tmp1 = gen_reg_rtx (HImode);
7284 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7286 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7287 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7289 /* Extract remainder from AH. */
7290 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7291 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7292 insn = emit_move_insn (operands[3], tmp1);
7294 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7295 set_unique_reg_note (insn, REG_EQUAL, mod);
7297 /* Extract quotient from AL. */
7298 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7300 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7301 set_unique_reg_note (insn, REG_EQUAL, div);
7306 (define_insn "udivmodhiqi3"
7307 [(set (match_operand:HI 0 "register_operand" "=a")
7312 (mod:HI (match_operand:HI 1 "register_operand" "0")
7314 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7318 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7319 (clobber (reg:CC FLAGS_REG))]
7320 "TARGET_QIMODE_MATH"
7322 [(set_attr "type" "idiv")
7323 (set_attr "mode" "QI")])
7325 ;; We cannot use div/idiv for double division, because it causes
7326 ;; "division by zero" on the overflow and that's not what we expect
7327 ;; from truncate. Because true (non truncating) double division is
7328 ;; never generated, we can't create this insn anyway.
7331 ; [(set (match_operand:SI 0 "register_operand" "=a")
7333 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7335 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7336 ; (set (match_operand:SI 3 "register_operand" "=d")
7338 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7339 ; (clobber (reg:CC FLAGS_REG))]
7341 ; "div{l}\t{%2, %0|%0, %2}"
7342 ; [(set_attr "type" "idiv")])
7344 ;;- Logical AND instructions
7346 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7347 ;; Note that this excludes ah.
7349 (define_expand "testsi_ccno_1"
7350 [(set (reg:CCNO FLAGS_REG)
7352 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7353 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7356 (define_expand "testqi_ccz_1"
7357 [(set (reg:CCZ FLAGS_REG)
7358 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7359 (match_operand:QI 1 "nonmemory_operand" ""))
7362 (define_expand "testdi_ccno_1"
7363 [(set (reg:CCNO FLAGS_REG)
7365 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7366 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7368 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7370 (define_insn "*testdi_1"
7371 [(set (reg FLAGS_REG)
7374 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7375 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7377 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7378 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7380 test{l}\t{%k1, %k0|%k0, %k1}
7381 test{l}\t{%k1, %k0|%k0, %k1}
7382 test{q}\t{%1, %0|%0, %1}
7383 test{q}\t{%1, %0|%0, %1}
7384 test{q}\t{%1, %0|%0, %1}"
7385 [(set_attr "type" "test")
7386 (set_attr "modrm" "0,1,0,1,1")
7387 (set_attr "mode" "SI,SI,DI,DI,DI")])
7389 (define_insn "*testqi_1_maybe_si"
7390 [(set (reg FLAGS_REG)
7393 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7394 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7396 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7397 && ix86_match_ccmode (insn,
7398 CONST_INT_P (operands[1])
7399 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7401 if (which_alternative == 3)
7403 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7404 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7405 return "test{l}\t{%1, %k0|%k0, %1}";
7407 return "test{b}\t{%1, %0|%0, %1}";
7409 [(set_attr "type" "test")
7410 (set_attr "modrm" "0,1,1,1")
7411 (set_attr "mode" "QI,QI,QI,SI")
7412 (set_attr "pent_pair" "uv,np,uv,np")])
7414 (define_insn "*test<mode>_1"
7415 [(set (reg FLAGS_REG)
7418 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7419 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7421 "ix86_match_ccmode (insn, CCNOmode)
7422 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7423 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7424 [(set_attr "type" "test")
7425 (set_attr "modrm" "0,1,1")
7426 (set_attr "mode" "<MODE>")
7427 (set_attr "pent_pair" "uv,np,uv")])
7429 (define_expand "testqi_ext_ccno_0"
7430 [(set (reg:CCNO FLAGS_REG)
7434 (match_operand 0 "ext_register_operand" "")
7437 (match_operand 1 "const_int_operand" ""))
7440 (define_insn "*testqi_ext_0"
7441 [(set (reg FLAGS_REG)
7445 (match_operand 0 "ext_register_operand" "Q")
7448 (match_operand 1 "const_int_operand" "n"))
7450 "ix86_match_ccmode (insn, CCNOmode)"
7451 "test{b}\t{%1, %h0|%h0, %1}"
7452 [(set_attr "type" "test")
7453 (set_attr "mode" "QI")
7454 (set_attr "length_immediate" "1")
7455 (set_attr "modrm" "1")
7456 (set_attr "pent_pair" "np")])
7458 (define_insn "*testqi_ext_1_rex64"
7459 [(set (reg FLAGS_REG)
7463 (match_operand 0 "ext_register_operand" "Q")
7467 (match_operand:QI 1 "register_operand" "Q")))
7469 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7470 "test{b}\t{%1, %h0|%h0, %1}"
7471 [(set_attr "type" "test")
7472 (set_attr "mode" "QI")])
7474 (define_insn "*testqi_ext_1"
7475 [(set (reg FLAGS_REG)
7479 (match_operand 0 "ext_register_operand" "Q")
7483 (match_operand:QI 1 "general_operand" "Qm")))
7485 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7486 "test{b}\t{%1, %h0|%h0, %1}"
7487 [(set_attr "type" "test")
7488 (set_attr "mode" "QI")])
7490 (define_insn "*testqi_ext_2"
7491 [(set (reg FLAGS_REG)
7495 (match_operand 0 "ext_register_operand" "Q")
7499 (match_operand 1 "ext_register_operand" "Q")
7503 "ix86_match_ccmode (insn, CCNOmode)"
7504 "test{b}\t{%h1, %h0|%h0, %h1}"
7505 [(set_attr "type" "test")
7506 (set_attr "mode" "QI")])
7508 (define_insn "*testqi_ext_3_rex64"
7509 [(set (reg FLAGS_REG)
7510 (compare (zero_extract:DI
7511 (match_operand 0 "nonimmediate_operand" "rm")
7512 (match_operand:DI 1 "const_int_operand" "")
7513 (match_operand:DI 2 "const_int_operand" ""))
7516 && ix86_match_ccmode (insn, CCNOmode)
7517 && INTVAL (operands[1]) > 0
7518 && INTVAL (operands[2]) >= 0
7519 /* Ensure that resulting mask is zero or sign extended operand. */
7520 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7521 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7522 && INTVAL (operands[1]) > 32))
7523 && (GET_MODE (operands[0]) == SImode
7524 || GET_MODE (operands[0]) == DImode
7525 || GET_MODE (operands[0]) == HImode
7526 || GET_MODE (operands[0]) == QImode)"
7529 ;; Combine likes to form bit extractions for some tests. Humor it.
7530 (define_insn "*testqi_ext_3"
7531 [(set (reg FLAGS_REG)
7532 (compare (zero_extract:SI
7533 (match_operand 0 "nonimmediate_operand" "rm")
7534 (match_operand:SI 1 "const_int_operand" "")
7535 (match_operand:SI 2 "const_int_operand" ""))
7537 "ix86_match_ccmode (insn, CCNOmode)
7538 && INTVAL (operands[1]) > 0
7539 && INTVAL (operands[2]) >= 0
7540 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7541 && (GET_MODE (operands[0]) == SImode
7542 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7543 || GET_MODE (operands[0]) == HImode
7544 || GET_MODE (operands[0]) == QImode)"
7548 [(set (match_operand 0 "flags_reg_operand" "")
7549 (match_operator 1 "compare_operator"
7551 (match_operand 2 "nonimmediate_operand" "")
7552 (match_operand 3 "const_int_operand" "")
7553 (match_operand 4 "const_int_operand" ""))
7555 "ix86_match_ccmode (insn, CCNOmode)"
7556 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7558 rtx val = operands[2];
7559 HOST_WIDE_INT len = INTVAL (operands[3]);
7560 HOST_WIDE_INT pos = INTVAL (operands[4]);
7562 enum machine_mode mode, submode;
7564 mode = GET_MODE (val);
7567 /* ??? Combine likes to put non-volatile mem extractions in QImode
7568 no matter the size of the test. So find a mode that works. */
7569 if (! MEM_VOLATILE_P (val))
7571 mode = smallest_mode_for_size (pos + len, MODE_INT);
7572 val = adjust_address (val, mode, 0);
7575 else if (GET_CODE (val) == SUBREG
7576 && (submode = GET_MODE (SUBREG_REG (val)),
7577 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7578 && pos + len <= GET_MODE_BITSIZE (submode)
7579 && GET_MODE_CLASS (submode) == MODE_INT)
7581 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7583 val = SUBREG_REG (val);
7585 else if (mode == HImode && pos + len <= 8)
7587 /* Small HImode tests can be converted to QImode. */
7589 val = gen_lowpart (QImode, val);
7592 if (len == HOST_BITS_PER_WIDE_INT)
7595 mask = ((HOST_WIDE_INT)1 << len) - 1;
7598 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7601 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7602 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7603 ;; this is relatively important trick.
7604 ;; Do the conversion only post-reload to avoid limiting of the register class
7607 [(set (match_operand 0 "flags_reg_operand" "")
7608 (match_operator 1 "compare_operator"
7609 [(and (match_operand 2 "register_operand" "")
7610 (match_operand 3 "const_int_operand" ""))
7613 && QI_REG_P (operands[2])
7614 && GET_MODE (operands[2]) != QImode
7615 && ((ix86_match_ccmode (insn, CCZmode)
7616 && !(INTVAL (operands[3]) & ~(255 << 8)))
7617 || (ix86_match_ccmode (insn, CCNOmode)
7618 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7621 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7625 operands[2] = gen_lowpart (SImode, operands[2]);
7626 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7630 [(set (match_operand 0 "flags_reg_operand" "")
7631 (match_operator 1 "compare_operator"
7632 [(and (match_operand 2 "nonimmediate_operand" "")
7633 (match_operand 3 "const_int_operand" ""))
7636 && GET_MODE (operands[2]) != QImode
7637 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7638 && ((ix86_match_ccmode (insn, CCZmode)
7639 && !(INTVAL (operands[3]) & ~255))
7640 || (ix86_match_ccmode (insn, CCNOmode)
7641 && !(INTVAL (operands[3]) & ~127)))"
7643 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7646 operands[2] = gen_lowpart (QImode, operands[2]);
7647 operands[3] = gen_lowpart (QImode, operands[3]);
7650 ;; %%% This used to optimize known byte-wide and operations to memory,
7651 ;; and sometimes to QImode registers. If this is considered useful,
7652 ;; it should be done with splitters.
7654 (define_expand "and<mode>3"
7655 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7656 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7657 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7660 if (<MODE>mode == DImode
7661 && GET_CODE (operands[2]) == CONST_INT
7662 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7663 && REG_P (operands[1]))
7664 emit_insn (gen_zero_extendsidi2 (operands[0],
7665 gen_lowpart (SImode, operands[1])));
7667 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7671 (define_insn "*anddi_1"
7672 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7674 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7675 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7676 (clobber (reg:CC FLAGS_REG))]
7677 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7679 switch (get_attr_type (insn))
7683 enum machine_mode mode;
7685 gcc_assert (CONST_INT_P (operands[2]));
7686 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7688 else if (INTVAL (operands[2]) == 0xffff)
7692 gcc_assert (INTVAL (operands[2]) == 0xff);
7696 operands[1] = gen_lowpart (mode, operands[1]);
7698 return "mov{l}\t{%1, %k0|%k0, %1}";
7699 else if (mode == HImode)
7700 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7702 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7706 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7707 if (get_attr_mode (insn) == MODE_SI)
7708 return "and{l}\t{%k2, %k0|%k0, %k2}";
7710 return "and{q}\t{%2, %0|%0, %2}";
7713 [(set_attr "type" "alu,alu,alu,imovx")
7714 (set_attr "length_immediate" "*,*,*,0")
7715 (set (attr "prefix_rex")
7717 (and (eq_attr "type" "imovx")
7718 (and (match_test "INTVAL (operands[2]) == 0xff")
7719 (match_operand 1 "ext_QIreg_operand" "")))
7721 (const_string "*")))
7722 (set_attr "mode" "SI,DI,DI,SI")])
7724 (define_insn "*andsi_1"
7725 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7726 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7727 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7728 (clobber (reg:CC FLAGS_REG))]
7729 "ix86_binary_operator_ok (AND, SImode, operands)"
7731 switch (get_attr_type (insn))
7735 enum machine_mode mode;
7737 gcc_assert (CONST_INT_P (operands[2]));
7738 if (INTVAL (operands[2]) == 0xffff)
7742 gcc_assert (INTVAL (operands[2]) == 0xff);
7746 operands[1] = gen_lowpart (mode, operands[1]);
7748 return "movz{wl|x}\t{%1, %0|%0, %1}";
7750 return "movz{bl|x}\t{%1, %0|%0, %1}";
7754 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7755 return "and{l}\t{%2, %0|%0, %2}";
7758 [(set_attr "type" "alu,alu,imovx")
7759 (set (attr "prefix_rex")
7761 (and (eq_attr "type" "imovx")
7762 (and (match_test "INTVAL (operands[2]) == 0xff")
7763 (match_operand 1 "ext_QIreg_operand" "")))
7765 (const_string "*")))
7766 (set_attr "length_immediate" "*,*,0")
7767 (set_attr "mode" "SI")])
7769 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7770 (define_insn "*andsi_1_zext"
7771 [(set (match_operand:DI 0 "register_operand" "=r")
7773 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7774 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7775 (clobber (reg:CC FLAGS_REG))]
7776 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7777 "and{l}\t{%2, %k0|%k0, %2}"
7778 [(set_attr "type" "alu")
7779 (set_attr "mode" "SI")])
7781 (define_insn "*andhi_1"
7782 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7783 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7784 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7785 (clobber (reg:CC FLAGS_REG))]
7786 "ix86_binary_operator_ok (AND, HImode, operands)"
7788 switch (get_attr_type (insn))
7791 gcc_assert (CONST_INT_P (operands[2]));
7792 gcc_assert (INTVAL (operands[2]) == 0xff);
7793 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7796 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7798 return "and{w}\t{%2, %0|%0, %2}";
7801 [(set_attr "type" "alu,alu,imovx")
7802 (set_attr "length_immediate" "*,*,0")
7803 (set (attr "prefix_rex")
7805 (and (eq_attr "type" "imovx")
7806 (match_operand 1 "ext_QIreg_operand" ""))
7808 (const_string "*")))
7809 (set_attr "mode" "HI,HI,SI")])
7811 ;; %%% Potential partial reg stall on alternative 2. What to do?
7812 (define_insn "*andqi_1"
7813 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7814 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7815 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7816 (clobber (reg:CC FLAGS_REG))]
7817 "ix86_binary_operator_ok (AND, QImode, operands)"
7819 and{b}\t{%2, %0|%0, %2}
7820 and{b}\t{%2, %0|%0, %2}
7821 and{l}\t{%k2, %k0|%k0, %k2}"
7822 [(set_attr "type" "alu")
7823 (set_attr "mode" "QI,QI,SI")])
7825 (define_insn "*andqi_1_slp"
7826 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7827 (and:QI (match_dup 0)
7828 (match_operand:QI 1 "general_operand" "qn,qmn")))
7829 (clobber (reg:CC FLAGS_REG))]
7830 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7831 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7832 "and{b}\t{%1, %0|%0, %1}"
7833 [(set_attr "type" "alu1")
7834 (set_attr "mode" "QI")])
7837 [(set (match_operand 0 "register_operand" "")
7839 (const_int -65536)))
7840 (clobber (reg:CC FLAGS_REG))]
7841 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7842 || optimize_function_for_size_p (cfun)"
7843 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7844 "operands[1] = gen_lowpart (HImode, operands[0]);")
7847 [(set (match_operand 0 "ext_register_operand" "")
7850 (clobber (reg:CC FLAGS_REG))]
7851 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7852 && reload_completed"
7853 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7854 "operands[1] = gen_lowpart (QImode, operands[0]);")
7857 [(set (match_operand 0 "ext_register_operand" "")
7859 (const_int -65281)))
7860 (clobber (reg:CC FLAGS_REG))]
7861 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7862 && reload_completed"
7863 [(parallel [(set (zero_extract:SI (match_dup 0)
7867 (zero_extract:SI (match_dup 0)
7870 (zero_extract:SI (match_dup 0)
7873 (clobber (reg:CC FLAGS_REG))])]
7874 "operands[0] = gen_lowpart (SImode, operands[0]);")
7876 (define_insn "*anddi_2"
7877 [(set (reg FLAGS_REG)
7880 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7881 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7883 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7884 (and:DI (match_dup 1) (match_dup 2)))]
7885 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7886 && ix86_binary_operator_ok (AND, DImode, operands)"
7888 and{l}\t{%k2, %k0|%k0, %k2}
7889 and{q}\t{%2, %0|%0, %2}
7890 and{q}\t{%2, %0|%0, %2}"
7891 [(set_attr "type" "alu")
7892 (set_attr "mode" "SI,DI,DI")])
7894 (define_insn "*andqi_2_maybe_si"
7895 [(set (reg FLAGS_REG)
7897 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7898 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7900 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7901 (and:QI (match_dup 1) (match_dup 2)))]
7902 "ix86_binary_operator_ok (AND, QImode, operands)
7903 && ix86_match_ccmode (insn,
7904 CONST_INT_P (operands[2])
7905 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7907 if (which_alternative == 2)
7909 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7910 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7911 return "and{l}\t{%2, %k0|%k0, %2}";
7913 return "and{b}\t{%2, %0|%0, %2}";
7915 [(set_attr "type" "alu")
7916 (set_attr "mode" "QI,QI,SI")])
7918 (define_insn "*and<mode>_2"
7919 [(set (reg FLAGS_REG)
7920 (compare (and:SWI124
7921 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7922 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7924 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7925 (and:SWI124 (match_dup 1) (match_dup 2)))]
7926 "ix86_match_ccmode (insn, CCNOmode)
7927 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7928 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7929 [(set_attr "type" "alu")
7930 (set_attr "mode" "<MODE>")])
7932 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7933 (define_insn "*andsi_2_zext"
7934 [(set (reg FLAGS_REG)
7936 (match_operand:SI 1 "nonimmediate_operand" "%0")
7937 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7939 (set (match_operand:DI 0 "register_operand" "=r")
7940 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7941 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7942 && ix86_binary_operator_ok (AND, SImode, operands)"
7943 "and{l}\t{%2, %k0|%k0, %2}"
7944 [(set_attr "type" "alu")
7945 (set_attr "mode" "SI")])
7947 (define_insn "*andqi_2_slp"
7948 [(set (reg FLAGS_REG)
7950 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7951 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7953 (set (strict_low_part (match_dup 0))
7954 (and:QI (match_dup 0) (match_dup 1)))]
7955 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7956 && ix86_match_ccmode (insn, CCNOmode)
7957 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7958 "and{b}\t{%1, %0|%0, %1}"
7959 [(set_attr "type" "alu1")
7960 (set_attr "mode" "QI")])
7962 ;; ??? A bug in recog prevents it from recognizing a const_int as an
7963 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
7964 ;; for a QImode operand, which of course failed.
7965 (define_insn "andqi_ext_0"
7966 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7971 (match_operand 1 "ext_register_operand" "0")
7974 (match_operand 2 "const_int_operand" "n")))
7975 (clobber (reg:CC FLAGS_REG))]
7977 "and{b}\t{%2, %h0|%h0, %2}"
7978 [(set_attr "type" "alu")
7979 (set_attr "length_immediate" "1")
7980 (set_attr "modrm" "1")
7981 (set_attr "mode" "QI")])
7983 ;; Generated by peephole translating test to and. This shows up
7984 ;; often in fp comparisons.
7985 (define_insn "*andqi_ext_0_cc"
7986 [(set (reg FLAGS_REG)
7990 (match_operand 1 "ext_register_operand" "0")
7993 (match_operand 2 "const_int_operand" "n"))
7995 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8004 "ix86_match_ccmode (insn, CCNOmode)"
8005 "and{b}\t{%2, %h0|%h0, %2}"
8006 [(set_attr "type" "alu")
8007 (set_attr "length_immediate" "1")
8008 (set_attr "modrm" "1")
8009 (set_attr "mode" "QI")])
8011 (define_insn "*andqi_ext_1_rex64"
8012 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8017 (match_operand 1 "ext_register_operand" "0")
8021 (match_operand 2 "ext_register_operand" "Q"))))
8022 (clobber (reg:CC FLAGS_REG))]
8024 "and{b}\t{%2, %h0|%h0, %2}"
8025 [(set_attr "type" "alu")
8026 (set_attr "length_immediate" "0")
8027 (set_attr "mode" "QI")])
8029 (define_insn "*andqi_ext_1"
8030 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8035 (match_operand 1 "ext_register_operand" "0")
8039 (match_operand:QI 2 "general_operand" "Qm"))))
8040 (clobber (reg:CC FLAGS_REG))]
8042 "and{b}\t{%2, %h0|%h0, %2}"
8043 [(set_attr "type" "alu")
8044 (set_attr "length_immediate" "0")
8045 (set_attr "mode" "QI")])
8047 (define_insn "*andqi_ext_2"
8048 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8053 (match_operand 1 "ext_register_operand" "%0")
8057 (match_operand 2 "ext_register_operand" "Q")
8060 (clobber (reg:CC FLAGS_REG))]
8062 "and{b}\t{%h2, %h0|%h0, %h2}"
8063 [(set_attr "type" "alu")
8064 (set_attr "length_immediate" "0")
8065 (set_attr "mode" "QI")])
8067 ;; Convert wide AND instructions with immediate operand to shorter QImode
8068 ;; equivalents when possible.
8069 ;; Don't do the splitting with memory operands, since it introduces risk
8070 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8071 ;; for size, but that can (should?) be handled by generic code instead.
8073 [(set (match_operand 0 "register_operand" "")
8074 (and (match_operand 1 "register_operand" "")
8075 (match_operand 2 "const_int_operand" "")))
8076 (clobber (reg:CC FLAGS_REG))]
8078 && QI_REG_P (operands[0])
8079 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8080 && !(~INTVAL (operands[2]) & ~(255 << 8))
8081 && GET_MODE (operands[0]) != QImode"
8082 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8083 (and:SI (zero_extract:SI (match_dup 1)
8084 (const_int 8) (const_int 8))
8086 (clobber (reg:CC FLAGS_REG))])]
8088 operands[0] = gen_lowpart (SImode, operands[0]);
8089 operands[1] = gen_lowpart (SImode, operands[1]);
8090 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8093 ;; Since AND can be encoded with sign extended immediate, this is only
8094 ;; profitable when 7th bit is not set.
8096 [(set (match_operand 0 "register_operand" "")
8097 (and (match_operand 1 "general_operand" "")
8098 (match_operand 2 "const_int_operand" "")))
8099 (clobber (reg:CC FLAGS_REG))]
8101 && ANY_QI_REG_P (operands[0])
8102 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8103 && !(~INTVAL (operands[2]) & ~255)
8104 && !(INTVAL (operands[2]) & 128)
8105 && GET_MODE (operands[0]) != QImode"
8106 [(parallel [(set (strict_low_part (match_dup 0))
8107 (and:QI (match_dup 1)
8109 (clobber (reg:CC FLAGS_REG))])]
8111 operands[0] = gen_lowpart (QImode, operands[0]);
8112 operands[1] = gen_lowpart (QImode, operands[1]);
8113 operands[2] = gen_lowpart (QImode, operands[2]);
8116 ;; Logical inclusive and exclusive OR instructions
8118 ;; %%% This used to optimize known byte-wide and operations to memory.
8119 ;; If this is considered useful, it should be done with splitters.
8121 (define_expand "<code><mode>3"
8122 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8123 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8124 (match_operand:SWIM 2 "<general_operand>" "")))]
8126 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8128 (define_insn "*<code><mode>_1"
8129 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8131 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8132 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8133 (clobber (reg:CC FLAGS_REG))]
8134 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8135 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8136 [(set_attr "type" "alu")
8137 (set_attr "mode" "<MODE>")])
8139 ;; %%% Potential partial reg stall on alternative 2. What to do?
8140 (define_insn "*<code>qi_1"
8141 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8142 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8143 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8144 (clobber (reg:CC FLAGS_REG))]
8145 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8147 <logic>{b}\t{%2, %0|%0, %2}
8148 <logic>{b}\t{%2, %0|%0, %2}
8149 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8150 [(set_attr "type" "alu")
8151 (set_attr "mode" "QI,QI,SI")])
8153 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8154 (define_insn "*<code>si_1_zext"
8155 [(set (match_operand:DI 0 "register_operand" "=r")
8157 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8158 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8159 (clobber (reg:CC FLAGS_REG))]
8160 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8161 "<logic>{l}\t{%2, %k0|%k0, %2}"
8162 [(set_attr "type" "alu")
8163 (set_attr "mode" "SI")])
8165 (define_insn "*<code>si_1_zext_imm"
8166 [(set (match_operand:DI 0 "register_operand" "=r")
8168 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8169 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8170 (clobber (reg:CC FLAGS_REG))]
8171 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8172 "<logic>{l}\t{%2, %k0|%k0, %2}"
8173 [(set_attr "type" "alu")
8174 (set_attr "mode" "SI")])
8176 (define_insn "*<code>qi_1_slp"
8177 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8178 (any_or:QI (match_dup 0)
8179 (match_operand:QI 1 "general_operand" "qmn,qn")))
8180 (clobber (reg:CC FLAGS_REG))]
8181 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8182 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8183 "<logic>{b}\t{%1, %0|%0, %1}"
8184 [(set_attr "type" "alu1")
8185 (set_attr "mode" "QI")])
8187 (define_insn "*<code><mode>_2"
8188 [(set (reg FLAGS_REG)
8189 (compare (any_or:SWI
8190 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8191 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8193 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8194 (any_or:SWI (match_dup 1) (match_dup 2)))]
8195 "ix86_match_ccmode (insn, CCNOmode)
8196 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8197 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8198 [(set_attr "type" "alu")
8199 (set_attr "mode" "<MODE>")])
8201 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8202 ;; ??? Special case for immediate operand is missing - it is tricky.
8203 (define_insn "*<code>si_2_zext"
8204 [(set (reg FLAGS_REG)
8205 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8206 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8208 (set (match_operand:DI 0 "register_operand" "=r")
8209 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8210 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8211 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8212 "<logic>{l}\t{%2, %k0|%k0, %2}"
8213 [(set_attr "type" "alu")
8214 (set_attr "mode" "SI")])
8216 (define_insn "*<code>si_2_zext_imm"
8217 [(set (reg FLAGS_REG)
8219 (match_operand:SI 1 "nonimmediate_operand" "%0")
8220 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8222 (set (match_operand:DI 0 "register_operand" "=r")
8223 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8224 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8225 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8226 "<logic>{l}\t{%2, %k0|%k0, %2}"
8227 [(set_attr "type" "alu")
8228 (set_attr "mode" "SI")])
8230 (define_insn "*<code>qi_2_slp"
8231 [(set (reg FLAGS_REG)
8232 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8233 (match_operand:QI 1 "general_operand" "qmn,qn"))
8235 (set (strict_low_part (match_dup 0))
8236 (any_or:QI (match_dup 0) (match_dup 1)))]
8237 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8238 && ix86_match_ccmode (insn, CCNOmode)
8239 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8240 "<logic>{b}\t{%1, %0|%0, %1}"
8241 [(set_attr "type" "alu1")
8242 (set_attr "mode" "QI")])
8244 (define_insn "*<code><mode>_3"
8245 [(set (reg FLAGS_REG)
8246 (compare (any_or:SWI
8247 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8248 (match_operand:SWI 2 "<general_operand>" "<g>"))
8250 (clobber (match_scratch:SWI 0 "=<r>"))]
8251 "ix86_match_ccmode (insn, CCNOmode)
8252 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8253 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8254 [(set_attr "type" "alu")
8255 (set_attr "mode" "<MODE>")])
8257 (define_insn "*<code>qi_ext_0"
8258 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8263 (match_operand 1 "ext_register_operand" "0")
8266 (match_operand 2 "const_int_operand" "n")))
8267 (clobber (reg:CC FLAGS_REG))]
8268 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8269 "<logic>{b}\t{%2, %h0|%h0, %2}"
8270 [(set_attr "type" "alu")
8271 (set_attr "length_immediate" "1")
8272 (set_attr "modrm" "1")
8273 (set_attr "mode" "QI")])
8275 (define_insn "*<code>qi_ext_1_rex64"
8276 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8281 (match_operand 1 "ext_register_operand" "0")
8285 (match_operand 2 "ext_register_operand" "Q"))))
8286 (clobber (reg:CC FLAGS_REG))]
8288 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8289 "<logic>{b}\t{%2, %h0|%h0, %2}"
8290 [(set_attr "type" "alu")
8291 (set_attr "length_immediate" "0")
8292 (set_attr "mode" "QI")])
8294 (define_insn "*<code>qi_ext_1"
8295 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8300 (match_operand 1 "ext_register_operand" "0")
8304 (match_operand:QI 2 "general_operand" "Qm"))))
8305 (clobber (reg:CC FLAGS_REG))]
8307 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8308 "<logic>{b}\t{%2, %h0|%h0, %2}"
8309 [(set_attr "type" "alu")
8310 (set_attr "length_immediate" "0")
8311 (set_attr "mode" "QI")])
8313 (define_insn "*<code>qi_ext_2"
8314 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8318 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8321 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8324 (clobber (reg:CC FLAGS_REG))]
8325 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8326 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8327 [(set_attr "type" "alu")
8328 (set_attr "length_immediate" "0")
8329 (set_attr "mode" "QI")])
8332 [(set (match_operand 0 "register_operand" "")
8333 (any_or (match_operand 1 "register_operand" "")
8334 (match_operand 2 "const_int_operand" "")))
8335 (clobber (reg:CC FLAGS_REG))]
8337 && QI_REG_P (operands[0])
8338 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8339 && !(INTVAL (operands[2]) & ~(255 << 8))
8340 && GET_MODE (operands[0]) != QImode"
8341 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8342 (any_or:SI (zero_extract:SI (match_dup 1)
8343 (const_int 8) (const_int 8))
8345 (clobber (reg:CC FLAGS_REG))])]
8347 operands[0] = gen_lowpart (SImode, operands[0]);
8348 operands[1] = gen_lowpart (SImode, operands[1]);
8349 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8352 ;; Since OR can be encoded with sign extended immediate, this is only
8353 ;; profitable when 7th bit is set.
8355 [(set (match_operand 0 "register_operand" "")
8356 (any_or (match_operand 1 "general_operand" "")
8357 (match_operand 2 "const_int_operand" "")))
8358 (clobber (reg:CC FLAGS_REG))]
8360 && ANY_QI_REG_P (operands[0])
8361 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8362 && !(INTVAL (operands[2]) & ~255)
8363 && (INTVAL (operands[2]) & 128)
8364 && GET_MODE (operands[0]) != QImode"
8365 [(parallel [(set (strict_low_part (match_dup 0))
8366 (any_or:QI (match_dup 1)
8368 (clobber (reg:CC FLAGS_REG))])]
8370 operands[0] = gen_lowpart (QImode, operands[0]);
8371 operands[1] = gen_lowpart (QImode, operands[1]);
8372 operands[2] = gen_lowpart (QImode, operands[2]);
8375 (define_expand "xorqi_cc_ext_1"
8377 (set (reg:CCNO FLAGS_REG)
8381 (match_operand 1 "ext_register_operand" "")
8384 (match_operand:QI 2 "general_operand" ""))
8386 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8396 (define_insn "*xorqi_cc_ext_1_rex64"
8397 [(set (reg FLAGS_REG)
8401 (match_operand 1 "ext_register_operand" "0")
8404 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8406 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8415 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8416 "xor{b}\t{%2, %h0|%h0, %2}"
8417 [(set_attr "type" "alu")
8418 (set_attr "modrm" "1")
8419 (set_attr "mode" "QI")])
8421 (define_insn "*xorqi_cc_ext_1"
8422 [(set (reg FLAGS_REG)
8426 (match_operand 1 "ext_register_operand" "0")
8429 (match_operand:QI 2 "general_operand" "qmn"))
8431 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8440 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8441 "xor{b}\t{%2, %h0|%h0, %2}"
8442 [(set_attr "type" "alu")
8443 (set_attr "modrm" "1")
8444 (set_attr "mode" "QI")])
8446 ;; Negation instructions
8448 (define_expand "neg<mode>2"
8449 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8450 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8452 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8454 (define_insn_and_split "*neg<dwi>2_doubleword"
8455 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8456 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8457 (clobber (reg:CC FLAGS_REG))]
8458 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8462 [(set (reg:CCZ FLAGS_REG)
8463 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8464 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8467 (plus:DWIH (match_dup 3)
8468 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8470 (clobber (reg:CC FLAGS_REG))])
8473 (neg:DWIH (match_dup 2)))
8474 (clobber (reg:CC FLAGS_REG))])]
8475 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8477 (define_insn "*neg<mode>2_1"
8478 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8479 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8480 (clobber (reg:CC FLAGS_REG))]
8481 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8482 "neg{<imodesuffix>}\t%0"
8483 [(set_attr "type" "negnot")
8484 (set_attr "mode" "<MODE>")])
8486 ;; Combine is quite creative about this pattern.
8487 (define_insn "*negsi2_1_zext"
8488 [(set (match_operand:DI 0 "register_operand" "=r")
8490 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8493 (clobber (reg:CC FLAGS_REG))]
8494 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8496 [(set_attr "type" "negnot")
8497 (set_attr "mode" "SI")])
8499 ;; The problem with neg is that it does not perform (compare x 0),
8500 ;; it really performs (compare 0 x), which leaves us with the zero
8501 ;; flag being the only useful item.
8503 (define_insn "*neg<mode>2_cmpz"
8504 [(set (reg:CCZ FLAGS_REG)
8506 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8508 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8509 (neg:SWI (match_dup 1)))]
8510 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8511 "neg{<imodesuffix>}\t%0"
8512 [(set_attr "type" "negnot")
8513 (set_attr "mode" "<MODE>")])
8515 (define_insn "*negsi2_cmpz_zext"
8516 [(set (reg:CCZ FLAGS_REG)
8520 (match_operand:DI 1 "register_operand" "0")
8524 (set (match_operand:DI 0 "register_operand" "=r")
8525 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8528 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8530 [(set_attr "type" "negnot")
8531 (set_attr "mode" "SI")])
8533 ;; Changing of sign for FP values is doable using integer unit too.
8535 (define_expand "<code><mode>2"
8536 [(set (match_operand:X87MODEF 0 "register_operand" "")
8537 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8538 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8539 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8541 (define_insn "*absneg<mode>2_mixed"
8542 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8543 (match_operator:MODEF 3 "absneg_operator"
8544 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8545 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8546 (clobber (reg:CC FLAGS_REG))]
8547 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8550 (define_insn "*absneg<mode>2_sse"
8551 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8552 (match_operator:MODEF 3 "absneg_operator"
8553 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8554 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8555 (clobber (reg:CC FLAGS_REG))]
8556 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8559 (define_insn "*absneg<mode>2_i387"
8560 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8561 (match_operator:X87MODEF 3 "absneg_operator"
8562 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8563 (use (match_operand 2 "" ""))
8564 (clobber (reg:CC FLAGS_REG))]
8565 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8568 (define_expand "<code>tf2"
8569 [(set (match_operand:TF 0 "register_operand" "")
8570 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8572 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8574 (define_insn "*absnegtf2_sse"
8575 [(set (match_operand:TF 0 "register_operand" "=x,x")
8576 (match_operator:TF 3 "absneg_operator"
8577 [(match_operand:TF 1 "register_operand" "0,x")]))
8578 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8579 (clobber (reg:CC FLAGS_REG))]
8583 ;; Splitters for fp abs and neg.
8586 [(set (match_operand 0 "fp_register_operand" "")
8587 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8588 (use (match_operand 2 "" ""))
8589 (clobber (reg:CC FLAGS_REG))]
8591 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8594 [(set (match_operand 0 "register_operand" "")
8595 (match_operator 3 "absneg_operator"
8596 [(match_operand 1 "register_operand" "")]))
8597 (use (match_operand 2 "nonimmediate_operand" ""))
8598 (clobber (reg:CC FLAGS_REG))]
8599 "reload_completed && SSE_REG_P (operands[0])"
8600 [(set (match_dup 0) (match_dup 3))]
8602 enum machine_mode mode = GET_MODE (operands[0]);
8603 enum machine_mode vmode = GET_MODE (operands[2]);
8606 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8607 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8608 if (operands_match_p (operands[0], operands[2]))
8611 operands[1] = operands[2];
8614 if (GET_CODE (operands[3]) == ABS)
8615 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8617 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8622 [(set (match_operand:SF 0 "register_operand" "")
8623 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8624 (use (match_operand:V4SF 2 "" ""))
8625 (clobber (reg:CC FLAGS_REG))]
8627 [(parallel [(set (match_dup 0) (match_dup 1))
8628 (clobber (reg:CC FLAGS_REG))])]
8631 operands[0] = gen_lowpart (SImode, operands[0]);
8632 if (GET_CODE (operands[1]) == ABS)
8634 tmp = gen_int_mode (0x7fffffff, SImode);
8635 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8639 tmp = gen_int_mode (0x80000000, SImode);
8640 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8646 [(set (match_operand:DF 0 "register_operand" "")
8647 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
8648 (use (match_operand 2 "" ""))
8649 (clobber (reg:CC FLAGS_REG))]
8651 [(parallel [(set (match_dup 0) (match_dup 1))
8652 (clobber (reg:CC FLAGS_REG))])]
8657 tmp = gen_lowpart (DImode, operands[0]);
8658 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8661 if (GET_CODE (operands[1]) == ABS)
8664 tmp = gen_rtx_NOT (DImode, tmp);
8668 operands[0] = gen_highpart (SImode, operands[0]);
8669 if (GET_CODE (operands[1]) == ABS)
8671 tmp = gen_int_mode (0x7fffffff, SImode);
8672 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8676 tmp = gen_int_mode (0x80000000, SImode);
8677 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8684 [(set (match_operand:XF 0 "register_operand" "")
8685 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8686 (use (match_operand 2 "" ""))
8687 (clobber (reg:CC FLAGS_REG))]
8689 [(parallel [(set (match_dup 0) (match_dup 1))
8690 (clobber (reg:CC FLAGS_REG))])]
8693 operands[0] = gen_rtx_REG (SImode,
8694 true_regnum (operands[0])
8695 + (TARGET_64BIT ? 1 : 2));
8696 if (GET_CODE (operands[1]) == ABS)
8698 tmp = GEN_INT (0x7fff);
8699 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8703 tmp = GEN_INT (0x8000);
8704 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8709 ;; Conditionalize these after reload. If they match before reload, we
8710 ;; lose the clobber and ability to use integer instructions.
8712 (define_insn "*<code><mode>2_1"
8713 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8714 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8716 && (reload_completed
8717 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8718 "f<absneg_mnemonic>"
8719 [(set_attr "type" "fsgn")
8720 (set_attr "mode" "<MODE>")])
8722 (define_insn "*<code>extendsfdf2"
8723 [(set (match_operand:DF 0 "register_operand" "=f")
8724 (absneg:DF (float_extend:DF
8725 (match_operand:SF 1 "register_operand" "0"))))]
8726 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8727 "f<absneg_mnemonic>"
8728 [(set_attr "type" "fsgn")
8729 (set_attr "mode" "DF")])
8731 (define_insn "*<code>extendsfxf2"
8732 [(set (match_operand:XF 0 "register_operand" "=f")
8733 (absneg:XF (float_extend:XF
8734 (match_operand:SF 1 "register_operand" "0"))))]
8736 "f<absneg_mnemonic>"
8737 [(set_attr "type" "fsgn")
8738 (set_attr "mode" "XF")])
8740 (define_insn "*<code>extenddfxf2"
8741 [(set (match_operand:XF 0 "register_operand" "=f")
8742 (absneg:XF (float_extend:XF
8743 (match_operand:DF 1 "register_operand" "0"))))]
8745 "f<absneg_mnemonic>"
8746 [(set_attr "type" "fsgn")
8747 (set_attr "mode" "XF")])
8749 ;; Copysign instructions
8751 (define_mode_iterator CSGNMODE [SF DF TF])
8752 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8754 (define_expand "copysign<mode>3"
8755 [(match_operand:CSGNMODE 0 "register_operand" "")
8756 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8757 (match_operand:CSGNMODE 2 "register_operand" "")]
8758 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8759 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8760 "ix86_expand_copysign (operands); DONE;")
8762 (define_insn_and_split "copysign<mode>3_const"
8763 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8765 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8766 (match_operand:CSGNMODE 2 "register_operand" "0")
8767 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8769 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8770 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8772 "&& reload_completed"
8774 "ix86_split_copysign_const (operands); DONE;")
8776 (define_insn "copysign<mode>3_var"
8777 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8779 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8780 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8781 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8782 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8784 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8785 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8786 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8790 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8792 [(match_operand:CSGNMODE 2 "register_operand" "")
8793 (match_operand:CSGNMODE 3 "register_operand" "")
8794 (match_operand:<CSGNVMODE> 4 "" "")
8795 (match_operand:<CSGNVMODE> 5 "" "")]
8797 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8798 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8799 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8800 && reload_completed"
8802 "ix86_split_copysign_var (operands); DONE;")
8804 ;; One complement instructions
8806 (define_expand "one_cmpl<mode>2"
8807 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8808 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8810 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8812 (define_insn "*one_cmpl<mode>2_1"
8813 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8814 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8815 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8816 "not{<imodesuffix>}\t%0"
8817 [(set_attr "type" "negnot")
8818 (set_attr "mode" "<MODE>")])
8820 ;; %%% Potential partial reg stall on alternative 1. What to do?
8821 (define_insn "*one_cmplqi2_1"
8822 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8823 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8824 "ix86_unary_operator_ok (NOT, QImode, operands)"
8828 [(set_attr "type" "negnot")
8829 (set_attr "mode" "QI,SI")])
8831 ;; ??? Currently never generated - xor is used instead.
8832 (define_insn "*one_cmplsi2_1_zext"
8833 [(set (match_operand:DI 0 "register_operand" "=r")
8835 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8836 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8838 [(set_attr "type" "negnot")
8839 (set_attr "mode" "SI")])
8841 (define_insn "*one_cmpl<mode>2_2"
8842 [(set (reg FLAGS_REG)
8843 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8845 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8846 (not:SWI (match_dup 1)))]
8847 "ix86_match_ccmode (insn, CCNOmode)
8848 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8850 [(set_attr "type" "alu1")
8851 (set_attr "mode" "<MODE>")])
8854 [(set (match_operand 0 "flags_reg_operand" "")
8855 (match_operator 2 "compare_operator"
8856 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8858 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8859 (not:SWI (match_dup 3)))]
8860 "ix86_match_ccmode (insn, CCNOmode)"
8861 [(parallel [(set (match_dup 0)
8862 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8865 (xor:SWI (match_dup 3) (const_int -1)))])])
8867 ;; ??? Currently never generated - xor is used instead.
8868 (define_insn "*one_cmplsi2_2_zext"
8869 [(set (reg FLAGS_REG)
8870 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8872 (set (match_operand:DI 0 "register_operand" "=r")
8873 (zero_extend:DI (not:SI (match_dup 1))))]
8874 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8875 && ix86_unary_operator_ok (NOT, SImode, operands)"
8877 [(set_attr "type" "alu1")
8878 (set_attr "mode" "SI")])
8881 [(set (match_operand 0 "flags_reg_operand" "")
8882 (match_operator 2 "compare_operator"
8883 [(not:SI (match_operand:SI 3 "register_operand" ""))
8885 (set (match_operand:DI 1 "register_operand" "")
8886 (zero_extend:DI (not:SI (match_dup 3))))]
8887 "ix86_match_ccmode (insn, CCNOmode)"
8888 [(parallel [(set (match_dup 0)
8889 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8892 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8894 ;; Shift instructions
8896 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8897 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8898 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8899 ;; from the assembler input.
8901 ;; This instruction shifts the target reg/mem as usual, but instead of
8902 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8903 ;; is a left shift double, bits are taken from the high order bits of
8904 ;; reg, else if the insn is a shift right double, bits are taken from the
8905 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8906 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8908 ;; Since sh[lr]d does not change the `reg' operand, that is done
8909 ;; separately, making all shifts emit pairs of shift double and normal
8910 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8911 ;; support a 63 bit shift, each shift where the count is in a reg expands
8912 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8914 ;; If the shift count is a constant, we need never emit more than one
8915 ;; shift pair, instead using moves and sign extension for counts greater
8918 (define_expand "ashl<mode>3"
8919 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8920 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8921 (match_operand:QI 2 "nonmemory_operand" "")))]
8923 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8925 (define_insn "*ashl<mode>3_doubleword"
8926 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8927 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8928 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8929 (clobber (reg:CC FLAGS_REG))]
8932 [(set_attr "type" "multi")])
8935 [(set (match_operand:DWI 0 "register_operand" "")
8936 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8937 (match_operand:QI 2 "nonmemory_operand" "")))
8938 (clobber (reg:CC FLAGS_REG))]
8939 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8941 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8943 ;; By default we don't ask for a scratch register, because when DWImode
8944 ;; values are manipulated, registers are already at a premium. But if
8945 ;; we have one handy, we won't turn it away.
8948 [(match_scratch:DWIH 3 "r")
8949 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8951 (match_operand:<DWI> 1 "nonmemory_operand" "")
8952 (match_operand:QI 2 "nonmemory_operand" "")))
8953 (clobber (reg:CC FLAGS_REG))])
8957 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8959 (define_insn "x86_64_shld"
8960 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8961 (ior:DI (ashift:DI (match_dup 0)
8962 (match_operand:QI 2 "nonmemory_operand" "Jc"))
8963 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
8964 (minus:QI (const_int 64) (match_dup 2)))))
8965 (clobber (reg:CC FLAGS_REG))]
8967 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
8968 [(set_attr "type" "ishift")
8969 (set_attr "prefix_0f" "1")
8970 (set_attr "mode" "DI")
8971 (set_attr "athlon_decode" "vector")
8972 (set_attr "amdfam10_decode" "vector")
8973 (set_attr "bdver1_decode" "vector")])
8975 (define_insn "x86_shld"
8976 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
8977 (ior:SI (ashift:SI (match_dup 0)
8978 (match_operand:QI 2 "nonmemory_operand" "Ic"))
8979 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
8980 (minus:QI (const_int 32) (match_dup 2)))))
8981 (clobber (reg:CC FLAGS_REG))]
8983 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
8984 [(set_attr "type" "ishift")
8985 (set_attr "prefix_0f" "1")
8986 (set_attr "mode" "SI")
8987 (set_attr "pent_pair" "np")
8988 (set_attr "athlon_decode" "vector")
8989 (set_attr "amdfam10_decode" "vector")
8990 (set_attr "bdver1_decode" "vector")])
8992 (define_expand "x86_shift<mode>_adj_1"
8993 [(set (reg:CCZ FLAGS_REG)
8994 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
8997 (set (match_operand:SWI48 0 "register_operand" "")
8998 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
8999 (match_operand:SWI48 1 "register_operand" "")
9002 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9003 (match_operand:SWI48 3 "register_operand" "")
9006 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9008 (define_expand "x86_shift<mode>_adj_2"
9009 [(use (match_operand:SWI48 0 "register_operand" ""))
9010 (use (match_operand:SWI48 1 "register_operand" ""))
9011 (use (match_operand:QI 2 "register_operand" ""))]
9014 rtx label = gen_label_rtx ();
9017 emit_insn (gen_testqi_ccz_1 (operands[2],
9018 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9020 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9021 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9022 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9023 gen_rtx_LABEL_REF (VOIDmode, label),
9025 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9026 JUMP_LABEL (tmp) = label;
9028 emit_move_insn (operands[0], operands[1]);
9029 ix86_expand_clear (operands[1]);
9032 LABEL_NUSES (label) = 1;
9037 ;; Avoid useless masking of count operand.
9038 (define_insn_and_split "*ashl<mode>3_mask"
9039 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9041 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9044 (match_operand:SI 2 "nonimmediate_operand" "c")
9045 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9046 (clobber (reg:CC FLAGS_REG))]
9047 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9048 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9049 == GET_MODE_BITSIZE (<MODE>mode)-1"
9052 [(parallel [(set (match_dup 0)
9053 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9054 (clobber (reg:CC FLAGS_REG))])]
9056 if (can_create_pseudo_p ())
9057 operands [2] = force_reg (SImode, operands[2]);
9059 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9061 [(set_attr "type" "ishift")
9062 (set_attr "mode" "<MODE>")])
9064 (define_insn "*bmi2_ashl<mode>3_1"
9065 [(set (match_operand:SWI48 0 "register_operand" "=r")
9066 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9067 (match_operand:SWI48 2 "register_operand" "r")))]
9069 "shlx\t{%2, %1, %0|%0, %1, %2}"
9070 [(set_attr "type" "ishiftx")
9071 (set_attr "mode" "<MODE>")])
9073 (define_insn "*ashl<mode>3_1"
9074 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9075 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9076 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9077 (clobber (reg:CC FLAGS_REG))]
9078 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9080 switch (get_attr_type (insn))
9087 gcc_assert (operands[2] == const1_rtx);
9088 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9089 return "add{<imodesuffix>}\t%0, %0";
9092 if (operands[2] == const1_rtx
9093 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9094 return "sal{<imodesuffix>}\t%0";
9096 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9099 [(set_attr "isa" "*,*,bmi2")
9101 (cond [(eq_attr "alternative" "1")
9102 (const_string "lea")
9103 (eq_attr "alternative" "2")
9104 (const_string "ishiftx")
9105 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9106 (match_operand 0 "register_operand" ""))
9107 (match_operand 2 "const1_operand" ""))
9108 (const_string "alu")
9110 (const_string "ishift")))
9111 (set (attr "length_immediate")
9113 (ior (eq_attr "type" "alu")
9114 (and (eq_attr "type" "ishift")
9115 (and (match_operand 2 "const1_operand" "")
9116 (ior (match_test "TARGET_SHIFT1")
9117 (match_test "optimize_function_for_size_p (cfun)")))))
9119 (const_string "*")))
9120 (set_attr "mode" "<MODE>")])
9122 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9124 [(set (match_operand:SWI48 0 "register_operand" "")
9125 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9126 (match_operand:QI 2 "register_operand" "")))
9127 (clobber (reg:CC FLAGS_REG))]
9128 "TARGET_BMI2 && reload_completed"
9130 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9131 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9133 (define_insn "*bmi2_ashlsi3_1_zext"
9134 [(set (match_operand:DI 0 "register_operand" "=r")
9136 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9137 (match_operand:SI 2 "register_operand" "r"))))]
9138 "TARGET_64BIT && TARGET_BMI2"
9139 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9140 [(set_attr "type" "ishiftx")
9141 (set_attr "mode" "SI")])
9143 (define_insn "*ashlsi3_1_zext"
9144 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9146 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9147 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9148 (clobber (reg:CC FLAGS_REG))]
9149 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9151 switch (get_attr_type (insn))
9158 gcc_assert (operands[2] == const1_rtx);
9159 return "add{l}\t%k0, %k0";
9162 if (operands[2] == const1_rtx
9163 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9164 return "sal{l}\t%k0";
9166 return "sal{l}\t{%2, %k0|%k0, %2}";
9169 [(set_attr "isa" "*,*,bmi2")
9171 (cond [(eq_attr "alternative" "1")
9172 (const_string "lea")
9173 (eq_attr "alternative" "2")
9174 (const_string "ishiftx")
9175 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9176 (match_operand 2 "const1_operand" ""))
9177 (const_string "alu")
9179 (const_string "ishift")))
9180 (set (attr "length_immediate")
9182 (ior (eq_attr "type" "alu")
9183 (and (eq_attr "type" "ishift")
9184 (and (match_operand 2 "const1_operand" "")
9185 (ior (match_test "TARGET_SHIFT1")
9186 (match_test "optimize_function_for_size_p (cfun)")))))
9188 (const_string "*")))
9189 (set_attr "mode" "SI")])
9191 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9193 [(set (match_operand:DI 0 "register_operand" "")
9195 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9196 (match_operand:QI 2 "register_operand" ""))))
9197 (clobber (reg:CC FLAGS_REG))]
9198 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9200 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9201 "operands[2] = gen_lowpart (SImode, operands[2]);")
9203 (define_insn "*ashlhi3_1"
9204 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9205 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9206 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9207 (clobber (reg:CC FLAGS_REG))]
9208 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9210 switch (get_attr_type (insn))
9216 gcc_assert (operands[2] == const1_rtx);
9217 return "add{w}\t%0, %0";
9220 if (operands[2] == const1_rtx
9221 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9222 return "sal{w}\t%0";
9224 return "sal{w}\t{%2, %0|%0, %2}";
9228 (cond [(eq_attr "alternative" "1")
9229 (const_string "lea")
9230 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9231 (match_operand 0 "register_operand" ""))
9232 (match_operand 2 "const1_operand" ""))
9233 (const_string "alu")
9235 (const_string "ishift")))
9236 (set (attr "length_immediate")
9238 (ior (eq_attr "type" "alu")
9239 (and (eq_attr "type" "ishift")
9240 (and (match_operand 2 "const1_operand" "")
9241 (ior (match_test "TARGET_SHIFT1")
9242 (match_test "optimize_function_for_size_p (cfun)")))))
9244 (const_string "*")))
9245 (set_attr "mode" "HI,SI")])
9247 ;; %%% Potential partial reg stall on alternative 1. What to do?
9248 (define_insn "*ashlqi3_1"
9249 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9250 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9251 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9252 (clobber (reg:CC FLAGS_REG))]
9253 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9255 switch (get_attr_type (insn))
9261 gcc_assert (operands[2] == const1_rtx);
9262 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9263 return "add{l}\t%k0, %k0";
9265 return "add{b}\t%0, %0";
9268 if (operands[2] == const1_rtx
9269 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9271 if (get_attr_mode (insn) == MODE_SI)
9272 return "sal{l}\t%k0";
9274 return "sal{b}\t%0";
9278 if (get_attr_mode (insn) == MODE_SI)
9279 return "sal{l}\t{%2, %k0|%k0, %2}";
9281 return "sal{b}\t{%2, %0|%0, %2}";
9286 (cond [(eq_attr "alternative" "2")
9287 (const_string "lea")
9288 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9289 (match_operand 0 "register_operand" ""))
9290 (match_operand 2 "const1_operand" ""))
9291 (const_string "alu")
9293 (const_string "ishift")))
9294 (set (attr "length_immediate")
9296 (ior (eq_attr "type" "alu")
9297 (and (eq_attr "type" "ishift")
9298 (and (match_operand 2 "const1_operand" "")
9299 (ior (match_test "TARGET_SHIFT1")
9300 (match_test "optimize_function_for_size_p (cfun)")))))
9302 (const_string "*")))
9303 (set_attr "mode" "QI,SI,SI")])
9305 (define_insn "*ashlqi3_1_slp"
9306 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9307 (ashift:QI (match_dup 0)
9308 (match_operand:QI 1 "nonmemory_operand" "cI")))
9309 (clobber (reg:CC FLAGS_REG))]
9310 "(optimize_function_for_size_p (cfun)
9311 || !TARGET_PARTIAL_FLAG_REG_STALL
9312 || (operands[1] == const1_rtx
9314 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9316 switch (get_attr_type (insn))
9319 gcc_assert (operands[1] == const1_rtx);
9320 return "add{b}\t%0, %0";
9323 if (operands[1] == const1_rtx
9324 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9325 return "sal{b}\t%0";
9327 return "sal{b}\t{%1, %0|%0, %1}";
9331 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9332 (match_operand 0 "register_operand" ""))
9333 (match_operand 1 "const1_operand" ""))
9334 (const_string "alu")
9336 (const_string "ishift1")))
9337 (set (attr "length_immediate")
9339 (ior (eq_attr "type" "alu")
9340 (and (eq_attr "type" "ishift1")
9341 (and (match_operand 1 "const1_operand" "")
9342 (ior (match_test "TARGET_SHIFT1")
9343 (match_test "optimize_function_for_size_p (cfun)")))))
9345 (const_string "*")))
9346 (set_attr "mode" "QI")])
9348 ;; Convert ashift to the lea pattern to avoid flags dependency.
9350 [(set (match_operand 0 "register_operand" "")
9351 (ashift (match_operand 1 "index_register_operand" "")
9352 (match_operand:QI 2 "const_int_operand" "")))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9356 && true_regnum (operands[0]) != true_regnum (operands[1])"
9359 enum machine_mode mode = GET_MODE (operands[0]);
9362 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9365 operands[0] = gen_lowpart (mode, operands[0]);
9366 operands[1] = gen_lowpart (mode, operands[1]);
9369 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9371 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9373 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9377 ;; Convert ashift to the lea pattern to avoid flags dependency.
9379 [(set (match_operand:DI 0 "register_operand" "")
9381 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9382 (match_operand:QI 2 "const_int_operand" ""))))
9383 (clobber (reg:CC FLAGS_REG))]
9384 "TARGET_64BIT && reload_completed
9385 && true_regnum (operands[0]) != true_regnum (operands[1])"
9387 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9389 operands[1] = gen_lowpart (DImode, operands[1]);
9390 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9393 ;; This pattern can't accept a variable shift count, since shifts by
9394 ;; zero don't affect the flags. We assume that shifts by constant
9395 ;; zero are optimized away.
9396 (define_insn "*ashl<mode>3_cmp"
9397 [(set (reg FLAGS_REG)
9399 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9400 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9402 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9403 (ashift:SWI (match_dup 1) (match_dup 2)))]
9404 "(optimize_function_for_size_p (cfun)
9405 || !TARGET_PARTIAL_FLAG_REG_STALL
9406 || (operands[2] == const1_rtx
9408 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9409 && ix86_match_ccmode (insn, CCGOCmode)
9410 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9412 switch (get_attr_type (insn))
9415 gcc_assert (operands[2] == const1_rtx);
9416 return "add{<imodesuffix>}\t%0, %0";
9419 if (operands[2] == const1_rtx
9420 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9421 return "sal{<imodesuffix>}\t%0";
9423 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9427 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9428 (match_operand 0 "register_operand" ""))
9429 (match_operand 2 "const1_operand" ""))
9430 (const_string "alu")
9432 (const_string "ishift")))
9433 (set (attr "length_immediate")
9435 (ior (eq_attr "type" "alu")
9436 (and (eq_attr "type" "ishift")
9437 (and (match_operand 2 "const1_operand" "")
9438 (ior (match_test "TARGET_SHIFT1")
9439 (match_test "optimize_function_for_size_p (cfun)")))))
9441 (const_string "*")))
9442 (set_attr "mode" "<MODE>")])
9444 (define_insn "*ashlsi3_cmp_zext"
9445 [(set (reg FLAGS_REG)
9447 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9448 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9450 (set (match_operand:DI 0 "register_operand" "=r")
9451 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9453 && (optimize_function_for_size_p (cfun)
9454 || !TARGET_PARTIAL_FLAG_REG_STALL
9455 || (operands[2] == const1_rtx
9457 || TARGET_DOUBLE_WITH_ADD)))
9458 && ix86_match_ccmode (insn, CCGOCmode)
9459 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9461 switch (get_attr_type (insn))
9464 gcc_assert (operands[2] == const1_rtx);
9465 return "add{l}\t%k0, %k0";
9468 if (operands[2] == const1_rtx
9469 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9470 return "sal{l}\t%k0";
9472 return "sal{l}\t{%2, %k0|%k0, %2}";
9476 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9477 (match_operand 2 "const1_operand" ""))
9478 (const_string "alu")
9480 (const_string "ishift")))
9481 (set (attr "length_immediate")
9483 (ior (eq_attr "type" "alu")
9484 (and (eq_attr "type" "ishift")
9485 (and (match_operand 2 "const1_operand" "")
9486 (ior (match_test "TARGET_SHIFT1")
9487 (match_test "optimize_function_for_size_p (cfun)")))))
9489 (const_string "*")))
9490 (set_attr "mode" "SI")])
9492 (define_insn "*ashl<mode>3_cconly"
9493 [(set (reg FLAGS_REG)
9495 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9496 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9498 (clobber (match_scratch:SWI 0 "=<r>"))]
9499 "(optimize_function_for_size_p (cfun)
9500 || !TARGET_PARTIAL_FLAG_REG_STALL
9501 || (operands[2] == const1_rtx
9503 || TARGET_DOUBLE_WITH_ADD)))
9504 && ix86_match_ccmode (insn, CCGOCmode)"
9506 switch (get_attr_type (insn))
9509 gcc_assert (operands[2] == const1_rtx);
9510 return "add{<imodesuffix>}\t%0, %0";
9513 if (operands[2] == const1_rtx
9514 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9515 return "sal{<imodesuffix>}\t%0";
9517 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9521 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9522 (match_operand 0 "register_operand" ""))
9523 (match_operand 2 "const1_operand" ""))
9524 (const_string "alu")
9526 (const_string "ishift")))
9527 (set (attr "length_immediate")
9529 (ior (eq_attr "type" "alu")
9530 (and (eq_attr "type" "ishift")
9531 (and (match_operand 2 "const1_operand" "")
9532 (ior (match_test "TARGET_SHIFT1")
9533 (match_test "optimize_function_for_size_p (cfun)")))))
9535 (const_string "*")))
9536 (set_attr "mode" "<MODE>")])
9538 ;; See comment above `ashl<mode>3' about how this works.
9540 (define_expand "<shift_insn><mode>3"
9541 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9542 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9543 (match_operand:QI 2 "nonmemory_operand" "")))]
9545 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9547 ;; Avoid useless masking of count operand.
9548 (define_insn_and_split "*<shift_insn><mode>3_mask"
9549 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9551 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9554 (match_operand:SI 2 "nonimmediate_operand" "c")
9555 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9556 (clobber (reg:CC FLAGS_REG))]
9557 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9558 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9559 == GET_MODE_BITSIZE (<MODE>mode)-1"
9562 [(parallel [(set (match_dup 0)
9563 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9564 (clobber (reg:CC FLAGS_REG))])]
9566 if (can_create_pseudo_p ())
9567 operands [2] = force_reg (SImode, operands[2]);
9569 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9571 [(set_attr "type" "ishift")
9572 (set_attr "mode" "<MODE>")])
9574 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9575 [(set (match_operand:DWI 0 "register_operand" "=r")
9576 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9577 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9578 (clobber (reg:CC FLAGS_REG))]
9581 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9583 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9584 [(set_attr "type" "multi")])
9586 ;; By default we don't ask for a scratch register, because when DWImode
9587 ;; values are manipulated, registers are already at a premium. But if
9588 ;; we have one handy, we won't turn it away.
9591 [(match_scratch:DWIH 3 "r")
9592 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9594 (match_operand:<DWI> 1 "register_operand" "")
9595 (match_operand:QI 2 "nonmemory_operand" "")))
9596 (clobber (reg:CC FLAGS_REG))])
9600 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9602 (define_insn "x86_64_shrd"
9603 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9604 (ior:DI (ashiftrt:DI (match_dup 0)
9605 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9606 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9607 (minus:QI (const_int 64) (match_dup 2)))))
9608 (clobber (reg:CC FLAGS_REG))]
9610 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9611 [(set_attr "type" "ishift")
9612 (set_attr "prefix_0f" "1")
9613 (set_attr "mode" "DI")
9614 (set_attr "athlon_decode" "vector")
9615 (set_attr "amdfam10_decode" "vector")
9616 (set_attr "bdver1_decode" "vector")])
9618 (define_insn "x86_shrd"
9619 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9620 (ior:SI (ashiftrt:SI (match_dup 0)
9621 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9622 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9623 (minus:QI (const_int 32) (match_dup 2)))))
9624 (clobber (reg:CC FLAGS_REG))]
9626 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9627 [(set_attr "type" "ishift")
9628 (set_attr "prefix_0f" "1")
9629 (set_attr "mode" "SI")
9630 (set_attr "pent_pair" "np")
9631 (set_attr "athlon_decode" "vector")
9632 (set_attr "amdfam10_decode" "vector")
9633 (set_attr "bdver1_decode" "vector")])
9635 (define_insn "ashrdi3_cvt"
9636 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9637 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9638 (match_operand:QI 2 "const_int_operand" "")))
9639 (clobber (reg:CC FLAGS_REG))]
9640 "TARGET_64BIT && INTVAL (operands[2]) == 63
9641 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9642 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9645 sar{q}\t{%2, %0|%0, %2}"
9646 [(set_attr "type" "imovx,ishift")
9647 (set_attr "prefix_0f" "0,*")
9648 (set_attr "length_immediate" "0,*")
9649 (set_attr "modrm" "0,1")
9650 (set_attr "mode" "DI")])
9652 (define_insn "ashrsi3_cvt"
9653 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9654 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9655 (match_operand:QI 2 "const_int_operand" "")))
9656 (clobber (reg:CC FLAGS_REG))]
9657 "INTVAL (operands[2]) == 31
9658 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9659 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9662 sar{l}\t{%2, %0|%0, %2}"
9663 [(set_attr "type" "imovx,ishift")
9664 (set_attr "prefix_0f" "0,*")
9665 (set_attr "length_immediate" "0,*")
9666 (set_attr "modrm" "0,1")
9667 (set_attr "mode" "SI")])
9669 (define_insn "*ashrsi3_cvt_zext"
9670 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9672 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9673 (match_operand:QI 2 "const_int_operand" ""))))
9674 (clobber (reg:CC FLAGS_REG))]
9675 "TARGET_64BIT && INTVAL (operands[2]) == 31
9676 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9677 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9680 sar{l}\t{%2, %k0|%k0, %2}"
9681 [(set_attr "type" "imovx,ishift")
9682 (set_attr "prefix_0f" "0,*")
9683 (set_attr "length_immediate" "0,*")
9684 (set_attr "modrm" "0,1")
9685 (set_attr "mode" "SI")])
9687 (define_expand "x86_shift<mode>_adj_3"
9688 [(use (match_operand:SWI48 0 "register_operand" ""))
9689 (use (match_operand:SWI48 1 "register_operand" ""))
9690 (use (match_operand:QI 2 "register_operand" ""))]
9693 rtx label = gen_label_rtx ();
9696 emit_insn (gen_testqi_ccz_1 (operands[2],
9697 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9699 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9700 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9701 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9702 gen_rtx_LABEL_REF (VOIDmode, label),
9704 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9705 JUMP_LABEL (tmp) = label;
9707 emit_move_insn (operands[0], operands[1]);
9708 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9709 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9711 LABEL_NUSES (label) = 1;
9716 (define_insn "*bmi2_<shift_insn><mode>3_1"
9717 [(set (match_operand:SWI48 0 "register_operand" "=r")
9718 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9719 (match_operand:SWI48 2 "register_operand" "r")))]
9721 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9722 [(set_attr "type" "ishiftx")
9723 (set_attr "mode" "<MODE>")])
9725 (define_insn "*<shift_insn><mode>3_1"
9726 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9728 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9729 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9730 (clobber (reg:CC FLAGS_REG))]
9731 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9733 switch (get_attr_type (insn))
9739 if (operands[2] == const1_rtx
9740 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9741 return "<shift>{<imodesuffix>}\t%0";
9743 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9746 [(set_attr "isa" "*,bmi2")
9747 (set_attr "type" "ishift,ishiftx")
9748 (set (attr "length_immediate")
9750 (and (match_operand 2 "const1_operand" "")
9751 (ior (match_test "TARGET_SHIFT1")
9752 (match_test "optimize_function_for_size_p (cfun)")))
9754 (const_string "*")))
9755 (set_attr "mode" "<MODE>")])
9757 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9759 [(set (match_operand:SWI48 0 "register_operand" "")
9760 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9761 (match_operand:QI 2 "register_operand" "")))
9762 (clobber (reg:CC FLAGS_REG))]
9763 "TARGET_BMI2 && reload_completed"
9765 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9766 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9768 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9769 [(set (match_operand:DI 0 "register_operand" "=r")
9771 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9772 (match_operand:SI 2 "register_operand" "r"))))]
9773 "TARGET_64BIT && TARGET_BMI2"
9774 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9775 [(set_attr "type" "ishiftx")
9776 (set_attr "mode" "SI")])
9778 (define_insn "*<shift_insn>si3_1_zext"
9779 [(set (match_operand:DI 0 "register_operand" "=r,r")
9781 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9782 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9783 (clobber (reg:CC FLAGS_REG))]
9784 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9786 switch (get_attr_type (insn))
9792 if (operands[2] == const1_rtx
9793 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9794 return "<shift>{l}\t%k0";
9796 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9799 [(set_attr "isa" "*,bmi2")
9800 (set_attr "type" "ishift,ishiftx")
9801 (set (attr "length_immediate")
9803 (and (match_operand 2 "const1_operand" "")
9804 (ior (match_test "TARGET_SHIFT1")
9805 (match_test "optimize_function_for_size_p (cfun)")))
9807 (const_string "*")))
9808 (set_attr "mode" "SI")])
9810 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9812 [(set (match_operand:DI 0 "register_operand" "")
9814 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9815 (match_operand:QI 2 "register_operand" ""))))
9816 (clobber (reg:CC FLAGS_REG))]
9817 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9819 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9820 "operands[2] = gen_lowpart (SImode, operands[2]);")
9822 (define_insn "*<shift_insn><mode>3_1"
9823 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9825 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9826 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9827 (clobber (reg:CC FLAGS_REG))]
9828 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9830 if (operands[2] == const1_rtx
9831 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9832 return "<shift>{<imodesuffix>}\t%0";
9834 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9836 [(set_attr "type" "ishift")
9837 (set (attr "length_immediate")
9839 (and (match_operand 2 "const1_operand" "")
9840 (ior (match_test "TARGET_SHIFT1")
9841 (match_test "optimize_function_for_size_p (cfun)")))
9843 (const_string "*")))
9844 (set_attr "mode" "<MODE>")])
9846 (define_insn "*<shift_insn>qi3_1_slp"
9847 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9848 (any_shiftrt:QI (match_dup 0)
9849 (match_operand:QI 1 "nonmemory_operand" "cI")))
9850 (clobber (reg:CC FLAGS_REG))]
9851 "(optimize_function_for_size_p (cfun)
9852 || !TARGET_PARTIAL_REG_STALL
9853 || (operands[1] == const1_rtx
9856 if (operands[1] == const1_rtx
9857 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9858 return "<shift>{b}\t%0";
9860 return "<shift>{b}\t{%1, %0|%0, %1}";
9862 [(set_attr "type" "ishift1")
9863 (set (attr "length_immediate")
9865 (and (match_operand 1 "const1_operand" "")
9866 (ior (match_test "TARGET_SHIFT1")
9867 (match_test "optimize_function_for_size_p (cfun)")))
9869 (const_string "*")))
9870 (set_attr "mode" "QI")])
9872 ;; This pattern can't accept a variable shift count, since shifts by
9873 ;; zero don't affect the flags. We assume that shifts by constant
9874 ;; zero are optimized away.
9875 (define_insn "*<shift_insn><mode>3_cmp"
9876 [(set (reg FLAGS_REG)
9879 (match_operand:SWI 1 "nonimmediate_operand" "0")
9880 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9882 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9883 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9884 "(optimize_function_for_size_p (cfun)
9885 || !TARGET_PARTIAL_FLAG_REG_STALL
9886 || (operands[2] == const1_rtx
9888 && ix86_match_ccmode (insn, CCGOCmode)
9889 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9891 if (operands[2] == const1_rtx
9892 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9893 return "<shift>{<imodesuffix>}\t%0";
9895 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9897 [(set_attr "type" "ishift")
9898 (set (attr "length_immediate")
9900 (and (match_operand 2 "const1_operand" "")
9901 (ior (match_test "TARGET_SHIFT1")
9902 (match_test "optimize_function_for_size_p (cfun)")))
9904 (const_string "*")))
9905 (set_attr "mode" "<MODE>")])
9907 (define_insn "*<shift_insn>si3_cmp_zext"
9908 [(set (reg FLAGS_REG)
9910 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9911 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9913 (set (match_operand:DI 0 "register_operand" "=r")
9914 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9916 && (optimize_function_for_size_p (cfun)
9917 || !TARGET_PARTIAL_FLAG_REG_STALL
9918 || (operands[2] == const1_rtx
9920 && ix86_match_ccmode (insn, CCGOCmode)
9921 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9923 if (operands[2] == const1_rtx
9924 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9925 return "<shift>{l}\t%k0";
9927 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9929 [(set_attr "type" "ishift")
9930 (set (attr "length_immediate")
9932 (and (match_operand 2 "const1_operand" "")
9933 (ior (match_test "TARGET_SHIFT1")
9934 (match_test "optimize_function_for_size_p (cfun)")))
9936 (const_string "*")))
9937 (set_attr "mode" "SI")])
9939 (define_insn "*<shift_insn><mode>3_cconly"
9940 [(set (reg FLAGS_REG)
9943 (match_operand:SWI 1 "register_operand" "0")
9944 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9946 (clobber (match_scratch:SWI 0 "=<r>"))]
9947 "(optimize_function_for_size_p (cfun)
9948 || !TARGET_PARTIAL_FLAG_REG_STALL
9949 || (operands[2] == const1_rtx
9951 && ix86_match_ccmode (insn, CCGOCmode)"
9953 if (operands[2] == const1_rtx
9954 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9955 return "<shift>{<imodesuffix>}\t%0";
9957 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9959 [(set_attr "type" "ishift")
9960 (set (attr "length_immediate")
9962 (and (match_operand 2 "const1_operand" "")
9963 (ior (match_test "TARGET_SHIFT1")
9964 (match_test "optimize_function_for_size_p (cfun)")))
9966 (const_string "*")))
9967 (set_attr "mode" "<MODE>")])
9969 ;; Rotate instructions
9971 (define_expand "<rotate_insn>ti3"
9972 [(set (match_operand:TI 0 "register_operand" "")
9973 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
9974 (match_operand:QI 2 "nonmemory_operand" "")))]
9977 if (const_1_to_63_operand (operands[2], VOIDmode))
9978 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
9979 (operands[0], operands[1], operands[2]));
9986 (define_expand "<rotate_insn>di3"
9987 [(set (match_operand:DI 0 "shiftdi_operand" "")
9988 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
9989 (match_operand:QI 2 "nonmemory_operand" "")))]
9993 ix86_expand_binary_operator (<CODE>, DImode, operands);
9994 else if (const_1_to_31_operand (operands[2], VOIDmode))
9995 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
9996 (operands[0], operands[1], operands[2]));
10003 (define_expand "<rotate_insn><mode>3"
10004 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10005 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10006 (match_operand:QI 2 "nonmemory_operand" "")))]
10008 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10010 ;; Avoid useless masking of count operand.
10011 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10012 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10014 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10017 (match_operand:SI 2 "nonimmediate_operand" "c")
10018 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10019 (clobber (reg:CC FLAGS_REG))]
10020 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10021 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10022 == GET_MODE_BITSIZE (<MODE>mode)-1"
10025 [(parallel [(set (match_dup 0)
10026 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10027 (clobber (reg:CC FLAGS_REG))])]
10029 if (can_create_pseudo_p ())
10030 operands [2] = force_reg (SImode, operands[2]);
10032 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10034 [(set_attr "type" "rotate")
10035 (set_attr "mode" "<MODE>")])
10037 ;; Implement rotation using two double-precision
10038 ;; shift instructions and a scratch register.
10040 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10041 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10042 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10043 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10044 (clobber (reg:CC FLAGS_REG))
10045 (clobber (match_scratch:DWIH 3 "=&r"))]
10049 [(set (match_dup 3) (match_dup 4))
10051 [(set (match_dup 4)
10052 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10053 (lshiftrt:DWIH (match_dup 5)
10054 (minus:QI (match_dup 6) (match_dup 2)))))
10055 (clobber (reg:CC FLAGS_REG))])
10057 [(set (match_dup 5)
10058 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10059 (lshiftrt:DWIH (match_dup 3)
10060 (minus:QI (match_dup 6) (match_dup 2)))))
10061 (clobber (reg:CC FLAGS_REG))])]
10063 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10065 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10068 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10069 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10070 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10071 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10072 (clobber (reg:CC FLAGS_REG))
10073 (clobber (match_scratch:DWIH 3 "=&r"))]
10077 [(set (match_dup 3) (match_dup 4))
10079 [(set (match_dup 4)
10080 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10081 (ashift:DWIH (match_dup 5)
10082 (minus:QI (match_dup 6) (match_dup 2)))))
10083 (clobber (reg:CC FLAGS_REG))])
10085 [(set (match_dup 5)
10086 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10087 (ashift:DWIH (match_dup 3)
10088 (minus:QI (match_dup 6) (match_dup 2)))))
10089 (clobber (reg:CC FLAGS_REG))])]
10091 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10093 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10096 (define_insn "*bmi2_rorx<mode>3_1"
10097 [(set (match_operand:SWI48 0 "register_operand" "=r")
10098 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10099 (match_operand:QI 2 "immediate_operand" "<S>")))]
10101 "rorx\t{%2, %1, %0|%0, %1, %2}"
10102 [(set_attr "type" "rotatex")
10103 (set_attr "mode" "<MODE>")])
10105 (define_insn "*<rotate_insn><mode>3_1"
10106 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10108 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10109 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10110 (clobber (reg:CC FLAGS_REG))]
10111 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10113 switch (get_attr_type (insn))
10119 if (operands[2] == const1_rtx
10120 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10121 return "<rotate>{<imodesuffix>}\t%0";
10123 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10126 [(set_attr "isa" "*,bmi2")
10127 (set_attr "type" "rotate,rotatex")
10128 (set (attr "length_immediate")
10130 (and (eq_attr "type" "rotate")
10131 (and (match_operand 2 "const1_operand" "")
10132 (ior (match_test "TARGET_SHIFT1")
10133 (match_test "optimize_function_for_size_p (cfun)"))))
10135 (const_string "*")))
10136 (set_attr "mode" "<MODE>")])
10138 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10140 [(set (match_operand:SWI48 0 "register_operand" "")
10141 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10142 (match_operand:QI 2 "immediate_operand" "")))
10143 (clobber (reg:CC FLAGS_REG))]
10144 "TARGET_BMI2 && reload_completed"
10145 [(set (match_dup 0)
10146 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10149 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10153 [(set (match_operand:SWI48 0 "register_operand" "")
10154 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10155 (match_operand:QI 2 "immediate_operand" "")))
10156 (clobber (reg:CC FLAGS_REG))]
10157 "TARGET_BMI2 && reload_completed"
10158 [(set (match_dup 0)
10159 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10161 (define_insn "*bmi2_rorxsi3_1_zext"
10162 [(set (match_operand:DI 0 "register_operand" "=r")
10164 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10165 (match_operand:QI 2 "immediate_operand" "I"))))]
10166 "TARGET_64BIT && TARGET_BMI2"
10167 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10168 [(set_attr "type" "rotatex")
10169 (set_attr "mode" "SI")])
10171 (define_insn "*<rotate_insn>si3_1_zext"
10172 [(set (match_operand:DI 0 "register_operand" "=r,r")
10174 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10175 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10176 (clobber (reg:CC FLAGS_REG))]
10177 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10179 switch (get_attr_type (insn))
10185 if (operands[2] == const1_rtx
10186 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10187 return "<rotate>{l}\t%k0";
10189 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10192 [(set_attr "isa" "*,bmi2")
10193 (set_attr "type" "rotate,rotatex")
10194 (set (attr "length_immediate")
10196 (and (eq_attr "type" "rotate")
10197 (and (match_operand 2 "const1_operand" "")
10198 (ior (match_test "TARGET_SHIFT1")
10199 (match_test "optimize_function_for_size_p (cfun)"))))
10201 (const_string "*")))
10202 (set_attr "mode" "SI")])
10204 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10206 [(set (match_operand:DI 0 "register_operand" "")
10208 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10209 (match_operand:QI 2 "immediate_operand" ""))))
10210 (clobber (reg:CC FLAGS_REG))]
10211 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10212 [(set (match_dup 0)
10213 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10216 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10220 [(set (match_operand:DI 0 "register_operand" "")
10222 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10223 (match_operand:QI 2 "immediate_operand" ""))))
10224 (clobber (reg:CC FLAGS_REG))]
10225 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10226 [(set (match_dup 0)
10227 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10229 (define_insn "*<rotate_insn><mode>3_1"
10230 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10231 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10232 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10233 (clobber (reg:CC FLAGS_REG))]
10234 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10236 if (operands[2] == const1_rtx
10237 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10238 return "<rotate>{<imodesuffix>}\t%0";
10240 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10242 [(set_attr "type" "rotate")
10243 (set (attr "length_immediate")
10245 (and (match_operand 2 "const1_operand" "")
10246 (ior (match_test "TARGET_SHIFT1")
10247 (match_test "optimize_function_for_size_p (cfun)")))
10249 (const_string "*")))
10250 (set_attr "mode" "<MODE>")])
10252 (define_insn "*<rotate_insn>qi3_1_slp"
10253 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10254 (any_rotate:QI (match_dup 0)
10255 (match_operand:QI 1 "nonmemory_operand" "cI")))
10256 (clobber (reg:CC FLAGS_REG))]
10257 "(optimize_function_for_size_p (cfun)
10258 || !TARGET_PARTIAL_REG_STALL
10259 || (operands[1] == const1_rtx
10260 && TARGET_SHIFT1))"
10262 if (operands[1] == const1_rtx
10263 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10264 return "<rotate>{b}\t%0";
10266 return "<rotate>{b}\t{%1, %0|%0, %1}";
10268 [(set_attr "type" "rotate1")
10269 (set (attr "length_immediate")
10271 (and (match_operand 1 "const1_operand" "")
10272 (ior (match_test "TARGET_SHIFT1")
10273 (match_test "optimize_function_for_size_p (cfun)")))
10275 (const_string "*")))
10276 (set_attr "mode" "QI")])
10279 [(set (match_operand:HI 0 "register_operand" "")
10280 (any_rotate:HI (match_dup 0) (const_int 8)))
10281 (clobber (reg:CC FLAGS_REG))]
10283 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10284 [(parallel [(set (strict_low_part (match_dup 0))
10285 (bswap:HI (match_dup 0)))
10286 (clobber (reg:CC FLAGS_REG))])])
10288 ;; Bit set / bit test instructions
10290 (define_expand "extv"
10291 [(set (match_operand:SI 0 "register_operand" "")
10292 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10293 (match_operand:SI 2 "const8_operand" "")
10294 (match_operand:SI 3 "const8_operand" "")))]
10297 /* Handle extractions from %ah et al. */
10298 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10301 /* From mips.md: extract_bit_field doesn't verify that our source
10302 matches the predicate, so check it again here. */
10303 if (! ext_register_operand (operands[1], VOIDmode))
10307 (define_expand "extzv"
10308 [(set (match_operand:SI 0 "register_operand" "")
10309 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10310 (match_operand:SI 2 "const8_operand" "")
10311 (match_operand:SI 3 "const8_operand" "")))]
10314 /* Handle extractions from %ah et al. */
10315 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10318 /* From mips.md: extract_bit_field doesn't verify that our source
10319 matches the predicate, so check it again here. */
10320 if (! ext_register_operand (operands[1], VOIDmode))
10324 (define_expand "insv"
10325 [(set (zero_extract (match_operand 0 "register_operand" "")
10326 (match_operand 1 "const_int_operand" "")
10327 (match_operand 2 "const_int_operand" ""))
10328 (match_operand 3 "register_operand" ""))]
10331 rtx (*gen_mov_insv_1) (rtx, rtx);
10333 if (ix86_expand_pinsr (operands))
10336 /* Handle insertions to %ah et al. */
10337 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10340 /* From mips.md: insert_bit_field doesn't verify that our source
10341 matches the predicate, so check it again here. */
10342 if (! ext_register_operand (operands[0], VOIDmode))
10345 gen_mov_insv_1 = (TARGET_64BIT
10346 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10348 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10352 ;; %%% bts, btr, btc, bt.
10353 ;; In general these instructions are *slow* when applied to memory,
10354 ;; since they enforce atomic operation. When applied to registers,
10355 ;; it depends on the cpu implementation. They're never faster than
10356 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10357 ;; no point. But in 64-bit, we can't hold the relevant immediates
10358 ;; within the instruction itself, so operating on bits in the high
10359 ;; 32-bits of a register becomes easier.
10361 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10362 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10363 ;; negdf respectively, so they can never be disabled entirely.
10365 (define_insn "*btsq"
10366 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10368 (match_operand:DI 1 "const_0_to_63_operand" ""))
10370 (clobber (reg:CC FLAGS_REG))]
10371 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10372 "bts{q}\t{%1, %0|%0, %1}"
10373 [(set_attr "type" "alu1")
10374 (set_attr "prefix_0f" "1")
10375 (set_attr "mode" "DI")])
10377 (define_insn "*btrq"
10378 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10380 (match_operand:DI 1 "const_0_to_63_operand" ""))
10382 (clobber (reg:CC FLAGS_REG))]
10383 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10384 "btr{q}\t{%1, %0|%0, %1}"
10385 [(set_attr "type" "alu1")
10386 (set_attr "prefix_0f" "1")
10387 (set_attr "mode" "DI")])
10389 (define_insn "*btcq"
10390 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10392 (match_operand:DI 1 "const_0_to_63_operand" ""))
10393 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10394 (clobber (reg:CC FLAGS_REG))]
10395 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10396 "btc{q}\t{%1, %0|%0, %1}"
10397 [(set_attr "type" "alu1")
10398 (set_attr "prefix_0f" "1")
10399 (set_attr "mode" "DI")])
10401 ;; Allow Nocona to avoid these instructions if a register is available.
10404 [(match_scratch:DI 2 "r")
10405 (parallel [(set (zero_extract:DI
10406 (match_operand:DI 0 "register_operand" "")
10408 (match_operand:DI 1 "const_0_to_63_operand" ""))
10410 (clobber (reg:CC FLAGS_REG))])]
10411 "TARGET_64BIT && !TARGET_USE_BT"
10414 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10417 if (HOST_BITS_PER_WIDE_INT >= 64)
10418 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10419 else if (i < HOST_BITS_PER_WIDE_INT)
10420 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10422 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10424 op1 = immed_double_const (lo, hi, DImode);
10427 emit_move_insn (operands[2], op1);
10431 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10436 [(match_scratch:DI 2 "r")
10437 (parallel [(set (zero_extract:DI
10438 (match_operand:DI 0 "register_operand" "")
10440 (match_operand:DI 1 "const_0_to_63_operand" ""))
10442 (clobber (reg:CC FLAGS_REG))])]
10443 "TARGET_64BIT && !TARGET_USE_BT"
10446 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10449 if (HOST_BITS_PER_WIDE_INT >= 64)
10450 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10451 else if (i < HOST_BITS_PER_WIDE_INT)
10452 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10454 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10456 op1 = immed_double_const (~lo, ~hi, DImode);
10459 emit_move_insn (operands[2], op1);
10463 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10468 [(match_scratch:DI 2 "r")
10469 (parallel [(set (zero_extract:DI
10470 (match_operand:DI 0 "register_operand" "")
10472 (match_operand:DI 1 "const_0_to_63_operand" ""))
10473 (not:DI (zero_extract:DI
10474 (match_dup 0) (const_int 1) (match_dup 1))))
10475 (clobber (reg:CC FLAGS_REG))])]
10476 "TARGET_64BIT && !TARGET_USE_BT"
10479 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10482 if (HOST_BITS_PER_WIDE_INT >= 64)
10483 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10484 else if (i < HOST_BITS_PER_WIDE_INT)
10485 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10487 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10489 op1 = immed_double_const (lo, hi, DImode);
10492 emit_move_insn (operands[2], op1);
10496 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10500 (define_insn "*bt<mode>"
10501 [(set (reg:CCC FLAGS_REG)
10503 (zero_extract:SWI48
10504 (match_operand:SWI48 0 "register_operand" "r")
10506 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10508 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10509 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10510 [(set_attr "type" "alu1")
10511 (set_attr "prefix_0f" "1")
10512 (set_attr "mode" "<MODE>")])
10514 ;; Store-flag instructions.
10516 ;; For all sCOND expanders, also expand the compare or test insn that
10517 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10519 (define_insn_and_split "*setcc_di_1"
10520 [(set (match_operand:DI 0 "register_operand" "=q")
10521 (match_operator:DI 1 "ix86_comparison_operator"
10522 [(reg FLAGS_REG) (const_int 0)]))]
10523 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10525 "&& reload_completed"
10526 [(set (match_dup 2) (match_dup 1))
10527 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10529 PUT_MODE (operands[1], QImode);
10530 operands[2] = gen_lowpart (QImode, operands[0]);
10533 (define_insn_and_split "*setcc_si_1_and"
10534 [(set (match_operand:SI 0 "register_operand" "=q")
10535 (match_operator:SI 1 "ix86_comparison_operator"
10536 [(reg FLAGS_REG) (const_int 0)]))
10537 (clobber (reg:CC FLAGS_REG))]
10538 "!TARGET_PARTIAL_REG_STALL
10539 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10541 "&& reload_completed"
10542 [(set (match_dup 2) (match_dup 1))
10543 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10544 (clobber (reg:CC FLAGS_REG))])]
10546 PUT_MODE (operands[1], QImode);
10547 operands[2] = gen_lowpart (QImode, operands[0]);
10550 (define_insn_and_split "*setcc_si_1_movzbl"
10551 [(set (match_operand:SI 0 "register_operand" "=q")
10552 (match_operator:SI 1 "ix86_comparison_operator"
10553 [(reg FLAGS_REG) (const_int 0)]))]
10554 "!TARGET_PARTIAL_REG_STALL
10555 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10557 "&& reload_completed"
10558 [(set (match_dup 2) (match_dup 1))
10559 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10561 PUT_MODE (operands[1], QImode);
10562 operands[2] = gen_lowpart (QImode, operands[0]);
10565 (define_insn "*setcc_qi"
10566 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10567 (match_operator:QI 1 "ix86_comparison_operator"
10568 [(reg FLAGS_REG) (const_int 0)]))]
10571 [(set_attr "type" "setcc")
10572 (set_attr "mode" "QI")])
10574 (define_insn "*setcc_qi_slp"
10575 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10576 (match_operator:QI 1 "ix86_comparison_operator"
10577 [(reg FLAGS_REG) (const_int 0)]))]
10580 [(set_attr "type" "setcc")
10581 (set_attr "mode" "QI")])
10583 ;; In general it is not safe to assume too much about CCmode registers,
10584 ;; so simplify-rtx stops when it sees a second one. Under certain
10585 ;; conditions this is safe on x86, so help combine not create
10592 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10593 (ne:QI (match_operator 1 "ix86_comparison_operator"
10594 [(reg FLAGS_REG) (const_int 0)])
10597 [(set (match_dup 0) (match_dup 1))]
10598 "PUT_MODE (operands[1], QImode);")
10601 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10602 (ne:QI (match_operator 1 "ix86_comparison_operator"
10603 [(reg FLAGS_REG) (const_int 0)])
10606 [(set (match_dup 0) (match_dup 1))]
10607 "PUT_MODE (operands[1], QImode);")
10610 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10611 (eq:QI (match_operator 1 "ix86_comparison_operator"
10612 [(reg FLAGS_REG) (const_int 0)])
10615 [(set (match_dup 0) (match_dup 1))]
10617 rtx new_op1 = copy_rtx (operands[1]);
10618 operands[1] = new_op1;
10619 PUT_MODE (new_op1, QImode);
10620 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10621 GET_MODE (XEXP (new_op1, 0))));
10623 /* Make sure that (a) the CCmode we have for the flags is strong
10624 enough for the reversed compare or (b) we have a valid FP compare. */
10625 if (! ix86_comparison_operator (new_op1, VOIDmode))
10630 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10631 (eq:QI (match_operator 1 "ix86_comparison_operator"
10632 [(reg FLAGS_REG) (const_int 0)])
10635 [(set (match_dup 0) (match_dup 1))]
10637 rtx new_op1 = copy_rtx (operands[1]);
10638 operands[1] = new_op1;
10639 PUT_MODE (new_op1, QImode);
10640 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10641 GET_MODE (XEXP (new_op1, 0))));
10643 /* Make sure that (a) the CCmode we have for the flags is strong
10644 enough for the reversed compare or (b) we have a valid FP compare. */
10645 if (! ix86_comparison_operator (new_op1, VOIDmode))
10649 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10650 ;; subsequent logical operations are used to imitate conditional moves.
10651 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10654 (define_insn "setcc_<mode>_sse"
10655 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10656 (match_operator:MODEF 3 "sse_comparison_operator"
10657 [(match_operand:MODEF 1 "register_operand" "0,x")
10658 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10659 "SSE_FLOAT_MODE_P (<MODE>mode)"
10661 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10662 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10663 [(set_attr "isa" "noavx,avx")
10664 (set_attr "type" "ssecmp")
10665 (set_attr "length_immediate" "1")
10666 (set_attr "prefix" "orig,vex")
10667 (set_attr "mode" "<MODE>")])
10669 ;; Basic conditional jump instructions.
10670 ;; We ignore the overflow flag for signed branch instructions.
10672 (define_insn "*jcc_1"
10674 (if_then_else (match_operator 1 "ix86_comparison_operator"
10675 [(reg FLAGS_REG) (const_int 0)])
10676 (label_ref (match_operand 0 "" ""))
10680 [(set_attr "type" "ibr")
10681 (set_attr "modrm" "0")
10682 (set (attr "length")
10683 (if_then_else (and (ge (minus (match_dup 0) (pc))
10685 (lt (minus (match_dup 0) (pc))
10690 (define_insn "*jcc_2"
10692 (if_then_else (match_operator 1 "ix86_comparison_operator"
10693 [(reg FLAGS_REG) (const_int 0)])
10695 (label_ref (match_operand 0 "" ""))))]
10698 [(set_attr "type" "ibr")
10699 (set_attr "modrm" "0")
10700 (set (attr "length")
10701 (if_then_else (and (ge (minus (match_dup 0) (pc))
10703 (lt (minus (match_dup 0) (pc))
10708 ;; In general it is not safe to assume too much about CCmode registers,
10709 ;; so simplify-rtx stops when it sees a second one. Under certain
10710 ;; conditions this is safe on x86, so help combine not create
10718 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10719 [(reg FLAGS_REG) (const_int 0)])
10721 (label_ref (match_operand 1 "" ""))
10725 (if_then_else (match_dup 0)
10726 (label_ref (match_dup 1))
10728 "PUT_MODE (operands[0], VOIDmode);")
10732 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10733 [(reg FLAGS_REG) (const_int 0)])
10735 (label_ref (match_operand 1 "" ""))
10739 (if_then_else (match_dup 0)
10740 (label_ref (match_dup 1))
10743 rtx new_op0 = copy_rtx (operands[0]);
10744 operands[0] = new_op0;
10745 PUT_MODE (new_op0, VOIDmode);
10746 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10747 GET_MODE (XEXP (new_op0, 0))));
10749 /* Make sure that (a) the CCmode we have for the flags is strong
10750 enough for the reversed compare or (b) we have a valid FP compare. */
10751 if (! ix86_comparison_operator (new_op0, VOIDmode))
10755 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10756 ;; pass generates from shift insn with QImode operand. Actually, the mode
10757 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10758 ;; appropriate modulo of the bit offset value.
10760 (define_insn_and_split "*jcc_bt<mode>"
10762 (if_then_else (match_operator 0 "bt_comparison_operator"
10763 [(zero_extract:SWI48
10764 (match_operand:SWI48 1 "register_operand" "r")
10767 (match_operand:QI 2 "register_operand" "r")))
10769 (label_ref (match_operand 3 "" ""))
10771 (clobber (reg:CC FLAGS_REG))]
10772 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10775 [(set (reg:CCC FLAGS_REG)
10777 (zero_extract:SWI48
10783 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10784 (label_ref (match_dup 3))
10787 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10789 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10792 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10793 ;; also for DImode, this is what combine produces.
10794 (define_insn_and_split "*jcc_bt<mode>_mask"
10796 (if_then_else (match_operator 0 "bt_comparison_operator"
10797 [(zero_extract:SWI48
10798 (match_operand:SWI48 1 "register_operand" "r")
10801 (match_operand:SI 2 "register_operand" "r")
10802 (match_operand:SI 3 "const_int_operand" "n")))])
10803 (label_ref (match_operand 4 "" ""))
10805 (clobber (reg:CC FLAGS_REG))]
10806 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10807 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10808 == GET_MODE_BITSIZE (<MODE>mode)-1"
10811 [(set (reg:CCC FLAGS_REG)
10813 (zero_extract:SWI48
10819 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10820 (label_ref (match_dup 4))
10823 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10825 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10828 (define_insn_and_split "*jcc_btsi_1"
10830 (if_then_else (match_operator 0 "bt_comparison_operator"
10833 (match_operand:SI 1 "register_operand" "r")
10834 (match_operand:QI 2 "register_operand" "r"))
10837 (label_ref (match_operand 3 "" ""))
10839 (clobber (reg:CC FLAGS_REG))]
10840 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10843 [(set (reg:CCC FLAGS_REG)
10851 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10852 (label_ref (match_dup 3))
10855 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10857 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10860 ;; avoid useless masking of bit offset operand
10861 (define_insn_and_split "*jcc_btsi_mask_1"
10864 (match_operator 0 "bt_comparison_operator"
10867 (match_operand:SI 1 "register_operand" "r")
10870 (match_operand:SI 2 "register_operand" "r")
10871 (match_operand:SI 3 "const_int_operand" "n")) 0))
10874 (label_ref (match_operand 4 "" ""))
10876 (clobber (reg:CC FLAGS_REG))]
10877 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10878 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10881 [(set (reg:CCC FLAGS_REG)
10889 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10890 (label_ref (match_dup 4))
10892 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10894 ;; Define combination compare-and-branch fp compare instructions to help
10897 (define_insn "*fp_jcc_1_387"
10899 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10900 [(match_operand 1 "register_operand" "f")
10901 (match_operand 2 "nonimmediate_operand" "fm")])
10902 (label_ref (match_operand 3 "" ""))
10904 (clobber (reg:CCFP FPSR_REG))
10905 (clobber (reg:CCFP FLAGS_REG))
10906 (clobber (match_scratch:HI 4 "=a"))]
10908 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10909 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10910 && SELECT_CC_MODE (GET_CODE (operands[0]),
10911 operands[1], operands[2]) == CCFPmode
10915 (define_insn "*fp_jcc_1r_387"
10917 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10918 [(match_operand 1 "register_operand" "f")
10919 (match_operand 2 "nonimmediate_operand" "fm")])
10921 (label_ref (match_operand 3 "" ""))))
10922 (clobber (reg:CCFP FPSR_REG))
10923 (clobber (reg:CCFP FLAGS_REG))
10924 (clobber (match_scratch:HI 4 "=a"))]
10926 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10927 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10928 && SELECT_CC_MODE (GET_CODE (operands[0]),
10929 operands[1], operands[2]) == CCFPmode
10933 (define_insn "*fp_jcc_2_387"
10935 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10936 [(match_operand 1 "register_operand" "f")
10937 (match_operand 2 "register_operand" "f")])
10938 (label_ref (match_operand 3 "" ""))
10940 (clobber (reg:CCFP FPSR_REG))
10941 (clobber (reg:CCFP FLAGS_REG))
10942 (clobber (match_scratch:HI 4 "=a"))]
10943 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10944 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10948 (define_insn "*fp_jcc_2r_387"
10950 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10951 [(match_operand 1 "register_operand" "f")
10952 (match_operand 2 "register_operand" "f")])
10954 (label_ref (match_operand 3 "" ""))))
10955 (clobber (reg:CCFP FPSR_REG))
10956 (clobber (reg:CCFP FLAGS_REG))
10957 (clobber (match_scratch:HI 4 "=a"))]
10958 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10959 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10963 (define_insn "*fp_jcc_3_387"
10965 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10966 [(match_operand 1 "register_operand" "f")
10967 (match_operand 2 "const0_operand" "")])
10968 (label_ref (match_operand 3 "" ""))
10970 (clobber (reg:CCFP FPSR_REG))
10971 (clobber (reg:CCFP FLAGS_REG))
10972 (clobber (match_scratch:HI 4 "=a"))]
10973 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10974 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10975 && SELECT_CC_MODE (GET_CODE (operands[0]),
10976 operands[1], operands[2]) == CCFPmode
10982 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10983 [(match_operand 1 "register_operand" "")
10984 (match_operand 2 "nonimmediate_operand" "")])
10985 (match_operand 3 "" "")
10986 (match_operand 4 "" "")))
10987 (clobber (reg:CCFP FPSR_REG))
10988 (clobber (reg:CCFP FLAGS_REG))]
10992 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
10993 operands[3], operands[4], NULL_RTX, NULL_RTX);
10999 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11000 [(match_operand 1 "register_operand" "")
11001 (match_operand 2 "general_operand" "")])
11002 (match_operand 3 "" "")
11003 (match_operand 4 "" "")))
11004 (clobber (reg:CCFP FPSR_REG))
11005 (clobber (reg:CCFP FLAGS_REG))
11006 (clobber (match_scratch:HI 5 "=a"))]
11010 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11011 operands[3], operands[4], operands[5], NULL_RTX);
11015 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11016 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11017 ;; with a precedence over other operators and is always put in the first
11018 ;; place. Swap condition and operands to match ficom instruction.
11020 (define_insn "*fp_jcc_4_<mode>_387"
11023 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11024 [(match_operator 1 "float_operator"
11025 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11026 (match_operand 3 "register_operand" "f,f")])
11027 (label_ref (match_operand 4 "" ""))
11029 (clobber (reg:CCFP FPSR_REG))
11030 (clobber (reg:CCFP FLAGS_REG))
11031 (clobber (match_scratch:HI 5 "=a,a"))]
11032 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11033 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11034 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11035 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11042 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11043 [(match_operator 1 "float_operator"
11044 [(match_operand:SWI24 2 "memory_operand" "")])
11045 (match_operand 3 "register_operand" "")])
11046 (match_operand 4 "" "")
11047 (match_operand 5 "" "")))
11048 (clobber (reg:CCFP FPSR_REG))
11049 (clobber (reg:CCFP FLAGS_REG))
11050 (clobber (match_scratch:HI 6 "=a"))]
11054 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11056 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11057 operands[3], operands[7],
11058 operands[4], operands[5], operands[6], NULL_RTX);
11062 ;; %%% Kill this when reload knows how to do it.
11066 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11067 [(match_operator 1 "float_operator"
11068 [(match_operand:SWI24 2 "register_operand" "")])
11069 (match_operand 3 "register_operand" "")])
11070 (match_operand 4 "" "")
11071 (match_operand 5 "" "")))
11072 (clobber (reg:CCFP FPSR_REG))
11073 (clobber (reg:CCFP FLAGS_REG))
11074 (clobber (match_scratch:HI 6 "=a"))]
11078 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11079 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11081 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11082 operands[3], operands[7],
11083 operands[4], operands[5], operands[6], operands[2]);
11087 ;; Unconditional and other jump instructions
11089 (define_insn "jump"
11091 (label_ref (match_operand 0 "" "")))]
11094 [(set_attr "type" "ibr")
11095 (set (attr "length")
11096 (if_then_else (and (ge (minus (match_dup 0) (pc))
11098 (lt (minus (match_dup 0) (pc))
11102 (set_attr "modrm" "0")])
11104 (define_expand "indirect_jump"
11105 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11107 (define_insn "*indirect_jump"
11108 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11111 [(set_attr "type" "ibr")
11112 (set_attr "length_immediate" "0")])
11114 (define_expand "tablejump"
11115 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11116 (use (label_ref (match_operand 1 "" "")))])]
11119 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11120 relative. Convert the relative address to an absolute address. */
11124 enum rtx_code code;
11126 /* We can't use @GOTOFF for text labels on VxWorks;
11127 see gotoff_operand. */
11128 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11132 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11134 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11138 op1 = pic_offset_table_rtx;
11143 op0 = pic_offset_table_rtx;
11147 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11150 else if (TARGET_X32)
11151 operands[0] = convert_memory_address (Pmode, operands[0]);
11154 (define_insn "*tablejump_1"
11155 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11156 (use (label_ref (match_operand 1 "" "")))]
11159 [(set_attr "type" "ibr")
11160 (set_attr "length_immediate" "0")])
11162 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11165 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11166 (set (match_operand:QI 1 "register_operand" "")
11167 (match_operator:QI 2 "ix86_comparison_operator"
11168 [(reg FLAGS_REG) (const_int 0)]))
11169 (set (match_operand 3 "q_regs_operand" "")
11170 (zero_extend (match_dup 1)))]
11171 "(peep2_reg_dead_p (3, operands[1])
11172 || operands_match_p (operands[1], operands[3]))
11173 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11174 [(set (match_dup 4) (match_dup 0))
11175 (set (strict_low_part (match_dup 5))
11178 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11179 operands[5] = gen_lowpart (QImode, operands[3]);
11180 ix86_expand_clear (operands[3]);
11183 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11186 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11187 (set (match_operand:QI 1 "register_operand" "")
11188 (match_operator:QI 2 "ix86_comparison_operator"
11189 [(reg FLAGS_REG) (const_int 0)]))
11190 (parallel [(set (match_operand 3 "q_regs_operand" "")
11191 (zero_extend (match_dup 1)))
11192 (clobber (reg:CC FLAGS_REG))])]
11193 "(peep2_reg_dead_p (3, operands[1])
11194 || operands_match_p (operands[1], operands[3]))
11195 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11196 [(set (match_dup 4) (match_dup 0))
11197 (set (strict_low_part (match_dup 5))
11200 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11201 operands[5] = gen_lowpart (QImode, operands[3]);
11202 ix86_expand_clear (operands[3]);
11205 ;; Call instructions.
11207 ;; The predicates normally associated with named expanders are not properly
11208 ;; checked for calls. This is a bug in the generic code, but it isn't that
11209 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11211 ;; P6 processors will jump to the address after the decrement when %esp
11212 ;; is used as a call operand, so they will execute return address as a code.
11213 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11215 ;; Register constraint for call instruction.
11216 (define_mode_attr c [(SI "l") (DI "r")])
11218 ;; Call subroutine returning no value.
11220 (define_expand "call"
11221 [(call (match_operand:QI 0 "" "")
11222 (match_operand 1 "" ""))
11223 (use (match_operand 2 "" ""))]
11226 ix86_expand_call (NULL, operands[0], operands[1],
11227 operands[2], NULL, false);
11231 (define_expand "sibcall"
11232 [(call (match_operand:QI 0 "" "")
11233 (match_operand 1 "" ""))
11234 (use (match_operand 2 "" ""))]
11237 ix86_expand_call (NULL, operands[0], operands[1],
11238 operands[2], NULL, true);
11242 (define_insn_and_split "*call_vzeroupper"
11243 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11244 (match_operand 1 "" ""))
11245 (unspec [(match_operand 2 "const_int_operand" "")]
11246 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11247 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11249 "&& reload_completed"
11251 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11252 [(set_attr "type" "call")])
11254 (define_insn "*call"
11255 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11256 (match_operand 1 "" ""))]
11257 "!SIBLING_CALL_P (insn)"
11258 "* return ix86_output_call_insn (insn, operands[0]);"
11259 [(set_attr "type" "call")])
11261 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11262 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11263 (match_operand 1 "" ""))
11264 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11265 (clobber (reg:TI XMM6_REG))
11266 (clobber (reg:TI XMM7_REG))
11267 (clobber (reg:TI XMM8_REG))
11268 (clobber (reg:TI XMM9_REG))
11269 (clobber (reg:TI XMM10_REG))
11270 (clobber (reg:TI XMM11_REG))
11271 (clobber (reg:TI XMM12_REG))
11272 (clobber (reg:TI XMM13_REG))
11273 (clobber (reg:TI XMM14_REG))
11274 (clobber (reg:TI XMM15_REG))
11275 (clobber (reg:DI SI_REG))
11276 (clobber (reg:DI DI_REG))
11277 (unspec [(match_operand 2 "const_int_operand" "")]
11278 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11279 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11281 "&& reload_completed"
11283 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11284 [(set_attr "type" "call")])
11286 (define_insn "*call_rex64_ms_sysv"
11287 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11288 (match_operand 1 "" ""))
11289 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11290 (clobber (reg:TI XMM6_REG))
11291 (clobber (reg:TI XMM7_REG))
11292 (clobber (reg:TI XMM8_REG))
11293 (clobber (reg:TI XMM9_REG))
11294 (clobber (reg:TI XMM10_REG))
11295 (clobber (reg:TI XMM11_REG))
11296 (clobber (reg:TI XMM12_REG))
11297 (clobber (reg:TI XMM13_REG))
11298 (clobber (reg:TI XMM14_REG))
11299 (clobber (reg:TI XMM15_REG))
11300 (clobber (reg:DI SI_REG))
11301 (clobber (reg:DI DI_REG))]
11302 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11303 "* return ix86_output_call_insn (insn, operands[0]);"
11304 [(set_attr "type" "call")])
11306 (define_insn_and_split "*sibcall_vzeroupper"
11307 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11308 (match_operand 1 "" ""))
11309 (unspec [(match_operand 2 "const_int_operand" "")]
11310 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11311 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11313 "&& reload_completed"
11315 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11316 [(set_attr "type" "call")])
11318 (define_insn "*sibcall"
11319 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11320 (match_operand 1 "" ""))]
11321 "SIBLING_CALL_P (insn)"
11322 "* return ix86_output_call_insn (insn, operands[0]);"
11323 [(set_attr "type" "call")])
11325 (define_expand "call_pop"
11326 [(parallel [(call (match_operand:QI 0 "" "")
11327 (match_operand:SI 1 "" ""))
11328 (set (reg:SI SP_REG)
11329 (plus:SI (reg:SI SP_REG)
11330 (match_operand:SI 3 "" "")))])]
11333 ix86_expand_call (NULL, operands[0], operands[1],
11334 operands[2], operands[3], false);
11338 (define_insn_and_split "*call_pop_vzeroupper"
11339 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11340 (match_operand:SI 1 "" ""))
11341 (set (reg:SI SP_REG)
11342 (plus:SI (reg:SI SP_REG)
11343 (match_operand:SI 2 "immediate_operand" "i")))
11344 (unspec [(match_operand 3 "const_int_operand" "")]
11345 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11346 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11348 "&& reload_completed"
11350 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11351 [(set_attr "type" "call")])
11353 (define_insn "*call_pop"
11354 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11355 (match_operand 1 "" ""))
11356 (set (reg:SI SP_REG)
11357 (plus:SI (reg:SI SP_REG)
11358 (match_operand:SI 2 "immediate_operand" "i")))]
11359 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11360 "* return ix86_output_call_insn (insn, operands[0]);"
11361 [(set_attr "type" "call")])
11363 (define_insn_and_split "*sibcall_pop_vzeroupper"
11364 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11365 (match_operand 1 "" ""))
11366 (set (reg:SI SP_REG)
11367 (plus:SI (reg:SI SP_REG)
11368 (match_operand:SI 2 "immediate_operand" "i")))
11369 (unspec [(match_operand 3 "const_int_operand" "")]
11370 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11371 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11373 "&& reload_completed"
11375 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11376 [(set_attr "type" "call")])
11378 (define_insn "*sibcall_pop"
11379 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11380 (match_operand 1 "" ""))
11381 (set (reg:SI SP_REG)
11382 (plus:SI (reg:SI SP_REG)
11383 (match_operand:SI 2 "immediate_operand" "i")))]
11384 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11385 "* return ix86_output_call_insn (insn, operands[0]);"
11386 [(set_attr "type" "call")])
11388 ;; Call subroutine, returning value in operand 0
11390 (define_expand "call_value"
11391 [(set (match_operand 0 "" "")
11392 (call (match_operand:QI 1 "" "")
11393 (match_operand 2 "" "")))
11394 (use (match_operand 3 "" ""))]
11397 ix86_expand_call (operands[0], operands[1], operands[2],
11398 operands[3], NULL, false);
11402 (define_expand "sibcall_value"
11403 [(set (match_operand 0 "" "")
11404 (call (match_operand:QI 1 "" "")
11405 (match_operand 2 "" "")))
11406 (use (match_operand 3 "" ""))]
11409 ix86_expand_call (operands[0], operands[1], operands[2],
11410 operands[3], NULL, true);
11414 (define_insn_and_split "*call_value_vzeroupper"
11415 [(set (match_operand 0 "" "")
11416 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11417 (match_operand 2 "" "")))
11418 (unspec [(match_operand 3 "const_int_operand" "")]
11419 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11420 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11422 "&& reload_completed"
11424 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11425 [(set_attr "type" "callv")])
11427 (define_insn "*call_value"
11428 [(set (match_operand 0 "" "")
11429 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11430 (match_operand 2 "" "")))]
11431 "!SIBLING_CALL_P (insn)"
11432 "* return ix86_output_call_insn (insn, operands[1]);"
11433 [(set_attr "type" "callv")])
11435 (define_insn_and_split "*sibcall_value_vzeroupper"
11436 [(set (match_operand 0 "" "")
11437 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11438 (match_operand 2 "" "")))
11439 (unspec [(match_operand 3 "const_int_operand" "")]
11440 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11441 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11443 "&& reload_completed"
11445 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11446 [(set_attr "type" "callv")])
11448 (define_insn "*sibcall_value"
11449 [(set (match_operand 0 "" "")
11450 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11451 (match_operand 2 "" "")))]
11452 "SIBLING_CALL_P (insn)"
11453 "* return ix86_output_call_insn (insn, operands[1]);"
11454 [(set_attr "type" "callv")])
11456 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11457 [(set (match_operand 0 "" "")
11458 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11459 (match_operand 2 "" "")))
11460 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11461 (clobber (reg:TI XMM6_REG))
11462 (clobber (reg:TI XMM7_REG))
11463 (clobber (reg:TI XMM8_REG))
11464 (clobber (reg:TI XMM9_REG))
11465 (clobber (reg:TI XMM10_REG))
11466 (clobber (reg:TI XMM11_REG))
11467 (clobber (reg:TI XMM12_REG))
11468 (clobber (reg:TI XMM13_REG))
11469 (clobber (reg:TI XMM14_REG))
11470 (clobber (reg:TI XMM15_REG))
11471 (clobber (reg:DI SI_REG))
11472 (clobber (reg:DI DI_REG))
11473 (unspec [(match_operand 3 "const_int_operand" "")]
11474 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11475 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11477 "&& reload_completed"
11479 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11480 [(set_attr "type" "callv")])
11482 (define_insn "*call_value_rex64_ms_sysv"
11483 [(set (match_operand 0 "" "")
11484 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11485 (match_operand 2 "" "")))
11486 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11487 (clobber (reg:TI XMM6_REG))
11488 (clobber (reg:TI XMM7_REG))
11489 (clobber (reg:TI XMM8_REG))
11490 (clobber (reg:TI XMM9_REG))
11491 (clobber (reg:TI XMM10_REG))
11492 (clobber (reg:TI XMM11_REG))
11493 (clobber (reg:TI XMM12_REG))
11494 (clobber (reg:TI XMM13_REG))
11495 (clobber (reg:TI XMM14_REG))
11496 (clobber (reg:TI XMM15_REG))
11497 (clobber (reg:DI SI_REG))
11498 (clobber (reg:DI DI_REG))]
11499 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11500 "* return ix86_output_call_insn (insn, operands[1]);"
11501 [(set_attr "type" "callv")])
11503 (define_expand "call_value_pop"
11504 [(parallel [(set (match_operand 0 "" "")
11505 (call (match_operand:QI 1 "" "")
11506 (match_operand:SI 2 "" "")))
11507 (set (reg:SI SP_REG)
11508 (plus:SI (reg:SI SP_REG)
11509 (match_operand:SI 4 "" "")))])]
11512 ix86_expand_call (operands[0], operands[1], operands[2],
11513 operands[3], operands[4], false);
11517 (define_insn_and_split "*call_value_pop_vzeroupper"
11518 [(set (match_operand 0 "" "")
11519 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11520 (match_operand 2 "" "")))
11521 (set (reg:SI SP_REG)
11522 (plus:SI (reg:SI SP_REG)
11523 (match_operand:SI 3 "immediate_operand" "i")))
11524 (unspec [(match_operand 4 "const_int_operand" "")]
11525 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11526 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11528 "&& reload_completed"
11530 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11531 [(set_attr "type" "callv")])
11533 (define_insn "*call_value_pop"
11534 [(set (match_operand 0 "" "")
11535 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11536 (match_operand 2 "" "")))
11537 (set (reg:SI SP_REG)
11538 (plus:SI (reg:SI SP_REG)
11539 (match_operand:SI 3 "immediate_operand" "i")))]
11540 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11541 "* return ix86_output_call_insn (insn, operands[1]);"
11542 [(set_attr "type" "callv")])
11544 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11545 [(set (match_operand 0 "" "")
11546 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11547 (match_operand 2 "" "")))
11548 (set (reg:SI SP_REG)
11549 (plus:SI (reg:SI SP_REG)
11550 (match_operand:SI 3 "immediate_operand" "i")))
11551 (unspec [(match_operand 4 "const_int_operand" "")]
11552 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11553 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11555 "&& reload_completed"
11557 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11558 [(set_attr "type" "callv")])
11560 (define_insn "*sibcall_value_pop"
11561 [(set (match_operand 0 "" "")
11562 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11563 (match_operand 2 "" "")))
11564 (set (reg:SI SP_REG)
11565 (plus:SI (reg:SI SP_REG)
11566 (match_operand:SI 3 "immediate_operand" "i")))]
11567 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11568 "* return ix86_output_call_insn (insn, operands[1]);"
11569 [(set_attr "type" "callv")])
11571 ;; Call subroutine returning any type.
11573 (define_expand "untyped_call"
11574 [(parallel [(call (match_operand 0 "" "")
11576 (match_operand 1 "" "")
11577 (match_operand 2 "" "")])]
11582 /* In order to give reg-stack an easier job in validating two
11583 coprocessor registers as containing a possible return value,
11584 simply pretend the untyped call returns a complex long double
11587 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11588 and should have the default ABI. */
11590 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11591 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11592 operands[0], const0_rtx,
11593 GEN_INT ((TARGET_64BIT
11594 ? (ix86_abi == SYSV_ABI
11595 ? X86_64_SSE_REGPARM_MAX
11596 : X86_64_MS_SSE_REGPARM_MAX)
11597 : X86_32_SSE_REGPARM_MAX)
11601 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11603 rtx set = XVECEXP (operands[2], 0, i);
11604 emit_move_insn (SET_DEST (set), SET_SRC (set));
11607 /* The optimizer does not know that the call sets the function value
11608 registers we stored in the result block. We avoid problems by
11609 claiming that all hard registers are used and clobbered at this
11611 emit_insn (gen_blockage ());
11616 ;; Prologue and epilogue instructions
11618 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11619 ;; all of memory. This blocks insns from being moved across this point.
11621 (define_insn "blockage"
11622 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11625 [(set_attr "length" "0")])
11627 ;; Do not schedule instructions accessing memory across this point.
11629 (define_expand "memory_blockage"
11630 [(set (match_dup 0)
11631 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11634 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11635 MEM_VOLATILE_P (operands[0]) = 1;
11638 (define_insn "*memory_blockage"
11639 [(set (match_operand:BLK 0 "" "")
11640 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11643 [(set_attr "length" "0")])
11645 ;; As USE insns aren't meaningful after reload, this is used instead
11646 ;; to prevent deleting instructions setting registers for PIC code
11647 (define_insn "prologue_use"
11648 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11651 [(set_attr "length" "0")])
11653 ;; Insn emitted into the body of a function to return from a function.
11654 ;; This is only done if the function's epilogue is known to be simple.
11655 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11657 (define_expand "return"
11659 "ix86_can_use_return_insn_p ()"
11661 ix86_maybe_emit_epilogue_vzeroupper ();
11662 if (crtl->args.pops_args)
11664 rtx popc = GEN_INT (crtl->args.pops_args);
11665 emit_jump_insn (gen_simple_return_pop_internal (popc));
11670 ;; We need to disable this for TARGET_SEH, as otherwise
11671 ;; shrink-wrapped prologue gets enabled too. This might exceed
11672 ;; the maximum size of prologue in unwind information.
11674 (define_expand "simple_return"
11678 ix86_maybe_emit_epilogue_vzeroupper ();
11679 if (crtl->args.pops_args)
11681 rtx popc = GEN_INT (crtl->args.pops_args);
11682 emit_jump_insn (gen_simple_return_pop_internal (popc));
11687 (define_insn "simple_return_internal"
11691 [(set_attr "length" "1")
11692 (set_attr "atom_unit" "jeu")
11693 (set_attr "length_immediate" "0")
11694 (set_attr "modrm" "0")])
11696 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11697 ;; instruction Athlon and K8 have.
11699 (define_insn "simple_return_internal_long"
11701 (unspec [(const_int 0)] UNSPEC_REP)]
11704 [(set_attr "length" "2")
11705 (set_attr "atom_unit" "jeu")
11706 (set_attr "length_immediate" "0")
11707 (set_attr "prefix_rep" "1")
11708 (set_attr "modrm" "0")])
11710 (define_insn "simple_return_pop_internal"
11712 (use (match_operand:SI 0 "const_int_operand" ""))]
11715 [(set_attr "length" "3")
11716 (set_attr "atom_unit" "jeu")
11717 (set_attr "length_immediate" "2")
11718 (set_attr "modrm" "0")])
11720 (define_insn "simple_return_indirect_internal"
11722 (use (match_operand:SI 0 "register_operand" "r"))]
11725 [(set_attr "type" "ibr")
11726 (set_attr "length_immediate" "0")])
11732 [(set_attr "length" "1")
11733 (set_attr "length_immediate" "0")
11734 (set_attr "modrm" "0")])
11736 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11737 (define_insn "nops"
11738 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11742 int num = INTVAL (operands[0]);
11744 gcc_assert (num >= 1 && num <= 8);
11747 fputs ("\tnop\n", asm_out_file);
11751 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11752 (set_attr "length_immediate" "0")
11753 (set_attr "modrm" "0")])
11755 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11756 ;; branch prediction penalty for the third jump in a 16-byte
11760 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11763 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11764 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11766 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11767 The align insn is used to avoid 3 jump instructions in the row to improve
11768 branch prediction and the benefits hardly outweigh the cost of extra 8
11769 nops on the average inserted by full alignment pseudo operation. */
11773 [(set_attr "length" "16")])
11775 (define_expand "prologue"
11778 "ix86_expand_prologue (); DONE;")
11780 (define_insn "set_got"
11781 [(set (match_operand:SI 0 "register_operand" "=r")
11782 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11783 (clobber (reg:CC FLAGS_REG))]
11785 "* return output_set_got (operands[0], NULL_RTX);"
11786 [(set_attr "type" "multi")
11787 (set_attr "length" "12")])
11789 (define_insn "set_got_labelled"
11790 [(set (match_operand:SI 0 "register_operand" "=r")
11791 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11793 (clobber (reg:CC FLAGS_REG))]
11795 "* return output_set_got (operands[0], operands[1]);"
11796 [(set_attr "type" "multi")
11797 (set_attr "length" "12")])
11799 (define_insn "set_got_rex64"
11800 [(set (match_operand:DI 0 "register_operand" "=r")
11801 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11803 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11804 [(set_attr "type" "lea")
11805 (set_attr "length_address" "4")
11806 (set_attr "mode" "DI")])
11808 (define_insn "set_rip_rex64"
11809 [(set (match_operand:DI 0 "register_operand" "=r")
11810 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11812 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11813 [(set_attr "type" "lea")
11814 (set_attr "length_address" "4")
11815 (set_attr "mode" "DI")])
11817 (define_insn "set_got_offset_rex64"
11818 [(set (match_operand:DI 0 "register_operand" "=r")
11820 [(label_ref (match_operand 1 "" ""))]
11821 UNSPEC_SET_GOT_OFFSET))]
11823 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11824 [(set_attr "type" "imov")
11825 (set_attr "length_immediate" "0")
11826 (set_attr "length_address" "8")
11827 (set_attr "mode" "DI")])
11829 (define_expand "epilogue"
11832 "ix86_expand_epilogue (1); DONE;")
11834 (define_expand "sibcall_epilogue"
11837 "ix86_expand_epilogue (0); DONE;")
11839 (define_expand "eh_return"
11840 [(use (match_operand 0 "register_operand" ""))]
11843 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11845 /* Tricky bit: we write the address of the handler to which we will
11846 be returning into someone else's stack frame, one word below the
11847 stack address we wish to restore. */
11848 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11849 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11850 tmp = gen_rtx_MEM (Pmode, tmp);
11851 emit_move_insn (tmp, ra);
11853 emit_jump_insn (gen_eh_return_internal ());
11858 (define_insn_and_split "eh_return_internal"
11862 "epilogue_completed"
11864 "ix86_expand_epilogue (2); DONE;")
11866 (define_insn "leave"
11867 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11868 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11869 (clobber (mem:BLK (scratch)))]
11872 [(set_attr "type" "leave")])
11874 (define_insn "leave_rex64"
11875 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11876 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11877 (clobber (mem:BLK (scratch)))]
11880 [(set_attr "type" "leave")])
11882 ;; Handle -fsplit-stack.
11884 (define_expand "split_stack_prologue"
11888 ix86_expand_split_stack_prologue ();
11892 ;; In order to support the call/return predictor, we use a return
11893 ;; instruction which the middle-end doesn't see.
11894 (define_insn "split_stack_return"
11895 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11896 UNSPECV_SPLIT_STACK_RETURN)]
11899 if (operands[0] == const0_rtx)
11904 [(set_attr "atom_unit" "jeu")
11905 (set_attr "modrm" "0")
11906 (set (attr "length")
11907 (if_then_else (match_operand:SI 0 "const0_operand" "")
11910 (set (attr "length_immediate")
11911 (if_then_else (match_operand:SI 0 "const0_operand" "")
11915 ;; If there are operand 0 bytes available on the stack, jump to
11918 (define_expand "split_stack_space_check"
11919 [(set (pc) (if_then_else
11920 (ltu (minus (reg SP_REG)
11921 (match_operand 0 "register_operand" ""))
11922 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11923 (label_ref (match_operand 1 "" ""))
11927 rtx reg, size, limit;
11929 reg = gen_reg_rtx (Pmode);
11930 size = force_reg (Pmode, operands[0]);
11931 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11932 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11933 UNSPEC_STACK_CHECK);
11934 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11935 ix86_expand_branch (GEU, reg, limit, operands[1]);
11940 ;; Bit manipulation instructions.
11942 (define_expand "ffs<mode>2"
11943 [(set (match_dup 2) (const_int -1))
11944 (parallel [(set (reg:CCZ FLAGS_REG)
11946 (match_operand:SWI48 1 "nonimmediate_operand" "")
11948 (set (match_operand:SWI48 0 "register_operand" "")
11949 (ctz:SWI48 (match_dup 1)))])
11950 (set (match_dup 0) (if_then_else:SWI48
11951 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11954 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11955 (clobber (reg:CC FLAGS_REG))])]
11958 if (<MODE>mode == SImode && !TARGET_CMOVE)
11960 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
11963 operands[2] = gen_reg_rtx (<MODE>mode);
11966 (define_insn_and_split "ffssi2_no_cmove"
11967 [(set (match_operand:SI 0 "register_operand" "=r")
11968 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
11969 (clobber (match_scratch:SI 2 "=&q"))
11970 (clobber (reg:CC FLAGS_REG))]
11973 "&& reload_completed"
11974 [(parallel [(set (reg:CCZ FLAGS_REG)
11975 (compare:CCZ (match_dup 1) (const_int 0)))
11976 (set (match_dup 0) (ctz:SI (match_dup 1)))])
11977 (set (strict_low_part (match_dup 3))
11978 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
11979 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
11980 (clobber (reg:CC FLAGS_REG))])
11981 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
11982 (clobber (reg:CC FLAGS_REG))])
11983 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
11984 (clobber (reg:CC FLAGS_REG))])]
11986 operands[3] = gen_lowpart (QImode, operands[2]);
11987 ix86_expand_clear (operands[2]);
11990 (define_insn "*ffs<mode>_1"
11991 [(set (reg:CCZ FLAGS_REG)
11992 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
11994 (set (match_operand:SWI48 0 "register_operand" "=r")
11995 (ctz:SWI48 (match_dup 1)))]
11997 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
11998 [(set_attr "type" "alu1")
11999 (set_attr "prefix_0f" "1")
12000 (set_attr "mode" "<MODE>")])
12002 (define_insn "ctz<mode>2"
12003 [(set (match_operand:SWI248 0 "register_operand" "=r")
12004 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12005 (clobber (reg:CC FLAGS_REG))]
12009 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12011 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12013 [(set_attr "type" "alu1")
12014 (set_attr "prefix_0f" "1")
12015 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12016 (set_attr "mode" "<MODE>")])
12018 (define_expand "clz<mode>2"
12020 [(set (match_operand:SWI248 0 "register_operand" "")
12023 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12024 (clobber (reg:CC FLAGS_REG))])
12026 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12027 (clobber (reg:CC FLAGS_REG))])]
12032 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12035 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12038 (define_insn "clz<mode>2_lzcnt"
12039 [(set (match_operand:SWI248 0 "register_operand" "=r")
12040 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12041 (clobber (reg:CC FLAGS_REG))]
12043 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12044 [(set_attr "prefix_rep" "1")
12045 (set_attr "type" "bitmanip")
12046 (set_attr "mode" "<MODE>")])
12048 ;; BMI instructions.
12049 (define_insn "*bmi_andn_<mode>"
12050 [(set (match_operand:SWI48 0 "register_operand" "=r")
12053 (match_operand:SWI48 1 "register_operand" "r"))
12054 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12055 (clobber (reg:CC FLAGS_REG))]
12057 "andn\t{%2, %1, %0|%0, %1, %2}"
12058 [(set_attr "type" "bitmanip")
12059 (set_attr "mode" "<MODE>")])
12061 (define_insn "bmi_bextr_<mode>"
12062 [(set (match_operand:SWI48 0 "register_operand" "=r")
12063 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12064 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12066 (clobber (reg:CC FLAGS_REG))]
12068 "bextr\t{%2, %1, %0|%0, %1, %2}"
12069 [(set_attr "type" "bitmanip")
12070 (set_attr "mode" "<MODE>")])
12072 (define_insn "*bmi_blsi_<mode>"
12073 [(set (match_operand:SWI48 0 "register_operand" "=r")
12076 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12078 (clobber (reg:CC FLAGS_REG))]
12080 "blsi\t{%1, %0|%0, %1}"
12081 [(set_attr "type" "bitmanip")
12082 (set_attr "mode" "<MODE>")])
12084 (define_insn "*bmi_blsmsk_<mode>"
12085 [(set (match_operand:SWI48 0 "register_operand" "=r")
12088 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12091 (clobber (reg:CC FLAGS_REG))]
12093 "blsmsk\t{%1, %0|%0, %1}"
12094 [(set_attr "type" "bitmanip")
12095 (set_attr "mode" "<MODE>")])
12097 (define_insn "*bmi_blsr_<mode>"
12098 [(set (match_operand:SWI48 0 "register_operand" "=r")
12101 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12104 (clobber (reg:CC FLAGS_REG))]
12106 "blsr\t{%1, %0|%0, %1}"
12107 [(set_attr "type" "bitmanip")
12108 (set_attr "mode" "<MODE>")])
12110 ;; BMI2 instructions.
12111 (define_insn "bmi2_bzhi_<mode>3"
12112 [(set (match_operand:SWI48 0 "register_operand" "=r")
12113 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12114 (lshiftrt:SWI48 (const_int -1)
12115 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12116 (clobber (reg:CC FLAGS_REG))]
12118 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12119 [(set_attr "type" "bitmanip")
12120 (set_attr "prefix" "vex")
12121 (set_attr "mode" "<MODE>")])
12123 (define_insn "bmi2_pdep_<mode>3"
12124 [(set (match_operand:SWI48 0 "register_operand" "=r")
12125 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12126 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12129 "pdep\t{%2, %1, %0|%0, %1, %2}"
12130 [(set_attr "type" "bitmanip")
12131 (set_attr "prefix" "vex")
12132 (set_attr "mode" "<MODE>")])
12134 (define_insn "bmi2_pext_<mode>3"
12135 [(set (match_operand:SWI48 0 "register_operand" "=r")
12136 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12137 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12140 "pext\t{%2, %1, %0|%0, %1, %2}"
12141 [(set_attr "type" "bitmanip")
12142 (set_attr "prefix" "vex")
12143 (set_attr "mode" "<MODE>")])
12145 ;; TBM instructions.
12146 (define_insn "tbm_bextri_<mode>"
12147 [(set (match_operand:SWI48 0 "register_operand" "=r")
12148 (zero_extract:SWI48
12149 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12150 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12151 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12152 (clobber (reg:CC FLAGS_REG))]
12155 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12156 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12158 [(set_attr "type" "bitmanip")
12159 (set_attr "mode" "<MODE>")])
12161 (define_insn "*tbm_blcfill_<mode>"
12162 [(set (match_operand:SWI48 0 "register_operand" "=r")
12165 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12168 (clobber (reg:CC FLAGS_REG))]
12170 "blcfill\t{%1, %0|%0, %1}"
12171 [(set_attr "type" "bitmanip")
12172 (set_attr "mode" "<MODE>")])
12174 (define_insn "*tbm_blci_<mode>"
12175 [(set (match_operand:SWI48 0 "register_operand" "=r")
12179 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12182 (clobber (reg:CC FLAGS_REG))]
12184 "blci\t{%1, %0|%0, %1}"
12185 [(set_attr "type" "bitmanip")
12186 (set_attr "mode" "<MODE>")])
12188 (define_insn "*tbm_blcic_<mode>"
12189 [(set (match_operand:SWI48 0 "register_operand" "=r")
12192 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12196 (clobber (reg:CC FLAGS_REG))]
12198 "blcic\t{%1, %0|%0, %1}"
12199 [(set_attr "type" "bitmanip")
12200 (set_attr "mode" "<MODE>")])
12202 (define_insn "*tbm_blcmsk_<mode>"
12203 [(set (match_operand:SWI48 0 "register_operand" "=r")
12206 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12209 (clobber (reg:CC FLAGS_REG))]
12211 "blcmsk\t{%1, %0|%0, %1}"
12212 [(set_attr "type" "bitmanip")
12213 (set_attr "mode" "<MODE>")])
12215 (define_insn "*tbm_blcs_<mode>"
12216 [(set (match_operand:SWI48 0 "register_operand" "=r")
12219 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12222 (clobber (reg:CC FLAGS_REG))]
12224 "blcs\t{%1, %0|%0, %1}"
12225 [(set_attr "type" "bitmanip")
12226 (set_attr "mode" "<MODE>")])
12228 (define_insn "*tbm_blsfill_<mode>"
12229 [(set (match_operand:SWI48 0 "register_operand" "=r")
12232 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12235 (clobber (reg:CC FLAGS_REG))]
12237 "blsfill\t{%1, %0|%0, %1}"
12238 [(set_attr "type" "bitmanip")
12239 (set_attr "mode" "<MODE>")])
12241 (define_insn "*tbm_blsic_<mode>"
12242 [(set (match_operand:SWI48 0 "register_operand" "=r")
12245 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12249 (clobber (reg:CC FLAGS_REG))]
12251 "blsic\t{%1, %0|%0, %1}"
12252 [(set_attr "type" "bitmanip")
12253 (set_attr "mode" "<MODE>")])
12255 (define_insn "*tbm_t1mskc_<mode>"
12256 [(set (match_operand:SWI48 0 "register_operand" "=r")
12259 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12263 (clobber (reg:CC FLAGS_REG))]
12265 "t1mskc\t{%1, %0|%0, %1}"
12266 [(set_attr "type" "bitmanip")
12267 (set_attr "mode" "<MODE>")])
12269 (define_insn "*tbm_tzmsk_<mode>"
12270 [(set (match_operand:SWI48 0 "register_operand" "=r")
12273 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12277 (clobber (reg:CC FLAGS_REG))]
12279 "tzmsk\t{%1, %0|%0, %1}"
12280 [(set_attr "type" "bitmanip")
12281 (set_attr "mode" "<MODE>")])
12283 (define_insn "bsr_rex64"
12284 [(set (match_operand:DI 0 "register_operand" "=r")
12285 (minus:DI (const_int 63)
12286 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12287 (clobber (reg:CC FLAGS_REG))]
12289 "bsr{q}\t{%1, %0|%0, %1}"
12290 [(set_attr "type" "alu1")
12291 (set_attr "prefix_0f" "1")
12292 (set_attr "mode" "DI")])
12295 [(set (match_operand:SI 0 "register_operand" "=r")
12296 (minus:SI (const_int 31)
12297 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12298 (clobber (reg:CC FLAGS_REG))]
12300 "bsr{l}\t{%1, %0|%0, %1}"
12301 [(set_attr "type" "alu1")
12302 (set_attr "prefix_0f" "1")
12303 (set_attr "mode" "SI")])
12305 (define_insn "*bsrhi"
12306 [(set (match_operand:HI 0 "register_operand" "=r")
12307 (minus:HI (const_int 15)
12308 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12309 (clobber (reg:CC FLAGS_REG))]
12311 "bsr{w}\t{%1, %0|%0, %1}"
12312 [(set_attr "type" "alu1")
12313 (set_attr "prefix_0f" "1")
12314 (set_attr "mode" "HI")])
12316 (define_insn "popcount<mode>2"
12317 [(set (match_operand:SWI248 0 "register_operand" "=r")
12319 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12320 (clobber (reg:CC FLAGS_REG))]
12324 return "popcnt\t{%1, %0|%0, %1}";
12326 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12329 [(set_attr "prefix_rep" "1")
12330 (set_attr "type" "bitmanip")
12331 (set_attr "mode" "<MODE>")])
12333 (define_insn "*popcount<mode>2_cmp"
12334 [(set (reg FLAGS_REG)
12337 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12339 (set (match_operand:SWI248 0 "register_operand" "=r")
12340 (popcount:SWI248 (match_dup 1)))]
12341 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12344 return "popcnt\t{%1, %0|%0, %1}";
12346 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12349 [(set_attr "prefix_rep" "1")
12350 (set_attr "type" "bitmanip")
12351 (set_attr "mode" "<MODE>")])
12353 (define_insn "*popcountsi2_cmp_zext"
12354 [(set (reg FLAGS_REG)
12356 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12358 (set (match_operand:DI 0 "register_operand" "=r")
12359 (zero_extend:DI(popcount:SI (match_dup 1))))]
12360 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12363 return "popcnt\t{%1, %0|%0, %1}";
12365 return "popcnt{l}\t{%1, %0|%0, %1}";
12368 [(set_attr "prefix_rep" "1")
12369 (set_attr "type" "bitmanip")
12370 (set_attr "mode" "SI")])
12372 (define_expand "bswap<mode>2"
12373 [(set (match_operand:SWI48 0 "register_operand" "")
12374 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12377 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12379 rtx x = operands[0];
12381 emit_move_insn (x, operands[1]);
12382 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12383 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12384 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12389 (define_insn "*bswap<mode>2_movbe"
12390 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12391 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12393 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12396 movbe\t{%1, %0|%0, %1}
12397 movbe\t{%1, %0|%0, %1}"
12398 [(set_attr "type" "bitmanip,imov,imov")
12399 (set_attr "modrm" "0,1,1")
12400 (set_attr "prefix_0f" "*,1,1")
12401 (set_attr "prefix_extra" "*,1,1")
12402 (set_attr "mode" "<MODE>")])
12404 (define_insn "*bswap<mode>2_1"
12405 [(set (match_operand:SWI48 0 "register_operand" "=r")
12406 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12409 [(set_attr "type" "bitmanip")
12410 (set_attr "modrm" "0")
12411 (set_attr "mode" "<MODE>")])
12413 (define_insn "*bswaphi_lowpart_1"
12414 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12415 (bswap:HI (match_dup 0)))
12416 (clobber (reg:CC FLAGS_REG))]
12417 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12419 xchg{b}\t{%h0, %b0|%b0, %h0}
12420 rol{w}\t{$8, %0|%0, 8}"
12421 [(set_attr "length" "2,4")
12422 (set_attr "mode" "QI,HI")])
12424 (define_insn "bswaphi_lowpart"
12425 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12426 (bswap:HI (match_dup 0)))
12427 (clobber (reg:CC FLAGS_REG))]
12429 "rol{w}\t{$8, %0|%0, 8}"
12430 [(set_attr "length" "4")
12431 (set_attr "mode" "HI")])
12433 (define_expand "paritydi2"
12434 [(set (match_operand:DI 0 "register_operand" "")
12435 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12438 rtx scratch = gen_reg_rtx (QImode);
12441 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12442 NULL_RTX, operands[1]));
12444 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12445 gen_rtx_REG (CCmode, FLAGS_REG),
12447 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12450 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12453 rtx tmp = gen_reg_rtx (SImode);
12455 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12456 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12461 (define_expand "paritysi2"
12462 [(set (match_operand:SI 0 "register_operand" "")
12463 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12466 rtx scratch = gen_reg_rtx (QImode);
12469 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12471 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12472 gen_rtx_REG (CCmode, FLAGS_REG),
12474 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12476 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12480 (define_insn_and_split "paritydi2_cmp"
12481 [(set (reg:CC FLAGS_REG)
12482 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12484 (clobber (match_scratch:DI 0 "=r"))
12485 (clobber (match_scratch:SI 1 "=&r"))
12486 (clobber (match_scratch:HI 2 "=Q"))]
12489 "&& reload_completed"
12491 [(set (match_dup 1)
12492 (xor:SI (match_dup 1) (match_dup 4)))
12493 (clobber (reg:CC FLAGS_REG))])
12495 [(set (reg:CC FLAGS_REG)
12496 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12497 (clobber (match_dup 1))
12498 (clobber (match_dup 2))])]
12500 operands[4] = gen_lowpart (SImode, operands[3]);
12504 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12505 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12508 operands[1] = gen_highpart (SImode, operands[3]);
12511 (define_insn_and_split "paritysi2_cmp"
12512 [(set (reg:CC FLAGS_REG)
12513 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12515 (clobber (match_scratch:SI 0 "=r"))
12516 (clobber (match_scratch:HI 1 "=&Q"))]
12519 "&& reload_completed"
12521 [(set (match_dup 1)
12522 (xor:HI (match_dup 1) (match_dup 3)))
12523 (clobber (reg:CC FLAGS_REG))])
12525 [(set (reg:CC FLAGS_REG)
12526 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12527 (clobber (match_dup 1))])]
12529 operands[3] = gen_lowpart (HImode, operands[2]);
12531 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12532 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12535 (define_insn "*parityhi2_cmp"
12536 [(set (reg:CC FLAGS_REG)
12537 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12539 (clobber (match_scratch:HI 0 "=Q"))]
12541 "xor{b}\t{%h0, %b0|%b0, %h0}"
12542 [(set_attr "length" "2")
12543 (set_attr "mode" "HI")])
12546 ;; Thread-local storage patterns for ELF.
12548 ;; Note that these code sequences must appear exactly as shown
12549 ;; in order to allow linker relaxation.
12551 (define_insn "*tls_global_dynamic_32_gnu"
12552 [(set (match_operand:SI 0 "register_operand" "=a")
12554 [(match_operand:SI 1 "register_operand" "b")
12555 (match_operand:SI 2 "tls_symbolic_operand" "")
12556 (match_operand:SI 3 "constant_call_address_operand" "z")]
12558 (clobber (match_scratch:SI 4 "=d"))
12559 (clobber (match_scratch:SI 5 "=c"))
12560 (clobber (reg:CC FLAGS_REG))]
12561 "!TARGET_64BIT && TARGET_GNU_TLS"
12564 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12565 if (TARGET_SUN_TLS)
12566 #ifdef HAVE_AS_IX86_TLSGDPLT
12567 return "call\t%a2@tlsgdplt";
12569 return "call\t%p3@plt";
12571 return "call\t%P3";
12573 [(set_attr "type" "multi")
12574 (set_attr "length" "12")])
12576 (define_expand "tls_global_dynamic_32"
12578 [(set (match_operand:SI 0 "register_operand" "")
12579 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12580 (match_operand:SI 1 "tls_symbolic_operand" "")
12581 (match_operand:SI 3 "constant_call_address_operand" "")]
12583 (clobber (match_scratch:SI 4 ""))
12584 (clobber (match_scratch:SI 5 ""))
12585 (clobber (reg:CC FLAGS_REG))])])
12587 (define_insn "*tls_global_dynamic_64"
12588 [(set (match_operand:DI 0 "register_operand" "=a")
12590 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12591 (match_operand:DI 3 "" "")))
12592 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12597 fputs (ASM_BYTE "0x66\n", asm_out_file);
12599 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12600 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12601 fputs ("\trex64\n", asm_out_file);
12602 if (TARGET_SUN_TLS)
12603 return "call\t%p2@plt";
12604 return "call\t%P2";
12606 [(set_attr "type" "multi")
12607 (set (attr "length")
12608 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12610 (define_expand "tls_global_dynamic_64"
12612 [(set (match_operand:DI 0 "register_operand" "")
12614 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12616 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12619 (define_insn "*tls_local_dynamic_base_32_gnu"
12620 [(set (match_operand:SI 0 "register_operand" "=a")
12622 [(match_operand:SI 1 "register_operand" "b")
12623 (match_operand:SI 2 "constant_call_address_operand" "z")]
12624 UNSPEC_TLS_LD_BASE))
12625 (clobber (match_scratch:SI 3 "=d"))
12626 (clobber (match_scratch:SI 4 "=c"))
12627 (clobber (reg:CC FLAGS_REG))]
12628 "!TARGET_64BIT && TARGET_GNU_TLS"
12631 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12632 if (TARGET_SUN_TLS)
12633 #ifdef HAVE_AS_IX86_TLSLDMPLT
12634 return "call\t%&@tlsldmplt";
12636 return "call\t%p2@plt";
12638 return "call\t%P2";
12640 [(set_attr "type" "multi")
12641 (set_attr "length" "11")])
12643 (define_expand "tls_local_dynamic_base_32"
12645 [(set (match_operand:SI 0 "register_operand" "")
12647 [(match_operand:SI 1 "register_operand" "")
12648 (match_operand:SI 2 "constant_call_address_operand" "")]
12649 UNSPEC_TLS_LD_BASE))
12650 (clobber (match_scratch:SI 3 ""))
12651 (clobber (match_scratch:SI 4 ""))
12652 (clobber (reg:CC FLAGS_REG))])])
12654 (define_insn "*tls_local_dynamic_base_64"
12655 [(set (match_operand:DI 0 "register_operand" "=a")
12657 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12658 (match_operand:DI 2 "" "")))
12659 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12663 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12664 if (TARGET_SUN_TLS)
12665 return "call\t%p1@plt";
12666 return "call\t%P1";
12668 [(set_attr "type" "multi")
12669 (set_attr "length" "12")])
12671 (define_expand "tls_local_dynamic_base_64"
12673 [(set (match_operand:DI 0 "register_operand" "")
12675 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12677 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12679 ;; Local dynamic of a single variable is a lose. Show combine how
12680 ;; to convert that back to global dynamic.
12682 (define_insn_and_split "*tls_local_dynamic_32_once"
12683 [(set (match_operand:SI 0 "register_operand" "=a")
12685 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12686 (match_operand:SI 2 "constant_call_address_operand" "z")]
12687 UNSPEC_TLS_LD_BASE)
12688 (const:SI (unspec:SI
12689 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12691 (clobber (match_scratch:SI 4 "=d"))
12692 (clobber (match_scratch:SI 5 "=c"))
12693 (clobber (reg:CC FLAGS_REG))]
12698 [(set (match_dup 0)
12699 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12701 (clobber (match_dup 4))
12702 (clobber (match_dup 5))
12703 (clobber (reg:CC FLAGS_REG))])])
12705 ;; Segment register for the thread base ptr load
12706 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12708 ;; Load and add the thread base pointer from %<tp_seg>:0.
12709 (define_insn "*load_tp_x32"
12710 [(set (match_operand:SI 0 "register_operand" "=r")
12711 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12713 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12714 [(set_attr "type" "imov")
12715 (set_attr "modrm" "0")
12716 (set_attr "length" "7")
12717 (set_attr "memory" "load")
12718 (set_attr "imm_disp" "false")])
12720 (define_insn "*load_tp_x32_zext"
12721 [(set (match_operand:DI 0 "register_operand" "=r")
12722 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12724 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12725 [(set_attr "type" "imov")
12726 (set_attr "modrm" "0")
12727 (set_attr "length" "7")
12728 (set_attr "memory" "load")
12729 (set_attr "imm_disp" "false")])
12731 (define_insn "*load_tp_<mode>"
12732 [(set (match_operand:P 0 "register_operand" "=r")
12733 (unspec:P [(const_int 0)] UNSPEC_TP))]
12735 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12736 [(set_attr "type" "imov")
12737 (set_attr "modrm" "0")
12738 (set_attr "length" "7")
12739 (set_attr "memory" "load")
12740 (set_attr "imm_disp" "false")])
12742 (define_insn "*add_tp_x32"
12743 [(set (match_operand:SI 0 "register_operand" "=r")
12744 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12745 (match_operand:SI 1 "register_operand" "0")))
12746 (clobber (reg:CC FLAGS_REG))]
12748 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12749 [(set_attr "type" "alu")
12750 (set_attr "modrm" "0")
12751 (set_attr "length" "7")
12752 (set_attr "memory" "load")
12753 (set_attr "imm_disp" "false")])
12755 (define_insn "*add_tp_x32_zext"
12756 [(set (match_operand:DI 0 "register_operand" "=r")
12758 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12759 (match_operand:SI 1 "register_operand" "0"))))
12760 (clobber (reg:CC FLAGS_REG))]
12762 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12763 [(set_attr "type" "alu")
12764 (set_attr "modrm" "0")
12765 (set_attr "length" "7")
12766 (set_attr "memory" "load")
12767 (set_attr "imm_disp" "false")])
12769 (define_insn "*add_tp_<mode>"
12770 [(set (match_operand:P 0 "register_operand" "=r")
12771 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12772 (match_operand:P 1 "register_operand" "0")))
12773 (clobber (reg:CC FLAGS_REG))]
12775 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12776 [(set_attr "type" "alu")
12777 (set_attr "modrm" "0")
12778 (set_attr "length" "7")
12779 (set_attr "memory" "load")
12780 (set_attr "imm_disp" "false")])
12782 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12783 ;; %rax as destination of the initial executable code sequence.
12784 (define_insn "tls_initial_exec_64_sun"
12785 [(set (match_operand:DI 0 "register_operand" "=a")
12787 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12788 UNSPEC_TLS_IE_SUN))
12789 (clobber (reg:CC FLAGS_REG))]
12790 "TARGET_64BIT && TARGET_SUN_TLS"
12793 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12794 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12796 [(set_attr "type" "multi")])
12798 ;; GNU2 TLS patterns can be split.
12800 (define_expand "tls_dynamic_gnu2_32"
12801 [(set (match_dup 3)
12802 (plus:SI (match_operand:SI 2 "register_operand" "")
12804 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12807 [(set (match_operand:SI 0 "register_operand" "")
12808 (unspec:SI [(match_dup 1) (match_dup 3)
12809 (match_dup 2) (reg:SI SP_REG)]
12811 (clobber (reg:CC FLAGS_REG))])]
12812 "!TARGET_64BIT && TARGET_GNU2_TLS"
12814 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12815 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12818 (define_insn "*tls_dynamic_gnu2_lea_32"
12819 [(set (match_operand:SI 0 "register_operand" "=r")
12820 (plus:SI (match_operand:SI 1 "register_operand" "b")
12822 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12823 UNSPEC_TLSDESC))))]
12824 "!TARGET_64BIT && TARGET_GNU2_TLS"
12825 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12826 [(set_attr "type" "lea")
12827 (set_attr "mode" "SI")
12828 (set_attr "length" "6")
12829 (set_attr "length_address" "4")])
12831 (define_insn "*tls_dynamic_gnu2_call_32"
12832 [(set (match_operand:SI 0 "register_operand" "=a")
12833 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12834 (match_operand:SI 2 "register_operand" "0")
12835 ;; we have to make sure %ebx still points to the GOT
12836 (match_operand:SI 3 "register_operand" "b")
12839 (clobber (reg:CC FLAGS_REG))]
12840 "!TARGET_64BIT && TARGET_GNU2_TLS"
12841 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12842 [(set_attr "type" "call")
12843 (set_attr "length" "2")
12844 (set_attr "length_address" "0")])
12846 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12847 [(set (match_operand:SI 0 "register_operand" "=&a")
12849 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12850 (match_operand:SI 4 "" "")
12851 (match_operand:SI 2 "register_operand" "b")
12854 (const:SI (unspec:SI
12855 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12857 (clobber (reg:CC FLAGS_REG))]
12858 "!TARGET_64BIT && TARGET_GNU2_TLS"
12861 [(set (match_dup 0) (match_dup 5))]
12863 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12864 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12867 (define_expand "tls_dynamic_gnu2_64"
12868 [(set (match_dup 2)
12869 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12872 [(set (match_operand:DI 0 "register_operand" "")
12873 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12875 (clobber (reg:CC FLAGS_REG))])]
12876 "TARGET_64BIT && TARGET_GNU2_TLS"
12878 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12879 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12882 (define_insn "*tls_dynamic_gnu2_lea_64"
12883 [(set (match_operand:DI 0 "register_operand" "=r")
12884 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12886 "TARGET_64BIT && TARGET_GNU2_TLS"
12887 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12888 [(set_attr "type" "lea")
12889 (set_attr "mode" "DI")
12890 (set_attr "length" "7")
12891 (set_attr "length_address" "4")])
12893 (define_insn "*tls_dynamic_gnu2_call_64"
12894 [(set (match_operand:DI 0 "register_operand" "=a")
12895 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12896 (match_operand:DI 2 "register_operand" "0")
12899 (clobber (reg:CC FLAGS_REG))]
12900 "TARGET_64BIT && TARGET_GNU2_TLS"
12901 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12902 [(set_attr "type" "call")
12903 (set_attr "length" "2")
12904 (set_attr "length_address" "0")])
12906 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12907 [(set (match_operand:DI 0 "register_operand" "=&a")
12909 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12910 (match_operand:DI 3 "" "")
12913 (const:DI (unspec:DI
12914 [(match_operand 1 "tls_symbolic_operand" "")]
12916 (clobber (reg:CC FLAGS_REG))]
12917 "TARGET_64BIT && TARGET_GNU2_TLS"
12920 [(set (match_dup 0) (match_dup 4))]
12922 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12923 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12926 ;; These patterns match the binary 387 instructions for addM3, subM3,
12927 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12928 ;; SFmode. The first is the normal insn, the second the same insn but
12929 ;; with one operand a conversion, and the third the same insn but with
12930 ;; the other operand a conversion. The conversion may be SFmode or
12931 ;; SImode if the target mode DFmode, but only SImode if the target mode
12934 ;; Gcc is slightly more smart about handling normal two address instructions
12935 ;; so use special patterns for add and mull.
12937 (define_insn "*fop_<mode>_comm_mixed"
12938 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12939 (match_operator:MODEF 3 "binary_fp_operator"
12940 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12941 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12942 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12943 && COMMUTATIVE_ARITH_P (operands[3])
12944 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12945 "* return output_387_binary_op (insn, operands);"
12946 [(set (attr "type")
12947 (if_then_else (eq_attr "alternative" "1,2")
12948 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12949 (const_string "ssemul")
12950 (const_string "sseadd"))
12951 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12952 (const_string "fmul")
12953 (const_string "fop"))))
12954 (set_attr "isa" "*,noavx,avx")
12955 (set_attr "prefix" "orig,orig,vex")
12956 (set_attr "mode" "<MODE>")])
12958 (define_insn "*fop_<mode>_comm_sse"
12959 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12960 (match_operator:MODEF 3 "binary_fp_operator"
12961 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
12962 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
12963 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
12964 && COMMUTATIVE_ARITH_P (operands[3])
12965 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12966 "* return output_387_binary_op (insn, operands);"
12967 [(set (attr "type")
12968 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12969 (const_string "ssemul")
12970 (const_string "sseadd")))
12971 (set_attr "isa" "noavx,avx")
12972 (set_attr "prefix" "orig,vex")
12973 (set_attr "mode" "<MODE>")])
12975 (define_insn "*fop_<mode>_comm_i387"
12976 [(set (match_operand:MODEF 0 "register_operand" "=f")
12977 (match_operator:MODEF 3 "binary_fp_operator"
12978 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
12979 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
12980 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
12981 && COMMUTATIVE_ARITH_P (operands[3])
12982 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12983 "* return output_387_binary_op (insn, operands);"
12984 [(set (attr "type")
12985 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12986 (const_string "fmul")
12987 (const_string "fop")))
12988 (set_attr "mode" "<MODE>")])
12990 (define_insn "*fop_<mode>_1_mixed"
12991 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
12992 (match_operator:MODEF 3 "binary_fp_operator"
12993 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
12994 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
12995 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
12996 && !COMMUTATIVE_ARITH_P (operands[3])
12997 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
12998 "* return output_387_binary_op (insn, operands);"
12999 [(set (attr "type")
13000 (cond [(and (eq_attr "alternative" "2,3")
13001 (match_operand:MODEF 3 "mult_operator" ""))
13002 (const_string "ssemul")
13003 (and (eq_attr "alternative" "2,3")
13004 (match_operand:MODEF 3 "div_operator" ""))
13005 (const_string "ssediv")
13006 (eq_attr "alternative" "2,3")
13007 (const_string "sseadd")
13008 (match_operand:MODEF 3 "mult_operator" "")
13009 (const_string "fmul")
13010 (match_operand:MODEF 3 "div_operator" "")
13011 (const_string "fdiv")
13013 (const_string "fop")))
13014 (set_attr "isa" "*,*,noavx,avx")
13015 (set_attr "prefix" "orig,orig,orig,vex")
13016 (set_attr "mode" "<MODE>")])
13018 (define_insn "*rcpsf2_sse"
13019 [(set (match_operand:SF 0 "register_operand" "=x")
13020 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13023 "%vrcpss\t{%1, %d0|%d0, %1}"
13024 [(set_attr "type" "sse")
13025 (set_attr "atom_sse_attr" "rcp")
13026 (set_attr "prefix" "maybe_vex")
13027 (set_attr "mode" "SF")])
13029 (define_insn "*fop_<mode>_1_sse"
13030 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13031 (match_operator:MODEF 3 "binary_fp_operator"
13032 [(match_operand:MODEF 1 "register_operand" "0,x")
13033 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13034 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13035 && !COMMUTATIVE_ARITH_P (operands[3])"
13036 "* return output_387_binary_op (insn, operands);"
13037 [(set (attr "type")
13038 (cond [(match_operand:MODEF 3 "mult_operator" "")
13039 (const_string "ssemul")
13040 (match_operand:MODEF 3 "div_operator" "")
13041 (const_string "ssediv")
13043 (const_string "sseadd")))
13044 (set_attr "isa" "noavx,avx")
13045 (set_attr "prefix" "orig,vex")
13046 (set_attr "mode" "<MODE>")])
13048 ;; This pattern is not fully shadowed by the pattern above.
13049 (define_insn "*fop_<mode>_1_i387"
13050 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13051 (match_operator:MODEF 3 "binary_fp_operator"
13052 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13053 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13054 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13055 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13056 && !COMMUTATIVE_ARITH_P (operands[3])
13057 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13058 "* return output_387_binary_op (insn, operands);"
13059 [(set (attr "type")
13060 (cond [(match_operand:MODEF 3 "mult_operator" "")
13061 (const_string "fmul")
13062 (match_operand:MODEF 3 "div_operator" "")
13063 (const_string "fdiv")
13065 (const_string "fop")))
13066 (set_attr "mode" "<MODE>")])
13068 ;; ??? Add SSE splitters for these!
13069 (define_insn "*fop_<MODEF:mode>_2_i387"
13070 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13071 (match_operator:MODEF 3 "binary_fp_operator"
13073 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13074 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13075 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13076 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13077 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13078 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13079 [(set (attr "type")
13080 (cond [(match_operand:MODEF 3 "mult_operator" "")
13081 (const_string "fmul")
13082 (match_operand:MODEF 3 "div_operator" "")
13083 (const_string "fdiv")
13085 (const_string "fop")))
13086 (set_attr "fp_int_src" "true")
13087 (set_attr "mode" "<SWI24:MODE>")])
13089 (define_insn "*fop_<MODEF:mode>_3_i387"
13090 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13091 (match_operator:MODEF 3 "binary_fp_operator"
13092 [(match_operand:MODEF 1 "register_operand" "0,0")
13094 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13095 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13096 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13097 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13098 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13099 [(set (attr "type")
13100 (cond [(match_operand:MODEF 3 "mult_operator" "")
13101 (const_string "fmul")
13102 (match_operand:MODEF 3 "div_operator" "")
13103 (const_string "fdiv")
13105 (const_string "fop")))
13106 (set_attr "fp_int_src" "true")
13107 (set_attr "mode" "<MODE>")])
13109 (define_insn "*fop_df_4_i387"
13110 [(set (match_operand:DF 0 "register_operand" "=f,f")
13111 (match_operator:DF 3 "binary_fp_operator"
13113 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13114 (match_operand:DF 2 "register_operand" "0,f")]))]
13115 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13116 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13117 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13118 "* return output_387_binary_op (insn, operands);"
13119 [(set (attr "type")
13120 (cond [(match_operand:DF 3 "mult_operator" "")
13121 (const_string "fmul")
13122 (match_operand:DF 3 "div_operator" "")
13123 (const_string "fdiv")
13125 (const_string "fop")))
13126 (set_attr "mode" "SF")])
13128 (define_insn "*fop_df_5_i387"
13129 [(set (match_operand:DF 0 "register_operand" "=f,f")
13130 (match_operator:DF 3 "binary_fp_operator"
13131 [(match_operand:DF 1 "register_operand" "0,f")
13133 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13134 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13135 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13136 "* return output_387_binary_op (insn, operands);"
13137 [(set (attr "type")
13138 (cond [(match_operand:DF 3 "mult_operator" "")
13139 (const_string "fmul")
13140 (match_operand:DF 3 "div_operator" "")
13141 (const_string "fdiv")
13143 (const_string "fop")))
13144 (set_attr "mode" "SF")])
13146 (define_insn "*fop_df_6_i387"
13147 [(set (match_operand:DF 0 "register_operand" "=f,f")
13148 (match_operator:DF 3 "binary_fp_operator"
13150 (match_operand:SF 1 "register_operand" "0,f"))
13152 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13153 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13154 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13155 "* return output_387_binary_op (insn, operands);"
13156 [(set (attr "type")
13157 (cond [(match_operand:DF 3 "mult_operator" "")
13158 (const_string "fmul")
13159 (match_operand:DF 3 "div_operator" "")
13160 (const_string "fdiv")
13162 (const_string "fop")))
13163 (set_attr "mode" "SF")])
13165 (define_insn "*fop_xf_comm_i387"
13166 [(set (match_operand:XF 0 "register_operand" "=f")
13167 (match_operator:XF 3 "binary_fp_operator"
13168 [(match_operand:XF 1 "register_operand" "%0")
13169 (match_operand:XF 2 "register_operand" "f")]))]
13171 && COMMUTATIVE_ARITH_P (operands[3])"
13172 "* return output_387_binary_op (insn, operands);"
13173 [(set (attr "type")
13174 (if_then_else (match_operand:XF 3 "mult_operator" "")
13175 (const_string "fmul")
13176 (const_string "fop")))
13177 (set_attr "mode" "XF")])
13179 (define_insn "*fop_xf_1_i387"
13180 [(set (match_operand:XF 0 "register_operand" "=f,f")
13181 (match_operator:XF 3 "binary_fp_operator"
13182 [(match_operand:XF 1 "register_operand" "0,f")
13183 (match_operand:XF 2 "register_operand" "f,0")]))]
13185 && !COMMUTATIVE_ARITH_P (operands[3])"
13186 "* return output_387_binary_op (insn, operands);"
13187 [(set (attr "type")
13188 (cond [(match_operand:XF 3 "mult_operator" "")
13189 (const_string "fmul")
13190 (match_operand:XF 3 "div_operator" "")
13191 (const_string "fdiv")
13193 (const_string "fop")))
13194 (set_attr "mode" "XF")])
13196 (define_insn "*fop_xf_2_i387"
13197 [(set (match_operand:XF 0 "register_operand" "=f,f")
13198 (match_operator:XF 3 "binary_fp_operator"
13200 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13201 (match_operand:XF 2 "register_operand" "0,0")]))]
13202 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13203 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13204 [(set (attr "type")
13205 (cond [(match_operand:XF 3 "mult_operator" "")
13206 (const_string "fmul")
13207 (match_operand:XF 3 "div_operator" "")
13208 (const_string "fdiv")
13210 (const_string "fop")))
13211 (set_attr "fp_int_src" "true")
13212 (set_attr "mode" "<MODE>")])
13214 (define_insn "*fop_xf_3_i387"
13215 [(set (match_operand:XF 0 "register_operand" "=f,f")
13216 (match_operator:XF 3 "binary_fp_operator"
13217 [(match_operand:XF 1 "register_operand" "0,0")
13219 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13220 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13221 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13222 [(set (attr "type")
13223 (cond [(match_operand:XF 3 "mult_operator" "")
13224 (const_string "fmul")
13225 (match_operand:XF 3 "div_operator" "")
13226 (const_string "fdiv")
13228 (const_string "fop")))
13229 (set_attr "fp_int_src" "true")
13230 (set_attr "mode" "<MODE>")])
13232 (define_insn "*fop_xf_4_i387"
13233 [(set (match_operand:XF 0 "register_operand" "=f,f")
13234 (match_operator:XF 3 "binary_fp_operator"
13236 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13237 (match_operand:XF 2 "register_operand" "0,f")]))]
13239 "* return output_387_binary_op (insn, operands);"
13240 [(set (attr "type")
13241 (cond [(match_operand:XF 3 "mult_operator" "")
13242 (const_string "fmul")
13243 (match_operand:XF 3 "div_operator" "")
13244 (const_string "fdiv")
13246 (const_string "fop")))
13247 (set_attr "mode" "<MODE>")])
13249 (define_insn "*fop_xf_5_i387"
13250 [(set (match_operand:XF 0 "register_operand" "=f,f")
13251 (match_operator:XF 3 "binary_fp_operator"
13252 [(match_operand:XF 1 "register_operand" "0,f")
13254 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13256 "* return output_387_binary_op (insn, operands);"
13257 [(set (attr "type")
13258 (cond [(match_operand:XF 3 "mult_operator" "")
13259 (const_string "fmul")
13260 (match_operand:XF 3 "div_operator" "")
13261 (const_string "fdiv")
13263 (const_string "fop")))
13264 (set_attr "mode" "<MODE>")])
13266 (define_insn "*fop_xf_6_i387"
13267 [(set (match_operand:XF 0 "register_operand" "=f,f")
13268 (match_operator:XF 3 "binary_fp_operator"
13270 (match_operand:MODEF 1 "register_operand" "0,f"))
13272 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13274 "* return output_387_binary_op (insn, operands);"
13275 [(set (attr "type")
13276 (cond [(match_operand:XF 3 "mult_operator" "")
13277 (const_string "fmul")
13278 (match_operand:XF 3 "div_operator" "")
13279 (const_string "fdiv")
13281 (const_string "fop")))
13282 (set_attr "mode" "<MODE>")])
13285 [(set (match_operand 0 "register_operand" "")
13286 (match_operator 3 "binary_fp_operator"
13287 [(float (match_operand:SWI24 1 "register_operand" ""))
13288 (match_operand 2 "register_operand" "")]))]
13290 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13291 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13294 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13295 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13296 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13297 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13298 GET_MODE (operands[3]),
13301 ix86_free_from_memory (GET_MODE (operands[1]));
13306 [(set (match_operand 0 "register_operand" "")
13307 (match_operator 3 "binary_fp_operator"
13308 [(match_operand 1 "register_operand" "")
13309 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13311 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13312 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13315 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13316 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13317 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13318 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13319 GET_MODE (operands[3]),
13322 ix86_free_from_memory (GET_MODE (operands[2]));
13326 ;; FPU special functions.
13328 ;; This pattern implements a no-op XFmode truncation for
13329 ;; all fancy i386 XFmode math functions.
13331 (define_insn "truncxf<mode>2_i387_noop_unspec"
13332 [(set (match_operand:MODEF 0 "register_operand" "=f")
13333 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13334 UNSPEC_TRUNC_NOOP))]
13335 "TARGET_USE_FANCY_MATH_387"
13336 "* return output_387_reg_move (insn, operands);"
13337 [(set_attr "type" "fmov")
13338 (set_attr "mode" "<MODE>")])
13340 (define_insn "sqrtxf2"
13341 [(set (match_operand:XF 0 "register_operand" "=f")
13342 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13343 "TARGET_USE_FANCY_MATH_387"
13345 [(set_attr "type" "fpspc")
13346 (set_attr "mode" "XF")
13347 (set_attr "athlon_decode" "direct")
13348 (set_attr "amdfam10_decode" "direct")
13349 (set_attr "bdver1_decode" "direct")])
13351 (define_insn "sqrt_extend<mode>xf2_i387"
13352 [(set (match_operand:XF 0 "register_operand" "=f")
13355 (match_operand:MODEF 1 "register_operand" "0"))))]
13356 "TARGET_USE_FANCY_MATH_387"
13358 [(set_attr "type" "fpspc")
13359 (set_attr "mode" "XF")
13360 (set_attr "athlon_decode" "direct")
13361 (set_attr "amdfam10_decode" "direct")
13362 (set_attr "bdver1_decode" "direct")])
13364 (define_insn "*rsqrtsf2_sse"
13365 [(set (match_operand:SF 0 "register_operand" "=x")
13366 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13369 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13370 [(set_attr "type" "sse")
13371 (set_attr "atom_sse_attr" "rcp")
13372 (set_attr "prefix" "maybe_vex")
13373 (set_attr "mode" "SF")])
13375 (define_expand "rsqrtsf2"
13376 [(set (match_operand:SF 0 "register_operand" "")
13377 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13381 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13385 (define_insn "*sqrt<mode>2_sse"
13386 [(set (match_operand:MODEF 0 "register_operand" "=x")
13388 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13389 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13390 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13391 [(set_attr "type" "sse")
13392 (set_attr "atom_sse_attr" "sqrt")
13393 (set_attr "prefix" "maybe_vex")
13394 (set_attr "mode" "<MODE>")
13395 (set_attr "athlon_decode" "*")
13396 (set_attr "amdfam10_decode" "*")
13397 (set_attr "bdver1_decode" "*")])
13399 (define_expand "sqrt<mode>2"
13400 [(set (match_operand:MODEF 0 "register_operand" "")
13402 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13403 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13404 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13406 if (<MODE>mode == SFmode
13408 && TARGET_RECIP_SQRT
13409 && !optimize_function_for_size_p (cfun)
13410 && flag_finite_math_only && !flag_trapping_math
13411 && flag_unsafe_math_optimizations)
13413 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13417 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13419 rtx op0 = gen_reg_rtx (XFmode);
13420 rtx op1 = force_reg (<MODE>mode, operands[1]);
13422 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13423 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13428 (define_insn "fpremxf4_i387"
13429 [(set (match_operand:XF 0 "register_operand" "=f")
13430 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13431 (match_operand:XF 3 "register_operand" "1")]
13433 (set (match_operand:XF 1 "register_operand" "=u")
13434 (unspec:XF [(match_dup 2) (match_dup 3)]
13436 (set (reg:CCFP FPSR_REG)
13437 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13439 "TARGET_USE_FANCY_MATH_387"
13441 [(set_attr "type" "fpspc")
13442 (set_attr "mode" "XF")])
13444 (define_expand "fmodxf3"
13445 [(use (match_operand:XF 0 "register_operand" ""))
13446 (use (match_operand:XF 1 "general_operand" ""))
13447 (use (match_operand:XF 2 "general_operand" ""))]
13448 "TARGET_USE_FANCY_MATH_387"
13450 rtx label = gen_label_rtx ();
13452 rtx op1 = gen_reg_rtx (XFmode);
13453 rtx op2 = gen_reg_rtx (XFmode);
13455 emit_move_insn (op2, operands[2]);
13456 emit_move_insn (op1, operands[1]);
13458 emit_label (label);
13459 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13460 ix86_emit_fp_unordered_jump (label);
13461 LABEL_NUSES (label) = 1;
13463 emit_move_insn (operands[0], op1);
13467 (define_expand "fmod<mode>3"
13468 [(use (match_operand:MODEF 0 "register_operand" ""))
13469 (use (match_operand:MODEF 1 "general_operand" ""))
13470 (use (match_operand:MODEF 2 "general_operand" ""))]
13471 "TARGET_USE_FANCY_MATH_387"
13473 rtx (*gen_truncxf) (rtx, rtx);
13475 rtx label = gen_label_rtx ();
13477 rtx op1 = gen_reg_rtx (XFmode);
13478 rtx op2 = gen_reg_rtx (XFmode);
13480 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13481 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13483 emit_label (label);
13484 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13485 ix86_emit_fp_unordered_jump (label);
13486 LABEL_NUSES (label) = 1;
13488 /* Truncate the result properly for strict SSE math. */
13489 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13490 && !TARGET_MIX_SSE_I387)
13491 gen_truncxf = gen_truncxf<mode>2;
13493 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13495 emit_insn (gen_truncxf (operands[0], op1));
13499 (define_insn "fprem1xf4_i387"
13500 [(set (match_operand:XF 0 "register_operand" "=f")
13501 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13502 (match_operand:XF 3 "register_operand" "1")]
13504 (set (match_operand:XF 1 "register_operand" "=u")
13505 (unspec:XF [(match_dup 2) (match_dup 3)]
13507 (set (reg:CCFP FPSR_REG)
13508 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13510 "TARGET_USE_FANCY_MATH_387"
13512 [(set_attr "type" "fpspc")
13513 (set_attr "mode" "XF")])
13515 (define_expand "remainderxf3"
13516 [(use (match_operand:XF 0 "register_operand" ""))
13517 (use (match_operand:XF 1 "general_operand" ""))
13518 (use (match_operand:XF 2 "general_operand" ""))]
13519 "TARGET_USE_FANCY_MATH_387"
13521 rtx label = gen_label_rtx ();
13523 rtx op1 = gen_reg_rtx (XFmode);
13524 rtx op2 = gen_reg_rtx (XFmode);
13526 emit_move_insn (op2, operands[2]);
13527 emit_move_insn (op1, operands[1]);
13529 emit_label (label);
13530 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13531 ix86_emit_fp_unordered_jump (label);
13532 LABEL_NUSES (label) = 1;
13534 emit_move_insn (operands[0], op1);
13538 (define_expand "remainder<mode>3"
13539 [(use (match_operand:MODEF 0 "register_operand" ""))
13540 (use (match_operand:MODEF 1 "general_operand" ""))
13541 (use (match_operand:MODEF 2 "general_operand" ""))]
13542 "TARGET_USE_FANCY_MATH_387"
13544 rtx (*gen_truncxf) (rtx, rtx);
13546 rtx label = gen_label_rtx ();
13548 rtx op1 = gen_reg_rtx (XFmode);
13549 rtx op2 = gen_reg_rtx (XFmode);
13551 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13552 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13554 emit_label (label);
13556 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13557 ix86_emit_fp_unordered_jump (label);
13558 LABEL_NUSES (label) = 1;
13560 /* Truncate the result properly for strict SSE math. */
13561 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13562 && !TARGET_MIX_SSE_I387)
13563 gen_truncxf = gen_truncxf<mode>2;
13565 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13567 emit_insn (gen_truncxf (operands[0], op1));
13571 (define_insn "*sinxf2_i387"
13572 [(set (match_operand:XF 0 "register_operand" "=f")
13573 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13574 "TARGET_USE_FANCY_MATH_387
13575 && flag_unsafe_math_optimizations"
13577 [(set_attr "type" "fpspc")
13578 (set_attr "mode" "XF")])
13580 (define_insn "*sin_extend<mode>xf2_i387"
13581 [(set (match_operand:XF 0 "register_operand" "=f")
13582 (unspec:XF [(float_extend:XF
13583 (match_operand:MODEF 1 "register_operand" "0"))]
13585 "TARGET_USE_FANCY_MATH_387
13586 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13587 || TARGET_MIX_SSE_I387)
13588 && flag_unsafe_math_optimizations"
13590 [(set_attr "type" "fpspc")
13591 (set_attr "mode" "XF")])
13593 (define_insn "*cosxf2_i387"
13594 [(set (match_operand:XF 0 "register_operand" "=f")
13595 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13596 "TARGET_USE_FANCY_MATH_387
13597 && flag_unsafe_math_optimizations"
13599 [(set_attr "type" "fpspc")
13600 (set_attr "mode" "XF")])
13602 (define_insn "*cos_extend<mode>xf2_i387"
13603 [(set (match_operand:XF 0 "register_operand" "=f")
13604 (unspec:XF [(float_extend:XF
13605 (match_operand:MODEF 1 "register_operand" "0"))]
13607 "TARGET_USE_FANCY_MATH_387
13608 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13609 || TARGET_MIX_SSE_I387)
13610 && flag_unsafe_math_optimizations"
13612 [(set_attr "type" "fpspc")
13613 (set_attr "mode" "XF")])
13615 ;; When sincos pattern is defined, sin and cos builtin functions will be
13616 ;; expanded to sincos pattern with one of its outputs left unused.
13617 ;; CSE pass will figure out if two sincos patterns can be combined,
13618 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13619 ;; depending on the unused output.
13621 (define_insn "sincosxf3"
13622 [(set (match_operand:XF 0 "register_operand" "=f")
13623 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13624 UNSPEC_SINCOS_COS))
13625 (set (match_operand:XF 1 "register_operand" "=u")
13626 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13627 "TARGET_USE_FANCY_MATH_387
13628 && flag_unsafe_math_optimizations"
13630 [(set_attr "type" "fpspc")
13631 (set_attr "mode" "XF")])
13634 [(set (match_operand:XF 0 "register_operand" "")
13635 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13636 UNSPEC_SINCOS_COS))
13637 (set (match_operand:XF 1 "register_operand" "")
13638 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13639 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13640 && can_create_pseudo_p ()"
13641 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13644 [(set (match_operand:XF 0 "register_operand" "")
13645 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13646 UNSPEC_SINCOS_COS))
13647 (set (match_operand:XF 1 "register_operand" "")
13648 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13649 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13650 && can_create_pseudo_p ()"
13651 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13653 (define_insn "sincos_extend<mode>xf3_i387"
13654 [(set (match_operand:XF 0 "register_operand" "=f")
13655 (unspec:XF [(float_extend:XF
13656 (match_operand:MODEF 2 "register_operand" "0"))]
13657 UNSPEC_SINCOS_COS))
13658 (set (match_operand:XF 1 "register_operand" "=u")
13659 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13660 "TARGET_USE_FANCY_MATH_387
13661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13662 || TARGET_MIX_SSE_I387)
13663 && flag_unsafe_math_optimizations"
13665 [(set_attr "type" "fpspc")
13666 (set_attr "mode" "XF")])
13669 [(set (match_operand:XF 0 "register_operand" "")
13670 (unspec:XF [(float_extend:XF
13671 (match_operand:MODEF 2 "register_operand" ""))]
13672 UNSPEC_SINCOS_COS))
13673 (set (match_operand:XF 1 "register_operand" "")
13674 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13675 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13676 && can_create_pseudo_p ()"
13677 [(set (match_dup 1)
13678 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13681 [(set (match_operand:XF 0 "register_operand" "")
13682 (unspec:XF [(float_extend:XF
13683 (match_operand:MODEF 2 "register_operand" ""))]
13684 UNSPEC_SINCOS_COS))
13685 (set (match_operand:XF 1 "register_operand" "")
13686 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13687 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13688 && can_create_pseudo_p ()"
13689 [(set (match_dup 0)
13690 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13692 (define_expand "sincos<mode>3"
13693 [(use (match_operand:MODEF 0 "register_operand" ""))
13694 (use (match_operand:MODEF 1 "register_operand" ""))
13695 (use (match_operand:MODEF 2 "register_operand" ""))]
13696 "TARGET_USE_FANCY_MATH_387
13697 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13698 || TARGET_MIX_SSE_I387)
13699 && flag_unsafe_math_optimizations"
13701 rtx op0 = gen_reg_rtx (XFmode);
13702 rtx op1 = gen_reg_rtx (XFmode);
13704 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13705 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13706 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13710 (define_insn "fptanxf4_i387"
13711 [(set (match_operand:XF 0 "register_operand" "=f")
13712 (match_operand:XF 3 "const_double_operand" "F"))
13713 (set (match_operand:XF 1 "register_operand" "=u")
13714 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13716 "TARGET_USE_FANCY_MATH_387
13717 && flag_unsafe_math_optimizations
13718 && standard_80387_constant_p (operands[3]) == 2"
13720 [(set_attr "type" "fpspc")
13721 (set_attr "mode" "XF")])
13723 (define_insn "fptan_extend<mode>xf4_i387"
13724 [(set (match_operand:MODEF 0 "register_operand" "=f")
13725 (match_operand:MODEF 3 "const_double_operand" "F"))
13726 (set (match_operand:XF 1 "register_operand" "=u")
13727 (unspec:XF [(float_extend:XF
13728 (match_operand:MODEF 2 "register_operand" "0"))]
13730 "TARGET_USE_FANCY_MATH_387
13731 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13732 || TARGET_MIX_SSE_I387)
13733 && flag_unsafe_math_optimizations
13734 && standard_80387_constant_p (operands[3]) == 2"
13736 [(set_attr "type" "fpspc")
13737 (set_attr "mode" "XF")])
13739 (define_expand "tanxf2"
13740 [(use (match_operand:XF 0 "register_operand" ""))
13741 (use (match_operand:XF 1 "register_operand" ""))]
13742 "TARGET_USE_FANCY_MATH_387
13743 && flag_unsafe_math_optimizations"
13745 rtx one = gen_reg_rtx (XFmode);
13746 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13748 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13752 (define_expand "tan<mode>2"
13753 [(use (match_operand:MODEF 0 "register_operand" ""))
13754 (use (match_operand:MODEF 1 "register_operand" ""))]
13755 "TARGET_USE_FANCY_MATH_387
13756 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13757 || TARGET_MIX_SSE_I387)
13758 && flag_unsafe_math_optimizations"
13760 rtx op0 = gen_reg_rtx (XFmode);
13762 rtx one = gen_reg_rtx (<MODE>mode);
13763 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13765 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13766 operands[1], op2));
13767 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13771 (define_insn "*fpatanxf3_i387"
13772 [(set (match_operand:XF 0 "register_operand" "=f")
13773 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13774 (match_operand:XF 2 "register_operand" "u")]
13776 (clobber (match_scratch:XF 3 "=2"))]
13777 "TARGET_USE_FANCY_MATH_387
13778 && flag_unsafe_math_optimizations"
13780 [(set_attr "type" "fpspc")
13781 (set_attr "mode" "XF")])
13783 (define_insn "fpatan_extend<mode>xf3_i387"
13784 [(set (match_operand:XF 0 "register_operand" "=f")
13785 (unspec:XF [(float_extend:XF
13786 (match_operand:MODEF 1 "register_operand" "0"))
13788 (match_operand:MODEF 2 "register_operand" "u"))]
13790 (clobber (match_scratch:XF 3 "=2"))]
13791 "TARGET_USE_FANCY_MATH_387
13792 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13793 || TARGET_MIX_SSE_I387)
13794 && flag_unsafe_math_optimizations"
13796 [(set_attr "type" "fpspc")
13797 (set_attr "mode" "XF")])
13799 (define_expand "atan2xf3"
13800 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13801 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13802 (match_operand:XF 1 "register_operand" "")]
13804 (clobber (match_scratch:XF 3 ""))])]
13805 "TARGET_USE_FANCY_MATH_387
13806 && flag_unsafe_math_optimizations")
13808 (define_expand "atan2<mode>3"
13809 [(use (match_operand:MODEF 0 "register_operand" ""))
13810 (use (match_operand:MODEF 1 "register_operand" ""))
13811 (use (match_operand:MODEF 2 "register_operand" ""))]
13812 "TARGET_USE_FANCY_MATH_387
13813 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13814 || TARGET_MIX_SSE_I387)
13815 && flag_unsafe_math_optimizations"
13817 rtx op0 = gen_reg_rtx (XFmode);
13819 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13820 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13824 (define_expand "atanxf2"
13825 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13826 (unspec:XF [(match_dup 2)
13827 (match_operand:XF 1 "register_operand" "")]
13829 (clobber (match_scratch:XF 3 ""))])]
13830 "TARGET_USE_FANCY_MATH_387
13831 && flag_unsafe_math_optimizations"
13833 operands[2] = gen_reg_rtx (XFmode);
13834 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13837 (define_expand "atan<mode>2"
13838 [(use (match_operand:MODEF 0 "register_operand" ""))
13839 (use (match_operand:MODEF 1 "register_operand" ""))]
13840 "TARGET_USE_FANCY_MATH_387
13841 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13842 || TARGET_MIX_SSE_I387)
13843 && flag_unsafe_math_optimizations"
13845 rtx op0 = gen_reg_rtx (XFmode);
13847 rtx op2 = gen_reg_rtx (<MODE>mode);
13848 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13850 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13851 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13855 (define_expand "asinxf2"
13856 [(set (match_dup 2)
13857 (mult:XF (match_operand:XF 1 "register_operand" "")
13859 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13860 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13861 (parallel [(set (match_operand:XF 0 "register_operand" "")
13862 (unspec:XF [(match_dup 5) (match_dup 1)]
13864 (clobber (match_scratch:XF 6 ""))])]
13865 "TARGET_USE_FANCY_MATH_387
13866 && flag_unsafe_math_optimizations"
13870 if (optimize_insn_for_size_p ())
13873 for (i = 2; i < 6; i++)
13874 operands[i] = gen_reg_rtx (XFmode);
13876 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13879 (define_expand "asin<mode>2"
13880 [(use (match_operand:MODEF 0 "register_operand" ""))
13881 (use (match_operand:MODEF 1 "general_operand" ""))]
13882 "TARGET_USE_FANCY_MATH_387
13883 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13884 || TARGET_MIX_SSE_I387)
13885 && flag_unsafe_math_optimizations"
13887 rtx op0 = gen_reg_rtx (XFmode);
13888 rtx op1 = gen_reg_rtx (XFmode);
13890 if (optimize_insn_for_size_p ())
13893 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13894 emit_insn (gen_asinxf2 (op0, op1));
13895 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13899 (define_expand "acosxf2"
13900 [(set (match_dup 2)
13901 (mult:XF (match_operand:XF 1 "register_operand" "")
13903 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13904 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13905 (parallel [(set (match_operand:XF 0 "register_operand" "")
13906 (unspec:XF [(match_dup 1) (match_dup 5)]
13908 (clobber (match_scratch:XF 6 ""))])]
13909 "TARGET_USE_FANCY_MATH_387
13910 && flag_unsafe_math_optimizations"
13914 if (optimize_insn_for_size_p ())
13917 for (i = 2; i < 6; i++)
13918 operands[i] = gen_reg_rtx (XFmode);
13920 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13923 (define_expand "acos<mode>2"
13924 [(use (match_operand:MODEF 0 "register_operand" ""))
13925 (use (match_operand:MODEF 1 "general_operand" ""))]
13926 "TARGET_USE_FANCY_MATH_387
13927 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13928 || TARGET_MIX_SSE_I387)
13929 && flag_unsafe_math_optimizations"
13931 rtx op0 = gen_reg_rtx (XFmode);
13932 rtx op1 = gen_reg_rtx (XFmode);
13934 if (optimize_insn_for_size_p ())
13937 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13938 emit_insn (gen_acosxf2 (op0, op1));
13939 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13943 (define_insn "fyl2xxf3_i387"
13944 [(set (match_operand:XF 0 "register_operand" "=f")
13945 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13946 (match_operand:XF 2 "register_operand" "u")]
13948 (clobber (match_scratch:XF 3 "=2"))]
13949 "TARGET_USE_FANCY_MATH_387
13950 && flag_unsafe_math_optimizations"
13952 [(set_attr "type" "fpspc")
13953 (set_attr "mode" "XF")])
13955 (define_insn "fyl2x_extend<mode>xf3_i387"
13956 [(set (match_operand:XF 0 "register_operand" "=f")
13957 (unspec:XF [(float_extend:XF
13958 (match_operand:MODEF 1 "register_operand" "0"))
13959 (match_operand:XF 2 "register_operand" "u")]
13961 (clobber (match_scratch:XF 3 "=2"))]
13962 "TARGET_USE_FANCY_MATH_387
13963 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13964 || TARGET_MIX_SSE_I387)
13965 && flag_unsafe_math_optimizations"
13967 [(set_attr "type" "fpspc")
13968 (set_attr "mode" "XF")])
13970 (define_expand "logxf2"
13971 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13972 (unspec:XF [(match_operand:XF 1 "register_operand" "")
13973 (match_dup 2)] UNSPEC_FYL2X))
13974 (clobber (match_scratch:XF 3 ""))])]
13975 "TARGET_USE_FANCY_MATH_387
13976 && flag_unsafe_math_optimizations"
13978 operands[2] = gen_reg_rtx (XFmode);
13979 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
13982 (define_expand "log<mode>2"
13983 [(use (match_operand:MODEF 0 "register_operand" ""))
13984 (use (match_operand:MODEF 1 "register_operand" ""))]
13985 "TARGET_USE_FANCY_MATH_387
13986 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13987 || TARGET_MIX_SSE_I387)
13988 && flag_unsafe_math_optimizations"
13990 rtx op0 = gen_reg_rtx (XFmode);
13992 rtx op2 = gen_reg_rtx (XFmode);
13993 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
13995 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
13996 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14000 (define_expand "log10xf2"
14001 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14002 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14003 (match_dup 2)] UNSPEC_FYL2X))
14004 (clobber (match_scratch:XF 3 ""))])]
14005 "TARGET_USE_FANCY_MATH_387
14006 && flag_unsafe_math_optimizations"
14008 operands[2] = gen_reg_rtx (XFmode);
14009 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14012 (define_expand "log10<mode>2"
14013 [(use (match_operand:MODEF 0 "register_operand" ""))
14014 (use (match_operand:MODEF 1 "register_operand" ""))]
14015 "TARGET_USE_FANCY_MATH_387
14016 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14017 || TARGET_MIX_SSE_I387)
14018 && flag_unsafe_math_optimizations"
14020 rtx op0 = gen_reg_rtx (XFmode);
14022 rtx op2 = gen_reg_rtx (XFmode);
14023 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14025 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14026 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14030 (define_expand "log2xf2"
14031 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14032 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14033 (match_dup 2)] UNSPEC_FYL2X))
14034 (clobber (match_scratch:XF 3 ""))])]
14035 "TARGET_USE_FANCY_MATH_387
14036 && flag_unsafe_math_optimizations"
14038 operands[2] = gen_reg_rtx (XFmode);
14039 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14042 (define_expand "log2<mode>2"
14043 [(use (match_operand:MODEF 0 "register_operand" ""))
14044 (use (match_operand:MODEF 1 "register_operand" ""))]
14045 "TARGET_USE_FANCY_MATH_387
14046 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14047 || TARGET_MIX_SSE_I387)
14048 && flag_unsafe_math_optimizations"
14050 rtx op0 = gen_reg_rtx (XFmode);
14052 rtx op2 = gen_reg_rtx (XFmode);
14053 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14055 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14056 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14060 (define_insn "fyl2xp1xf3_i387"
14061 [(set (match_operand:XF 0 "register_operand" "=f")
14062 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14063 (match_operand:XF 2 "register_operand" "u")]
14065 (clobber (match_scratch:XF 3 "=2"))]
14066 "TARGET_USE_FANCY_MATH_387
14067 && flag_unsafe_math_optimizations"
14069 [(set_attr "type" "fpspc")
14070 (set_attr "mode" "XF")])
14072 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14073 [(set (match_operand:XF 0 "register_operand" "=f")
14074 (unspec:XF [(float_extend:XF
14075 (match_operand:MODEF 1 "register_operand" "0"))
14076 (match_operand:XF 2 "register_operand" "u")]
14078 (clobber (match_scratch:XF 3 "=2"))]
14079 "TARGET_USE_FANCY_MATH_387
14080 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14081 || TARGET_MIX_SSE_I387)
14082 && flag_unsafe_math_optimizations"
14084 [(set_attr "type" "fpspc")
14085 (set_attr "mode" "XF")])
14087 (define_expand "log1pxf2"
14088 [(use (match_operand:XF 0 "register_operand" ""))
14089 (use (match_operand:XF 1 "register_operand" ""))]
14090 "TARGET_USE_FANCY_MATH_387
14091 && flag_unsafe_math_optimizations"
14093 if (optimize_insn_for_size_p ())
14096 ix86_emit_i387_log1p (operands[0], operands[1]);
14100 (define_expand "log1p<mode>2"
14101 [(use (match_operand:MODEF 0 "register_operand" ""))
14102 (use (match_operand:MODEF 1 "register_operand" ""))]
14103 "TARGET_USE_FANCY_MATH_387
14104 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14105 || TARGET_MIX_SSE_I387)
14106 && flag_unsafe_math_optimizations"
14110 if (optimize_insn_for_size_p ())
14113 op0 = gen_reg_rtx (XFmode);
14115 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14117 ix86_emit_i387_log1p (op0, operands[1]);
14118 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14122 (define_insn "fxtractxf3_i387"
14123 [(set (match_operand:XF 0 "register_operand" "=f")
14124 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14125 UNSPEC_XTRACT_FRACT))
14126 (set (match_operand:XF 1 "register_operand" "=u")
14127 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14128 "TARGET_USE_FANCY_MATH_387
14129 && flag_unsafe_math_optimizations"
14131 [(set_attr "type" "fpspc")
14132 (set_attr "mode" "XF")])
14134 (define_insn "fxtract_extend<mode>xf3_i387"
14135 [(set (match_operand:XF 0 "register_operand" "=f")
14136 (unspec:XF [(float_extend:XF
14137 (match_operand:MODEF 2 "register_operand" "0"))]
14138 UNSPEC_XTRACT_FRACT))
14139 (set (match_operand:XF 1 "register_operand" "=u")
14140 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14141 "TARGET_USE_FANCY_MATH_387
14142 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14143 || TARGET_MIX_SSE_I387)
14144 && flag_unsafe_math_optimizations"
14146 [(set_attr "type" "fpspc")
14147 (set_attr "mode" "XF")])
14149 (define_expand "logbxf2"
14150 [(parallel [(set (match_dup 2)
14151 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14152 UNSPEC_XTRACT_FRACT))
14153 (set (match_operand:XF 0 "register_operand" "")
14154 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14155 "TARGET_USE_FANCY_MATH_387
14156 && flag_unsafe_math_optimizations"
14157 "operands[2] = gen_reg_rtx (XFmode);")
14159 (define_expand "logb<mode>2"
14160 [(use (match_operand:MODEF 0 "register_operand" ""))
14161 (use (match_operand:MODEF 1 "register_operand" ""))]
14162 "TARGET_USE_FANCY_MATH_387
14163 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14164 || TARGET_MIX_SSE_I387)
14165 && flag_unsafe_math_optimizations"
14167 rtx op0 = gen_reg_rtx (XFmode);
14168 rtx op1 = gen_reg_rtx (XFmode);
14170 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14171 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14175 (define_expand "ilogbxf2"
14176 [(use (match_operand:SI 0 "register_operand" ""))
14177 (use (match_operand:XF 1 "register_operand" ""))]
14178 "TARGET_USE_FANCY_MATH_387
14179 && flag_unsafe_math_optimizations"
14183 if (optimize_insn_for_size_p ())
14186 op0 = gen_reg_rtx (XFmode);
14187 op1 = gen_reg_rtx (XFmode);
14189 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14190 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14194 (define_expand "ilogb<mode>2"
14195 [(use (match_operand:SI 0 "register_operand" ""))
14196 (use (match_operand:MODEF 1 "register_operand" ""))]
14197 "TARGET_USE_FANCY_MATH_387
14198 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14199 || TARGET_MIX_SSE_I387)
14200 && flag_unsafe_math_optimizations"
14204 if (optimize_insn_for_size_p ())
14207 op0 = gen_reg_rtx (XFmode);
14208 op1 = gen_reg_rtx (XFmode);
14210 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14211 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14215 (define_insn "*f2xm1xf2_i387"
14216 [(set (match_operand:XF 0 "register_operand" "=f")
14217 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14219 "TARGET_USE_FANCY_MATH_387
14220 && flag_unsafe_math_optimizations"
14222 [(set_attr "type" "fpspc")
14223 (set_attr "mode" "XF")])
14225 (define_insn "*fscalexf4_i387"
14226 [(set (match_operand:XF 0 "register_operand" "=f")
14227 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14228 (match_operand:XF 3 "register_operand" "1")]
14229 UNSPEC_FSCALE_FRACT))
14230 (set (match_operand:XF 1 "register_operand" "=u")
14231 (unspec:XF [(match_dup 2) (match_dup 3)]
14232 UNSPEC_FSCALE_EXP))]
14233 "TARGET_USE_FANCY_MATH_387
14234 && flag_unsafe_math_optimizations"
14236 [(set_attr "type" "fpspc")
14237 (set_attr "mode" "XF")])
14239 (define_expand "expNcorexf3"
14240 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14241 (match_operand:XF 2 "register_operand" "")))
14242 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14243 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14244 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14245 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14246 (parallel [(set (match_operand:XF 0 "register_operand" "")
14247 (unspec:XF [(match_dup 8) (match_dup 4)]
14248 UNSPEC_FSCALE_FRACT))
14250 (unspec:XF [(match_dup 8) (match_dup 4)]
14251 UNSPEC_FSCALE_EXP))])]
14252 "TARGET_USE_FANCY_MATH_387
14253 && flag_unsafe_math_optimizations"
14257 if (optimize_insn_for_size_p ())
14260 for (i = 3; i < 10; i++)
14261 operands[i] = gen_reg_rtx (XFmode);
14263 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14266 (define_expand "expxf2"
14267 [(use (match_operand:XF 0 "register_operand" ""))
14268 (use (match_operand:XF 1 "register_operand" ""))]
14269 "TARGET_USE_FANCY_MATH_387
14270 && flag_unsafe_math_optimizations"
14274 if (optimize_insn_for_size_p ())
14277 op2 = gen_reg_rtx (XFmode);
14278 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14280 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14284 (define_expand "exp<mode>2"
14285 [(use (match_operand:MODEF 0 "register_operand" ""))
14286 (use (match_operand:MODEF 1 "general_operand" ""))]
14287 "TARGET_USE_FANCY_MATH_387
14288 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14289 || TARGET_MIX_SSE_I387)
14290 && flag_unsafe_math_optimizations"
14294 if (optimize_insn_for_size_p ())
14297 op0 = gen_reg_rtx (XFmode);
14298 op1 = gen_reg_rtx (XFmode);
14300 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14301 emit_insn (gen_expxf2 (op0, op1));
14302 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14306 (define_expand "exp10xf2"
14307 [(use (match_operand:XF 0 "register_operand" ""))
14308 (use (match_operand:XF 1 "register_operand" ""))]
14309 "TARGET_USE_FANCY_MATH_387
14310 && flag_unsafe_math_optimizations"
14314 if (optimize_insn_for_size_p ())
14317 op2 = gen_reg_rtx (XFmode);
14318 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14320 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14324 (define_expand "exp10<mode>2"
14325 [(use (match_operand:MODEF 0 "register_operand" ""))
14326 (use (match_operand:MODEF 1 "general_operand" ""))]
14327 "TARGET_USE_FANCY_MATH_387
14328 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14329 || TARGET_MIX_SSE_I387)
14330 && flag_unsafe_math_optimizations"
14334 if (optimize_insn_for_size_p ())
14337 op0 = gen_reg_rtx (XFmode);
14338 op1 = gen_reg_rtx (XFmode);
14340 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14341 emit_insn (gen_exp10xf2 (op0, op1));
14342 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14346 (define_expand "exp2xf2"
14347 [(use (match_operand:XF 0 "register_operand" ""))
14348 (use (match_operand:XF 1 "register_operand" ""))]
14349 "TARGET_USE_FANCY_MATH_387
14350 && flag_unsafe_math_optimizations"
14354 if (optimize_insn_for_size_p ())
14357 op2 = gen_reg_rtx (XFmode);
14358 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14360 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14364 (define_expand "exp2<mode>2"
14365 [(use (match_operand:MODEF 0 "register_operand" ""))
14366 (use (match_operand:MODEF 1 "general_operand" ""))]
14367 "TARGET_USE_FANCY_MATH_387
14368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14369 || TARGET_MIX_SSE_I387)
14370 && flag_unsafe_math_optimizations"
14374 if (optimize_insn_for_size_p ())
14377 op0 = gen_reg_rtx (XFmode);
14378 op1 = gen_reg_rtx (XFmode);
14380 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14381 emit_insn (gen_exp2xf2 (op0, op1));
14382 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14386 (define_expand "expm1xf2"
14387 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14389 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14390 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14391 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14392 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14393 (parallel [(set (match_dup 7)
14394 (unspec:XF [(match_dup 6) (match_dup 4)]
14395 UNSPEC_FSCALE_FRACT))
14397 (unspec:XF [(match_dup 6) (match_dup 4)]
14398 UNSPEC_FSCALE_EXP))])
14399 (parallel [(set (match_dup 10)
14400 (unspec:XF [(match_dup 9) (match_dup 8)]
14401 UNSPEC_FSCALE_FRACT))
14402 (set (match_dup 11)
14403 (unspec:XF [(match_dup 9) (match_dup 8)]
14404 UNSPEC_FSCALE_EXP))])
14405 (set (match_dup 12) (minus:XF (match_dup 10)
14406 (float_extend:XF (match_dup 13))))
14407 (set (match_operand:XF 0 "register_operand" "")
14408 (plus:XF (match_dup 12) (match_dup 7)))]
14409 "TARGET_USE_FANCY_MATH_387
14410 && flag_unsafe_math_optimizations"
14414 if (optimize_insn_for_size_p ())
14417 for (i = 2; i < 13; i++)
14418 operands[i] = gen_reg_rtx (XFmode);
14421 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14423 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14426 (define_expand "expm1<mode>2"
14427 [(use (match_operand:MODEF 0 "register_operand" ""))
14428 (use (match_operand:MODEF 1 "general_operand" ""))]
14429 "TARGET_USE_FANCY_MATH_387
14430 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14431 || TARGET_MIX_SSE_I387)
14432 && flag_unsafe_math_optimizations"
14436 if (optimize_insn_for_size_p ())
14439 op0 = gen_reg_rtx (XFmode);
14440 op1 = gen_reg_rtx (XFmode);
14442 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14443 emit_insn (gen_expm1xf2 (op0, op1));
14444 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14448 (define_expand "ldexpxf3"
14449 [(set (match_dup 3)
14450 (float:XF (match_operand:SI 2 "register_operand" "")))
14451 (parallel [(set (match_operand:XF 0 " register_operand" "")
14452 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14454 UNSPEC_FSCALE_FRACT))
14456 (unspec:XF [(match_dup 1) (match_dup 3)]
14457 UNSPEC_FSCALE_EXP))])]
14458 "TARGET_USE_FANCY_MATH_387
14459 && flag_unsafe_math_optimizations"
14461 if (optimize_insn_for_size_p ())
14464 operands[3] = gen_reg_rtx (XFmode);
14465 operands[4] = gen_reg_rtx (XFmode);
14468 (define_expand "ldexp<mode>3"
14469 [(use (match_operand:MODEF 0 "register_operand" ""))
14470 (use (match_operand:MODEF 1 "general_operand" ""))
14471 (use (match_operand:SI 2 "register_operand" ""))]
14472 "TARGET_USE_FANCY_MATH_387
14473 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14474 || TARGET_MIX_SSE_I387)
14475 && flag_unsafe_math_optimizations"
14479 if (optimize_insn_for_size_p ())
14482 op0 = gen_reg_rtx (XFmode);
14483 op1 = gen_reg_rtx (XFmode);
14485 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14486 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14487 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14491 (define_expand "scalbxf3"
14492 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14493 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14494 (match_operand:XF 2 "register_operand" "")]
14495 UNSPEC_FSCALE_FRACT))
14497 (unspec:XF [(match_dup 1) (match_dup 2)]
14498 UNSPEC_FSCALE_EXP))])]
14499 "TARGET_USE_FANCY_MATH_387
14500 && flag_unsafe_math_optimizations"
14502 if (optimize_insn_for_size_p ())
14505 operands[3] = gen_reg_rtx (XFmode);
14508 (define_expand "scalb<mode>3"
14509 [(use (match_operand:MODEF 0 "register_operand" ""))
14510 (use (match_operand:MODEF 1 "general_operand" ""))
14511 (use (match_operand:MODEF 2 "general_operand" ""))]
14512 "TARGET_USE_FANCY_MATH_387
14513 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14514 || TARGET_MIX_SSE_I387)
14515 && flag_unsafe_math_optimizations"
14519 if (optimize_insn_for_size_p ())
14522 op0 = gen_reg_rtx (XFmode);
14523 op1 = gen_reg_rtx (XFmode);
14524 op2 = gen_reg_rtx (XFmode);
14526 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14527 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14528 emit_insn (gen_scalbxf3 (op0, op1, op2));
14529 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14533 (define_expand "significandxf2"
14534 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14535 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14536 UNSPEC_XTRACT_FRACT))
14538 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14539 "TARGET_USE_FANCY_MATH_387
14540 && flag_unsafe_math_optimizations"
14541 "operands[2] = gen_reg_rtx (XFmode);")
14543 (define_expand "significand<mode>2"
14544 [(use (match_operand:MODEF 0 "register_operand" ""))
14545 (use (match_operand:MODEF 1 "register_operand" ""))]
14546 "TARGET_USE_FANCY_MATH_387
14547 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14548 || TARGET_MIX_SSE_I387)
14549 && flag_unsafe_math_optimizations"
14551 rtx op0 = gen_reg_rtx (XFmode);
14552 rtx op1 = gen_reg_rtx (XFmode);
14554 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14555 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14560 (define_insn "sse4_1_round<mode>2"
14561 [(set (match_operand:MODEF 0 "register_operand" "=x")
14562 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14563 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14566 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14567 [(set_attr "type" "ssecvt")
14568 (set_attr "prefix_extra" "1")
14569 (set_attr "prefix" "maybe_vex")
14570 (set_attr "mode" "<MODE>")])
14572 (define_insn "rintxf2"
14573 [(set (match_operand:XF 0 "register_operand" "=f")
14574 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14576 "TARGET_USE_FANCY_MATH_387
14577 && flag_unsafe_math_optimizations"
14579 [(set_attr "type" "fpspc")
14580 (set_attr "mode" "XF")])
14582 (define_expand "rint<mode>2"
14583 [(use (match_operand:MODEF 0 "register_operand" ""))
14584 (use (match_operand:MODEF 1 "register_operand" ""))]
14585 "(TARGET_USE_FANCY_MATH_387
14586 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14587 || TARGET_MIX_SSE_I387)
14588 && flag_unsafe_math_optimizations)
14589 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14590 && !flag_trapping_math)"
14592 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14593 && !flag_trapping_math)
14596 emit_insn (gen_sse4_1_round<mode>2
14597 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14598 else if (optimize_insn_for_size_p ())
14601 ix86_expand_rint (operands[0], operands[1]);
14605 rtx op0 = gen_reg_rtx (XFmode);
14606 rtx op1 = gen_reg_rtx (XFmode);
14608 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14609 emit_insn (gen_rintxf2 (op0, op1));
14611 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14616 (define_expand "round<mode>2"
14617 [(match_operand:X87MODEF 0 "register_operand" "")
14618 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14619 "(TARGET_USE_FANCY_MATH_387
14620 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14621 || TARGET_MIX_SSE_I387)
14622 && flag_unsafe_math_optimizations)
14623 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14624 && !flag_trapping_math && !flag_rounding_math)"
14626 if (optimize_insn_for_size_p ())
14629 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14630 && !flag_trapping_math && !flag_rounding_math)
14634 operands[1] = force_reg (<MODE>mode, operands[1]);
14635 ix86_expand_round_sse4 (operands[0], operands[1]);
14637 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14638 ix86_expand_round (operands[0], operands[1]);
14640 ix86_expand_rounddf_32 (operands[0], operands[1]);
14644 operands[1] = force_reg (<MODE>mode, operands[1]);
14645 ix86_emit_i387_round (operands[0], operands[1]);
14650 (define_insn_and_split "*fistdi2_1"
14651 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14652 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14654 "TARGET_USE_FANCY_MATH_387
14655 && can_create_pseudo_p ()"
14660 if (memory_operand (operands[0], VOIDmode))
14661 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14664 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14665 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14670 [(set_attr "type" "fpspc")
14671 (set_attr "mode" "DI")])
14673 (define_insn "fistdi2"
14674 [(set (match_operand:DI 0 "memory_operand" "=m")
14675 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14677 (clobber (match_scratch:XF 2 "=&1f"))]
14678 "TARGET_USE_FANCY_MATH_387"
14679 "* return output_fix_trunc (insn, operands, false);"
14680 [(set_attr "type" "fpspc")
14681 (set_attr "mode" "DI")])
14683 (define_insn "fistdi2_with_temp"
14684 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14685 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14687 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14688 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14689 "TARGET_USE_FANCY_MATH_387"
14691 [(set_attr "type" "fpspc")
14692 (set_attr "mode" "DI")])
14695 [(set (match_operand:DI 0 "register_operand" "")
14696 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14698 (clobber (match_operand:DI 2 "memory_operand" ""))
14699 (clobber (match_scratch 3 ""))]
14701 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14702 (clobber (match_dup 3))])
14703 (set (match_dup 0) (match_dup 2))])
14706 [(set (match_operand:DI 0 "memory_operand" "")
14707 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14709 (clobber (match_operand:DI 2 "memory_operand" ""))
14710 (clobber (match_scratch 3 ""))]
14712 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14713 (clobber (match_dup 3))])])
14715 (define_insn_and_split "*fist<mode>2_1"
14716 [(set (match_operand:SWI24 0 "register_operand" "")
14717 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14719 "TARGET_USE_FANCY_MATH_387
14720 && can_create_pseudo_p ()"
14725 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14726 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14730 [(set_attr "type" "fpspc")
14731 (set_attr "mode" "<MODE>")])
14733 (define_insn "fist<mode>2"
14734 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14735 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14737 "TARGET_USE_FANCY_MATH_387"
14738 "* return output_fix_trunc (insn, operands, false);"
14739 [(set_attr "type" "fpspc")
14740 (set_attr "mode" "<MODE>")])
14742 (define_insn "fist<mode>2_with_temp"
14743 [(set (match_operand:SWI24 0 "register_operand" "=r")
14744 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14746 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14747 "TARGET_USE_FANCY_MATH_387"
14749 [(set_attr "type" "fpspc")
14750 (set_attr "mode" "<MODE>")])
14753 [(set (match_operand:SWI24 0 "register_operand" "")
14754 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14756 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14758 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14759 (set (match_dup 0) (match_dup 2))])
14762 [(set (match_operand:SWI24 0 "memory_operand" "")
14763 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14765 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14767 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14769 (define_expand "lrintxf<mode>2"
14770 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14771 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14773 "TARGET_USE_FANCY_MATH_387")
14775 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14776 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14777 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14778 UNSPEC_FIX_NOTRUNC))]
14779 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14780 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14782 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14783 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14784 (match_operand:X87MODEF 1 "register_operand" "")]
14785 "(TARGET_USE_FANCY_MATH_387
14786 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14787 || TARGET_MIX_SSE_I387)
14788 && flag_unsafe_math_optimizations)
14789 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14790 && <SWI248x:MODE>mode != HImode
14791 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14792 && !flag_trapping_math && !flag_rounding_math)"
14794 if (optimize_insn_for_size_p ())
14797 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14798 && <SWI248x:MODE>mode != HImode
14799 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14800 && !flag_trapping_math && !flag_rounding_math)
14801 ix86_expand_lround (operands[0], operands[1]);
14803 ix86_emit_i387_round (operands[0], operands[1]);
14807 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14808 (define_insn_and_split "frndintxf2_floor"
14809 [(set (match_operand:XF 0 "register_operand" "")
14810 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14811 UNSPEC_FRNDINT_FLOOR))
14812 (clobber (reg:CC FLAGS_REG))]
14813 "TARGET_USE_FANCY_MATH_387
14814 && flag_unsafe_math_optimizations
14815 && can_create_pseudo_p ()"
14820 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14822 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14823 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14825 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14826 operands[2], operands[3]));
14829 [(set_attr "type" "frndint")
14830 (set_attr "i387_cw" "floor")
14831 (set_attr "mode" "XF")])
14833 (define_insn "frndintxf2_floor_i387"
14834 [(set (match_operand:XF 0 "register_operand" "=f")
14835 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14836 UNSPEC_FRNDINT_FLOOR))
14837 (use (match_operand:HI 2 "memory_operand" "m"))
14838 (use (match_operand:HI 3 "memory_operand" "m"))]
14839 "TARGET_USE_FANCY_MATH_387
14840 && flag_unsafe_math_optimizations"
14841 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14842 [(set_attr "type" "frndint")
14843 (set_attr "i387_cw" "floor")
14844 (set_attr "mode" "XF")])
14846 (define_expand "floorxf2"
14847 [(use (match_operand:XF 0 "register_operand" ""))
14848 (use (match_operand:XF 1 "register_operand" ""))]
14849 "TARGET_USE_FANCY_MATH_387
14850 && flag_unsafe_math_optimizations"
14852 if (optimize_insn_for_size_p ())
14854 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14858 (define_expand "floor<mode>2"
14859 [(use (match_operand:MODEF 0 "register_operand" ""))
14860 (use (match_operand:MODEF 1 "register_operand" ""))]
14861 "(TARGET_USE_FANCY_MATH_387
14862 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14863 || TARGET_MIX_SSE_I387)
14864 && flag_unsafe_math_optimizations)
14865 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14866 && !flag_trapping_math)"
14868 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14869 && !flag_trapping_math)
14872 emit_insn (gen_sse4_1_round<mode>2
14873 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14874 else if (optimize_insn_for_size_p ())
14876 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14877 ix86_expand_floorceil (operands[0], operands[1], true);
14879 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14885 if (optimize_insn_for_size_p ())
14888 op0 = gen_reg_rtx (XFmode);
14889 op1 = gen_reg_rtx (XFmode);
14890 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14891 emit_insn (gen_frndintxf2_floor (op0, op1));
14893 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14898 (define_insn_and_split "*fist<mode>2_floor_1"
14899 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14900 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14901 UNSPEC_FIST_FLOOR))
14902 (clobber (reg:CC FLAGS_REG))]
14903 "TARGET_USE_FANCY_MATH_387
14904 && flag_unsafe_math_optimizations
14905 && can_create_pseudo_p ()"
14910 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14912 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14913 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14914 if (memory_operand (operands[0], VOIDmode))
14915 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14916 operands[2], operands[3]));
14919 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14920 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14921 operands[2], operands[3],
14926 [(set_attr "type" "fistp")
14927 (set_attr "i387_cw" "floor")
14928 (set_attr "mode" "<MODE>")])
14930 (define_insn "fistdi2_floor"
14931 [(set (match_operand:DI 0 "memory_operand" "=m")
14932 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14933 UNSPEC_FIST_FLOOR))
14934 (use (match_operand:HI 2 "memory_operand" "m"))
14935 (use (match_operand:HI 3 "memory_operand" "m"))
14936 (clobber (match_scratch:XF 4 "=&1f"))]
14937 "TARGET_USE_FANCY_MATH_387
14938 && flag_unsafe_math_optimizations"
14939 "* return output_fix_trunc (insn, operands, false);"
14940 [(set_attr "type" "fistp")
14941 (set_attr "i387_cw" "floor")
14942 (set_attr "mode" "DI")])
14944 (define_insn "fistdi2_floor_with_temp"
14945 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14946 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14947 UNSPEC_FIST_FLOOR))
14948 (use (match_operand:HI 2 "memory_operand" "m,m"))
14949 (use (match_operand:HI 3 "memory_operand" "m,m"))
14950 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14951 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14952 "TARGET_USE_FANCY_MATH_387
14953 && flag_unsafe_math_optimizations"
14955 [(set_attr "type" "fistp")
14956 (set_attr "i387_cw" "floor")
14957 (set_attr "mode" "DI")])
14960 [(set (match_operand:DI 0 "register_operand" "")
14961 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14962 UNSPEC_FIST_FLOOR))
14963 (use (match_operand:HI 2 "memory_operand" ""))
14964 (use (match_operand:HI 3 "memory_operand" ""))
14965 (clobber (match_operand:DI 4 "memory_operand" ""))
14966 (clobber (match_scratch 5 ""))]
14968 [(parallel [(set (match_dup 4)
14969 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14970 (use (match_dup 2))
14971 (use (match_dup 3))
14972 (clobber (match_dup 5))])
14973 (set (match_dup 0) (match_dup 4))])
14976 [(set (match_operand:DI 0 "memory_operand" "")
14977 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14978 UNSPEC_FIST_FLOOR))
14979 (use (match_operand:HI 2 "memory_operand" ""))
14980 (use (match_operand:HI 3 "memory_operand" ""))
14981 (clobber (match_operand:DI 4 "memory_operand" ""))
14982 (clobber (match_scratch 5 ""))]
14984 [(parallel [(set (match_dup 0)
14985 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
14986 (use (match_dup 2))
14987 (use (match_dup 3))
14988 (clobber (match_dup 5))])])
14990 (define_insn "fist<mode>2_floor"
14991 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14992 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14993 UNSPEC_FIST_FLOOR))
14994 (use (match_operand:HI 2 "memory_operand" "m"))
14995 (use (match_operand:HI 3 "memory_operand" "m"))]
14996 "TARGET_USE_FANCY_MATH_387
14997 && flag_unsafe_math_optimizations"
14998 "* return output_fix_trunc (insn, operands, false);"
14999 [(set_attr "type" "fistp")
15000 (set_attr "i387_cw" "floor")
15001 (set_attr "mode" "<MODE>")])
15003 (define_insn "fist<mode>2_floor_with_temp"
15004 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15005 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15006 UNSPEC_FIST_FLOOR))
15007 (use (match_operand:HI 2 "memory_operand" "m,m"))
15008 (use (match_operand:HI 3 "memory_operand" "m,m"))
15009 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15010 "TARGET_USE_FANCY_MATH_387
15011 && flag_unsafe_math_optimizations"
15013 [(set_attr "type" "fistp")
15014 (set_attr "i387_cw" "floor")
15015 (set_attr "mode" "<MODE>")])
15018 [(set (match_operand:SWI24 0 "register_operand" "")
15019 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15020 UNSPEC_FIST_FLOOR))
15021 (use (match_operand:HI 2 "memory_operand" ""))
15022 (use (match_operand:HI 3 "memory_operand" ""))
15023 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15025 [(parallel [(set (match_dup 4)
15026 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15027 (use (match_dup 2))
15028 (use (match_dup 3))])
15029 (set (match_dup 0) (match_dup 4))])
15032 [(set (match_operand:SWI24 0 "memory_operand" "")
15033 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15034 UNSPEC_FIST_FLOOR))
15035 (use (match_operand:HI 2 "memory_operand" ""))
15036 (use (match_operand:HI 3 "memory_operand" ""))
15037 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15039 [(parallel [(set (match_dup 0)
15040 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15041 (use (match_dup 2))
15042 (use (match_dup 3))])])
15044 (define_expand "lfloorxf<mode>2"
15045 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15046 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15047 UNSPEC_FIST_FLOOR))
15048 (clobber (reg:CC FLAGS_REG))])]
15049 "TARGET_USE_FANCY_MATH_387
15050 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15051 && flag_unsafe_math_optimizations")
15053 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15054 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15055 (match_operand:MODEF 1 "register_operand" "")]
15056 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15057 && !flag_trapping_math"
15059 if (TARGET_64BIT && optimize_insn_for_size_p ())
15061 ix86_expand_lfloorceil (operands[0], operands[1], true);
15065 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15066 (define_insn_and_split "frndintxf2_ceil"
15067 [(set (match_operand:XF 0 "register_operand" "")
15068 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15069 UNSPEC_FRNDINT_CEIL))
15070 (clobber (reg:CC FLAGS_REG))]
15071 "TARGET_USE_FANCY_MATH_387
15072 && flag_unsafe_math_optimizations
15073 && can_create_pseudo_p ()"
15078 ix86_optimize_mode_switching[I387_CEIL] = 1;
15080 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15081 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15083 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15084 operands[2], operands[3]));
15087 [(set_attr "type" "frndint")
15088 (set_attr "i387_cw" "ceil")
15089 (set_attr "mode" "XF")])
15091 (define_insn "frndintxf2_ceil_i387"
15092 [(set (match_operand:XF 0 "register_operand" "=f")
15093 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15094 UNSPEC_FRNDINT_CEIL))
15095 (use (match_operand:HI 2 "memory_operand" "m"))
15096 (use (match_operand:HI 3 "memory_operand" "m"))]
15097 "TARGET_USE_FANCY_MATH_387
15098 && flag_unsafe_math_optimizations"
15099 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15100 [(set_attr "type" "frndint")
15101 (set_attr "i387_cw" "ceil")
15102 (set_attr "mode" "XF")])
15104 (define_expand "ceilxf2"
15105 [(use (match_operand:XF 0 "register_operand" ""))
15106 (use (match_operand:XF 1 "register_operand" ""))]
15107 "TARGET_USE_FANCY_MATH_387
15108 && flag_unsafe_math_optimizations"
15110 if (optimize_insn_for_size_p ())
15112 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15116 (define_expand "ceil<mode>2"
15117 [(use (match_operand:MODEF 0 "register_operand" ""))
15118 (use (match_operand:MODEF 1 "register_operand" ""))]
15119 "(TARGET_USE_FANCY_MATH_387
15120 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15121 || TARGET_MIX_SSE_I387)
15122 && flag_unsafe_math_optimizations)
15123 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15124 && !flag_trapping_math)"
15126 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15127 && !flag_trapping_math)
15130 emit_insn (gen_sse4_1_round<mode>2
15131 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15132 else if (optimize_insn_for_size_p ())
15134 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15135 ix86_expand_floorceil (operands[0], operands[1], false);
15137 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15143 if (optimize_insn_for_size_p ())
15146 op0 = gen_reg_rtx (XFmode);
15147 op1 = gen_reg_rtx (XFmode);
15148 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15149 emit_insn (gen_frndintxf2_ceil (op0, op1));
15151 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15156 (define_insn_and_split "*fist<mode>2_ceil_1"
15157 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15158 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15160 (clobber (reg:CC FLAGS_REG))]
15161 "TARGET_USE_FANCY_MATH_387
15162 && flag_unsafe_math_optimizations
15163 && can_create_pseudo_p ()"
15168 ix86_optimize_mode_switching[I387_CEIL] = 1;
15170 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15171 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15172 if (memory_operand (operands[0], VOIDmode))
15173 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15174 operands[2], operands[3]));
15177 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15178 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15179 operands[2], operands[3],
15184 [(set_attr "type" "fistp")
15185 (set_attr "i387_cw" "ceil")
15186 (set_attr "mode" "<MODE>")])
15188 (define_insn "fistdi2_ceil"
15189 [(set (match_operand:DI 0 "memory_operand" "=m")
15190 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15192 (use (match_operand:HI 2 "memory_operand" "m"))
15193 (use (match_operand:HI 3 "memory_operand" "m"))
15194 (clobber (match_scratch:XF 4 "=&1f"))]
15195 "TARGET_USE_FANCY_MATH_387
15196 && flag_unsafe_math_optimizations"
15197 "* return output_fix_trunc (insn, operands, false);"
15198 [(set_attr "type" "fistp")
15199 (set_attr "i387_cw" "ceil")
15200 (set_attr "mode" "DI")])
15202 (define_insn "fistdi2_ceil_with_temp"
15203 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15204 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15206 (use (match_operand:HI 2 "memory_operand" "m,m"))
15207 (use (match_operand:HI 3 "memory_operand" "m,m"))
15208 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15209 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15210 "TARGET_USE_FANCY_MATH_387
15211 && flag_unsafe_math_optimizations"
15213 [(set_attr "type" "fistp")
15214 (set_attr "i387_cw" "ceil")
15215 (set_attr "mode" "DI")])
15218 [(set (match_operand:DI 0 "register_operand" "")
15219 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15221 (use (match_operand:HI 2 "memory_operand" ""))
15222 (use (match_operand:HI 3 "memory_operand" ""))
15223 (clobber (match_operand:DI 4 "memory_operand" ""))
15224 (clobber (match_scratch 5 ""))]
15226 [(parallel [(set (match_dup 4)
15227 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15228 (use (match_dup 2))
15229 (use (match_dup 3))
15230 (clobber (match_dup 5))])
15231 (set (match_dup 0) (match_dup 4))])
15234 [(set (match_operand:DI 0 "memory_operand" "")
15235 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15237 (use (match_operand:HI 2 "memory_operand" ""))
15238 (use (match_operand:HI 3 "memory_operand" ""))
15239 (clobber (match_operand:DI 4 "memory_operand" ""))
15240 (clobber (match_scratch 5 ""))]
15242 [(parallel [(set (match_dup 0)
15243 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15244 (use (match_dup 2))
15245 (use (match_dup 3))
15246 (clobber (match_dup 5))])])
15248 (define_insn "fist<mode>2_ceil"
15249 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15250 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15252 (use (match_operand:HI 2 "memory_operand" "m"))
15253 (use (match_operand:HI 3 "memory_operand" "m"))]
15254 "TARGET_USE_FANCY_MATH_387
15255 && flag_unsafe_math_optimizations"
15256 "* return output_fix_trunc (insn, operands, false);"
15257 [(set_attr "type" "fistp")
15258 (set_attr "i387_cw" "ceil")
15259 (set_attr "mode" "<MODE>")])
15261 (define_insn "fist<mode>2_ceil_with_temp"
15262 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15263 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15265 (use (match_operand:HI 2 "memory_operand" "m,m"))
15266 (use (match_operand:HI 3 "memory_operand" "m,m"))
15267 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15268 "TARGET_USE_FANCY_MATH_387
15269 && flag_unsafe_math_optimizations"
15271 [(set_attr "type" "fistp")
15272 (set_attr "i387_cw" "ceil")
15273 (set_attr "mode" "<MODE>")])
15276 [(set (match_operand:SWI24 0 "register_operand" "")
15277 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15279 (use (match_operand:HI 2 "memory_operand" ""))
15280 (use (match_operand:HI 3 "memory_operand" ""))
15281 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15283 [(parallel [(set (match_dup 4)
15284 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15285 (use (match_dup 2))
15286 (use (match_dup 3))])
15287 (set (match_dup 0) (match_dup 4))])
15290 [(set (match_operand:SWI24 0 "memory_operand" "")
15291 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15293 (use (match_operand:HI 2 "memory_operand" ""))
15294 (use (match_operand:HI 3 "memory_operand" ""))
15295 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15297 [(parallel [(set (match_dup 0)
15298 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15299 (use (match_dup 2))
15300 (use (match_dup 3))])])
15302 (define_expand "lceilxf<mode>2"
15303 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15304 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15306 (clobber (reg:CC FLAGS_REG))])]
15307 "TARGET_USE_FANCY_MATH_387
15308 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15309 && flag_unsafe_math_optimizations")
15311 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15312 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15313 (match_operand:MODEF 1 "register_operand" "")]
15314 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15315 && !flag_trapping_math"
15317 ix86_expand_lfloorceil (operands[0], operands[1], false);
15321 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15322 (define_insn_and_split "frndintxf2_trunc"
15323 [(set (match_operand:XF 0 "register_operand" "")
15324 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15325 UNSPEC_FRNDINT_TRUNC))
15326 (clobber (reg:CC FLAGS_REG))]
15327 "TARGET_USE_FANCY_MATH_387
15328 && flag_unsafe_math_optimizations
15329 && can_create_pseudo_p ()"
15334 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15336 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15337 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15339 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15340 operands[2], operands[3]));
15343 [(set_attr "type" "frndint")
15344 (set_attr "i387_cw" "trunc")
15345 (set_attr "mode" "XF")])
15347 (define_insn "frndintxf2_trunc_i387"
15348 [(set (match_operand:XF 0 "register_operand" "=f")
15349 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15350 UNSPEC_FRNDINT_TRUNC))
15351 (use (match_operand:HI 2 "memory_operand" "m"))
15352 (use (match_operand:HI 3 "memory_operand" "m"))]
15353 "TARGET_USE_FANCY_MATH_387
15354 && flag_unsafe_math_optimizations"
15355 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15356 [(set_attr "type" "frndint")
15357 (set_attr "i387_cw" "trunc")
15358 (set_attr "mode" "XF")])
15360 (define_expand "btruncxf2"
15361 [(use (match_operand:XF 0 "register_operand" ""))
15362 (use (match_operand:XF 1 "register_operand" ""))]
15363 "TARGET_USE_FANCY_MATH_387
15364 && flag_unsafe_math_optimizations"
15366 if (optimize_insn_for_size_p ())
15368 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15372 (define_expand "btrunc<mode>2"
15373 [(use (match_operand:MODEF 0 "register_operand" ""))
15374 (use (match_operand:MODEF 1 "register_operand" ""))]
15375 "(TARGET_USE_FANCY_MATH_387
15376 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15377 || TARGET_MIX_SSE_I387)
15378 && flag_unsafe_math_optimizations)
15379 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15380 && !flag_trapping_math)"
15382 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15383 && !flag_trapping_math)
15386 emit_insn (gen_sse4_1_round<mode>2
15387 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15388 else if (optimize_insn_for_size_p ())
15390 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15391 ix86_expand_trunc (operands[0], operands[1]);
15393 ix86_expand_truncdf_32 (operands[0], operands[1]);
15399 if (optimize_insn_for_size_p ())
15402 op0 = gen_reg_rtx (XFmode);
15403 op1 = gen_reg_rtx (XFmode);
15404 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15405 emit_insn (gen_frndintxf2_trunc (op0, op1));
15407 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15412 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15413 (define_insn_and_split "frndintxf2_mask_pm"
15414 [(set (match_operand:XF 0 "register_operand" "")
15415 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15416 UNSPEC_FRNDINT_MASK_PM))
15417 (clobber (reg:CC FLAGS_REG))]
15418 "TARGET_USE_FANCY_MATH_387
15419 && flag_unsafe_math_optimizations
15420 && can_create_pseudo_p ()"
15425 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15427 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15428 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15430 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15431 operands[2], operands[3]));
15434 [(set_attr "type" "frndint")
15435 (set_attr "i387_cw" "mask_pm")
15436 (set_attr "mode" "XF")])
15438 (define_insn "frndintxf2_mask_pm_i387"
15439 [(set (match_operand:XF 0 "register_operand" "=f")
15440 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15441 UNSPEC_FRNDINT_MASK_PM))
15442 (use (match_operand:HI 2 "memory_operand" "m"))
15443 (use (match_operand:HI 3 "memory_operand" "m"))]
15444 "TARGET_USE_FANCY_MATH_387
15445 && flag_unsafe_math_optimizations"
15446 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15447 [(set_attr "type" "frndint")
15448 (set_attr "i387_cw" "mask_pm")
15449 (set_attr "mode" "XF")])
15451 (define_expand "nearbyintxf2"
15452 [(use (match_operand:XF 0 "register_operand" ""))
15453 (use (match_operand:XF 1 "register_operand" ""))]
15454 "TARGET_USE_FANCY_MATH_387
15455 && flag_unsafe_math_optimizations"
15457 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15461 (define_expand "nearbyint<mode>2"
15462 [(use (match_operand:MODEF 0 "register_operand" ""))
15463 (use (match_operand:MODEF 1 "register_operand" ""))]
15464 "TARGET_USE_FANCY_MATH_387
15465 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15466 || TARGET_MIX_SSE_I387)
15467 && flag_unsafe_math_optimizations"
15469 rtx op0 = gen_reg_rtx (XFmode);
15470 rtx op1 = gen_reg_rtx (XFmode);
15472 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15473 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15475 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15479 (define_insn "fxam<mode>2_i387"
15480 [(set (match_operand:HI 0 "register_operand" "=a")
15482 [(match_operand:X87MODEF 1 "register_operand" "f")]
15484 "TARGET_USE_FANCY_MATH_387"
15485 "fxam\n\tfnstsw\t%0"
15486 [(set_attr "type" "multi")
15487 (set_attr "length" "4")
15488 (set_attr "unit" "i387")
15489 (set_attr "mode" "<MODE>")])
15491 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15492 [(set (match_operand:HI 0 "register_operand" "")
15494 [(match_operand:MODEF 1 "memory_operand" "")]
15496 "TARGET_USE_FANCY_MATH_387
15497 && can_create_pseudo_p ()"
15500 [(set (match_dup 2)(match_dup 1))
15502 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15504 operands[2] = gen_reg_rtx (<MODE>mode);
15506 MEM_VOLATILE_P (operands[1]) = 1;
15508 [(set_attr "type" "multi")
15509 (set_attr "unit" "i387")
15510 (set_attr "mode" "<MODE>")])
15512 (define_expand "isinfxf2"
15513 [(use (match_operand:SI 0 "register_operand" ""))
15514 (use (match_operand:XF 1 "register_operand" ""))]
15515 "TARGET_USE_FANCY_MATH_387
15516 && TARGET_C99_FUNCTIONS"
15518 rtx mask = GEN_INT (0x45);
15519 rtx val = GEN_INT (0x05);
15523 rtx scratch = gen_reg_rtx (HImode);
15524 rtx res = gen_reg_rtx (QImode);
15526 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15528 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15529 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15530 cond = gen_rtx_fmt_ee (EQ, QImode,
15531 gen_rtx_REG (CCmode, FLAGS_REG),
15533 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15534 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15538 (define_expand "isinf<mode>2"
15539 [(use (match_operand:SI 0 "register_operand" ""))
15540 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15541 "TARGET_USE_FANCY_MATH_387
15542 && TARGET_C99_FUNCTIONS
15543 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15545 rtx mask = GEN_INT (0x45);
15546 rtx val = GEN_INT (0x05);
15550 rtx scratch = gen_reg_rtx (HImode);
15551 rtx res = gen_reg_rtx (QImode);
15553 /* Remove excess precision by forcing value through memory. */
15554 if (memory_operand (operands[1], VOIDmode))
15555 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15558 rtx temp = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15560 emit_move_insn (temp, operands[1]);
15561 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15564 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15565 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15566 cond = gen_rtx_fmt_ee (EQ, QImode,
15567 gen_rtx_REG (CCmode, FLAGS_REG),
15569 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15570 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15574 (define_expand "signbitxf2"
15575 [(use (match_operand:SI 0 "register_operand" ""))
15576 (use (match_operand:XF 1 "register_operand" ""))]
15577 "TARGET_USE_FANCY_MATH_387"
15579 rtx scratch = gen_reg_rtx (HImode);
15581 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15582 emit_insn (gen_andsi3 (operands[0],
15583 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15587 (define_insn "movmsk_df"
15588 [(set (match_operand:SI 0 "register_operand" "=r")
15590 [(match_operand:DF 1 "register_operand" "x")]
15592 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15593 "%vmovmskpd\t{%1, %0|%0, %1}"
15594 [(set_attr "type" "ssemov")
15595 (set_attr "prefix" "maybe_vex")
15596 (set_attr "mode" "DF")])
15598 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15599 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15600 (define_expand "signbitdf2"
15601 [(use (match_operand:SI 0 "register_operand" ""))
15602 (use (match_operand:DF 1 "register_operand" ""))]
15603 "TARGET_USE_FANCY_MATH_387
15604 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15606 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15608 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15609 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15613 rtx scratch = gen_reg_rtx (HImode);
15615 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15616 emit_insn (gen_andsi3 (operands[0],
15617 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15622 (define_expand "signbitsf2"
15623 [(use (match_operand:SI 0 "register_operand" ""))
15624 (use (match_operand:SF 1 "register_operand" ""))]
15625 "TARGET_USE_FANCY_MATH_387
15626 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15628 rtx scratch = gen_reg_rtx (HImode);
15630 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15631 emit_insn (gen_andsi3 (operands[0],
15632 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15636 ;; Block operation instructions
15639 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15642 [(set_attr "length" "1")
15643 (set_attr "length_immediate" "0")
15644 (set_attr "modrm" "0")])
15646 (define_expand "movmem<mode>"
15647 [(use (match_operand:BLK 0 "memory_operand" ""))
15648 (use (match_operand:BLK 1 "memory_operand" ""))
15649 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15650 (use (match_operand:SWI48 3 "const_int_operand" ""))
15651 (use (match_operand:SI 4 "const_int_operand" ""))
15652 (use (match_operand:SI 5 "const_int_operand" ""))]
15655 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15656 operands[4], operands[5]))
15662 ;; Most CPUs don't like single string operations
15663 ;; Handle this case here to simplify previous expander.
15665 (define_expand "strmov"
15666 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15667 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15668 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15669 (clobber (reg:CC FLAGS_REG))])
15670 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15671 (clobber (reg:CC FLAGS_REG))])]
15674 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15676 /* If .md ever supports :P for Pmode, these can be directly
15677 in the pattern above. */
15678 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15679 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15681 /* Can't use this if the user has appropriated esi or edi. */
15682 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15683 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15685 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15686 operands[2], operands[3],
15687 operands[5], operands[6]));
15691 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15694 (define_expand "strmov_singleop"
15695 [(parallel [(set (match_operand 1 "memory_operand" "")
15696 (match_operand 3 "memory_operand" ""))
15697 (set (match_operand 0 "register_operand" "")
15698 (match_operand 4 "" ""))
15699 (set (match_operand 2 "register_operand" "")
15700 (match_operand 5 "" ""))])]
15702 "ix86_current_function_needs_cld = 1;")
15704 (define_insn "*strmovdi_rex_1"
15705 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15706 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15707 (set (match_operand:DI 0 "register_operand" "=D")
15708 (plus:DI (match_dup 2)
15710 (set (match_operand:DI 1 "register_operand" "=S")
15711 (plus:DI (match_dup 3)
15714 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15716 [(set_attr "type" "str")
15717 (set_attr "memory" "both")
15718 (set_attr "mode" "DI")])
15720 (define_insn "*strmovsi_1"
15721 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15722 (mem:SI (match_operand:P 3 "register_operand" "1")))
15723 (set (match_operand:P 0 "register_operand" "=D")
15724 (plus:P (match_dup 2)
15726 (set (match_operand:P 1 "register_operand" "=S")
15727 (plus:P (match_dup 3)
15729 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15731 [(set_attr "type" "str")
15732 (set_attr "memory" "both")
15733 (set_attr "mode" "SI")])
15735 (define_insn "*strmovhi_1"
15736 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15737 (mem:HI (match_operand:P 3 "register_operand" "1")))
15738 (set (match_operand:P 0 "register_operand" "=D")
15739 (plus:P (match_dup 2)
15741 (set (match_operand:P 1 "register_operand" "=S")
15742 (plus:P (match_dup 3)
15744 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15746 [(set_attr "type" "str")
15747 (set_attr "memory" "both")
15748 (set_attr "mode" "HI")])
15750 (define_insn "*strmovqi_1"
15751 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15752 (mem:QI (match_operand:P 3 "register_operand" "1")))
15753 (set (match_operand:P 0 "register_operand" "=D")
15754 (plus:P (match_dup 2)
15756 (set (match_operand:P 1 "register_operand" "=S")
15757 (plus:P (match_dup 3)
15759 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15761 [(set_attr "type" "str")
15762 (set_attr "memory" "both")
15763 (set (attr "prefix_rex")
15765 (match_test "<P:MODE>mode == DImode")
15767 (const_string "*")))
15768 (set_attr "mode" "QI")])
15770 (define_expand "rep_mov"
15771 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15772 (set (match_operand 0 "register_operand" "")
15773 (match_operand 5 "" ""))
15774 (set (match_operand 2 "register_operand" "")
15775 (match_operand 6 "" ""))
15776 (set (match_operand 1 "memory_operand" "")
15777 (match_operand 3 "memory_operand" ""))
15778 (use (match_dup 4))])]
15780 "ix86_current_function_needs_cld = 1;")
15782 (define_insn "*rep_movdi_rex64"
15783 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15784 (set (match_operand:DI 0 "register_operand" "=D")
15785 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15787 (match_operand:DI 3 "register_operand" "0")))
15788 (set (match_operand:DI 1 "register_operand" "=S")
15789 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15790 (match_operand:DI 4 "register_operand" "1")))
15791 (set (mem:BLK (match_dup 3))
15792 (mem:BLK (match_dup 4)))
15793 (use (match_dup 5))]
15795 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15797 [(set_attr "type" "str")
15798 (set_attr "prefix_rep" "1")
15799 (set_attr "memory" "both")
15800 (set_attr "mode" "DI")])
15802 (define_insn "*rep_movsi"
15803 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15804 (set (match_operand:P 0 "register_operand" "=D")
15805 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15807 (match_operand:P 3 "register_operand" "0")))
15808 (set (match_operand:P 1 "register_operand" "=S")
15809 (plus:P (ashift:P (match_dup 5) (const_int 2))
15810 (match_operand:P 4 "register_operand" "1")))
15811 (set (mem:BLK (match_dup 3))
15812 (mem:BLK (match_dup 4)))
15813 (use (match_dup 5))]
15814 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15815 "rep{%;} movs{l|d}"
15816 [(set_attr "type" "str")
15817 (set_attr "prefix_rep" "1")
15818 (set_attr "memory" "both")
15819 (set_attr "mode" "SI")])
15821 (define_insn "*rep_movqi"
15822 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15823 (set (match_operand:P 0 "register_operand" "=D")
15824 (plus:P (match_operand:P 3 "register_operand" "0")
15825 (match_operand:P 5 "register_operand" "2")))
15826 (set (match_operand:P 1 "register_operand" "=S")
15827 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15828 (set (mem:BLK (match_dup 3))
15829 (mem:BLK (match_dup 4)))
15830 (use (match_dup 5))]
15831 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15833 [(set_attr "type" "str")
15834 (set_attr "prefix_rep" "1")
15835 (set_attr "memory" "both")
15836 (set_attr "mode" "QI")])
15838 (define_expand "setmem<mode>"
15839 [(use (match_operand:BLK 0 "memory_operand" ""))
15840 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15841 (use (match_operand:QI 2 "nonmemory_operand" ""))
15842 (use (match_operand 3 "const_int_operand" ""))
15843 (use (match_operand:SI 4 "const_int_operand" ""))
15844 (use (match_operand:SI 5 "const_int_operand" ""))]
15847 if (ix86_expand_setmem (operands[0], operands[1],
15848 operands[2], operands[3],
15849 operands[4], operands[5]))
15855 ;; Most CPUs don't like single string operations
15856 ;; Handle this case here to simplify previous expander.
15858 (define_expand "strset"
15859 [(set (match_operand 1 "memory_operand" "")
15860 (match_operand 2 "register_operand" ""))
15861 (parallel [(set (match_operand 0 "register_operand" "")
15863 (clobber (reg:CC FLAGS_REG))])]
15866 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15867 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15869 /* If .md ever supports :P for Pmode, this can be directly
15870 in the pattern above. */
15871 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15872 GEN_INT (GET_MODE_SIZE (GET_MODE
15874 /* Can't use this if the user has appropriated eax or edi. */
15875 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15876 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15878 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15884 (define_expand "strset_singleop"
15885 [(parallel [(set (match_operand 1 "memory_operand" "")
15886 (match_operand 2 "register_operand" ""))
15887 (set (match_operand 0 "register_operand" "")
15888 (match_operand 3 "" ""))])]
15890 "ix86_current_function_needs_cld = 1;")
15892 (define_insn "*strsetdi_rex_1"
15893 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15894 (match_operand:DI 2 "register_operand" "a"))
15895 (set (match_operand:DI 0 "register_operand" "=D")
15896 (plus:DI (match_dup 1)
15899 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15901 [(set_attr "type" "str")
15902 (set_attr "memory" "store")
15903 (set_attr "mode" "DI")])
15905 (define_insn "*strsetsi_1"
15906 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15907 (match_operand:SI 2 "register_operand" "a"))
15908 (set (match_operand:P 0 "register_operand" "=D")
15909 (plus:P (match_dup 1)
15911 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15913 [(set_attr "type" "str")
15914 (set_attr "memory" "store")
15915 (set_attr "mode" "SI")])
15917 (define_insn "*strsethi_1"
15918 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15919 (match_operand:HI 2 "register_operand" "a"))
15920 (set (match_operand:P 0 "register_operand" "=D")
15921 (plus:P (match_dup 1)
15923 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15925 [(set_attr "type" "str")
15926 (set_attr "memory" "store")
15927 (set_attr "mode" "HI")])
15929 (define_insn "*strsetqi_1"
15930 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15931 (match_operand:QI 2 "register_operand" "a"))
15932 (set (match_operand:P 0 "register_operand" "=D")
15933 (plus:P (match_dup 1)
15935 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15937 [(set_attr "type" "str")
15938 (set_attr "memory" "store")
15939 (set (attr "prefix_rex")
15941 (match_test "<P:MODE>mode == DImode")
15943 (const_string "*")))
15944 (set_attr "mode" "QI")])
15946 (define_expand "rep_stos"
15947 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15948 (set (match_operand 0 "register_operand" "")
15949 (match_operand 4 "" ""))
15950 (set (match_operand 2 "memory_operand" "") (const_int 0))
15951 (use (match_operand 3 "register_operand" ""))
15952 (use (match_dup 1))])]
15954 "ix86_current_function_needs_cld = 1;")
15956 (define_insn "*rep_stosdi_rex64"
15957 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15958 (set (match_operand:DI 0 "register_operand" "=D")
15959 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
15961 (match_operand:DI 3 "register_operand" "0")))
15962 (set (mem:BLK (match_dup 3))
15964 (use (match_operand:DI 2 "register_operand" "a"))
15965 (use (match_dup 4))]
15967 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15969 [(set_attr "type" "str")
15970 (set_attr "prefix_rep" "1")
15971 (set_attr "memory" "store")
15972 (set_attr "mode" "DI")])
15974 (define_insn "*rep_stossi"
15975 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15976 (set (match_operand:P 0 "register_operand" "=D")
15977 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
15979 (match_operand:P 3 "register_operand" "0")))
15980 (set (mem:BLK (match_dup 3))
15982 (use (match_operand:SI 2 "register_operand" "a"))
15983 (use (match_dup 4))]
15984 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
15985 "rep{%;} stos{l|d}"
15986 [(set_attr "type" "str")
15987 (set_attr "prefix_rep" "1")
15988 (set_attr "memory" "store")
15989 (set_attr "mode" "SI")])
15991 (define_insn "*rep_stosqi"
15992 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
15993 (set (match_operand:P 0 "register_operand" "=D")
15994 (plus:P (match_operand:P 3 "register_operand" "0")
15995 (match_operand:P 4 "register_operand" "1")))
15996 (set (mem:BLK (match_dup 3))
15998 (use (match_operand:QI 2 "register_operand" "a"))
15999 (use (match_dup 4))]
16000 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16002 [(set_attr "type" "str")
16003 (set_attr "prefix_rep" "1")
16004 (set_attr "memory" "store")
16005 (set (attr "prefix_rex")
16007 (match_test "<P:MODE>mode == DImode")
16009 (const_string "*")))
16010 (set_attr "mode" "QI")])
16012 (define_expand "cmpstrnsi"
16013 [(set (match_operand:SI 0 "register_operand" "")
16014 (compare:SI (match_operand:BLK 1 "general_operand" "")
16015 (match_operand:BLK 2 "general_operand" "")))
16016 (use (match_operand 3 "general_operand" ""))
16017 (use (match_operand 4 "immediate_operand" ""))]
16020 rtx addr1, addr2, out, outlow, count, countreg, align;
16022 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16025 /* Can't use this if the user has appropriated ecx, esi or edi. */
16026 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16031 out = gen_reg_rtx (SImode);
16033 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16034 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16035 if (addr1 != XEXP (operands[1], 0))
16036 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16037 if (addr2 != XEXP (operands[2], 0))
16038 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16040 count = operands[3];
16041 countreg = ix86_zero_extend_to_Pmode (count);
16043 /* %%% Iff we are testing strict equality, we can use known alignment
16044 to good advantage. This may be possible with combine, particularly
16045 once cc0 is dead. */
16046 align = operands[4];
16048 if (CONST_INT_P (count))
16050 if (INTVAL (count) == 0)
16052 emit_move_insn (operands[0], const0_rtx);
16055 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16056 operands[1], operands[2]));
16060 rtx (*gen_cmp) (rtx, rtx);
16062 gen_cmp = (TARGET_64BIT
16063 ? gen_cmpdi_1 : gen_cmpsi_1);
16065 emit_insn (gen_cmp (countreg, countreg));
16066 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16067 operands[1], operands[2]));
16070 outlow = gen_lowpart (QImode, out);
16071 emit_insn (gen_cmpintqi (outlow));
16072 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16074 if (operands[0] != out)
16075 emit_move_insn (operands[0], out);
16080 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16082 (define_expand "cmpintqi"
16083 [(set (match_dup 1)
16084 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16086 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16087 (parallel [(set (match_operand:QI 0 "register_operand" "")
16088 (minus:QI (match_dup 1)
16090 (clobber (reg:CC FLAGS_REG))])]
16093 operands[1] = gen_reg_rtx (QImode);
16094 operands[2] = gen_reg_rtx (QImode);
16097 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16098 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16100 (define_expand "cmpstrnqi_nz_1"
16101 [(parallel [(set (reg:CC FLAGS_REG)
16102 (compare:CC (match_operand 4 "memory_operand" "")
16103 (match_operand 5 "memory_operand" "")))
16104 (use (match_operand 2 "register_operand" ""))
16105 (use (match_operand:SI 3 "immediate_operand" ""))
16106 (clobber (match_operand 0 "register_operand" ""))
16107 (clobber (match_operand 1 "register_operand" ""))
16108 (clobber (match_dup 2))])]
16110 "ix86_current_function_needs_cld = 1;")
16112 (define_insn "*cmpstrnqi_nz_1"
16113 [(set (reg:CC FLAGS_REG)
16114 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16115 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16116 (use (match_operand:P 6 "register_operand" "2"))
16117 (use (match_operand:SI 3 "immediate_operand" "i"))
16118 (clobber (match_operand:P 0 "register_operand" "=S"))
16119 (clobber (match_operand:P 1 "register_operand" "=D"))
16120 (clobber (match_operand:P 2 "register_operand" "=c"))]
16121 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16123 [(set_attr "type" "str")
16124 (set_attr "mode" "QI")
16125 (set (attr "prefix_rex")
16127 (match_test "<P:MODE>mode == DImode")
16129 (const_string "*")))
16130 (set_attr "prefix_rep" "1")])
16132 ;; The same, but the count is not known to not be zero.
16134 (define_expand "cmpstrnqi_1"
16135 [(parallel [(set (reg:CC FLAGS_REG)
16136 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16138 (compare:CC (match_operand 4 "memory_operand" "")
16139 (match_operand 5 "memory_operand" ""))
16141 (use (match_operand:SI 3 "immediate_operand" ""))
16142 (use (reg:CC FLAGS_REG))
16143 (clobber (match_operand 0 "register_operand" ""))
16144 (clobber (match_operand 1 "register_operand" ""))
16145 (clobber (match_dup 2))])]
16147 "ix86_current_function_needs_cld = 1;")
16149 (define_insn "*cmpstrnqi_1"
16150 [(set (reg:CC FLAGS_REG)
16151 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16153 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16154 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16156 (use (match_operand:SI 3 "immediate_operand" "i"))
16157 (use (reg:CC FLAGS_REG))
16158 (clobber (match_operand:P 0 "register_operand" "=S"))
16159 (clobber (match_operand:P 1 "register_operand" "=D"))
16160 (clobber (match_operand:P 2 "register_operand" "=c"))]
16161 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16163 [(set_attr "type" "str")
16164 (set_attr "mode" "QI")
16165 (set (attr "prefix_rex")
16167 (match_test "<P:MODE>mode == DImode")
16169 (const_string "*")))
16170 (set_attr "prefix_rep" "1")])
16172 (define_expand "strlen<mode>"
16173 [(set (match_operand:P 0 "register_operand" "")
16174 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16175 (match_operand:QI 2 "immediate_operand" "")
16176 (match_operand 3 "immediate_operand" "")]
16180 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16186 (define_expand "strlenqi_1"
16187 [(parallel [(set (match_operand 0 "register_operand" "")
16188 (match_operand 2 "" ""))
16189 (clobber (match_operand 1 "register_operand" ""))
16190 (clobber (reg:CC FLAGS_REG))])]
16192 "ix86_current_function_needs_cld = 1;")
16194 (define_insn "*strlenqi_1"
16195 [(set (match_operand:P 0 "register_operand" "=&c")
16196 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16197 (match_operand:QI 2 "register_operand" "a")
16198 (match_operand:P 3 "immediate_operand" "i")
16199 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16200 (clobber (match_operand:P 1 "register_operand" "=D"))
16201 (clobber (reg:CC FLAGS_REG))]
16202 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16204 [(set_attr "type" "str")
16205 (set_attr "mode" "QI")
16206 (set (attr "prefix_rex")
16208 (match_test "<P:MODE>mode == DImode")
16210 (const_string "*")))
16211 (set_attr "prefix_rep" "1")])
16213 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16214 ;; handled in combine, but it is not currently up to the task.
16215 ;; When used for their truth value, the cmpstrn* expanders generate
16224 ;; The intermediate three instructions are unnecessary.
16226 ;; This one handles cmpstrn*_nz_1...
16229 (set (reg:CC FLAGS_REG)
16230 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16231 (mem:BLK (match_operand 5 "register_operand" ""))))
16232 (use (match_operand 6 "register_operand" ""))
16233 (use (match_operand:SI 3 "immediate_operand" ""))
16234 (clobber (match_operand 0 "register_operand" ""))
16235 (clobber (match_operand 1 "register_operand" ""))
16236 (clobber (match_operand 2 "register_operand" ""))])
16237 (set (match_operand:QI 7 "register_operand" "")
16238 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16239 (set (match_operand:QI 8 "register_operand" "")
16240 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16241 (set (reg FLAGS_REG)
16242 (compare (match_dup 7) (match_dup 8)))
16244 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16246 (set (reg:CC FLAGS_REG)
16247 (compare:CC (mem:BLK (match_dup 4))
16248 (mem:BLK (match_dup 5))))
16249 (use (match_dup 6))
16250 (use (match_dup 3))
16251 (clobber (match_dup 0))
16252 (clobber (match_dup 1))
16253 (clobber (match_dup 2))])])
16255 ;; ...and this one handles cmpstrn*_1.
16258 (set (reg:CC FLAGS_REG)
16259 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16261 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16262 (mem:BLK (match_operand 5 "register_operand" "")))
16264 (use (match_operand:SI 3 "immediate_operand" ""))
16265 (use (reg:CC FLAGS_REG))
16266 (clobber (match_operand 0 "register_operand" ""))
16267 (clobber (match_operand 1 "register_operand" ""))
16268 (clobber (match_operand 2 "register_operand" ""))])
16269 (set (match_operand:QI 7 "register_operand" "")
16270 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16271 (set (match_operand:QI 8 "register_operand" "")
16272 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16273 (set (reg FLAGS_REG)
16274 (compare (match_dup 7) (match_dup 8)))
16276 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16278 (set (reg:CC FLAGS_REG)
16279 (if_then_else:CC (ne (match_dup 6)
16281 (compare:CC (mem:BLK (match_dup 4))
16282 (mem:BLK (match_dup 5)))
16284 (use (match_dup 3))
16285 (use (reg:CC FLAGS_REG))
16286 (clobber (match_dup 0))
16287 (clobber (match_dup 1))
16288 (clobber (match_dup 2))])])
16290 ;; Conditional move instructions.
16292 (define_expand "mov<mode>cc"
16293 [(set (match_operand:SWIM 0 "register_operand" "")
16294 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16295 (match_operand:SWIM 2 "<general_operand>" "")
16296 (match_operand:SWIM 3 "<general_operand>" "")))]
16298 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16300 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16301 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16302 ;; So just document what we're doing explicitly.
16304 (define_expand "x86_mov<mode>cc_0_m1"
16306 [(set (match_operand:SWI48 0 "register_operand" "")
16307 (if_then_else:SWI48
16308 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16309 [(match_operand 1 "flags_reg_operand" "")
16313 (clobber (reg:CC FLAGS_REG))])])
16315 (define_insn "*x86_mov<mode>cc_0_m1"
16316 [(set (match_operand:SWI48 0 "register_operand" "=r")
16317 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16318 [(reg FLAGS_REG) (const_int 0)])
16321 (clobber (reg:CC FLAGS_REG))]
16323 "sbb{<imodesuffix>}\t%0, %0"
16324 ; Since we don't have the proper number of operands for an alu insn,
16325 ; fill in all the blanks.
16326 [(set_attr "type" "alu")
16327 (set_attr "use_carry" "1")
16328 (set_attr "pent_pair" "pu")
16329 (set_attr "memory" "none")
16330 (set_attr "imm_disp" "false")
16331 (set_attr "mode" "<MODE>")
16332 (set_attr "length_immediate" "0")])
16334 (define_insn "*x86_mov<mode>cc_0_m1_se"
16335 [(set (match_operand:SWI48 0 "register_operand" "=r")
16336 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16337 [(reg FLAGS_REG) (const_int 0)])
16340 (clobber (reg:CC FLAGS_REG))]
16342 "sbb{<imodesuffix>}\t%0, %0"
16343 [(set_attr "type" "alu")
16344 (set_attr "use_carry" "1")
16345 (set_attr "pent_pair" "pu")
16346 (set_attr "memory" "none")
16347 (set_attr "imm_disp" "false")
16348 (set_attr "mode" "<MODE>")
16349 (set_attr "length_immediate" "0")])
16351 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16352 [(set (match_operand:SWI48 0 "register_operand" "=r")
16353 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16354 [(reg FLAGS_REG) (const_int 0)])))
16355 (clobber (reg:CC FLAGS_REG))]
16357 "sbb{<imodesuffix>}\t%0, %0"
16358 [(set_attr "type" "alu")
16359 (set_attr "use_carry" "1")
16360 (set_attr "pent_pair" "pu")
16361 (set_attr "memory" "none")
16362 (set_attr "imm_disp" "false")
16363 (set_attr "mode" "<MODE>")
16364 (set_attr "length_immediate" "0")])
16366 (define_insn "*mov<mode>cc_noc"
16367 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16368 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16369 [(reg FLAGS_REG) (const_int 0)])
16370 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16371 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16372 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16374 cmov%O2%C1\t{%2, %0|%0, %2}
16375 cmov%O2%c1\t{%3, %0|%0, %3}"
16376 [(set_attr "type" "icmov")
16377 (set_attr "mode" "<MODE>")])
16379 (define_insn "*movqicc_noc"
16380 [(set (match_operand:QI 0 "register_operand" "=r,r")
16381 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16382 [(reg FLAGS_REG) (const_int 0)])
16383 (match_operand:QI 2 "register_operand" "r,0")
16384 (match_operand:QI 3 "register_operand" "0,r")))]
16385 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16387 [(set_attr "type" "icmov")
16388 (set_attr "mode" "QI")])
16391 [(set (match_operand 0 "register_operand")
16392 (if_then_else (match_operator 1 "ix86_comparison_operator"
16393 [(reg FLAGS_REG) (const_int 0)])
16394 (match_operand 2 "register_operand")
16395 (match_operand 3 "register_operand")))]
16396 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16397 && (GET_MODE (operands[0]) == QImode
16398 || GET_MODE (operands[0]) == HImode)
16399 && reload_completed"
16400 [(set (match_dup 0)
16401 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16403 operands[0] = gen_lowpart (SImode, operands[0]);
16404 operands[2] = gen_lowpart (SImode, operands[2]);
16405 operands[3] = gen_lowpart (SImode, operands[3]);
16408 (define_expand "mov<mode>cc"
16409 [(set (match_operand:X87MODEF 0 "register_operand" "")
16410 (if_then_else:X87MODEF
16411 (match_operand 1 "ix86_fp_comparison_operator" "")
16412 (match_operand:X87MODEF 2 "register_operand" "")
16413 (match_operand:X87MODEF 3 "register_operand" "")))]
16414 "(TARGET_80387 && TARGET_CMOVE)
16415 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16416 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16418 (define_insn "*movxfcc_1"
16419 [(set (match_operand:XF 0 "register_operand" "=f,f")
16420 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16421 [(reg FLAGS_REG) (const_int 0)])
16422 (match_operand:XF 2 "register_operand" "f,0")
16423 (match_operand:XF 3 "register_operand" "0,f")))]
16424 "TARGET_80387 && TARGET_CMOVE"
16426 fcmov%F1\t{%2, %0|%0, %2}
16427 fcmov%f1\t{%3, %0|%0, %3}"
16428 [(set_attr "type" "fcmov")
16429 (set_attr "mode" "XF")])
16431 (define_insn "*movdfcc_1_rex64"
16432 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16433 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16434 [(reg FLAGS_REG) (const_int 0)])
16435 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16436 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16437 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16438 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16440 fcmov%F1\t{%2, %0|%0, %2}
16441 fcmov%f1\t{%3, %0|%0, %3}
16442 cmov%O2%C1\t{%2, %0|%0, %2}
16443 cmov%O2%c1\t{%3, %0|%0, %3}"
16444 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16445 (set_attr "mode" "DF,DF,DI,DI")])
16447 (define_insn "*movdfcc_1"
16448 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16449 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16450 [(reg FLAGS_REG) (const_int 0)])
16451 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16452 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16453 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16454 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16456 fcmov%F1\t{%2, %0|%0, %2}
16457 fcmov%f1\t{%3, %0|%0, %3}
16460 [(set_attr "type" "fcmov,fcmov,multi,multi")
16461 (set_attr "mode" "DF,DF,DI,DI")])
16464 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16465 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16466 [(reg FLAGS_REG) (const_int 0)])
16467 (match_operand:DF 2 "nonimmediate_operand")
16468 (match_operand:DF 3 "nonimmediate_operand")))]
16469 "!TARGET_64BIT && reload_completed"
16470 [(set (match_dup 2)
16471 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16473 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16475 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16476 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16479 (define_insn "*movsfcc_1_387"
16480 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16481 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16482 [(reg FLAGS_REG) (const_int 0)])
16483 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16484 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16485 "TARGET_80387 && TARGET_CMOVE
16486 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16488 fcmov%F1\t{%2, %0|%0, %2}
16489 fcmov%f1\t{%3, %0|%0, %3}
16490 cmov%O2%C1\t{%2, %0|%0, %2}
16491 cmov%O2%c1\t{%3, %0|%0, %3}"
16492 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16493 (set_attr "mode" "SF,SF,SI,SI")])
16495 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16496 ;; the scalar versions to have only XMM registers as operands.
16498 ;; XOP conditional move
16499 (define_insn "*xop_pcmov_<mode>"
16500 [(set (match_operand:MODEF 0 "register_operand" "=x")
16501 (if_then_else:MODEF
16502 (match_operand:MODEF 1 "register_operand" "x")
16503 (match_operand:MODEF 2 "register_operand" "x")
16504 (match_operand:MODEF 3 "register_operand" "x")))]
16506 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16507 [(set_attr "type" "sse4arg")])
16509 ;; These versions of the min/max patterns are intentionally ignorant of
16510 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16511 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16512 ;; are undefined in this condition, we're certain this is correct.
16514 (define_insn "<code><mode>3"
16515 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16517 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16518 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16519 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16521 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16522 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16523 [(set_attr "isa" "noavx,avx")
16524 (set_attr "prefix" "orig,vex")
16525 (set_attr "type" "sseadd")
16526 (set_attr "mode" "<MODE>")])
16528 ;; These versions of the min/max patterns implement exactly the operations
16529 ;; min = (op1 < op2 ? op1 : op2)
16530 ;; max = (!(op1 < op2) ? op1 : op2)
16531 ;; Their operands are not commutative, and thus they may be used in the
16532 ;; presence of -0.0 and NaN.
16534 (define_insn "*ieee_smin<mode>3"
16535 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16537 [(match_operand:MODEF 1 "register_operand" "0,x")
16538 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16540 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16542 min<ssemodesuffix>\t{%2, %0|%0, %2}
16543 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16544 [(set_attr "isa" "noavx,avx")
16545 (set_attr "prefix" "orig,vex")
16546 (set_attr "type" "sseadd")
16547 (set_attr "mode" "<MODE>")])
16549 (define_insn "*ieee_smax<mode>3"
16550 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16552 [(match_operand:MODEF 1 "register_operand" "0,x")
16553 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16555 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16557 max<ssemodesuffix>\t{%2, %0|%0, %2}
16558 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16559 [(set_attr "isa" "noavx,avx")
16560 (set_attr "prefix" "orig,vex")
16561 (set_attr "type" "sseadd")
16562 (set_attr "mode" "<MODE>")])
16564 ;; Make two stack loads independent:
16566 ;; fld %st(0) -> fld bb
16567 ;; fmul bb fmul %st(1), %st
16569 ;; Actually we only match the last two instructions for simplicity.
16571 [(set (match_operand 0 "fp_register_operand" "")
16572 (match_operand 1 "fp_register_operand" ""))
16574 (match_operator 2 "binary_fp_operator"
16576 (match_operand 3 "memory_operand" "")]))]
16577 "REGNO (operands[0]) != REGNO (operands[1])"
16578 [(set (match_dup 0) (match_dup 3))
16579 (set (match_dup 0) (match_dup 4))]
16581 ;; The % modifier is not operational anymore in peephole2's, so we have to
16582 ;; swap the operands manually in the case of addition and multiplication.
16586 if (COMMUTATIVE_ARITH_P (operands[2]))
16587 op0 = operands[0], op1 = operands[1];
16589 op0 = operands[1], op1 = operands[0];
16591 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16592 GET_MODE (operands[2]),
16596 ;; Conditional addition patterns
16597 (define_expand "add<mode>cc"
16598 [(match_operand:SWI 0 "register_operand" "")
16599 (match_operand 1 "ordered_comparison_operator" "")
16600 (match_operand:SWI 2 "register_operand" "")
16601 (match_operand:SWI 3 "const_int_operand" "")]
16603 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16605 ;; Misc patterns (?)
16607 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16608 ;; Otherwise there will be nothing to keep
16610 ;; [(set (reg ebp) (reg esp))]
16611 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16612 ;; (clobber (eflags)]
16613 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16615 ;; in proper program order.
16617 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16618 [(set (match_operand:P 0 "register_operand" "=r,r")
16619 (plus:P (match_operand:P 1 "register_operand" "0,r")
16620 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16621 (clobber (reg:CC FLAGS_REG))
16622 (clobber (mem:BLK (scratch)))]
16625 switch (get_attr_type (insn))
16628 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16631 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16632 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16633 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16635 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16638 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16639 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16642 [(set (attr "type")
16643 (cond [(and (eq_attr "alternative" "0")
16644 (not (match_test "TARGET_OPT_AGU")))
16645 (const_string "alu")
16646 (match_operand:<MODE> 2 "const0_operand" "")
16647 (const_string "imov")
16649 (const_string "lea")))
16650 (set (attr "length_immediate")
16651 (cond [(eq_attr "type" "imov")
16653 (and (eq_attr "type" "alu")
16654 (match_operand 2 "const128_operand" ""))
16657 (const_string "*")))
16658 (set_attr "mode" "<MODE>")])
16660 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16661 [(set (match_operand:P 0 "register_operand" "=r")
16662 (minus:P (match_operand:P 1 "register_operand" "0")
16663 (match_operand:P 2 "register_operand" "r")))
16664 (clobber (reg:CC FLAGS_REG))
16665 (clobber (mem:BLK (scratch)))]
16667 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16668 [(set_attr "type" "alu")
16669 (set_attr "mode" "<MODE>")])
16671 (define_insn "allocate_stack_worker_probe_<mode>"
16672 [(set (match_operand:P 0 "register_operand" "=a")
16673 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16674 UNSPECV_STACK_PROBE))
16675 (clobber (reg:CC FLAGS_REG))]
16676 "ix86_target_stack_probe ()"
16677 "call\t___chkstk_ms"
16678 [(set_attr "type" "multi")
16679 (set_attr "length" "5")])
16681 (define_expand "allocate_stack"
16682 [(match_operand 0 "register_operand" "")
16683 (match_operand 1 "general_operand" "")]
16684 "ix86_target_stack_probe ()"
16688 #ifndef CHECK_STACK_LIMIT
16689 #define CHECK_STACK_LIMIT 0
16692 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16693 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16695 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16696 stack_pointer_rtx, 0, OPTAB_DIRECT);
16697 if (x != stack_pointer_rtx)
16698 emit_move_insn (stack_pointer_rtx, x);
16702 x = copy_to_mode_reg (Pmode, operands[1]);
16704 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16706 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16707 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16708 stack_pointer_rtx, 0, OPTAB_DIRECT);
16709 if (x != stack_pointer_rtx)
16710 emit_move_insn (stack_pointer_rtx, x);
16713 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16717 ;; Use IOR for stack probes, this is shorter.
16718 (define_expand "probe_stack"
16719 [(match_operand 0 "memory_operand" "")]
16722 rtx (*gen_ior3) (rtx, rtx, rtx);
16724 gen_ior3 = (GET_MODE (operands[0]) == DImode
16725 ? gen_iordi3 : gen_iorsi3);
16727 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16731 (define_insn "adjust_stack_and_probe<mode>"
16732 [(set (match_operand:P 0 "register_operand" "=r")
16733 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16734 UNSPECV_PROBE_STACK_RANGE))
16735 (set (reg:P SP_REG)
16736 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16737 (clobber (reg:CC FLAGS_REG))
16738 (clobber (mem:BLK (scratch)))]
16740 "* return output_adjust_stack_and_probe (operands[0]);"
16741 [(set_attr "type" "multi")])
16743 (define_insn "probe_stack_range<mode>"
16744 [(set (match_operand:P 0 "register_operand" "=r")
16745 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16746 (match_operand:P 2 "const_int_operand" "n")]
16747 UNSPECV_PROBE_STACK_RANGE))
16748 (clobber (reg:CC FLAGS_REG))]
16750 "* return output_probe_stack_range (operands[0], operands[2]);"
16751 [(set_attr "type" "multi")])
16753 (define_expand "builtin_setjmp_receiver"
16754 [(label_ref (match_operand 0 "" ""))]
16755 "!TARGET_64BIT && flag_pic"
16761 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16762 rtx label_rtx = gen_label_rtx ();
16763 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16764 xops[0] = xops[1] = picreg;
16765 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16766 ix86_expand_binary_operator (MINUS, SImode, xops);
16770 emit_insn (gen_set_got (pic_offset_table_rtx));
16774 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16777 [(set (match_operand 0 "register_operand" "")
16778 (match_operator 3 "promotable_binary_operator"
16779 [(match_operand 1 "register_operand" "")
16780 (match_operand 2 "aligned_operand" "")]))
16781 (clobber (reg:CC FLAGS_REG))]
16782 "! TARGET_PARTIAL_REG_STALL && reload_completed
16783 && ((GET_MODE (operands[0]) == HImode
16784 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16785 /* ??? next two lines just !satisfies_constraint_K (...) */
16786 || !CONST_INT_P (operands[2])
16787 || satisfies_constraint_K (operands[2])))
16788 || (GET_MODE (operands[0]) == QImode
16789 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16790 [(parallel [(set (match_dup 0)
16791 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16792 (clobber (reg:CC FLAGS_REG))])]
16794 operands[0] = gen_lowpart (SImode, operands[0]);
16795 operands[1] = gen_lowpart (SImode, operands[1]);
16796 if (GET_CODE (operands[3]) != ASHIFT)
16797 operands[2] = gen_lowpart (SImode, operands[2]);
16798 PUT_MODE (operands[3], SImode);
16801 ; Promote the QImode tests, as i386 has encoding of the AND
16802 ; instruction with 32-bit sign-extended immediate and thus the
16803 ; instruction size is unchanged, except in the %eax case for
16804 ; which it is increased by one byte, hence the ! optimize_size.
16806 [(set (match_operand 0 "flags_reg_operand" "")
16807 (match_operator 2 "compare_operator"
16808 [(and (match_operand 3 "aligned_operand" "")
16809 (match_operand 4 "const_int_operand" ""))
16811 (set (match_operand 1 "register_operand" "")
16812 (and (match_dup 3) (match_dup 4)))]
16813 "! TARGET_PARTIAL_REG_STALL && reload_completed
16814 && optimize_insn_for_speed_p ()
16815 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16816 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16817 /* Ensure that the operand will remain sign-extended immediate. */
16818 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16819 [(parallel [(set (match_dup 0)
16820 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16823 (and:SI (match_dup 3) (match_dup 4)))])]
16826 = gen_int_mode (INTVAL (operands[4])
16827 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16828 operands[1] = gen_lowpart (SImode, operands[1]);
16829 operands[3] = gen_lowpart (SImode, operands[3]);
16832 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16833 ; the TEST instruction with 32-bit sign-extended immediate and thus
16834 ; the instruction size would at least double, which is not what we
16835 ; want even with ! optimize_size.
16837 [(set (match_operand 0 "flags_reg_operand" "")
16838 (match_operator 1 "compare_operator"
16839 [(and (match_operand:HI 2 "aligned_operand" "")
16840 (match_operand:HI 3 "const_int_operand" ""))
16842 "! TARGET_PARTIAL_REG_STALL && reload_completed
16843 && ! TARGET_FAST_PREFIX
16844 && optimize_insn_for_speed_p ()
16845 /* Ensure that the operand will remain sign-extended immediate. */
16846 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16847 [(set (match_dup 0)
16848 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16852 = gen_int_mode (INTVAL (operands[3])
16853 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16854 operands[2] = gen_lowpart (SImode, operands[2]);
16858 [(set (match_operand 0 "register_operand" "")
16859 (neg (match_operand 1 "register_operand" "")))
16860 (clobber (reg:CC FLAGS_REG))]
16861 "! TARGET_PARTIAL_REG_STALL && reload_completed
16862 && (GET_MODE (operands[0]) == HImode
16863 || (GET_MODE (operands[0]) == QImode
16864 && (TARGET_PROMOTE_QImode
16865 || optimize_insn_for_size_p ())))"
16866 [(parallel [(set (match_dup 0)
16867 (neg:SI (match_dup 1)))
16868 (clobber (reg:CC FLAGS_REG))])]
16870 operands[0] = gen_lowpart (SImode, operands[0]);
16871 operands[1] = gen_lowpart (SImode, operands[1]);
16875 [(set (match_operand 0 "register_operand" "")
16876 (not (match_operand 1 "register_operand" "")))]
16877 "! TARGET_PARTIAL_REG_STALL && reload_completed
16878 && (GET_MODE (operands[0]) == HImode
16879 || (GET_MODE (operands[0]) == QImode
16880 && (TARGET_PROMOTE_QImode
16881 || optimize_insn_for_size_p ())))"
16882 [(set (match_dup 0)
16883 (not:SI (match_dup 1)))]
16885 operands[0] = gen_lowpart (SImode, operands[0]);
16886 operands[1] = gen_lowpart (SImode, operands[1]);
16889 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16890 ;; transform a complex memory operation into two memory to register operations.
16892 ;; Don't push memory operands
16894 [(set (match_operand:SWI 0 "push_operand" "")
16895 (match_operand:SWI 1 "memory_operand" ""))
16896 (match_scratch:SWI 2 "<r>")]
16897 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16898 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16899 [(set (match_dup 2) (match_dup 1))
16900 (set (match_dup 0) (match_dup 2))])
16902 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16905 [(set (match_operand:SF 0 "push_operand" "")
16906 (match_operand:SF 1 "memory_operand" ""))
16907 (match_scratch:SF 2 "r")]
16908 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16909 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16910 [(set (match_dup 2) (match_dup 1))
16911 (set (match_dup 0) (match_dup 2))])
16913 ;; Don't move an immediate directly to memory when the instruction
16916 [(match_scratch:SWI124 1 "<r>")
16917 (set (match_operand:SWI124 0 "memory_operand" "")
16919 "optimize_insn_for_speed_p ()
16920 && !TARGET_USE_MOV0
16921 && TARGET_SPLIT_LONG_MOVES
16922 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16923 && peep2_regno_dead_p (0, FLAGS_REG)"
16924 [(parallel [(set (match_dup 2) (const_int 0))
16925 (clobber (reg:CC FLAGS_REG))])
16926 (set (match_dup 0) (match_dup 1))]
16927 "operands[2] = gen_lowpart (SImode, operands[1]);")
16930 [(match_scratch:SWI124 2 "<r>")
16931 (set (match_operand:SWI124 0 "memory_operand" "")
16932 (match_operand:SWI124 1 "immediate_operand" ""))]
16933 "optimize_insn_for_speed_p ()
16934 && TARGET_SPLIT_LONG_MOVES
16935 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16936 [(set (match_dup 2) (match_dup 1))
16937 (set (match_dup 0) (match_dup 2))])
16939 ;; Don't compare memory with zero, load and use a test instead.
16941 [(set (match_operand 0 "flags_reg_operand" "")
16942 (match_operator 1 "compare_operator"
16943 [(match_operand:SI 2 "memory_operand" "")
16945 (match_scratch:SI 3 "r")]
16946 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16947 [(set (match_dup 3) (match_dup 2))
16948 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16950 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16951 ;; Don't split NOTs with a displacement operand, because resulting XOR
16952 ;; will not be pairable anyway.
16954 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16955 ;; represented using a modRM byte. The XOR replacement is long decoded,
16956 ;; so this split helps here as well.
16958 ;; Note: Can't do this as a regular split because we can't get proper
16959 ;; lifetime information then.
16962 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
16963 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
16964 "optimize_insn_for_speed_p ()
16965 && ((TARGET_NOT_UNPAIRABLE
16966 && (!MEM_P (operands[0])
16967 || !memory_displacement_operand (operands[0], <MODE>mode)))
16968 || (TARGET_NOT_VECTORMODE
16969 && long_memory_operand (operands[0], <MODE>mode)))
16970 && peep2_regno_dead_p (0, FLAGS_REG)"
16971 [(parallel [(set (match_dup 0)
16972 (xor:SWI124 (match_dup 1) (const_int -1)))
16973 (clobber (reg:CC FLAGS_REG))])])
16975 ;; Non pairable "test imm, reg" instructions can be translated to
16976 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
16977 ;; byte opcode instead of two, have a short form for byte operands),
16978 ;; so do it for other CPUs as well. Given that the value was dead,
16979 ;; this should not create any new dependencies. Pass on the sub-word
16980 ;; versions if we're concerned about partial register stalls.
16983 [(set (match_operand 0 "flags_reg_operand" "")
16984 (match_operator 1 "compare_operator"
16985 [(and:SI (match_operand:SI 2 "register_operand" "")
16986 (match_operand:SI 3 "immediate_operand" ""))
16988 "ix86_match_ccmode (insn, CCNOmode)
16989 && (true_regnum (operands[2]) != AX_REG
16990 || satisfies_constraint_K (operands[3]))
16991 && peep2_reg_dead_p (1, operands[2])"
16993 [(set (match_dup 0)
16994 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16997 (and:SI (match_dup 2) (match_dup 3)))])])
16999 ;; We don't need to handle HImode case, because it will be promoted to SImode
17000 ;; on ! TARGET_PARTIAL_REG_STALL
17003 [(set (match_operand 0 "flags_reg_operand" "")
17004 (match_operator 1 "compare_operator"
17005 [(and:QI (match_operand:QI 2 "register_operand" "")
17006 (match_operand:QI 3 "immediate_operand" ""))
17008 "! TARGET_PARTIAL_REG_STALL
17009 && ix86_match_ccmode (insn, CCNOmode)
17010 && true_regnum (operands[2]) != AX_REG
17011 && peep2_reg_dead_p (1, operands[2])"
17013 [(set (match_dup 0)
17014 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17017 (and:QI (match_dup 2) (match_dup 3)))])])
17020 [(set (match_operand 0 "flags_reg_operand" "")
17021 (match_operator 1 "compare_operator"
17024 (match_operand 2 "ext_register_operand" "")
17027 (match_operand 3 "const_int_operand" ""))
17029 "! TARGET_PARTIAL_REG_STALL
17030 && ix86_match_ccmode (insn, CCNOmode)
17031 && true_regnum (operands[2]) != AX_REG
17032 && peep2_reg_dead_p (1, operands[2])"
17033 [(parallel [(set (match_dup 0)
17042 (set (zero_extract:SI (match_dup 2)
17050 (match_dup 3)))])])
17052 ;; Don't do logical operations with memory inputs.
17054 [(match_scratch:SI 2 "r")
17055 (parallel [(set (match_operand:SI 0 "register_operand" "")
17056 (match_operator:SI 3 "arith_or_logical_operator"
17058 (match_operand:SI 1 "memory_operand" "")]))
17059 (clobber (reg:CC FLAGS_REG))])]
17060 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17061 [(set (match_dup 2) (match_dup 1))
17062 (parallel [(set (match_dup 0)
17063 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17064 (clobber (reg:CC FLAGS_REG))])])
17067 [(match_scratch:SI 2 "r")
17068 (parallel [(set (match_operand:SI 0 "register_operand" "")
17069 (match_operator:SI 3 "arith_or_logical_operator"
17070 [(match_operand:SI 1 "memory_operand" "")
17072 (clobber (reg:CC FLAGS_REG))])]
17073 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17074 [(set (match_dup 2) (match_dup 1))
17075 (parallel [(set (match_dup 0)
17076 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17077 (clobber (reg:CC FLAGS_REG))])])
17079 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17080 ;; refers to the destination of the load!
17083 [(set (match_operand:SI 0 "register_operand" "")
17084 (match_operand:SI 1 "register_operand" ""))
17085 (parallel [(set (match_dup 0)
17086 (match_operator:SI 3 "commutative_operator"
17088 (match_operand:SI 2 "memory_operand" "")]))
17089 (clobber (reg:CC FLAGS_REG))])]
17090 "REGNO (operands[0]) != REGNO (operands[1])
17091 && GENERAL_REGNO_P (REGNO (operands[0]))
17092 && GENERAL_REGNO_P (REGNO (operands[1]))"
17093 [(set (match_dup 0) (match_dup 4))
17094 (parallel [(set (match_dup 0)
17095 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17096 (clobber (reg:CC FLAGS_REG))])]
17097 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17100 [(set (match_operand 0 "register_operand" "")
17101 (match_operand 1 "register_operand" ""))
17103 (match_operator 3 "commutative_operator"
17105 (match_operand 2 "memory_operand" "")]))]
17106 "REGNO (operands[0]) != REGNO (operands[1])
17107 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17108 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17109 [(set (match_dup 0) (match_dup 2))
17111 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17113 ; Don't do logical operations with memory outputs
17115 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17116 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17117 ; the same decoder scheduling characteristics as the original.
17120 [(match_scratch:SI 2 "r")
17121 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17122 (match_operator:SI 3 "arith_or_logical_operator"
17124 (match_operand:SI 1 "nonmemory_operand" "")]))
17125 (clobber (reg:CC FLAGS_REG))])]
17126 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17127 /* Do not split stack checking probes. */
17128 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17129 [(set (match_dup 2) (match_dup 0))
17130 (parallel [(set (match_dup 2)
17131 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17132 (clobber (reg:CC FLAGS_REG))])
17133 (set (match_dup 0) (match_dup 2))])
17136 [(match_scratch:SI 2 "r")
17137 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17138 (match_operator:SI 3 "arith_or_logical_operator"
17139 [(match_operand:SI 1 "nonmemory_operand" "")
17141 (clobber (reg:CC FLAGS_REG))])]
17142 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17143 /* Do not split stack checking probes. */
17144 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17145 [(set (match_dup 2) (match_dup 0))
17146 (parallel [(set (match_dup 2)
17147 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17148 (clobber (reg:CC FLAGS_REG))])
17149 (set (match_dup 0) (match_dup 2))])
17151 ;; Attempt to use arith or logical operations with memory outputs with
17152 ;; setting of flags.
17154 [(set (match_operand:SWI 0 "register_operand" "")
17155 (match_operand:SWI 1 "memory_operand" ""))
17156 (parallel [(set (match_dup 0)
17157 (match_operator:SWI 3 "plusminuslogic_operator"
17159 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17160 (clobber (reg:CC FLAGS_REG))])
17161 (set (match_dup 1) (match_dup 0))
17162 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17163 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17164 && peep2_reg_dead_p (4, operands[0])
17165 && !reg_overlap_mentioned_p (operands[0], operands[1])
17166 && (<MODE>mode != QImode
17167 || immediate_operand (operands[2], QImode)
17168 || q_regs_operand (operands[2], QImode))
17169 && ix86_match_ccmode (peep2_next_insn (3),
17170 (GET_CODE (operands[3]) == PLUS
17171 || GET_CODE (operands[3]) == MINUS)
17172 ? CCGOCmode : CCNOmode)"
17173 [(parallel [(set (match_dup 4) (match_dup 5))
17174 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17175 (match_dup 2)]))])]
17177 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17178 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17179 copy_rtx (operands[1]),
17180 copy_rtx (operands[2]));
17181 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17182 operands[5], const0_rtx);
17186 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17187 (match_operator:SWI 2 "plusminuslogic_operator"
17189 (match_operand:SWI 1 "memory_operand" "")]))
17190 (clobber (reg:CC FLAGS_REG))])
17191 (set (match_dup 1) (match_dup 0))
17192 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17193 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17194 && GET_CODE (operands[2]) != MINUS
17195 && peep2_reg_dead_p (3, operands[0])
17196 && !reg_overlap_mentioned_p (operands[0], operands[1])
17197 && ix86_match_ccmode (peep2_next_insn (2),
17198 GET_CODE (operands[2]) == PLUS
17199 ? CCGOCmode : CCNOmode)"
17200 [(parallel [(set (match_dup 3) (match_dup 4))
17201 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17202 (match_dup 0)]))])]
17204 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17205 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17206 copy_rtx (operands[1]),
17207 copy_rtx (operands[0]));
17208 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17209 operands[4], const0_rtx);
17213 [(set (match_operand:SWI12 0 "register_operand" "")
17214 (match_operand:SWI12 1 "memory_operand" ""))
17215 (parallel [(set (match_operand:SI 4 "register_operand" "")
17216 (match_operator:SI 3 "plusminuslogic_operator"
17218 (match_operand:SI 2 "nonmemory_operand" "")]))
17219 (clobber (reg:CC FLAGS_REG))])
17220 (set (match_dup 1) (match_dup 0))
17221 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17222 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17223 && REG_P (operands[0]) && REG_P (operands[4])
17224 && REGNO (operands[0]) == REGNO (operands[4])
17225 && peep2_reg_dead_p (4, operands[0])
17226 && (<MODE>mode != QImode
17227 || immediate_operand (operands[2], SImode)
17228 || q_regs_operand (operands[2], SImode))
17229 && !reg_overlap_mentioned_p (operands[0], operands[1])
17230 && ix86_match_ccmode (peep2_next_insn (3),
17231 (GET_CODE (operands[3]) == PLUS
17232 || GET_CODE (operands[3]) == MINUS)
17233 ? CCGOCmode : CCNOmode)"
17234 [(parallel [(set (match_dup 4) (match_dup 5))
17235 (set (match_dup 1) (match_dup 6))])]
17237 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17238 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17239 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17240 copy_rtx (operands[1]), operands[2]);
17241 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17242 operands[5], const0_rtx);
17243 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17244 copy_rtx (operands[1]),
17245 copy_rtx (operands[2]));
17248 ;; Attempt to always use XOR for zeroing registers.
17250 [(set (match_operand 0 "register_operand" "")
17251 (match_operand 1 "const0_operand" ""))]
17252 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17253 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17254 && GENERAL_REG_P (operands[0])
17255 && peep2_regno_dead_p (0, FLAGS_REG)"
17256 [(parallel [(set (match_dup 0) (const_int 0))
17257 (clobber (reg:CC FLAGS_REG))])]
17258 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17261 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17263 "(GET_MODE (operands[0]) == QImode
17264 || GET_MODE (operands[0]) == HImode)
17265 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17266 && peep2_regno_dead_p (0, FLAGS_REG)"
17267 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17268 (clobber (reg:CC FLAGS_REG))])])
17270 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17272 [(set (match_operand:SWI248 0 "register_operand" "")
17274 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17275 && peep2_regno_dead_p (0, FLAGS_REG)"
17276 [(parallel [(set (match_dup 0) (const_int -1))
17277 (clobber (reg:CC FLAGS_REG))])]
17279 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17280 operands[0] = gen_lowpart (SImode, operands[0]);
17283 ;; Attempt to convert simple lea to add/shift.
17284 ;; These can be created by move expanders.
17287 [(set (match_operand:SWI48 0 "register_operand" "")
17288 (plus:SWI48 (match_dup 0)
17289 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17290 "peep2_regno_dead_p (0, FLAGS_REG)"
17291 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17292 (clobber (reg:CC FLAGS_REG))])])
17295 [(set (match_operand:SI 0 "register_operand" "")
17296 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17297 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17299 && peep2_regno_dead_p (0, FLAGS_REG)
17300 && REGNO (operands[0]) == REGNO (operands[1])"
17301 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17302 (clobber (reg:CC FLAGS_REG))])]
17303 "operands[2] = gen_lowpart (SImode, operands[2]);")
17306 [(set (match_operand:SWI48 0 "register_operand" "")
17307 (mult:SWI48 (match_dup 0)
17308 (match_operand:SWI48 1 "const_int_operand" "")))]
17309 "exact_log2 (INTVAL (operands[1])) >= 0
17310 && peep2_regno_dead_p (0, FLAGS_REG)"
17311 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17312 (clobber (reg:CC FLAGS_REG))])]
17313 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17316 [(set (match_operand:SI 0 "register_operand" "")
17317 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17318 (match_operand:DI 2 "const_int_operand" "")) 0))]
17320 && exact_log2 (INTVAL (operands[2])) >= 0
17321 && REGNO (operands[0]) == REGNO (operands[1])
17322 && peep2_regno_dead_p (0, FLAGS_REG)"
17323 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17324 (clobber (reg:CC FLAGS_REG))])]
17325 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17327 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17328 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17329 ;; On many CPUs it is also faster, since special hardware to avoid esp
17330 ;; dependencies is present.
17332 ;; While some of these conversions may be done using splitters, we use
17333 ;; peepholes in order to allow combine_stack_adjustments pass to see
17334 ;; nonobfuscated RTL.
17336 ;; Convert prologue esp subtractions to push.
17337 ;; We need register to push. In order to keep verify_flow_info happy we have
17339 ;; - use scratch and clobber it in order to avoid dependencies
17340 ;; - use already live register
17341 ;; We can't use the second way right now, since there is no reliable way how to
17342 ;; verify that given register is live. First choice will also most likely in
17343 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17344 ;; call clobbered registers are dead. We may want to use base pointer as an
17345 ;; alternative when no register is available later.
17348 [(match_scratch:P 1 "r")
17349 (parallel [(set (reg:P SP_REG)
17350 (plus:P (reg:P SP_REG)
17351 (match_operand:P 0 "const_int_operand" "")))
17352 (clobber (reg:CC FLAGS_REG))
17353 (clobber (mem:BLK (scratch)))])]
17354 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17355 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17356 [(clobber (match_dup 1))
17357 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17358 (clobber (mem:BLK (scratch)))])])
17361 [(match_scratch:P 1 "r")
17362 (parallel [(set (reg:P SP_REG)
17363 (plus:P (reg:P SP_REG)
17364 (match_operand:P 0 "const_int_operand" "")))
17365 (clobber (reg:CC FLAGS_REG))
17366 (clobber (mem:BLK (scratch)))])]
17367 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17368 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17369 [(clobber (match_dup 1))
17370 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17371 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17372 (clobber (mem:BLK (scratch)))])])
17374 ;; Convert esp subtractions to push.
17376 [(match_scratch:P 1 "r")
17377 (parallel [(set (reg:P SP_REG)
17378 (plus:P (reg:P SP_REG)
17379 (match_operand:P 0 "const_int_operand" "")))
17380 (clobber (reg:CC FLAGS_REG))])]
17381 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17382 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17383 [(clobber (match_dup 1))
17384 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17387 [(match_scratch:P 1 "r")
17388 (parallel [(set (reg:P SP_REG)
17389 (plus:P (reg:P SP_REG)
17390 (match_operand:P 0 "const_int_operand" "")))
17391 (clobber (reg:CC FLAGS_REG))])]
17392 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17393 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17394 [(clobber (match_dup 1))
17395 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17396 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17398 ;; Convert epilogue deallocator to pop.
17400 [(match_scratch:P 1 "r")
17401 (parallel [(set (reg:P SP_REG)
17402 (plus:P (reg:P SP_REG)
17403 (match_operand:P 0 "const_int_operand" "")))
17404 (clobber (reg:CC FLAGS_REG))
17405 (clobber (mem:BLK (scratch)))])]
17406 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17407 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17408 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17409 (clobber (mem:BLK (scratch)))])])
17411 ;; Two pops case is tricky, since pop causes dependency
17412 ;; on destination register. We use two registers if available.
17414 [(match_scratch:P 1 "r")
17415 (match_scratch:P 2 "r")
17416 (parallel [(set (reg:P SP_REG)
17417 (plus:P (reg:P SP_REG)
17418 (match_operand:P 0 "const_int_operand" "")))
17419 (clobber (reg:CC FLAGS_REG))
17420 (clobber (mem:BLK (scratch)))])]
17421 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17422 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17423 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17424 (clobber (mem:BLK (scratch)))])
17425 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17428 [(match_scratch:P 1 "r")
17429 (parallel [(set (reg:P SP_REG)
17430 (plus:P (reg:P SP_REG)
17431 (match_operand:P 0 "const_int_operand" "")))
17432 (clobber (reg:CC FLAGS_REG))
17433 (clobber (mem:BLK (scratch)))])]
17434 "optimize_insn_for_size_p ()
17435 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17436 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17437 (clobber (mem:BLK (scratch)))])
17438 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17440 ;; Convert esp additions to pop.
17442 [(match_scratch:P 1 "r")
17443 (parallel [(set (reg:P SP_REG)
17444 (plus:P (reg:P SP_REG)
17445 (match_operand:P 0 "const_int_operand" "")))
17446 (clobber (reg:CC FLAGS_REG))])]
17447 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17448 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17450 ;; Two pops case is tricky, since pop causes dependency
17451 ;; on destination register. We use two registers if available.
17453 [(match_scratch:P 1 "r")
17454 (match_scratch:P 2 "r")
17455 (parallel [(set (reg:P SP_REG)
17456 (plus:P (reg:P SP_REG)
17457 (match_operand:P 0 "const_int_operand" "")))
17458 (clobber (reg:CC FLAGS_REG))])]
17459 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17460 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17461 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17464 [(match_scratch:P 1 "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 "optimize_insn_for_size_p ()
17470 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17471 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17472 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17474 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17475 ;; required and register dies. Similarly for 128 to -128.
17477 [(set (match_operand 0 "flags_reg_operand" "")
17478 (match_operator 1 "compare_operator"
17479 [(match_operand 2 "register_operand" "")
17480 (match_operand 3 "const_int_operand" "")]))]
17481 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17482 && incdec_operand (operands[3], GET_MODE (operands[3])))
17483 || (!TARGET_FUSE_CMP_AND_BRANCH
17484 && INTVAL (operands[3]) == 128))
17485 && ix86_match_ccmode (insn, CCGCmode)
17486 && peep2_reg_dead_p (1, operands[2])"
17487 [(parallel [(set (match_dup 0)
17488 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17489 (clobber (match_dup 2))])])
17491 ;; Convert imul by three, five and nine into lea
17494 [(set (match_operand:SWI48 0 "register_operand" "")
17495 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17496 (match_operand:SWI48 2 "const359_operand" "")))
17497 (clobber (reg:CC FLAGS_REG))])]
17498 "!TARGET_PARTIAL_REG_STALL
17499 || <MODE>mode == SImode
17500 || optimize_function_for_size_p (cfun)"
17501 [(set (match_dup 0)
17502 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17504 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17508 [(set (match_operand:SWI48 0 "register_operand" "")
17509 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17510 (match_operand:SWI48 2 "const359_operand" "")))
17511 (clobber (reg:CC FLAGS_REG))])]
17512 "optimize_insn_for_speed_p ()
17513 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17514 [(set (match_dup 0) (match_dup 1))
17516 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17518 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17520 ;; imul $32bit_imm, mem, reg is vector decoded, while
17521 ;; imul $32bit_imm, reg, reg is direct decoded.
17523 [(match_scratch:SWI48 3 "r")
17524 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17525 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17526 (match_operand:SWI48 2 "immediate_operand" "")))
17527 (clobber (reg:CC FLAGS_REG))])]
17528 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17529 && !satisfies_constraint_K (operands[2])"
17530 [(set (match_dup 3) (match_dup 1))
17531 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17532 (clobber (reg:CC FLAGS_REG))])])
17535 [(match_scratch:SI 3 "r")
17536 (parallel [(set (match_operand:DI 0 "register_operand" "")
17538 (mult:SI (match_operand:SI 1 "memory_operand" "")
17539 (match_operand:SI 2 "immediate_operand" ""))))
17540 (clobber (reg:CC FLAGS_REG))])]
17542 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17543 && !satisfies_constraint_K (operands[2])"
17544 [(set (match_dup 3) (match_dup 1))
17545 (parallel [(set (match_dup 0)
17546 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17547 (clobber (reg:CC FLAGS_REG))])])
17549 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17550 ;; Convert it into imul reg, reg
17551 ;; It would be better to force assembler to encode instruction using long
17552 ;; immediate, but there is apparently no way to do so.
17554 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17556 (match_operand:SWI248 1 "nonimmediate_operand" "")
17557 (match_operand:SWI248 2 "const_int_operand" "")))
17558 (clobber (reg:CC FLAGS_REG))])
17559 (match_scratch:SWI248 3 "r")]
17560 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17561 && satisfies_constraint_K (operands[2])"
17562 [(set (match_dup 3) (match_dup 2))
17563 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17564 (clobber (reg:CC FLAGS_REG))])]
17566 if (!rtx_equal_p (operands[0], operands[1]))
17567 emit_move_insn (operands[0], operands[1]);
17570 ;; After splitting up read-modify operations, array accesses with memory
17571 ;; operands might end up in form:
17573 ;; movl 4(%esp), %edx
17575 ;; instead of pre-splitting:
17577 ;; addl 4(%esp), %eax
17579 ;; movl 4(%esp), %edx
17580 ;; leal (%edx,%eax,4), %eax
17583 [(match_scratch:P 5 "r")
17584 (parallel [(set (match_operand 0 "register_operand" "")
17585 (ashift (match_operand 1 "register_operand" "")
17586 (match_operand 2 "const_int_operand" "")))
17587 (clobber (reg:CC FLAGS_REG))])
17588 (parallel [(set (match_operand 3 "register_operand" "")
17589 (plus (match_dup 0)
17590 (match_operand 4 "x86_64_general_operand" "")))
17591 (clobber (reg:CC FLAGS_REG))])]
17592 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17593 /* Validate MODE for lea. */
17594 && ((!TARGET_PARTIAL_REG_STALL
17595 && (GET_MODE (operands[0]) == QImode
17596 || GET_MODE (operands[0]) == HImode))
17597 || GET_MODE (operands[0]) == SImode
17598 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17599 && (rtx_equal_p (operands[0], operands[3])
17600 || peep2_reg_dead_p (2, operands[0]))
17601 /* We reorder load and the shift. */
17602 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17603 [(set (match_dup 5) (match_dup 4))
17604 (set (match_dup 0) (match_dup 1))]
17606 enum machine_mode op1mode = GET_MODE (operands[1]);
17607 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17608 int scale = 1 << INTVAL (operands[2]);
17609 rtx index = gen_lowpart (Pmode, operands[1]);
17610 rtx base = gen_lowpart (Pmode, operands[5]);
17611 rtx dest = gen_lowpart (mode, operands[3]);
17613 operands[1] = gen_rtx_PLUS (Pmode, base,
17614 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17615 operands[5] = base;
17617 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17618 if (op1mode != Pmode)
17619 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17620 operands[0] = dest;
17623 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17624 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17625 ;; caught for use by garbage collectors and the like. Using an insn that
17626 ;; maps to SIGILL makes it more likely the program will rightfully die.
17627 ;; Keeping with tradition, "6" is in honor of #UD.
17628 (define_insn "trap"
17629 [(trap_if (const_int 1) (const_int 6))]
17631 { return ASM_SHORT "0x0b0f"; }
17632 [(set_attr "length" "2")])
17634 (define_expand "prefetch"
17635 [(prefetch (match_operand 0 "address_operand" "")
17636 (match_operand:SI 1 "const_int_operand" "")
17637 (match_operand:SI 2 "const_int_operand" ""))]
17638 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17640 int rw = INTVAL (operands[1]);
17641 int locality = INTVAL (operands[2]);
17643 gcc_assert (rw == 0 || rw == 1);
17644 gcc_assert (IN_RANGE (locality, 0, 3));
17646 if (TARGET_PREFETCHW && rw)
17647 operands[2] = GEN_INT (3);
17648 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17649 supported by SSE counterpart or the SSE prefetch is not available
17650 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17652 else if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17653 operands[2] = GEN_INT (3);
17655 operands[1] = const0_rtx;
17658 (define_insn "*prefetch_sse"
17659 [(prefetch (match_operand 0 "address_operand" "p")
17661 (match_operand:SI 1 "const_int_operand" ""))]
17662 "TARGET_PREFETCH_SSE"
17664 static const char * const patterns[4] = {
17665 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17668 int locality = INTVAL (operands[1]);
17669 gcc_assert (IN_RANGE (locality, 0, 3));
17671 return patterns[locality];
17673 [(set_attr "type" "sse")
17674 (set_attr "atom_sse_attr" "prefetch")
17675 (set (attr "length_address")
17676 (symbol_ref "memory_address_length (operands[0], false)"))
17677 (set_attr "memory" "none")])
17679 (define_insn "*prefetch_3dnow"
17680 [(prefetch (match_operand 0 "address_operand" "p")
17681 (match_operand:SI 1 "const_int_operand" "n")
17683 "TARGET_3DNOW || TARGET_PREFETCHW"
17685 if (INTVAL (operands[1]) == 0)
17686 return "prefetch\t%a0";
17688 return "prefetchw\t%a0";
17690 [(set_attr "type" "mmx")
17691 (set (attr "length_address")
17692 (symbol_ref "memory_address_length (operands[0], false)"))
17693 (set_attr "memory" "none")])
17695 (define_expand "stack_protect_set"
17696 [(match_operand 0 "memory_operand" "")
17697 (match_operand 1 "memory_operand" "")]
17698 "!TARGET_HAS_BIONIC"
17700 rtx (*insn)(rtx, rtx);
17702 #ifdef TARGET_THREAD_SSP_OFFSET
17703 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17704 insn = (TARGET_LP64
17705 ? gen_stack_tls_protect_set_di
17706 : gen_stack_tls_protect_set_si);
17708 insn = (TARGET_LP64
17709 ? gen_stack_protect_set_di
17710 : gen_stack_protect_set_si);
17713 emit_insn (insn (operands[0], operands[1]));
17717 (define_insn "stack_protect_set_<mode>"
17718 [(set (match_operand:PTR 0 "memory_operand" "=m")
17719 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17721 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17722 (clobber (reg:CC FLAGS_REG))]
17723 "!TARGET_HAS_BIONIC"
17724 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17725 [(set_attr "type" "multi")])
17727 (define_insn "stack_tls_protect_set_<mode>"
17728 [(set (match_operand:PTR 0 "memory_operand" "=m")
17729 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17730 UNSPEC_SP_TLS_SET))
17731 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17732 (clobber (reg:CC FLAGS_REG))]
17734 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17735 [(set_attr "type" "multi")])
17737 (define_expand "stack_protect_test"
17738 [(match_operand 0 "memory_operand" "")
17739 (match_operand 1 "memory_operand" "")
17740 (match_operand 2 "" "")]
17741 "!TARGET_HAS_BIONIC"
17743 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17745 rtx (*insn)(rtx, rtx, rtx);
17747 #ifdef TARGET_THREAD_SSP_OFFSET
17748 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17749 insn = (TARGET_LP64
17750 ? gen_stack_tls_protect_test_di
17751 : gen_stack_tls_protect_test_si);
17753 insn = (TARGET_LP64
17754 ? gen_stack_protect_test_di
17755 : gen_stack_protect_test_si);
17758 emit_insn (insn (flags, operands[0], operands[1]));
17760 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17761 flags, const0_rtx, operands[2]));
17765 (define_insn "stack_protect_test_<mode>"
17766 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17767 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17768 (match_operand:PTR 2 "memory_operand" "m")]
17770 (clobber (match_scratch:PTR 3 "=&r"))]
17771 "!TARGET_HAS_BIONIC"
17772 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17773 [(set_attr "type" "multi")])
17775 (define_insn "stack_tls_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 "const_int_operand" "i")]
17779 UNSPEC_SP_TLS_TEST))
17780 (clobber (match_scratch:PTR 3 "=r"))]
17782 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17783 [(set_attr "type" "multi")])
17785 (define_insn "sse4_2_crc32<mode>"
17786 [(set (match_operand:SI 0 "register_operand" "=r")
17788 [(match_operand:SI 1 "register_operand" "0")
17789 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17791 "TARGET_SSE4_2 || TARGET_CRC32"
17792 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17793 [(set_attr "type" "sselog1")
17794 (set_attr "prefix_rep" "1")
17795 (set_attr "prefix_extra" "1")
17796 (set (attr "prefix_data16")
17797 (if_then_else (match_operand:HI 2 "" "")
17799 (const_string "*")))
17800 (set (attr "prefix_rex")
17801 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17803 (const_string "*")))
17804 (set_attr "mode" "SI")])
17806 (define_insn "sse4_2_crc32di"
17807 [(set (match_operand:DI 0 "register_operand" "=r")
17809 [(match_operand:DI 1 "register_operand" "0")
17810 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17812 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17813 "crc32{q}\t{%2, %0|%0, %2}"
17814 [(set_attr "type" "sselog1")
17815 (set_attr "prefix_rep" "1")
17816 (set_attr "prefix_extra" "1")
17817 (set_attr "mode" "DI")])
17819 (define_expand "rdpmc"
17820 [(match_operand:DI 0 "register_operand" "")
17821 (match_operand:SI 1 "register_operand" "")]
17824 rtx reg = gen_reg_rtx (DImode);
17827 /* Force operand 1 into ECX. */
17828 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17829 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17830 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17835 rtvec vec = rtvec_alloc (2);
17836 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17837 rtx upper = gen_reg_rtx (DImode);
17838 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17839 gen_rtvec (1, const0_rtx),
17841 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17842 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17844 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17845 NULL, 1, OPTAB_DIRECT);
17846 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17850 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17851 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17855 (define_insn "*rdpmc"
17856 [(set (match_operand:DI 0 "register_operand" "=A")
17857 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17861 [(set_attr "type" "other")
17862 (set_attr "length" "2")])
17864 (define_insn "*rdpmc_rex64"
17865 [(set (match_operand:DI 0 "register_operand" "=a")
17866 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17868 (set (match_operand:DI 1 "register_operand" "=d")
17869 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17872 [(set_attr "type" "other")
17873 (set_attr "length" "2")])
17875 (define_expand "rdtsc"
17876 [(set (match_operand:DI 0 "register_operand" "")
17877 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17882 rtvec vec = rtvec_alloc (2);
17883 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17884 rtx upper = gen_reg_rtx (DImode);
17885 rtx lower = gen_reg_rtx (DImode);
17886 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17887 gen_rtvec (1, const0_rtx),
17889 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17890 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17892 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17893 NULL, 1, OPTAB_DIRECT);
17894 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17896 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17901 (define_insn "*rdtsc"
17902 [(set (match_operand:DI 0 "register_operand" "=A")
17903 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17906 [(set_attr "type" "other")
17907 (set_attr "length" "2")])
17909 (define_insn "*rdtsc_rex64"
17910 [(set (match_operand:DI 0 "register_operand" "=a")
17911 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17912 (set (match_operand:DI 1 "register_operand" "=d")
17913 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17916 [(set_attr "type" "other")
17917 (set_attr "length" "2")])
17919 (define_expand "rdtscp"
17920 [(match_operand:DI 0 "register_operand" "")
17921 (match_operand:SI 1 "memory_operand" "")]
17924 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17925 gen_rtvec (1, const0_rtx),
17927 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17928 gen_rtvec (1, const0_rtx),
17930 rtx reg = gen_reg_rtx (DImode);
17931 rtx tmp = gen_reg_rtx (SImode);
17935 rtvec vec = rtvec_alloc (3);
17936 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17937 rtx upper = gen_reg_rtx (DImode);
17938 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17939 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17940 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17942 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17943 NULL, 1, OPTAB_DIRECT);
17944 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17949 rtvec vec = rtvec_alloc (2);
17950 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17951 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17952 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17955 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17956 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
17960 (define_insn "*rdtscp"
17961 [(set (match_operand:DI 0 "register_operand" "=A")
17962 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17963 (set (match_operand:SI 1 "register_operand" "=c")
17964 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17967 [(set_attr "type" "other")
17968 (set_attr "length" "3")])
17970 (define_insn "*rdtscp_rex64"
17971 [(set (match_operand:DI 0 "register_operand" "=a")
17972 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17973 (set (match_operand:DI 1 "register_operand" "=d")
17974 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
17975 (set (match_operand:SI 2 "register_operand" "=c")
17976 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
17979 [(set_attr "type" "other")
17980 (set_attr "length" "3")])
17982 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17984 ;; LWP instructions
17986 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
17988 (define_expand "lwp_llwpcb"
17989 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
17990 UNSPECV_LLWP_INTRINSIC)]
17993 (define_insn "*lwp_llwpcb<mode>1"
17994 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
17995 UNSPECV_LLWP_INTRINSIC)]
17998 [(set_attr "type" "lwp")
17999 (set_attr "mode" "<MODE>")
18000 (set_attr "length" "5")])
18002 (define_expand "lwp_slwpcb"
18003 [(set (match_operand 0 "register_operand" "=r")
18004 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18009 insn = (TARGET_64BIT
18011 : gen_lwp_slwpcbsi);
18013 emit_insn (insn (operands[0]));
18017 (define_insn "lwp_slwpcb<mode>"
18018 [(set (match_operand:P 0 "register_operand" "=r")
18019 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18022 [(set_attr "type" "lwp")
18023 (set_attr "mode" "<MODE>")
18024 (set_attr "length" "5")])
18026 (define_expand "lwp_lwpval<mode>3"
18027 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18028 (match_operand:SI 2 "nonimmediate_operand" "rm")
18029 (match_operand:SI 3 "const_int_operand" "i")]
18030 UNSPECV_LWPVAL_INTRINSIC)]
18032 ;; Avoid unused variable warning.
18033 "(void) operands[0];")
18035 (define_insn "*lwp_lwpval<mode>3_1"
18036 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18037 (match_operand:SI 1 "nonimmediate_operand" "rm")
18038 (match_operand:SI 2 "const_int_operand" "i")]
18039 UNSPECV_LWPVAL_INTRINSIC)]
18041 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18042 [(set_attr "type" "lwp")
18043 (set_attr "mode" "<MODE>")
18044 (set (attr "length")
18045 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18047 (define_expand "lwp_lwpins<mode>3"
18048 [(set (reg:CCC FLAGS_REG)
18049 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18050 (match_operand:SI 2 "nonimmediate_operand" "rm")
18051 (match_operand:SI 3 "const_int_operand" "i")]
18052 UNSPECV_LWPINS_INTRINSIC))
18053 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18054 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18057 (define_insn "*lwp_lwpins<mode>3_1"
18058 [(set (reg:CCC FLAGS_REG)
18059 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18060 (match_operand:SI 1 "nonimmediate_operand" "rm")
18061 (match_operand:SI 2 "const_int_operand" "i")]
18062 UNSPECV_LWPINS_INTRINSIC))]
18064 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18065 [(set_attr "type" "lwp")
18066 (set_attr "mode" "<MODE>")
18067 (set (attr "length")
18068 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18070 (define_insn "rdfsbase<mode>"
18071 [(set (match_operand:SWI48 0 "register_operand" "=r")
18072 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18073 "TARGET_64BIT && TARGET_FSGSBASE"
18075 [(set_attr "type" "other")
18076 (set_attr "prefix_extra" "2")])
18078 (define_insn "rdgsbase<mode>"
18079 [(set (match_operand:SWI48 0 "register_operand" "=r")
18080 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18081 "TARGET_64BIT && TARGET_FSGSBASE"
18083 [(set_attr "type" "other")
18084 (set_attr "prefix_extra" "2")])
18086 (define_insn "wrfsbase<mode>"
18087 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18089 "TARGET_64BIT && TARGET_FSGSBASE"
18091 [(set_attr "type" "other")
18092 (set_attr "prefix_extra" "2")])
18094 (define_insn "wrgsbase<mode>"
18095 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18097 "TARGET_64BIT && TARGET_FSGSBASE"
18099 [(set_attr "type" "other")
18100 (set_attr "prefix_extra" "2")])
18102 (define_insn "rdrand<mode>_1"
18103 [(set (match_operand:SWI248 0 "register_operand" "=r")
18104 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18105 (set (reg:CCC FLAGS_REG)
18106 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18109 [(set_attr "type" "other")
18110 (set_attr "prefix_extra" "1")])
18112 (define_expand "pause"
18113 [(set (match_dup 0)
18114 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18117 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18118 MEM_VOLATILE_P (operands[0]) = 1;
18121 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18122 ;; They have the same encoding.
18123 (define_insn "*pause"
18124 [(set (match_operand:BLK 0 "" "")
18125 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18128 [(set_attr "length" "2")
18129 (set_attr "memory" "unknown")])
18133 (include "sync.md")