1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; E -- print address with DImode register names if TARGET_64BIT.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; p -- print raw symbol name.
58 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
59 ;; & -- print some in-use local-dynamic symbol name.
60 ;; H -- print a memory address offset by 8; used for sse high-parts
61 ;; Y -- print condition for XOP pcom* instruction.
62 ;; + -- print a branch hint as 'cs' or 'ds' prefix
63 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
64 ;; @ -- print a segment register of thread base pointer load
66 (define_c_enum "unspec" [
67 ;; Relocation specifiers
78 UNSPEC_MACHOPIC_OFFSET
86 UNSPEC_MEMORY_BLOCKAGE
96 ;; Other random patterns
105 UNSPEC_LD_MPIC ; load_macho_picbase
107 UNSPEC_DIV_ALREADY_SPLIT
108 UNSPEC_MS_TO_SYSV_CALL
109 UNSPEC_CALL_NEEDS_VZEROUPPER
113 ;; For SSE/MMX support:
121 ;; Generic math support
123 UNSPEC_IEEE_MIN ; not commutative
124 UNSPEC_IEEE_MAX ; not commutative
126 ;; x87 Floating point
142 UNSPEC_FRNDINT_MASK_PM
146 ;; x87 Double output FP
181 (define_c_enum "unspecv" [
184 UNSPECV_PROBE_STACK_RANGE
187 UNSPECV_SPLIT_STACK_RETURN
193 UNSPECV_LLWP_INTRINSIC
194 UNSPECV_SLWP_INTRINSIC
195 UNSPECV_LWPVAL_INTRINSIC
196 UNSPECV_LWPINS_INTRINSIC
202 ;; For RDRAND support
206 ;; Constants to represent rounding modes in the ROUND instruction
215 ;; Constants to represent pcomtrue/pcomfalse variants
225 ;; Constants used in the XOP pperm instruction
227 [(PPERM_SRC 0x00) /* copy source */
228 (PPERM_INVERT 0x20) /* invert source */
229 (PPERM_REVERSE 0x40) /* bit reverse source */
230 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
231 (PPERM_ZERO 0x80) /* all 0's */
232 (PPERM_ONES 0xa0) /* all 1's */
233 (PPERM_SIGN 0xc0) /* propagate sign bit */
234 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
235 (PPERM_SRC1 0x00) /* use first source byte */
236 (PPERM_SRC2 0x10) /* use second source byte */
239 ;; Registers by name.
292 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
295 ;; In C guard expressions, put expressions which may be compile-time
296 ;; constants first. This allows for better optimization. For
297 ;; example, write "TARGET_64BIT && reload_completed", not
298 ;; "reload_completed && TARGET_64BIT".
302 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,corei7,
303 atom,generic64,amdfam10,bdver1,bdver2,btver1"
304 (const (symbol_ref "ix86_schedule")))
306 ;; A basic instruction type. Refinements due to arguments to be
307 ;; provided in other attributes.
310 alu,alu1,negnot,imov,imovx,lea,
311 incdec,ishift,ishiftx,ishift1,rotate,rotatex,rotate1,imul,imulx,idiv,
312 icmp,test,ibr,setcc,icmov,
313 push,pop,call,callv,leave,
315 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
316 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
317 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
318 ssemuladd,sse4arg,lwp,
319 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
320 (const_string "other"))
322 ;; Main data type used by the insn
324 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
325 (const_string "unknown"))
327 ;; The CPU unit operations uses.
328 (define_attr "unit" "integer,i387,sse,mmx,unknown"
329 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
330 (const_string "i387")
331 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseishft1,sseimul,
332 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
333 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
335 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
337 (eq_attr "type" "other")
338 (const_string "unknown")]
339 (const_string "integer")))
341 ;; The (bounding maximum) length of an instruction immediate.
342 (define_attr "length_immediate" ""
343 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
346 (eq_attr "unit" "i387,sse,mmx")
348 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,ishiftx,ishift1,
349 rotate,rotatex,rotate1,imul,icmp,push,pop")
350 (symbol_ref "ix86_attr_length_immediate_default (insn, true)")
351 (eq_attr "type" "imov,test")
352 (symbol_ref "ix86_attr_length_immediate_default (insn, false)")
353 (eq_attr "type" "call")
354 (if_then_else (match_operand 0 "constant_call_address_operand" "")
357 (eq_attr "type" "callv")
358 (if_then_else (match_operand 1 "constant_call_address_operand" "")
361 ;; We don't know the size before shorten_branches. Expect
362 ;; the instruction to fit for better scheduling.
363 (eq_attr "type" "ibr")
366 (symbol_ref "/* Update immediate_length and other attributes! */
367 gcc_unreachable (),1")))
369 ;; The (bounding maximum) length of an instruction address.
370 (define_attr "length_address" ""
371 (cond [(eq_attr "type" "str,other,multi,fxch")
373 (and (eq_attr "type" "call")
374 (match_operand 0 "constant_call_address_operand" ""))
376 (and (eq_attr "type" "callv")
377 (match_operand 1 "constant_call_address_operand" ""))
380 (symbol_ref "ix86_attr_length_address_default (insn)")))
382 ;; Set when length prefix is used.
383 (define_attr "prefix_data16" ""
384 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
386 (eq_attr "mode" "HI")
388 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
393 ;; Set when string REP prefix is used.
394 (define_attr "prefix_rep" ""
395 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
397 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
402 ;; Set when 0f opcode prefix is used.
403 (define_attr "prefix_0f" ""
405 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
406 (eq_attr "unit" "sse,mmx"))
410 ;; Set when REX opcode prefix is used.
411 (define_attr "prefix_rex" ""
412 (cond [(not (match_test "TARGET_64BIT"))
414 (and (eq_attr "mode" "DI")
415 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
416 (eq_attr "unit" "!mmx")))
418 (and (eq_attr "mode" "QI")
419 (match_test "x86_extended_QIreg_mentioned_p (insn)"))
421 (match_test "x86_extended_reg_mentioned_p (insn)")
423 (and (eq_attr "type" "imovx")
424 (match_operand:QI 1 "ext_QIreg_operand" ""))
429 ;; There are also additional prefixes in 3DNOW, SSSE3.
430 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
431 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
432 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
433 (define_attr "prefix_extra" ""
434 (cond [(eq_attr "type" "ssemuladd,sse4arg")
436 (eq_attr "type" "sseiadd1,ssecvt1")
441 ;; Prefix used: original, VEX or maybe VEX.
442 (define_attr "prefix" "orig,vex,maybe_vex"
443 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
445 (const_string "orig")))
447 ;; VEX W bit is used.
448 (define_attr "prefix_vex_w" "" (const_int 0))
450 ;; The length of VEX prefix
451 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
452 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
453 ;; still prefix_0f 1, with prefix_extra 1.
454 (define_attr "length_vex" ""
455 (if_then_else (and (eq_attr "prefix_0f" "1")
456 (eq_attr "prefix_extra" "0"))
457 (if_then_else (eq_attr "prefix_vex_w" "1")
458 (symbol_ref "ix86_attr_length_vex_default (insn, true, true)")
459 (symbol_ref "ix86_attr_length_vex_default (insn, true, false)"))
460 (if_then_else (eq_attr "prefix_vex_w" "1")
461 (symbol_ref "ix86_attr_length_vex_default (insn, false, true)")
462 (symbol_ref "ix86_attr_length_vex_default (insn, false, false)"))))
464 ;; Set when modrm byte is used.
465 (define_attr "modrm" ""
466 (cond [(eq_attr "type" "str,leave")
468 (eq_attr "unit" "i387")
470 (and (eq_attr "type" "incdec")
471 (and (not (match_test "TARGET_64BIT"))
472 (ior (match_operand:SI 1 "register_operand" "")
473 (match_operand:HI 1 "register_operand" ""))))
475 (and (eq_attr "type" "push")
476 (not (match_operand 1 "memory_operand" "")))
478 (and (eq_attr "type" "pop")
479 (not (match_operand 0 "memory_operand" "")))
481 (and (eq_attr "type" "imov")
482 (and (not (eq_attr "mode" "DI"))
483 (ior (and (match_operand 0 "register_operand" "")
484 (match_operand 1 "immediate_operand" ""))
485 (ior (and (match_operand 0 "ax_reg_operand" "")
486 (match_operand 1 "memory_displacement_only_operand" ""))
487 (and (match_operand 0 "memory_displacement_only_operand" "")
488 (match_operand 1 "ax_reg_operand" ""))))))
490 (and (eq_attr "type" "call")
491 (match_operand 0 "constant_call_address_operand" ""))
493 (and (eq_attr "type" "callv")
494 (match_operand 1 "constant_call_address_operand" ""))
496 (and (eq_attr "type" "alu,alu1,icmp,test")
497 (match_operand 0 "ax_reg_operand" ""))
498 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
502 ;; The (bounding maximum) length of an instruction in bytes.
503 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
504 ;; Later we may want to split them and compute proper length as for
506 (define_attr "length" ""
507 (cond [(eq_attr "type" "other,multi,fistp,frndint")
509 (eq_attr "type" "fcmp")
511 (eq_attr "unit" "i387")
513 (plus (attr "prefix_data16")
514 (attr "length_address")))
515 (ior (eq_attr "prefix" "vex")
516 (and (eq_attr "prefix" "maybe_vex")
517 (match_test "TARGET_AVX")))
518 (plus (attr "length_vex")
519 (plus (attr "length_immediate")
521 (attr "length_address"))))]
522 (plus (plus (attr "modrm")
523 (plus (attr "prefix_0f")
524 (plus (attr "prefix_rex")
525 (plus (attr "prefix_extra")
527 (plus (attr "prefix_rep")
528 (plus (attr "prefix_data16")
529 (plus (attr "length_immediate")
530 (attr "length_address")))))))
532 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
533 ;; `store' if there is a simple memory reference therein, or `unknown'
534 ;; if the instruction is complex.
536 (define_attr "memory" "none,load,store,both,unknown"
537 (cond [(eq_attr "type" "other,multi,str,lwp")
538 (const_string "unknown")
539 (eq_attr "type" "lea,fcmov,fpspc")
540 (const_string "none")
541 (eq_attr "type" "fistp,leave")
542 (const_string "both")
543 (eq_attr "type" "frndint")
544 (const_string "load")
545 (eq_attr "type" "push")
546 (if_then_else (match_operand 1 "memory_operand" "")
547 (const_string "both")
548 (const_string "store"))
549 (eq_attr "type" "pop")
550 (if_then_else (match_operand 0 "memory_operand" "")
551 (const_string "both")
552 (const_string "load"))
553 (eq_attr "type" "setcc")
554 (if_then_else (match_operand 0 "memory_operand" "")
555 (const_string "store")
556 (const_string "none"))
557 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
558 (if_then_else (ior (match_operand 0 "memory_operand" "")
559 (match_operand 1 "memory_operand" ""))
560 (const_string "load")
561 (const_string "none"))
562 (eq_attr "type" "ibr")
563 (if_then_else (match_operand 0 "memory_operand" "")
564 (const_string "load")
565 (const_string "none"))
566 (eq_attr "type" "call")
567 (if_then_else (match_operand 0 "constant_call_address_operand" "")
568 (const_string "none")
569 (const_string "load"))
570 (eq_attr "type" "callv")
571 (if_then_else (match_operand 1 "constant_call_address_operand" "")
572 (const_string "none")
573 (const_string "load"))
574 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
575 (match_operand 1 "memory_operand" ""))
576 (const_string "both")
577 (and (match_operand 0 "memory_operand" "")
578 (match_operand 1 "memory_operand" ""))
579 (const_string "both")
580 (match_operand 0 "memory_operand" "")
581 (const_string "store")
582 (match_operand 1 "memory_operand" "")
583 (const_string "load")
585 "!alu1,negnot,ishift1,
586 imov,imovx,icmp,test,bitmanip,
588 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
589 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
590 (match_operand 2 "memory_operand" ""))
591 (const_string "load")
592 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
593 (match_operand 3 "memory_operand" ""))
594 (const_string "load")
596 (const_string "none")))
598 ;; Indicates if an instruction has both an immediate and a displacement.
600 (define_attr "imm_disp" "false,true,unknown"
601 (cond [(eq_attr "type" "other,multi")
602 (const_string "unknown")
603 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
604 (and (match_operand 0 "memory_displacement_operand" "")
605 (match_operand 1 "immediate_operand" "")))
606 (const_string "true")
607 (and (eq_attr "type" "alu,ishift,ishiftx,rotate,rotatex,imul,idiv")
608 (and (match_operand 0 "memory_displacement_operand" "")
609 (match_operand 2 "immediate_operand" "")))
610 (const_string "true")
612 (const_string "false")))
614 ;; Indicates if an FP operation has an integer source.
616 (define_attr "fp_int_src" "false,true"
617 (const_string "false"))
619 ;; Defines rounding mode of an FP operation.
621 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
622 (const_string "any"))
624 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
625 (define_attr "use_carry" "0,1" (const_string "0"))
627 ;; Define attribute to indicate unaligned ssemov insns
628 (define_attr "movu" "0,1" (const_string "0"))
630 ;; Used to control the "enabled" attribute on a per-instruction basis.
631 (define_attr "isa" "base,sse2,sse2_noavx,sse3,sse4,sse4_noavx,noavx,avx,bmi2"
632 (const_string "base"))
634 (define_attr "enabled" ""
635 (cond [(eq_attr "isa" "sse2") (symbol_ref "TARGET_SSE2")
636 (eq_attr "isa" "sse2_noavx")
637 (symbol_ref "TARGET_SSE2 && !TARGET_AVX")
638 (eq_attr "isa" "sse3") (symbol_ref "TARGET_SSE3")
639 (eq_attr "isa" "sse4") (symbol_ref "TARGET_SSE4_1")
640 (eq_attr "isa" "sse4_noavx")
641 (symbol_ref "TARGET_SSE4_1 && !TARGET_AVX")
642 (eq_attr "isa" "avx") (symbol_ref "TARGET_AVX")
643 (eq_attr "isa" "noavx") (symbol_ref "!TARGET_AVX")
644 (eq_attr "isa" "bmi2") (symbol_ref "TARGET_BMI2")
648 ;; Describe a user's asm statement.
649 (define_asm_attributes
650 [(set_attr "length" "128")
651 (set_attr "type" "multi")])
653 (define_code_iterator plusminus [plus minus])
655 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
657 ;; Base name for define_insn
658 (define_code_attr plusminus_insn
659 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
660 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
662 ;; Base name for insn mnemonic.
663 (define_code_attr plusminus_mnemonic
664 [(plus "add") (ss_plus "adds") (us_plus "addus")
665 (minus "sub") (ss_minus "subs") (us_minus "subus")])
666 (define_code_attr plusminus_carry_mnemonic
667 [(plus "adc") (minus "sbb")])
669 ;; Mark commutative operators as such in constraints.
670 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
671 (minus "") (ss_minus "") (us_minus "")])
673 ;; Mapping of max and min
674 (define_code_iterator maxmin [smax smin umax umin])
676 ;; Mapping of signed max and min
677 (define_code_iterator smaxmin [smax smin])
679 ;; Mapping of unsigned max and min
680 (define_code_iterator umaxmin [umax umin])
682 ;; Base name for integer and FP insn mnemonic
683 (define_code_attr maxmin_int [(smax "maxs") (smin "mins")
684 (umax "maxu") (umin "minu")])
685 (define_code_attr maxmin_float [(smax "max") (smin "min")])
687 ;; Mapping of logic operators
688 (define_code_iterator any_logic [and ior xor])
689 (define_code_iterator any_or [ior xor])
691 ;; Base name for insn mnemonic.
692 (define_code_attr logic [(and "and") (ior "or") (xor "xor")])
694 ;; Mapping of logic-shift operators
695 (define_code_iterator any_lshift [ashift lshiftrt])
697 ;; Mapping of shift-right operators
698 (define_code_iterator any_shiftrt [lshiftrt ashiftrt])
700 ;; Base name for define_insn
701 (define_code_attr shift_insn
702 [(ashift "ashl") (lshiftrt "lshr") (ashiftrt "ashr")])
704 ;; Base name for insn mnemonic.
705 (define_code_attr shift [(ashift "sll") (lshiftrt "shr") (ashiftrt "sar")])
706 (define_code_attr vshift [(ashift "sll") (lshiftrt "srl") (ashiftrt "sra")])
708 ;; Mapping of rotate operators
709 (define_code_iterator any_rotate [rotate rotatert])
711 ;; Base name for define_insn
712 (define_code_attr rotate_insn [(rotate "rotl") (rotatert "rotr")])
714 ;; Base name for insn mnemonic.
715 (define_code_attr rotate [(rotate "rol") (rotatert "ror")])
717 ;; Mapping of abs neg operators
718 (define_code_iterator absneg [abs neg])
720 ;; Base name for x87 insn mnemonic.
721 (define_code_attr absneg_mnemonic [(abs "abs") (neg "chs")])
723 ;; Used in signed and unsigned widening multiplications.
724 (define_code_iterator any_extend [sign_extend zero_extend])
726 ;; Prefix for insn menmonic.
727 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")])
729 ;; Prefix for define_insn
730 (define_code_attr u [(sign_extend "") (zero_extend "u")])
731 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
733 ;; All integer modes.
734 (define_mode_iterator SWI1248x [QI HI SI DI])
736 ;; All integer modes without QImode.
737 (define_mode_iterator SWI248x [HI SI DI])
739 ;; All integer modes without QImode and HImode.
740 (define_mode_iterator SWI48x [SI DI])
742 ;; All integer modes without SImode and DImode.
743 (define_mode_iterator SWI12 [QI HI])
745 ;; All integer modes without DImode.
746 (define_mode_iterator SWI124 [QI HI SI])
748 ;; All integer modes without QImode and DImode.
749 (define_mode_iterator SWI24 [HI SI])
751 ;; Single word integer modes.
752 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
754 ;; Single word integer modes without QImode.
755 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
757 ;; Single word integer modes without QImode and HImode.
758 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
760 ;; All math-dependant single and double word integer modes.
761 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
762 (HI "TARGET_HIMODE_MATH")
763 SI DI (TI "TARGET_64BIT")])
765 ;; Math-dependant single word integer modes.
766 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
767 (HI "TARGET_HIMODE_MATH")
768 SI (DI "TARGET_64BIT")])
770 ;; Math-dependant integer modes without DImode.
771 (define_mode_iterator SWIM124 [(QI "TARGET_QIMODE_MATH")
772 (HI "TARGET_HIMODE_MATH")
775 ;; Math-dependant single word integer modes without QImode.
776 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
777 SI (DI "TARGET_64BIT")])
779 ;; Double word integer modes.
780 (define_mode_iterator DWI [(DI "!TARGET_64BIT")
781 (TI "TARGET_64BIT")])
783 ;; Double word integer modes as mode attribute.
784 (define_mode_attr DWI [(SI "DI") (DI "TI")])
785 (define_mode_attr dwi [(SI "di") (DI "ti")])
787 ;; Half mode for double word integer modes.
788 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
789 (DI "TARGET_64BIT")])
791 ;; Instruction suffix for integer modes.
792 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
794 ;; Pointer size prefix for integer modes (Intel asm dialect)
795 (define_mode_attr iptrsize [(QI "BYTE")
800 ;; Register class for integer modes.
801 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
803 ;; Immediate operand constraint for integer modes.
804 (define_mode_attr i [(QI "n") (HI "n") (SI "e") (DI "e")])
806 ;; General operand constraint for word modes.
807 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "rme") (DI "rme")])
809 ;; Immediate operand constraint for double integer modes.
810 (define_mode_attr di [(SI "nF") (DI "e")])
812 ;; Immediate operand constraint for shifts.
813 (define_mode_attr S [(QI "I") (HI "I") (SI "I") (DI "J") (TI "O")])
815 ;; General operand predicate for integer modes.
816 (define_mode_attr general_operand
817 [(QI "general_operand")
818 (HI "general_operand")
819 (SI "x86_64_general_operand")
820 (DI "x86_64_general_operand")
821 (TI "x86_64_general_operand")])
823 ;; General sign/zero extend operand predicate for integer modes.
824 (define_mode_attr general_szext_operand
825 [(QI "general_operand")
826 (HI "general_operand")
827 (SI "x86_64_szext_general_operand")
828 (DI "x86_64_szext_general_operand")])
830 ;; Immediate operand predicate for integer modes.
831 (define_mode_attr immediate_operand
832 [(QI "immediate_operand")
833 (HI "immediate_operand")
834 (SI "x86_64_immediate_operand")
835 (DI "x86_64_immediate_operand")])
837 ;; Nonmemory operand predicate for integer modes.
838 (define_mode_attr nonmemory_operand
839 [(QI "nonmemory_operand")
840 (HI "nonmemory_operand")
841 (SI "x86_64_nonmemory_operand")
842 (DI "x86_64_nonmemory_operand")])
844 ;; Operand predicate for shifts.
845 (define_mode_attr shift_operand
846 [(QI "nonimmediate_operand")
847 (HI "nonimmediate_operand")
848 (SI "nonimmediate_operand")
849 (DI "shiftdi_operand")
850 (TI "register_operand")])
852 ;; Operand predicate for shift argument.
853 (define_mode_attr shift_immediate_operand
854 [(QI "const_1_to_31_operand")
855 (HI "const_1_to_31_operand")
856 (SI "const_1_to_31_operand")
857 (DI "const_1_to_63_operand")])
859 ;; Input operand predicate for arithmetic left shifts.
860 (define_mode_attr ashl_input_operand
861 [(QI "nonimmediate_operand")
862 (HI "nonimmediate_operand")
863 (SI "nonimmediate_operand")
864 (DI "ashldi_input_operand")
865 (TI "reg_or_pm1_operand")])
867 ;; SSE and x87 SFmode and DFmode floating point modes
868 (define_mode_iterator MODEF [SF DF])
870 ;; All x87 floating point modes
871 (define_mode_iterator X87MODEF [SF DF XF])
873 ;; SSE instruction suffix for various modes
874 (define_mode_attr ssemodesuffix
876 (V8SF "ps") (V4DF "pd")
877 (V4SF "ps") (V2DF "pd")
878 (V16QI "b") (V8HI "w") (V4SI "d") (V2DI "q")
879 (V32QI "b") (V16HI "w") (V8SI "d") (V4DI "q")])
881 ;; SSE vector suffix for floating point modes
882 (define_mode_attr ssevecmodesuffix [(SF "ps") (DF "pd")])
884 ;; SSE vector mode corresponding to a scalar mode
885 (define_mode_attr ssevecmode
886 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
888 ;; Instruction suffix for REX 64bit operators.
889 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
891 ;; This mode iterator allows :P to be used for patterns that operate on
892 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
893 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
895 ;; This mode iterator allows :PTR to be used for patterns that operate on
896 ;; ptr_mode sized quantities.
897 (define_mode_iterator PTR
898 [(SI "ptr_mode == SImode") (DI "ptr_mode == DImode")])
900 ;; Scheduling descriptions
902 (include "pentium.md")
905 (include "athlon.md")
906 (include "bdver1.md")
912 ;; Operand and operator predicates and constraints
914 (include "predicates.md")
915 (include "constraints.md")
918 ;; Compare and branch/compare and store instructions.
920 (define_expand "cbranch<mode>4"
921 [(set (reg:CC FLAGS_REG)
922 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
923 (match_operand:SDWIM 2 "<general_operand>" "")))
924 (set (pc) (if_then_else
925 (match_operator 0 "ordered_comparison_operator"
926 [(reg:CC FLAGS_REG) (const_int 0)])
927 (label_ref (match_operand 3 "" ""))
931 if (MEM_P (operands[1]) && MEM_P (operands[2]))
932 operands[1] = force_reg (<MODE>mode, operands[1]);
933 ix86_expand_branch (GET_CODE (operands[0]),
934 operands[1], operands[2], operands[3]);
938 (define_expand "cstore<mode>4"
939 [(set (reg:CC FLAGS_REG)
940 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
941 (match_operand:SWIM 3 "<general_operand>" "")))
942 (set (match_operand:QI 0 "register_operand" "")
943 (match_operator 1 "ordered_comparison_operator"
944 [(reg:CC FLAGS_REG) (const_int 0)]))]
947 if (MEM_P (operands[2]) && MEM_P (operands[3]))
948 operands[2] = force_reg (<MODE>mode, operands[2]);
949 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
950 operands[2], operands[3]);
954 (define_expand "cmp<mode>_1"
955 [(set (reg:CC FLAGS_REG)
956 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
957 (match_operand:SWI48 1 "<general_operand>" "")))])
959 (define_insn "*cmp<mode>_ccno_1"
960 [(set (reg FLAGS_REG)
961 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
962 (match_operand:SWI 1 "const0_operand" "")))]
963 "ix86_match_ccmode (insn, CCNOmode)"
965 test{<imodesuffix>}\t%0, %0
966 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
967 [(set_attr "type" "test,icmp")
968 (set_attr "length_immediate" "0,1")
969 (set_attr "mode" "<MODE>")])
971 (define_insn "*cmp<mode>_1"
972 [(set (reg FLAGS_REG)
973 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
974 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
975 "ix86_match_ccmode (insn, CCmode)"
976 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
977 [(set_attr "type" "icmp")
978 (set_attr "mode" "<MODE>")])
980 (define_insn "*cmp<mode>_minus_1"
981 [(set (reg FLAGS_REG)
983 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
984 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
986 "ix86_match_ccmode (insn, CCGOCmode)"
987 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
988 [(set_attr "type" "icmp")
989 (set_attr "mode" "<MODE>")])
991 (define_insn "*cmpqi_ext_1"
992 [(set (reg FLAGS_REG)
994 (match_operand:QI 0 "general_operand" "Qm")
997 (match_operand 1 "ext_register_operand" "Q")
1000 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001 "cmp{b}\t{%h1, %0|%0, %h1}"
1002 [(set_attr "type" "icmp")
1003 (set_attr "mode" "QI")])
1005 (define_insn "*cmpqi_ext_1_rex64"
1006 [(set (reg FLAGS_REG)
1008 (match_operand:QI 0 "register_operand" "Q")
1011 (match_operand 1 "ext_register_operand" "Q")
1013 (const_int 8)) 0)))]
1014 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1015 "cmp{b}\t{%h1, %0|%0, %h1}"
1016 [(set_attr "type" "icmp")
1017 (set_attr "mode" "QI")])
1019 (define_insn "*cmpqi_ext_2"
1020 [(set (reg FLAGS_REG)
1024 (match_operand 0 "ext_register_operand" "Q")
1027 (match_operand:QI 1 "const0_operand" "")))]
1028 "ix86_match_ccmode (insn, CCNOmode)"
1030 [(set_attr "type" "test")
1031 (set_attr "length_immediate" "0")
1032 (set_attr "mode" "QI")])
1034 (define_expand "cmpqi_ext_3"
1035 [(set (reg:CC FLAGS_REG)
1039 (match_operand 0 "ext_register_operand" "")
1042 (match_operand:QI 1 "immediate_operand" "")))])
1044 (define_insn "*cmpqi_ext_3_insn"
1045 [(set (reg FLAGS_REG)
1049 (match_operand 0 "ext_register_operand" "Q")
1052 (match_operand:QI 1 "general_operand" "Qmn")))]
1053 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1054 "cmp{b}\t{%1, %h0|%h0, %1}"
1055 [(set_attr "type" "icmp")
1056 (set_attr "modrm" "1")
1057 (set_attr "mode" "QI")])
1059 (define_insn "*cmpqi_ext_3_insn_rex64"
1060 [(set (reg FLAGS_REG)
1064 (match_operand 0 "ext_register_operand" "Q")
1067 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1068 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1069 "cmp{b}\t{%1, %h0|%h0, %1}"
1070 [(set_attr "type" "icmp")
1071 (set_attr "modrm" "1")
1072 (set_attr "mode" "QI")])
1074 (define_insn "*cmpqi_ext_4"
1075 [(set (reg FLAGS_REG)
1079 (match_operand 0 "ext_register_operand" "Q")
1084 (match_operand 1 "ext_register_operand" "Q")
1086 (const_int 8)) 0)))]
1087 "ix86_match_ccmode (insn, CCmode)"
1088 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1089 [(set_attr "type" "icmp")
1090 (set_attr "mode" "QI")])
1092 ;; These implement float point compares.
1093 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1094 ;; which would allow mix and match FP modes on the compares. Which is what
1095 ;; the old patterns did, but with many more of them.
1097 (define_expand "cbranchxf4"
1098 [(set (reg:CC FLAGS_REG)
1099 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1100 (match_operand:XF 2 "nonmemory_operand" "")))
1101 (set (pc) (if_then_else
1102 (match_operator 0 "ix86_fp_comparison_operator"
1105 (label_ref (match_operand 3 "" ""))
1109 ix86_expand_branch (GET_CODE (operands[0]),
1110 operands[1], operands[2], operands[3]);
1114 (define_expand "cstorexf4"
1115 [(set (reg:CC FLAGS_REG)
1116 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1117 (match_operand:XF 3 "nonmemory_operand" "")))
1118 (set (match_operand:QI 0 "register_operand" "")
1119 (match_operator 1 "ix86_fp_comparison_operator"
1124 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1125 operands[2], operands[3]);
1129 (define_expand "cbranch<mode>4"
1130 [(set (reg:CC FLAGS_REG)
1131 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1132 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1133 (set (pc) (if_then_else
1134 (match_operator 0 "ix86_fp_comparison_operator"
1137 (label_ref (match_operand 3 "" ""))
1139 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1141 ix86_expand_branch (GET_CODE (operands[0]),
1142 operands[1], operands[2], operands[3]);
1146 (define_expand "cstore<mode>4"
1147 [(set (reg:CC FLAGS_REG)
1148 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1149 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1150 (set (match_operand:QI 0 "register_operand" "")
1151 (match_operator 1 "ix86_fp_comparison_operator"
1154 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1156 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1157 operands[2], operands[3]);
1161 (define_expand "cbranchcc4"
1162 [(set (pc) (if_then_else
1163 (match_operator 0 "comparison_operator"
1164 [(match_operand 1 "flags_reg_operand" "")
1165 (match_operand 2 "const0_operand" "")])
1166 (label_ref (match_operand 3 "" ""))
1170 ix86_expand_branch (GET_CODE (operands[0]),
1171 operands[1], operands[2], operands[3]);
1175 (define_expand "cstorecc4"
1176 [(set (match_operand:QI 0 "register_operand" "")
1177 (match_operator 1 "comparison_operator"
1178 [(match_operand 2 "flags_reg_operand" "")
1179 (match_operand 3 "const0_operand" "")]))]
1182 ix86_expand_setcc (operands[0], GET_CODE (operands[1]),
1183 operands[2], operands[3]);
1188 ;; FP compares, step 1:
1189 ;; Set the FP condition codes.
1191 ;; CCFPmode compare with exceptions
1192 ;; CCFPUmode compare with no exceptions
1194 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1195 ;; used to manage the reg stack popping would not be preserved.
1197 (define_insn "*cmpfp_0"
1198 [(set (match_operand:HI 0 "register_operand" "=a")
1201 (match_operand 1 "register_operand" "f")
1202 (match_operand 2 "const0_operand" ""))]
1204 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1205 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1206 "* return output_fp_compare (insn, operands, false, false);"
1207 [(set_attr "type" "multi")
1208 (set_attr "unit" "i387")
1210 (cond [(match_operand:SF 1 "" "")
1212 (match_operand:DF 1 "" "")
1215 (const_string "XF")))])
1217 (define_insn_and_split "*cmpfp_0_cc"
1218 [(set (reg:CCFP FLAGS_REG)
1220 (match_operand 1 "register_operand" "f")
1221 (match_operand 2 "const0_operand" "")))
1222 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1223 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1224 && TARGET_SAHF && !TARGET_CMOVE
1225 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1227 "&& reload_completed"
1230 [(compare:CCFP (match_dup 1)(match_dup 2))]
1232 (set (reg:CC FLAGS_REG)
1233 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1235 [(set_attr "type" "multi")
1236 (set_attr "unit" "i387")
1238 (cond [(match_operand:SF 1 "" "")
1240 (match_operand:DF 1 "" "")
1243 (const_string "XF")))])
1245 (define_insn "*cmpfp_xf"
1246 [(set (match_operand:HI 0 "register_operand" "=a")
1249 (match_operand:XF 1 "register_operand" "f")
1250 (match_operand:XF 2 "register_operand" "f"))]
1253 "* return output_fp_compare (insn, operands, false, false);"
1254 [(set_attr "type" "multi")
1255 (set_attr "unit" "i387")
1256 (set_attr "mode" "XF")])
1258 (define_insn_and_split "*cmpfp_xf_cc"
1259 [(set (reg:CCFP FLAGS_REG)
1261 (match_operand:XF 1 "register_operand" "f")
1262 (match_operand:XF 2 "register_operand" "f")))
1263 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1265 && TARGET_SAHF && !TARGET_CMOVE"
1267 "&& reload_completed"
1270 [(compare:CCFP (match_dup 1)(match_dup 2))]
1272 (set (reg:CC FLAGS_REG)
1273 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1275 [(set_attr "type" "multi")
1276 (set_attr "unit" "i387")
1277 (set_attr "mode" "XF")])
1279 (define_insn "*cmpfp_<mode>"
1280 [(set (match_operand:HI 0 "register_operand" "=a")
1283 (match_operand:MODEF 1 "register_operand" "f")
1284 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1287 "* return output_fp_compare (insn, operands, false, false);"
1288 [(set_attr "type" "multi")
1289 (set_attr "unit" "i387")
1290 (set_attr "mode" "<MODE>")])
1292 (define_insn_and_split "*cmpfp_<mode>_cc"
1293 [(set (reg:CCFP FLAGS_REG)
1295 (match_operand:MODEF 1 "register_operand" "f")
1296 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1297 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1299 && TARGET_SAHF && !TARGET_CMOVE"
1301 "&& reload_completed"
1304 [(compare:CCFP (match_dup 1)(match_dup 2))]
1306 (set (reg:CC FLAGS_REG)
1307 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1309 [(set_attr "type" "multi")
1310 (set_attr "unit" "i387")
1311 (set_attr "mode" "<MODE>")])
1313 (define_insn "*cmpfp_u"
1314 [(set (match_operand:HI 0 "register_operand" "=a")
1317 (match_operand 1 "register_operand" "f")
1318 (match_operand 2 "register_operand" "f"))]
1320 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1322 "* return output_fp_compare (insn, operands, false, true);"
1323 [(set_attr "type" "multi")
1324 (set_attr "unit" "i387")
1326 (cond [(match_operand:SF 1 "" "")
1328 (match_operand:DF 1 "" "")
1331 (const_string "XF")))])
1333 (define_insn_and_split "*cmpfp_u_cc"
1334 [(set (reg:CCFPU FLAGS_REG)
1336 (match_operand 1 "register_operand" "f")
1337 (match_operand 2 "register_operand" "f")))
1338 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1339 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1340 && TARGET_SAHF && !TARGET_CMOVE
1341 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1343 "&& reload_completed"
1346 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1348 (set (reg:CC FLAGS_REG)
1349 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351 [(set_attr "type" "multi")
1352 (set_attr "unit" "i387")
1354 (cond [(match_operand:SF 1 "" "")
1356 (match_operand:DF 1 "" "")
1359 (const_string "XF")))])
1361 (define_insn "*cmpfp_<mode>"
1362 [(set (match_operand:HI 0 "register_operand" "=a")
1365 (match_operand 1 "register_operand" "f")
1366 (match_operator 3 "float_operator"
1367 [(match_operand:SWI24 2 "memory_operand" "m")]))]
1369 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1370 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1371 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1372 "* return output_fp_compare (insn, operands, false, false);"
1373 [(set_attr "type" "multi")
1374 (set_attr "unit" "i387")
1375 (set_attr "fp_int_src" "true")
1376 (set_attr "mode" "<MODE>")])
1378 (define_insn_and_split "*cmpfp_<mode>_cc"
1379 [(set (reg:CCFP FLAGS_REG)
1381 (match_operand 1 "register_operand" "f")
1382 (match_operator 3 "float_operator"
1383 [(match_operand:SWI24 2 "memory_operand" "m")])))
1384 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1385 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1386 && TARGET_SAHF && !TARGET_CMOVE
1387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1388 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1390 "&& reload_completed"
1395 (match_op_dup 3 [(match_dup 2)]))]
1397 (set (reg:CC FLAGS_REG)
1398 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1400 [(set_attr "type" "multi")
1401 (set_attr "unit" "i387")
1402 (set_attr "fp_int_src" "true")
1403 (set_attr "mode" "<MODE>")])
1405 ;; FP compares, step 2
1406 ;; Move the fpsw to ax.
1408 (define_insn "x86_fnstsw_1"
1409 [(set (match_operand:HI 0 "register_operand" "=a")
1410 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1413 [(set (attr "length")
1414 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1415 (set_attr "mode" "SI")
1416 (set_attr "unit" "i387")])
1418 ;; FP compares, step 3
1419 ;; Get ax into flags, general case.
1421 (define_insn "x86_sahf_1"
1422 [(set (reg:CC FLAGS_REG)
1423 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1427 #ifndef HAVE_AS_IX86_SAHF
1429 return ASM_BYTE "0x9e";
1434 [(set_attr "length" "1")
1435 (set_attr "athlon_decode" "vector")
1436 (set_attr "amdfam10_decode" "direct")
1437 (set_attr "bdver1_decode" "direct")
1438 (set_attr "mode" "SI")])
1440 ;; Pentium Pro can do steps 1 through 3 in one go.
1441 ;; comi*, ucomi*, fcomi*, ficomi*, fucomi*
1442 ;; (these i387 instructions set flags directly)
1443 (define_insn "*cmpfp_i_mixed"
1444 [(set (reg:CCFP FLAGS_REG)
1445 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1446 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1447 "TARGET_MIX_SSE_I387
1448 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1449 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1450 "* return output_fp_compare (insn, operands, true, false);"
1451 [(set_attr "type" "fcmp,ssecomi")
1452 (set_attr "prefix" "orig,maybe_vex")
1454 (if_then_else (match_operand:SF 1 "" "")
1456 (const_string "DF")))
1457 (set (attr "prefix_rep")
1458 (if_then_else (eq_attr "type" "ssecomi")
1460 (const_string "*")))
1461 (set (attr "prefix_data16")
1462 (cond [(eq_attr "type" "fcmp")
1464 (eq_attr "mode" "DF")
1467 (const_string "0")))
1468 (set_attr "athlon_decode" "vector")
1469 (set_attr "amdfam10_decode" "direct")
1470 (set_attr "bdver1_decode" "double")])
1472 (define_insn "*cmpfp_i_sse"
1473 [(set (reg:CCFP FLAGS_REG)
1474 (compare:CCFP (match_operand 0 "register_operand" "x")
1475 (match_operand 1 "nonimmediate_operand" "xm")))]
1477 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1478 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1479 "* return output_fp_compare (insn, operands, true, false);"
1480 [(set_attr "type" "ssecomi")
1481 (set_attr "prefix" "maybe_vex")
1483 (if_then_else (match_operand:SF 1 "" "")
1485 (const_string "DF")))
1486 (set_attr "prefix_rep" "0")
1487 (set (attr "prefix_data16")
1488 (if_then_else (eq_attr "mode" "DF")
1490 (const_string "0")))
1491 (set_attr "athlon_decode" "vector")
1492 (set_attr "amdfam10_decode" "direct")
1493 (set_attr "bdver1_decode" "double")])
1495 (define_insn "*cmpfp_i_i387"
1496 [(set (reg:CCFP FLAGS_REG)
1497 (compare:CCFP (match_operand 0 "register_operand" "f")
1498 (match_operand 1 "register_operand" "f")))]
1499 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1501 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1502 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1503 "* return output_fp_compare (insn, operands, true, false);"
1504 [(set_attr "type" "fcmp")
1506 (cond [(match_operand:SF 1 "" "")
1508 (match_operand:DF 1 "" "")
1511 (const_string "XF")))
1512 (set_attr "athlon_decode" "vector")
1513 (set_attr "amdfam10_decode" "direct")
1514 (set_attr "bdver1_decode" "double")])
1516 (define_insn "*cmpfp_iu_mixed"
1517 [(set (reg:CCFPU FLAGS_REG)
1518 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1519 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1520 "TARGET_MIX_SSE_I387
1521 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1522 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1523 "* return output_fp_compare (insn, operands, true, true);"
1524 [(set_attr "type" "fcmp,ssecomi")
1525 (set_attr "prefix" "orig,maybe_vex")
1527 (if_then_else (match_operand:SF 1 "" "")
1529 (const_string "DF")))
1530 (set (attr "prefix_rep")
1531 (if_then_else (eq_attr "type" "ssecomi")
1533 (const_string "*")))
1534 (set (attr "prefix_data16")
1535 (cond [(eq_attr "type" "fcmp")
1537 (eq_attr "mode" "DF")
1540 (const_string "0")))
1541 (set_attr "athlon_decode" "vector")
1542 (set_attr "amdfam10_decode" "direct")
1543 (set_attr "bdver1_decode" "double")])
1545 (define_insn "*cmpfp_iu_sse"
1546 [(set (reg:CCFPU FLAGS_REG)
1547 (compare:CCFPU (match_operand 0 "register_operand" "x")
1548 (match_operand 1 "nonimmediate_operand" "xm")))]
1550 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1551 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1552 "* return output_fp_compare (insn, operands, true, true);"
1553 [(set_attr "type" "ssecomi")
1554 (set_attr "prefix" "maybe_vex")
1556 (if_then_else (match_operand:SF 1 "" "")
1558 (const_string "DF")))
1559 (set_attr "prefix_rep" "0")
1560 (set (attr "prefix_data16")
1561 (if_then_else (eq_attr "mode" "DF")
1563 (const_string "0")))
1564 (set_attr "athlon_decode" "vector")
1565 (set_attr "amdfam10_decode" "direct")
1566 (set_attr "bdver1_decode" "double")])
1568 (define_insn "*cmpfp_iu_387"
1569 [(set (reg:CCFPU FLAGS_REG)
1570 (compare:CCFPU (match_operand 0 "register_operand" "f")
1571 (match_operand 1 "register_operand" "f")))]
1572 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1574 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1575 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1576 "* return output_fp_compare (insn, operands, true, true);"
1577 [(set_attr "type" "fcmp")
1579 (cond [(match_operand:SF 1 "" "")
1581 (match_operand:DF 1 "" "")
1584 (const_string "XF")))
1585 (set_attr "athlon_decode" "vector")
1586 (set_attr "amdfam10_decode" "direct")
1587 (set_attr "bdver1_decode" "direct")])
1589 ;; Push/pop instructions.
1591 (define_insn "*push<mode>2"
1592 [(set (match_operand:DWI 0 "push_operand" "=<")
1593 (match_operand:DWI 1 "general_no_elim_operand" "riF*o"))]
1596 [(set_attr "type" "multi")
1597 (set_attr "mode" "<MODE>")])
1600 [(set (match_operand:TI 0 "push_operand" "")
1601 (match_operand:TI 1 "general_operand" ""))]
1602 "TARGET_64BIT && reload_completed
1603 && !SSE_REG_P (operands[1])"
1605 "ix86_split_long_move (operands); DONE;")
1607 (define_insn "*pushdi2_rex64"
1608 [(set (match_operand:DI 0 "push_operand" "=<,!<")
1609 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
1614 [(set_attr "type" "push,multi")
1615 (set_attr "mode" "DI")])
1617 ;; Convert impossible pushes of immediate to existing instructions.
1618 ;; First try to get scratch register and go through it. In case this
1619 ;; fails, push sign extended lower part first and then overwrite
1620 ;; upper part by 32bit move.
1622 [(match_scratch:DI 2 "r")
1623 (set (match_operand:DI 0 "push_operand" "")
1624 (match_operand:DI 1 "immediate_operand" ""))]
1625 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1626 && !x86_64_immediate_operand (operands[1], DImode)"
1627 [(set (match_dup 2) (match_dup 1))
1628 (set (match_dup 0) (match_dup 2))])
1630 ;; We need to define this as both peepholer and splitter for case
1631 ;; peephole2 pass is not run.
1632 ;; "&& 1" is needed to keep it from matching the previous pattern.
1634 [(set (match_operand:DI 0 "push_operand" "")
1635 (match_operand:DI 1 "immediate_operand" ""))]
1636 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
1637 && !x86_64_immediate_operand (operands[1], DImode) && 1"
1638 [(set (match_dup 0) (match_dup 1))
1639 (set (match_dup 2) (match_dup 3))]
1641 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1643 operands[1] = gen_lowpart (DImode, operands[2]);
1644 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1649 [(set (match_operand:DI 0 "push_operand" "")
1650 (match_operand:DI 1 "immediate_operand" ""))]
1651 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
1652 ? epilogue_completed : reload_completed)
1653 && !symbolic_operand (operands[1], DImode)
1654 && !x86_64_immediate_operand (operands[1], DImode)"
1655 [(set (match_dup 0) (match_dup 1))
1656 (set (match_dup 2) (match_dup 3))]
1658 split_double_mode (DImode, &operands[1], 1, &operands[2], &operands[3]);
1660 operands[1] = gen_lowpart (DImode, operands[2]);
1661 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
1666 [(set (match_operand:DI 0 "push_operand" "")
1667 (match_operand:DI 1 "general_operand" ""))]
1668 "!TARGET_64BIT && reload_completed
1669 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
1671 "ix86_split_long_move (operands); DONE;")
1673 (define_insn "*pushsi2"
1674 [(set (match_operand:SI 0 "push_operand" "=<")
1675 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1678 [(set_attr "type" "push")
1679 (set_attr "mode" "SI")])
1681 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1682 ;; "push a byte/word". But actually we use pushl, which has the effect
1683 ;; of rounding the amount pushed up to a word.
1685 ;; For TARGET_64BIT we always round up to 8 bytes.
1686 (define_insn "*push<mode>2_rex64"
1687 [(set (match_operand:SWI124 0 "push_operand" "=X")
1688 (match_operand:SWI124 1 "nonmemory_no_elim_operand" "r<i>"))]
1691 [(set_attr "type" "push")
1692 (set_attr "mode" "DI")])
1694 (define_insn "*push<mode>2"
1695 [(set (match_operand:SWI12 0 "push_operand" "=X")
1696 (match_operand:SWI12 1 "nonmemory_no_elim_operand" "rn"))]
1699 [(set_attr "type" "push")
1700 (set_attr "mode" "SI")])
1702 (define_insn "*push<mode>2_prologue"
1703 [(set (match_operand:P 0 "push_operand" "=<")
1704 (match_operand:P 1 "general_no_elim_operand" "r<i>*m"))
1705 (clobber (mem:BLK (scratch)))]
1707 "push{<imodesuffix>}\t%1"
1708 [(set_attr "type" "push")
1709 (set_attr "mode" "<MODE>")])
1711 (define_insn "*pop<mode>1"
1712 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1713 (match_operand:P 1 "pop_operand" ">"))]
1715 "pop{<imodesuffix>}\t%0"
1716 [(set_attr "type" "pop")
1717 (set_attr "mode" "<MODE>")])
1719 (define_insn "*pop<mode>1_epilogue"
1720 [(set (match_operand:P 0 "nonimmediate_operand" "=r*m")
1721 (match_operand:P 1 "pop_operand" ">"))
1722 (clobber (mem:BLK (scratch)))]
1724 "pop{<imodesuffix>}\t%0"
1725 [(set_attr "type" "pop")
1726 (set_attr "mode" "<MODE>")])
1728 ;; Move instructions.
1730 (define_expand "movoi"
1731 [(set (match_operand:OI 0 "nonimmediate_operand" "")
1732 (match_operand:OI 1 "general_operand" ""))]
1734 "ix86_expand_move (OImode, operands); DONE;")
1736 (define_expand "movti"
1737 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1738 (match_operand:TI 1 "nonimmediate_operand" ""))]
1739 "TARGET_64BIT || TARGET_SSE"
1742 ix86_expand_move (TImode, operands);
1743 else if (push_operand (operands[0], TImode))
1744 ix86_expand_push (TImode, operands[1]);
1746 ix86_expand_vector_move (TImode, operands);
1750 ;; This expands to what emit_move_complex would generate if we didn't
1751 ;; have a movti pattern. Having this avoids problems with reload on
1752 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
1753 ;; to have around all the time.
1754 (define_expand "movcdi"
1755 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
1756 (match_operand:CDI 1 "general_operand" ""))]
1759 if (push_operand (operands[0], CDImode))
1760 emit_move_complex_push (CDImode, operands[0], operands[1]);
1762 emit_move_complex_parts (operands[0], operands[1]);
1766 (define_expand "mov<mode>"
1767 [(set (match_operand:SWI1248x 0 "nonimmediate_operand" "")
1768 (match_operand:SWI1248x 1 "general_operand" ""))]
1770 "ix86_expand_move (<MODE>mode, operands); DONE;")
1772 (define_insn "*mov<mode>_xor"
1773 [(set (match_operand:SWI48 0 "register_operand" "=r")
1774 (match_operand:SWI48 1 "const0_operand" ""))
1775 (clobber (reg:CC FLAGS_REG))]
1778 [(set_attr "type" "alu1")
1779 (set_attr "mode" "SI")
1780 (set_attr "length_immediate" "0")])
1782 (define_insn "*mov<mode>_or"
1783 [(set (match_operand:SWI48 0 "register_operand" "=r")
1784 (match_operand:SWI48 1 "const_int_operand" ""))
1785 (clobber (reg:CC FLAGS_REG))]
1787 && operands[1] == constm1_rtx"
1788 "or{<imodesuffix>}\t{%1, %0|%0, %1}"
1789 [(set_attr "type" "alu1")
1790 (set_attr "mode" "<MODE>")
1791 (set_attr "length_immediate" "1")])
1793 (define_insn "*movoi_internal_avx"
1794 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
1795 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
1796 "TARGET_AVX && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1798 switch (which_alternative)
1801 return standard_sse_constant_opcode (insn, operands[1]);
1804 if (misaligned_operand (operands[0], OImode)
1805 || misaligned_operand (operands[1], OImode))
1806 return "vmovdqu\t{%1, %0|%0, %1}";
1808 return "vmovdqa\t{%1, %0|%0, %1}";
1813 [(set_attr "type" "sselog1,ssemov,ssemov")
1814 (set_attr "prefix" "vex")
1815 (set_attr "mode" "OI")])
1817 (define_insn "*movti_internal_rex64"
1818 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
1819 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
1820 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1822 switch (which_alternative)
1828 return standard_sse_constant_opcode (insn, operands[1]);
1831 /* TDmode values are passed as TImode on the stack. Moving them
1832 to stack may result in unaligned memory access. */
1833 if (misaligned_operand (operands[0], TImode)
1834 || misaligned_operand (operands[1], TImode))
1836 if (get_attr_mode (insn) == MODE_V4SF)
1837 return "%vmovups\t{%1, %0|%0, %1}";
1839 return "%vmovdqu\t{%1, %0|%0, %1}";
1843 if (get_attr_mode (insn) == MODE_V4SF)
1844 return "%vmovaps\t{%1, %0|%0, %1}";
1846 return "%vmovdqa\t{%1, %0|%0, %1}";
1852 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
1853 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
1855 (cond [(eq_attr "alternative" "2,3")
1857 (match_test "optimize_function_for_size_p (cfun)")
1858 (const_string "V4SF")
1859 (const_string "TI"))
1860 (eq_attr "alternative" "4")
1862 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
1863 (match_test "optimize_function_for_size_p (cfun)"))
1864 (const_string "V4SF")
1865 (const_string "TI"))]
1866 (const_string "DI")))])
1869 [(set (match_operand:TI 0 "nonimmediate_operand" "")
1870 (match_operand:TI 1 "general_operand" ""))]
1872 && !SSE_REG_P (operands[0]) && !SSE_REG_P (operands[1])"
1874 "ix86_split_long_move (operands); DONE;")
1876 (define_insn "*movti_internal_sse"
1877 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
1878 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
1879 "TARGET_SSE && !TARGET_64BIT
1880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1882 switch (which_alternative)
1885 return standard_sse_constant_opcode (insn, operands[1]);
1888 /* TDmode values are passed as TImode on the stack. Moving them
1889 to stack may result in unaligned memory access. */
1890 if (misaligned_operand (operands[0], TImode)
1891 || misaligned_operand (operands[1], TImode))
1893 if (get_attr_mode (insn) == MODE_V4SF)
1894 return "%vmovups\t{%1, %0|%0, %1}";
1896 return "%vmovdqu\t{%1, %0|%0, %1}";
1900 if (get_attr_mode (insn) == MODE_V4SF)
1901 return "%vmovaps\t{%1, %0|%0, %1}";
1903 return "%vmovdqa\t{%1, %0|%0, %1}";
1909 [(set_attr "type" "sselog1,ssemov,ssemov")
1910 (set_attr "prefix" "maybe_vex")
1912 (cond [(ior (not (match_test "TARGET_SSE2"))
1913 (match_test "optimize_function_for_size_p (cfun)"))
1914 (const_string "V4SF")
1915 (and (eq_attr "alternative" "2")
1916 (match_test "TARGET_SSE_TYPELESS_STORES"))
1917 (const_string "V4SF")]
1918 (const_string "TI")))])
1920 (define_insn "*movdi_internal_rex64"
1921 [(set (match_operand:DI 0 "nonimmediate_operand"
1922 "=r,r ,r,m ,!o,*y,m*y,?*y,?r ,?*Ym,*x,m ,*x,*x,?r ,?*Yi,?*x,?*Ym")
1923 (match_operand:DI 1 "general_operand"
1924 "Z ,rem,i,re,n ,C ,*y ,m ,*Ym,r ,C ,*x,*x,m ,*Yi,r ,*Ym,*x"))]
1925 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1927 switch (get_attr_type (insn))
1930 if (SSE_REG_P (operands[0]))
1931 return "movq2dq\t{%1, %0|%0, %1}";
1933 return "movdq2q\t{%1, %0|%0, %1}";
1936 if (get_attr_mode (insn) == MODE_TI)
1937 return "%vmovdqa\t{%1, %0|%0, %1}";
1938 /* Handle broken assemblers that require movd instead of movq. */
1939 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1940 return "%vmovd\t{%1, %0|%0, %1}";
1942 return "%vmovq\t{%1, %0|%0, %1}";
1945 /* Handle broken assemblers that require movd instead of movq. */
1946 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
1947 return "movd\t{%1, %0|%0, %1}";
1949 return "movq\t{%1, %0|%0, %1}";
1952 return standard_sse_constant_opcode (insn, operands[1]);
1955 return "pxor\t%0, %0";
1961 return "lea{q}\t{%E1, %0|%0, %E1}";
1964 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1965 if (get_attr_mode (insn) == MODE_SI)
1966 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1967 else if (which_alternative == 2)
1968 return "movabs{q}\t{%1, %0|%0, %1}";
1969 else if (ix86_use_lea_for_mov (insn, operands))
1970 return "lea{q}\t{%E1, %0|%0, %E1}";
1972 return "mov{q}\t{%1, %0|%0, %1}";
1976 (cond [(eq_attr "alternative" "4")
1977 (const_string "multi")
1978 (eq_attr "alternative" "5")
1979 (const_string "mmx")
1980 (eq_attr "alternative" "6,7,8,9")
1981 (const_string "mmxmov")
1982 (eq_attr "alternative" "10")
1983 (const_string "sselog1")
1984 (eq_attr "alternative" "11,12,13,14,15")
1985 (const_string "ssemov")
1986 (eq_attr "alternative" "16,17")
1987 (const_string "ssecvt")
1988 (match_operand 1 "pic_32bit_operand" "")
1989 (const_string "lea")
1991 (const_string "imov")))
1994 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
1996 (const_string "*")))
1997 (set (attr "length_immediate")
1999 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2001 (const_string "*")))
2002 (set (attr "prefix_rex")
2003 (if_then_else (eq_attr "alternative" "8,9")
2005 (const_string "*")))
2006 (set (attr "prefix_data16")
2007 (if_then_else (eq_attr "alternative" "11")
2009 (const_string "*")))
2010 (set (attr "prefix")
2011 (if_then_else (eq_attr "alternative" "10,11,12,13,14,15")
2012 (const_string "maybe_vex")
2013 (const_string "orig")))
2014 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,TI,DI,TI,DI,DI,DI,DI,DI")])
2016 ;; Reload patterns to support multi-word load/store
2017 ;; with non-offsetable address.
2018 (define_expand "reload_noff_store"
2019 [(parallel [(match_operand 0 "memory_operand" "=m")
2020 (match_operand 1 "register_operand" "r")
2021 (match_operand:DI 2 "register_operand" "=&r")])]
2024 rtx mem = operands[0];
2025 rtx addr = XEXP (mem, 0);
2027 emit_move_insn (operands[2], addr);
2028 mem = replace_equiv_address_nv (mem, operands[2]);
2030 emit_insn (gen_rtx_SET (VOIDmode, mem, operands[1]));
2034 (define_expand "reload_noff_load"
2035 [(parallel [(match_operand 0 "register_operand" "=r")
2036 (match_operand 1 "memory_operand" "m")
2037 (match_operand:DI 2 "register_operand" "=r")])]
2040 rtx mem = operands[1];
2041 rtx addr = XEXP (mem, 0);
2043 emit_move_insn (operands[2], addr);
2044 mem = replace_equiv_address_nv (mem, operands[2]);
2046 emit_insn (gen_rtx_SET (VOIDmode, operands[0], mem));
2050 ;; Convert impossible stores of immediate to existing instructions.
2051 ;; First try to get scratch register and go through it. In case this
2052 ;; fails, move by 32bit parts.
2054 [(match_scratch:DI 2 "r")
2055 (set (match_operand:DI 0 "memory_operand" "")
2056 (match_operand:DI 1 "immediate_operand" ""))]
2057 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2058 && !x86_64_immediate_operand (operands[1], DImode)"
2059 [(set (match_dup 2) (match_dup 1))
2060 (set (match_dup 0) (match_dup 2))])
2062 ;; We need to define this as both peepholer and splitter for case
2063 ;; peephole2 pass is not run.
2064 ;; "&& 1" is needed to keep it from matching the previous pattern.
2066 [(set (match_operand:DI 0 "memory_operand" "")
2067 (match_operand:DI 1 "immediate_operand" ""))]
2068 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2069 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2070 [(set (match_dup 2) (match_dup 3))
2071 (set (match_dup 4) (match_dup 5))]
2072 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2075 [(set (match_operand:DI 0 "memory_operand" "")
2076 (match_operand:DI 1 "immediate_operand" ""))]
2077 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2078 ? epilogue_completed : reload_completed)
2079 && !symbolic_operand (operands[1], DImode)
2080 && !x86_64_immediate_operand (operands[1], DImode)"
2081 [(set (match_dup 2) (match_dup 3))
2082 (set (match_dup 4) (match_dup 5))]
2083 "split_double_mode (DImode, &operands[0], 2, &operands[2], &operands[4]);")
2085 (define_insn "*movdi_internal"
2086 [(set (match_operand:DI 0 "nonimmediate_operand"
2087 "=r ,o ,*y,m*y,*y,*x,m ,*x,*x,*x,m ,*x,*x,?*x,?*Ym")
2088 (match_operand:DI 1 "general_operand"
2089 "riFo,riF,C ,*y ,m ,C ,*x,*x,m ,C ,*x,*x,m ,*Ym,*x"))]
2090 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2092 switch (get_attr_type (insn))
2095 if (SSE_REG_P (operands[0]))
2096 return "movq2dq\t{%1, %0|%0, %1}";
2098 return "movdq2q\t{%1, %0|%0, %1}";
2101 switch (get_attr_mode (insn))
2104 return "%vmovdqa\t{%1, %0|%0, %1}";
2106 return "%vmovq\t{%1, %0|%0, %1}";
2108 return "movaps\t{%1, %0|%0, %1}";
2110 return "movlps\t{%1, %0|%0, %1}";
2116 return "movq\t{%1, %0|%0, %1}";
2119 return standard_sse_constant_opcode (insn, operands[1]);
2122 return "pxor\t%0, %0";
2132 (cond [(eq_attr "alternative" "5,6,7,8,13,14")
2133 (const_string "sse2")
2134 (eq_attr "alternative" "9,10,11,12")
2135 (const_string "noavx")
2137 (const_string "*")))
2139 (cond [(eq_attr "alternative" "0,1")
2140 (const_string "multi")
2141 (eq_attr "alternative" "2")
2142 (const_string "mmx")
2143 (eq_attr "alternative" "3,4")
2144 (const_string "mmxmov")
2145 (eq_attr "alternative" "5,9")
2146 (const_string "sselog1")
2147 (eq_attr "alternative" "13,14")
2148 (const_string "ssecvt")
2150 (const_string "ssemov")))
2151 (set (attr "prefix")
2152 (if_then_else (eq_attr "alternative" "5,6,7,8")
2153 (const_string "maybe_vex")
2154 (const_string "orig")))
2155 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF,DI,DI")])
2158 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2159 (match_operand:DI 1 "general_operand" ""))]
2160 "!TARGET_64BIT && reload_completed
2161 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))
2162 && !(MMX_REG_P (operands[1]) || SSE_REG_P (operands[1]))"
2164 "ix86_split_long_move (operands); DONE;")
2166 (define_insn "*movsi_internal"
2167 [(set (match_operand:SI 0 "nonimmediate_operand"
2168 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
2169 (match_operand:SI 1 "general_operand"
2170 "g ,re,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
2171 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2173 switch (get_attr_type (insn))
2176 return standard_sse_constant_opcode (insn, operands[1]);
2179 switch (get_attr_mode (insn))
2182 return "%vmovdqa\t{%1, %0|%0, %1}";
2184 return "%vmovaps\t{%1, %0|%0, %1}";
2186 return "%vmovd\t{%1, %0|%0, %1}";
2188 return "%vmovss\t{%1, %0|%0, %1}";
2194 return "pxor\t%0, %0";
2197 if (get_attr_mode (insn) == MODE_DI)
2198 return "movq\t{%1, %0|%0, %1}";
2199 return "movd\t{%1, %0|%0, %1}";
2202 return "lea{l}\t{%E1, %0|%0, %E1}";
2205 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2206 if (ix86_use_lea_for_mov (insn, operands))
2207 return "lea{l}\t{%E1, %0|%0, %E1}";
2209 return "mov{l}\t{%1, %0|%0, %1}";
2213 (cond [(eq_attr "alternative" "2")
2214 (const_string "mmx")
2215 (eq_attr "alternative" "3,4,5")
2216 (const_string "mmxmov")
2217 (eq_attr "alternative" "6")
2218 (const_string "sselog1")
2219 (eq_attr "alternative" "7,8,9,10,11")
2220 (const_string "ssemov")
2221 (match_operand 1 "pic_32bit_operand" "")
2222 (const_string "lea")
2224 (const_string "imov")))
2225 (set (attr "prefix")
2226 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
2227 (const_string "orig")
2228 (const_string "maybe_vex")))
2229 (set (attr "prefix_data16")
2230 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
2232 (const_string "*")))
2234 (cond [(eq_attr "alternative" "2,3")
2236 (eq_attr "alternative" "6,7")
2238 (not (match_test "TARGET_SSE2"))
2239 (const_string "V4SF")
2240 (const_string "TI"))
2241 (and (eq_attr "alternative" "8,9,10,11")
2242 (not (match_test "TARGET_SSE2")))
2245 (const_string "SI")))])
2247 (define_insn "*movhi_internal"
2248 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
2249 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
2250 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2252 switch (get_attr_type (insn))
2255 /* movzwl is faster than movw on p2 due to partial word stalls,
2256 though not as fast as an aligned movl. */
2257 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
2259 if (get_attr_mode (insn) == MODE_SI)
2260 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2262 return "mov{w}\t{%1, %0|%0, %1}";
2266 (cond [(match_test "optimize_function_for_size_p (cfun)")
2267 (const_string "imov")
2268 (and (eq_attr "alternative" "0")
2269 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2270 (not (match_test "TARGET_HIMODE_MATH"))))
2271 (const_string "imov")
2272 (and (eq_attr "alternative" "1,2")
2273 (match_operand:HI 1 "aligned_operand" ""))
2274 (const_string "imov")
2275 (and (match_test "TARGET_MOVX")
2276 (eq_attr "alternative" "0,2"))
2277 (const_string "imovx")
2279 (const_string "imov")))
2281 (cond [(eq_attr "type" "imovx")
2283 (and (eq_attr "alternative" "1,2")
2284 (match_operand:HI 1 "aligned_operand" ""))
2286 (and (eq_attr "alternative" "0")
2287 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2288 (not (match_test "TARGET_HIMODE_MATH"))))
2291 (const_string "HI")))])
2293 ;; Situation is quite tricky about when to choose full sized (SImode) move
2294 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2295 ;; partial register dependency machines (such as AMD Athlon), where QImode
2296 ;; moves issue extra dependency and for partial register stalls machines
2297 ;; that don't use QImode patterns (and QImode move cause stall on the next
2300 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2301 ;; register stall machines with, where we use QImode instructions, since
2302 ;; partial register stall can be caused there. Then we use movzx.
2303 (define_insn "*movqi_internal"
2304 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2305 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2306 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2308 switch (get_attr_type (insn))
2311 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2312 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2314 if (get_attr_mode (insn) == MODE_SI)
2315 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2317 return "mov{b}\t{%1, %0|%0, %1}";
2321 (cond [(and (eq_attr "alternative" "5")
2322 (not (match_operand:QI 1 "aligned_operand" "")))
2323 (const_string "imovx")
2324 (match_test "optimize_function_for_size_p (cfun)")
2325 (const_string "imov")
2326 (and (eq_attr "alternative" "3")
2327 (ior (not (match_test "TARGET_PARTIAL_REG_STALL"))
2328 (not (match_test "TARGET_QIMODE_MATH"))))
2329 (const_string "imov")
2330 (eq_attr "alternative" "3,5")
2331 (const_string "imovx")
2332 (and (match_test "TARGET_MOVX")
2333 (eq_attr "alternative" "2"))
2334 (const_string "imovx")
2336 (const_string "imov")))
2338 (cond [(eq_attr "alternative" "3,4,5")
2340 (eq_attr "alternative" "6")
2342 (eq_attr "type" "imovx")
2344 (and (eq_attr "type" "imov")
2345 (and (eq_attr "alternative" "0,1")
2346 (and (match_test "TARGET_PARTIAL_REG_DEPENDENCY")
2347 (and (not (match_test "optimize_function_for_size_p (cfun)"))
2348 (not (match_test "TARGET_PARTIAL_REG_STALL"))))))
2350 ;; Avoid partial register stalls when not using QImode arithmetic
2351 (and (eq_attr "type" "imov")
2352 (and (eq_attr "alternative" "0,1")
2353 (and (match_test "TARGET_PARTIAL_REG_STALL")
2354 (not (match_test "TARGET_QIMODE_MATH")))))
2357 (const_string "QI")))])
2359 ;; Stores and loads of ax to arbitrary constant address.
2360 ;; We fake an second form of instruction to force reload to load address
2361 ;; into register when rax is not available
2362 (define_insn "*movabs<mode>_1"
2363 [(set (mem:SWI1248x (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2364 (match_operand:SWI1248x 1 "nonmemory_operand" "a,r<i>"))]
2365 "TARGET_LP64 && ix86_check_movabs (insn, 0)"
2367 movabs{<imodesuffix>}\t{%1, %P0|%P0, %1}
2368 mov{<imodesuffix>}\t{%1, %a0|%a0, %1}"
2369 [(set_attr "type" "imov")
2370 (set_attr "modrm" "0,*")
2371 (set_attr "length_address" "8,0")
2372 (set_attr "length_immediate" "0,*")
2373 (set_attr "memory" "store")
2374 (set_attr "mode" "<MODE>")])
2376 (define_insn "*movabs<mode>_2"
2377 [(set (match_operand:SWI1248x 0 "register_operand" "=a,r")
2378 (mem:SWI1248x (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2379 "TARGET_LP64 && ix86_check_movabs (insn, 1)"
2381 movabs{<imodesuffix>}\t{%P1, %0|%0, %P1}
2382 mov{<imodesuffix>}\t{%a1, %0|%0, %a1}"
2383 [(set_attr "type" "imov")
2384 (set_attr "modrm" "0,*")
2385 (set_attr "length_address" "8,0")
2386 (set_attr "length_immediate" "0")
2387 (set_attr "memory" "load")
2388 (set_attr "mode" "<MODE>")])
2390 (define_insn "*swap<mode>"
2391 [(set (match_operand:SWI48 0 "register_operand" "+r")
2392 (match_operand:SWI48 1 "register_operand" "+r"))
2396 "xchg{<imodesuffix>}\t%1, %0"
2397 [(set_attr "type" "imov")
2398 (set_attr "mode" "<MODE>")
2399 (set_attr "pent_pair" "np")
2400 (set_attr "athlon_decode" "vector")
2401 (set_attr "amdfam10_decode" "double")
2402 (set_attr "bdver1_decode" "double")])
2404 (define_insn "*swap<mode>_1"
2405 [(set (match_operand:SWI12 0 "register_operand" "+r")
2406 (match_operand:SWI12 1 "register_operand" "+r"))
2409 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2411 [(set_attr "type" "imov")
2412 (set_attr "mode" "SI")
2413 (set_attr "pent_pair" "np")
2414 (set_attr "athlon_decode" "vector")
2415 (set_attr "amdfam10_decode" "double")
2416 (set_attr "bdver1_decode" "double")])
2418 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL
2419 ;; is disabled for AMDFAM10
2420 (define_insn "*swap<mode>_2"
2421 [(set (match_operand:SWI12 0 "register_operand" "+<r>")
2422 (match_operand:SWI12 1 "register_operand" "+<r>"))
2425 "TARGET_PARTIAL_REG_STALL"
2426 "xchg{<imodesuffix>}\t%1, %0"
2427 [(set_attr "type" "imov")
2428 (set_attr "mode" "<MODE>")
2429 (set_attr "pent_pair" "np")
2430 (set_attr "athlon_decode" "vector")])
2432 (define_expand "movstrict<mode>"
2433 [(set (strict_low_part (match_operand:SWI12 0 "nonimmediate_operand" ""))
2434 (match_operand:SWI12 1 "general_operand" ""))]
2437 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2439 if (GET_CODE (operands[0]) == SUBREG
2440 && GET_MODE_CLASS (GET_MODE (SUBREG_REG (operands[0]))) != MODE_INT)
2442 /* Don't generate memory->memory moves, go through a register */
2443 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2444 operands[1] = force_reg (<MODE>mode, operands[1]);
2447 (define_insn "*movstrict<mode>_1"
2448 [(set (strict_low_part
2449 (match_operand:SWI12 0 "nonimmediate_operand" "+<r>m,<r>"))
2450 (match_operand:SWI12 1 "general_operand" "<r>n,m"))]
2451 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2452 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2453 "mov{<imodesuffix>}\t{%1, %0|%0, %1}"
2454 [(set_attr "type" "imov")
2455 (set_attr "mode" "<MODE>")])
2457 (define_insn "*movstrict<mode>_xor"
2458 [(set (strict_low_part (match_operand:SWI12 0 "register_operand" "+<r>"))
2459 (match_operand:SWI12 1 "const0_operand" ""))
2460 (clobber (reg:CC FLAGS_REG))]
2462 "xor{<imodesuffix>}\t%0, %0"
2463 [(set_attr "type" "alu1")
2464 (set_attr "mode" "<MODE>")
2465 (set_attr "length_immediate" "0")])
2467 (define_insn "*mov<mode>_extv_1"
2468 [(set (match_operand:SWI24 0 "register_operand" "=R")
2469 (sign_extract:SWI24 (match_operand 1 "ext_register_operand" "Q")
2473 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2474 [(set_attr "type" "imovx")
2475 (set_attr "mode" "SI")])
2477 (define_insn "*movqi_extv_1_rex64"
2478 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2479 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2484 switch (get_attr_type (insn))
2487 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2489 return "mov{b}\t{%h1, %0|%0, %h1}";
2493 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2494 (match_test "TARGET_MOVX"))
2495 (const_string "imovx")
2496 (const_string "imov")))
2498 (if_then_else (eq_attr "type" "imovx")
2500 (const_string "QI")))])
2502 (define_insn "*movqi_extv_1"
2503 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2504 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2509 switch (get_attr_type (insn))
2512 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2514 return "mov{b}\t{%h1, %0|%0, %h1}";
2518 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2519 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2520 (match_test "TARGET_MOVX")))
2521 (const_string "imovx")
2522 (const_string "imov")))
2524 (if_then_else (eq_attr "type" "imovx")
2526 (const_string "QI")))])
2528 (define_insn "*mov<mode>_extzv_1"
2529 [(set (match_operand:SWI48 0 "register_operand" "=R")
2530 (zero_extract:SWI48 (match_operand 1 "ext_register_operand" "Q")
2534 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2535 [(set_attr "type" "imovx")
2536 (set_attr "mode" "SI")])
2538 (define_insn "*movqi_extzv_2_rex64"
2539 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2541 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2546 switch (get_attr_type (insn))
2549 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2551 return "mov{b}\t{%h1, %0|%0, %h1}";
2555 (if_then_else (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2556 (match_test "TARGET_MOVX"))
2557 (const_string "imovx")
2558 (const_string "imov")))
2560 (if_then_else (eq_attr "type" "imovx")
2562 (const_string "QI")))])
2564 (define_insn "*movqi_extzv_2"
2565 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2567 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2572 switch (get_attr_type (insn))
2575 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2577 return "mov{b}\t{%h1, %0|%0, %h1}";
2581 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2582 (ior (not (match_operand:QI 0 "QIreg_operand" ""))
2583 (match_test "TARGET_MOVX")))
2584 (const_string "imovx")
2585 (const_string "imov")))
2587 (if_then_else (eq_attr "type" "imovx")
2589 (const_string "QI")))])
2591 (define_expand "mov<mode>_insv_1"
2592 [(set (zero_extract:SWI48 (match_operand 0 "ext_register_operand" "")
2595 (match_operand:SWI48 1 "nonmemory_operand" ""))])
2597 (define_insn "*mov<mode>_insv_1_rex64"
2598 [(set (zero_extract:SWI48x (match_operand 0 "ext_register_operand" "+Q")
2601 (match_operand:SWI48x 1 "nonmemory_operand" "Qn"))]
2603 "mov{b}\t{%b1, %h0|%h0, %b1}"
2604 [(set_attr "type" "imov")
2605 (set_attr "mode" "QI")])
2607 (define_insn "*movsi_insv_1"
2608 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2611 (match_operand:SI 1 "general_operand" "Qmn"))]
2613 "mov{b}\t{%b1, %h0|%h0, %b1}"
2614 [(set_attr "type" "imov")
2615 (set_attr "mode" "QI")])
2617 (define_insn "*movqi_insv_2"
2618 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2621 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2624 "mov{b}\t{%h1, %h0|%h0, %h1}"
2625 [(set_attr "type" "imov")
2626 (set_attr "mode" "QI")])
2628 ;; Floating point push instructions.
2630 (define_insn "*pushtf"
2631 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
2632 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
2635 /* This insn should be already split before reg-stack. */
2638 [(set_attr "type" "multi")
2639 (set_attr "unit" "sse,*,*")
2640 (set_attr "mode" "TF,SI,SI")])
2642 ;; %%% Kill this when call knows how to work this out.
2644 [(set (match_operand:TF 0 "push_operand" "")
2645 (match_operand:TF 1 "sse_reg_operand" ""))]
2646 "TARGET_SSE2 && reload_completed"
2647 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
2648 (set (mem:TF (reg:P SP_REG)) (match_dup 1))])
2650 (define_insn "*pushxf"
2651 [(set (match_operand:XF 0 "push_operand" "=<,<")
2652 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
2653 "optimize_function_for_speed_p (cfun)"
2655 /* This insn should be already split before reg-stack. */
2658 [(set_attr "type" "multi")
2659 (set_attr "unit" "i387,*")
2660 (set_attr "mode" "XF,SI")])
2662 ;; Size of pushxf is 3 (for sub) + 2 (for fstp) + memory operand size.
2663 ;; Size of pushxf using integer instructions is 3+3*memory operand size
2664 ;; Pushing using integer instructions is longer except for constants
2665 ;; and direct memory references (assuming that any given constant is pushed
2666 ;; only once, but this ought to be handled elsewhere).
2668 (define_insn "*pushxf_nointeger"
2669 [(set (match_operand:XF 0 "push_operand" "=<,<")
2670 (match_operand:XF 1 "general_no_elim_operand" "f,*rFo"))]
2671 "optimize_function_for_size_p (cfun)"
2673 /* This insn should be already split before reg-stack. */
2676 [(set_attr "type" "multi")
2677 (set_attr "unit" "i387,*")
2678 (set_attr "mode" "XF,SI")])
2680 ;; %%% Kill this when call knows how to work this out.
2682 [(set (match_operand:XF 0 "push_operand" "")
2683 (match_operand:XF 1 "fp_register_operand" ""))]
2685 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2686 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
2687 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
2689 (define_insn "*pushdf_rex64"
2690 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2691 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFm,x"))]
2694 /* This insn should be already split before reg-stack. */
2697 [(set_attr "type" "multi")
2698 (set_attr "unit" "i387,*,*")
2699 (set_attr "mode" "DF,DI,DF")])
2701 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2702 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2703 ;; On the average, pushdf using integers can be still shorter.
2705 (define_insn "*pushdf"
2706 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2707 (match_operand:DF 1 "general_no_elim_operand" "f,Yd*rFo,x"))]
2710 /* This insn should be already split before reg-stack. */
2713 [(set_attr "isa" "*,*,sse2")
2714 (set_attr "type" "multi")
2715 (set_attr "unit" "i387,*,*")
2716 (set_attr "mode" "DF,DI,DF")])
2718 ;; %%% Kill this when call knows how to work this out.
2720 [(set (match_operand:DF 0 "push_operand" "")
2721 (match_operand:DF 1 "any_fp_register_operand" ""))]
2723 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2724 (set (mem:DF (reg:P SP_REG)) (match_dup 1))])
2726 (define_insn "*pushsf_rex64"
2727 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2728 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2731 /* Anything else should be already split before reg-stack. */
2732 gcc_assert (which_alternative == 1);
2733 return "push{q}\t%q1";
2735 [(set_attr "type" "multi,push,multi")
2736 (set_attr "unit" "i387,*,*")
2737 (set_attr "mode" "SF,DI,SF")])
2739 (define_insn "*pushsf"
2740 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2741 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2744 /* Anything else should be already split before reg-stack. */
2745 gcc_assert (which_alternative == 1);
2746 return "push{l}\t%1";
2748 [(set_attr "type" "multi,push,multi")
2749 (set_attr "unit" "i387,*,*")
2750 (set_attr "mode" "SF,SI,SF")])
2752 ;; %%% Kill this when call knows how to work this out.
2754 [(set (match_operand:SF 0 "push_operand" "")
2755 (match_operand:SF 1 "any_fp_register_operand" ""))]
2757 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
2758 (set (mem:SF (reg:P SP_REG)) (match_dup 1))]
2759 "operands[2] = GEN_INT (-GET_MODE_SIZE (<P:MODE>mode));")
2762 [(set (match_operand:SF 0 "push_operand" "")
2763 (match_operand:SF 1 "memory_operand" ""))]
2765 && (operands[2] = find_constant_src (insn))"
2766 [(set (match_dup 0) (match_dup 2))])
2769 [(set (match_operand 0 "push_operand" "")
2770 (match_operand 1 "general_operand" ""))]
2772 && (GET_MODE (operands[0]) == TFmode
2773 || GET_MODE (operands[0]) == XFmode
2774 || GET_MODE (operands[0]) == DFmode)
2775 && !ANY_FP_REG_P (operands[1])"
2777 "ix86_split_long_move (operands); DONE;")
2779 ;; Floating point move instructions.
2781 (define_expand "movtf"
2782 [(set (match_operand:TF 0 "nonimmediate_operand" "")
2783 (match_operand:TF 1 "nonimmediate_operand" ""))]
2786 ix86_expand_move (TFmode, operands);
2790 (define_expand "mov<mode>"
2791 [(set (match_operand:X87MODEF 0 "nonimmediate_operand" "")
2792 (match_operand:X87MODEF 1 "general_operand" ""))]
2794 "ix86_expand_move (<MODE>mode, operands); DONE;")
2796 (define_insn "*movtf_internal"
2797 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?*r ,!o")
2798 (match_operand:TF 1 "general_operand" "xm,x,C,*roF,F*r"))]
2800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2801 && (!can_create_pseudo_p ()
2802 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2803 || GET_CODE (operands[1]) != CONST_DOUBLE
2804 || (optimize_function_for_size_p (cfun)
2805 && standard_sse_constant_p (operands[1])
2806 && !memory_operand (operands[0], TFmode))
2807 || (!TARGET_MEMORY_MISMATCH_STALL
2808 && memory_operand (operands[0], TFmode)))"
2810 switch (which_alternative)
2814 /* Handle misaligned load/store since we
2815 don't have movmisaligntf pattern. */
2816 if (misaligned_operand (operands[0], TFmode)
2817 || misaligned_operand (operands[1], TFmode))
2819 if (get_attr_mode (insn) == MODE_V4SF)
2820 return "%vmovups\t{%1, %0|%0, %1}";
2822 return "%vmovdqu\t{%1, %0|%0, %1}";
2826 if (get_attr_mode (insn) == MODE_V4SF)
2827 return "%vmovaps\t{%1, %0|%0, %1}";
2829 return "%vmovdqa\t{%1, %0|%0, %1}";
2833 return standard_sse_constant_opcode (insn, operands[1]);
2843 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
2844 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
2846 (cond [(eq_attr "alternative" "0,2")
2848 (match_test "optimize_function_for_size_p (cfun)")
2849 (const_string "V4SF")
2850 (const_string "TI"))
2851 (eq_attr "alternative" "1")
2853 (ior (match_test "TARGET_SSE_TYPELESS_STORES")
2854 (match_test "optimize_function_for_size_p (cfun)"))
2855 (const_string "V4SF")
2856 (const_string "TI"))]
2857 (const_string "DI")))])
2859 ;; Possible store forwarding (partial memory) stall in alternative 4.
2860 (define_insn "*movxf_internal"
2861 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,?Yx*r ,!o")
2862 (match_operand:XF 1 "general_operand" "fm,f,G,Yx*roF,FYx*r"))]
2863 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2864 && (!can_create_pseudo_p ()
2865 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2866 || GET_CODE (operands[1]) != CONST_DOUBLE
2867 || (optimize_function_for_size_p (cfun)
2868 && standard_80387_constant_p (operands[1]) > 0
2869 && !memory_operand (operands[0], XFmode))
2870 || (!TARGET_MEMORY_MISMATCH_STALL
2871 && memory_operand (operands[0], XFmode)))"
2873 switch (which_alternative)
2877 return output_387_reg_move (insn, operands);
2880 return standard_80387_constant_opcode (operands[1]);
2890 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
2891 (set_attr "mode" "XF,XF,XF,SI,SI")])
2893 (define_insn "*movdf_internal_rex64"
2894 [(set (match_operand:DF 0 "nonimmediate_operand"
2895 "=f,m,f,?r,?m,?r,!o,x,x,x,m,Yi,r ")
2896 (match_operand:DF 1 "general_operand"
2897 "fm,f,G,rm,r ,F ,F ,C,x,m,x,r ,Yi"))]
2898 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
2899 && (!can_create_pseudo_p ()
2900 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2901 || GET_CODE (operands[1]) != CONST_DOUBLE
2902 || (optimize_function_for_size_p (cfun)
2903 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
2904 && standard_80387_constant_p (operands[1]) > 0)
2905 || (TARGET_SSE2 && TARGET_SSE_MATH
2906 && standard_sse_constant_p (operands[1]))))
2907 || memory_operand (operands[0], DFmode))"
2909 switch (which_alternative)
2913 return output_387_reg_move (insn, operands);
2916 return standard_80387_constant_opcode (operands[1]);
2920 return "mov{q}\t{%1, %0|%0, %1}";
2923 return "movabs{q}\t{%1, %0|%0, %1}";
2929 return standard_sse_constant_opcode (insn, operands[1]);
2934 switch (get_attr_mode (insn))
2937 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
2938 return "%vmovapd\t{%1, %0|%0, %1}";
2940 return "%vmovaps\t{%1, %0|%0, %1}";
2943 return "%vmovq\t{%1, %0|%0, %1}";
2945 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
2946 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
2947 return "%vmovsd\t{%1, %0|%0, %1}";
2949 return "%vmovlpd\t{%1, %d0|%d0, %1}";
2951 return "%vmovlps\t{%1, %d0|%d0, %1}";
2958 /* Handle broken assemblers that require movd instead of movq. */
2959 return "%vmovd\t{%1, %0|%0, %1}";
2966 (cond [(eq_attr "alternative" "0,1,2")
2967 (const_string "fmov")
2968 (eq_attr "alternative" "3,4,5")
2969 (const_string "imov")
2970 (eq_attr "alternative" "6")
2971 (const_string "multi")
2972 (eq_attr "alternative" "7")
2973 (const_string "sselog1")
2975 (const_string "ssemov")))
2978 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2980 (const_string "*")))
2981 (set (attr "length_immediate")
2983 (and (eq_attr "alternative" "5") (eq_attr "type" "imov"))
2985 (const_string "*")))
2986 (set (attr "prefix")
2987 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5,6")
2988 (const_string "orig")
2989 (const_string "maybe_vex")))
2990 (set (attr "prefix_data16")
2991 (if_then_else (eq_attr "mode" "V1DF")
2993 (const_string "*")))
2995 (cond [(eq_attr "alternative" "0,1,2")
2997 (eq_attr "alternative" "3,4,5,6,11,12")
3000 /* xorps is one byte shorter. */
3001 (eq_attr "alternative" "7")
3002 (cond [(match_test "optimize_function_for_size_p (cfun)")
3003 (const_string "V4SF")
3004 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3007 (const_string "V2DF"))
3009 /* For architectures resolving dependencies on
3010 whole SSE registers use APD move to break dependency
3011 chains, otherwise use short move to avoid extra work.
3013 movaps encodes one byte shorter. */
3014 (eq_attr "alternative" "8")
3016 [(match_test "optimize_function_for_size_p (cfun)")
3017 (const_string "V4SF")
3018 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3019 (const_string "V2DF")
3021 (const_string "DF"))
3022 /* For architectures resolving dependencies on register
3023 parts we may avoid extra work to zero out upper part
3025 (eq_attr "alternative" "9")
3027 (match_test "TARGET_SSE_SPLIT_REGS")
3028 (const_string "V1DF")
3029 (const_string "DF"))
3031 (const_string "DF")))])
3033 ;; Possible store forwarding (partial memory) stall in alternative 4.
3034 (define_insn "*movdf_internal"
3035 [(set (match_operand:DF 0 "nonimmediate_operand"
3036 "=f,m,f,?Yd*r ,!o ,x,x,x,m,*x,*x,*x,m")
3037 (match_operand:DF 1 "general_operand"
3038 "fm,f,G,Yd*roF,FYd*r,C,x,m,x,C ,*x,m ,*x"))]
3039 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3040 && (!can_create_pseudo_p ()
3041 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3042 || GET_CODE (operands[1]) != CONST_DOUBLE
3043 || (optimize_function_for_size_p (cfun)
3044 && ((!(TARGET_SSE2 && TARGET_SSE_MATH)
3045 && standard_80387_constant_p (operands[1]) > 0)
3046 || (TARGET_SSE2 && TARGET_SSE_MATH
3047 && standard_sse_constant_p (operands[1])))
3048 && !memory_operand (operands[0], DFmode))
3049 || (!TARGET_MEMORY_MISMATCH_STALL
3050 && memory_operand (operands[0], DFmode)))"
3052 switch (which_alternative)
3056 return output_387_reg_move (insn, operands);
3059 return standard_80387_constant_opcode (operands[1]);
3067 return standard_sse_constant_opcode (insn, operands[1]);
3075 switch (get_attr_mode (insn))
3078 if (!TARGET_SSE_PACKED_SINGLE_INSN_OPTIMAL)
3079 return "%vmovapd\t{%1, %0|%0, %1}";
3081 return "%vmovaps\t{%1, %0|%0, %1}";
3084 return "%vmovq\t{%1, %0|%0, %1}";
3086 if (TARGET_AVX && REG_P (operands[0]) && REG_P (operands[1]))
3087 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3088 return "%vmovsd\t{%1, %0|%0, %1}";
3090 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3092 return "%vmovlps\t{%1, %d0|%d0, %1}";
3102 (if_then_else (eq_attr "alternative" "5,6,7,8")
3103 (const_string "sse2")
3104 (const_string "*")))
3106 (cond [(eq_attr "alternative" "0,1,2")
3107 (const_string "fmov")
3108 (eq_attr "alternative" "3,4")
3109 (const_string "multi")
3110 (eq_attr "alternative" "5,9")
3111 (const_string "sselog1")
3113 (const_string "ssemov")))
3114 (set (attr "prefix")
3115 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3116 (const_string "orig")
3117 (const_string "maybe_vex")))
3118 (set (attr "prefix_data16")
3119 (if_then_else (eq_attr "mode" "V1DF")
3121 (const_string "*")))
3123 (cond [(eq_attr "alternative" "0,1,2")
3125 (eq_attr "alternative" "3,4")
3128 /* For SSE1, we have many fewer alternatives. */
3129 (not (match_test "TARGET_SSE2"))
3131 (eq_attr "alternative" "5,6,9,10")
3132 (const_string "V4SF")
3133 (const_string "V2SF"))
3135 /* xorps is one byte shorter. */
3136 (eq_attr "alternative" "5,9")
3137 (cond [(match_test "optimize_function_for_size_p (cfun)")
3138 (const_string "V4SF")
3139 (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3142 (const_string "V2DF"))
3144 /* For architectures resolving dependencies on
3145 whole SSE registers use APD move to break dependency
3146 chains, otherwise use short move to avoid extra work.
3148 movaps encodes one byte shorter. */
3149 (eq_attr "alternative" "6,10")
3151 [(match_test "optimize_function_for_size_p (cfun)")
3152 (const_string "V4SF")
3153 (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3154 (const_string "V2DF")
3156 (const_string "DF"))
3157 /* For architectures resolving dependencies on register
3158 parts we may avoid extra work to zero out upper part
3160 (eq_attr "alternative" "7,11")
3162 (match_test "TARGET_SSE_SPLIT_REGS")
3163 (const_string "V1DF")
3164 (const_string "DF"))
3166 (const_string "DF")))])
3168 (define_insn "*movsf_internal"
3169 [(set (match_operand:SF 0 "nonimmediate_operand"
3170 "=f,m,f,?r ,?m,x,x,x,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3171 (match_operand:SF 1 "general_operand"
3172 "fm,f,G,rmF,Fr,C,x,m,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3173 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3174 && (!can_create_pseudo_p ()
3175 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3176 || GET_CODE (operands[1]) != CONST_DOUBLE
3177 || (optimize_function_for_size_p (cfun)
3178 && ((!TARGET_SSE_MATH
3179 && standard_80387_constant_p (operands[1]) > 0)
3181 && standard_sse_constant_p (operands[1]))))
3182 || memory_operand (operands[0], SFmode))"
3184 switch (which_alternative)
3188 return output_387_reg_move (insn, operands);
3191 return standard_80387_constant_opcode (operands[1]);
3195 return "mov{l}\t{%1, %0|%0, %1}";
3198 return standard_sse_constant_opcode (insn, operands[1]);
3201 if (get_attr_mode (insn) == MODE_V4SF)
3202 return "%vmovaps\t{%1, %0|%0, %1}";
3204 return "vmovss\t{%1, %0, %0|%0, %0, %1}";
3208 return "%vmovss\t{%1, %0|%0, %1}";
3214 return "movd\t{%1, %0|%0, %1}";
3217 return "movq\t{%1, %0|%0, %1}";
3221 return "%vmovd\t{%1, %0|%0, %1}";
3228 (cond [(eq_attr "alternative" "0,1,2")
3229 (const_string "fmov")
3230 (eq_attr "alternative" "3,4")
3231 (const_string "multi")
3232 (eq_attr "alternative" "5")
3233 (const_string "sselog1")
3234 (eq_attr "alternative" "9,10,11,14,15")
3235 (const_string "mmxmov")
3237 (const_string "ssemov")))
3238 (set (attr "prefix")
3239 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3240 (const_string "maybe_vex")
3241 (const_string "orig")))
3243 (cond [(eq_attr "alternative" "3,4,9,10")
3245 (eq_attr "alternative" "5")
3247 (and (and (match_test "TARGET_SSE_LOAD0_BY_PXOR")
3248 (match_test "TARGET_SSE2"))
3249 (not (match_test "optimize_function_for_size_p (cfun)")))
3251 (const_string "V4SF"))
3252 /* For architectures resolving dependencies on
3253 whole SSE registers use APS move to break dependency
3254 chains, otherwise use short move to avoid extra work.
3256 Do the same for architectures resolving dependencies on
3257 the parts. While in DF mode it is better to always handle
3258 just register parts, the SF mode is different due to lack
3259 of instructions to load just part of the register. It is
3260 better to maintain the whole registers in single format
3261 to avoid problems on using packed logical operations. */
3262 (eq_attr "alternative" "6")
3264 (ior (match_test "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3265 (match_test "TARGET_SSE_SPLIT_REGS"))
3266 (const_string "V4SF")
3267 (const_string "SF"))
3268 (eq_attr "alternative" "11")
3269 (const_string "DI")]
3270 (const_string "SF")))])
3273 [(set (match_operand 0 "any_fp_register_operand" "")
3274 (match_operand 1 "memory_operand" ""))]
3276 && (GET_MODE (operands[0]) == TFmode
3277 || GET_MODE (operands[0]) == XFmode
3278 || GET_MODE (operands[0]) == DFmode
3279 || GET_MODE (operands[0]) == SFmode)
3280 && (operands[2] = find_constant_src (insn))"
3281 [(set (match_dup 0) (match_dup 2))]
3283 rtx c = operands[2];
3284 int r = REGNO (operands[0]);
3286 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3287 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3292 [(set (match_operand 0 "any_fp_register_operand" "")
3293 (float_extend (match_operand 1 "memory_operand" "")))]
3295 && (GET_MODE (operands[0]) == TFmode
3296 || GET_MODE (operands[0]) == XFmode
3297 || GET_MODE (operands[0]) == DFmode)
3298 && (operands[2] = find_constant_src (insn))"
3299 [(set (match_dup 0) (match_dup 2))]
3301 rtx c = operands[2];
3302 int r = REGNO (operands[0]);
3304 if ((SSE_REGNO_P (r) && !standard_sse_constant_p (c))
3305 || (FP_REGNO_P (r) && standard_80387_constant_p (c) < 1))
3309 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3311 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
3312 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3314 && (standard_80387_constant_p (operands[1]) == 8
3315 || standard_80387_constant_p (operands[1]) == 9)"
3316 [(set (match_dup 0)(match_dup 1))
3318 (neg:X87MODEF (match_dup 0)))]
3322 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3323 if (real_isnegzero (&r))
3324 operands[1] = CONST0_RTX (<MODE>mode);
3326 operands[1] = CONST1_RTX (<MODE>mode);
3330 [(set (match_operand 0 "nonimmediate_operand" "")
3331 (match_operand 1 "general_operand" ""))]
3333 && (GET_MODE (operands[0]) == TFmode
3334 || GET_MODE (operands[0]) == XFmode
3335 || GET_MODE (operands[0]) == DFmode)
3336 && !(ANY_FP_REG_P (operands[0]) || ANY_FP_REG_P (operands[1]))"
3338 "ix86_split_long_move (operands); DONE;")
3340 (define_insn "swapxf"
3341 [(set (match_operand:XF 0 "register_operand" "+f")
3342 (match_operand:XF 1 "register_operand" "+f"))
3347 if (STACK_TOP_P (operands[0]))
3352 [(set_attr "type" "fxch")
3353 (set_attr "mode" "XF")])
3355 (define_insn "*swap<mode>"
3356 [(set (match_operand:MODEF 0 "fp_register_operand" "+f")
3357 (match_operand:MODEF 1 "fp_register_operand" "+f"))
3360 "TARGET_80387 || reload_completed"
3362 if (STACK_TOP_P (operands[0]))
3367 [(set_attr "type" "fxch")
3368 (set_attr "mode" "<MODE>")])
3370 ;; Zero extension instructions
3372 (define_expand "zero_extendsidi2"
3373 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3374 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3379 emit_insn (gen_zero_extendsidi2_1 (operands[0], operands[1]));
3384 (define_insn "*zero_extendsidi2_rex64"
3385 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*x")
3387 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3390 mov{l}\t{%1, %k0|%k0, %1}
3392 movd\t{%1, %0|%0, %1}
3393 movd\t{%1, %0|%0, %1}
3394 %vmovd\t{%1, %0|%0, %1}
3395 %vmovd\t{%1, %0|%0, %1}"
3396 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
3397 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
3398 (set_attr "prefix_0f" "0,*,*,*,*,*")
3399 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
3402 [(set (match_operand:DI 0 "memory_operand" "")
3403 (zero_extend:DI (match_dup 0)))]
3405 [(set (match_dup 4) (const_int 0))]
3406 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3408 ;; %%% Kill me once multi-word ops are sane.
3409 (define_insn "zero_extendsidi2_1"
3410 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*x")
3412 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3413 (clobber (reg:CC FLAGS_REG))]
3419 movd\t{%1, %0|%0, %1}
3420 movd\t{%1, %0|%0, %1}
3421 %vmovd\t{%1, %0|%0, %1}
3422 %vmovd\t{%1, %0|%0, %1}"
3423 [(set_attr "isa" "*,*,*,*,*,*,sse2")
3424 (set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3425 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3426 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3429 [(set (match_operand:DI 0 "register_operand" "")
3430 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
3431 (clobber (reg:CC FLAGS_REG))]
3432 "!TARGET_64BIT && reload_completed
3433 && true_regnum (operands[0]) == true_regnum (operands[1])"
3434 [(set (match_dup 4) (const_int 0))]
3435 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3438 [(set (match_operand:DI 0 "nonimmediate_operand" "")
3439 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
3440 (clobber (reg:CC FLAGS_REG))]
3441 "!TARGET_64BIT && reload_completed
3442 && !(MMX_REG_P (operands[0]) || SSE_REG_P (operands[0]))"
3443 [(set (match_dup 3) (match_dup 1))
3444 (set (match_dup 4) (const_int 0))]
3445 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3447 (define_insn "zero_extend<mode>di2"
3448 [(set (match_operand:DI 0 "register_operand" "=r")
3450 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3452 "movz{<imodesuffix>l|x}\t{%1, %k0|%k0, %1}"
3453 [(set_attr "type" "imovx")
3454 (set_attr "mode" "SI")])
3456 (define_expand "zero_extendhisi2"
3457 [(set (match_operand:SI 0 "register_operand" "")
3458 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3461 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3463 operands[1] = force_reg (HImode, operands[1]);
3464 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3469 (define_insn_and_split "zero_extendhisi2_and"
3470 [(set (match_operand:SI 0 "register_operand" "=r")
3471 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3472 (clobber (reg:CC FLAGS_REG))]
3473 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3475 "&& reload_completed"
3476 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3477 (clobber (reg:CC FLAGS_REG))])]
3479 [(set_attr "type" "alu1")
3480 (set_attr "mode" "SI")])
3482 (define_insn "*zero_extendhisi2_movzwl"
3483 [(set (match_operand:SI 0 "register_operand" "=r")
3484 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3485 "!TARGET_ZERO_EXTEND_WITH_AND
3486 || optimize_function_for_size_p (cfun)"
3487 "movz{wl|x}\t{%1, %0|%0, %1}"
3488 [(set_attr "type" "imovx")
3489 (set_attr "mode" "SI")])
3491 (define_expand "zero_extendqi<mode>2"
3493 [(set (match_operand:SWI24 0 "register_operand" "")
3494 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3495 (clobber (reg:CC FLAGS_REG))])])
3497 (define_insn "*zero_extendqi<mode>2_and"
3498 [(set (match_operand:SWI24 0 "register_operand" "=r,?&q")
3499 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3500 (clobber (reg:CC FLAGS_REG))]
3501 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3503 [(set_attr "type" "alu1")
3504 (set_attr "mode" "<MODE>")])
3506 ;; When source and destination does not overlap, clear destination
3507 ;; first and then do the movb
3509 [(set (match_operand:SWI24 0 "register_operand" "")
3510 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3511 (clobber (reg:CC FLAGS_REG))]
3513 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3514 && ANY_QI_REG_P (operands[0])
3515 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3516 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3517 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3519 operands[2] = gen_lowpart (QImode, operands[0]);
3520 ix86_expand_clear (operands[0]);
3523 (define_insn "*zero_extendqi<mode>2_movzbl_and"
3524 [(set (match_operand:SWI24 0 "register_operand" "=r,r")
3525 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3526 (clobber (reg:CC FLAGS_REG))]
3527 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3529 [(set_attr "type" "imovx,alu1")
3530 (set_attr "mode" "<MODE>")])
3532 ;; For the movzbl case strip only the clobber
3534 [(set (match_operand:SWI24 0 "register_operand" "")
3535 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "")))
3536 (clobber (reg:CC FLAGS_REG))]
3538 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3539 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3541 (zero_extend:SWI24 (match_dup 1)))])
3543 ; zero extend to SImode to avoid partial register stalls
3544 (define_insn "*zero_extendqi<mode>2_movzbl"
3545 [(set (match_operand:SWI24 0 "register_operand" "=r")
3546 (zero_extend:SWI24 (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3548 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
3549 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3550 [(set_attr "type" "imovx")
3551 (set_attr "mode" "SI")])
3553 ;; Rest is handled by single and.
3555 [(set (match_operand:SWI24 0 "register_operand" "")
3556 (zero_extend:SWI24 (match_operand:QI 1 "register_operand" "")))
3557 (clobber (reg:CC FLAGS_REG))]
3559 && true_regnum (operands[0]) == true_regnum (operands[1])"
3560 [(parallel [(set (match_dup 0) (and:SWI24 (match_dup 0) (const_int 255)))
3561 (clobber (reg:CC FLAGS_REG))])])
3563 ;; Sign extension instructions
3565 (define_expand "extendsidi2"
3566 [(set (match_operand:DI 0 "register_operand" "")
3567 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))]
3572 emit_insn (gen_extendsidi2_1 (operands[0], operands[1]));
3577 (define_insn "*extendsidi2_rex64"
3578 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3579 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
3583 movs{lq|x}\t{%1, %0|%0, %1}"
3584 [(set_attr "type" "imovx")
3585 (set_attr "mode" "DI")
3586 (set_attr "prefix_0f" "0")
3587 (set_attr "modrm" "0,1")])
3589 (define_insn "extendsidi2_1"
3590 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
3591 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
3592 (clobber (reg:CC FLAGS_REG))
3593 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
3597 ;; Extend to memory case when source register does die.
3599 [(set (match_operand:DI 0 "memory_operand" "")
3600 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3601 (clobber (reg:CC FLAGS_REG))
3602 (clobber (match_operand:SI 2 "register_operand" ""))]
3604 && dead_or_set_p (insn, operands[1])
3605 && !reg_mentioned_p (operands[1], operands[0]))"
3606 [(set (match_dup 3) (match_dup 1))
3607 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
3608 (clobber (reg:CC FLAGS_REG))])
3609 (set (match_dup 4) (match_dup 1))]
3610 "split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);")
3612 ;; Extend to memory case when source register does not die.
3614 [(set (match_operand:DI 0 "memory_operand" "")
3615 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3616 (clobber (reg:CC FLAGS_REG))
3617 (clobber (match_operand:SI 2 "register_operand" ""))]
3621 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3623 emit_move_insn (operands[3], operands[1]);
3625 /* Generate a cltd if possible and doing so it profitable. */
3626 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3627 && true_regnum (operands[1]) == AX_REG
3628 && true_regnum (operands[2]) == DX_REG)
3630 emit_insn (gen_ashrsi3_cvt (operands[2], operands[1], GEN_INT (31)));
3634 emit_move_insn (operands[2], operands[1]);
3635 emit_insn (gen_ashrsi3_cvt (operands[2], operands[2], GEN_INT (31)));
3637 emit_move_insn (operands[4], operands[2]);
3641 ;; Extend to register case. Optimize case where source and destination
3642 ;; registers match and cases where we can use cltd.
3644 [(set (match_operand:DI 0 "register_operand" "")
3645 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
3646 (clobber (reg:CC FLAGS_REG))
3647 (clobber (match_scratch:SI 2 ""))]
3651 split_double_mode (DImode, &operands[0], 1, &operands[3], &operands[4]);
3653 if (true_regnum (operands[3]) != true_regnum (operands[1]))
3654 emit_move_insn (operands[3], operands[1]);
3656 /* Generate a cltd if possible and doing so it profitable. */
3657 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
3658 && true_regnum (operands[3]) == AX_REG
3659 && true_regnum (operands[4]) == DX_REG)
3661 emit_insn (gen_ashrsi3_cvt (operands[4], operands[3], GEN_INT (31)));
3665 if (true_regnum (operands[4]) != true_regnum (operands[1]))
3666 emit_move_insn (operands[4], operands[1]);
3668 emit_insn (gen_ashrsi3_cvt (operands[4], operands[4], GEN_INT (31)));
3672 (define_insn "extend<mode>di2"
3673 [(set (match_operand:DI 0 "register_operand" "=r")
3675 (match_operand:SWI12 1 "nonimmediate_operand" "<r>m")))]
3677 "movs{<imodesuffix>q|x}\t{%1, %0|%0, %1}"
3678 [(set_attr "type" "imovx")
3679 (set_attr "mode" "DI")])
3681 (define_insn "extendhisi2"
3682 [(set (match_operand:SI 0 "register_operand" "=*a,r")
3683 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
3686 switch (get_attr_prefix_0f (insn))
3689 return "{cwtl|cwde}";
3691 return "movs{wl|x}\t{%1, %0|%0, %1}";
3694 [(set_attr "type" "imovx")
3695 (set_attr "mode" "SI")
3696 (set (attr "prefix_0f")
3697 ;; movsx is short decodable while cwtl is vector decoded.
3698 (if_then_else (and (eq_attr "cpu" "!k6")
3699 (eq_attr "alternative" "0"))
3701 (const_string "1")))
3703 (if_then_else (eq_attr "prefix_0f" "0")
3705 (const_string "1")))])
3707 (define_insn "*extendhisi2_zext"
3708 [(set (match_operand:DI 0 "register_operand" "=*a,r")
3711 (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
3714 switch (get_attr_prefix_0f (insn))
3717 return "{cwtl|cwde}";
3719 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
3722 [(set_attr "type" "imovx")
3723 (set_attr "mode" "SI")
3724 (set (attr "prefix_0f")
3725 ;; movsx is short decodable while cwtl is vector decoded.
3726 (if_then_else (and (eq_attr "cpu" "!k6")
3727 (eq_attr "alternative" "0"))
3729 (const_string "1")))
3731 (if_then_else (eq_attr "prefix_0f" "0")
3733 (const_string "1")))])
3735 (define_insn "extendqisi2"
3736 [(set (match_operand:SI 0 "register_operand" "=r")
3737 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3739 "movs{bl|x}\t{%1, %0|%0, %1}"
3740 [(set_attr "type" "imovx")
3741 (set_attr "mode" "SI")])
3743 (define_insn "*extendqisi2_zext"
3744 [(set (match_operand:DI 0 "register_operand" "=r")
3746 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
3748 "movs{bl|x}\t{%1, %k0|%k0, %1}"
3749 [(set_attr "type" "imovx")
3750 (set_attr "mode" "SI")])
3752 (define_insn "extendqihi2"
3753 [(set (match_operand:HI 0 "register_operand" "=*a,r")
3754 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
3757 switch (get_attr_prefix_0f (insn))
3760 return "{cbtw|cbw}";
3762 return "movs{bw|x}\t{%1, %0|%0, %1}";
3765 [(set_attr "type" "imovx")
3766 (set_attr "mode" "HI")
3767 (set (attr "prefix_0f")
3768 ;; movsx is short decodable while cwtl is vector decoded.
3769 (if_then_else (and (eq_attr "cpu" "!k6")
3770 (eq_attr "alternative" "0"))
3772 (const_string "1")))
3774 (if_then_else (eq_attr "prefix_0f" "0")
3776 (const_string "1")))])
3778 ;; Conversions between float and double.
3780 ;; These are all no-ops in the model used for the 80387.
3781 ;; So just emit moves.
3783 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
3785 [(set (match_operand:DF 0 "push_operand" "")
3786 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
3788 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3789 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
3792 [(set (match_operand:XF 0 "push_operand" "")
3793 (float_extend:XF (match_operand:MODEF 1 "fp_register_operand" "")))]
3795 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3796 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
3797 "operands[2] = GEN_INT (-GET_MODE_SIZE (XFmode));")
3799 (define_expand "extendsfdf2"
3800 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3801 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
3802 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3804 /* ??? Needed for compress_float_constant since all fp constants
3805 are TARGET_LEGITIMATE_CONSTANT_P. */
3806 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3808 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
3809 && standard_80387_constant_p (operands[1]) > 0)
3811 operands[1] = simplify_const_unary_operation
3812 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
3813 emit_move_insn_1 (operands[0], operands[1]);
3816 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
3820 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
3822 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3824 We do the conversion post reload to avoid producing of 128bit spills
3825 that might lead to ICE on 32bit target. The sequence unlikely combine
3828 [(set (match_operand:DF 0 "register_operand" "")
3830 (match_operand:SF 1 "nonimmediate_operand" "")))]
3831 "TARGET_USE_VECTOR_FP_CONVERTS
3832 && optimize_insn_for_speed_p ()
3833 && reload_completed && SSE_REG_P (operands[0])"
3838 (parallel [(const_int 0) (const_int 1)]))))]
3840 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
3841 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
3842 /* Use movss for loading from memory, unpcklps reg, reg for registers.
3843 Try to avoid move when unpacking can be done in source. */
3844 if (REG_P (operands[1]))
3846 /* If it is unsafe to overwrite upper half of source, we need
3847 to move to destination and unpack there. */
3848 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3849 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
3850 && true_regnum (operands[0]) != true_regnum (operands[1]))
3852 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
3853 emit_move_insn (tmp, operands[1]);
3856 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
3857 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
3861 emit_insn (gen_vec_setv4sf_0 (operands[3],
3862 CONST0_RTX (V4SFmode), operands[1]));
3865 (define_insn "*extendsfdf2_mixed"
3866 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
3868 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
3869 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
3871 switch (which_alternative)
3875 return output_387_reg_move (insn, operands);
3878 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
3884 [(set_attr "type" "fmov,fmov,ssecvt")
3885 (set_attr "prefix" "orig,orig,maybe_vex")
3886 (set_attr "mode" "SF,XF,DF")])
3888 (define_insn "*extendsfdf2_sse"
3889 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
3890 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
3891 "TARGET_SSE2 && TARGET_SSE_MATH"
3892 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
3893 [(set_attr "type" "ssecvt")
3894 (set_attr "prefix" "maybe_vex")
3895 (set_attr "mode" "DF")])
3897 (define_insn "*extendsfdf2_i387"
3898 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
3899 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
3901 "* return output_387_reg_move (insn, operands);"
3902 [(set_attr "type" "fmov")
3903 (set_attr "mode" "SF,XF")])
3905 (define_expand "extend<mode>xf2"
3906 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3907 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
3910 /* ??? Needed for compress_float_constant since all fp constants
3911 are TARGET_LEGITIMATE_CONSTANT_P. */
3912 if (GET_CODE (operands[1]) == CONST_DOUBLE)
3914 if (standard_80387_constant_p (operands[1]) > 0)
3916 operands[1] = simplify_const_unary_operation
3917 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
3918 emit_move_insn_1 (operands[0], operands[1]);
3921 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
3925 (define_insn "*extend<mode>xf2_i387"
3926 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
3928 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
3930 "* return output_387_reg_move (insn, operands);"
3931 [(set_attr "type" "fmov")
3932 (set_attr "mode" "<MODE>,XF")])
3934 ;; %%% This seems bad bad news.
3935 ;; This cannot output into an f-reg because there is no way to be sure
3936 ;; of truncating in that case. Otherwise this is just like a simple move
3937 ;; insn. So we pretend we can output to a reg in order to get better
3938 ;; register preferencing, but we really use a stack slot.
3940 ;; Conversion from DFmode to SFmode.
3942 (define_expand "truncdfsf2"
3943 [(set (match_operand:SF 0 "nonimmediate_operand" "")
3945 (match_operand:DF 1 "nonimmediate_operand" "")))]
3946 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
3948 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
3950 else if (flag_unsafe_math_optimizations)
3954 enum ix86_stack_slot slot = (virtuals_instantiated
3957 rtx temp = assign_386_stack_local (SFmode, slot);
3958 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
3963 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
3965 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
3967 We do the conversion post reload to avoid producing of 128bit spills
3968 that might lead to ICE on 32bit target. The sequence unlikely combine
3971 [(set (match_operand:SF 0 "register_operand" "")
3973 (match_operand:DF 1 "nonimmediate_operand" "")))]
3974 "TARGET_USE_VECTOR_FP_CONVERTS
3975 && optimize_insn_for_speed_p ()
3976 && reload_completed && SSE_REG_P (operands[0])"
3979 (float_truncate:V2SF
3983 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
3984 operands[3] = CONST0_RTX (V2SFmode);
3985 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
3986 /* Use movsd for loading from memory, unpcklpd for registers.
3987 Try to avoid move when unpacking can be done in source, or SSE3
3988 movddup is available. */
3989 if (REG_P (operands[1]))
3992 && true_regnum (operands[0]) != true_regnum (operands[1])
3993 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
3994 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
3996 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
3997 emit_move_insn (tmp, operands[1]);
4000 else if (!TARGET_SSE3)
4001 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4002 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4005 emit_insn (gen_sse2_loadlpd (operands[4],
4006 CONST0_RTX (V2DFmode), operands[1]));
4009 (define_expand "truncdfsf2_with_temp"
4010 [(parallel [(set (match_operand:SF 0 "" "")
4011 (float_truncate:SF (match_operand:DF 1 "" "")))
4012 (clobber (match_operand:SF 2 "" ""))])])
4014 (define_insn "*truncdfsf_fast_mixed"
4015 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4017 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4018 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4020 switch (which_alternative)
4023 return output_387_reg_move (insn, operands);
4025 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4030 [(set_attr "type" "fmov,ssecvt")
4031 (set_attr "prefix" "orig,maybe_vex")
4032 (set_attr "mode" "SF")])
4034 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4035 ;; because nothing we do here is unsafe.
4036 (define_insn "*truncdfsf_fast_sse"
4037 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4039 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4040 "TARGET_SSE2 && TARGET_SSE_MATH"
4041 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4042 [(set_attr "type" "ssecvt")
4043 (set_attr "prefix" "maybe_vex")
4044 (set_attr "mode" "SF")])
4046 (define_insn "*truncdfsf_fast_i387"
4047 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4049 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4050 "TARGET_80387 && flag_unsafe_math_optimizations"
4051 "* return output_387_reg_move (insn, operands);"
4052 [(set_attr "type" "fmov")
4053 (set_attr "mode" "SF")])
4055 (define_insn "*truncdfsf_mixed"
4056 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,x ,?f,?x,?*r")
4058 (match_operand:DF 1 "nonimmediate_operand" "f ,xm,f ,f ,f")))
4059 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4060 "TARGET_MIX_SSE_I387"
4062 switch (which_alternative)
4065 return output_387_reg_move (insn, operands);
4067 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4073 [(set_attr "isa" "*,sse2,*,*,*")
4074 (set_attr "type" "fmov,ssecvt,multi,multi,multi")
4075 (set_attr "unit" "*,*,i387,i387,i387")
4076 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4077 (set_attr "mode" "SF")])
4079 (define_insn "*truncdfsf_i387"
4080 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4082 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4083 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4086 switch (which_alternative)
4089 return output_387_reg_move (insn, operands);
4095 [(set_attr "type" "fmov,multi,multi,multi")
4096 (set_attr "unit" "*,i387,i387,i387")
4097 (set_attr "mode" "SF")])
4099 (define_insn "*truncdfsf2_i387_1"
4100 [(set (match_operand:SF 0 "memory_operand" "=m")
4102 (match_operand:DF 1 "register_operand" "f")))]
4104 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4105 && !TARGET_MIX_SSE_I387"
4106 "* return output_387_reg_move (insn, operands);"
4107 [(set_attr "type" "fmov")
4108 (set_attr "mode" "SF")])
4111 [(set (match_operand:SF 0 "register_operand" "")
4113 (match_operand:DF 1 "fp_register_operand" "")))
4114 (clobber (match_operand 2 "" ""))]
4116 [(set (match_dup 2) (match_dup 1))
4117 (set (match_dup 0) (match_dup 2))]
4118 "operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));")
4120 ;; Conversion from XFmode to {SF,DF}mode
4122 (define_expand "truncxf<mode>2"
4123 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4124 (float_truncate:MODEF
4125 (match_operand:XF 1 "register_operand" "")))
4126 (clobber (match_dup 2))])]
4129 if (flag_unsafe_math_optimizations)
4131 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4132 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4133 if (reg != operands[0])
4134 emit_move_insn (operands[0], reg);
4139 enum ix86_stack_slot slot = (virtuals_instantiated
4142 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4146 (define_insn "*truncxfsf2_mixed"
4147 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4149 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4150 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4153 gcc_assert (!which_alternative);
4154 return output_387_reg_move (insn, operands);
4156 [(set_attr "type" "fmov,multi,multi,multi")
4157 (set_attr "unit" "*,i387,i387,i387")
4158 (set_attr "mode" "SF")])
4160 (define_insn "*truncxfdf2_mixed"
4161 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4163 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4164 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4167 gcc_assert (!which_alternative);
4168 return output_387_reg_move (insn, operands);
4170 [(set_attr "isa" "*,*,sse2,*")
4171 (set_attr "type" "fmov,multi,multi,multi")
4172 (set_attr "unit" "*,i387,i387,i387")
4173 (set_attr "mode" "DF")])
4175 (define_insn "truncxf<mode>2_i387_noop"
4176 [(set (match_operand:MODEF 0 "register_operand" "=f")
4177 (float_truncate:MODEF
4178 (match_operand:XF 1 "register_operand" "f")))]
4179 "TARGET_80387 && flag_unsafe_math_optimizations"
4180 "* return output_387_reg_move (insn, operands);"
4181 [(set_attr "type" "fmov")
4182 (set_attr "mode" "<MODE>")])
4184 (define_insn "*truncxf<mode>2_i387"
4185 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4186 (float_truncate:MODEF
4187 (match_operand:XF 1 "register_operand" "f")))]
4189 "* return output_387_reg_move (insn, operands);"
4190 [(set_attr "type" "fmov")
4191 (set_attr "mode" "<MODE>")])
4194 [(set (match_operand:MODEF 0 "register_operand" "")
4195 (float_truncate:MODEF
4196 (match_operand:XF 1 "register_operand" "")))
4197 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4198 "TARGET_80387 && reload_completed"
4199 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4200 (set (match_dup 0) (match_dup 2))])
4203 [(set (match_operand:MODEF 0 "memory_operand" "")
4204 (float_truncate:MODEF
4205 (match_operand:XF 1 "register_operand" "")))
4206 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4208 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))])
4210 ;; Signed conversion to DImode.
4212 (define_expand "fix_truncxfdi2"
4213 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4214 (fix:DI (match_operand:XF 1 "register_operand" "")))
4215 (clobber (reg:CC FLAGS_REG))])]
4220 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4225 (define_expand "fix_trunc<mode>di2"
4226 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4227 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4228 (clobber (reg:CC FLAGS_REG))])]
4229 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4232 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4234 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4237 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4239 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4240 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4241 if (out != operands[0])
4242 emit_move_insn (operands[0], out);
4247 ;; Signed conversion to SImode.
4249 (define_expand "fix_truncxfsi2"
4250 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4251 (fix:SI (match_operand:XF 1 "register_operand" "")))
4252 (clobber (reg:CC FLAGS_REG))])]
4257 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4262 (define_expand "fix_trunc<mode>si2"
4263 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4264 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4265 (clobber (reg:CC FLAGS_REG))])]
4266 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4269 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4271 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4274 if (SSE_FLOAT_MODE_P (<MODE>mode))
4276 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4277 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4278 if (out != operands[0])
4279 emit_move_insn (operands[0], out);
4284 ;; Signed conversion to HImode.
4286 (define_expand "fix_trunc<mode>hi2"
4287 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4288 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4289 (clobber (reg:CC FLAGS_REG))])]
4291 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4295 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4300 ;; Unsigned conversion to SImode.
4302 (define_expand "fixuns_trunc<mode>si2"
4304 [(set (match_operand:SI 0 "register_operand" "")
4306 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4308 (clobber (match_scratch:<ssevecmode> 3 ""))
4309 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4310 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4312 enum machine_mode mode = <MODE>mode;
4313 enum machine_mode vecmode = <ssevecmode>mode;
4314 REAL_VALUE_TYPE TWO31r;
4317 if (optimize_insn_for_size_p ())
4320 real_ldexp (&TWO31r, &dconst1, 31);
4321 two31 = const_double_from_real_value (TWO31r, mode);
4322 two31 = ix86_build_const_vector (vecmode, true, two31);
4323 operands[2] = force_reg (vecmode, two31);
4326 (define_insn_and_split "*fixuns_trunc<mode>_1"
4327 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4329 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4330 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4331 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4332 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4333 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4334 && optimize_function_for_speed_p (cfun)"
4336 "&& reload_completed"
4339 ix86_split_convert_uns_si_sse (operands);
4343 ;; Unsigned conversion to HImode.
4344 ;; Without these patterns, we'll try the unsigned SI conversion which
4345 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4347 (define_expand "fixuns_trunc<mode>hi2"
4349 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4350 (set (match_operand:HI 0 "nonimmediate_operand" "")
4351 (subreg:HI (match_dup 2) 0))]
4352 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4353 "operands[2] = gen_reg_rtx (SImode);")
4355 ;; When SSE is available, it is always faster to use it!
4356 (define_insn "fix_trunc<mode>di_sse"
4357 [(set (match_operand:DI 0 "register_operand" "=r,r")
4358 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4359 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4360 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4361 "%vcvtt<ssemodesuffix>2si{q}\t{%1, %0|%0, %1}"
4362 [(set_attr "type" "sseicvt")
4363 (set_attr "prefix" "maybe_vex")
4364 (set_attr "prefix_rex" "1")
4365 (set_attr "mode" "<MODE>")
4366 (set_attr "athlon_decode" "double,vector")
4367 (set_attr "amdfam10_decode" "double,double")
4368 (set_attr "bdver1_decode" "double,double")])
4370 (define_insn "fix_trunc<mode>si_sse"
4371 [(set (match_operand:SI 0 "register_operand" "=r,r")
4372 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4373 "SSE_FLOAT_MODE_P (<MODE>mode)
4374 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4375 "%vcvtt<ssemodesuffix>2si\t{%1, %0|%0, %1}"
4376 [(set_attr "type" "sseicvt")
4377 (set_attr "prefix" "maybe_vex")
4378 (set_attr "mode" "<MODE>")
4379 (set_attr "athlon_decode" "double,vector")
4380 (set_attr "amdfam10_decode" "double,double")
4381 (set_attr "bdver1_decode" "double,double")])
4383 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4385 [(set (match_operand:MODEF 0 "register_operand" "")
4386 (match_operand:MODEF 1 "memory_operand" ""))
4387 (set (match_operand:SWI48x 2 "register_operand" "")
4388 (fix:SWI48x (match_dup 0)))]
4389 "TARGET_SHORTEN_X87_SSE
4390 && !(TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ())
4391 && peep2_reg_dead_p (2, operands[0])"
4392 [(set (match_dup 2) (fix:SWI48x (match_dup 1)))])
4394 ;; Avoid vector decoded forms of the instruction.
4396 [(match_scratch:DF 2 "x")
4397 (set (match_operand:SWI48x 0 "register_operand" "")
4398 (fix:SWI48x (match_operand:DF 1 "memory_operand" "")))]
4399 "TARGET_SSE2 && TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4400 [(set (match_dup 2) (match_dup 1))
4401 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4404 [(match_scratch:SF 2 "x")
4405 (set (match_operand:SWI48x 0 "register_operand" "")
4406 (fix:SWI48x (match_operand:SF 1 "memory_operand" "")))]
4407 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4408 [(set (match_dup 2) (match_dup 1))
4409 (set (match_dup 0) (fix:SWI48x (match_dup 2)))])
4411 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4412 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4413 (fix:SWI248x (match_operand 1 "register_operand" "")))]
4414 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4416 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4417 && (TARGET_64BIT || <MODE>mode != DImode))
4419 && can_create_pseudo_p ()"
4424 if (memory_operand (operands[0], VOIDmode))
4425 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4428 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4429 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4435 [(set_attr "type" "fisttp")
4436 (set_attr "mode" "<MODE>")])
4438 (define_insn "fix_trunc<mode>_i387_fisttp"
4439 [(set (match_operand:SWI248x 0 "memory_operand" "=m")
4440 (fix:SWI248x (match_operand 1 "register_operand" "f")))
4441 (clobber (match_scratch:XF 2 "=&1f"))]
4442 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4444 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4445 && (TARGET_64BIT || <MODE>mode != DImode))
4446 && TARGET_SSE_MATH)"
4447 "* return output_fix_trunc (insn, operands, true);"
4448 [(set_attr "type" "fisttp")
4449 (set_attr "mode" "<MODE>")])
4451 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4452 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "=m,?r")
4453 (fix:SWI248x (match_operand 1 "register_operand" "f,f")))
4454 (clobber (match_operand:SWI248x 2 "memory_operand" "=X,m"))
4455 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4456 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4458 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4459 && (TARGET_64BIT || <MODE>mode != DImode))
4460 && TARGET_SSE_MATH)"
4462 [(set_attr "type" "fisttp")
4463 (set_attr "mode" "<MODE>")])
4466 [(set (match_operand:SWI248x 0 "register_operand" "")
4467 (fix:SWI248x (match_operand 1 "register_operand" "")))
4468 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4469 (clobber (match_scratch 3 ""))]
4471 [(parallel [(set (match_dup 2) (fix:SWI248x (match_dup 1)))
4472 (clobber (match_dup 3))])
4473 (set (match_dup 0) (match_dup 2))])
4476 [(set (match_operand:SWI248x 0 "memory_operand" "")
4477 (fix:SWI248x (match_operand 1 "register_operand" "")))
4478 (clobber (match_operand:SWI248x 2 "memory_operand" ""))
4479 (clobber (match_scratch 3 ""))]
4481 [(parallel [(set (match_dup 0) (fix:SWI248x (match_dup 1)))
4482 (clobber (match_dup 3))])])
4484 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
4485 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
4486 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
4487 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
4488 ;; function in i386.c.
4489 (define_insn_and_split "*fix_trunc<mode>_i387_1"
4490 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
4491 (fix:SWI248x (match_operand 1 "register_operand" "")))
4492 (clobber (reg:CC FLAGS_REG))]
4493 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4495 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4496 && (TARGET_64BIT || <MODE>mode != DImode))
4497 && can_create_pseudo_p ()"
4502 ix86_optimize_mode_switching[I387_TRUNC] = 1;
4504 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
4505 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
4506 if (memory_operand (operands[0], VOIDmode))
4507 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
4508 operands[2], operands[3]));
4511 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4512 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
4513 operands[2], operands[3],
4518 [(set_attr "type" "fistp")
4519 (set_attr "i387_cw" "trunc")
4520 (set_attr "mode" "<MODE>")])
4522 (define_insn "fix_truncdi_i387"
4523 [(set (match_operand:DI 0 "memory_operand" "=m")
4524 (fix:DI (match_operand 1 "register_operand" "f")))
4525 (use (match_operand:HI 2 "memory_operand" "m"))
4526 (use (match_operand:HI 3 "memory_operand" "m"))
4527 (clobber (match_scratch:XF 4 "=&1f"))]
4528 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4530 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4531 "* return output_fix_trunc (insn, operands, false);"
4532 [(set_attr "type" "fistp")
4533 (set_attr "i387_cw" "trunc")
4534 (set_attr "mode" "DI")])
4536 (define_insn "fix_truncdi_i387_with_temp"
4537 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
4538 (fix:DI (match_operand 1 "register_operand" "f,f")))
4539 (use (match_operand:HI 2 "memory_operand" "m,m"))
4540 (use (match_operand:HI 3 "memory_operand" "m,m"))
4541 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
4542 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
4543 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4545 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
4547 [(set_attr "type" "fistp")
4548 (set_attr "i387_cw" "trunc")
4549 (set_attr "mode" "DI")])
4552 [(set (match_operand:DI 0 "register_operand" "")
4553 (fix:DI (match_operand 1 "register_operand" "")))
4554 (use (match_operand:HI 2 "memory_operand" ""))
4555 (use (match_operand:HI 3 "memory_operand" ""))
4556 (clobber (match_operand:DI 4 "memory_operand" ""))
4557 (clobber (match_scratch 5 ""))]
4559 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
4562 (clobber (match_dup 5))])
4563 (set (match_dup 0) (match_dup 4))])
4566 [(set (match_operand:DI 0 "memory_operand" "")
4567 (fix:DI (match_operand 1 "register_operand" "")))
4568 (use (match_operand:HI 2 "memory_operand" ""))
4569 (use (match_operand:HI 3 "memory_operand" ""))
4570 (clobber (match_operand:DI 4 "memory_operand" ""))
4571 (clobber (match_scratch 5 ""))]
4573 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
4576 (clobber (match_dup 5))])])
4578 (define_insn "fix_trunc<mode>_i387"
4579 [(set (match_operand:SWI24 0 "memory_operand" "=m")
4580 (fix:SWI24 (match_operand 1 "register_operand" "f")))
4581 (use (match_operand:HI 2 "memory_operand" "m"))
4582 (use (match_operand:HI 3 "memory_operand" "m"))]
4583 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4585 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4586 "* return output_fix_trunc (insn, operands, false);"
4587 [(set_attr "type" "fistp")
4588 (set_attr "i387_cw" "trunc")
4589 (set_attr "mode" "<MODE>")])
4591 (define_insn "fix_trunc<mode>_i387_with_temp"
4592 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
4593 (fix:SWI24 (match_operand 1 "register_operand" "f,f")))
4594 (use (match_operand:HI 2 "memory_operand" "m,m"))
4595 (use (match_operand:HI 3 "memory_operand" "m,m"))
4596 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
4597 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4599 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
4601 [(set_attr "type" "fistp")
4602 (set_attr "i387_cw" "trunc")
4603 (set_attr "mode" "<MODE>")])
4606 [(set (match_operand:SWI24 0 "register_operand" "")
4607 (fix:SWI24 (match_operand 1 "register_operand" "")))
4608 (use (match_operand:HI 2 "memory_operand" ""))
4609 (use (match_operand:HI 3 "memory_operand" ""))
4610 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4612 [(parallel [(set (match_dup 4) (fix:SWI24 (match_dup 1)))
4614 (use (match_dup 3))])
4615 (set (match_dup 0) (match_dup 4))])
4618 [(set (match_operand:SWI24 0 "memory_operand" "")
4619 (fix:SWI24 (match_operand 1 "register_operand" "")))
4620 (use (match_operand:HI 2 "memory_operand" ""))
4621 (use (match_operand:HI 3 "memory_operand" ""))
4622 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
4624 [(parallel [(set (match_dup 0) (fix:SWI24 (match_dup 1)))
4626 (use (match_dup 3))])])
4628 (define_insn "x86_fnstcw_1"
4629 [(set (match_operand:HI 0 "memory_operand" "=m")
4630 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
4633 [(set (attr "length")
4634 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4635 (set_attr "mode" "HI")
4636 (set_attr "unit" "i387")
4637 (set_attr "bdver1_decode" "vector")])
4639 (define_insn "x86_fldcw_1"
4640 [(set (reg:HI FPCR_REG)
4641 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
4644 [(set (attr "length")
4645 (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
4646 (set_attr "mode" "HI")
4647 (set_attr "unit" "i387")
4648 (set_attr "athlon_decode" "vector")
4649 (set_attr "amdfam10_decode" "vector")
4650 (set_attr "bdver1_decode" "vector")])
4652 ;; Conversion between fixed point and floating point.
4654 ;; Even though we only accept memory inputs, the backend _really_
4655 ;; wants to be able to do this between registers.
4657 (define_expand "floathi<mode>2"
4658 [(set (match_operand:X87MODEF 0 "register_operand" "")
4659 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
4661 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4662 || TARGET_MIX_SSE_I387)")
4664 ;; Pre-reload splitter to add memory clobber to the pattern.
4665 (define_insn_and_split "*floathi<mode>2_1"
4666 [(set (match_operand:X87MODEF 0 "register_operand" "")
4667 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
4669 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4670 || TARGET_MIX_SSE_I387)
4671 && can_create_pseudo_p ()"
4674 [(parallel [(set (match_dup 0)
4675 (float:X87MODEF (match_dup 1)))
4676 (clobber (match_dup 2))])]
4677 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
4679 (define_insn "*floathi<mode>2_i387_with_temp"
4680 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
4681 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
4682 (clobber (match_operand:HI 2 "memory_operand" "=X,m"))]
4684 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4685 || TARGET_MIX_SSE_I387)"
4687 [(set_attr "type" "fmov,multi")
4688 (set_attr "mode" "<MODE>")
4689 (set_attr "unit" "*,i387")
4690 (set_attr "fp_int_src" "true")])
4692 (define_insn "*floathi<mode>2_i387"
4693 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
4694 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
4696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4697 || TARGET_MIX_SSE_I387)"
4699 [(set_attr "type" "fmov")
4700 (set_attr "mode" "<MODE>")
4701 (set_attr "fp_int_src" "true")])
4704 [(set (match_operand:X87MODEF 0 "register_operand" "")
4705 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
4706 (clobber (match_operand:HI 2 "memory_operand" ""))]
4708 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4709 || TARGET_MIX_SSE_I387)
4710 && reload_completed"
4711 [(set (match_dup 2) (match_dup 1))
4712 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
4715 [(set (match_operand:X87MODEF 0 "register_operand" "")
4716 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
4717 (clobber (match_operand:HI 2 "memory_operand" ""))]
4719 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
4720 || TARGET_MIX_SSE_I387)
4721 && reload_completed"
4722 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
4724 (define_expand "float<SWI48x:mode><X87MODEF:mode>2"
4725 [(set (match_operand:X87MODEF 0 "register_operand" "")
4727 (match_operand:SWI48x 1 "nonimmediate_operand" "")))]
4729 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4730 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
4732 if (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4733 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4734 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode))
4736 rtx reg = gen_reg_rtx (XFmode);
4737 rtx (*insn)(rtx, rtx);
4739 emit_insn (gen_float<SWI48x:mode>xf2 (reg, operands[1]));
4741 if (<X87MODEF:MODE>mode == SFmode)
4742 insn = gen_truncxfsf2;
4743 else if (<X87MODEF:MODE>mode == DFmode)
4744 insn = gen_truncxfdf2;
4748 emit_insn (insn (operands[0], reg));
4753 ;; Pre-reload splitter to add memory clobber to the pattern.
4754 (define_insn_and_split "*float<SWI48x:mode><X87MODEF:mode>2_1"
4755 [(set (match_operand:X87MODEF 0 "register_operand" "")
4756 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))]
4758 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
4759 && (!((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4760 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
4761 || TARGET_MIX_SSE_I387))
4762 || ((<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4763 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
4764 && ((<SWI48x:MODE>mode == SImode
4765 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
4766 && optimize_function_for_speed_p (cfun)
4767 && flag_trapping_math)
4768 || !(TARGET_INTER_UNIT_CONVERSIONS
4769 || optimize_function_for_size_p (cfun)))))
4770 && can_create_pseudo_p ()"
4773 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
4774 (clobber (match_dup 2))])]
4776 operands[2] = assign_386_stack_local (<SWI48x:MODE>mode, SLOT_TEMP);
4778 /* Avoid store forwarding (partial memory) stall penalty
4779 by passing DImode value through XMM registers. */
4780 if (<SWI48x:MODE>mode == DImode && !TARGET_64BIT
4781 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
4782 && optimize_function_for_speed_p (cfun))
4784 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
4791 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
4792 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
4794 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
4795 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
4796 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4797 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4799 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
4800 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
4801 (set_attr "unit" "*,i387,*,*,*")
4802 (set_attr "athlon_decode" "*,*,double,direct,double")
4803 (set_attr "amdfam10_decode" "*,*,vector,double,double")
4804 (set_attr "bdver1_decode" "*,*,double,direct,double")
4805 (set_attr "fp_int_src" "true")])
4807 (define_insn "*floatsi<mode>2_vector_mixed"
4808 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4809 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
4810 "TARGET_SSE2 && TARGET_MIX_SSE_I387
4811 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4815 [(set_attr "type" "fmov,sseicvt")
4816 (set_attr "mode" "<MODE>,<ssevecmode>")
4817 (set_attr "unit" "i387,*")
4818 (set_attr "athlon_decode" "*,direct")
4819 (set_attr "amdfam10_decode" "*,double")
4820 (set_attr "bdver1_decode" "*,direct")
4821 (set_attr "fp_int_src" "true")])
4823 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_with_temp"
4824 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
4826 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r,r,m")))
4827 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m,m,X"))]
4828 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4829 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
4831 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
4832 (set_attr "mode" "<MODEF:MODE>")
4833 (set_attr "unit" "*,i387,*,*")
4834 (set_attr "athlon_decode" "*,*,double,direct")
4835 (set_attr "amdfam10_decode" "*,*,vector,double")
4836 (set_attr "bdver1_decode" "*,*,double,direct")
4837 (set_attr "fp_int_src" "true")])
4840 [(set (match_operand:MODEF 0 "register_operand" "")
4841 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4842 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4843 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4844 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4845 && TARGET_INTER_UNIT_CONVERSIONS
4847 && (SSE_REG_P (operands[0])
4848 || (GET_CODE (operands[0]) == SUBREG
4849 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4850 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
4853 [(set (match_operand:MODEF 0 "register_operand" "")
4854 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
4855 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
4856 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4857 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4858 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
4860 && (SSE_REG_P (operands[0])
4861 || (GET_CODE (operands[0]) == SUBREG
4862 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4863 [(set (match_dup 2) (match_dup 1))
4864 (set (match_dup 0) (float:MODEF (match_dup 2)))])
4866 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_interunit"
4867 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
4869 (match_operand:SWI48x 1 "nonimmediate_operand" "m,r,m")))]
4870 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4871 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4872 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4875 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}
4876 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4877 [(set_attr "type" "fmov,sseicvt,sseicvt")
4878 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
4879 (set_attr "mode" "<MODEF:MODE>")
4880 (set (attr "prefix_rex")
4882 (and (eq_attr "prefix" "maybe_vex")
4883 (match_test "<SWI48x:MODE>mode == DImode"))
4885 (const_string "*")))
4886 (set_attr "unit" "i387,*,*")
4887 (set_attr "athlon_decode" "*,double,direct")
4888 (set_attr "amdfam10_decode" "*,vector,double")
4889 (set_attr "bdver1_decode" "*,double,direct")
4890 (set_attr "fp_int_src" "true")])
4892 (define_insn "*float<SWI48x:mode><MODEF:mode>2_mixed_nointerunit"
4893 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
4895 (match_operand:SWI48x 1 "memory_operand" "m,m")))]
4896 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
4897 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
4898 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
4901 %vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
4902 [(set_attr "type" "fmov,sseicvt")
4903 (set_attr "prefix" "orig,maybe_vex")
4904 (set_attr "mode" "<MODEF:MODE>")
4905 (set (attr "prefix_rex")
4907 (and (eq_attr "prefix" "maybe_vex")
4908 (match_test "<SWI48x:MODE>mode == DImode"))
4910 (const_string "*")))
4911 (set_attr "athlon_decode" "*,direct")
4912 (set_attr "amdfam10_decode" "*,double")
4913 (set_attr "bdver1_decode" "*,direct")
4914 (set_attr "fp_int_src" "true")])
4916 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
4917 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
4919 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
4920 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
4921 "TARGET_SSE2 && TARGET_SSE_MATH
4922 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4924 [(set_attr "type" "sseicvt")
4925 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
4926 (set_attr "athlon_decode" "double,direct,double")
4927 (set_attr "amdfam10_decode" "vector,double,double")
4928 (set_attr "bdver1_decode" "double,direct,double")
4929 (set_attr "fp_int_src" "true")])
4931 (define_insn "*floatsi<mode>2_vector_sse"
4932 [(set (match_operand:MODEF 0 "register_operand" "=x")
4933 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
4934 "TARGET_SSE2 && TARGET_SSE_MATH
4935 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
4937 [(set_attr "type" "sseicvt")
4938 (set_attr "mode" "<MODE>")
4939 (set_attr "athlon_decode" "direct")
4940 (set_attr "amdfam10_decode" "double")
4941 (set_attr "bdver1_decode" "direct")
4942 (set_attr "fp_int_src" "true")])
4945 [(set (match_operand:MODEF 0 "register_operand" "")
4946 (float:MODEF (match_operand:SI 1 "register_operand" "")))
4947 (clobber (match_operand:SI 2 "memory_operand" ""))]
4948 "TARGET_SSE2 && TARGET_SSE_MATH
4949 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4951 && (SSE_REG_P (operands[0])
4952 || (GET_CODE (operands[0]) == SUBREG
4953 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4956 rtx op1 = operands[1];
4958 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
4960 if (GET_CODE (op1) == SUBREG)
4961 op1 = SUBREG_REG (op1);
4963 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
4965 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4966 emit_insn (gen_sse2_loadld (operands[4],
4967 CONST0_RTX (V4SImode), operands[1]));
4969 /* We can ignore possible trapping value in the
4970 high part of SSE register for non-trapping math. */
4971 else if (SSE_REG_P (op1) && !flag_trapping_math)
4972 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
4975 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
4976 emit_move_insn (operands[2], operands[1]);
4977 emit_insn (gen_sse2_loadld (operands[4],
4978 CONST0_RTX (V4SImode), operands[2]));
4980 if (<ssevecmode>mode == V4SFmode)
4981 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
4983 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
4988 [(set (match_operand:MODEF 0 "register_operand" "")
4989 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
4990 (clobber (match_operand:SI 2 "memory_operand" ""))]
4991 "TARGET_SSE2 && TARGET_SSE_MATH
4992 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
4994 && (SSE_REG_P (operands[0])
4995 || (GET_CODE (operands[0]) == SUBREG
4996 && SSE_REG_P (SUBREG_REG (operands[0]))))"
4999 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5001 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5003 emit_insn (gen_sse2_loadld (operands[4],
5004 CONST0_RTX (V4SImode), operands[1]));
5005 if (<ssevecmode>mode == V4SFmode)
5006 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5008 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5013 [(set (match_operand:MODEF 0 "register_operand" "")
5014 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5015 "TARGET_SSE2 && TARGET_SSE_MATH
5016 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5018 && (SSE_REG_P (operands[0])
5019 || (GET_CODE (operands[0]) == SUBREG
5020 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5023 rtx op1 = operands[1];
5025 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5027 if (GET_CODE (op1) == SUBREG)
5028 op1 = SUBREG_REG (op1);
5030 if (GENERAL_REG_P (op1))
5032 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5033 if (TARGET_INTER_UNIT_MOVES)
5034 emit_insn (gen_sse2_loadld (operands[4],
5035 CONST0_RTX (V4SImode), operands[1]));
5038 operands[5] = ix86_force_to_memory (GET_MODE (operands[1]),
5040 emit_insn (gen_sse2_loadld (operands[4],
5041 CONST0_RTX (V4SImode), operands[5]));
5042 ix86_free_from_memory (GET_MODE (operands[1]));
5045 /* We can ignore possible trapping value in the
5046 high part of SSE register for non-trapping math. */
5047 else if (SSE_REG_P (op1) && !flag_trapping_math)
5048 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5051 if (<ssevecmode>mode == V4SFmode)
5052 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5054 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5059 [(set (match_operand:MODEF 0 "register_operand" "")
5060 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5061 "TARGET_SSE2 && TARGET_SSE_MATH
5062 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5064 && (SSE_REG_P (operands[0])
5065 || (GET_CODE (operands[0]) == SUBREG
5066 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5069 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5071 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5073 emit_insn (gen_sse2_loadld (operands[4],
5074 CONST0_RTX (V4SImode), operands[1]));
5075 if (<ssevecmode>mode == V4SFmode)
5076 emit_insn (gen_floatv4siv4sf2 (operands[3], operands[4]));
5078 emit_insn (gen_sse2_cvtdq2pd (operands[3], operands[4]));
5082 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_with_temp"
5083 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5085 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))
5086 (clobber (match_operand:SWI48x 2 "memory_operand" "=m,X"))]
5087 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5088 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5090 [(set_attr "type" "sseicvt")
5091 (set_attr "mode" "<MODEF:MODE>")
5092 (set_attr "athlon_decode" "double,direct")
5093 (set_attr "amdfam10_decode" "vector,double")
5094 (set_attr "bdver1_decode" "double,direct")
5095 (set_attr "fp_int_src" "true")])
5097 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_interunit"
5098 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5100 (match_operand:SWI48x 1 "nonimmediate_operand" "r,m")))]
5101 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5102 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5103 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5104 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5105 [(set_attr "type" "sseicvt")
5106 (set_attr "prefix" "maybe_vex")
5107 (set_attr "mode" "<MODEF:MODE>")
5108 (set (attr "prefix_rex")
5110 (and (eq_attr "prefix" "maybe_vex")
5111 (match_test "<SWI48x:MODE>mode == DImode"))
5113 (const_string "*")))
5114 (set_attr "athlon_decode" "double,direct")
5115 (set_attr "amdfam10_decode" "vector,double")
5116 (set_attr "bdver1_decode" "double,direct")
5117 (set_attr "fp_int_src" "true")])
5120 [(set (match_operand:MODEF 0 "register_operand" "")
5121 (float:MODEF (match_operand:SWI48x 1 "nonimmediate_operand" "")))
5122 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5123 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5124 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5125 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5127 && (SSE_REG_P (operands[0])
5128 || (GET_CODE (operands[0]) == SUBREG
5129 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5130 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5132 (define_insn "*float<SWI48x:mode><MODEF:mode>2_sse_nointerunit"
5133 [(set (match_operand:MODEF 0 "register_operand" "=x")
5135 (match_operand:SWI48x 1 "memory_operand" "m")))]
5136 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5137 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5138 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5139 "%vcvtsi2<MODEF:ssemodesuffix><SWI48x:rex64suffix>\t{%1, %d0|%d0, %1}"
5140 [(set_attr "type" "sseicvt")
5141 (set_attr "prefix" "maybe_vex")
5142 (set_attr "mode" "<MODEF:MODE>")
5143 (set (attr "prefix_rex")
5145 (and (eq_attr "prefix" "maybe_vex")
5146 (match_test "<SWI48x:MODE>mode == DImode"))
5148 (const_string "*")))
5149 (set_attr "athlon_decode" "direct")
5150 (set_attr "amdfam10_decode" "double")
5151 (set_attr "bdver1_decode" "direct")
5152 (set_attr "fp_int_src" "true")])
5155 [(set (match_operand:MODEF 0 "register_operand" "")
5156 (float:MODEF (match_operand:SWI48x 1 "register_operand" "")))
5157 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5158 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5159 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5160 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5162 && (SSE_REG_P (operands[0])
5163 || (GET_CODE (operands[0]) == SUBREG
5164 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5165 [(set (match_dup 2) (match_dup 1))
5166 (set (match_dup 0) (float:MODEF (match_dup 2)))])
5169 [(set (match_operand:MODEF 0 "register_operand" "")
5170 (float:MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5171 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5172 "(<SWI48x:MODE>mode != DImode || TARGET_64BIT)
5173 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5175 && (SSE_REG_P (operands[0])
5176 || (GET_CODE (operands[0]) == SUBREG
5177 && SSE_REG_P (SUBREG_REG (operands[0]))))"
5178 [(set (match_dup 0) (float:MODEF (match_dup 1)))])
5180 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387_with_temp"
5181 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5183 (match_operand:SWI48x 1 "nonimmediate_operand" "m,?r")))
5184 (clobber (match_operand:SWI48x 2 "memory_operand" "=X,m"))]
5186 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5190 [(set_attr "type" "fmov,multi")
5191 (set_attr "mode" "<X87MODEF:MODE>")
5192 (set_attr "unit" "*,i387")
5193 (set_attr "fp_int_src" "true")])
5195 (define_insn "*float<SWI48x:mode><X87MODEF:mode>2_i387"
5196 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5198 (match_operand:SWI48x 1 "memory_operand" "m")))]
5200 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)"
5202 [(set_attr "type" "fmov")
5203 (set_attr "mode" "<X87MODEF:MODE>")
5204 (set_attr "fp_int_src" "true")])
5207 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5208 (float:X87MODEF (match_operand:SWI48x 1 "register_operand" "")))
5209 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5211 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5212 && reload_completed"
5213 [(set (match_dup 2) (match_dup 1))
5214 (set (match_dup 0) (float:X87MODEF (match_dup 2)))])
5217 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5218 (float:X87MODEF (match_operand:SWI48x 1 "memory_operand" "")))
5219 (clobber (match_operand:SWI48x 2 "memory_operand" ""))]
5221 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SWI48x:MODE>mode)
5222 && reload_completed"
5223 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5225 ;; Avoid store forwarding (partial memory) stall penalty
5226 ;; by passing DImode value through XMM registers. */
5228 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5229 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5231 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5232 (clobber (match_scratch:V4SI 3 "=X,x"))
5233 (clobber (match_scratch:V4SI 4 "=X,x"))
5234 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5235 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5236 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5237 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5239 [(set_attr "type" "multi")
5240 (set_attr "mode" "<X87MODEF:MODE>")
5241 (set_attr "unit" "i387")
5242 (set_attr "fp_int_src" "true")])
5245 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5246 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5247 (clobber (match_scratch:V4SI 3 ""))
5248 (clobber (match_scratch:V4SI 4 ""))
5249 (clobber (match_operand:DI 2 "memory_operand" ""))]
5250 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5251 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5252 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5253 && reload_completed"
5254 [(set (match_dup 2) (match_dup 3))
5255 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5257 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5258 Assemble the 64-bit DImode value in an xmm register. */
5259 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5260 gen_rtx_SUBREG (SImode, operands[1], 0)));
5261 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5262 gen_rtx_SUBREG (SImode, operands[1], 4)));
5263 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5266 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5270 [(set (match_operand:X87MODEF 0 "fp_register_operand" "")
5271 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5272 (clobber (match_scratch:V4SI 3 ""))
5273 (clobber (match_scratch:V4SI 4 ""))
5274 (clobber (match_operand:DI 2 "memory_operand" ""))]
5275 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5276 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5277 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5278 && reload_completed"
5279 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))])
5281 ;; Avoid store forwarding (partial memory) stall penalty by extending
5282 ;; SImode value to DImode through XMM register instead of pushing two
5283 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5284 ;; targets benefit from this optimization. Also note that fild
5285 ;; loads from memory only.
5287 (define_insn "*floatunssi<mode>2_1"
5288 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5289 (unsigned_float:X87MODEF
5290 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5291 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5292 (clobber (match_scratch:SI 3 "=X,x"))]
5294 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5297 [(set_attr "type" "multi")
5298 (set_attr "mode" "<MODE>")])
5301 [(set (match_operand:X87MODEF 0 "register_operand" "")
5302 (unsigned_float:X87MODEF
5303 (match_operand:SI 1 "register_operand" "")))
5304 (clobber (match_operand:DI 2 "memory_operand" ""))
5305 (clobber (match_scratch:SI 3 ""))]
5307 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5309 && reload_completed"
5310 [(set (match_dup 2) (match_dup 1))
5312 (float:X87MODEF (match_dup 2)))]
5313 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5316 [(set (match_operand:X87MODEF 0 "register_operand" "")
5317 (unsigned_float:X87MODEF
5318 (match_operand:SI 1 "memory_operand" "")))
5319 (clobber (match_operand:DI 2 "memory_operand" ""))
5320 (clobber (match_scratch:SI 3 ""))]
5322 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5324 && reload_completed"
5325 [(set (match_dup 2) (match_dup 3))
5327 (float:X87MODEF (match_dup 2)))]
5329 emit_move_insn (operands[3], operands[1]);
5330 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5333 (define_expand "floatunssi<mode>2"
5335 [(set (match_operand:X87MODEF 0 "register_operand" "")
5336 (unsigned_float:X87MODEF
5337 (match_operand:SI 1 "nonimmediate_operand" "")))
5338 (clobber (match_dup 2))
5339 (clobber (match_scratch:SI 3 ""))])]
5341 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5343 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5345 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5347 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5352 enum ix86_stack_slot slot = (virtuals_instantiated
5355 operands[2] = assign_386_stack_local (DImode, slot);
5359 (define_expand "floatunsdisf2"
5360 [(use (match_operand:SF 0 "register_operand" ""))
5361 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5362 "TARGET_64BIT && TARGET_SSE_MATH"
5363 "x86_emit_floatuns (operands); DONE;")
5365 (define_expand "floatunsdidf2"
5366 [(use (match_operand:DF 0 "register_operand" ""))
5367 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5368 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5369 && TARGET_SSE2 && TARGET_SSE_MATH"
5372 x86_emit_floatuns (operands);
5374 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5380 (define_expand "add<mode>3"
5381 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5382 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5383 (match_operand:SDWIM 2 "<general_operand>" "")))]
5385 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5387 (define_insn_and_split "*add<dwi>3_doubleword"
5388 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5390 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5391 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5392 (clobber (reg:CC FLAGS_REG))]
5393 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5396 [(parallel [(set (reg:CC FLAGS_REG)
5397 (unspec:CC [(match_dup 1) (match_dup 2)]
5400 (plus:DWIH (match_dup 1) (match_dup 2)))])
5401 (parallel [(set (match_dup 3)
5405 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5407 (clobber (reg:CC FLAGS_REG))])]
5408 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
5410 (define_insn "*add<mode>3_cc"
5411 [(set (reg:CC FLAGS_REG)
5413 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5414 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5416 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5417 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5418 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5419 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5420 [(set_attr "type" "alu")
5421 (set_attr "mode" "<MODE>")])
5423 (define_insn "addqi3_cc"
5424 [(set (reg:CC FLAGS_REG)
5426 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5427 (match_operand:QI 2 "general_operand" "qn,qm")]
5429 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5430 (plus:QI (match_dup 1) (match_dup 2)))]
5431 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5432 "add{b}\t{%2, %0|%0, %2}"
5433 [(set_attr "type" "alu")
5434 (set_attr "mode" "QI")])
5436 (define_insn_and_split "*lea_1"
5437 [(set (match_operand:SI 0 "register_operand" "=r")
5438 (subreg:SI (match_operand:DI 1 "lea_address_operand" "p") 0))]
5440 "lea{l}\t{%E1, %0|%0, %E1}"
5441 "&& reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5444 ix86_split_lea_for_addr (operands, SImode);
5447 [(set_attr "type" "lea")
5448 (set_attr "mode" "SI")])
5450 (define_insn_and_split "*lea<mode>_2"
5451 [(set (match_operand:SWI48 0 "register_operand" "=r")
5452 (match_operand:SWI48 1 "lea_address_operand" "p"))]
5454 "lea{<imodesuffix>}\t{%E1, %0|%0, %E1}"
5455 "reload_completed && ix86_avoid_lea_for_addr (insn, operands)"
5458 ix86_split_lea_for_addr (operands, <MODE>mode);
5461 [(set_attr "type" "lea")
5462 (set_attr "mode" "<MODE>")])
5464 (define_insn "*lea_3_zext"
5465 [(set (match_operand:DI 0 "register_operand" "=r")
5467 (subreg:SI (match_operand:DI 1 "lea_address_operand" "j") 0)))]
5469 "lea{l}\t{%E1, %k0|%k0, %E1}"
5470 [(set_attr "type" "lea")
5471 (set_attr "mode" "SI")])
5473 (define_insn "*lea_4_zext"
5474 [(set (match_operand:DI 0 "register_operand" "=r")
5476 (match_operand:SI 1 "lea_address_operand" "j")))]
5478 "lea{l}\t{%E1, %k0|%k0, %E1}"
5479 [(set_attr "type" "lea")
5480 (set_attr "mode" "SI")])
5482 (define_insn "*lea_5_zext"
5483 [(set (match_operand:DI 0 "register_operand" "=r")
5485 (subreg:DI (match_operand:SI 1 "lea_address_operand" "p") 0)
5486 (match_operand:DI 2 "const_32bit_mask" "n")))]
5488 "lea{l}\t{%E1, %k0|%k0, %E1}"
5489 [(set_attr "type" "lea")
5490 (set_attr "mode" "SI")])
5492 (define_insn "*lea_6_zext"
5493 [(set (match_operand:DI 0 "register_operand" "=r")
5495 (match_operand:DI 1 "lea_address_operand" "p")
5496 (match_operand:DI 2 "const_32bit_mask" "n")))]
5498 "lea{l}\t{%E1, %k0|%k0, %E1}"
5499 [(set_attr "type" "lea")
5500 (set_attr "mode" "SI")])
5502 (define_insn "*add<mode>_1"
5503 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5505 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5506 (match_operand:SWI48 2 "x86_64_general_operand" "rme,re,0,le")))
5507 (clobber (reg:CC FLAGS_REG))]
5508 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5510 switch (get_attr_type (insn))
5516 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5517 if (operands[2] == const1_rtx)
5518 return "inc{<imodesuffix>}\t%0";
5521 gcc_assert (operands[2] == constm1_rtx);
5522 return "dec{<imodesuffix>}\t%0";
5526 /* For most processors, ADD is faster than LEA. This alternative
5527 was added to use ADD as much as possible. */
5528 if (which_alternative == 2)
5531 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5534 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5535 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5536 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5538 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5542 (cond [(eq_attr "alternative" "3")
5543 (const_string "lea")
5544 (match_operand:SWI48 2 "incdec_operand" "")
5545 (const_string "incdec")
5547 (const_string "alu")))
5548 (set (attr "length_immediate")
5550 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5552 (const_string "*")))
5553 (set_attr "mode" "<MODE>")])
5555 ;; It may seem that nonimmediate operand is proper one for operand 1.
5556 ;; The addsi_1 pattern allows nonimmediate operand at that place and
5557 ;; we take care in ix86_binary_operator_ok to not allow two memory
5558 ;; operands so proper swapping will be done in reload. This allow
5559 ;; patterns constructed from addsi_1 to match.
5561 (define_insn "addsi_1_zext"
5562 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
5564 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r,r")
5565 (match_operand:SI 2 "x86_64_general_operand" "rme,0,le"))))
5566 (clobber (reg:CC FLAGS_REG))]
5567 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5569 switch (get_attr_type (insn))
5575 if (operands[2] == const1_rtx)
5576 return "inc{l}\t%k0";
5579 gcc_assert (operands[2] == constm1_rtx);
5580 return "dec{l}\t%k0";
5584 /* For most processors, ADD is faster than LEA. This alternative
5585 was added to use ADD as much as possible. */
5586 if (which_alternative == 1)
5589 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5592 if (x86_maybe_negate_const_int (&operands[2], SImode))
5593 return "sub{l}\t{%2, %k0|%k0, %2}";
5595 return "add{l}\t{%2, %k0|%k0, %2}";
5599 (cond [(eq_attr "alternative" "2")
5600 (const_string "lea")
5601 (match_operand:SI 2 "incdec_operand" "")
5602 (const_string "incdec")
5604 (const_string "alu")))
5605 (set (attr "length_immediate")
5607 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5609 (const_string "*")))
5610 (set_attr "mode" "SI")])
5612 (define_insn "*addhi_1"
5613 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r,Yp")
5614 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r,Yp")
5615 (match_operand:HI 2 "general_operand" "rn,rm,0,ln")))
5616 (clobber (reg:CC FLAGS_REG))]
5617 "ix86_binary_operator_ok (PLUS, HImode, operands)"
5619 switch (get_attr_type (insn))
5625 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5626 if (operands[2] == const1_rtx)
5627 return "inc{w}\t%0";
5630 gcc_assert (operands[2] == constm1_rtx);
5631 return "dec{w}\t%0";
5635 /* For most processors, ADD is faster than LEA. This alternative
5636 was added to use ADD as much as possible. */
5637 if (which_alternative == 2)
5640 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5643 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5644 if (x86_maybe_negate_const_int (&operands[2], HImode))
5645 return "sub{w}\t{%2, %0|%0, %2}";
5647 return "add{w}\t{%2, %0|%0, %2}";
5651 (cond [(eq_attr "alternative" "3")
5652 (const_string "lea")
5653 (match_operand:HI 2 "incdec_operand" "")
5654 (const_string "incdec")
5656 (const_string "alu")))
5657 (set (attr "length_immediate")
5659 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5661 (const_string "*")))
5662 (set_attr "mode" "HI,HI,HI,SI")])
5664 ;; %%% Potential partial reg stall on alternatives 3 and 4. What to do?
5665 (define_insn "*addqi_1"
5666 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,q,r,r,Yp")
5667 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,q,0,r,Yp")
5668 (match_operand:QI 2 "general_operand" "qn,qm,0,rn,0,ln")))
5669 (clobber (reg:CC FLAGS_REG))]
5670 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5672 bool widen = (which_alternative == 3 || which_alternative == 4);
5674 switch (get_attr_type (insn))
5680 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5681 if (operands[2] == const1_rtx)
5682 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
5685 gcc_assert (operands[2] == constm1_rtx);
5686 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
5690 /* For most processors, ADD is faster than LEA. These alternatives
5691 were added to use ADD as much as possible. */
5692 if (which_alternative == 2 || which_alternative == 4)
5695 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5698 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5699 if (x86_maybe_negate_const_int (&operands[2], QImode))
5702 return "sub{l}\t{%2, %k0|%k0, %2}";
5704 return "sub{b}\t{%2, %0|%0, %2}";
5707 return "add{l}\t{%k2, %k0|%k0, %k2}";
5709 return "add{b}\t{%2, %0|%0, %2}";
5713 (cond [(eq_attr "alternative" "5")
5714 (const_string "lea")
5715 (match_operand:QI 2 "incdec_operand" "")
5716 (const_string "incdec")
5718 (const_string "alu")))
5719 (set (attr "length_immediate")
5721 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5723 (const_string "*")))
5724 (set_attr "mode" "QI,QI,QI,SI,SI,SI")])
5726 (define_insn "*addqi_1_slp"
5727 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
5728 (plus:QI (match_dup 0)
5729 (match_operand:QI 1 "general_operand" "qn,qm")))
5730 (clobber (reg:CC FLAGS_REG))]
5731 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
5732 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
5734 switch (get_attr_type (insn))
5737 if (operands[1] == const1_rtx)
5738 return "inc{b}\t%0";
5741 gcc_assert (operands[1] == constm1_rtx);
5742 return "dec{b}\t%0";
5746 if (x86_maybe_negate_const_int (&operands[1], QImode))
5747 return "sub{b}\t{%1, %0|%0, %1}";
5749 return "add{b}\t{%1, %0|%0, %1}";
5753 (if_then_else (match_operand:QI 1 "incdec_operand" "")
5754 (const_string "incdec")
5755 (const_string "alu1")))
5756 (set (attr "memory")
5757 (if_then_else (match_operand 1 "memory_operand" "")
5758 (const_string "load")
5759 (const_string "none")))
5760 (set_attr "mode" "QI")])
5762 ;; Split non destructive adds if we cannot use lea.
5764 [(set (match_operand:SWI48 0 "register_operand" "")
5765 (plus:SWI48 (match_operand:SWI48 1 "register_operand" "")
5766 (match_operand:SWI48 2 "nonmemory_operand" "")))
5767 (clobber (reg:CC FLAGS_REG))]
5768 "reload_completed && ix86_avoid_lea_for_add (insn, operands)"
5769 [(set (match_dup 0) (match_dup 1))
5770 (parallel [(set (match_dup 0) (plus:<MODE> (match_dup 0) (match_dup 2)))
5771 (clobber (reg:CC FLAGS_REG))])])
5773 ;; Convert add to the lea pattern to avoid flags dependency.
5775 [(set (match_operand:SWI 0 "register_operand" "")
5776 (plus:SWI (match_operand:SWI 1 "register_operand" "")
5777 (match_operand:SWI 2 "<nonmemory_operand>" "")))
5778 (clobber (reg:CC FLAGS_REG))]
5779 "reload_completed && ix86_lea_for_add_ok (insn, operands)"
5782 enum machine_mode mode = <MODE>mode;
5785 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
5788 operands[0] = gen_lowpart (mode, operands[0]);
5789 operands[1] = gen_lowpart (mode, operands[1]);
5790 operands[2] = gen_lowpart (mode, operands[2]);
5793 pat = gen_rtx_PLUS (mode, operands[1], operands[2]);
5795 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
5799 ;; Convert add to the lea pattern to avoid flags dependency.
5801 [(set (match_operand:DI 0 "register_operand" "")
5803 (plus:SI (match_operand:SI 1 "register_operand" "")
5804 (match_operand:SI 2 "x86_64_nonmemory_operand" ""))))
5805 (clobber (reg:CC FLAGS_REG))]
5806 "TARGET_64BIT && reload_completed && ix86_lea_for_add_ok (insn, operands)"
5808 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))])
5810 (define_insn "*add<mode>_2"
5811 [(set (reg FLAGS_REG)
5814 (match_operand:SWI 1 "nonimmediate_operand" "%0,0,<r>")
5815 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>,0"))
5817 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m,<r>")
5818 (plus:SWI (match_dup 1) (match_dup 2)))]
5819 "ix86_match_ccmode (insn, CCGOCmode)
5820 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5822 switch (get_attr_type (insn))
5825 if (operands[2] == const1_rtx)
5826 return "inc{<imodesuffix>}\t%0";
5829 gcc_assert (operands[2] == constm1_rtx);
5830 return "dec{<imodesuffix>}\t%0";
5834 if (which_alternative == 2)
5837 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5840 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5841 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5842 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5844 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5848 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5849 (const_string "incdec")
5850 (const_string "alu")))
5851 (set (attr "length_immediate")
5853 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5855 (const_string "*")))
5856 (set_attr "mode" "<MODE>")])
5858 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5859 (define_insn "*addsi_2_zext"
5860 [(set (reg FLAGS_REG)
5862 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
5863 (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5865 (set (match_operand:DI 0 "register_operand" "=r,r")
5866 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5867 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
5868 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5870 switch (get_attr_type (insn))
5873 if (operands[2] == const1_rtx)
5874 return "inc{l}\t%k0";
5877 gcc_assert (operands[2] == constm1_rtx);
5878 return "dec{l}\t%k0";
5882 if (which_alternative == 1)
5885 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5888 if (x86_maybe_negate_const_int (&operands[2], SImode))
5889 return "sub{l}\t{%2, %k0|%k0, %2}";
5891 return "add{l}\t{%2, %k0|%k0, %2}";
5895 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5896 (const_string "incdec")
5897 (const_string "alu")))
5898 (set (attr "length_immediate")
5900 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5902 (const_string "*")))
5903 (set_attr "mode" "SI")])
5905 (define_insn "*add<mode>_3"
5906 [(set (reg FLAGS_REG)
5908 (neg:SWI (match_operand:SWI 2 "<general_operand>" "<g>,0"))
5909 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")))
5910 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
5911 "ix86_match_ccmode (insn, CCZmode)
5912 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
5914 switch (get_attr_type (insn))
5917 if (operands[2] == const1_rtx)
5918 return "inc{<imodesuffix>}\t%0";
5921 gcc_assert (operands[2] == constm1_rtx);
5922 return "dec{<imodesuffix>}\t%0";
5926 if (which_alternative == 1)
5929 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5932 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5933 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
5934 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
5936 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
5940 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
5941 (const_string "incdec")
5942 (const_string "alu")))
5943 (set (attr "length_immediate")
5945 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5947 (const_string "*")))
5948 (set_attr "mode" "<MODE>")])
5950 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
5951 (define_insn "*addsi_3_zext"
5952 [(set (reg FLAGS_REG)
5954 (neg:SI (match_operand:SI 2 "x86_64_general_operand" "rme,0"))
5955 (match_operand:SI 1 "nonimmediate_operand" "%0,r")))
5956 (set (match_operand:DI 0 "register_operand" "=r,r")
5957 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
5958 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
5959 && ix86_binary_operator_ok (PLUS, SImode, operands)"
5961 switch (get_attr_type (insn))
5964 if (operands[2] == const1_rtx)
5965 return "inc{l}\t%k0";
5968 gcc_assert (operands[2] == constm1_rtx);
5969 return "dec{l}\t%k0";
5973 if (which_alternative == 1)
5976 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
5979 if (x86_maybe_negate_const_int (&operands[2], SImode))
5980 return "sub{l}\t{%2, %k0|%k0, %2}";
5982 return "add{l}\t{%2, %k0|%k0, %2}";
5986 (if_then_else (match_operand:SI 2 "incdec_operand" "")
5987 (const_string "incdec")
5988 (const_string "alu")))
5989 (set (attr "length_immediate")
5991 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
5993 (const_string "*")))
5994 (set_attr "mode" "SI")])
5996 ; For comparisons against 1, -1 and 128, we may generate better code
5997 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
5998 ; is matched then. We can't accept general immediate, because for
5999 ; case of overflows, the result is messed up.
6000 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6001 ; only for comparisons not depending on it.
6003 (define_insn "*adddi_4"
6004 [(set (reg FLAGS_REG)
6006 (match_operand:DI 1 "nonimmediate_operand" "0")
6007 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6008 (clobber (match_scratch:DI 0 "=rm"))]
6010 && ix86_match_ccmode (insn, CCGCmode)"
6012 switch (get_attr_type (insn))
6015 if (operands[2] == constm1_rtx)
6016 return "inc{q}\t%0";
6019 gcc_assert (operands[2] == const1_rtx);
6020 return "dec{q}\t%0";
6024 if (x86_maybe_negate_const_int (&operands[2], DImode))
6025 return "add{q}\t{%2, %0|%0, %2}";
6027 return "sub{q}\t{%2, %0|%0, %2}";
6031 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6032 (const_string "incdec")
6033 (const_string "alu")))
6034 (set (attr "length_immediate")
6036 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6038 (const_string "*")))
6039 (set_attr "mode" "DI")])
6041 ; For comparisons against 1, -1 and 128, we may generate better code
6042 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6043 ; is matched then. We can't accept general immediate, because for
6044 ; case of overflows, the result is messed up.
6045 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6046 ; only for comparisons not depending on it.
6048 (define_insn "*add<mode>_4"
6049 [(set (reg FLAGS_REG)
6051 (match_operand:SWI124 1 "nonimmediate_operand" "0")
6052 (match_operand:SWI124 2 "const_int_operand" "n")))
6053 (clobber (match_scratch:SWI124 0 "=<r>m"))]
6054 "ix86_match_ccmode (insn, CCGCmode)"
6056 switch (get_attr_type (insn))
6059 if (operands[2] == constm1_rtx)
6060 return "inc{<imodesuffix>}\t%0";
6063 gcc_assert (operands[2] == const1_rtx);
6064 return "dec{<imodesuffix>}\t%0";
6068 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6069 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6071 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6075 (if_then_else (match_operand:<MODE> 2 "incdec_operand" "")
6076 (const_string "incdec")
6077 (const_string "alu")))
6078 (set (attr "length_immediate")
6080 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6082 (const_string "*")))
6083 (set_attr "mode" "<MODE>")])
6085 (define_insn "*add<mode>_5"
6086 [(set (reg FLAGS_REG)
6089 (match_operand:SWI 1 "nonimmediate_operand" "%0,<r>")
6090 (match_operand:SWI 2 "<general_operand>" "<g>,0"))
6092 (clobber (match_scratch:SWI 0 "=<r>,<r>"))]
6093 "ix86_match_ccmode (insn, CCGOCmode)
6094 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6096 switch (get_attr_type (insn))
6099 if (operands[2] == const1_rtx)
6100 return "inc{<imodesuffix>}\t%0";
6103 gcc_assert (operands[2] == constm1_rtx);
6104 return "dec{<imodesuffix>}\t%0";
6108 if (which_alternative == 1)
6111 tmp = operands[1], operands[1] = operands[2], operands[2] = tmp;
6114 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6115 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6116 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6118 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6122 (if_then_else (match_operand:SWI 2 "incdec_operand" "")
6123 (const_string "incdec")
6124 (const_string "alu")))
6125 (set (attr "length_immediate")
6127 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6129 (const_string "*")))
6130 (set_attr "mode" "<MODE>")])
6132 (define_insn "*addqi_ext_1_rex64"
6133 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6138 (match_operand 1 "ext_register_operand" "0")
6141 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6142 (clobber (reg:CC FLAGS_REG))]
6145 switch (get_attr_type (insn))
6148 if (operands[2] == const1_rtx)
6149 return "inc{b}\t%h0";
6152 gcc_assert (operands[2] == constm1_rtx);
6153 return "dec{b}\t%h0";
6157 return "add{b}\t{%2, %h0|%h0, %2}";
6161 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6162 (const_string "incdec")
6163 (const_string "alu")))
6164 (set_attr "modrm" "1")
6165 (set_attr "mode" "QI")])
6167 (define_insn "addqi_ext_1"
6168 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6173 (match_operand 1 "ext_register_operand" "0")
6176 (match_operand:QI 2 "general_operand" "Qmn")))
6177 (clobber (reg:CC FLAGS_REG))]
6180 switch (get_attr_type (insn))
6183 if (operands[2] == const1_rtx)
6184 return "inc{b}\t%h0";
6187 gcc_assert (operands[2] == constm1_rtx);
6188 return "dec{b}\t%h0";
6192 return "add{b}\t{%2, %h0|%h0, %2}";
6196 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6197 (const_string "incdec")
6198 (const_string "alu")))
6199 (set_attr "modrm" "1")
6200 (set_attr "mode" "QI")])
6202 (define_insn "*addqi_ext_2"
6203 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6208 (match_operand 1 "ext_register_operand" "%0")
6212 (match_operand 2 "ext_register_operand" "Q")
6215 (clobber (reg:CC FLAGS_REG))]
6217 "add{b}\t{%h2, %h0|%h0, %h2}"
6218 [(set_attr "type" "alu")
6219 (set_attr "mode" "QI")])
6221 ;; The lea patterns for modes less than 32 bits need to be matched by
6222 ;; several insns converted to real lea by splitters.
6224 (define_insn_and_split "*lea_general_1"
6225 [(set (match_operand 0 "register_operand" "=r")
6226 (plus (plus (match_operand 1 "index_register_operand" "l")
6227 (match_operand 2 "register_operand" "r"))
6228 (match_operand 3 "immediate_operand" "i")))]
6229 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6230 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6231 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6232 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6233 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6234 || GET_MODE (operands[3]) == VOIDmode)"
6236 "&& reload_completed"
6239 enum machine_mode mode = SImode;
6242 operands[0] = gen_lowpart (mode, operands[0]);
6243 operands[1] = gen_lowpart (mode, operands[1]);
6244 operands[2] = gen_lowpart (mode, operands[2]);
6245 operands[3] = gen_lowpart (mode, operands[3]);
6247 pat = gen_rtx_PLUS (mode, gen_rtx_PLUS (mode, operands[1], operands[2]),
6250 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6253 [(set_attr "type" "lea")
6254 (set_attr "mode" "SI")])
6256 (define_insn_and_split "*lea_general_2"
6257 [(set (match_operand 0 "register_operand" "=r")
6258 (plus (mult (match_operand 1 "index_register_operand" "l")
6259 (match_operand 2 "const248_operand" "n"))
6260 (match_operand 3 "nonmemory_operand" "ri")))]
6261 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6262 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6263 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6264 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6265 || GET_MODE (operands[3]) == VOIDmode)"
6267 "&& reload_completed"
6270 enum machine_mode mode = SImode;
6273 operands[0] = gen_lowpart (mode, operands[0]);
6274 operands[1] = gen_lowpart (mode, operands[1]);
6275 operands[3] = gen_lowpart (mode, operands[3]);
6277 pat = gen_rtx_PLUS (mode, gen_rtx_MULT (mode, operands[1], operands[2]),
6280 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6283 [(set_attr "type" "lea")
6284 (set_attr "mode" "SI")])
6286 (define_insn_and_split "*lea_general_3"
6287 [(set (match_operand 0 "register_operand" "=r")
6288 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6289 (match_operand 2 "const248_operand" "n"))
6290 (match_operand 3 "register_operand" "r"))
6291 (match_operand 4 "immediate_operand" "i")))]
6292 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6293 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6294 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6295 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6297 "&& reload_completed"
6300 enum machine_mode mode = SImode;
6303 operands[0] = gen_lowpart (mode, operands[0]);
6304 operands[1] = gen_lowpart (mode, operands[1]);
6305 operands[3] = gen_lowpart (mode, operands[3]);
6306 operands[4] = gen_lowpart (mode, operands[4]);
6308 pat = gen_rtx_PLUS (mode,
6310 gen_rtx_MULT (mode, operands[1],
6315 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6318 [(set_attr "type" "lea")
6319 (set_attr "mode" "SI")])
6321 (define_insn_and_split "*lea_general_4"
6322 [(set (match_operand 0 "register_operand" "=r")
6324 (match_operand 1 "index_register_operand" "l")
6325 (match_operand 2 "const_int_operand" "n"))
6326 (match_operand 3 "const_int_operand" "n")))]
6327 "(((GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode)
6328 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)))
6329 || GET_MODE (operands[0]) == SImode
6330 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
6331 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6332 && ((unsigned HOST_WIDE_INT) INTVAL (operands[2])) - 1 < 3
6333 && ((unsigned HOST_WIDE_INT) INTVAL (operands[3])
6334 < ((unsigned HOST_WIDE_INT) 1 << INTVAL (operands[2])))"
6336 "&& reload_completed"
6339 enum machine_mode mode = GET_MODE (operands[0]);
6342 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
6345 operands[0] = gen_lowpart (mode, operands[0]);
6346 operands[1] = gen_lowpart (mode, operands[1]);
6349 operands[2] = GEN_INT (1 << INTVAL (operands[2]));
6351 pat = plus_constant (gen_rtx_MULT (mode, operands[1], operands[2]),
6352 INTVAL (operands[3]));
6354 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6357 [(set_attr "type" "lea")
6359 (if_then_else (match_operand:DI 0 "" "")
6361 (const_string "SI")))])
6363 ;; Subtract instructions
6365 (define_expand "sub<mode>3"
6366 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
6367 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
6368 (match_operand:SDWIM 2 "<general_operand>" "")))]
6370 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
6372 (define_insn_and_split "*sub<dwi>3_doubleword"
6373 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
6375 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
6376 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
6377 (clobber (reg:CC FLAGS_REG))]
6378 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6381 [(parallel [(set (reg:CC FLAGS_REG)
6382 (compare:CC (match_dup 1) (match_dup 2)))
6384 (minus:DWIH (match_dup 1) (match_dup 2)))])
6385 (parallel [(set (match_dup 3)
6389 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
6391 (clobber (reg:CC FLAGS_REG))])]
6392 "split_double_mode (<DWI>mode, &operands[0], 3, &operands[0], &operands[3]);")
6394 (define_insn "*sub<mode>_1"
6395 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6397 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6398 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6399 (clobber (reg:CC FLAGS_REG))]
6400 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6401 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6402 [(set_attr "type" "alu")
6403 (set_attr "mode" "<MODE>")])
6405 (define_insn "*subsi_1_zext"
6406 [(set (match_operand:DI 0 "register_operand" "=r")
6408 (minus:SI (match_operand:SI 1 "register_operand" "0")
6409 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
6410 (clobber (reg:CC FLAGS_REG))]
6411 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6412 "sub{l}\t{%2, %k0|%k0, %2}"
6413 [(set_attr "type" "alu")
6414 (set_attr "mode" "SI")])
6416 (define_insn "*subqi_1_slp"
6417 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6418 (minus:QI (match_dup 0)
6419 (match_operand:QI 1 "general_operand" "qn,qm")))
6420 (clobber (reg:CC FLAGS_REG))]
6421 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6422 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6423 "sub{b}\t{%1, %0|%0, %1}"
6424 [(set_attr "type" "alu1")
6425 (set_attr "mode" "QI")])
6427 (define_insn "*sub<mode>_2"
6428 [(set (reg FLAGS_REG)
6431 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6432 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6434 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6435 (minus:SWI (match_dup 1) (match_dup 2)))]
6436 "ix86_match_ccmode (insn, CCGOCmode)
6437 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6438 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6439 [(set_attr "type" "alu")
6440 (set_attr "mode" "<MODE>")])
6442 (define_insn "*subsi_2_zext"
6443 [(set (reg FLAGS_REG)
6445 (minus:SI (match_operand:SI 1 "register_operand" "0")
6446 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6448 (set (match_operand:DI 0 "register_operand" "=r")
6450 (minus:SI (match_dup 1)
6452 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6453 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6454 "sub{l}\t{%2, %k0|%k0, %2}"
6455 [(set_attr "type" "alu")
6456 (set_attr "mode" "SI")])
6458 (define_insn "*sub<mode>_3"
6459 [(set (reg FLAGS_REG)
6460 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
6461 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
6462 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6463 (minus:SWI (match_dup 1) (match_dup 2)))]
6464 "ix86_match_ccmode (insn, CCmode)
6465 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
6466 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
6467 [(set_attr "type" "alu")
6468 (set_attr "mode" "<MODE>")])
6470 (define_insn "*subsi_3_zext"
6471 [(set (reg FLAGS_REG)
6472 (compare (match_operand:SI 1 "register_operand" "0")
6473 (match_operand:SI 2 "x86_64_general_operand" "rme")))
6474 (set (match_operand:DI 0 "register_operand" "=r")
6476 (minus:SI (match_dup 1)
6478 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
6479 && ix86_binary_operator_ok (MINUS, SImode, operands)"
6480 "sub{l}\t{%2, %1|%1, %2}"
6481 [(set_attr "type" "alu")
6482 (set_attr "mode" "SI")])
6484 ;; Add with carry and subtract with borrow
6486 (define_expand "<plusminus_insn><mode>3_carry"
6488 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
6490 (match_operand:SWI 1 "nonimmediate_operand" "")
6491 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
6492 [(match_operand 3 "flags_reg_operand" "")
6494 (match_operand:SWI 2 "<general_operand>" ""))))
6495 (clobber (reg:CC FLAGS_REG))])]
6496 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)")
6498 (define_insn "*<plusminus_insn><mode>3_carry"
6499 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6501 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6503 (match_operator 3 "ix86_carry_flag_operator"
6504 [(reg FLAGS_REG) (const_int 0)])
6505 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
6506 (clobber (reg:CC FLAGS_REG))]
6507 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6508 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6509 [(set_attr "type" "alu")
6510 (set_attr "use_carry" "1")
6511 (set_attr "pent_pair" "pu")
6512 (set_attr "mode" "<MODE>")])
6514 (define_insn "*addsi3_carry_zext"
6515 [(set (match_operand:DI 0 "register_operand" "=r")
6517 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6518 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6519 [(reg FLAGS_REG) (const_int 0)])
6520 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6521 (clobber (reg:CC FLAGS_REG))]
6522 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6523 "adc{l}\t{%2, %k0|%k0, %2}"
6524 [(set_attr "type" "alu")
6525 (set_attr "use_carry" "1")
6526 (set_attr "pent_pair" "pu")
6527 (set_attr "mode" "SI")])
6529 (define_insn "*subsi3_carry_zext"
6530 [(set (match_operand:DI 0 "register_operand" "=r")
6532 (minus:SI (match_operand:SI 1 "register_operand" "0")
6533 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
6534 [(reg FLAGS_REG) (const_int 0)])
6535 (match_operand:SI 2 "x86_64_general_operand" "rme")))))
6536 (clobber (reg:CC FLAGS_REG))]
6537 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
6538 "sbb{l}\t{%2, %k0|%k0, %2}"
6539 [(set_attr "type" "alu")
6540 (set_attr "pent_pair" "pu")
6541 (set_attr "mode" "SI")])
6543 ;; Overflow setting add and subtract instructions
6545 (define_insn "*add<mode>3_cconly_overflow"
6546 [(set (reg:CCC FLAGS_REG)
6549 (match_operand:SWI 1 "nonimmediate_operand" "%0")
6550 (match_operand:SWI 2 "<general_operand>" "<g>"))
6552 (clobber (match_scratch:SWI 0 "=<r>"))]
6553 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6554 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6555 [(set_attr "type" "alu")
6556 (set_attr "mode" "<MODE>")])
6558 (define_insn "*sub<mode>3_cconly_overflow"
6559 [(set (reg:CCC FLAGS_REG)
6562 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6563 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6566 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6567 [(set_attr "type" "icmp")
6568 (set_attr "mode" "<MODE>")])
6570 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6571 [(set (reg:CCC FLAGS_REG)
6574 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6575 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6577 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6578 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6579 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6580 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6581 [(set_attr "type" "alu")
6582 (set_attr "mode" "<MODE>")])
6584 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6585 [(set (reg:CCC FLAGS_REG)
6588 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6589 (match_operand:SI 2 "x86_64_general_operand" "rme"))
6591 (set (match_operand:DI 0 "register_operand" "=r")
6592 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6593 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6594 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6595 [(set_attr "type" "alu")
6596 (set_attr "mode" "SI")])
6598 ;; The patterns that match these are at the end of this file.
6600 (define_expand "<plusminus_insn>xf3"
6601 [(set (match_operand:XF 0 "register_operand" "")
6603 (match_operand:XF 1 "register_operand" "")
6604 (match_operand:XF 2 "register_operand" "")))]
6607 (define_expand "<plusminus_insn><mode>3"
6608 [(set (match_operand:MODEF 0 "register_operand" "")
6610 (match_operand:MODEF 1 "register_operand" "")
6611 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
6612 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
6613 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
6615 ;; Multiply instructions
6617 (define_expand "mul<mode>3"
6618 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
6620 (match_operand:SWIM248 1 "register_operand" "")
6621 (match_operand:SWIM248 2 "<general_operand>" "")))
6622 (clobber (reg:CC FLAGS_REG))])])
6624 (define_expand "mulqi3"
6625 [(parallel [(set (match_operand:QI 0 "register_operand" "")
6627 (match_operand:QI 1 "register_operand" "")
6628 (match_operand:QI 2 "nonimmediate_operand" "")))
6629 (clobber (reg:CC FLAGS_REG))])]
6630 "TARGET_QIMODE_MATH")
6633 ;; IMUL reg32/64, reg32/64, imm8 Direct
6634 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
6635 ;; IMUL reg32/64, reg32/64, imm32 Direct
6636 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
6637 ;; IMUL reg32/64, reg32/64 Direct
6638 ;; IMUL reg32/64, mem32/64 Direct
6640 ;; On BDVER1, all above IMULs use DirectPath
6642 (define_insn "*mul<mode>3_1"
6643 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
6645 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
6646 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
6647 (clobber (reg:CC FLAGS_REG))]
6648 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6650 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6651 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
6652 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
6653 [(set_attr "type" "imul")
6654 (set_attr "prefix_0f" "0,0,1")
6655 (set (attr "athlon_decode")
6656 (cond [(eq_attr "cpu" "athlon")
6657 (const_string "vector")
6658 (eq_attr "alternative" "1")
6659 (const_string "vector")
6660 (and (eq_attr "alternative" "2")
6661 (match_operand 1 "memory_operand" ""))
6662 (const_string "vector")]
6663 (const_string "direct")))
6664 (set (attr "amdfam10_decode")
6665 (cond [(and (eq_attr "alternative" "0,1")
6666 (match_operand 1 "memory_operand" ""))
6667 (const_string "vector")]
6668 (const_string "direct")))
6669 (set_attr "bdver1_decode" "direct")
6670 (set_attr "mode" "<MODE>")])
6672 (define_insn "*mulsi3_1_zext"
6673 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
6675 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
6676 (match_operand:SI 2 "x86_64_general_operand" "K,e,mr"))))
6677 (clobber (reg:CC FLAGS_REG))]
6679 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6681 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6682 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
6683 imul{l}\t{%2, %k0|%k0, %2}"
6684 [(set_attr "type" "imul")
6685 (set_attr "prefix_0f" "0,0,1")
6686 (set (attr "athlon_decode")
6687 (cond [(eq_attr "cpu" "athlon")
6688 (const_string "vector")
6689 (eq_attr "alternative" "1")
6690 (const_string "vector")
6691 (and (eq_attr "alternative" "2")
6692 (match_operand 1 "memory_operand" ""))
6693 (const_string "vector")]
6694 (const_string "direct")))
6695 (set (attr "amdfam10_decode")
6696 (cond [(and (eq_attr "alternative" "0,1")
6697 (match_operand 1 "memory_operand" ""))
6698 (const_string "vector")]
6699 (const_string "direct")))
6700 (set_attr "bdver1_decode" "direct")
6701 (set_attr "mode" "SI")])
6704 ;; IMUL reg16, reg16, imm8 VectorPath
6705 ;; IMUL reg16, mem16, imm8 VectorPath
6706 ;; IMUL reg16, reg16, imm16 VectorPath
6707 ;; IMUL reg16, mem16, imm16 VectorPath
6708 ;; IMUL reg16, reg16 Direct
6709 ;; IMUL reg16, mem16 Direct
6711 ;; On BDVER1, all HI MULs use DoublePath
6713 (define_insn "*mulhi3_1"
6714 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
6715 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
6716 (match_operand:HI 2 "general_operand" "K,n,mr")))
6717 (clobber (reg:CC FLAGS_REG))]
6719 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6721 imul{w}\t{%2, %1, %0|%0, %1, %2}
6722 imul{w}\t{%2, %1, %0|%0, %1, %2}
6723 imul{w}\t{%2, %0|%0, %2}"
6724 [(set_attr "type" "imul")
6725 (set_attr "prefix_0f" "0,0,1")
6726 (set (attr "athlon_decode")
6727 (cond [(eq_attr "cpu" "athlon")
6728 (const_string "vector")
6729 (eq_attr "alternative" "1,2")
6730 (const_string "vector")]
6731 (const_string "direct")))
6732 (set (attr "amdfam10_decode")
6733 (cond [(eq_attr "alternative" "0,1")
6734 (const_string "vector")]
6735 (const_string "direct")))
6736 (set_attr "bdver1_decode" "double")
6737 (set_attr "mode" "HI")])
6739 ;;On AMDFAM10 and BDVER1
6743 (define_insn "*mulqi3_1"
6744 [(set (match_operand:QI 0 "register_operand" "=a")
6745 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6746 (match_operand:QI 2 "nonimmediate_operand" "qm")))
6747 (clobber (reg:CC FLAGS_REG))]
6749 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6751 [(set_attr "type" "imul")
6752 (set_attr "length_immediate" "0")
6753 (set (attr "athlon_decode")
6754 (if_then_else (eq_attr "cpu" "athlon")
6755 (const_string "vector")
6756 (const_string "direct")))
6757 (set_attr "amdfam10_decode" "direct")
6758 (set_attr "bdver1_decode" "direct")
6759 (set_attr "mode" "QI")])
6761 (define_expand "<u>mul<mode><dwi>3"
6762 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
6765 (match_operand:DWIH 1 "nonimmediate_operand" ""))
6767 (match_operand:DWIH 2 "register_operand" ""))))
6768 (clobber (reg:CC FLAGS_REG))])])
6770 (define_expand "<u>mulqihi3"
6771 [(parallel [(set (match_operand:HI 0 "register_operand" "")
6774 (match_operand:QI 1 "nonimmediate_operand" ""))
6776 (match_operand:QI 2 "register_operand" ""))))
6777 (clobber (reg:CC FLAGS_REG))])]
6778 "TARGET_QIMODE_MATH")
6780 (define_insn "*bmi2_umulditi3_1"
6781 [(set (match_operand:DI 0 "register_operand" "=r")
6783 (match_operand:DI 2 "nonimmediate_operand" "%d")
6784 (match_operand:DI 3 "nonimmediate_operand" "rm")))
6785 (set (match_operand:DI 1 "register_operand" "=r")
6788 (mult:TI (zero_extend:TI (match_dup 2))
6789 (zero_extend:TI (match_dup 3)))
6791 "TARGET_64BIT && TARGET_BMI2
6792 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6793 "mulx\t{%3, %0, %1|%1, %0, %3}"
6794 [(set_attr "type" "imulx")
6795 (set_attr "prefix" "vex")
6796 (set_attr "mode" "DI")])
6798 (define_insn "*bmi2_umulsidi3_1"
6799 [(set (match_operand:SI 0 "register_operand" "=r")
6801 (match_operand:SI 2 "nonimmediate_operand" "%d")
6802 (match_operand:SI 3 "nonimmediate_operand" "rm")))
6803 (set (match_operand:SI 1 "register_operand" "=r")
6806 (mult:DI (zero_extend:DI (match_dup 2))
6807 (zero_extend:DI (match_dup 3)))
6809 "!TARGET_64BIT && TARGET_BMI2
6810 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6811 "mulx\t{%3, %0, %1|%1, %0, %3}"
6812 [(set_attr "type" "imulx")
6813 (set_attr "prefix" "vex")
6814 (set_attr "mode" "SI")])
6816 (define_insn "*umul<mode><dwi>3_1"
6817 [(set (match_operand:<DWI> 0 "register_operand" "=A,r")
6820 (match_operand:DWIH 1 "nonimmediate_operand" "%0,d"))
6822 (match_operand:DWIH 2 "nonimmediate_operand" "rm,rm"))))
6823 (clobber (reg:CC FLAGS_REG))]
6824 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6826 mul{<imodesuffix>}\t%2
6828 [(set_attr "isa" "*,bmi2")
6829 (set_attr "type" "imul,imulx")
6830 (set_attr "length_immediate" "0,*")
6831 (set (attr "athlon_decode")
6832 (cond [(eq_attr "alternative" "0")
6833 (if_then_else (eq_attr "cpu" "athlon")
6834 (const_string "vector")
6835 (const_string "double"))]
6836 (const_string "*")))
6837 (set_attr "amdfam10_decode" "double,*")
6838 (set_attr "bdver1_decode" "direct,*")
6839 (set_attr "prefix" "orig,vex")
6840 (set_attr "mode" "<MODE>")])
6842 ;; Convert mul to the mulx pattern to avoid flags dependency.
6844 [(set (match_operand:<DWI> 0 "register_operand" "")
6847 (match_operand:DWIH 1 "register_operand" ""))
6849 (match_operand:DWIH 2 "nonimmediate_operand" ""))))
6850 (clobber (reg:CC FLAGS_REG))]
6851 "TARGET_BMI2 && reload_completed
6852 && true_regnum (operands[1]) == DX_REG"
6853 [(parallel [(set (match_dup 3)
6854 (mult:DWIH (match_dup 1) (match_dup 2)))
6858 (mult:<DWI> (zero_extend:<DWI> (match_dup 1))
6859 (zero_extend:<DWI> (match_dup 2)))
6862 split_double_mode (<DWI>mode, &operands[0], 1, &operands[3], &operands[4]);
6864 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
6867 (define_insn "*mul<mode><dwi>3_1"
6868 [(set (match_operand:<DWI> 0 "register_operand" "=A")
6871 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
6873 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
6874 (clobber (reg:CC FLAGS_REG))]
6875 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6876 "imul{<imodesuffix>}\t%2"
6877 [(set_attr "type" "imul")
6878 (set_attr "length_immediate" "0")
6879 (set (attr "athlon_decode")
6880 (if_then_else (eq_attr "cpu" "athlon")
6881 (const_string "vector")
6882 (const_string "double")))
6883 (set_attr "amdfam10_decode" "double")
6884 (set_attr "bdver1_decode" "direct")
6885 (set_attr "mode" "<MODE>")])
6887 (define_insn "*<u>mulqihi3_1"
6888 [(set (match_operand:HI 0 "register_operand" "=a")
6891 (match_operand:QI 1 "nonimmediate_operand" "%0"))
6893 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
6894 (clobber (reg:CC FLAGS_REG))]
6896 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6897 "<sgnprefix>mul{b}\t%2"
6898 [(set_attr "type" "imul")
6899 (set_attr "length_immediate" "0")
6900 (set (attr "athlon_decode")
6901 (if_then_else (eq_attr "cpu" "athlon")
6902 (const_string "vector")
6903 (const_string "direct")))
6904 (set_attr "amdfam10_decode" "direct")
6905 (set_attr "bdver1_decode" "direct")
6906 (set_attr "mode" "QI")])
6908 (define_expand "<s>mul<mode>3_highpart"
6909 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
6914 (match_operand:SWI48 1 "nonimmediate_operand" ""))
6916 (match_operand:SWI48 2 "register_operand" "")))
6918 (clobber (match_scratch:SWI48 3 ""))
6919 (clobber (reg:CC FLAGS_REG))])]
6921 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
6923 (define_insn "*<s>muldi3_highpart_1"
6924 [(set (match_operand:DI 0 "register_operand" "=d")
6929 (match_operand:DI 1 "nonimmediate_operand" "%a"))
6931 (match_operand:DI 2 "nonimmediate_operand" "rm")))
6933 (clobber (match_scratch:DI 3 "=1"))
6934 (clobber (reg:CC FLAGS_REG))]
6936 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6937 "<sgnprefix>mul{q}\t%2"
6938 [(set_attr "type" "imul")
6939 (set_attr "length_immediate" "0")
6940 (set (attr "athlon_decode")
6941 (if_then_else (eq_attr "cpu" "athlon")
6942 (const_string "vector")
6943 (const_string "double")))
6944 (set_attr "amdfam10_decode" "double")
6945 (set_attr "bdver1_decode" "direct")
6946 (set_attr "mode" "DI")])
6948 (define_insn "*<s>mulsi3_highpart_1"
6949 [(set (match_operand:SI 0 "register_operand" "=d")
6954 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6956 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6958 (clobber (match_scratch:SI 3 "=1"))
6959 (clobber (reg:CC FLAGS_REG))]
6960 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
6961 "<sgnprefix>mul{l}\t%2"
6962 [(set_attr "type" "imul")
6963 (set_attr "length_immediate" "0")
6964 (set (attr "athlon_decode")
6965 (if_then_else (eq_attr "cpu" "athlon")
6966 (const_string "vector")
6967 (const_string "double")))
6968 (set_attr "amdfam10_decode" "double")
6969 (set_attr "bdver1_decode" "direct")
6970 (set_attr "mode" "SI")])
6972 (define_insn "*<s>mulsi3_highpart_zext"
6973 [(set (match_operand:DI 0 "register_operand" "=d")
6974 (zero_extend:DI (truncate:SI
6976 (mult:DI (any_extend:DI
6977 (match_operand:SI 1 "nonimmediate_operand" "%a"))
6979 (match_operand:SI 2 "nonimmediate_operand" "rm")))
6981 (clobber (match_scratch:SI 3 "=1"))
6982 (clobber (reg:CC FLAGS_REG))]
6984 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6985 "<sgnprefix>mul{l}\t%2"
6986 [(set_attr "type" "imul")
6987 (set_attr "length_immediate" "0")
6988 (set (attr "athlon_decode")
6989 (if_then_else (eq_attr "cpu" "athlon")
6990 (const_string "vector")
6991 (const_string "double")))
6992 (set_attr "amdfam10_decode" "double")
6993 (set_attr "bdver1_decode" "direct")
6994 (set_attr "mode" "SI")])
6996 ;; The patterns that match these are at the end of this file.
6998 (define_expand "mulxf3"
6999 [(set (match_operand:XF 0 "register_operand" "")
7000 (mult:XF (match_operand:XF 1 "register_operand" "")
7001 (match_operand:XF 2 "register_operand" "")))]
7004 (define_expand "mul<mode>3"
7005 [(set (match_operand:MODEF 0 "register_operand" "")
7006 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7007 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7008 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7009 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)")
7011 ;; Divide instructions
7013 ;; The patterns that match these are at the end of this file.
7015 (define_expand "divxf3"
7016 [(set (match_operand:XF 0 "register_operand" "")
7017 (div:XF (match_operand:XF 1 "register_operand" "")
7018 (match_operand:XF 2 "register_operand" "")))]
7021 (define_expand "divdf3"
7022 [(set (match_operand:DF 0 "register_operand" "")
7023 (div:DF (match_operand:DF 1 "register_operand" "")
7024 (match_operand:DF 2 "nonimmediate_operand" "")))]
7025 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7026 || (TARGET_SSE2 && TARGET_SSE_MATH)")
7028 (define_expand "divsf3"
7029 [(set (match_operand:SF 0 "register_operand" "")
7030 (div:SF (match_operand:SF 1 "register_operand" "")
7031 (match_operand:SF 2 "nonimmediate_operand" "")))]
7032 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7037 && optimize_insn_for_speed_p ()
7038 && flag_finite_math_only && !flag_trapping_math
7039 && flag_unsafe_math_optimizations)
7041 ix86_emit_swdivsf (operands[0], operands[1],
7042 operands[2], SFmode);
7047 ;; Divmod instructions.
7049 (define_expand "divmod<mode>4"
7050 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7052 (match_operand:SWIM248 1 "register_operand" "")
7053 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7054 (set (match_operand:SWIM248 3 "register_operand" "")
7055 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7056 (clobber (reg:CC FLAGS_REG))])])
7058 ;; Split with 8bit unsigned divide:
7059 ;; if (dividend an divisor are in [0-255])
7060 ;; use 8bit unsigned integer divide
7062 ;; use original integer divide
7064 [(set (match_operand:SWI48 0 "register_operand" "")
7065 (div:SWI48 (match_operand:SWI48 2 "register_operand" "")
7066 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7067 (set (match_operand:SWI48 1 "register_operand" "")
7068 (mod:SWI48 (match_dup 2) (match_dup 3)))
7069 (clobber (reg:CC FLAGS_REG))]
7070 "TARGET_USE_8BIT_IDIV
7071 && TARGET_QIMODE_MATH
7072 && can_create_pseudo_p ()
7073 && !optimize_insn_for_size_p ()"
7075 "ix86_split_idivmod (<MODE>mode, operands, true); DONE;")
7077 (define_insn_and_split "divmod<mode>4_1"
7078 [(set (match_operand:SWI48 0 "register_operand" "=a")
7079 (div:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7080 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7081 (set (match_operand:SWI48 1 "register_operand" "=&d")
7082 (mod:SWI48 (match_dup 2) (match_dup 3)))
7083 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7084 (clobber (reg:CC FLAGS_REG))]
7088 [(parallel [(set (match_dup 1)
7089 (ashiftrt:SWI48 (match_dup 4) (match_dup 5)))
7090 (clobber (reg:CC FLAGS_REG))])
7091 (parallel [(set (match_dup 0)
7092 (div:SWI48 (match_dup 2) (match_dup 3)))
7094 (mod:SWI48 (match_dup 2) (match_dup 3)))
7096 (clobber (reg:CC FLAGS_REG))])]
7098 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7100 if (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
7101 operands[4] = operands[2];
7104 /* Avoid use of cltd in favor of a mov+shift. */
7105 emit_move_insn (operands[1], operands[2]);
7106 operands[4] = operands[1];
7109 [(set_attr "type" "multi")
7110 (set_attr "mode" "<MODE>")])
7112 (define_insn_and_split "*divmod<mode>4"
7113 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7114 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7115 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7116 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7117 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7118 (clobber (reg:CC FLAGS_REG))]
7122 [(parallel [(set (match_dup 1)
7123 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7124 (clobber (reg:CC FLAGS_REG))])
7125 (parallel [(set (match_dup 0)
7126 (div:SWIM248 (match_dup 2) (match_dup 3)))
7128 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7130 (clobber (reg:CC FLAGS_REG))])]
7132 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
7134 if (<MODE>mode != HImode
7135 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7136 operands[4] = operands[2];
7139 /* Avoid use of cltd in favor of a mov+shift. */
7140 emit_move_insn (operands[1], operands[2]);
7141 operands[4] = operands[1];
7144 [(set_attr "type" "multi")
7145 (set_attr "mode" "<MODE>")])
7147 (define_insn "*divmod<mode>4_noext"
7148 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7149 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7150 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7151 (set (match_operand:SWIM248 1 "register_operand" "=d")
7152 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7153 (use (match_operand:SWIM248 4 "register_operand" "1"))
7154 (clobber (reg:CC FLAGS_REG))]
7156 "idiv{<imodesuffix>}\t%3"
7157 [(set_attr "type" "idiv")
7158 (set_attr "mode" "<MODE>")])
7160 (define_expand "divmodqi4"
7161 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7163 (match_operand:QI 1 "register_operand" "")
7164 (match_operand:QI 2 "nonimmediate_operand" "")))
7165 (set (match_operand:QI 3 "register_operand" "")
7166 (mod:QI (match_dup 1) (match_dup 2)))
7167 (clobber (reg:CC FLAGS_REG))])]
7168 "TARGET_QIMODE_MATH"
7173 tmp0 = gen_reg_rtx (HImode);
7174 tmp1 = gen_reg_rtx (HImode);
7176 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7178 emit_insn (gen_extendqihi2 (tmp1, operands[1]));
7179 emit_insn (gen_divmodhiqi3 (tmp0, tmp1, operands[2]));
7181 /* Extract remainder from AH. */
7182 tmp1 = gen_rtx_SIGN_EXTRACT (QImode, tmp0, GEN_INT (8), GEN_INT (8));
7183 insn = emit_move_insn (operands[3], tmp1);
7185 mod = gen_rtx_MOD (QImode, operands[1], operands[2]);
7186 set_unique_reg_note (insn, REG_EQUAL, mod);
7188 /* Extract quotient from AL. */
7189 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7191 div = gen_rtx_DIV (QImode, operands[1], operands[2]);
7192 set_unique_reg_note (insn, REG_EQUAL, div);
7197 ;; Divide AX by r/m8, with result stored in
7200 ;; Change div/mod to HImode and extend the second argument to HImode
7201 ;; so that mode of div/mod matches with mode of arguments. Otherwise
7202 ;; combine may fail.
7203 (define_insn "divmodhiqi3"
7204 [(set (match_operand:HI 0 "register_operand" "=a")
7209 (mod:HI (match_operand:HI 1 "register_operand" "0")
7211 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7215 (div:HI (match_dup 1) (sign_extend:HI (match_dup 2)))))))
7216 (clobber (reg:CC FLAGS_REG))]
7217 "TARGET_QIMODE_MATH"
7219 [(set_attr "type" "idiv")
7220 (set_attr "mode" "QI")])
7222 (define_expand "udivmod<mode>4"
7223 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7225 (match_operand:SWIM248 1 "register_operand" "")
7226 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7227 (set (match_operand:SWIM248 3 "register_operand" "")
7228 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7229 (clobber (reg:CC FLAGS_REG))])])
7231 ;; Split with 8bit unsigned divide:
7232 ;; if (dividend an divisor are in [0-255])
7233 ;; use 8bit unsigned integer divide
7235 ;; use original integer divide
7237 [(set (match_operand:SWI48 0 "register_operand" "")
7238 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "")
7239 (match_operand:SWI48 3 "nonimmediate_operand" "")))
7240 (set (match_operand:SWI48 1 "register_operand" "")
7241 (umod:SWI48 (match_dup 2) (match_dup 3)))
7242 (clobber (reg:CC FLAGS_REG))]
7243 "TARGET_USE_8BIT_IDIV
7244 && TARGET_QIMODE_MATH
7245 && can_create_pseudo_p ()
7246 && !optimize_insn_for_size_p ()"
7248 "ix86_split_idivmod (<MODE>mode, operands, false); DONE;")
7250 (define_insn_and_split "udivmod<mode>4_1"
7251 [(set (match_operand:SWI48 0 "register_operand" "=a")
7252 (udiv:SWI48 (match_operand:SWI48 2 "register_operand" "0")
7253 (match_operand:SWI48 3 "nonimmediate_operand" "rm")))
7254 (set (match_operand:SWI48 1 "register_operand" "=&d")
7255 (umod:SWI48 (match_dup 2) (match_dup 3)))
7256 (unspec [(const_int 0)] UNSPEC_DIV_ALREADY_SPLIT)
7257 (clobber (reg:CC FLAGS_REG))]
7261 [(set (match_dup 1) (const_int 0))
7262 (parallel [(set (match_dup 0)
7263 (udiv:SWI48 (match_dup 2) (match_dup 3)))
7265 (umod:SWI48 (match_dup 2) (match_dup 3)))
7267 (clobber (reg:CC FLAGS_REG))])]
7269 [(set_attr "type" "multi")
7270 (set_attr "mode" "<MODE>")])
7272 (define_insn_and_split "*udivmod<mode>4"
7273 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7274 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7275 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7276 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7277 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7278 (clobber (reg:CC FLAGS_REG))]
7282 [(set (match_dup 1) (const_int 0))
7283 (parallel [(set (match_dup 0)
7284 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7286 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7288 (clobber (reg:CC FLAGS_REG))])]
7290 [(set_attr "type" "multi")
7291 (set_attr "mode" "<MODE>")])
7293 (define_insn "*udivmod<mode>4_noext"
7294 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7295 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7296 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7297 (set (match_operand:SWIM248 1 "register_operand" "=d")
7298 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7299 (use (match_operand:SWIM248 4 "register_operand" "1"))
7300 (clobber (reg:CC FLAGS_REG))]
7302 "div{<imodesuffix>}\t%3"
7303 [(set_attr "type" "idiv")
7304 (set_attr "mode" "<MODE>")])
7306 (define_expand "udivmodqi4"
7307 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7309 (match_operand:QI 1 "register_operand" "")
7310 (match_operand:QI 2 "nonimmediate_operand" "")))
7311 (set (match_operand:QI 3 "register_operand" "")
7312 (umod:QI (match_dup 1) (match_dup 2)))
7313 (clobber (reg:CC FLAGS_REG))])]
7314 "TARGET_QIMODE_MATH"
7319 tmp0 = gen_reg_rtx (HImode);
7320 tmp1 = gen_reg_rtx (HImode);
7322 /* Extend operands[1] to HImode. Generate 8bit divide. Result is
7324 emit_insn (gen_zero_extendqihi2 (tmp1, operands[1]));
7325 emit_insn (gen_udivmodhiqi3 (tmp0, tmp1, operands[2]));
7327 /* Extract remainder from AH. */
7328 tmp1 = gen_rtx_ZERO_EXTRACT (SImode, tmp0, GEN_INT (8), GEN_INT (8));
7329 tmp1 = simplify_gen_subreg (QImode, tmp1, SImode, 0);
7330 insn = emit_move_insn (operands[3], tmp1);
7332 mod = gen_rtx_UMOD (QImode, operands[1], operands[2]);
7333 set_unique_reg_note (insn, REG_EQUAL, mod);
7335 /* Extract quotient from AL. */
7336 insn = emit_move_insn (operands[0], gen_lowpart (QImode, tmp0));
7338 div = gen_rtx_UDIV (QImode, operands[1], operands[2]);
7339 set_unique_reg_note (insn, REG_EQUAL, div);
7344 (define_insn "udivmodhiqi3"
7345 [(set (match_operand:HI 0 "register_operand" "=a")
7350 (mod:HI (match_operand:HI 1 "register_operand" "0")
7352 (match_operand:QI 2 "nonimmediate_operand" "qm")))))
7356 (div:HI (match_dup 1) (zero_extend:HI (match_dup 2)))))))
7357 (clobber (reg:CC FLAGS_REG))]
7358 "TARGET_QIMODE_MATH"
7360 [(set_attr "type" "idiv")
7361 (set_attr "mode" "QI")])
7363 ;; We cannot use div/idiv for double division, because it causes
7364 ;; "division by zero" on the overflow and that's not what we expect
7365 ;; from truncate. Because true (non truncating) double division is
7366 ;; never generated, we can't create this insn anyway.
7369 ; [(set (match_operand:SI 0 "register_operand" "=a")
7371 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7373 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7374 ; (set (match_operand:SI 3 "register_operand" "=d")
7376 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7377 ; (clobber (reg:CC FLAGS_REG))]
7379 ; "div{l}\t{%2, %0|%0, %2}"
7380 ; [(set_attr "type" "idiv")])
7382 ;;- Logical AND instructions
7384 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7385 ;; Note that this excludes ah.
7387 (define_expand "testsi_ccno_1"
7388 [(set (reg:CCNO FLAGS_REG)
7390 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7391 (match_operand:SI 1 "x86_64_nonmemory_operand" ""))
7394 (define_expand "testqi_ccz_1"
7395 [(set (reg:CCZ FLAGS_REG)
7396 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7397 (match_operand:QI 1 "nonmemory_operand" ""))
7400 (define_expand "testdi_ccno_1"
7401 [(set (reg:CCNO FLAGS_REG)
7403 (and:DI (match_operand:DI 0 "nonimmediate_operand" "")
7404 (match_operand:DI 1 "x86_64_szext_general_operand" ""))
7406 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))")
7408 (define_insn "*testdi_1"
7409 [(set (reg FLAGS_REG)
7412 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7413 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7415 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7416 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7418 test{l}\t{%k1, %k0|%k0, %k1}
7419 test{l}\t{%k1, %k0|%k0, %k1}
7420 test{q}\t{%1, %0|%0, %1}
7421 test{q}\t{%1, %0|%0, %1}
7422 test{q}\t{%1, %0|%0, %1}"
7423 [(set_attr "type" "test")
7424 (set_attr "modrm" "0,1,0,1,1")
7425 (set_attr "mode" "SI,SI,DI,DI,DI")])
7427 (define_insn "*testqi_1_maybe_si"
7428 [(set (reg FLAGS_REG)
7431 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
7432 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
7434 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
7435 && ix86_match_ccmode (insn,
7436 CONST_INT_P (operands[1])
7437 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
7439 if (which_alternative == 3)
7441 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
7442 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
7443 return "test{l}\t{%1, %k0|%k0, %1}";
7445 return "test{b}\t{%1, %0|%0, %1}";
7447 [(set_attr "type" "test")
7448 (set_attr "modrm" "0,1,1,1")
7449 (set_attr "mode" "QI,QI,QI,SI")
7450 (set_attr "pent_pair" "uv,np,uv,np")])
7452 (define_insn "*test<mode>_1"
7453 [(set (reg FLAGS_REG)
7456 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
7457 (match_operand:SWI124 1 "<general_operand>" "<i>,<i>,<r><i>"))
7459 "ix86_match_ccmode (insn, CCNOmode)
7460 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7461 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
7462 [(set_attr "type" "test")
7463 (set_attr "modrm" "0,1,1")
7464 (set_attr "mode" "<MODE>")
7465 (set_attr "pent_pair" "uv,np,uv")])
7467 (define_expand "testqi_ext_ccno_0"
7468 [(set (reg:CCNO FLAGS_REG)
7472 (match_operand 0 "ext_register_operand" "")
7475 (match_operand 1 "const_int_operand" ""))
7478 (define_insn "*testqi_ext_0"
7479 [(set (reg FLAGS_REG)
7483 (match_operand 0 "ext_register_operand" "Q")
7486 (match_operand 1 "const_int_operand" "n"))
7488 "ix86_match_ccmode (insn, CCNOmode)"
7489 "test{b}\t{%1, %h0|%h0, %1}"
7490 [(set_attr "type" "test")
7491 (set_attr "mode" "QI")
7492 (set_attr "length_immediate" "1")
7493 (set_attr "modrm" "1")
7494 (set_attr "pent_pair" "np")])
7496 (define_insn "*testqi_ext_1_rex64"
7497 [(set (reg FLAGS_REG)
7501 (match_operand 0 "ext_register_operand" "Q")
7505 (match_operand:QI 1 "register_operand" "Q")))
7507 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7508 "test{b}\t{%1, %h0|%h0, %1}"
7509 [(set_attr "type" "test")
7510 (set_attr "mode" "QI")])
7512 (define_insn "*testqi_ext_1"
7513 [(set (reg FLAGS_REG)
7517 (match_operand 0 "ext_register_operand" "Q")
7521 (match_operand:QI 1 "general_operand" "Qm")))
7523 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
7524 "test{b}\t{%1, %h0|%h0, %1}"
7525 [(set_attr "type" "test")
7526 (set_attr "mode" "QI")])
7528 (define_insn "*testqi_ext_2"
7529 [(set (reg FLAGS_REG)
7533 (match_operand 0 "ext_register_operand" "Q")
7537 (match_operand 1 "ext_register_operand" "Q")
7541 "ix86_match_ccmode (insn, CCNOmode)"
7542 "test{b}\t{%h1, %h0|%h0, %h1}"
7543 [(set_attr "type" "test")
7544 (set_attr "mode" "QI")])
7546 (define_insn "*testqi_ext_3_rex64"
7547 [(set (reg FLAGS_REG)
7548 (compare (zero_extract:DI
7549 (match_operand 0 "nonimmediate_operand" "rm")
7550 (match_operand:DI 1 "const_int_operand" "")
7551 (match_operand:DI 2 "const_int_operand" ""))
7554 && ix86_match_ccmode (insn, CCNOmode)
7555 && INTVAL (operands[1]) > 0
7556 && INTVAL (operands[2]) >= 0
7557 /* Ensure that resulting mask is zero or sign extended operand. */
7558 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7559 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
7560 && INTVAL (operands[1]) > 32))
7561 && (GET_MODE (operands[0]) == SImode
7562 || GET_MODE (operands[0]) == DImode
7563 || GET_MODE (operands[0]) == HImode
7564 || GET_MODE (operands[0]) == QImode)"
7567 ;; Combine likes to form bit extractions for some tests. Humor it.
7568 (define_insn "*testqi_ext_3"
7569 [(set (reg FLAGS_REG)
7570 (compare (zero_extract:SI
7571 (match_operand 0 "nonimmediate_operand" "rm")
7572 (match_operand:SI 1 "const_int_operand" "")
7573 (match_operand:SI 2 "const_int_operand" ""))
7575 "ix86_match_ccmode (insn, CCNOmode)
7576 && INTVAL (operands[1]) > 0
7577 && INTVAL (operands[2]) >= 0
7578 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
7579 && (GET_MODE (operands[0]) == SImode
7580 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
7581 || GET_MODE (operands[0]) == HImode
7582 || GET_MODE (operands[0]) == QImode)"
7586 [(set (match_operand 0 "flags_reg_operand" "")
7587 (match_operator 1 "compare_operator"
7589 (match_operand 2 "nonimmediate_operand" "")
7590 (match_operand 3 "const_int_operand" "")
7591 (match_operand 4 "const_int_operand" ""))
7593 "ix86_match_ccmode (insn, CCNOmode)"
7594 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
7596 rtx val = operands[2];
7597 HOST_WIDE_INT len = INTVAL (operands[3]);
7598 HOST_WIDE_INT pos = INTVAL (operands[4]);
7600 enum machine_mode mode, submode;
7602 mode = GET_MODE (val);
7605 /* ??? Combine likes to put non-volatile mem extractions in QImode
7606 no matter the size of the test. So find a mode that works. */
7607 if (! MEM_VOLATILE_P (val))
7609 mode = smallest_mode_for_size (pos + len, MODE_INT);
7610 val = adjust_address (val, mode, 0);
7613 else if (GET_CODE (val) == SUBREG
7614 && (submode = GET_MODE (SUBREG_REG (val)),
7615 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
7616 && pos + len <= GET_MODE_BITSIZE (submode)
7617 && GET_MODE_CLASS (submode) == MODE_INT)
7619 /* Narrow a paradoxical subreg to prevent partial register stalls. */
7621 val = SUBREG_REG (val);
7623 else if (mode == HImode && pos + len <= 8)
7625 /* Small HImode tests can be converted to QImode. */
7627 val = gen_lowpart (QImode, val);
7630 if (len == HOST_BITS_PER_WIDE_INT)
7633 mask = ((HOST_WIDE_INT)1 << len) - 1;
7636 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
7639 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
7640 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
7641 ;; this is relatively important trick.
7642 ;; Do the conversion only post-reload to avoid limiting of the register class
7645 [(set (match_operand 0 "flags_reg_operand" "")
7646 (match_operator 1 "compare_operator"
7647 [(and (match_operand 2 "register_operand" "")
7648 (match_operand 3 "const_int_operand" ""))
7651 && QI_REG_P (operands[2])
7652 && GET_MODE (operands[2]) != QImode
7653 && ((ix86_match_ccmode (insn, CCZmode)
7654 && !(INTVAL (operands[3]) & ~(255 << 8)))
7655 || (ix86_match_ccmode (insn, CCNOmode)
7656 && !(INTVAL (operands[3]) & ~(127 << 8))))"
7659 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
7663 operands[2] = gen_lowpart (SImode, operands[2]);
7664 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);
7668 [(set (match_operand 0 "flags_reg_operand" "")
7669 (match_operator 1 "compare_operator"
7670 [(and (match_operand 2 "nonimmediate_operand" "")
7671 (match_operand 3 "const_int_operand" ""))
7674 && GET_MODE (operands[2]) != QImode
7675 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
7676 && ((ix86_match_ccmode (insn, CCZmode)
7677 && !(INTVAL (operands[3]) & ~255))
7678 || (ix86_match_ccmode (insn, CCNOmode)
7679 && !(INTVAL (operands[3]) & ~127)))"
7681 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
7684 operands[2] = gen_lowpart (QImode, operands[2]);
7685 operands[3] = gen_lowpart (QImode, operands[3]);
7688 ;; %%% This used to optimize known byte-wide and operations to memory,
7689 ;; and sometimes to QImode registers. If this is considered useful,
7690 ;; it should be done with splitters.
7692 (define_expand "and<mode>3"
7693 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
7694 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
7695 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
7698 if (<MODE>mode == DImode
7699 && GET_CODE (operands[2]) == CONST_INT
7700 && INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff
7701 && REG_P (operands[1]))
7702 emit_insn (gen_zero_extendsidi2 (operands[0],
7703 gen_lowpart (SImode, operands[1])));
7705 ix86_expand_binary_operator (AND, <MODE>mode, operands);
7709 (define_insn "*anddi_1"
7710 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
7712 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
7713 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
7714 (clobber (reg:CC FLAGS_REG))]
7715 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
7717 switch (get_attr_type (insn))
7721 enum machine_mode mode;
7723 gcc_assert (CONST_INT_P (operands[2]));
7724 if (INTVAL (operands[2]) == (HOST_WIDE_INT) 0xffffffff)
7726 else if (INTVAL (operands[2]) == 0xffff)
7730 gcc_assert (INTVAL (operands[2]) == 0xff);
7734 operands[1] = gen_lowpart (mode, operands[1]);
7736 return "mov{l}\t{%1, %k0|%k0, %1}";
7737 else if (mode == HImode)
7738 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
7740 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
7744 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7745 if (get_attr_mode (insn) == MODE_SI)
7746 return "and{l}\t{%k2, %k0|%k0, %k2}";
7748 return "and{q}\t{%2, %0|%0, %2}";
7751 [(set_attr "type" "alu,alu,alu,imovx")
7752 (set_attr "length_immediate" "*,*,*,0")
7753 (set (attr "prefix_rex")
7755 (and (eq_attr "type" "imovx")
7756 (and (match_test "INTVAL (operands[2]) == 0xff")
7757 (match_operand 1 "ext_QIreg_operand" "")))
7759 (const_string "*")))
7760 (set_attr "mode" "SI,DI,DI,SI")])
7762 (define_insn "*andsi_1"
7763 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
7764 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
7765 (match_operand:SI 2 "x86_64_general_operand" "re,rm,L")))
7766 (clobber (reg:CC FLAGS_REG))]
7767 "ix86_binary_operator_ok (AND, SImode, operands)"
7769 switch (get_attr_type (insn))
7773 enum machine_mode mode;
7775 gcc_assert (CONST_INT_P (operands[2]));
7776 if (INTVAL (operands[2]) == 0xffff)
7780 gcc_assert (INTVAL (operands[2]) == 0xff);
7784 operands[1] = gen_lowpart (mode, operands[1]);
7786 return "movz{wl|x}\t{%1, %0|%0, %1}";
7788 return "movz{bl|x}\t{%1, %0|%0, %1}";
7792 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7793 return "and{l}\t{%2, %0|%0, %2}";
7796 [(set_attr "type" "alu,alu,imovx")
7797 (set (attr "prefix_rex")
7799 (and (eq_attr "type" "imovx")
7800 (and (match_test "INTVAL (operands[2]) == 0xff")
7801 (match_operand 1 "ext_QIreg_operand" "")))
7803 (const_string "*")))
7804 (set_attr "length_immediate" "*,*,0")
7805 (set_attr "mode" "SI")])
7807 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7808 (define_insn "*andsi_1_zext"
7809 [(set (match_operand:DI 0 "register_operand" "=r")
7811 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7812 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
7813 (clobber (reg:CC FLAGS_REG))]
7814 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
7815 "and{l}\t{%2, %k0|%k0, %2}"
7816 [(set_attr "type" "alu")
7817 (set_attr "mode" "SI")])
7819 (define_insn "*andhi_1"
7820 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7821 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
7822 (match_operand:HI 2 "general_operand" "rn,rm,L")))
7823 (clobber (reg:CC FLAGS_REG))]
7824 "ix86_binary_operator_ok (AND, HImode, operands)"
7826 switch (get_attr_type (insn))
7829 gcc_assert (CONST_INT_P (operands[2]));
7830 gcc_assert (INTVAL (operands[2]) == 0xff);
7831 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
7834 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7836 return "and{w}\t{%2, %0|%0, %2}";
7839 [(set_attr "type" "alu,alu,imovx")
7840 (set_attr "length_immediate" "*,*,0")
7841 (set (attr "prefix_rex")
7843 (and (eq_attr "type" "imovx")
7844 (match_operand 1 "ext_QIreg_operand" ""))
7846 (const_string "*")))
7847 (set_attr "mode" "HI,HI,SI")])
7849 ;; %%% Potential partial reg stall on alternative 2. What to do?
7850 (define_insn "*andqi_1"
7851 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7852 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7853 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7854 (clobber (reg:CC FLAGS_REG))]
7855 "ix86_binary_operator_ok (AND, QImode, operands)"
7857 and{b}\t{%2, %0|%0, %2}
7858 and{b}\t{%2, %0|%0, %2}
7859 and{l}\t{%k2, %k0|%k0, %k2}"
7860 [(set_attr "type" "alu")
7861 (set_attr "mode" "QI,QI,SI")])
7863 (define_insn "*andqi_1_slp"
7864 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7865 (and:QI (match_dup 0)
7866 (match_operand:QI 1 "general_operand" "qn,qmn")))
7867 (clobber (reg:CC FLAGS_REG))]
7868 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7869 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7870 "and{b}\t{%1, %0|%0, %1}"
7871 [(set_attr "type" "alu1")
7872 (set_attr "mode" "QI")])
7875 [(set (match_operand 0 "register_operand" "")
7877 (const_int -65536)))
7878 (clobber (reg:CC FLAGS_REG))]
7879 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
7880 || optimize_function_for_size_p (cfun)"
7881 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7882 "operands[1] = gen_lowpart (HImode, operands[0]);")
7885 [(set (match_operand 0 "ext_register_operand" "")
7888 (clobber (reg:CC FLAGS_REG))]
7889 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7890 && reload_completed"
7891 [(set (strict_low_part (match_dup 1)) (const_int 0))]
7892 "operands[1] = gen_lowpart (QImode, operands[0]);")
7895 [(set (match_operand 0 "ext_register_operand" "")
7897 (const_int -65281)))
7898 (clobber (reg:CC FLAGS_REG))]
7899 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7900 && reload_completed"
7901 [(parallel [(set (zero_extract:SI (match_dup 0)
7905 (zero_extract:SI (match_dup 0)
7908 (zero_extract:SI (match_dup 0)
7911 (clobber (reg:CC FLAGS_REG))])]
7912 "operands[0] = gen_lowpart (SImode, operands[0]);")
7914 (define_insn "*anddi_2"
7915 [(set (reg FLAGS_REG)
7918 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
7919 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
7921 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
7922 (and:DI (match_dup 1) (match_dup 2)))]
7923 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7924 && ix86_binary_operator_ok (AND, DImode, operands)"
7926 and{l}\t{%k2, %k0|%k0, %k2}
7927 and{q}\t{%2, %0|%0, %2}
7928 and{q}\t{%2, %0|%0, %2}"
7929 [(set_attr "type" "alu")
7930 (set_attr "mode" "SI,DI,DI")])
7932 (define_insn "*andqi_2_maybe_si"
7933 [(set (reg FLAGS_REG)
7935 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7936 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
7938 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
7939 (and:QI (match_dup 1) (match_dup 2)))]
7940 "ix86_binary_operator_ok (AND, QImode, operands)
7941 && ix86_match_ccmode (insn,
7942 CONST_INT_P (operands[2])
7943 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
7945 if (which_alternative == 2)
7947 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
7948 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
7949 return "and{l}\t{%2, %k0|%k0, %2}";
7951 return "and{b}\t{%2, %0|%0, %2}";
7953 [(set_attr "type" "alu")
7954 (set_attr "mode" "QI,QI,SI")])
7956 (define_insn "*and<mode>_2"
7957 [(set (reg FLAGS_REG)
7958 (compare (and:SWI124
7959 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
7960 (match_operand:SWI124 2 "<general_operand>" "<g>,<r><i>"))
7962 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
7963 (and:SWI124 (match_dup 1) (match_dup 2)))]
7964 "ix86_match_ccmode (insn, CCNOmode)
7965 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
7966 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
7967 [(set_attr "type" "alu")
7968 (set_attr "mode" "<MODE>")])
7970 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7971 (define_insn "*andsi_2_zext"
7972 [(set (reg FLAGS_REG)
7974 (match_operand:SI 1 "nonimmediate_operand" "%0")
7975 (match_operand:SI 2 "x86_64_general_operand" "rme"))
7977 (set (match_operand:DI 0 "register_operand" "=r")
7978 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
7979 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7980 && ix86_binary_operator_ok (AND, SImode, operands)"
7981 "and{l}\t{%2, %k0|%k0, %2}"
7982 [(set_attr "type" "alu")
7983 (set_attr "mode" "SI")])
7985 (define_insn "*andqi_2_slp"
7986 [(set (reg FLAGS_REG)
7988 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
7989 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
7991 (set (strict_low_part (match_dup 0))
7992 (and:QI (match_dup 0) (match_dup 1)))]
7993 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7994 && ix86_match_ccmode (insn, CCNOmode)
7995 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7996 "and{b}\t{%1, %0|%0, %1}"
7997 [(set_attr "type" "alu1")
7998 (set_attr "mode" "QI")])
8000 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8001 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8002 ;; for a QImode operand, which of course failed.
8003 (define_insn "andqi_ext_0"
8004 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8009 (match_operand 1 "ext_register_operand" "0")
8012 (match_operand 2 "const_int_operand" "n")))
8013 (clobber (reg:CC FLAGS_REG))]
8015 "and{b}\t{%2, %h0|%h0, %2}"
8016 [(set_attr "type" "alu")
8017 (set_attr "length_immediate" "1")
8018 (set_attr "modrm" "1")
8019 (set_attr "mode" "QI")])
8021 ;; Generated by peephole translating test to and. This shows up
8022 ;; often in fp comparisons.
8023 (define_insn "*andqi_ext_0_cc"
8024 [(set (reg FLAGS_REG)
8028 (match_operand 1 "ext_register_operand" "0")
8031 (match_operand 2 "const_int_operand" "n"))
8033 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8042 "ix86_match_ccmode (insn, CCNOmode)"
8043 "and{b}\t{%2, %h0|%h0, %2}"
8044 [(set_attr "type" "alu")
8045 (set_attr "length_immediate" "1")
8046 (set_attr "modrm" "1")
8047 (set_attr "mode" "QI")])
8049 (define_insn "*andqi_ext_1_rex64"
8050 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8055 (match_operand 1 "ext_register_operand" "0")
8059 (match_operand 2 "ext_register_operand" "Q"))))
8060 (clobber (reg:CC FLAGS_REG))]
8062 "and{b}\t{%2, %h0|%h0, %2}"
8063 [(set_attr "type" "alu")
8064 (set_attr "length_immediate" "0")
8065 (set_attr "mode" "QI")])
8067 (define_insn "*andqi_ext_1"
8068 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8073 (match_operand 1 "ext_register_operand" "0")
8077 (match_operand:QI 2 "general_operand" "Qm"))))
8078 (clobber (reg:CC FLAGS_REG))]
8080 "and{b}\t{%2, %h0|%h0, %2}"
8081 [(set_attr "type" "alu")
8082 (set_attr "length_immediate" "0")
8083 (set_attr "mode" "QI")])
8085 (define_insn "*andqi_ext_2"
8086 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8091 (match_operand 1 "ext_register_operand" "%0")
8095 (match_operand 2 "ext_register_operand" "Q")
8098 (clobber (reg:CC FLAGS_REG))]
8100 "and{b}\t{%h2, %h0|%h0, %h2}"
8101 [(set_attr "type" "alu")
8102 (set_attr "length_immediate" "0")
8103 (set_attr "mode" "QI")])
8105 ;; Convert wide AND instructions with immediate operand to shorter QImode
8106 ;; equivalents when possible.
8107 ;; Don't do the splitting with memory operands, since it introduces risk
8108 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8109 ;; for size, but that can (should?) be handled by generic code instead.
8111 [(set (match_operand 0 "register_operand" "")
8112 (and (match_operand 1 "register_operand" "")
8113 (match_operand 2 "const_int_operand" "")))
8114 (clobber (reg:CC FLAGS_REG))]
8116 && QI_REG_P (operands[0])
8117 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8118 && !(~INTVAL (operands[2]) & ~(255 << 8))
8119 && GET_MODE (operands[0]) != QImode"
8120 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8121 (and:SI (zero_extract:SI (match_dup 1)
8122 (const_int 8) (const_int 8))
8124 (clobber (reg:CC FLAGS_REG))])]
8126 operands[0] = gen_lowpart (SImode, operands[0]);
8127 operands[1] = gen_lowpart (SImode, operands[1]);
8128 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8131 ;; Since AND can be encoded with sign extended immediate, this is only
8132 ;; profitable when 7th bit is not set.
8134 [(set (match_operand 0 "register_operand" "")
8135 (and (match_operand 1 "general_operand" "")
8136 (match_operand 2 "const_int_operand" "")))
8137 (clobber (reg:CC FLAGS_REG))]
8139 && ANY_QI_REG_P (operands[0])
8140 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8141 && !(~INTVAL (operands[2]) & ~255)
8142 && !(INTVAL (operands[2]) & 128)
8143 && GET_MODE (operands[0]) != QImode"
8144 [(parallel [(set (strict_low_part (match_dup 0))
8145 (and:QI (match_dup 1)
8147 (clobber (reg:CC FLAGS_REG))])]
8149 operands[0] = gen_lowpart (QImode, operands[0]);
8150 operands[1] = gen_lowpart (QImode, operands[1]);
8151 operands[2] = gen_lowpart (QImode, operands[2]);
8154 ;; Logical inclusive and exclusive OR instructions
8156 ;; %%% This used to optimize known byte-wide and operations to memory.
8157 ;; If this is considered useful, it should be done with splitters.
8159 (define_expand "<code><mode>3"
8160 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8161 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8162 (match_operand:SWIM 2 "<general_operand>" "")))]
8164 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8166 (define_insn "*<code><mode>_1"
8167 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8169 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8170 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8171 (clobber (reg:CC FLAGS_REG))]
8172 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8173 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8174 [(set_attr "type" "alu")
8175 (set_attr "mode" "<MODE>")])
8177 ;; %%% Potential partial reg stall on alternative 2. What to do?
8178 (define_insn "*<code>qi_1"
8179 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8180 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8181 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8182 (clobber (reg:CC FLAGS_REG))]
8183 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8185 <logic>{b}\t{%2, %0|%0, %2}
8186 <logic>{b}\t{%2, %0|%0, %2}
8187 <logic>{l}\t{%k2, %k0|%k0, %k2}"
8188 [(set_attr "type" "alu")
8189 (set_attr "mode" "QI,QI,SI")])
8191 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8192 (define_insn "*<code>si_1_zext"
8193 [(set (match_operand:DI 0 "register_operand" "=r")
8195 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8196 (match_operand:SI 2 "x86_64_general_operand" "rme"))))
8197 (clobber (reg:CC FLAGS_REG))]
8198 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8199 "<logic>{l}\t{%2, %k0|%k0, %2}"
8200 [(set_attr "type" "alu")
8201 (set_attr "mode" "SI")])
8203 (define_insn "*<code>si_1_zext_imm"
8204 [(set (match_operand:DI 0 "register_operand" "=r")
8206 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8207 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8208 (clobber (reg:CC FLAGS_REG))]
8209 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8210 "<logic>{l}\t{%2, %k0|%k0, %2}"
8211 [(set_attr "type" "alu")
8212 (set_attr "mode" "SI")])
8214 (define_insn "*<code>qi_1_slp"
8215 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8216 (any_or:QI (match_dup 0)
8217 (match_operand:QI 1 "general_operand" "qmn,qn")))
8218 (clobber (reg:CC FLAGS_REG))]
8219 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8220 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8221 "<logic>{b}\t{%1, %0|%0, %1}"
8222 [(set_attr "type" "alu1")
8223 (set_attr "mode" "QI")])
8225 (define_insn "*<code><mode>_2"
8226 [(set (reg FLAGS_REG)
8227 (compare (any_or:SWI
8228 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8229 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8231 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8232 (any_or:SWI (match_dup 1) (match_dup 2)))]
8233 "ix86_match_ccmode (insn, CCNOmode)
8234 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8235 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8236 [(set_attr "type" "alu")
8237 (set_attr "mode" "<MODE>")])
8239 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8240 ;; ??? Special case for immediate operand is missing - it is tricky.
8241 (define_insn "*<code>si_2_zext"
8242 [(set (reg FLAGS_REG)
8243 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8244 (match_operand:SI 2 "x86_64_general_operand" "rme"))
8246 (set (match_operand:DI 0 "register_operand" "=r")
8247 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8248 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8249 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8250 "<logic>{l}\t{%2, %k0|%k0, %2}"
8251 [(set_attr "type" "alu")
8252 (set_attr "mode" "SI")])
8254 (define_insn "*<code>si_2_zext_imm"
8255 [(set (reg FLAGS_REG)
8257 (match_operand:SI 1 "nonimmediate_operand" "%0")
8258 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8260 (set (match_operand:DI 0 "register_operand" "=r")
8261 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8262 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8263 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8264 "<logic>{l}\t{%2, %k0|%k0, %2}"
8265 [(set_attr "type" "alu")
8266 (set_attr "mode" "SI")])
8268 (define_insn "*<code>qi_2_slp"
8269 [(set (reg FLAGS_REG)
8270 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8271 (match_operand:QI 1 "general_operand" "qmn,qn"))
8273 (set (strict_low_part (match_dup 0))
8274 (any_or:QI (match_dup 0) (match_dup 1)))]
8275 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8276 && ix86_match_ccmode (insn, CCNOmode)
8277 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8278 "<logic>{b}\t{%1, %0|%0, %1}"
8279 [(set_attr "type" "alu1")
8280 (set_attr "mode" "QI")])
8282 (define_insn "*<code><mode>_3"
8283 [(set (reg FLAGS_REG)
8284 (compare (any_or:SWI
8285 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8286 (match_operand:SWI 2 "<general_operand>" "<g>"))
8288 (clobber (match_scratch:SWI 0 "=<r>"))]
8289 "ix86_match_ccmode (insn, CCNOmode)
8290 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8291 "<logic>{<imodesuffix>}\t{%2, %0|%0, %2}"
8292 [(set_attr "type" "alu")
8293 (set_attr "mode" "<MODE>")])
8295 (define_insn "*<code>qi_ext_0"
8296 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8301 (match_operand 1 "ext_register_operand" "0")
8304 (match_operand 2 "const_int_operand" "n")))
8305 (clobber (reg:CC FLAGS_REG))]
8306 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8307 "<logic>{b}\t{%2, %h0|%h0, %2}"
8308 [(set_attr "type" "alu")
8309 (set_attr "length_immediate" "1")
8310 (set_attr "modrm" "1")
8311 (set_attr "mode" "QI")])
8313 (define_insn "*<code>qi_ext_1_rex64"
8314 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8319 (match_operand 1 "ext_register_operand" "0")
8323 (match_operand 2 "ext_register_operand" "Q"))))
8324 (clobber (reg:CC FLAGS_REG))]
8326 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8327 "<logic>{b}\t{%2, %h0|%h0, %2}"
8328 [(set_attr "type" "alu")
8329 (set_attr "length_immediate" "0")
8330 (set_attr "mode" "QI")])
8332 (define_insn "*<code>qi_ext_1"
8333 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8338 (match_operand 1 "ext_register_operand" "0")
8342 (match_operand:QI 2 "general_operand" "Qm"))))
8343 (clobber (reg:CC FLAGS_REG))]
8345 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8346 "<logic>{b}\t{%2, %h0|%h0, %2}"
8347 [(set_attr "type" "alu")
8348 (set_attr "length_immediate" "0")
8349 (set_attr "mode" "QI")])
8351 (define_insn "*<code>qi_ext_2"
8352 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8356 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8359 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8362 (clobber (reg:CC FLAGS_REG))]
8363 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8364 "<logic>{b}\t{%h2, %h0|%h0, %h2}"
8365 [(set_attr "type" "alu")
8366 (set_attr "length_immediate" "0")
8367 (set_attr "mode" "QI")])
8370 [(set (match_operand 0 "register_operand" "")
8371 (any_or (match_operand 1 "register_operand" "")
8372 (match_operand 2 "const_int_operand" "")))
8373 (clobber (reg:CC FLAGS_REG))]
8375 && QI_REG_P (operands[0])
8376 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8377 && !(INTVAL (operands[2]) & ~(255 << 8))
8378 && GET_MODE (operands[0]) != QImode"
8379 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8380 (any_or:SI (zero_extract:SI (match_dup 1)
8381 (const_int 8) (const_int 8))
8383 (clobber (reg:CC FLAGS_REG))])]
8385 operands[0] = gen_lowpart (SImode, operands[0]);
8386 operands[1] = gen_lowpart (SImode, operands[1]);
8387 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);
8390 ;; Since OR can be encoded with sign extended immediate, this is only
8391 ;; profitable when 7th bit is set.
8393 [(set (match_operand 0 "register_operand" "")
8394 (any_or (match_operand 1 "general_operand" "")
8395 (match_operand 2 "const_int_operand" "")))
8396 (clobber (reg:CC FLAGS_REG))]
8398 && ANY_QI_REG_P (operands[0])
8399 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8400 && !(INTVAL (operands[2]) & ~255)
8401 && (INTVAL (operands[2]) & 128)
8402 && GET_MODE (operands[0]) != QImode"
8403 [(parallel [(set (strict_low_part (match_dup 0))
8404 (any_or:QI (match_dup 1)
8406 (clobber (reg:CC FLAGS_REG))])]
8408 operands[0] = gen_lowpart (QImode, operands[0]);
8409 operands[1] = gen_lowpart (QImode, operands[1]);
8410 operands[2] = gen_lowpart (QImode, operands[2]);
8413 (define_expand "xorqi_cc_ext_1"
8415 (set (reg:CCNO FLAGS_REG)
8419 (match_operand 1 "ext_register_operand" "")
8422 (match_operand:QI 2 "general_operand" ""))
8424 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8434 (define_insn "*xorqi_cc_ext_1_rex64"
8435 [(set (reg FLAGS_REG)
8439 (match_operand 1 "ext_register_operand" "0")
8442 (match_operand:QI 2 "nonmemory_operand" "Qn"))
8444 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8453 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8454 "xor{b}\t{%2, %h0|%h0, %2}"
8455 [(set_attr "type" "alu")
8456 (set_attr "modrm" "1")
8457 (set_attr "mode" "QI")])
8459 (define_insn "*xorqi_cc_ext_1"
8460 [(set (reg FLAGS_REG)
8464 (match_operand 1 "ext_register_operand" "0")
8467 (match_operand:QI 2 "general_operand" "qmn"))
8469 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
8478 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8479 "xor{b}\t{%2, %h0|%h0, %2}"
8480 [(set_attr "type" "alu")
8481 (set_attr "modrm" "1")
8482 (set_attr "mode" "QI")])
8484 ;; Negation instructions
8486 (define_expand "neg<mode>2"
8487 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
8488 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
8490 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
8492 (define_insn_and_split "*neg<dwi>2_doubleword"
8493 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
8494 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
8495 (clobber (reg:CC FLAGS_REG))]
8496 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
8500 [(set (reg:CCZ FLAGS_REG)
8501 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
8502 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
8505 (plus:DWIH (match_dup 3)
8506 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
8508 (clobber (reg:CC FLAGS_REG))])
8511 (neg:DWIH (match_dup 2)))
8512 (clobber (reg:CC FLAGS_REG))])]
8513 "split_double_mode (<DWI>mode, &operands[0], 2, &operands[0], &operands[2]);")
8515 (define_insn "*neg<mode>2_1"
8516 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8517 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
8518 (clobber (reg:CC FLAGS_REG))]
8519 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8520 "neg{<imodesuffix>}\t%0"
8521 [(set_attr "type" "negnot")
8522 (set_attr "mode" "<MODE>")])
8524 ;; Combine is quite creative about this pattern.
8525 (define_insn "*negsi2_1_zext"
8526 [(set (match_operand:DI 0 "register_operand" "=r")
8528 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
8531 (clobber (reg:CC FLAGS_REG))]
8532 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8534 [(set_attr "type" "negnot")
8535 (set_attr "mode" "SI")])
8537 ;; The problem with neg is that it does not perform (compare x 0),
8538 ;; it really performs (compare 0 x), which leaves us with the zero
8539 ;; flag being the only useful item.
8541 (define_insn "*neg<mode>2_cmpz"
8542 [(set (reg:CCZ FLAGS_REG)
8544 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8546 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8547 (neg:SWI (match_dup 1)))]
8548 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
8549 "neg{<imodesuffix>}\t%0"
8550 [(set_attr "type" "negnot")
8551 (set_attr "mode" "<MODE>")])
8553 (define_insn "*negsi2_cmpz_zext"
8554 [(set (reg:CCZ FLAGS_REG)
8558 (match_operand:DI 1 "register_operand" "0")
8562 (set (match_operand:DI 0 "register_operand" "=r")
8563 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
8566 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
8568 [(set_attr "type" "negnot")
8569 (set_attr "mode" "SI")])
8571 ;; Changing of sign for FP values is doable using integer unit too.
8573 (define_expand "<code><mode>2"
8574 [(set (match_operand:X87MODEF 0 "register_operand" "")
8575 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
8576 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8577 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
8579 (define_insn "*absneg<mode>2_mixed"
8580 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
8581 (match_operator:MODEF 3 "absneg_operator"
8582 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
8583 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
8584 (clobber (reg:CC FLAGS_REG))]
8585 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
8588 (define_insn "*absneg<mode>2_sse"
8589 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
8590 (match_operator:MODEF 3 "absneg_operator"
8591 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
8592 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
8593 (clobber (reg:CC FLAGS_REG))]
8594 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
8597 (define_insn "*absneg<mode>2_i387"
8598 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
8599 (match_operator:X87MODEF 3 "absneg_operator"
8600 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
8601 (use (match_operand 2 "" ""))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8606 (define_expand "<code>tf2"
8607 [(set (match_operand:TF 0 "register_operand" "")
8608 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
8610 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
8612 (define_insn "*absnegtf2_sse"
8613 [(set (match_operand:TF 0 "register_operand" "=x,x")
8614 (match_operator:TF 3 "absneg_operator"
8615 [(match_operand:TF 1 "register_operand" "0,x")]))
8616 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
8617 (clobber (reg:CC FLAGS_REG))]
8621 ;; Splitters for fp abs and neg.
8624 [(set (match_operand 0 "fp_register_operand" "")
8625 (match_operator 1 "absneg_operator" [(match_dup 0)]))
8626 (use (match_operand 2 "" ""))
8627 (clobber (reg:CC FLAGS_REG))]
8629 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
8632 [(set (match_operand 0 "register_operand" "")
8633 (match_operator 3 "absneg_operator"
8634 [(match_operand 1 "register_operand" "")]))
8635 (use (match_operand 2 "nonimmediate_operand" ""))
8636 (clobber (reg:CC FLAGS_REG))]
8637 "reload_completed && SSE_REG_P (operands[0])"
8638 [(set (match_dup 0) (match_dup 3))]
8640 enum machine_mode mode = GET_MODE (operands[0]);
8641 enum machine_mode vmode = GET_MODE (operands[2]);
8644 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
8645 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
8646 if (operands_match_p (operands[0], operands[2]))
8649 operands[1] = operands[2];
8652 if (GET_CODE (operands[3]) == ABS)
8653 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
8655 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
8660 [(set (match_operand:SF 0 "register_operand" "")
8661 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
8662 (use (match_operand:V4SF 2 "" ""))
8663 (clobber (reg:CC FLAGS_REG))]
8665 [(parallel [(set (match_dup 0) (match_dup 1))
8666 (clobber (reg:CC FLAGS_REG))])]
8669 operands[0] = gen_lowpart (SImode, operands[0]);
8670 if (GET_CODE (operands[1]) == ABS)
8672 tmp = gen_int_mode (0x7fffffff, SImode);
8673 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8677 tmp = gen_int_mode (0x80000000, SImode);
8678 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8684 [(set (match_operand:DF 0 "register_operand" "")
8685 (match_operator:DF 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))])]
8695 tmp = gen_lowpart (DImode, operands[0]);
8696 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
8699 if (GET_CODE (operands[1]) == ABS)
8702 tmp = gen_rtx_NOT (DImode, tmp);
8706 operands[0] = gen_highpart (SImode, operands[0]);
8707 if (GET_CODE (operands[1]) == ABS)
8709 tmp = gen_int_mode (0x7fffffff, SImode);
8710 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8714 tmp = gen_int_mode (0x80000000, SImode);
8715 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8722 [(set (match_operand:XF 0 "register_operand" "")
8723 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
8724 (use (match_operand 2 "" ""))
8725 (clobber (reg:CC FLAGS_REG))]
8727 [(parallel [(set (match_dup 0) (match_dup 1))
8728 (clobber (reg:CC FLAGS_REG))])]
8731 operands[0] = gen_rtx_REG (SImode,
8732 true_regnum (operands[0])
8733 + (TARGET_64BIT ? 1 : 2));
8734 if (GET_CODE (operands[1]) == ABS)
8736 tmp = GEN_INT (0x7fff);
8737 tmp = gen_rtx_AND (SImode, operands[0], tmp);
8741 tmp = GEN_INT (0x8000);
8742 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
8747 ;; Conditionalize these after reload. If they match before reload, we
8748 ;; lose the clobber and ability to use integer instructions.
8750 (define_insn "*<code><mode>2_1"
8751 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
8752 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
8754 && (reload_completed
8755 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
8756 "f<absneg_mnemonic>"
8757 [(set_attr "type" "fsgn")
8758 (set_attr "mode" "<MODE>")])
8760 (define_insn "*<code>extendsfdf2"
8761 [(set (match_operand:DF 0 "register_operand" "=f")
8762 (absneg:DF (float_extend:DF
8763 (match_operand:SF 1 "register_operand" "0"))))]
8764 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
8765 "f<absneg_mnemonic>"
8766 [(set_attr "type" "fsgn")
8767 (set_attr "mode" "DF")])
8769 (define_insn "*<code>extendsfxf2"
8770 [(set (match_operand:XF 0 "register_operand" "=f")
8771 (absneg:XF (float_extend:XF
8772 (match_operand:SF 1 "register_operand" "0"))))]
8774 "f<absneg_mnemonic>"
8775 [(set_attr "type" "fsgn")
8776 (set_attr "mode" "XF")])
8778 (define_insn "*<code>extenddfxf2"
8779 [(set (match_operand:XF 0 "register_operand" "=f")
8780 (absneg:XF (float_extend:XF
8781 (match_operand:DF 1 "register_operand" "0"))))]
8783 "f<absneg_mnemonic>"
8784 [(set_attr "type" "fsgn")
8785 (set_attr "mode" "XF")])
8787 ;; Copysign instructions
8789 (define_mode_iterator CSGNMODE [SF DF TF])
8790 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
8792 (define_expand "copysign<mode>3"
8793 [(match_operand:CSGNMODE 0 "register_operand" "")
8794 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
8795 (match_operand:CSGNMODE 2 "register_operand" "")]
8796 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8797 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8798 "ix86_expand_copysign (operands); DONE;")
8800 (define_insn_and_split "copysign<mode>3_const"
8801 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
8803 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
8804 (match_operand:CSGNMODE 2 "register_operand" "0")
8805 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
8807 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8808 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8810 "&& reload_completed"
8812 "ix86_split_copysign_const (operands); DONE;")
8814 (define_insn "copysign<mode>3_var"
8815 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
8817 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
8818 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
8819 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
8820 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
8822 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
8823 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8824 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
8828 [(set (match_operand:CSGNMODE 0 "register_operand" "")
8830 [(match_operand:CSGNMODE 2 "register_operand" "")
8831 (match_operand:CSGNMODE 3 "register_operand" "")
8832 (match_operand:<CSGNVMODE> 4 "" "")
8833 (match_operand:<CSGNVMODE> 5 "" "")]
8835 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
8836 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
8837 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
8838 && reload_completed"
8840 "ix86_split_copysign_var (operands); DONE;")
8842 ;; One complement instructions
8844 (define_expand "one_cmpl<mode>2"
8845 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8846 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
8848 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
8850 (define_insn "*one_cmpl<mode>2_1"
8851 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
8852 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
8853 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8854 "not{<imodesuffix>}\t%0"
8855 [(set_attr "type" "negnot")
8856 (set_attr "mode" "<MODE>")])
8858 ;; %%% Potential partial reg stall on alternative 1. What to do?
8859 (define_insn "*one_cmplqi2_1"
8860 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
8861 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
8862 "ix86_unary_operator_ok (NOT, QImode, operands)"
8866 [(set_attr "type" "negnot")
8867 (set_attr "mode" "QI,SI")])
8869 ;; ??? Currently never generated - xor is used instead.
8870 (define_insn "*one_cmplsi2_1_zext"
8871 [(set (match_operand:DI 0 "register_operand" "=r")
8873 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
8874 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
8876 [(set_attr "type" "negnot")
8877 (set_attr "mode" "SI")])
8879 (define_insn "*one_cmpl<mode>2_2"
8880 [(set (reg FLAGS_REG)
8881 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
8883 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
8884 (not:SWI (match_dup 1)))]
8885 "ix86_match_ccmode (insn, CCNOmode)
8886 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
8888 [(set_attr "type" "alu1")
8889 (set_attr "mode" "<MODE>")])
8892 [(set (match_operand 0 "flags_reg_operand" "")
8893 (match_operator 2 "compare_operator"
8894 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
8896 (set (match_operand:SWI 1 "nonimmediate_operand" "")
8897 (not:SWI (match_dup 3)))]
8898 "ix86_match_ccmode (insn, CCNOmode)"
8899 [(parallel [(set (match_dup 0)
8900 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
8903 (xor:SWI (match_dup 3) (const_int -1)))])])
8905 ;; ??? Currently never generated - xor is used instead.
8906 (define_insn "*one_cmplsi2_2_zext"
8907 [(set (reg FLAGS_REG)
8908 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
8910 (set (match_operand:DI 0 "register_operand" "=r")
8911 (zero_extend:DI (not:SI (match_dup 1))))]
8912 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8913 && ix86_unary_operator_ok (NOT, SImode, operands)"
8915 [(set_attr "type" "alu1")
8916 (set_attr "mode" "SI")])
8919 [(set (match_operand 0 "flags_reg_operand" "")
8920 (match_operator 2 "compare_operator"
8921 [(not:SI (match_operand:SI 3 "register_operand" ""))
8923 (set (match_operand:DI 1 "register_operand" "")
8924 (zero_extend:DI (not:SI (match_dup 3))))]
8925 "ix86_match_ccmode (insn, CCNOmode)"
8926 [(parallel [(set (match_dup 0)
8927 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
8930 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])])
8932 ;; Shift instructions
8934 ;; DImode shifts are implemented using the i386 "shift double" opcode,
8935 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
8936 ;; is variable, then the count is in %cl and the "imm" operand is dropped
8937 ;; from the assembler input.
8939 ;; This instruction shifts the target reg/mem as usual, but instead of
8940 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
8941 ;; is a left shift double, bits are taken from the high order bits of
8942 ;; reg, else if the insn is a shift right double, bits are taken from the
8943 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
8944 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
8946 ;; Since sh[lr]d does not change the `reg' operand, that is done
8947 ;; separately, making all shifts emit pairs of shift double and normal
8948 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
8949 ;; support a 63 bit shift, each shift where the count is in a reg expands
8950 ;; to a pair of shifts, a branch, a shift by 32 and a label.
8952 ;; If the shift count is a constant, we need never emit more than one
8953 ;; shift pair, instead using moves and sign extension for counts greater
8956 (define_expand "ashl<mode>3"
8957 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
8958 (ashift:SDWIM (match_operand:SDWIM 1 "<ashl_input_operand>" "")
8959 (match_operand:QI 2 "nonmemory_operand" "")))]
8961 "ix86_expand_binary_operator (ASHIFT, <MODE>mode, operands); DONE;")
8963 (define_insn "*ashl<mode>3_doubleword"
8964 [(set (match_operand:DWI 0 "register_operand" "=&r,r")
8965 (ashift:DWI (match_operand:DWI 1 "reg_or_pm1_operand" "n,0")
8966 (match_operand:QI 2 "nonmemory_operand" "<S>c,<S>c")))
8967 (clobber (reg:CC FLAGS_REG))]
8970 [(set_attr "type" "multi")])
8973 [(set (match_operand:DWI 0 "register_operand" "")
8974 (ashift:DWI (match_operand:DWI 1 "nonmemory_operand" "")
8975 (match_operand:QI 2 "nonmemory_operand" "")))
8976 (clobber (reg:CC FLAGS_REG))]
8977 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
8979 "ix86_split_ashl (operands, NULL_RTX, <MODE>mode); DONE;")
8981 ;; By default we don't ask for a scratch register, because when DWImode
8982 ;; values are manipulated, registers are already at a premium. But if
8983 ;; we have one handy, we won't turn it away.
8986 [(match_scratch:DWIH 3 "r")
8987 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
8989 (match_operand:<DWI> 1 "nonmemory_operand" "")
8990 (match_operand:QI 2 "nonmemory_operand" "")))
8991 (clobber (reg:CC FLAGS_REG))])
8995 "ix86_split_ashl (operands, operands[3], <DWI>mode); DONE;")
8997 (define_insn "x86_64_shld"
8998 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
8999 (ior:DI (ashift:DI (match_dup 0)
9000 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9001 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9002 (minus:QI (const_int 64) (match_dup 2)))))
9003 (clobber (reg:CC FLAGS_REG))]
9005 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9006 [(set_attr "type" "ishift")
9007 (set_attr "prefix_0f" "1")
9008 (set_attr "mode" "DI")
9009 (set_attr "athlon_decode" "vector")
9010 (set_attr "amdfam10_decode" "vector")
9011 (set_attr "bdver1_decode" "vector")])
9013 (define_insn "x86_shld"
9014 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9015 (ior:SI (ashift:SI (match_dup 0)
9016 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9017 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9018 (minus:QI (const_int 32) (match_dup 2)))))
9019 (clobber (reg:CC FLAGS_REG))]
9021 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9022 [(set_attr "type" "ishift")
9023 (set_attr "prefix_0f" "1")
9024 (set_attr "mode" "SI")
9025 (set_attr "pent_pair" "np")
9026 (set_attr "athlon_decode" "vector")
9027 (set_attr "amdfam10_decode" "vector")
9028 (set_attr "bdver1_decode" "vector")])
9030 (define_expand "x86_shift<mode>_adj_1"
9031 [(set (reg:CCZ FLAGS_REG)
9032 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9035 (set (match_operand:SWI48 0 "register_operand" "")
9036 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9037 (match_operand:SWI48 1 "register_operand" "")
9040 (if_then_else:SWI48 (ne (reg:CCZ FLAGS_REG) (const_int 0))
9041 (match_operand:SWI48 3 "register_operand" "")
9044 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
9046 (define_expand "x86_shift<mode>_adj_2"
9047 [(use (match_operand:SWI48 0 "register_operand" ""))
9048 (use (match_operand:SWI48 1 "register_operand" ""))
9049 (use (match_operand:QI 2 "register_operand" ""))]
9052 rtx label = gen_label_rtx ();
9055 emit_insn (gen_testqi_ccz_1 (operands[2],
9056 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9058 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9059 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9060 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9061 gen_rtx_LABEL_REF (VOIDmode, label),
9063 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9064 JUMP_LABEL (tmp) = label;
9066 emit_move_insn (operands[0], operands[1]);
9067 ix86_expand_clear (operands[1]);
9070 LABEL_NUSES (label) = 1;
9075 ;; Avoid useless masking of count operand.
9076 (define_insn_and_split "*ashl<mode>3_mask"
9077 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9079 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9082 (match_operand:SI 2 "nonimmediate_operand" "c")
9083 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9084 (clobber (reg:CC FLAGS_REG))]
9085 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)
9086 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9087 == GET_MODE_BITSIZE (<MODE>mode)-1"
9090 [(parallel [(set (match_dup 0)
9091 (ashift:SWI48 (match_dup 1) (match_dup 2)))
9092 (clobber (reg:CC FLAGS_REG))])]
9094 if (can_create_pseudo_p ())
9095 operands [2] = force_reg (SImode, operands[2]);
9097 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9099 [(set_attr "type" "ishift")
9100 (set_attr "mode" "<MODE>")])
9102 (define_insn "*bmi2_ashl<mode>3_1"
9103 [(set (match_operand:SWI48 0 "register_operand" "=r")
9104 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9105 (match_operand:SWI48 2 "register_operand" "r")))]
9107 "shlx\t{%2, %1, %0|%0, %1, %2}"
9108 [(set_attr "type" "ishiftx")
9109 (set_attr "mode" "<MODE>")])
9111 (define_insn "*ashl<mode>3_1"
9112 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r,r")
9113 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,l,rm")
9114 (match_operand:QI 2 "nonmemory_operand" "c<S>,M,r")))
9115 (clobber (reg:CC FLAGS_REG))]
9116 "ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9118 switch (get_attr_type (insn))
9125 gcc_assert (operands[2] == const1_rtx);
9126 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9127 return "add{<imodesuffix>}\t%0, %0";
9130 if (operands[2] == const1_rtx
9131 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9132 return "sal{<imodesuffix>}\t%0";
9134 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9137 [(set_attr "isa" "*,*,bmi2")
9139 (cond [(eq_attr "alternative" "1")
9140 (const_string "lea")
9141 (eq_attr "alternative" "2")
9142 (const_string "ishiftx")
9143 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9144 (match_operand 0 "register_operand" ""))
9145 (match_operand 2 "const1_operand" ""))
9146 (const_string "alu")
9148 (const_string "ishift")))
9149 (set (attr "length_immediate")
9151 (ior (eq_attr "type" "alu")
9152 (and (eq_attr "type" "ishift")
9153 (and (match_operand 2 "const1_operand" "")
9154 (ior (match_test "TARGET_SHIFT1")
9155 (match_test "optimize_function_for_size_p (cfun)")))))
9157 (const_string "*")))
9158 (set_attr "mode" "<MODE>")])
9160 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9162 [(set (match_operand:SWI48 0 "register_operand" "")
9163 (ashift:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9164 (match_operand:QI 2 "register_operand" "")))
9165 (clobber (reg:CC FLAGS_REG))]
9166 "TARGET_BMI2 && reload_completed"
9168 (ashift:SWI48 (match_dup 1) (match_dup 2)))]
9169 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9171 (define_insn "*bmi2_ashlsi3_1_zext"
9172 [(set (match_operand:DI 0 "register_operand" "=r")
9174 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9175 (match_operand:SI 2 "register_operand" "r"))))]
9176 "TARGET_64BIT && TARGET_BMI2"
9177 "shlx\t{%2, %1, %k0|%k0, %1, %2}"
9178 [(set_attr "type" "ishiftx")
9179 (set_attr "mode" "SI")])
9181 (define_insn "*ashlsi3_1_zext"
9182 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
9184 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l,rm")
9185 (match_operand:QI 2 "nonmemory_operand" "cI,M,r"))))
9186 (clobber (reg:CC FLAGS_REG))]
9187 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9189 switch (get_attr_type (insn))
9196 gcc_assert (operands[2] == const1_rtx);
9197 return "add{l}\t%k0, %k0";
9200 if (operands[2] == const1_rtx
9201 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9202 return "sal{l}\t%k0";
9204 return "sal{l}\t{%2, %k0|%k0, %2}";
9207 [(set_attr "isa" "*,*,bmi2")
9209 (cond [(eq_attr "alternative" "1")
9210 (const_string "lea")
9211 (eq_attr "alternative" "2")
9212 (const_string "ishiftx")
9213 (and (match_test "TARGET_DOUBLE_WITH_ADD")
9214 (match_operand 2 "const1_operand" ""))
9215 (const_string "alu")
9217 (const_string "ishift")))
9218 (set (attr "length_immediate")
9220 (ior (eq_attr "type" "alu")
9221 (and (eq_attr "type" "ishift")
9222 (and (match_operand 2 "const1_operand" "")
9223 (ior (match_test "TARGET_SHIFT1")
9224 (match_test "optimize_function_for_size_p (cfun)")))))
9226 (const_string "*")))
9227 (set_attr "mode" "SI")])
9229 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9231 [(set (match_operand:DI 0 "register_operand" "")
9233 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9234 (match_operand:QI 2 "register_operand" ""))))
9235 (clobber (reg:CC FLAGS_REG))]
9236 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9238 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9239 "operands[2] = gen_lowpart (SImode, operands[2]);")
9241 (define_insn "*ashlhi3_1"
9242 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,Yp")
9243 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
9244 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9245 (clobber (reg:CC FLAGS_REG))]
9246 "ix86_binary_operator_ok (ASHIFT, HImode, operands)"
9248 switch (get_attr_type (insn))
9254 gcc_assert (operands[2] == const1_rtx);
9255 return "add{w}\t%0, %0";
9258 if (operands[2] == const1_rtx
9259 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9260 return "sal{w}\t%0";
9262 return "sal{w}\t{%2, %0|%0, %2}";
9266 (cond [(eq_attr "alternative" "1")
9267 (const_string "lea")
9268 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9269 (match_operand 0 "register_operand" ""))
9270 (match_operand 2 "const1_operand" ""))
9271 (const_string "alu")
9273 (const_string "ishift")))
9274 (set (attr "length_immediate")
9276 (ior (eq_attr "type" "alu")
9277 (and (eq_attr "type" "ishift")
9278 (and (match_operand 2 "const1_operand" "")
9279 (ior (match_test "TARGET_SHIFT1")
9280 (match_test "optimize_function_for_size_p (cfun)")))))
9282 (const_string "*")))
9283 (set_attr "mode" "HI,SI")])
9285 ;; %%% Potential partial reg stall on alternative 1. What to do?
9286 (define_insn "*ashlqi3_1"
9287 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,Yp")
9288 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
9289 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
9290 (clobber (reg:CC FLAGS_REG))]
9291 "ix86_binary_operator_ok (ASHIFT, QImode, operands)"
9293 switch (get_attr_type (insn))
9299 gcc_assert (operands[2] == const1_rtx);
9300 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
9301 return "add{l}\t%k0, %k0";
9303 return "add{b}\t%0, %0";
9306 if (operands[2] == const1_rtx
9307 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9309 if (get_attr_mode (insn) == MODE_SI)
9310 return "sal{l}\t%k0";
9312 return "sal{b}\t%0";
9316 if (get_attr_mode (insn) == MODE_SI)
9317 return "sal{l}\t{%2, %k0|%k0, %2}";
9319 return "sal{b}\t{%2, %0|%0, %2}";
9324 (cond [(eq_attr "alternative" "2")
9325 (const_string "lea")
9326 (and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9327 (match_operand 0 "register_operand" ""))
9328 (match_operand 2 "const1_operand" ""))
9329 (const_string "alu")
9331 (const_string "ishift")))
9332 (set (attr "length_immediate")
9334 (ior (eq_attr "type" "alu")
9335 (and (eq_attr "type" "ishift")
9336 (and (match_operand 2 "const1_operand" "")
9337 (ior (match_test "TARGET_SHIFT1")
9338 (match_test "optimize_function_for_size_p (cfun)")))))
9340 (const_string "*")))
9341 (set_attr "mode" "QI,SI,SI")])
9343 (define_insn "*ashlqi3_1_slp"
9344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9345 (ashift:QI (match_dup 0)
9346 (match_operand:QI 1 "nonmemory_operand" "cI")))
9347 (clobber (reg:CC FLAGS_REG))]
9348 "(optimize_function_for_size_p (cfun)
9349 || !TARGET_PARTIAL_FLAG_REG_STALL
9350 || (operands[1] == const1_rtx
9352 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))"
9354 switch (get_attr_type (insn))
9357 gcc_assert (operands[1] == const1_rtx);
9358 return "add{b}\t%0, %0";
9361 if (operands[1] == const1_rtx
9362 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9363 return "sal{b}\t%0";
9365 return "sal{b}\t{%1, %0|%0, %1}";
9369 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9370 (match_operand 0 "register_operand" ""))
9371 (match_operand 1 "const1_operand" ""))
9372 (const_string "alu")
9374 (const_string "ishift1")))
9375 (set (attr "length_immediate")
9377 (ior (eq_attr "type" "alu")
9378 (and (eq_attr "type" "ishift1")
9379 (and (match_operand 1 "const1_operand" "")
9380 (ior (match_test "TARGET_SHIFT1")
9381 (match_test "optimize_function_for_size_p (cfun)")))))
9383 (const_string "*")))
9384 (set_attr "mode" "QI")])
9386 ;; Convert ashift to the lea pattern to avoid flags dependency.
9388 [(set (match_operand 0 "register_operand" "")
9389 (ashift (match_operand 1 "index_register_operand" "")
9390 (match_operand:QI 2 "const_int_operand" "")))
9391 (clobber (reg:CC FLAGS_REG))]
9392 "GET_MODE (operands[0]) == GET_MODE (operands[1])
9394 && true_regnum (operands[0]) != true_regnum (operands[1])"
9397 enum machine_mode mode = GET_MODE (operands[0]);
9400 if (GET_MODE_SIZE (mode) < GET_MODE_SIZE (SImode))
9403 operands[0] = gen_lowpart (mode, operands[0]);
9404 operands[1] = gen_lowpart (mode, operands[1]);
9407 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), mode);
9409 pat = gen_rtx_MULT (mode, operands[1], operands[2]);
9411 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9415 ;; Convert ashift to the lea pattern to avoid flags dependency.
9417 [(set (match_operand:DI 0 "register_operand" "")
9419 (ashift:SI (match_operand:SI 1 "index_register_operand" "")
9420 (match_operand:QI 2 "const_int_operand" ""))))
9421 (clobber (reg:CC FLAGS_REG))]
9422 "TARGET_64BIT && reload_completed
9423 && true_regnum (operands[0]) != true_regnum (operands[1])"
9425 (zero_extend:DI (subreg:SI (mult:DI (match_dup 1) (match_dup 2)) 0)))]
9427 operands[1] = gen_lowpart (DImode, operands[1]);
9428 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);
9431 ;; This pattern can't accept a variable shift count, since shifts by
9432 ;; zero don't affect the flags. We assume that shifts by constant
9433 ;; zero are optimized away.
9434 (define_insn "*ashl<mode>3_cmp"
9435 [(set (reg FLAGS_REG)
9437 (ashift:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")
9438 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9440 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9441 (ashift:SWI (match_dup 1) (match_dup 2)))]
9442 "(optimize_function_for_size_p (cfun)
9443 || !TARGET_PARTIAL_FLAG_REG_STALL
9444 || (operands[2] == const1_rtx
9446 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9447 && ix86_match_ccmode (insn, CCGOCmode)
9448 && ix86_binary_operator_ok (ASHIFT, <MODE>mode, operands)"
9450 switch (get_attr_type (insn))
9453 gcc_assert (operands[2] == const1_rtx);
9454 return "add{<imodesuffix>}\t%0, %0";
9457 if (operands[2] == const1_rtx
9458 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9459 return "sal{<imodesuffix>}\t%0";
9461 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9465 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9466 (match_operand 0 "register_operand" ""))
9467 (match_operand 2 "const1_operand" ""))
9468 (const_string "alu")
9470 (const_string "ishift")))
9471 (set (attr "length_immediate")
9473 (ior (eq_attr "type" "alu")
9474 (and (eq_attr "type" "ishift")
9475 (and (match_operand 2 "const1_operand" "")
9476 (ior (match_test "TARGET_SHIFT1")
9477 (match_test "optimize_function_for_size_p (cfun)")))))
9479 (const_string "*")))
9480 (set_attr "mode" "<MODE>")])
9482 (define_insn "*ashlsi3_cmp_zext"
9483 [(set (reg FLAGS_REG)
9485 (ashift:SI (match_operand:SI 1 "register_operand" "0")
9486 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9488 (set (match_operand:DI 0 "register_operand" "=r")
9489 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
9491 && (optimize_function_for_size_p (cfun)
9492 || !TARGET_PARTIAL_FLAG_REG_STALL
9493 || (operands[2] == const1_rtx
9495 || TARGET_DOUBLE_WITH_ADD)))
9496 && ix86_match_ccmode (insn, CCGOCmode)
9497 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9499 switch (get_attr_type (insn))
9502 gcc_assert (operands[2] == const1_rtx);
9503 return "add{l}\t%k0, %k0";
9506 if (operands[2] == const1_rtx
9507 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9508 return "sal{l}\t%k0";
9510 return "sal{l}\t{%2, %k0|%k0, %2}";
9514 (cond [(and (match_test "TARGET_DOUBLE_WITH_ADD")
9515 (match_operand 2 "const1_operand" ""))
9516 (const_string "alu")
9518 (const_string "ishift")))
9519 (set (attr "length_immediate")
9521 (ior (eq_attr "type" "alu")
9522 (and (eq_attr "type" "ishift")
9523 (and (match_operand 2 "const1_operand" "")
9524 (ior (match_test "TARGET_SHIFT1")
9525 (match_test "optimize_function_for_size_p (cfun)")))))
9527 (const_string "*")))
9528 (set_attr "mode" "SI")])
9530 (define_insn "*ashl<mode>3_cconly"
9531 [(set (reg FLAGS_REG)
9533 (ashift:SWI (match_operand:SWI 1 "register_operand" "0")
9534 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9536 (clobber (match_scratch:SWI 0 "=<r>"))]
9537 "(optimize_function_for_size_p (cfun)
9538 || !TARGET_PARTIAL_FLAG_REG_STALL
9539 || (operands[2] == const1_rtx
9541 || TARGET_DOUBLE_WITH_ADD)))
9542 && ix86_match_ccmode (insn, CCGOCmode)"
9544 switch (get_attr_type (insn))
9547 gcc_assert (operands[2] == const1_rtx);
9548 return "add{<imodesuffix>}\t%0, %0";
9551 if (operands[2] == const1_rtx
9552 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9553 return "sal{<imodesuffix>}\t%0";
9555 return "sal{<imodesuffix>}\t{%2, %0|%0, %2}";
9559 (cond [(and (and (match_test "TARGET_DOUBLE_WITH_ADD")
9560 (match_operand 0 "register_operand" ""))
9561 (match_operand 2 "const1_operand" ""))
9562 (const_string "alu")
9564 (const_string "ishift")))
9565 (set (attr "length_immediate")
9567 (ior (eq_attr "type" "alu")
9568 (and (eq_attr "type" "ishift")
9569 (and (match_operand 2 "const1_operand" "")
9570 (ior (match_test "TARGET_SHIFT1")
9571 (match_test "optimize_function_for_size_p (cfun)")))))
9573 (const_string "*")))
9574 (set_attr "mode" "<MODE>")])
9576 ;; See comment above `ashl<mode>3' about how this works.
9578 (define_expand "<shift_insn><mode>3"
9579 [(set (match_operand:SDWIM 0 "<shift_operand>" "")
9580 (any_shiftrt:SDWIM (match_operand:SDWIM 1 "<shift_operand>" "")
9581 (match_operand:QI 2 "nonmemory_operand" "")))]
9583 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
9585 ;; Avoid useless masking of count operand.
9586 (define_insn_and_split "*<shift_insn><mode>3_mask"
9587 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
9589 (match_operand:SWI48 1 "nonimmediate_operand" "0")
9592 (match_operand:SI 2 "nonimmediate_operand" "c")
9593 (match_operand:SI 3 "const_int_operand" "n")) 0)))
9594 (clobber (reg:CC FLAGS_REG))]
9595 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
9596 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
9597 == GET_MODE_BITSIZE (<MODE>mode)-1"
9600 [(parallel [(set (match_dup 0)
9601 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))
9602 (clobber (reg:CC FLAGS_REG))])]
9604 if (can_create_pseudo_p ())
9605 operands [2] = force_reg (SImode, operands[2]);
9607 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
9609 [(set_attr "type" "ishift")
9610 (set_attr "mode" "<MODE>")])
9612 (define_insn_and_split "*<shift_insn><mode>3_doubleword"
9613 [(set (match_operand:DWI 0 "register_operand" "=r")
9614 (any_shiftrt:DWI (match_operand:DWI 1 "register_operand" "0")
9615 (match_operand:QI 2 "nonmemory_operand" "<S>c")))
9616 (clobber (reg:CC FLAGS_REG))]
9619 "(optimize && flag_peephole2) ? epilogue_completed : reload_completed"
9621 "ix86_split_<shift_insn> (operands, NULL_RTX, <MODE>mode); DONE;"
9622 [(set_attr "type" "multi")])
9624 ;; By default we don't ask for a scratch register, because when DWImode
9625 ;; values are manipulated, registers are already at a premium. But if
9626 ;; we have one handy, we won't turn it away.
9629 [(match_scratch:DWIH 3 "r")
9630 (parallel [(set (match_operand:<DWI> 0 "register_operand" "")
9632 (match_operand:<DWI> 1 "register_operand" "")
9633 (match_operand:QI 2 "nonmemory_operand" "")))
9634 (clobber (reg:CC FLAGS_REG))])
9638 "ix86_split_<shift_insn> (operands, operands[3], <DWI>mode); DONE;")
9640 (define_insn "x86_64_shrd"
9641 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9642 (ior:DI (ashiftrt:DI (match_dup 0)
9643 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9644 (ashift:DI (match_operand:DI 1 "register_operand" "r")
9645 (minus:QI (const_int 64) (match_dup 2)))))
9646 (clobber (reg:CC FLAGS_REG))]
9648 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
9649 [(set_attr "type" "ishift")
9650 (set_attr "prefix_0f" "1")
9651 (set_attr "mode" "DI")
9652 (set_attr "athlon_decode" "vector")
9653 (set_attr "amdfam10_decode" "vector")
9654 (set_attr "bdver1_decode" "vector")])
9656 (define_insn "x86_shrd"
9657 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9658 (ior:SI (ashiftrt:SI (match_dup 0)
9659 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9660 (ashift:SI (match_operand:SI 1 "register_operand" "r")
9661 (minus:QI (const_int 32) (match_dup 2)))))
9662 (clobber (reg:CC FLAGS_REG))]
9664 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
9665 [(set_attr "type" "ishift")
9666 (set_attr "prefix_0f" "1")
9667 (set_attr "mode" "SI")
9668 (set_attr "pent_pair" "np")
9669 (set_attr "athlon_decode" "vector")
9670 (set_attr "amdfam10_decode" "vector")
9671 (set_attr "bdver1_decode" "vector")])
9673 (define_insn "ashrdi3_cvt"
9674 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
9675 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
9676 (match_operand:QI 2 "const_int_operand" "")))
9677 (clobber (reg:CC FLAGS_REG))]
9678 "TARGET_64BIT && INTVAL (operands[2]) == 63
9679 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9680 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
9683 sar{q}\t{%2, %0|%0, %2}"
9684 [(set_attr "type" "imovx,ishift")
9685 (set_attr "prefix_0f" "0,*")
9686 (set_attr "length_immediate" "0,*")
9687 (set_attr "modrm" "0,1")
9688 (set_attr "mode" "DI")])
9690 (define_insn "ashrsi3_cvt"
9691 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
9692 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
9693 (match_operand:QI 2 "const_int_operand" "")))
9694 (clobber (reg:CC FLAGS_REG))]
9695 "INTVAL (operands[2]) == 31
9696 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9697 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9700 sar{l}\t{%2, %0|%0, %2}"
9701 [(set_attr "type" "imovx,ishift")
9702 (set_attr "prefix_0f" "0,*")
9703 (set_attr "length_immediate" "0,*")
9704 (set_attr "modrm" "0,1")
9705 (set_attr "mode" "SI")])
9707 (define_insn "*ashrsi3_cvt_zext"
9708 [(set (match_operand:DI 0 "register_operand" "=*d,r")
9710 (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
9711 (match_operand:QI 2 "const_int_operand" ""))))
9712 (clobber (reg:CC FLAGS_REG))]
9713 "TARGET_64BIT && INTVAL (operands[2]) == 31
9714 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
9715 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
9718 sar{l}\t{%2, %k0|%k0, %2}"
9719 [(set_attr "type" "imovx,ishift")
9720 (set_attr "prefix_0f" "0,*")
9721 (set_attr "length_immediate" "0,*")
9722 (set_attr "modrm" "0,1")
9723 (set_attr "mode" "SI")])
9725 (define_expand "x86_shift<mode>_adj_3"
9726 [(use (match_operand:SWI48 0 "register_operand" ""))
9727 (use (match_operand:SWI48 1 "register_operand" ""))
9728 (use (match_operand:QI 2 "register_operand" ""))]
9731 rtx label = gen_label_rtx ();
9734 emit_insn (gen_testqi_ccz_1 (operands[2],
9735 GEN_INT (GET_MODE_BITSIZE (<MODE>mode))));
9737 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9738 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9739 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9740 gen_rtx_LABEL_REF (VOIDmode, label),
9742 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9743 JUMP_LABEL (tmp) = label;
9745 emit_move_insn (operands[0], operands[1]);
9746 emit_insn (gen_ashr<mode>3_cvt (operands[1], operands[1],
9747 GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1)));
9749 LABEL_NUSES (label) = 1;
9754 (define_insn "*bmi2_<shift_insn><mode>3_1"
9755 [(set (match_operand:SWI48 0 "register_operand" "=r")
9756 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
9757 (match_operand:SWI48 2 "register_operand" "r")))]
9759 "<shift>x\t{%2, %1, %0|%0, %1, %2}"
9760 [(set_attr "type" "ishiftx")
9761 (set_attr "mode" "<MODE>")])
9763 (define_insn "*<shift_insn><mode>3_1"
9764 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
9766 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
9767 (match_operand:QI 2 "nonmemory_operand" "c<S>,r")))
9768 (clobber (reg:CC FLAGS_REG))]
9769 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9771 switch (get_attr_type (insn))
9777 if (operands[2] == const1_rtx
9778 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9779 return "<shift>{<imodesuffix>}\t%0";
9781 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9784 [(set_attr "isa" "*,bmi2")
9785 (set_attr "type" "ishift,ishiftx")
9786 (set (attr "length_immediate")
9788 (and (match_operand 2 "const1_operand" "")
9789 (ior (match_test "TARGET_SHIFT1")
9790 (match_test "optimize_function_for_size_p (cfun)")))
9792 (const_string "*")))
9793 (set_attr "mode" "<MODE>")])
9795 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9797 [(set (match_operand:SWI48 0 "register_operand" "")
9798 (any_shiftrt:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
9799 (match_operand:QI 2 "register_operand" "")))
9800 (clobber (reg:CC FLAGS_REG))]
9801 "TARGET_BMI2 && reload_completed"
9803 (any_shiftrt:SWI48 (match_dup 1) (match_dup 2)))]
9804 "operands[2] = gen_lowpart (<MODE>mode, operands[2]);")
9806 (define_insn "*bmi2_<shift_insn>si3_1_zext"
9807 [(set (match_operand:DI 0 "register_operand" "=r")
9809 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
9810 (match_operand:SI 2 "register_operand" "r"))))]
9811 "TARGET_64BIT && TARGET_BMI2"
9812 "<shift>x\t{%2, %1, %k0|%k0, %1, %2}"
9813 [(set_attr "type" "ishiftx")
9814 (set_attr "mode" "SI")])
9816 (define_insn "*<shift_insn>si3_1_zext"
9817 [(set (match_operand:DI 0 "register_operand" "=r,r")
9819 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
9820 (match_operand:QI 2 "nonmemory_operand" "cI,r"))))
9821 (clobber (reg:CC FLAGS_REG))]
9822 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9824 switch (get_attr_type (insn))
9830 if (operands[2] == const1_rtx
9831 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9832 return "<shift>{l}\t%k0";
9834 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9837 [(set_attr "isa" "*,bmi2")
9838 (set_attr "type" "ishift,ishiftx")
9839 (set (attr "length_immediate")
9841 (and (match_operand 2 "const1_operand" "")
9842 (ior (match_test "TARGET_SHIFT1")
9843 (match_test "optimize_function_for_size_p (cfun)")))
9845 (const_string "*")))
9846 (set_attr "mode" "SI")])
9848 ;; Convert shift to the shiftx pattern to avoid flags dependency.
9850 [(set (match_operand:DI 0 "register_operand" "")
9852 (any_shiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
9853 (match_operand:QI 2 "register_operand" ""))))
9854 (clobber (reg:CC FLAGS_REG))]
9855 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
9857 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9858 "operands[2] = gen_lowpart (SImode, operands[2]);")
9860 (define_insn "*<shift_insn><mode>3_1"
9861 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
9863 (match_operand:SWI12 1 "nonimmediate_operand" "0")
9864 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
9865 (clobber (reg:CC FLAGS_REG))]
9866 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9868 if (operands[2] == const1_rtx
9869 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9870 return "<shift>{<imodesuffix>}\t%0";
9872 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9874 [(set_attr "type" "ishift")
9875 (set (attr "length_immediate")
9877 (and (match_operand 2 "const1_operand" "")
9878 (ior (match_test "TARGET_SHIFT1")
9879 (match_test "optimize_function_for_size_p (cfun)")))
9881 (const_string "*")))
9882 (set_attr "mode" "<MODE>")])
9884 (define_insn "*<shift_insn>qi3_1_slp"
9885 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
9886 (any_shiftrt:QI (match_dup 0)
9887 (match_operand:QI 1 "nonmemory_operand" "cI")))
9888 (clobber (reg:CC FLAGS_REG))]
9889 "(optimize_function_for_size_p (cfun)
9890 || !TARGET_PARTIAL_REG_STALL
9891 || (operands[1] == const1_rtx
9894 if (operands[1] == const1_rtx
9895 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9896 return "<shift>{b}\t%0";
9898 return "<shift>{b}\t{%1, %0|%0, %1}";
9900 [(set_attr "type" "ishift1")
9901 (set (attr "length_immediate")
9903 (and (match_operand 1 "const1_operand" "")
9904 (ior (match_test "TARGET_SHIFT1")
9905 (match_test "optimize_function_for_size_p (cfun)")))
9907 (const_string "*")))
9908 (set_attr "mode" "QI")])
9910 ;; This pattern can't accept a variable shift count, since shifts by
9911 ;; zero don't affect the flags. We assume that shifts by constant
9912 ;; zero are optimized away.
9913 (define_insn "*<shift_insn><mode>3_cmp"
9914 [(set (reg FLAGS_REG)
9917 (match_operand:SWI 1 "nonimmediate_operand" "0")
9918 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9920 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9921 (any_shiftrt:SWI (match_dup 1) (match_dup 2)))]
9922 "(optimize_function_for_size_p (cfun)
9923 || !TARGET_PARTIAL_FLAG_REG_STALL
9924 || (operands[2] == const1_rtx
9926 && ix86_match_ccmode (insn, CCGOCmode)
9927 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
9929 if (operands[2] == const1_rtx
9930 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9931 return "<shift>{<imodesuffix>}\t%0";
9933 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9935 [(set_attr "type" "ishift")
9936 (set (attr "length_immediate")
9938 (and (match_operand 2 "const1_operand" "")
9939 (ior (match_test "TARGET_SHIFT1")
9940 (match_test "optimize_function_for_size_p (cfun)")))
9942 (const_string "*")))
9943 (set_attr "mode" "<MODE>")])
9945 (define_insn "*<shift_insn>si3_cmp_zext"
9946 [(set (reg FLAGS_REG)
9948 (any_shiftrt:SI (match_operand:SI 1 "register_operand" "0")
9949 (match_operand:QI 2 "const_1_to_31_operand" "I"))
9951 (set (match_operand:DI 0 "register_operand" "=r")
9952 (zero_extend:DI (any_shiftrt:SI (match_dup 1) (match_dup 2))))]
9954 && (optimize_function_for_size_p (cfun)
9955 || !TARGET_PARTIAL_FLAG_REG_STALL
9956 || (operands[2] == const1_rtx
9958 && ix86_match_ccmode (insn, CCGOCmode)
9959 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
9961 if (operands[2] == const1_rtx
9962 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9963 return "<shift>{l}\t%k0";
9965 return "<shift>{l}\t{%2, %k0|%k0, %2}";
9967 [(set_attr "type" "ishift")
9968 (set (attr "length_immediate")
9970 (and (match_operand 2 "const1_operand" "")
9971 (ior (match_test "TARGET_SHIFT1")
9972 (match_test "optimize_function_for_size_p (cfun)")))
9974 (const_string "*")))
9975 (set_attr "mode" "SI")])
9977 (define_insn "*<shift_insn><mode>3_cconly"
9978 [(set (reg FLAGS_REG)
9981 (match_operand:SWI 1 "register_operand" "0")
9982 (match_operand:QI 2 "<shift_immediate_operand>" "<S>"))
9984 (clobber (match_scratch:SWI 0 "=<r>"))]
9985 "(optimize_function_for_size_p (cfun)
9986 || !TARGET_PARTIAL_FLAG_REG_STALL
9987 || (operands[2] == const1_rtx
9989 && ix86_match_ccmode (insn, CCGOCmode)"
9991 if (operands[2] == const1_rtx
9992 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9993 return "<shift>{<imodesuffix>}\t%0";
9995 return "<shift>{<imodesuffix>}\t{%2, %0|%0, %2}";
9997 [(set_attr "type" "ishift")
9998 (set (attr "length_immediate")
10000 (and (match_operand 2 "const1_operand" "")
10001 (ior (match_test "TARGET_SHIFT1")
10002 (match_test "optimize_function_for_size_p (cfun)")))
10004 (const_string "*")))
10005 (set_attr "mode" "<MODE>")])
10007 ;; Rotate instructions
10009 (define_expand "<rotate_insn>ti3"
10010 [(set (match_operand:TI 0 "register_operand" "")
10011 (any_rotate:TI (match_operand:TI 1 "register_operand" "")
10012 (match_operand:QI 2 "nonmemory_operand" "")))]
10015 if (const_1_to_63_operand (operands[2], VOIDmode))
10016 emit_insn (gen_ix86_<rotate_insn>ti3_doubleword
10017 (operands[0], operands[1], operands[2]));
10024 (define_expand "<rotate_insn>di3"
10025 [(set (match_operand:DI 0 "shiftdi_operand" "")
10026 (any_rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
10027 (match_operand:QI 2 "nonmemory_operand" "")))]
10031 ix86_expand_binary_operator (<CODE>, DImode, operands);
10032 else if (const_1_to_31_operand (operands[2], VOIDmode))
10033 emit_insn (gen_ix86_<rotate_insn>di3_doubleword
10034 (operands[0], operands[1], operands[2]));
10041 (define_expand "<rotate_insn><mode>3"
10042 [(set (match_operand:SWIM124 0 "nonimmediate_operand" "")
10043 (any_rotate:SWIM124 (match_operand:SWIM124 1 "nonimmediate_operand" "")
10044 (match_operand:QI 2 "nonmemory_operand" "")))]
10046 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
10048 ;; Avoid useless masking of count operand.
10049 (define_insn_and_split "*<rotate_insn><mode>3_mask"
10050 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm")
10052 (match_operand:SWI48 1 "nonimmediate_operand" "0")
10055 (match_operand:SI 2 "nonimmediate_operand" "c")
10056 (match_operand:SI 3 "const_int_operand" "n")) 0)))
10057 (clobber (reg:CC FLAGS_REG))]
10058 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)
10059 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10060 == GET_MODE_BITSIZE (<MODE>mode)-1"
10063 [(parallel [(set (match_dup 0)
10064 (any_rotate:SWI48 (match_dup 1) (match_dup 2)))
10065 (clobber (reg:CC FLAGS_REG))])]
10067 if (can_create_pseudo_p ())
10068 operands [2] = force_reg (SImode, operands[2]);
10070 operands[2] = simplify_gen_subreg (QImode, operands[2], SImode, 0);
10072 [(set_attr "type" "rotate")
10073 (set_attr "mode" "<MODE>")])
10075 ;; Implement rotation using two double-precision
10076 ;; shift instructions and a scratch register.
10078 (define_insn_and_split "ix86_rotl<dwi>3_doubleword"
10079 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10080 (rotate:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10081 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10082 (clobber (reg:CC FLAGS_REG))
10083 (clobber (match_scratch:DWIH 3 "=&r"))]
10087 [(set (match_dup 3) (match_dup 4))
10089 [(set (match_dup 4)
10090 (ior:DWIH (ashift:DWIH (match_dup 4) (match_dup 2))
10091 (lshiftrt:DWIH (match_dup 5)
10092 (minus:QI (match_dup 6) (match_dup 2)))))
10093 (clobber (reg:CC FLAGS_REG))])
10095 [(set (match_dup 5)
10096 (ior:DWIH (ashift:DWIH (match_dup 5) (match_dup 2))
10097 (lshiftrt:DWIH (match_dup 3)
10098 (minus:QI (match_dup 6) (match_dup 2)))))
10099 (clobber (reg:CC FLAGS_REG))])]
10101 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10103 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10106 (define_insn_and_split "ix86_rotr<dwi>3_doubleword"
10107 [(set (match_operand:<DWI> 0 "register_operand" "=r")
10108 (rotatert:<DWI> (match_operand:<DWI> 1 "register_operand" "0")
10109 (match_operand:QI 2 "<shift_immediate_operand>" "<S>")))
10110 (clobber (reg:CC FLAGS_REG))
10111 (clobber (match_scratch:DWIH 3 "=&r"))]
10115 [(set (match_dup 3) (match_dup 4))
10117 [(set (match_dup 4)
10118 (ior:DWIH (ashiftrt:DWIH (match_dup 4) (match_dup 2))
10119 (ashift:DWIH (match_dup 5)
10120 (minus:QI (match_dup 6) (match_dup 2)))))
10121 (clobber (reg:CC FLAGS_REG))])
10123 [(set (match_dup 5)
10124 (ior:DWIH (ashiftrt:DWIH (match_dup 5) (match_dup 2))
10125 (ashift:DWIH (match_dup 3)
10126 (minus:QI (match_dup 6) (match_dup 2)))))
10127 (clobber (reg:CC FLAGS_REG))])]
10129 operands[6] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));
10131 split_double_mode (<DWI>mode, &operands[0], 1, &operands[4], &operands[5]);
10134 (define_insn "*bmi2_rorx<mode>3_1"
10135 [(set (match_operand:SWI48 0 "register_operand" "=r")
10136 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
10137 (match_operand:QI 2 "immediate_operand" "<S>")))]
10139 "rorx\t{%2, %1, %0|%0, %1, %2}"
10140 [(set_attr "type" "rotatex")
10141 (set_attr "mode" "<MODE>")])
10143 (define_insn "*<rotate_insn><mode>3_1"
10144 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
10146 (match_operand:SWI48 1 "nonimmediate_operand" "0,rm")
10147 (match_operand:QI 2 "nonmemory_operand" "c<S>,<S>")))
10148 (clobber (reg:CC FLAGS_REG))]
10149 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10151 switch (get_attr_type (insn))
10157 if (operands[2] == const1_rtx
10158 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10159 return "<rotate>{<imodesuffix>}\t%0";
10161 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10164 [(set_attr "isa" "*,bmi2")
10165 (set_attr "type" "rotate,rotatex")
10166 (set (attr "length_immediate")
10168 (and (eq_attr "type" "rotate")
10169 (and (match_operand 2 "const1_operand" "")
10170 (ior (match_test "TARGET_SHIFT1")
10171 (match_test "optimize_function_for_size_p (cfun)"))))
10173 (const_string "*")))
10174 (set_attr "mode" "<MODE>")])
10176 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10178 [(set (match_operand:SWI48 0 "register_operand" "")
10179 (rotate:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10180 (match_operand:QI 2 "immediate_operand" "")))
10181 (clobber (reg:CC FLAGS_REG))]
10182 "TARGET_BMI2 && reload_completed"
10183 [(set (match_dup 0)
10184 (rotatert:SWI48 (match_dup 1) (match_dup 2)))]
10187 = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - INTVAL (operands[2]));
10191 [(set (match_operand:SWI48 0 "register_operand" "")
10192 (rotatert:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
10193 (match_operand:QI 2 "immediate_operand" "")))
10194 (clobber (reg:CC FLAGS_REG))]
10195 "TARGET_BMI2 && reload_completed"
10196 [(set (match_dup 0)
10197 (rotatert:SWI48 (match_dup 1) (match_dup 2)))])
10199 (define_insn "*bmi2_rorxsi3_1_zext"
10200 [(set (match_operand:DI 0 "register_operand" "=r")
10202 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "rm")
10203 (match_operand:QI 2 "immediate_operand" "I"))))]
10204 "TARGET_64BIT && TARGET_BMI2"
10205 "rorx\t{%2, %1, %k0|%k0, %1, %2}"
10206 [(set_attr "type" "rotatex")
10207 (set_attr "mode" "SI")])
10209 (define_insn "*<rotate_insn>si3_1_zext"
10210 [(set (match_operand:DI 0 "register_operand" "=r,r")
10212 (any_rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,rm")
10213 (match_operand:QI 2 "nonmemory_operand" "cI,I"))))
10214 (clobber (reg:CC FLAGS_REG))]
10215 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
10217 switch (get_attr_type (insn))
10223 if (operands[2] == const1_rtx
10224 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10225 return "<rotate>{l}\t%k0";
10227 return "<rotate>{l}\t{%2, %k0|%k0, %2}";
10230 [(set_attr "isa" "*,bmi2")
10231 (set_attr "type" "rotate,rotatex")
10232 (set (attr "length_immediate")
10234 (and (eq_attr "type" "rotate")
10235 (and (match_operand 2 "const1_operand" "")
10236 (ior (match_test "TARGET_SHIFT1")
10237 (match_test "optimize_function_for_size_p (cfun)"))))
10239 (const_string "*")))
10240 (set_attr "mode" "SI")])
10242 ;; Convert rotate to the rotatex pattern to avoid flags dependency.
10244 [(set (match_operand:DI 0 "register_operand" "")
10246 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
10247 (match_operand:QI 2 "immediate_operand" ""))))
10248 (clobber (reg:CC FLAGS_REG))]
10249 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10250 [(set (match_dup 0)
10251 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))]
10254 = GEN_INT (GET_MODE_BITSIZE (SImode) - INTVAL (operands[2]));
10258 [(set (match_operand:DI 0 "register_operand" "")
10260 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
10261 (match_operand:QI 2 "immediate_operand" ""))))
10262 (clobber (reg:CC FLAGS_REG))]
10263 "TARGET_64BIT && TARGET_BMI2 && reload_completed"
10264 [(set (match_dup 0)
10265 (zero_extend:DI (rotatert:SI (match_dup 1) (match_dup 2))))])
10267 (define_insn "*<rotate_insn><mode>3_1"
10268 [(set (match_operand:SWI12 0 "nonimmediate_operand" "=<r>m")
10269 (any_rotate:SWI12 (match_operand:SWI12 1 "nonimmediate_operand" "0")
10270 (match_operand:QI 2 "nonmemory_operand" "c<S>")))
10271 (clobber (reg:CC FLAGS_REG))]
10272 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
10274 if (operands[2] == const1_rtx
10275 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10276 return "<rotate>{<imodesuffix>}\t%0";
10278 return "<rotate>{<imodesuffix>}\t{%2, %0|%0, %2}";
10280 [(set_attr "type" "rotate")
10281 (set (attr "length_immediate")
10283 (and (match_operand 2 "const1_operand" "")
10284 (ior (match_test "TARGET_SHIFT1")
10285 (match_test "optimize_function_for_size_p (cfun)")))
10287 (const_string "*")))
10288 (set_attr "mode" "<MODE>")])
10290 (define_insn "*<rotate_insn>qi3_1_slp"
10291 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10292 (any_rotate:QI (match_dup 0)
10293 (match_operand:QI 1 "nonmemory_operand" "cI")))
10294 (clobber (reg:CC FLAGS_REG))]
10295 "(optimize_function_for_size_p (cfun)
10296 || !TARGET_PARTIAL_REG_STALL
10297 || (operands[1] == const1_rtx
10298 && TARGET_SHIFT1))"
10300 if (operands[1] == const1_rtx
10301 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10302 return "<rotate>{b}\t%0";
10304 return "<rotate>{b}\t{%1, %0|%0, %1}";
10306 [(set_attr "type" "rotate1")
10307 (set (attr "length_immediate")
10309 (and (match_operand 1 "const1_operand" "")
10310 (ior (match_test "TARGET_SHIFT1")
10311 (match_test "optimize_function_for_size_p (cfun)")))
10313 (const_string "*")))
10314 (set_attr "mode" "QI")])
10317 [(set (match_operand:HI 0 "register_operand" "")
10318 (any_rotate:HI (match_dup 0) (const_int 8)))
10319 (clobber (reg:CC FLAGS_REG))]
10321 && (TARGET_USE_XCHGB || optimize_function_for_size_p (cfun))"
10322 [(parallel [(set (strict_low_part (match_dup 0))
10323 (bswap:HI (match_dup 0)))
10324 (clobber (reg:CC FLAGS_REG))])])
10326 ;; Bit set / bit test instructions
10328 (define_expand "extv"
10329 [(set (match_operand:SI 0 "register_operand" "")
10330 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
10331 (match_operand:SI 2 "const8_operand" "")
10332 (match_operand:SI 3 "const8_operand" "")))]
10335 /* Handle extractions from %ah et al. */
10336 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10339 /* From mips.md: extract_bit_field doesn't verify that our source
10340 matches the predicate, so check it again here. */
10341 if (! ext_register_operand (operands[1], VOIDmode))
10345 (define_expand "extzv"
10346 [(set (match_operand:SI 0 "register_operand" "")
10347 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
10348 (match_operand:SI 2 "const8_operand" "")
10349 (match_operand:SI 3 "const8_operand" "")))]
10352 /* Handle extractions from %ah et al. */
10353 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
10356 /* From mips.md: extract_bit_field doesn't verify that our source
10357 matches the predicate, so check it again here. */
10358 if (! ext_register_operand (operands[1], VOIDmode))
10362 (define_expand "insv"
10363 [(set (zero_extract (match_operand 0 "register_operand" "")
10364 (match_operand 1 "const_int_operand" "")
10365 (match_operand 2 "const_int_operand" ""))
10366 (match_operand 3 "register_operand" ""))]
10369 rtx (*gen_mov_insv_1) (rtx, rtx);
10371 if (ix86_expand_pinsr (operands))
10374 /* Handle insertions to %ah et al. */
10375 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
10378 /* From mips.md: insert_bit_field doesn't verify that our source
10379 matches the predicate, so check it again here. */
10380 if (! ext_register_operand (operands[0], VOIDmode))
10383 gen_mov_insv_1 = (TARGET_64BIT
10384 ? gen_movdi_insv_1 : gen_movsi_insv_1);
10386 emit_insn (gen_mov_insv_1 (operands[0], operands[3]));
10390 ;; %%% bts, btr, btc, bt.
10391 ;; In general these instructions are *slow* when applied to memory,
10392 ;; since they enforce atomic operation. When applied to registers,
10393 ;; it depends on the cpu implementation. They're never faster than
10394 ;; the corresponding and/ior/xor operations, so with 32-bit there's
10395 ;; no point. But in 64-bit, we can't hold the relevant immediates
10396 ;; within the instruction itself, so operating on bits in the high
10397 ;; 32-bits of a register becomes easier.
10399 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
10400 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
10401 ;; negdf respectively, so they can never be disabled entirely.
10403 (define_insn "*btsq"
10404 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10406 (match_operand:DI 1 "const_0_to_63_operand" ""))
10408 (clobber (reg:CC FLAGS_REG))]
10409 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10410 "bts{q}\t{%1, %0|%0, %1}"
10411 [(set_attr "type" "alu1")
10412 (set_attr "prefix_0f" "1")
10413 (set_attr "mode" "DI")])
10415 (define_insn "*btrq"
10416 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10418 (match_operand:DI 1 "const_0_to_63_operand" ""))
10420 (clobber (reg:CC FLAGS_REG))]
10421 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10422 "btr{q}\t{%1, %0|%0, %1}"
10423 [(set_attr "type" "alu1")
10424 (set_attr "prefix_0f" "1")
10425 (set_attr "mode" "DI")])
10427 (define_insn "*btcq"
10428 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
10430 (match_operand:DI 1 "const_0_to_63_operand" ""))
10431 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
10432 (clobber (reg:CC FLAGS_REG))]
10433 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
10434 "btc{q}\t{%1, %0|%0, %1}"
10435 [(set_attr "type" "alu1")
10436 (set_attr "prefix_0f" "1")
10437 (set_attr "mode" "DI")])
10439 ;; Allow Nocona to avoid these instructions if a register is available.
10442 [(match_scratch:DI 2 "r")
10443 (parallel [(set (zero_extract:DI
10444 (match_operand:DI 0 "register_operand" "")
10446 (match_operand:DI 1 "const_0_to_63_operand" ""))
10448 (clobber (reg:CC FLAGS_REG))])]
10449 "TARGET_64BIT && !TARGET_USE_BT"
10452 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10455 if (HOST_BITS_PER_WIDE_INT >= 64)
10456 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10457 else if (i < HOST_BITS_PER_WIDE_INT)
10458 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10460 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10462 op1 = immed_double_const (lo, hi, DImode);
10465 emit_move_insn (operands[2], op1);
10469 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
10474 [(match_scratch:DI 2 "r")
10475 (parallel [(set (zero_extract:DI
10476 (match_operand:DI 0 "register_operand" "")
10478 (match_operand:DI 1 "const_0_to_63_operand" ""))
10480 (clobber (reg:CC FLAGS_REG))])]
10481 "TARGET_64BIT && !TARGET_USE_BT"
10484 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10487 if (HOST_BITS_PER_WIDE_INT >= 64)
10488 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10489 else if (i < HOST_BITS_PER_WIDE_INT)
10490 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10492 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10494 op1 = immed_double_const (~lo, ~hi, DImode);
10497 emit_move_insn (operands[2], op1);
10501 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
10506 [(match_scratch:DI 2 "r")
10507 (parallel [(set (zero_extract:DI
10508 (match_operand:DI 0 "register_operand" "")
10510 (match_operand:DI 1 "const_0_to_63_operand" ""))
10511 (not:DI (zero_extract:DI
10512 (match_dup 0) (const_int 1) (match_dup 1))))
10513 (clobber (reg:CC FLAGS_REG))])]
10514 "TARGET_64BIT && !TARGET_USE_BT"
10517 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
10520 if (HOST_BITS_PER_WIDE_INT >= 64)
10521 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10522 else if (i < HOST_BITS_PER_WIDE_INT)
10523 lo = (HOST_WIDE_INT)1 << i, hi = 0;
10525 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
10527 op1 = immed_double_const (lo, hi, DImode);
10530 emit_move_insn (operands[2], op1);
10534 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
10538 (define_insn "*bt<mode>"
10539 [(set (reg:CCC FLAGS_REG)
10541 (zero_extract:SWI48
10542 (match_operand:SWI48 0 "register_operand" "r")
10544 (match_operand:SWI48 1 "x86_64_nonmemory_operand" "rN"))
10546 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10547 "bt{<imodesuffix>}\t{%1, %0|%0, %1}"
10548 [(set_attr "type" "alu1")
10549 (set_attr "prefix_0f" "1")
10550 (set_attr "mode" "<MODE>")])
10552 ;; Store-flag instructions.
10554 ;; For all sCOND expanders, also expand the compare or test insn that
10555 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
10557 (define_insn_and_split "*setcc_di_1"
10558 [(set (match_operand:DI 0 "register_operand" "=q")
10559 (match_operator:DI 1 "ix86_comparison_operator"
10560 [(reg FLAGS_REG) (const_int 0)]))]
10561 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
10563 "&& reload_completed"
10564 [(set (match_dup 2) (match_dup 1))
10565 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
10567 PUT_MODE (operands[1], QImode);
10568 operands[2] = gen_lowpart (QImode, operands[0]);
10571 (define_insn_and_split "*setcc_si_1_and"
10572 [(set (match_operand:SI 0 "register_operand" "=q")
10573 (match_operator:SI 1 "ix86_comparison_operator"
10574 [(reg FLAGS_REG) (const_int 0)]))
10575 (clobber (reg:CC FLAGS_REG))]
10576 "!TARGET_PARTIAL_REG_STALL
10577 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
10579 "&& reload_completed"
10580 [(set (match_dup 2) (match_dup 1))
10581 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
10582 (clobber (reg:CC FLAGS_REG))])]
10584 PUT_MODE (operands[1], QImode);
10585 operands[2] = gen_lowpart (QImode, operands[0]);
10588 (define_insn_and_split "*setcc_si_1_movzbl"
10589 [(set (match_operand:SI 0 "register_operand" "=q")
10590 (match_operator:SI 1 "ix86_comparison_operator"
10591 [(reg FLAGS_REG) (const_int 0)]))]
10592 "!TARGET_PARTIAL_REG_STALL
10593 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
10595 "&& reload_completed"
10596 [(set (match_dup 2) (match_dup 1))
10597 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
10599 PUT_MODE (operands[1], QImode);
10600 operands[2] = gen_lowpart (QImode, operands[0]);
10603 (define_insn "*setcc_qi"
10604 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10605 (match_operator:QI 1 "ix86_comparison_operator"
10606 [(reg FLAGS_REG) (const_int 0)]))]
10609 [(set_attr "type" "setcc")
10610 (set_attr "mode" "QI")])
10612 (define_insn "*setcc_qi_slp"
10613 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
10614 (match_operator:QI 1 "ix86_comparison_operator"
10615 [(reg FLAGS_REG) (const_int 0)]))]
10618 [(set_attr "type" "setcc")
10619 (set_attr "mode" "QI")])
10621 ;; In general it is not safe to assume too much about CCmode registers,
10622 ;; so simplify-rtx stops when it sees a second one. Under certain
10623 ;; conditions this is safe on x86, so help combine not create
10630 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10631 (ne:QI (match_operator 1 "ix86_comparison_operator"
10632 [(reg FLAGS_REG) (const_int 0)])
10635 [(set (match_dup 0) (match_dup 1))]
10636 "PUT_MODE (operands[1], QImode);")
10639 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10640 (ne:QI (match_operator 1 "ix86_comparison_operator"
10641 [(reg FLAGS_REG) (const_int 0)])
10644 [(set (match_dup 0) (match_dup 1))]
10645 "PUT_MODE (operands[1], QImode);")
10648 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10649 (eq:QI (match_operator 1 "ix86_comparison_operator"
10650 [(reg FLAGS_REG) (const_int 0)])
10653 [(set (match_dup 0) (match_dup 1))]
10655 rtx new_op1 = copy_rtx (operands[1]);
10656 operands[1] = new_op1;
10657 PUT_MODE (new_op1, QImode);
10658 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10659 GET_MODE (XEXP (new_op1, 0))));
10661 /* Make sure that (a) the CCmode we have for the flags is strong
10662 enough for the reversed compare or (b) we have a valid FP compare. */
10663 if (! ix86_comparison_operator (new_op1, VOIDmode))
10668 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
10669 (eq:QI (match_operator 1 "ix86_comparison_operator"
10670 [(reg FLAGS_REG) (const_int 0)])
10673 [(set (match_dup 0) (match_dup 1))]
10675 rtx new_op1 = copy_rtx (operands[1]);
10676 operands[1] = new_op1;
10677 PUT_MODE (new_op1, QImode);
10678 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
10679 GET_MODE (XEXP (new_op1, 0))));
10681 /* Make sure that (a) the CCmode we have for the flags is strong
10682 enough for the reversed compare or (b) we have a valid FP compare. */
10683 if (! ix86_comparison_operator (new_op1, VOIDmode))
10687 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
10688 ;; subsequent logical operations are used to imitate conditional moves.
10689 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
10692 (define_insn "setcc_<mode>_sse"
10693 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
10694 (match_operator:MODEF 3 "sse_comparison_operator"
10695 [(match_operand:MODEF 1 "register_operand" "0,x")
10696 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
10697 "SSE_FLOAT_MODE_P (<MODE>mode)"
10699 cmp%D3<ssemodesuffix>\t{%2, %0|%0, %2}
10700 vcmp%D3<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
10701 [(set_attr "isa" "noavx,avx")
10702 (set_attr "type" "ssecmp")
10703 (set_attr "length_immediate" "1")
10704 (set_attr "prefix" "orig,vex")
10705 (set_attr "mode" "<MODE>")])
10707 ;; Basic conditional jump instructions.
10708 ;; We ignore the overflow flag for signed branch instructions.
10710 (define_insn "*jcc_1"
10712 (if_then_else (match_operator 1 "ix86_comparison_operator"
10713 [(reg FLAGS_REG) (const_int 0)])
10714 (label_ref (match_operand 0 "" ""))
10718 [(set_attr "type" "ibr")
10719 (set_attr "modrm" "0")
10720 (set (attr "length")
10721 (if_then_else (and (ge (minus (match_dup 0) (pc))
10723 (lt (minus (match_dup 0) (pc))
10728 (define_insn "*jcc_2"
10730 (if_then_else (match_operator 1 "ix86_comparison_operator"
10731 [(reg FLAGS_REG) (const_int 0)])
10733 (label_ref (match_operand 0 "" ""))))]
10736 [(set_attr "type" "ibr")
10737 (set_attr "modrm" "0")
10738 (set (attr "length")
10739 (if_then_else (and (ge (minus (match_dup 0) (pc))
10741 (lt (minus (match_dup 0) (pc))
10746 ;; In general it is not safe to assume too much about CCmode registers,
10747 ;; so simplify-rtx stops when it sees a second one. Under certain
10748 ;; conditions this is safe on x86, so help combine not create
10756 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
10757 [(reg FLAGS_REG) (const_int 0)])
10759 (label_ref (match_operand 1 "" ""))
10763 (if_then_else (match_dup 0)
10764 (label_ref (match_dup 1))
10766 "PUT_MODE (operands[0], VOIDmode);")
10770 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
10771 [(reg FLAGS_REG) (const_int 0)])
10773 (label_ref (match_operand 1 "" ""))
10777 (if_then_else (match_dup 0)
10778 (label_ref (match_dup 1))
10781 rtx new_op0 = copy_rtx (operands[0]);
10782 operands[0] = new_op0;
10783 PUT_MODE (new_op0, VOIDmode);
10784 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
10785 GET_MODE (XEXP (new_op0, 0))));
10787 /* Make sure that (a) the CCmode we have for the flags is strong
10788 enough for the reversed compare or (b) we have a valid FP compare. */
10789 if (! ix86_comparison_operator (new_op0, VOIDmode))
10793 ;; zero_extend in SImode is correct also for DImode, since this is what combine
10794 ;; pass generates from shift insn with QImode operand. Actually, the mode
10795 ;; of operand 2 (bit offset operand) doesn't matter since bt insn takes
10796 ;; appropriate modulo of the bit offset value.
10798 (define_insn_and_split "*jcc_bt<mode>"
10800 (if_then_else (match_operator 0 "bt_comparison_operator"
10801 [(zero_extract:SWI48
10802 (match_operand:SWI48 1 "register_operand" "r")
10805 (match_operand:QI 2 "register_operand" "r")))
10807 (label_ref (match_operand 3 "" ""))
10809 (clobber (reg:CC FLAGS_REG))]
10810 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
10813 [(set (reg:CCC FLAGS_REG)
10815 (zero_extract:SWI48
10821 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10822 (label_ref (match_dup 3))
10825 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], QImode, 0);
10827 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10830 ;; Avoid useless masking of bit offset operand. "and" in SImode is correct
10831 ;; also for DImode, this is what combine produces.
10832 (define_insn_and_split "*jcc_bt<mode>_mask"
10834 (if_then_else (match_operator 0 "bt_comparison_operator"
10835 [(zero_extract:SWI48
10836 (match_operand:SWI48 1 "register_operand" "r")
10839 (match_operand:SI 2 "register_operand" "r")
10840 (match_operand:SI 3 "const_int_operand" "n")))])
10841 (label_ref (match_operand 4 "" ""))
10843 (clobber (reg:CC FLAGS_REG))]
10844 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10845 && (INTVAL (operands[3]) & (GET_MODE_BITSIZE (<MODE>mode)-1))
10846 == GET_MODE_BITSIZE (<MODE>mode)-1"
10849 [(set (reg:CCC FLAGS_REG)
10851 (zero_extract:SWI48
10857 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10858 (label_ref (match_dup 4))
10861 operands[2] = simplify_gen_subreg (<MODE>mode, operands[2], SImode, 0);
10863 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10866 (define_insn_and_split "*jcc_btsi_1"
10868 (if_then_else (match_operator 0 "bt_comparison_operator"
10871 (match_operand:SI 1 "register_operand" "r")
10872 (match_operand:QI 2 "register_operand" "r"))
10875 (label_ref (match_operand 3 "" ""))
10877 (clobber (reg:CC FLAGS_REG))]
10878 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
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 3))
10893 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
10895 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
10898 ;; avoid useless masking of bit offset operand
10899 (define_insn_and_split "*jcc_btsi_mask_1"
10902 (match_operator 0 "bt_comparison_operator"
10905 (match_operand:SI 1 "register_operand" "r")
10908 (match_operand:SI 2 "register_operand" "r")
10909 (match_operand:SI 3 "const_int_operand" "n")) 0))
10912 (label_ref (match_operand 4 "" ""))
10914 (clobber (reg:CC FLAGS_REG))]
10915 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
10916 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
10919 [(set (reg:CCC FLAGS_REG)
10927 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
10928 (label_ref (match_dup 4))
10930 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
10932 ;; Define combination compare-and-branch fp compare instructions to help
10935 (define_insn "*fp_jcc_1_387"
10937 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10938 [(match_operand 1 "register_operand" "f")
10939 (match_operand 2 "nonimmediate_operand" "fm")])
10940 (label_ref (match_operand 3 "" ""))
10942 (clobber (reg:CCFP FPSR_REG))
10943 (clobber (reg:CCFP FLAGS_REG))
10944 (clobber (match_scratch:HI 4 "=a"))]
10946 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10947 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10948 && SELECT_CC_MODE (GET_CODE (operands[0]),
10949 operands[1], operands[2]) == CCFPmode
10953 (define_insn "*fp_jcc_1r_387"
10955 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10956 [(match_operand 1 "register_operand" "f")
10957 (match_operand 2 "nonimmediate_operand" "fm")])
10959 (label_ref (match_operand 3 "" ""))))
10960 (clobber (reg:CCFP FPSR_REG))
10961 (clobber (reg:CCFP FLAGS_REG))
10962 (clobber (match_scratch:HI 4 "=a"))]
10964 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
10965 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10966 && SELECT_CC_MODE (GET_CODE (operands[0]),
10967 operands[1], operands[2]) == CCFPmode
10971 (define_insn "*fp_jcc_2_387"
10973 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10974 [(match_operand 1 "register_operand" "f")
10975 (match_operand 2 "register_operand" "f")])
10976 (label_ref (match_operand 3 "" ""))
10978 (clobber (reg:CCFP FPSR_REG))
10979 (clobber (reg:CCFP FLAGS_REG))
10980 (clobber (match_scratch:HI 4 "=a"))]
10981 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10982 && GET_MODE (operands[1]) == GET_MODE (operands[2])
10986 (define_insn "*fp_jcc_2r_387"
10988 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
10989 [(match_operand 1 "register_operand" "f")
10990 (match_operand 2 "register_operand" "f")])
10992 (label_ref (match_operand 3 "" ""))))
10993 (clobber (reg:CCFP FPSR_REG))
10994 (clobber (reg:CCFP FLAGS_REG))
10995 (clobber (match_scratch:HI 4 "=a"))]
10996 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
10997 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11001 (define_insn "*fp_jcc_3_387"
11003 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11004 [(match_operand 1 "register_operand" "f")
11005 (match_operand 2 "const0_operand" "")])
11006 (label_ref (match_operand 3 "" ""))
11008 (clobber (reg:CCFP FPSR_REG))
11009 (clobber (reg:CCFP FLAGS_REG))
11010 (clobber (match_scratch:HI 4 "=a"))]
11011 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
11012 && GET_MODE (operands[1]) == GET_MODE (operands[2])
11013 && SELECT_CC_MODE (GET_CODE (operands[0]),
11014 operands[1], operands[2]) == CCFPmode
11020 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11021 [(match_operand 1 "register_operand" "")
11022 (match_operand 2 "nonimmediate_operand" "")])
11023 (match_operand 3 "" "")
11024 (match_operand 4 "" "")))
11025 (clobber (reg:CCFP FPSR_REG))
11026 (clobber (reg:CCFP FLAGS_REG))]
11030 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11031 operands[3], operands[4], NULL_RTX, NULL_RTX);
11037 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
11038 [(match_operand 1 "register_operand" "")
11039 (match_operand 2 "general_operand" "")])
11040 (match_operand 3 "" "")
11041 (match_operand 4 "" "")))
11042 (clobber (reg:CCFP FPSR_REG))
11043 (clobber (reg:CCFP FLAGS_REG))
11044 (clobber (match_scratch:HI 5 "=a"))]
11048 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
11049 operands[3], operands[4], operands[5], NULL_RTX);
11053 ;; The order of operands in *fp_jcc_4_387 is forced by combine in
11054 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
11055 ;; with a precedence over other operators and is always put in the first
11056 ;; place. Swap condition and operands to match ficom instruction.
11058 (define_insn "*fp_jcc_4_<mode>_387"
11061 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11062 [(match_operator 1 "float_operator"
11063 [(match_operand:SWI24 2 "nonimmediate_operand" "m,?r")])
11064 (match_operand 3 "register_operand" "f,f")])
11065 (label_ref (match_operand 4 "" ""))
11067 (clobber (reg:CCFP FPSR_REG))
11068 (clobber (reg:CCFP FLAGS_REG))
11069 (clobber (match_scratch:HI 5 "=a,a"))]
11070 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
11071 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
11072 && GET_MODE (operands[1]) == GET_MODE (operands[3])
11073 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
11080 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11081 [(match_operator 1 "float_operator"
11082 [(match_operand:SWI24 2 "memory_operand" "")])
11083 (match_operand 3 "register_operand" "")])
11084 (match_operand 4 "" "")
11085 (match_operand 5 "" "")))
11086 (clobber (reg:CCFP FPSR_REG))
11087 (clobber (reg:CCFP FLAGS_REG))
11088 (clobber (match_scratch:HI 6 "=a"))]
11092 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
11094 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11095 operands[3], operands[7],
11096 operands[4], operands[5], operands[6], NULL_RTX);
11100 ;; %%% Kill this when reload knows how to do it.
11104 (match_operator 0 "ix86_swapped_fp_comparison_operator"
11105 [(match_operator 1 "float_operator"
11106 [(match_operand:SWI24 2 "register_operand" "")])
11107 (match_operand 3 "register_operand" "")])
11108 (match_operand 4 "" "")
11109 (match_operand 5 "" "")))
11110 (clobber (reg:CCFP FPSR_REG))
11111 (clobber (reg:CCFP FLAGS_REG))
11112 (clobber (match_scratch:HI 6 "=a"))]
11116 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
11117 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
11119 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
11120 operands[3], operands[7],
11121 operands[4], operands[5], operands[6], operands[2]);
11125 ;; Unconditional and other jump instructions
11127 (define_insn "jump"
11129 (label_ref (match_operand 0 "" "")))]
11132 [(set_attr "type" "ibr")
11133 (set (attr "length")
11134 (if_then_else (and (ge (minus (match_dup 0) (pc))
11136 (lt (minus (match_dup 0) (pc))
11140 (set_attr "modrm" "0")])
11142 (define_expand "indirect_jump"
11143 [(set (pc) (match_operand 0 "indirect_branch_operand" ""))])
11145 (define_insn "*indirect_jump"
11146 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))]
11149 [(set_attr "type" "ibr")
11150 (set_attr "length_immediate" "0")])
11152 (define_expand "tablejump"
11153 [(parallel [(set (pc) (match_operand 0 "indirect_branch_operand" ""))
11154 (use (label_ref (match_operand 1 "" "")))])]
11157 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
11158 relative. Convert the relative address to an absolute address. */
11162 enum rtx_code code;
11164 /* We can't use @GOTOFF for text labels on VxWorks;
11165 see gotoff_operand. */
11166 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
11170 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
11172 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
11176 op1 = pic_offset_table_rtx;
11181 op0 = pic_offset_table_rtx;
11185 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
11188 else if (TARGET_X32)
11189 operands[0] = convert_memory_address (Pmode, operands[0]);
11192 (define_insn "*tablejump_1"
11193 [(set (pc) (match_operand:P 0 "indirect_branch_operand" "rw"))
11194 (use (label_ref (match_operand 1 "" "")))]
11197 [(set_attr "type" "ibr")
11198 (set_attr "length_immediate" "0")])
11200 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
11203 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11204 (set (match_operand:QI 1 "register_operand" "")
11205 (match_operator:QI 2 "ix86_comparison_operator"
11206 [(reg FLAGS_REG) (const_int 0)]))
11207 (set (match_operand 3 "q_regs_operand" "")
11208 (zero_extend (match_dup 1)))]
11209 "(peep2_reg_dead_p (3, operands[1])
11210 || operands_match_p (operands[1], operands[3]))
11211 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11212 [(set (match_dup 4) (match_dup 0))
11213 (set (strict_low_part (match_dup 5))
11216 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11217 operands[5] = gen_lowpart (QImode, operands[3]);
11218 ix86_expand_clear (operands[3]);
11221 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
11224 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
11225 (set (match_operand:QI 1 "register_operand" "")
11226 (match_operator:QI 2 "ix86_comparison_operator"
11227 [(reg FLAGS_REG) (const_int 0)]))
11228 (parallel [(set (match_operand 3 "q_regs_operand" "")
11229 (zero_extend (match_dup 1)))
11230 (clobber (reg:CC FLAGS_REG))])]
11231 "(peep2_reg_dead_p (3, operands[1])
11232 || operands_match_p (operands[1], operands[3]))
11233 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
11234 [(set (match_dup 4) (match_dup 0))
11235 (set (strict_low_part (match_dup 5))
11238 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
11239 operands[5] = gen_lowpart (QImode, operands[3]);
11240 ix86_expand_clear (operands[3]);
11243 ;; Call instructions.
11245 ;; The predicates normally associated with named expanders are not properly
11246 ;; checked for calls. This is a bug in the generic code, but it isn't that
11247 ;; easy to fix. Ignore it for now and be prepared to fix things up.
11249 ;; P6 processors will jump to the address after the decrement when %esp
11250 ;; is used as a call operand, so they will execute return address as a code.
11251 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
11253 ;; Register constraint for call instruction.
11254 (define_mode_attr c [(SI "l") (DI "r")])
11256 ;; Call subroutine returning no value.
11258 (define_expand "call"
11259 [(call (match_operand:QI 0 "" "")
11260 (match_operand 1 "" ""))
11261 (use (match_operand 2 "" ""))]
11264 ix86_expand_call (NULL, operands[0], operands[1],
11265 operands[2], NULL, false);
11269 (define_expand "sibcall"
11270 [(call (match_operand:QI 0 "" "")
11271 (match_operand 1 "" ""))
11272 (use (match_operand 2 "" ""))]
11275 ix86_expand_call (NULL, operands[0], operands[1],
11276 operands[2], NULL, true);
11280 (define_insn_and_split "*call_vzeroupper"
11281 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11282 (match_operand 1 "" ""))
11283 (unspec [(match_operand 2 "const_int_operand" "")]
11284 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11285 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11287 "&& reload_completed"
11289 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11290 [(set_attr "type" "call")])
11292 (define_insn "*call"
11293 [(call (mem:QI (match_operand:P 0 "call_insn_operand" "<c>zw"))
11294 (match_operand 1 "" ""))]
11295 "!SIBLING_CALL_P (insn)"
11296 "* return ix86_output_call_insn (insn, operands[0]);"
11297 [(set_attr "type" "call")])
11299 (define_insn_and_split "*call_rex64_ms_sysv_vzeroupper"
11300 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11301 (match_operand 1 "" ""))
11302 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11303 (clobber (reg:TI XMM6_REG))
11304 (clobber (reg:TI XMM7_REG))
11305 (clobber (reg:TI XMM8_REG))
11306 (clobber (reg:TI XMM9_REG))
11307 (clobber (reg:TI XMM10_REG))
11308 (clobber (reg:TI XMM11_REG))
11309 (clobber (reg:TI XMM12_REG))
11310 (clobber (reg:TI XMM13_REG))
11311 (clobber (reg:TI XMM14_REG))
11312 (clobber (reg:TI XMM15_REG))
11313 (clobber (reg:DI SI_REG))
11314 (clobber (reg:DI DI_REG))
11315 (unspec [(match_operand 2 "const_int_operand" "")]
11316 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11317 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11319 "&& reload_completed"
11321 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11322 [(set_attr "type" "call")])
11324 (define_insn "*call_rex64_ms_sysv"
11325 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rzw"))
11326 (match_operand 1 "" ""))
11327 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11328 (clobber (reg:TI XMM6_REG))
11329 (clobber (reg:TI XMM7_REG))
11330 (clobber (reg:TI XMM8_REG))
11331 (clobber (reg:TI XMM9_REG))
11332 (clobber (reg:TI XMM10_REG))
11333 (clobber (reg:TI XMM11_REG))
11334 (clobber (reg:TI XMM12_REG))
11335 (clobber (reg:TI XMM13_REG))
11336 (clobber (reg:TI XMM14_REG))
11337 (clobber (reg:TI XMM15_REG))
11338 (clobber (reg:DI SI_REG))
11339 (clobber (reg:DI DI_REG))]
11340 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11341 "* return ix86_output_call_insn (insn, operands[0]);"
11342 [(set_attr "type" "call")])
11344 (define_insn_and_split "*sibcall_vzeroupper"
11345 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11346 (match_operand 1 "" ""))
11347 (unspec [(match_operand 2 "const_int_operand" "")]
11348 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11349 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11351 "&& reload_completed"
11353 "ix86_split_call_vzeroupper (curr_insn, operands[2]); DONE;"
11354 [(set_attr "type" "call")])
11356 (define_insn "*sibcall"
11357 [(call (mem:QI (match_operand:P 0 "sibcall_insn_operand" "Uz"))
11358 (match_operand 1 "" ""))]
11359 "SIBLING_CALL_P (insn)"
11360 "* return ix86_output_call_insn (insn, operands[0]);"
11361 [(set_attr "type" "call")])
11363 (define_expand "call_pop"
11364 [(parallel [(call (match_operand:QI 0 "" "")
11365 (match_operand:SI 1 "" ""))
11366 (set (reg:SI SP_REG)
11367 (plus:SI (reg:SI SP_REG)
11368 (match_operand:SI 3 "" "")))])]
11371 ix86_expand_call (NULL, operands[0], operands[1],
11372 operands[2], operands[3], false);
11376 (define_insn_and_split "*call_pop_vzeroupper"
11377 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11378 (match_operand:SI 1 "" ""))
11379 (set (reg:SI SP_REG)
11380 (plus:SI (reg:SI SP_REG)
11381 (match_operand:SI 2 "immediate_operand" "i")))
11382 (unspec [(match_operand 3 "const_int_operand" "")]
11383 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11384 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11386 "&& reload_completed"
11388 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11389 [(set_attr "type" "call")])
11391 (define_insn "*call_pop"
11392 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lzm"))
11393 (match_operand 1 "" ""))
11394 (set (reg:SI SP_REG)
11395 (plus:SI (reg:SI SP_REG)
11396 (match_operand:SI 2 "immediate_operand" "i")))]
11397 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11398 "* return ix86_output_call_insn (insn, operands[0]);"
11399 [(set_attr "type" "call")])
11401 (define_insn_and_split "*sibcall_pop_vzeroupper"
11402 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11403 (match_operand 1 "" ""))
11404 (set (reg:SI SP_REG)
11405 (plus:SI (reg:SI SP_REG)
11406 (match_operand:SI 2 "immediate_operand" "i")))
11407 (unspec [(match_operand 3 "const_int_operand" "")]
11408 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11409 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11411 "&& reload_completed"
11413 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11414 [(set_attr "type" "call")])
11416 (define_insn "*sibcall_pop"
11417 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "Uz"))
11418 (match_operand 1 "" ""))
11419 (set (reg:SI SP_REG)
11420 (plus:SI (reg:SI SP_REG)
11421 (match_operand:SI 2 "immediate_operand" "i")))]
11422 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11423 "* return ix86_output_call_insn (insn, operands[0]);"
11424 [(set_attr "type" "call")])
11426 ;; Call subroutine, returning value in operand 0
11428 (define_expand "call_value"
11429 [(set (match_operand 0 "" "")
11430 (call (match_operand:QI 1 "" "")
11431 (match_operand 2 "" "")))
11432 (use (match_operand 3 "" ""))]
11435 ix86_expand_call (operands[0], operands[1], operands[2],
11436 operands[3], NULL, false);
11440 (define_expand "sibcall_value"
11441 [(set (match_operand 0 "" "")
11442 (call (match_operand:QI 1 "" "")
11443 (match_operand 2 "" "")))
11444 (use (match_operand 3 "" ""))]
11447 ix86_expand_call (operands[0], operands[1], operands[2],
11448 operands[3], NULL, true);
11452 (define_insn_and_split "*call_value_vzeroupper"
11453 [(set (match_operand 0 "" "")
11454 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11455 (match_operand 2 "" "")))
11456 (unspec [(match_operand 3 "const_int_operand" "")]
11457 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11458 "TARGET_VZEROUPPER && !SIBLING_CALL_P (insn)"
11460 "&& reload_completed"
11462 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11463 [(set_attr "type" "callv")])
11465 (define_insn "*call_value"
11466 [(set (match_operand 0 "" "")
11467 (call (mem:QI (match_operand:P 1 "call_insn_operand" "<c>zw"))
11468 (match_operand 2 "" "")))]
11469 "!SIBLING_CALL_P (insn)"
11470 "* return ix86_output_call_insn (insn, operands[1]);"
11471 [(set_attr "type" "callv")])
11473 (define_insn_and_split "*sibcall_value_vzeroupper"
11474 [(set (match_operand 0 "" "")
11475 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11476 (match_operand 2 "" "")))
11477 (unspec [(match_operand 3 "const_int_operand" "")]
11478 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11479 "TARGET_VZEROUPPER && SIBLING_CALL_P (insn)"
11481 "&& reload_completed"
11483 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11484 [(set_attr "type" "callv")])
11486 (define_insn "*sibcall_value"
11487 [(set (match_operand 0 "" "")
11488 (call (mem:QI (match_operand:P 1 "sibcall_insn_operand" "Uz"))
11489 (match_operand 2 "" "")))]
11490 "SIBLING_CALL_P (insn)"
11491 "* return ix86_output_call_insn (insn, operands[1]);"
11492 [(set_attr "type" "callv")])
11494 (define_insn_and_split "*call_value_rex64_ms_sysv_vzeroupper"
11495 [(set (match_operand 0 "" "")
11496 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11497 (match_operand 2 "" "")))
11498 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11499 (clobber (reg:TI XMM6_REG))
11500 (clobber (reg:TI XMM7_REG))
11501 (clobber (reg:TI XMM8_REG))
11502 (clobber (reg:TI XMM9_REG))
11503 (clobber (reg:TI XMM10_REG))
11504 (clobber (reg:TI XMM11_REG))
11505 (clobber (reg:TI XMM12_REG))
11506 (clobber (reg:TI XMM13_REG))
11507 (clobber (reg:TI XMM14_REG))
11508 (clobber (reg:TI XMM15_REG))
11509 (clobber (reg:DI SI_REG))
11510 (clobber (reg:DI DI_REG))
11511 (unspec [(match_operand 3 "const_int_operand" "")]
11512 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11513 "TARGET_VZEROUPPER && TARGET_64BIT && !SIBLING_CALL_P (insn)"
11515 "&& reload_completed"
11517 "ix86_split_call_vzeroupper (curr_insn, operands[3]); DONE;"
11518 [(set_attr "type" "callv")])
11520 (define_insn "*call_value_rex64_ms_sysv"
11521 [(set (match_operand 0 "" "")
11522 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rzw"))
11523 (match_operand 2 "" "")))
11524 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
11525 (clobber (reg:TI XMM6_REG))
11526 (clobber (reg:TI XMM7_REG))
11527 (clobber (reg:TI XMM8_REG))
11528 (clobber (reg:TI XMM9_REG))
11529 (clobber (reg:TI XMM10_REG))
11530 (clobber (reg:TI XMM11_REG))
11531 (clobber (reg:TI XMM12_REG))
11532 (clobber (reg:TI XMM13_REG))
11533 (clobber (reg:TI XMM14_REG))
11534 (clobber (reg:TI XMM15_REG))
11535 (clobber (reg:DI SI_REG))
11536 (clobber (reg:DI DI_REG))]
11537 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
11538 "* return ix86_output_call_insn (insn, operands[1]);"
11539 [(set_attr "type" "callv")])
11541 (define_expand "call_value_pop"
11542 [(parallel [(set (match_operand 0 "" "")
11543 (call (match_operand:QI 1 "" "")
11544 (match_operand:SI 2 "" "")))
11545 (set (reg:SI SP_REG)
11546 (plus:SI (reg:SI SP_REG)
11547 (match_operand:SI 4 "" "")))])]
11550 ix86_expand_call (operands[0], operands[1], operands[2],
11551 operands[3], operands[4], false);
11555 (define_insn_and_split "*call_value_pop_vzeroupper"
11556 [(set (match_operand 0 "" "")
11557 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11558 (match_operand 2 "" "")))
11559 (set (reg:SI SP_REG)
11560 (plus:SI (reg:SI SP_REG)
11561 (match_operand:SI 3 "immediate_operand" "i")))
11562 (unspec [(match_operand 4 "const_int_operand" "")]
11563 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11564 "TARGET_VZEROUPPER && !TARGET_64BIT && !SIBLING_CALL_P (insn)"
11566 "&& reload_completed"
11568 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11569 [(set_attr "type" "callv")])
11571 (define_insn "*call_value_pop"
11572 [(set (match_operand 0 "" "")
11573 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lzm"))
11574 (match_operand 2 "" "")))
11575 (set (reg:SI SP_REG)
11576 (plus:SI (reg:SI SP_REG)
11577 (match_operand:SI 3 "immediate_operand" "i")))]
11578 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
11579 "* return ix86_output_call_insn (insn, operands[1]);"
11580 [(set_attr "type" "callv")])
11582 (define_insn_and_split "*sibcall_value_pop_vzeroupper"
11583 [(set (match_operand 0 "" "")
11584 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11585 (match_operand 2 "" "")))
11586 (set (reg:SI SP_REG)
11587 (plus:SI (reg:SI SP_REG)
11588 (match_operand:SI 3 "immediate_operand" "i")))
11589 (unspec [(match_operand 4 "const_int_operand" "")]
11590 UNSPEC_CALL_NEEDS_VZEROUPPER)]
11591 "TARGET_VZEROUPPER && !TARGET_64BIT && SIBLING_CALL_P (insn)"
11593 "&& reload_completed"
11595 "ix86_split_call_vzeroupper (curr_insn, operands[4]); DONE;"
11596 [(set_attr "type" "callv")])
11598 (define_insn "*sibcall_value_pop"
11599 [(set (match_operand 0 "" "")
11600 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "Uz"))
11601 (match_operand 2 "" "")))
11602 (set (reg:SI SP_REG)
11603 (plus:SI (reg:SI SP_REG)
11604 (match_operand:SI 3 "immediate_operand" "i")))]
11605 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
11606 "* return ix86_output_call_insn (insn, operands[1]);"
11607 [(set_attr "type" "callv")])
11609 ;; Call subroutine returning any type.
11611 (define_expand "untyped_call"
11612 [(parallel [(call (match_operand 0 "" "")
11614 (match_operand 1 "" "")
11615 (match_operand 2 "" "")])]
11620 /* In order to give reg-stack an easier job in validating two
11621 coprocessor registers as containing a possible return value,
11622 simply pretend the untyped call returns a complex long double
11625 We can't use SSE_REGPARM_MAX here since callee is unprototyped
11626 and should have the default ABI. */
11628 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
11629 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
11630 operands[0], const0_rtx,
11631 GEN_INT ((TARGET_64BIT
11632 ? (ix86_abi == SYSV_ABI
11633 ? X86_64_SSE_REGPARM_MAX
11634 : X86_64_MS_SSE_REGPARM_MAX)
11635 : X86_32_SSE_REGPARM_MAX)
11639 for (i = 0; i < XVECLEN (operands[2], 0); i++)
11641 rtx set = XVECEXP (operands[2], 0, i);
11642 emit_move_insn (SET_DEST (set), SET_SRC (set));
11645 /* The optimizer does not know that the call sets the function value
11646 registers we stored in the result block. We avoid problems by
11647 claiming that all hard registers are used and clobbered at this
11649 emit_insn (gen_blockage ());
11654 ;; Prologue and epilogue instructions
11656 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
11657 ;; all of memory. This blocks insns from being moved across this point.
11659 (define_insn "blockage"
11660 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
11663 [(set_attr "length" "0")])
11665 ;; Do not schedule instructions accessing memory across this point.
11667 (define_expand "memory_blockage"
11668 [(set (match_dup 0)
11669 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11672 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
11673 MEM_VOLATILE_P (operands[0]) = 1;
11676 (define_insn "*memory_blockage"
11677 [(set (match_operand:BLK 0 "" "")
11678 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
11681 [(set_attr "length" "0")])
11683 ;; As USE insns aren't meaningful after reload, this is used instead
11684 ;; to prevent deleting instructions setting registers for PIC code
11685 (define_insn "prologue_use"
11686 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
11689 [(set_attr "length" "0")])
11691 ;; Insn emitted into the body of a function to return from a function.
11692 ;; This is only done if the function's epilogue is known to be simple.
11693 ;; See comments for ix86_can_use_return_insn_p in i386.c.
11695 (define_expand "return"
11697 "ix86_can_use_return_insn_p ()"
11699 ix86_maybe_emit_epilogue_vzeroupper ();
11700 if (crtl->args.pops_args)
11702 rtx popc = GEN_INT (crtl->args.pops_args);
11703 emit_jump_insn (gen_simple_return_pop_internal (popc));
11708 ;; We need to disable this for TARGET_SEH, as otherwise
11709 ;; shrink-wrapped prologue gets enabled too. This might exceed
11710 ;; the maximum size of prologue in unwind information.
11712 (define_expand "simple_return"
11716 ix86_maybe_emit_epilogue_vzeroupper ();
11717 if (crtl->args.pops_args)
11719 rtx popc = GEN_INT (crtl->args.pops_args);
11720 emit_jump_insn (gen_simple_return_pop_internal (popc));
11725 (define_insn "simple_return_internal"
11729 [(set_attr "length" "1")
11730 (set_attr "atom_unit" "jeu")
11731 (set_attr "length_immediate" "0")
11732 (set_attr "modrm" "0")])
11734 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
11735 ;; instruction Athlon and K8 have.
11737 (define_insn "simple_return_internal_long"
11739 (unspec [(const_int 0)] UNSPEC_REP)]
11742 [(set_attr "length" "2")
11743 (set_attr "atom_unit" "jeu")
11744 (set_attr "length_immediate" "0")
11745 (set_attr "prefix_rep" "1")
11746 (set_attr "modrm" "0")])
11748 (define_insn "simple_return_pop_internal"
11750 (use (match_operand:SI 0 "const_int_operand" ""))]
11753 [(set_attr "length" "3")
11754 (set_attr "atom_unit" "jeu")
11755 (set_attr "length_immediate" "2")
11756 (set_attr "modrm" "0")])
11758 (define_insn "simple_return_indirect_internal"
11760 (use (match_operand:SI 0 "register_operand" "r"))]
11763 [(set_attr "type" "ibr")
11764 (set_attr "length_immediate" "0")])
11770 [(set_attr "length" "1")
11771 (set_attr "length_immediate" "0")
11772 (set_attr "modrm" "0")])
11774 ;; Generate nops. Operand 0 is the number of nops, up to 8.
11775 (define_insn "nops"
11776 [(unspec_volatile [(match_operand 0 "const_int_operand" "")]
11780 int num = INTVAL (operands[0]);
11782 gcc_assert (num >= 1 && num <= 8);
11785 fputs ("\tnop\n", asm_out_file);
11789 [(set (attr "length") (symbol_ref "INTVAL (operands[0])"))
11790 (set_attr "length_immediate" "0")
11791 (set_attr "modrm" "0")])
11793 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
11794 ;; branch prediction penalty for the third jump in a 16-byte
11798 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
11801 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
11802 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
11804 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
11805 The align insn is used to avoid 3 jump instructions in the row to improve
11806 branch prediction and the benefits hardly outweigh the cost of extra 8
11807 nops on the average inserted by full alignment pseudo operation. */
11811 [(set_attr "length" "16")])
11813 (define_expand "prologue"
11816 "ix86_expand_prologue (); DONE;")
11818 (define_insn "set_got"
11819 [(set (match_operand:SI 0 "register_operand" "=r")
11820 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
11821 (clobber (reg:CC FLAGS_REG))]
11823 "* return output_set_got (operands[0], NULL_RTX);"
11824 [(set_attr "type" "multi")
11825 (set_attr "length" "12")])
11827 (define_insn "set_got_labelled"
11828 [(set (match_operand:SI 0 "register_operand" "=r")
11829 (unspec:SI [(label_ref (match_operand 1 "" ""))]
11831 (clobber (reg:CC FLAGS_REG))]
11833 "* return output_set_got (operands[0], operands[1]);"
11834 [(set_attr "type" "multi")
11835 (set_attr "length" "12")])
11837 (define_insn "set_got_rex64"
11838 [(set (match_operand:DI 0 "register_operand" "=r")
11839 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
11841 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
11842 [(set_attr "type" "lea")
11843 (set_attr "length_address" "4")
11844 (set_attr "mode" "DI")])
11846 (define_insn "set_rip_rex64"
11847 [(set (match_operand:DI 0 "register_operand" "=r")
11848 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
11850 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
11851 [(set_attr "type" "lea")
11852 (set_attr "length_address" "4")
11853 (set_attr "mode" "DI")])
11855 (define_insn "set_got_offset_rex64"
11856 [(set (match_operand:DI 0 "register_operand" "=r")
11858 [(label_ref (match_operand 1 "" ""))]
11859 UNSPEC_SET_GOT_OFFSET))]
11861 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
11862 [(set_attr "type" "imov")
11863 (set_attr "length_immediate" "0")
11864 (set_attr "length_address" "8")
11865 (set_attr "mode" "DI")])
11867 (define_expand "epilogue"
11870 "ix86_expand_epilogue (1); DONE;")
11872 (define_expand "sibcall_epilogue"
11875 "ix86_expand_epilogue (0); DONE;")
11877 (define_expand "eh_return"
11878 [(use (match_operand 0 "register_operand" ""))]
11881 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
11883 /* Tricky bit: we write the address of the handler to which we will
11884 be returning into someone else's stack frame, one word below the
11885 stack address we wish to restore. */
11886 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
11887 tmp = plus_constant (tmp, -UNITS_PER_WORD);
11888 tmp = gen_rtx_MEM (Pmode, tmp);
11889 emit_move_insn (tmp, ra);
11891 emit_jump_insn (gen_eh_return_internal ());
11896 (define_insn_and_split "eh_return_internal"
11900 "epilogue_completed"
11902 "ix86_expand_epilogue (2); DONE;")
11904 (define_insn "leave"
11905 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
11906 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
11907 (clobber (mem:BLK (scratch)))]
11910 [(set_attr "type" "leave")])
11912 (define_insn "leave_rex64"
11913 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
11914 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
11915 (clobber (mem:BLK (scratch)))]
11918 [(set_attr "type" "leave")])
11920 ;; Handle -fsplit-stack.
11922 (define_expand "split_stack_prologue"
11926 ix86_expand_split_stack_prologue ();
11930 ;; In order to support the call/return predictor, we use a return
11931 ;; instruction which the middle-end doesn't see.
11932 (define_insn "split_stack_return"
11933 [(unspec_volatile [(match_operand:SI 0 "const_int_operand" "")]
11934 UNSPECV_SPLIT_STACK_RETURN)]
11937 if (operands[0] == const0_rtx)
11942 [(set_attr "atom_unit" "jeu")
11943 (set_attr "modrm" "0")
11944 (set (attr "length")
11945 (if_then_else (match_operand:SI 0 "const0_operand" "")
11948 (set (attr "length_immediate")
11949 (if_then_else (match_operand:SI 0 "const0_operand" "")
11953 ;; If there are operand 0 bytes available on the stack, jump to
11956 (define_expand "split_stack_space_check"
11957 [(set (pc) (if_then_else
11958 (ltu (minus (reg SP_REG)
11959 (match_operand 0 "register_operand" ""))
11960 (unspec [(const_int 0)] UNSPEC_STACK_CHECK))
11961 (label_ref (match_operand 1 "" ""))
11965 rtx reg, size, limit;
11967 reg = gen_reg_rtx (Pmode);
11968 size = force_reg (Pmode, operands[0]);
11969 emit_insn (gen_sub3_insn (reg, stack_pointer_rtx, size));
11970 limit = gen_rtx_UNSPEC (Pmode, gen_rtvec (1, const0_rtx),
11971 UNSPEC_STACK_CHECK);
11972 limit = gen_rtx_MEM (Pmode, gen_rtx_CONST (Pmode, limit));
11973 ix86_expand_branch (GEU, reg, limit, operands[1]);
11978 ;; Bit manipulation instructions.
11980 (define_expand "ffs<mode>2"
11981 [(set (match_dup 2) (const_int -1))
11982 (parallel [(set (reg:CCZ FLAGS_REG)
11984 (match_operand:SWI48 1 "nonimmediate_operand" "")
11986 (set (match_operand:SWI48 0 "register_operand" "")
11987 (ctz:SWI48 (match_dup 1)))])
11988 (set (match_dup 0) (if_then_else:SWI48
11989 (eq (reg:CCZ FLAGS_REG) (const_int 0))
11992 (parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (const_int 1)))
11993 (clobber (reg:CC FLAGS_REG))])]
11996 if (<MODE>mode == SImode && !TARGET_CMOVE)
11998 emit_insn (gen_ffssi2_no_cmove (operands[0], operands [1]));
12001 operands[2] = gen_reg_rtx (<MODE>mode);
12004 (define_insn_and_split "ffssi2_no_cmove"
12005 [(set (match_operand:SI 0 "register_operand" "=r")
12006 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
12007 (clobber (match_scratch:SI 2 "=&q"))
12008 (clobber (reg:CC FLAGS_REG))]
12011 "&& reload_completed"
12012 [(parallel [(set (reg:CCZ FLAGS_REG)
12013 (compare:CCZ (match_dup 1) (const_int 0)))
12014 (set (match_dup 0) (ctz:SI (match_dup 1)))])
12015 (set (strict_low_part (match_dup 3))
12016 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
12017 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
12018 (clobber (reg:CC FLAGS_REG))])
12019 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
12020 (clobber (reg:CC FLAGS_REG))])
12021 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
12022 (clobber (reg:CC FLAGS_REG))])]
12024 operands[3] = gen_lowpart (QImode, operands[2]);
12025 ix86_expand_clear (operands[2]);
12028 (define_insn "*ffs<mode>_1"
12029 [(set (reg:CCZ FLAGS_REG)
12030 (compare:CCZ (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12032 (set (match_operand:SWI48 0 "register_operand" "=r")
12033 (ctz:SWI48 (match_dup 1)))]
12035 "bsf{<imodesuffix>}\t{%1, %0|%0, %1}"
12036 [(set_attr "type" "alu1")
12037 (set_attr "prefix_0f" "1")
12038 (set_attr "mode" "<MODE>")])
12040 (define_insn "ctz<mode>2"
12041 [(set (match_operand:SWI248 0 "register_operand" "=r")
12042 (ctz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12043 (clobber (reg:CC FLAGS_REG))]
12047 return "tzcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12049 return "bsf{<imodesuffix>}\t{%1, %0|%0, %1}";
12051 [(set_attr "type" "alu1")
12052 (set_attr "prefix_0f" "1")
12053 (set (attr "prefix_rep") (symbol_ref "TARGET_BMI"))
12054 (set_attr "mode" "<MODE>")])
12056 (define_expand "clz<mode>2"
12058 [(set (match_operand:SWI248 0 "register_operand" "")
12061 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" ""))))
12062 (clobber (reg:CC FLAGS_REG))])
12064 [(set (match_dup 0) (xor:SWI248 (match_dup 0) (match_dup 2)))
12065 (clobber (reg:CC FLAGS_REG))])]
12070 emit_insn (gen_clz<mode>2_lzcnt (operands[0], operands[1]));
12073 operands[2] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode)-1);
12076 (define_insn "clz<mode>2_lzcnt"
12077 [(set (match_operand:SWI248 0 "register_operand" "=r")
12078 (clz:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12079 (clobber (reg:CC FLAGS_REG))]
12081 "lzcnt{<imodesuffix>}\t{%1, %0|%0, %1}"
12082 [(set_attr "prefix_rep" "1")
12083 (set_attr "type" "bitmanip")
12084 (set_attr "mode" "<MODE>")])
12086 ;; BMI instructions.
12087 (define_insn "*bmi_andn_<mode>"
12088 [(set (match_operand:SWI48 0 "register_operand" "=r")
12091 (match_operand:SWI48 1 "register_operand" "r"))
12092 (match_operand:SWI48 2 "nonimmediate_operand" "rm")))
12093 (clobber (reg:CC FLAGS_REG))]
12095 "andn\t{%2, %1, %0|%0, %1, %2}"
12096 [(set_attr "type" "bitmanip")
12097 (set_attr "mode" "<MODE>")])
12099 (define_insn "bmi_bextr_<mode>"
12100 [(set (match_operand:SWI48 0 "register_operand" "=r")
12101 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12102 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12104 (clobber (reg:CC FLAGS_REG))]
12106 "bextr\t{%2, %1, %0|%0, %1, %2}"
12107 [(set_attr "type" "bitmanip")
12108 (set_attr "mode" "<MODE>")])
12110 (define_insn "*bmi_blsi_<mode>"
12111 [(set (match_operand:SWI48 0 "register_operand" "=r")
12114 (match_operand:SWI48 1 "nonimmediate_operand" "rm"))
12116 (clobber (reg:CC FLAGS_REG))]
12118 "blsi\t{%1, %0|%0, %1}"
12119 [(set_attr "type" "bitmanip")
12120 (set_attr "mode" "<MODE>")])
12122 (define_insn "*bmi_blsmsk_<mode>"
12123 [(set (match_operand:SWI48 0 "register_operand" "=r")
12126 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12129 (clobber (reg:CC FLAGS_REG))]
12131 "blsmsk\t{%1, %0|%0, %1}"
12132 [(set_attr "type" "bitmanip")
12133 (set_attr "mode" "<MODE>")])
12135 (define_insn "*bmi_blsr_<mode>"
12136 [(set (match_operand:SWI48 0 "register_operand" "=r")
12139 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12142 (clobber (reg:CC FLAGS_REG))]
12144 "blsr\t{%1, %0|%0, %1}"
12145 [(set_attr "type" "bitmanip")
12146 (set_attr "mode" "<MODE>")])
12148 ;; BMI2 instructions.
12149 (define_insn "bmi2_bzhi_<mode>3"
12150 [(set (match_operand:SWI48 0 "register_operand" "=r")
12151 (and:SWI48 (match_operand:SWI48 1 "register_operand" "r")
12152 (lshiftrt:SWI48 (const_int -1)
12153 (match_operand:SWI48 2 "nonimmediate_operand" "rm"))))
12154 (clobber (reg:CC FLAGS_REG))]
12156 "bzhi\t{%2, %1, %0|%0, %1, %2}"
12157 [(set_attr "type" "bitmanip")
12158 (set_attr "prefix" "vex")
12159 (set_attr "mode" "<MODE>")])
12161 (define_insn "bmi2_pdep_<mode>3"
12162 [(set (match_operand:SWI48 0 "register_operand" "=r")
12163 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12164 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12167 "pdep\t{%2, %1, %0|%0, %1, %2}"
12168 [(set_attr "type" "bitmanip")
12169 (set_attr "prefix" "vex")
12170 (set_attr "mode" "<MODE>")])
12172 (define_insn "bmi2_pext_<mode>3"
12173 [(set (match_operand:SWI48 0 "register_operand" "=r")
12174 (unspec:SWI48 [(match_operand:SWI48 1 "register_operand" "r")
12175 (match_operand:SWI48 2 "nonimmediate_operand" "rm")]
12178 "pext\t{%2, %1, %0|%0, %1, %2}"
12179 [(set_attr "type" "bitmanip")
12180 (set_attr "prefix" "vex")
12181 (set_attr "mode" "<MODE>")])
12183 ;; TBM instructions.
12184 (define_insn "tbm_bextri_<mode>"
12185 [(set (match_operand:SWI48 0 "register_operand" "=r")
12186 (zero_extract:SWI48
12187 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12188 (match_operand:SWI48 2 "const_0_to_255_operand" "n")
12189 (match_operand:SWI48 3 "const_0_to_255_operand" "n")))
12190 (clobber (reg:CC FLAGS_REG))]
12193 operands[2] = GEN_INT (INTVAL (operands[2]) << 8 | INTVAL (operands[3]));
12194 return "bextr\t{%2, %1, %0|%0, %1, %2}";
12196 [(set_attr "type" "bitmanip")
12197 (set_attr "mode" "<MODE>")])
12199 (define_insn "*tbm_blcfill_<mode>"
12200 [(set (match_operand:SWI48 0 "register_operand" "=r")
12203 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12206 (clobber (reg:CC FLAGS_REG))]
12208 "blcfill\t{%1, %0|%0, %1}"
12209 [(set_attr "type" "bitmanip")
12210 (set_attr "mode" "<MODE>")])
12212 (define_insn "*tbm_blci_<mode>"
12213 [(set (match_operand:SWI48 0 "register_operand" "=r")
12217 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12220 (clobber (reg:CC FLAGS_REG))]
12222 "blci\t{%1, %0|%0, %1}"
12223 [(set_attr "type" "bitmanip")
12224 (set_attr "mode" "<MODE>")])
12226 (define_insn "*tbm_blcic_<mode>"
12227 [(set (match_operand:SWI48 0 "register_operand" "=r")
12230 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12234 (clobber (reg:CC FLAGS_REG))]
12236 "blcic\t{%1, %0|%0, %1}"
12237 [(set_attr "type" "bitmanip")
12238 (set_attr "mode" "<MODE>")])
12240 (define_insn "*tbm_blcmsk_<mode>"
12241 [(set (match_operand:SWI48 0 "register_operand" "=r")
12244 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12247 (clobber (reg:CC FLAGS_REG))]
12249 "blcmsk\t{%1, %0|%0, %1}"
12250 [(set_attr "type" "bitmanip")
12251 (set_attr "mode" "<MODE>")])
12253 (define_insn "*tbm_blcs_<mode>"
12254 [(set (match_operand:SWI48 0 "register_operand" "=r")
12257 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12260 (clobber (reg:CC FLAGS_REG))]
12262 "blcs\t{%1, %0|%0, %1}"
12263 [(set_attr "type" "bitmanip")
12264 (set_attr "mode" "<MODE>")])
12266 (define_insn "*tbm_blsfill_<mode>"
12267 [(set (match_operand:SWI48 0 "register_operand" "=r")
12270 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12273 (clobber (reg:CC FLAGS_REG))]
12275 "blsfill\t{%1, %0|%0, %1}"
12276 [(set_attr "type" "bitmanip")
12277 (set_attr "mode" "<MODE>")])
12279 (define_insn "*tbm_blsic_<mode>"
12280 [(set (match_operand:SWI48 0 "register_operand" "=r")
12283 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12287 (clobber (reg:CC FLAGS_REG))]
12289 "blsic\t{%1, %0|%0, %1}"
12290 [(set_attr "type" "bitmanip")
12291 (set_attr "mode" "<MODE>")])
12293 (define_insn "*tbm_t1mskc_<mode>"
12294 [(set (match_operand:SWI48 0 "register_operand" "=r")
12297 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12301 (clobber (reg:CC FLAGS_REG))]
12303 "t1mskc\t{%1, %0|%0, %1}"
12304 [(set_attr "type" "bitmanip")
12305 (set_attr "mode" "<MODE>")])
12307 (define_insn "*tbm_tzmsk_<mode>"
12308 [(set (match_operand:SWI48 0 "register_operand" "=r")
12311 (match_operand:SWI48 1 "nonimmediate_operand" "rm")
12315 (clobber (reg:CC FLAGS_REG))]
12317 "tzmsk\t{%1, %0|%0, %1}"
12318 [(set_attr "type" "bitmanip")
12319 (set_attr "mode" "<MODE>")])
12321 (define_insn "bsr_rex64"
12322 [(set (match_operand:DI 0 "register_operand" "=r")
12323 (minus:DI (const_int 63)
12324 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
12325 (clobber (reg:CC FLAGS_REG))]
12327 "bsr{q}\t{%1, %0|%0, %1}"
12328 [(set_attr "type" "alu1")
12329 (set_attr "prefix_0f" "1")
12330 (set_attr "mode" "DI")])
12333 [(set (match_operand:SI 0 "register_operand" "=r")
12334 (minus:SI (const_int 31)
12335 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
12336 (clobber (reg:CC FLAGS_REG))]
12338 "bsr{l}\t{%1, %0|%0, %1}"
12339 [(set_attr "type" "alu1")
12340 (set_attr "prefix_0f" "1")
12341 (set_attr "mode" "SI")])
12343 (define_insn "*bsrhi"
12344 [(set (match_operand:HI 0 "register_operand" "=r")
12345 (minus:HI (const_int 15)
12346 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
12347 (clobber (reg:CC FLAGS_REG))]
12349 "bsr{w}\t{%1, %0|%0, %1}"
12350 [(set_attr "type" "alu1")
12351 (set_attr "prefix_0f" "1")
12352 (set_attr "mode" "HI")])
12354 (define_insn "popcount<mode>2"
12355 [(set (match_operand:SWI248 0 "register_operand" "=r")
12357 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
12358 (clobber (reg:CC FLAGS_REG))]
12362 return "popcnt\t{%1, %0|%0, %1}";
12364 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12367 [(set_attr "prefix_rep" "1")
12368 (set_attr "type" "bitmanip")
12369 (set_attr "mode" "<MODE>")])
12371 (define_insn "*popcount<mode>2_cmp"
12372 [(set (reg FLAGS_REG)
12375 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
12377 (set (match_operand:SWI248 0 "register_operand" "=r")
12378 (popcount:SWI248 (match_dup 1)))]
12379 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12382 return "popcnt\t{%1, %0|%0, %1}";
12384 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
12387 [(set_attr "prefix_rep" "1")
12388 (set_attr "type" "bitmanip")
12389 (set_attr "mode" "<MODE>")])
12391 (define_insn "*popcountsi2_cmp_zext"
12392 [(set (reg FLAGS_REG)
12394 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
12396 (set (match_operand:DI 0 "register_operand" "=r")
12397 (zero_extend:DI(popcount:SI (match_dup 1))))]
12398 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
12401 return "popcnt\t{%1, %0|%0, %1}";
12403 return "popcnt{l}\t{%1, %0|%0, %1}";
12406 [(set_attr "prefix_rep" "1")
12407 (set_attr "type" "bitmanip")
12408 (set_attr "mode" "SI")])
12410 (define_expand "bswap<mode>2"
12411 [(set (match_operand:SWI48 0 "register_operand" "")
12412 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "")))]
12415 if (<MODE>mode == SImode && !(TARGET_BSWAP || TARGET_MOVBE))
12417 rtx x = operands[0];
12419 emit_move_insn (x, operands[1]);
12420 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12421 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
12422 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
12427 (define_insn "*bswap<mode>2_movbe"
12428 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,r,m")
12429 (bswap:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "0,m,r")))]
12431 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12434 movbe\t{%1, %0|%0, %1}
12435 movbe\t{%1, %0|%0, %1}"
12436 [(set_attr "type" "bitmanip,imov,imov")
12437 (set_attr "modrm" "0,1,1")
12438 (set_attr "prefix_0f" "*,1,1")
12439 (set_attr "prefix_extra" "*,1,1")
12440 (set_attr "mode" "<MODE>")])
12442 (define_insn "*bswap<mode>2_1"
12443 [(set (match_operand:SWI48 0 "register_operand" "=r")
12444 (bswap:SWI48 (match_operand:SWI48 1 "register_operand" "0")))]
12447 [(set_attr "type" "bitmanip")
12448 (set_attr "modrm" "0")
12449 (set_attr "mode" "<MODE>")])
12451 (define_insn "*bswaphi_lowpart_1"
12452 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
12453 (bswap:HI (match_dup 0)))
12454 (clobber (reg:CC FLAGS_REG))]
12455 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
12457 xchg{b}\t{%h0, %b0|%b0, %h0}
12458 rol{w}\t{$8, %0|%0, 8}"
12459 [(set_attr "length" "2,4")
12460 (set_attr "mode" "QI,HI")])
12462 (define_insn "bswaphi_lowpart"
12463 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
12464 (bswap:HI (match_dup 0)))
12465 (clobber (reg:CC FLAGS_REG))]
12467 "rol{w}\t{$8, %0|%0, 8}"
12468 [(set_attr "length" "4")
12469 (set_attr "mode" "HI")])
12471 (define_expand "paritydi2"
12472 [(set (match_operand:DI 0 "register_operand" "")
12473 (parity:DI (match_operand:DI 1 "register_operand" "")))]
12476 rtx scratch = gen_reg_rtx (QImode);
12479 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
12480 NULL_RTX, operands[1]));
12482 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12483 gen_rtx_REG (CCmode, FLAGS_REG),
12485 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12488 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
12491 rtx tmp = gen_reg_rtx (SImode);
12493 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
12494 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
12499 (define_expand "paritysi2"
12500 [(set (match_operand:SI 0 "register_operand" "")
12501 (parity:SI (match_operand:SI 1 "register_operand" "")))]
12504 rtx scratch = gen_reg_rtx (QImode);
12507 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
12509 cond = gen_rtx_fmt_ee (ORDERED, QImode,
12510 gen_rtx_REG (CCmode, FLAGS_REG),
12512 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
12514 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
12518 (define_insn_and_split "paritydi2_cmp"
12519 [(set (reg:CC FLAGS_REG)
12520 (unspec:CC [(match_operand:DI 3 "register_operand" "0")]
12522 (clobber (match_scratch:DI 0 "=r"))
12523 (clobber (match_scratch:SI 1 "=&r"))
12524 (clobber (match_scratch:HI 2 "=Q"))]
12527 "&& reload_completed"
12529 [(set (match_dup 1)
12530 (xor:SI (match_dup 1) (match_dup 4)))
12531 (clobber (reg:CC FLAGS_REG))])
12533 [(set (reg:CC FLAGS_REG)
12534 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12535 (clobber (match_dup 1))
12536 (clobber (match_dup 2))])]
12538 operands[4] = gen_lowpart (SImode, operands[3]);
12542 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
12543 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
12546 operands[1] = gen_highpart (SImode, operands[3]);
12549 (define_insn_and_split "paritysi2_cmp"
12550 [(set (reg:CC FLAGS_REG)
12551 (unspec:CC [(match_operand:SI 2 "register_operand" "0")]
12553 (clobber (match_scratch:SI 0 "=r"))
12554 (clobber (match_scratch:HI 1 "=&Q"))]
12557 "&& reload_completed"
12559 [(set (match_dup 1)
12560 (xor:HI (match_dup 1) (match_dup 3)))
12561 (clobber (reg:CC FLAGS_REG))])
12563 [(set (reg:CC FLAGS_REG)
12564 (unspec:CC [(match_dup 1)] UNSPEC_PARITY))
12565 (clobber (match_dup 1))])]
12567 operands[3] = gen_lowpart (HImode, operands[2]);
12569 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
12570 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
12573 (define_insn "*parityhi2_cmp"
12574 [(set (reg:CC FLAGS_REG)
12575 (unspec:CC [(match_operand:HI 1 "register_operand" "0")]
12577 (clobber (match_scratch:HI 0 "=Q"))]
12579 "xor{b}\t{%h0, %b0|%b0, %h0}"
12580 [(set_attr "length" "2")
12581 (set_attr "mode" "HI")])
12584 ;; Thread-local storage patterns for ELF.
12586 ;; Note that these code sequences must appear exactly as shown
12587 ;; in order to allow linker relaxation.
12589 (define_insn "*tls_global_dynamic_32_gnu"
12590 [(set (match_operand:SI 0 "register_operand" "=a")
12592 [(match_operand:SI 1 "register_operand" "b")
12593 (match_operand:SI 2 "tls_symbolic_operand" "")
12594 (match_operand:SI 3 "constant_call_address_operand" "z")]
12596 (clobber (match_scratch:SI 4 "=d"))
12597 (clobber (match_scratch:SI 5 "=c"))
12598 (clobber (reg:CC FLAGS_REG))]
12599 "!TARGET_64BIT && TARGET_GNU_TLS"
12602 ("lea{l}\t{%E2@tlsgd(,%1,1), %0|%0, %E2@tlsgd[%1*1]}", operands);
12603 if (TARGET_SUN_TLS)
12604 #ifdef HAVE_AS_IX86_TLSGDPLT
12605 return "call\t%a2@tlsgdplt";
12607 return "call\t%p3@plt";
12609 return "call\t%P3";
12611 [(set_attr "type" "multi")
12612 (set_attr "length" "12")])
12614 (define_expand "tls_global_dynamic_32"
12616 [(set (match_operand:SI 0 "register_operand" "")
12617 (unspec:SI [(match_operand:SI 2 "register_operand" "")
12618 (match_operand:SI 1 "tls_symbolic_operand" "")
12619 (match_operand:SI 3 "constant_call_address_operand" "")]
12621 (clobber (match_scratch:SI 4 ""))
12622 (clobber (match_scratch:SI 5 ""))
12623 (clobber (reg:CC FLAGS_REG))])])
12625 (define_insn "*tls_global_dynamic_64"
12626 [(set (match_operand:DI 0 "register_operand" "=a")
12628 (mem:QI (match_operand:DI 2 "constant_call_address_operand" "z"))
12629 (match_operand:DI 3 "" "")))
12630 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12635 fputs (ASM_BYTE "0x66\n", asm_out_file);
12637 ("lea{q}\t{%E1@tlsgd(%%rip), %%rdi|rdi, %E1@tlsgd[rip]}", operands);
12638 fputs (ASM_SHORT "0x6666\n", asm_out_file);
12639 fputs ("\trex64\n", asm_out_file);
12640 if (TARGET_SUN_TLS)
12641 return "call\t%p2@plt";
12642 return "call\t%P2";
12644 [(set_attr "type" "multi")
12645 (set (attr "length")
12646 (symbol_ref "TARGET_X32 ? 15 : 16"))])
12648 (define_expand "tls_global_dynamic_64"
12650 [(set (match_operand:DI 0 "register_operand" "")
12652 (mem:QI (match_operand:DI 2 "constant_call_address_operand" ""))
12654 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12657 (define_insn "*tls_local_dynamic_base_32_gnu"
12658 [(set (match_operand:SI 0 "register_operand" "=a")
12660 [(match_operand:SI 1 "register_operand" "b")
12661 (match_operand:SI 2 "constant_call_address_operand" "z")]
12662 UNSPEC_TLS_LD_BASE))
12663 (clobber (match_scratch:SI 3 "=d"))
12664 (clobber (match_scratch:SI 4 "=c"))
12665 (clobber (reg:CC FLAGS_REG))]
12666 "!TARGET_64BIT && TARGET_GNU_TLS"
12669 ("lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}", operands);
12670 if (TARGET_SUN_TLS)
12671 #ifdef HAVE_AS_IX86_TLSLDMPLT
12672 return "call\t%&@tlsldmplt";
12674 return "call\t%p2@plt";
12676 return "call\t%P2";
12678 [(set_attr "type" "multi")
12679 (set_attr "length" "11")])
12681 (define_expand "tls_local_dynamic_base_32"
12683 [(set (match_operand:SI 0 "register_operand" "")
12685 [(match_operand:SI 1 "register_operand" "")
12686 (match_operand:SI 2 "constant_call_address_operand" "")]
12687 UNSPEC_TLS_LD_BASE))
12688 (clobber (match_scratch:SI 3 ""))
12689 (clobber (match_scratch:SI 4 ""))
12690 (clobber (reg:CC FLAGS_REG))])])
12692 (define_insn "*tls_local_dynamic_base_64"
12693 [(set (match_operand:DI 0 "register_operand" "=a")
12695 (mem:QI (match_operand:DI 1 "constant_call_address_operand" "z"))
12696 (match_operand:DI 2 "" "")))
12697 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
12701 ("lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}", operands);
12702 if (TARGET_SUN_TLS)
12703 return "call\t%p1@plt";
12704 return "call\t%P1";
12706 [(set_attr "type" "multi")
12707 (set_attr "length" "12")])
12709 (define_expand "tls_local_dynamic_base_64"
12711 [(set (match_operand:DI 0 "register_operand" "")
12713 (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
12715 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])])
12717 ;; Local dynamic of a single variable is a lose. Show combine how
12718 ;; to convert that back to global dynamic.
12720 (define_insn_and_split "*tls_local_dynamic_32_once"
12721 [(set (match_operand:SI 0 "register_operand" "=a")
12723 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
12724 (match_operand:SI 2 "constant_call_address_operand" "z")]
12725 UNSPEC_TLS_LD_BASE)
12726 (const:SI (unspec:SI
12727 [(match_operand:SI 3 "tls_symbolic_operand" "")]
12729 (clobber (match_scratch:SI 4 "=d"))
12730 (clobber (match_scratch:SI 5 "=c"))
12731 (clobber (reg:CC FLAGS_REG))]
12736 [(set (match_dup 0)
12737 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
12739 (clobber (match_dup 4))
12740 (clobber (match_dup 5))
12741 (clobber (reg:CC FLAGS_REG))])])
12743 ;; Segment register for the thread base ptr load
12744 (define_mode_attr tp_seg [(SI "gs") (DI "fs")])
12746 ;; Load and add the thread base pointer from %<tp_seg>:0.
12747 (define_insn "*load_tp_x32"
12748 [(set (match_operand:SI 0 "register_operand" "=r")
12749 (unspec:SI [(const_int 0)] UNSPEC_TP))]
12751 "mov{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12752 [(set_attr "type" "imov")
12753 (set_attr "modrm" "0")
12754 (set_attr "length" "7")
12755 (set_attr "memory" "load")
12756 (set_attr "imm_disp" "false")])
12758 (define_insn "*load_tp_x32_zext"
12759 [(set (match_operand:DI 0 "register_operand" "=r")
12760 (zero_extend:DI (unspec:SI [(const_int 0)] UNSPEC_TP)))]
12762 "mov{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12763 [(set_attr "type" "imov")
12764 (set_attr "modrm" "0")
12765 (set_attr "length" "7")
12766 (set_attr "memory" "load")
12767 (set_attr "imm_disp" "false")])
12769 (define_insn "*load_tp_<mode>"
12770 [(set (match_operand:P 0 "register_operand" "=r")
12771 (unspec:P [(const_int 0)] UNSPEC_TP))]
12773 "mov{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12774 [(set_attr "type" "imov")
12775 (set_attr "modrm" "0")
12776 (set_attr "length" "7")
12777 (set_attr "memory" "load")
12778 (set_attr "imm_disp" "false")])
12780 (define_insn "*add_tp_x32"
12781 [(set (match_operand:SI 0 "register_operand" "=r")
12782 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12783 (match_operand:SI 1 "register_operand" "0")))
12784 (clobber (reg:CC FLAGS_REG))]
12786 "add{l}\t{%%fs:0, %0|%0, DWORD PTR fs:0}"
12787 [(set_attr "type" "alu")
12788 (set_attr "modrm" "0")
12789 (set_attr "length" "7")
12790 (set_attr "memory" "load")
12791 (set_attr "imm_disp" "false")])
12793 (define_insn "*add_tp_x32_zext"
12794 [(set (match_operand:DI 0 "register_operand" "=r")
12796 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
12797 (match_operand:SI 1 "register_operand" "0"))))
12798 (clobber (reg:CC FLAGS_REG))]
12800 "add{l}\t{%%fs:0, %k0|%k0, DWORD PTR fs:0}"
12801 [(set_attr "type" "alu")
12802 (set_attr "modrm" "0")
12803 (set_attr "length" "7")
12804 (set_attr "memory" "load")
12805 (set_attr "imm_disp" "false")])
12807 (define_insn "*add_tp_<mode>"
12808 [(set (match_operand:P 0 "register_operand" "=r")
12809 (plus:P (unspec:P [(const_int 0)] UNSPEC_TP)
12810 (match_operand:P 1 "register_operand" "0")))
12811 (clobber (reg:CC FLAGS_REG))]
12813 "add{<imodesuffix>}\t{%%<tp_seg>:0, %0|%0, <iptrsize> PTR <tp_seg>:0}"
12814 [(set_attr "type" "alu")
12815 (set_attr "modrm" "0")
12816 (set_attr "length" "7")
12817 (set_attr "memory" "load")
12818 (set_attr "imm_disp" "false")])
12820 ;; The Sun linker took the AMD64 TLS spec literally and can only handle
12821 ;; %rax as destination of the initial executable code sequence.
12822 (define_insn "tls_initial_exec_64_sun"
12823 [(set (match_operand:DI 0 "register_operand" "=a")
12825 [(match_operand:DI 1 "tls_symbolic_operand" "")]
12826 UNSPEC_TLS_IE_SUN))
12827 (clobber (reg:CC FLAGS_REG))]
12828 "TARGET_64BIT && TARGET_SUN_TLS"
12831 ("mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}", operands);
12832 return "add{q}\t{%a1@gottpoff(%%rip), %0|%0, %a1@gottpoff[rip]}";
12834 [(set_attr "type" "multi")])
12836 ;; GNU2 TLS patterns can be split.
12838 (define_expand "tls_dynamic_gnu2_32"
12839 [(set (match_dup 3)
12840 (plus:SI (match_operand:SI 2 "register_operand" "")
12842 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
12845 [(set (match_operand:SI 0 "register_operand" "")
12846 (unspec:SI [(match_dup 1) (match_dup 3)
12847 (match_dup 2) (reg:SI SP_REG)]
12849 (clobber (reg:CC FLAGS_REG))])]
12850 "!TARGET_64BIT && TARGET_GNU2_TLS"
12852 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12853 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12856 (define_insn "*tls_dynamic_gnu2_lea_32"
12857 [(set (match_operand:SI 0 "register_operand" "=r")
12858 (plus:SI (match_operand:SI 1 "register_operand" "b")
12860 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
12861 UNSPEC_TLSDESC))))]
12862 "!TARGET_64BIT && TARGET_GNU2_TLS"
12863 "lea{l}\t{%E2@TLSDESC(%1), %0|%0, %E2@TLSDESC[%1]}"
12864 [(set_attr "type" "lea")
12865 (set_attr "mode" "SI")
12866 (set_attr "length" "6")
12867 (set_attr "length_address" "4")])
12869 (define_insn "*tls_dynamic_gnu2_call_32"
12870 [(set (match_operand:SI 0 "register_operand" "=a")
12871 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
12872 (match_operand:SI 2 "register_operand" "0")
12873 ;; we have to make sure %ebx still points to the GOT
12874 (match_operand:SI 3 "register_operand" "b")
12877 (clobber (reg:CC FLAGS_REG))]
12878 "!TARGET_64BIT && TARGET_GNU2_TLS"
12879 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
12880 [(set_attr "type" "call")
12881 (set_attr "length" "2")
12882 (set_attr "length_address" "0")])
12884 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
12885 [(set (match_operand:SI 0 "register_operand" "=&a")
12887 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
12888 (match_operand:SI 4 "" "")
12889 (match_operand:SI 2 "register_operand" "b")
12892 (const:SI (unspec:SI
12893 [(match_operand:SI 1 "tls_symbolic_operand" "")]
12895 (clobber (reg:CC FLAGS_REG))]
12896 "!TARGET_64BIT && TARGET_GNU2_TLS"
12899 [(set (match_dup 0) (match_dup 5))]
12901 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12902 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
12905 (define_expand "tls_dynamic_gnu2_64"
12906 [(set (match_dup 2)
12907 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12910 [(set (match_operand:DI 0 "register_operand" "")
12911 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
12913 (clobber (reg:CC FLAGS_REG))])]
12914 "TARGET_64BIT && TARGET_GNU2_TLS"
12916 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12917 ix86_tls_descriptor_calls_expanded_in_cfun = true;
12920 (define_insn "*tls_dynamic_gnu2_lea_64"
12921 [(set (match_operand:DI 0 "register_operand" "=r")
12922 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")]
12924 "TARGET_64BIT && TARGET_GNU2_TLS"
12925 "lea{q}\t{%E1@TLSDESC(%%rip), %0|%0, %E1@TLSDESC[rip]}"
12926 [(set_attr "type" "lea")
12927 (set_attr "mode" "DI")
12928 (set_attr "length" "7")
12929 (set_attr "length_address" "4")])
12931 (define_insn "*tls_dynamic_gnu2_call_64"
12932 [(set (match_operand:DI 0 "register_operand" "=a")
12933 (unspec:DI [(match_operand 1 "tls_symbolic_operand" "")
12934 (match_operand:DI 2 "register_operand" "0")
12937 (clobber (reg:CC FLAGS_REG))]
12938 "TARGET_64BIT && TARGET_GNU2_TLS"
12939 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
12940 [(set_attr "type" "call")
12941 (set_attr "length" "2")
12942 (set_attr "length_address" "0")])
12944 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
12945 [(set (match_operand:DI 0 "register_operand" "=&a")
12947 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
12948 (match_operand:DI 3 "" "")
12951 (const:DI (unspec:DI
12952 [(match_operand 1 "tls_symbolic_operand" "")]
12954 (clobber (reg:CC FLAGS_REG))]
12955 "TARGET_64BIT && TARGET_GNU2_TLS"
12958 [(set (match_dup 0) (match_dup 4))]
12960 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
12961 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
12964 ;; These patterns match the binary 387 instructions for addM3, subM3,
12965 ;; mulM3 and divM3. There are three patterns for each of DFmode and
12966 ;; SFmode. The first is the normal insn, the second the same insn but
12967 ;; with one operand a conversion, and the third the same insn but with
12968 ;; the other operand a conversion. The conversion may be SFmode or
12969 ;; SImode if the target mode DFmode, but only SImode if the target mode
12972 ;; Gcc is slightly more smart about handling normal two address instructions
12973 ;; so use special patterns for add and mull.
12975 (define_insn "*fop_<mode>_comm_mixed"
12976 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
12977 (match_operator:MODEF 3 "binary_fp_operator"
12978 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0,x")
12979 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm,xm")]))]
12980 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
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 (eq_attr "alternative" "1,2")
12986 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12987 (const_string "ssemul")
12988 (const_string "sseadd"))
12989 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
12990 (const_string "fmul")
12991 (const_string "fop"))))
12992 (set_attr "isa" "*,noavx,avx")
12993 (set_attr "prefix" "orig,orig,vex")
12994 (set_attr "mode" "<MODE>")])
12996 (define_insn "*fop_<mode>_comm_sse"
12997 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
12998 (match_operator:MODEF 3 "binary_fp_operator"
12999 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
13000 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13001 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13002 && COMMUTATIVE_ARITH_P (operands[3])
13003 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13004 "* return output_387_binary_op (insn, operands);"
13005 [(set (attr "type")
13006 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13007 (const_string "ssemul")
13008 (const_string "sseadd")))
13009 (set_attr "isa" "noavx,avx")
13010 (set_attr "prefix" "orig,vex")
13011 (set_attr "mode" "<MODE>")])
13013 (define_insn "*fop_<mode>_comm_i387"
13014 [(set (match_operand:MODEF 0 "register_operand" "=f")
13015 (match_operator:MODEF 3 "binary_fp_operator"
13016 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
13017 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
13018 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13019 && COMMUTATIVE_ARITH_P (operands[3])
13020 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13021 "* return output_387_binary_op (insn, operands);"
13022 [(set (attr "type")
13023 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
13024 (const_string "fmul")
13025 (const_string "fop")))
13026 (set_attr "mode" "<MODE>")])
13028 (define_insn "*fop_<mode>_1_mixed"
13029 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
13030 (match_operator:MODEF 3 "binary_fp_operator"
13031 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0,x")
13032 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm,xm")]))]
13033 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
13034 && !COMMUTATIVE_ARITH_P (operands[3])
13035 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13036 "* return output_387_binary_op (insn, operands);"
13037 [(set (attr "type")
13038 (cond [(and (eq_attr "alternative" "2,3")
13039 (match_operand:MODEF 3 "mult_operator" ""))
13040 (const_string "ssemul")
13041 (and (eq_attr "alternative" "2,3")
13042 (match_operand:MODEF 3 "div_operator" ""))
13043 (const_string "ssediv")
13044 (eq_attr "alternative" "2,3")
13045 (const_string "sseadd")
13046 (match_operand:MODEF 3 "mult_operator" "")
13047 (const_string "fmul")
13048 (match_operand:MODEF 3 "div_operator" "")
13049 (const_string "fdiv")
13051 (const_string "fop")))
13052 (set_attr "isa" "*,*,noavx,avx")
13053 (set_attr "prefix" "orig,orig,orig,vex")
13054 (set_attr "mode" "<MODE>")])
13056 (define_insn "*rcpsf2_sse"
13057 [(set (match_operand:SF 0 "register_operand" "=x")
13058 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13061 "%vrcpss\t{%1, %d0|%d0, %1}"
13062 [(set_attr "type" "sse")
13063 (set_attr "atom_sse_attr" "rcp")
13064 (set_attr "prefix" "maybe_vex")
13065 (set_attr "mode" "SF")])
13067 (define_insn "*fop_<mode>_1_sse"
13068 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
13069 (match_operator:MODEF 3 "binary_fp_operator"
13070 [(match_operand:MODEF 1 "register_operand" "0,x")
13071 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]))]
13072 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13073 && !COMMUTATIVE_ARITH_P (operands[3])"
13074 "* return output_387_binary_op (insn, operands);"
13075 [(set (attr "type")
13076 (cond [(match_operand:MODEF 3 "mult_operator" "")
13077 (const_string "ssemul")
13078 (match_operand:MODEF 3 "div_operator" "")
13079 (const_string "ssediv")
13081 (const_string "sseadd")))
13082 (set_attr "isa" "noavx,avx")
13083 (set_attr "prefix" "orig,vex")
13084 (set_attr "mode" "<MODE>")])
13086 ;; This pattern is not fully shadowed by the pattern above.
13087 (define_insn "*fop_<mode>_1_i387"
13088 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13089 (match_operator:MODEF 3 "binary_fp_operator"
13090 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
13091 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
13092 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
13093 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13094 && !COMMUTATIVE_ARITH_P (operands[3])
13095 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13096 "* return output_387_binary_op (insn, operands);"
13097 [(set (attr "type")
13098 (cond [(match_operand:MODEF 3 "mult_operator" "")
13099 (const_string "fmul")
13100 (match_operand:MODEF 3 "div_operator" "")
13101 (const_string "fdiv")
13103 (const_string "fop")))
13104 (set_attr "mode" "<MODE>")])
13106 ;; ??? Add SSE splitters for these!
13107 (define_insn "*fop_<MODEF:mode>_2_i387"
13108 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13109 (match_operator:MODEF 3 "binary_fp_operator"
13111 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13112 (match_operand:MODEF 2 "register_operand" "0,0")]))]
13113 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13114 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13115 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13116 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13117 [(set (attr "type")
13118 (cond [(match_operand:MODEF 3 "mult_operator" "")
13119 (const_string "fmul")
13120 (match_operand:MODEF 3 "div_operator" "")
13121 (const_string "fdiv")
13123 (const_string "fop")))
13124 (set_attr "fp_int_src" "true")
13125 (set_attr "mode" "<SWI24:MODE>")])
13127 (define_insn "*fop_<MODEF:mode>_3_i387"
13128 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
13129 (match_operator:MODEF 3 "binary_fp_operator"
13130 [(match_operand:MODEF 1 "register_operand" "0,0")
13132 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13133 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <SWI24:MODE>mode)
13134 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
13135 && (TARGET_USE_<SWI24:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13136 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13137 [(set (attr "type")
13138 (cond [(match_operand:MODEF 3 "mult_operator" "")
13139 (const_string "fmul")
13140 (match_operand:MODEF 3 "div_operator" "")
13141 (const_string "fdiv")
13143 (const_string "fop")))
13144 (set_attr "fp_int_src" "true")
13145 (set_attr "mode" "<MODE>")])
13147 (define_insn "*fop_df_4_i387"
13148 [(set (match_operand:DF 0 "register_operand" "=f,f")
13149 (match_operator:DF 3 "binary_fp_operator"
13151 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
13152 (match_operand:DF 2 "register_operand" "0,f")]))]
13153 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13154 && !(TARGET_SSE2 && TARGET_SSE_MATH)
13155 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
13156 "* return output_387_binary_op (insn, operands);"
13157 [(set (attr "type")
13158 (cond [(match_operand:DF 3 "mult_operator" "")
13159 (const_string "fmul")
13160 (match_operand:DF 3 "div_operator" "")
13161 (const_string "fdiv")
13163 (const_string "fop")))
13164 (set_attr "mode" "SF")])
13166 (define_insn "*fop_df_5_i387"
13167 [(set (match_operand:DF 0 "register_operand" "=f,f")
13168 (match_operator:DF 3 "binary_fp_operator"
13169 [(match_operand:DF 1 "register_operand" "0,f")
13171 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13172 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13173 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13174 "* return output_387_binary_op (insn, operands);"
13175 [(set (attr "type")
13176 (cond [(match_operand:DF 3 "mult_operator" "")
13177 (const_string "fmul")
13178 (match_operand:DF 3 "div_operator" "")
13179 (const_string "fdiv")
13181 (const_string "fop")))
13182 (set_attr "mode" "SF")])
13184 (define_insn "*fop_df_6_i387"
13185 [(set (match_operand:DF 0 "register_operand" "=f,f")
13186 (match_operator:DF 3 "binary_fp_operator"
13188 (match_operand:SF 1 "register_operand" "0,f"))
13190 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
13191 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
13192 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
13193 "* return output_387_binary_op (insn, operands);"
13194 [(set (attr "type")
13195 (cond [(match_operand:DF 3 "mult_operator" "")
13196 (const_string "fmul")
13197 (match_operand:DF 3 "div_operator" "")
13198 (const_string "fdiv")
13200 (const_string "fop")))
13201 (set_attr "mode" "SF")])
13203 (define_insn "*fop_xf_comm_i387"
13204 [(set (match_operand:XF 0 "register_operand" "=f")
13205 (match_operator:XF 3 "binary_fp_operator"
13206 [(match_operand:XF 1 "register_operand" "%0")
13207 (match_operand:XF 2 "register_operand" "f")]))]
13209 && COMMUTATIVE_ARITH_P (operands[3])"
13210 "* return output_387_binary_op (insn, operands);"
13211 [(set (attr "type")
13212 (if_then_else (match_operand:XF 3 "mult_operator" "")
13213 (const_string "fmul")
13214 (const_string "fop")))
13215 (set_attr "mode" "XF")])
13217 (define_insn "*fop_xf_1_i387"
13218 [(set (match_operand:XF 0 "register_operand" "=f,f")
13219 (match_operator:XF 3 "binary_fp_operator"
13220 [(match_operand:XF 1 "register_operand" "0,f")
13221 (match_operand:XF 2 "register_operand" "f,0")]))]
13223 && !COMMUTATIVE_ARITH_P (operands[3])"
13224 "* return output_387_binary_op (insn, operands);"
13225 [(set (attr "type")
13226 (cond [(match_operand:XF 3 "mult_operator" "")
13227 (const_string "fmul")
13228 (match_operand:XF 3 "div_operator" "")
13229 (const_string "fdiv")
13231 (const_string "fop")))
13232 (set_attr "mode" "XF")])
13234 (define_insn "*fop_xf_2_i387"
13235 [(set (match_operand:XF 0 "register_operand" "=f,f")
13236 (match_operator:XF 3 "binary_fp_operator"
13238 (match_operand:SWI24 1 "nonimmediate_operand" "m,?r"))
13239 (match_operand:XF 2 "register_operand" "0,0")]))]
13240 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13241 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13242 [(set (attr "type")
13243 (cond [(match_operand:XF 3 "mult_operator" "")
13244 (const_string "fmul")
13245 (match_operand:XF 3 "div_operator" "")
13246 (const_string "fdiv")
13248 (const_string "fop")))
13249 (set_attr "fp_int_src" "true")
13250 (set_attr "mode" "<MODE>")])
13252 (define_insn "*fop_xf_3_i387"
13253 [(set (match_operand:XF 0 "register_operand" "=f,f")
13254 (match_operator:XF 3 "binary_fp_operator"
13255 [(match_operand:XF 1 "register_operand" "0,0")
13257 (match_operand:SWI24 2 "nonimmediate_operand" "m,?r"))]))]
13258 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
13259 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
13260 [(set (attr "type")
13261 (cond [(match_operand:XF 3 "mult_operator" "")
13262 (const_string "fmul")
13263 (match_operand:XF 3 "div_operator" "")
13264 (const_string "fdiv")
13266 (const_string "fop")))
13267 (set_attr "fp_int_src" "true")
13268 (set_attr "mode" "<MODE>")])
13270 (define_insn "*fop_xf_4_i387"
13271 [(set (match_operand:XF 0 "register_operand" "=f,f")
13272 (match_operator:XF 3 "binary_fp_operator"
13274 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
13275 (match_operand:XF 2 "register_operand" "0,f")]))]
13277 "* return output_387_binary_op (insn, operands);"
13278 [(set (attr "type")
13279 (cond [(match_operand:XF 3 "mult_operator" "")
13280 (const_string "fmul")
13281 (match_operand:XF 3 "div_operator" "")
13282 (const_string "fdiv")
13284 (const_string "fop")))
13285 (set_attr "mode" "<MODE>")])
13287 (define_insn "*fop_xf_5_i387"
13288 [(set (match_operand:XF 0 "register_operand" "=f,f")
13289 (match_operator:XF 3 "binary_fp_operator"
13290 [(match_operand:XF 1 "register_operand" "0,f")
13292 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13294 "* return output_387_binary_op (insn, operands);"
13295 [(set (attr "type")
13296 (cond [(match_operand:XF 3 "mult_operator" "")
13297 (const_string "fmul")
13298 (match_operand:XF 3 "div_operator" "")
13299 (const_string "fdiv")
13301 (const_string "fop")))
13302 (set_attr "mode" "<MODE>")])
13304 (define_insn "*fop_xf_6_i387"
13305 [(set (match_operand:XF 0 "register_operand" "=f,f")
13306 (match_operator:XF 3 "binary_fp_operator"
13308 (match_operand:MODEF 1 "register_operand" "0,f"))
13310 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
13312 "* return output_387_binary_op (insn, operands);"
13313 [(set (attr "type")
13314 (cond [(match_operand:XF 3 "mult_operator" "")
13315 (const_string "fmul")
13316 (match_operand:XF 3 "div_operator" "")
13317 (const_string "fdiv")
13319 (const_string "fop")))
13320 (set_attr "mode" "<MODE>")])
13323 [(set (match_operand 0 "register_operand" "")
13324 (match_operator 3 "binary_fp_operator"
13325 [(float (match_operand:SWI24 1 "register_operand" ""))
13326 (match_operand 2 "register_operand" "")]))]
13328 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13329 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
13332 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
13333 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13334 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13335 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13336 GET_MODE (operands[3]),
13339 ix86_free_from_memory (GET_MODE (operands[1]));
13344 [(set (match_operand 0 "register_operand" "")
13345 (match_operator 3 "binary_fp_operator"
13346 [(match_operand 1 "register_operand" "")
13347 (float (match_operand:SWI24 2 "register_operand" ""))]))]
13349 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
13350 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
13353 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13354 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
13355 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
13356 gen_rtx_fmt_ee (GET_CODE (operands[3]),
13357 GET_MODE (operands[3]),
13360 ix86_free_from_memory (GET_MODE (operands[2]));
13364 ;; FPU special functions.
13366 ;; This pattern implements a no-op XFmode truncation for
13367 ;; all fancy i386 XFmode math functions.
13369 (define_insn "truncxf<mode>2_i387_noop_unspec"
13370 [(set (match_operand:MODEF 0 "register_operand" "=f")
13371 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
13372 UNSPEC_TRUNC_NOOP))]
13373 "TARGET_USE_FANCY_MATH_387"
13374 "* return output_387_reg_move (insn, operands);"
13375 [(set_attr "type" "fmov")
13376 (set_attr "mode" "<MODE>")])
13378 (define_insn "sqrtxf2"
13379 [(set (match_operand:XF 0 "register_operand" "=f")
13380 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
13381 "TARGET_USE_FANCY_MATH_387"
13383 [(set_attr "type" "fpspc")
13384 (set_attr "mode" "XF")
13385 (set_attr "athlon_decode" "direct")
13386 (set_attr "amdfam10_decode" "direct")
13387 (set_attr "bdver1_decode" "direct")])
13389 (define_insn "sqrt_extend<mode>xf2_i387"
13390 [(set (match_operand:XF 0 "register_operand" "=f")
13393 (match_operand:MODEF 1 "register_operand" "0"))))]
13394 "TARGET_USE_FANCY_MATH_387"
13396 [(set_attr "type" "fpspc")
13397 (set_attr "mode" "XF")
13398 (set_attr "athlon_decode" "direct")
13399 (set_attr "amdfam10_decode" "direct")
13400 (set_attr "bdver1_decode" "direct")])
13402 (define_insn "*rsqrtsf2_sse"
13403 [(set (match_operand:SF 0 "register_operand" "=x")
13404 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
13407 "%vrsqrtss\t{%1, %d0|%d0, %1}"
13408 [(set_attr "type" "sse")
13409 (set_attr "atom_sse_attr" "rcp")
13410 (set_attr "prefix" "maybe_vex")
13411 (set_attr "mode" "SF")])
13413 (define_expand "rsqrtsf2"
13414 [(set (match_operand:SF 0 "register_operand" "")
13415 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
13419 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
13423 (define_insn "*sqrt<mode>2_sse"
13424 [(set (match_operand:MODEF 0 "register_operand" "=x")
13426 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
13427 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
13428 "%vsqrt<ssemodesuffix>\t{%1, %d0|%d0, %1}"
13429 [(set_attr "type" "sse")
13430 (set_attr "atom_sse_attr" "sqrt")
13431 (set_attr "prefix" "maybe_vex")
13432 (set_attr "mode" "<MODE>")
13433 (set_attr "athlon_decode" "*")
13434 (set_attr "amdfam10_decode" "*")
13435 (set_attr "bdver1_decode" "*")])
13437 (define_expand "sqrt<mode>2"
13438 [(set (match_operand:MODEF 0 "register_operand" "")
13440 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
13441 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
13442 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
13444 if (<MODE>mode == SFmode
13446 && TARGET_RECIP_SQRT
13447 && !optimize_function_for_size_p (cfun)
13448 && flag_finite_math_only && !flag_trapping_math
13449 && flag_unsafe_math_optimizations)
13451 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
13455 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
13457 rtx op0 = gen_reg_rtx (XFmode);
13458 rtx op1 = force_reg (<MODE>mode, operands[1]);
13460 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
13461 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
13466 (define_insn "fpremxf4_i387"
13467 [(set (match_operand:XF 0 "register_operand" "=f")
13468 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13469 (match_operand:XF 3 "register_operand" "1")]
13471 (set (match_operand:XF 1 "register_operand" "=u")
13472 (unspec:XF [(match_dup 2) (match_dup 3)]
13474 (set (reg:CCFP FPSR_REG)
13475 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13477 "TARGET_USE_FANCY_MATH_387"
13479 [(set_attr "type" "fpspc")
13480 (set_attr "mode" "XF")])
13482 (define_expand "fmodxf3"
13483 [(use (match_operand:XF 0 "register_operand" ""))
13484 (use (match_operand:XF 1 "general_operand" ""))
13485 (use (match_operand:XF 2 "general_operand" ""))]
13486 "TARGET_USE_FANCY_MATH_387"
13488 rtx label = gen_label_rtx ();
13490 rtx op1 = gen_reg_rtx (XFmode);
13491 rtx op2 = gen_reg_rtx (XFmode);
13493 emit_move_insn (op2, operands[2]);
13494 emit_move_insn (op1, operands[1]);
13496 emit_label (label);
13497 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13498 ix86_emit_fp_unordered_jump (label);
13499 LABEL_NUSES (label) = 1;
13501 emit_move_insn (operands[0], op1);
13505 (define_expand "fmod<mode>3"
13506 [(use (match_operand:MODEF 0 "register_operand" ""))
13507 (use (match_operand:MODEF 1 "general_operand" ""))
13508 (use (match_operand:MODEF 2 "general_operand" ""))]
13509 "TARGET_USE_FANCY_MATH_387"
13511 rtx (*gen_truncxf) (rtx, rtx);
13513 rtx label = gen_label_rtx ();
13515 rtx op1 = gen_reg_rtx (XFmode);
13516 rtx op2 = gen_reg_rtx (XFmode);
13518 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13519 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13521 emit_label (label);
13522 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
13523 ix86_emit_fp_unordered_jump (label);
13524 LABEL_NUSES (label) = 1;
13526 /* Truncate the result properly for strict SSE math. */
13527 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13528 && !TARGET_MIX_SSE_I387)
13529 gen_truncxf = gen_truncxf<mode>2;
13531 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13533 emit_insn (gen_truncxf (operands[0], op1));
13537 (define_insn "fprem1xf4_i387"
13538 [(set (match_operand:XF 0 "register_operand" "=f")
13539 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
13540 (match_operand:XF 3 "register_operand" "1")]
13542 (set (match_operand:XF 1 "register_operand" "=u")
13543 (unspec:XF [(match_dup 2) (match_dup 3)]
13545 (set (reg:CCFP FPSR_REG)
13546 (unspec:CCFP [(match_dup 2) (match_dup 3)]
13548 "TARGET_USE_FANCY_MATH_387"
13550 [(set_attr "type" "fpspc")
13551 (set_attr "mode" "XF")])
13553 (define_expand "remainderxf3"
13554 [(use (match_operand:XF 0 "register_operand" ""))
13555 (use (match_operand:XF 1 "general_operand" ""))
13556 (use (match_operand:XF 2 "general_operand" ""))]
13557 "TARGET_USE_FANCY_MATH_387"
13559 rtx label = gen_label_rtx ();
13561 rtx op1 = gen_reg_rtx (XFmode);
13562 rtx op2 = gen_reg_rtx (XFmode);
13564 emit_move_insn (op2, operands[2]);
13565 emit_move_insn (op1, operands[1]);
13567 emit_label (label);
13568 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13569 ix86_emit_fp_unordered_jump (label);
13570 LABEL_NUSES (label) = 1;
13572 emit_move_insn (operands[0], op1);
13576 (define_expand "remainder<mode>3"
13577 [(use (match_operand:MODEF 0 "register_operand" ""))
13578 (use (match_operand:MODEF 1 "general_operand" ""))
13579 (use (match_operand:MODEF 2 "general_operand" ""))]
13580 "TARGET_USE_FANCY_MATH_387"
13582 rtx (*gen_truncxf) (rtx, rtx);
13584 rtx label = gen_label_rtx ();
13586 rtx op1 = gen_reg_rtx (XFmode);
13587 rtx op2 = gen_reg_rtx (XFmode);
13589 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
13590 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13592 emit_label (label);
13594 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
13595 ix86_emit_fp_unordered_jump (label);
13596 LABEL_NUSES (label) = 1;
13598 /* Truncate the result properly for strict SSE math. */
13599 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
13600 && !TARGET_MIX_SSE_I387)
13601 gen_truncxf = gen_truncxf<mode>2;
13603 gen_truncxf = gen_truncxf<mode>2_i387_noop_unspec;
13605 emit_insn (gen_truncxf (operands[0], op1));
13609 (define_insn "*sinxf2_i387"
13610 [(set (match_operand:XF 0 "register_operand" "=f")
13611 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
13612 "TARGET_USE_FANCY_MATH_387
13613 && flag_unsafe_math_optimizations"
13615 [(set_attr "type" "fpspc")
13616 (set_attr "mode" "XF")])
13618 (define_insn "*sin_extend<mode>xf2_i387"
13619 [(set (match_operand:XF 0 "register_operand" "=f")
13620 (unspec:XF [(float_extend:XF
13621 (match_operand:MODEF 1 "register_operand" "0"))]
13623 "TARGET_USE_FANCY_MATH_387
13624 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13625 || TARGET_MIX_SSE_I387)
13626 && flag_unsafe_math_optimizations"
13628 [(set_attr "type" "fpspc")
13629 (set_attr "mode" "XF")])
13631 (define_insn "*cosxf2_i387"
13632 [(set (match_operand:XF 0 "register_operand" "=f")
13633 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
13634 "TARGET_USE_FANCY_MATH_387
13635 && flag_unsafe_math_optimizations"
13637 [(set_attr "type" "fpspc")
13638 (set_attr "mode" "XF")])
13640 (define_insn "*cos_extend<mode>xf2_i387"
13641 [(set (match_operand:XF 0 "register_operand" "=f")
13642 (unspec:XF [(float_extend:XF
13643 (match_operand:MODEF 1 "register_operand" "0"))]
13645 "TARGET_USE_FANCY_MATH_387
13646 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13647 || TARGET_MIX_SSE_I387)
13648 && flag_unsafe_math_optimizations"
13650 [(set_attr "type" "fpspc")
13651 (set_attr "mode" "XF")])
13653 ;; When sincos pattern is defined, sin and cos builtin functions will be
13654 ;; expanded to sincos pattern with one of its outputs left unused.
13655 ;; CSE pass will figure out if two sincos patterns can be combined,
13656 ;; otherwise sincos pattern will be split back to sin or cos pattern,
13657 ;; depending on the unused output.
13659 (define_insn "sincosxf3"
13660 [(set (match_operand:XF 0 "register_operand" "=f")
13661 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13662 UNSPEC_SINCOS_COS))
13663 (set (match_operand:XF 1 "register_operand" "=u")
13664 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13665 "TARGET_USE_FANCY_MATH_387
13666 && flag_unsafe_math_optimizations"
13668 [(set_attr "type" "fpspc")
13669 (set_attr "mode" "XF")])
13672 [(set (match_operand:XF 0 "register_operand" "")
13673 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13674 UNSPEC_SINCOS_COS))
13675 (set (match_operand:XF 1 "register_operand" "")
13676 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
13677 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13678 && can_create_pseudo_p ()"
13679 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))])
13682 [(set (match_operand:XF 0 "register_operand" "")
13683 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
13684 UNSPEC_SINCOS_COS))
13685 (set (match_operand:XF 1 "register_operand" "")
13686 (unspec: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) (unspec:XF [(match_dup 2)] UNSPEC_COS))])
13691 (define_insn "sincos_extend<mode>xf3_i387"
13692 [(set (match_operand:XF 0 "register_operand" "=f")
13693 (unspec:XF [(float_extend:XF
13694 (match_operand:MODEF 2 "register_operand" "0"))]
13695 UNSPEC_SINCOS_COS))
13696 (set (match_operand:XF 1 "register_operand" "=u")
13697 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13698 "TARGET_USE_FANCY_MATH_387
13699 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13700 || TARGET_MIX_SSE_I387)
13701 && flag_unsafe_math_optimizations"
13703 [(set_attr "type" "fpspc")
13704 (set_attr "mode" "XF")])
13707 [(set (match_operand:XF 0 "register_operand" "")
13708 (unspec:XF [(float_extend:XF
13709 (match_operand:MODEF 2 "register_operand" ""))]
13710 UNSPEC_SINCOS_COS))
13711 (set (match_operand:XF 1 "register_operand" "")
13712 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13713 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
13714 && can_create_pseudo_p ()"
13715 [(set (match_dup 1)
13716 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))])
13719 [(set (match_operand:XF 0 "register_operand" "")
13720 (unspec:XF [(float_extend:XF
13721 (match_operand:MODEF 2 "register_operand" ""))]
13722 UNSPEC_SINCOS_COS))
13723 (set (match_operand:XF 1 "register_operand" "")
13724 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
13725 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
13726 && can_create_pseudo_p ()"
13727 [(set (match_dup 0)
13728 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))])
13730 (define_expand "sincos<mode>3"
13731 [(use (match_operand:MODEF 0 "register_operand" ""))
13732 (use (match_operand:MODEF 1 "register_operand" ""))
13733 (use (match_operand:MODEF 2 "register_operand" ""))]
13734 "TARGET_USE_FANCY_MATH_387
13735 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13736 || TARGET_MIX_SSE_I387)
13737 && flag_unsafe_math_optimizations"
13739 rtx op0 = gen_reg_rtx (XFmode);
13740 rtx op1 = gen_reg_rtx (XFmode);
13742 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
13743 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13744 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
13748 (define_insn "fptanxf4_i387"
13749 [(set (match_operand:XF 0 "register_operand" "=f")
13750 (match_operand:XF 3 "const_double_operand" "F"))
13751 (set (match_operand:XF 1 "register_operand" "=u")
13752 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
13754 "TARGET_USE_FANCY_MATH_387
13755 && flag_unsafe_math_optimizations
13756 && standard_80387_constant_p (operands[3]) == 2"
13758 [(set_attr "type" "fpspc")
13759 (set_attr "mode" "XF")])
13761 (define_insn "fptan_extend<mode>xf4_i387"
13762 [(set (match_operand:MODEF 0 "register_operand" "=f")
13763 (match_operand:MODEF 3 "const_double_operand" "F"))
13764 (set (match_operand:XF 1 "register_operand" "=u")
13765 (unspec:XF [(float_extend:XF
13766 (match_operand:MODEF 2 "register_operand" "0"))]
13768 "TARGET_USE_FANCY_MATH_387
13769 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13770 || TARGET_MIX_SSE_I387)
13771 && flag_unsafe_math_optimizations
13772 && standard_80387_constant_p (operands[3]) == 2"
13774 [(set_attr "type" "fpspc")
13775 (set_attr "mode" "XF")])
13777 (define_expand "tanxf2"
13778 [(use (match_operand:XF 0 "register_operand" ""))
13779 (use (match_operand:XF 1 "register_operand" ""))]
13780 "TARGET_USE_FANCY_MATH_387
13781 && flag_unsafe_math_optimizations"
13783 rtx one = gen_reg_rtx (XFmode);
13784 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
13786 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
13790 (define_expand "tan<mode>2"
13791 [(use (match_operand:MODEF 0 "register_operand" ""))
13792 (use (match_operand:MODEF 1 "register_operand" ""))]
13793 "TARGET_USE_FANCY_MATH_387
13794 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13795 || TARGET_MIX_SSE_I387)
13796 && flag_unsafe_math_optimizations"
13798 rtx op0 = gen_reg_rtx (XFmode);
13800 rtx one = gen_reg_rtx (<MODE>mode);
13801 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
13803 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
13804 operands[1], op2));
13805 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13809 (define_insn "*fpatanxf3_i387"
13810 [(set (match_operand:XF 0 "register_operand" "=f")
13811 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13812 (match_operand:XF 2 "register_operand" "u")]
13814 (clobber (match_scratch:XF 3 "=2"))]
13815 "TARGET_USE_FANCY_MATH_387
13816 && flag_unsafe_math_optimizations"
13818 [(set_attr "type" "fpspc")
13819 (set_attr "mode" "XF")])
13821 (define_insn "fpatan_extend<mode>xf3_i387"
13822 [(set (match_operand:XF 0 "register_operand" "=f")
13823 (unspec:XF [(float_extend:XF
13824 (match_operand:MODEF 1 "register_operand" "0"))
13826 (match_operand:MODEF 2 "register_operand" "u"))]
13828 (clobber (match_scratch:XF 3 "=2"))]
13829 "TARGET_USE_FANCY_MATH_387
13830 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13831 || TARGET_MIX_SSE_I387)
13832 && flag_unsafe_math_optimizations"
13834 [(set_attr "type" "fpspc")
13835 (set_attr "mode" "XF")])
13837 (define_expand "atan2xf3"
13838 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13839 (unspec:XF [(match_operand:XF 2 "register_operand" "")
13840 (match_operand:XF 1 "register_operand" "")]
13842 (clobber (match_scratch:XF 3 ""))])]
13843 "TARGET_USE_FANCY_MATH_387
13844 && flag_unsafe_math_optimizations")
13846 (define_expand "atan2<mode>3"
13847 [(use (match_operand:MODEF 0 "register_operand" ""))
13848 (use (match_operand:MODEF 1 "register_operand" ""))
13849 (use (match_operand:MODEF 2 "register_operand" ""))]
13850 "TARGET_USE_FANCY_MATH_387
13851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13852 || TARGET_MIX_SSE_I387)
13853 && flag_unsafe_math_optimizations"
13855 rtx op0 = gen_reg_rtx (XFmode);
13857 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
13858 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13862 (define_expand "atanxf2"
13863 [(parallel [(set (match_operand:XF 0 "register_operand" "")
13864 (unspec:XF [(match_dup 2)
13865 (match_operand:XF 1 "register_operand" "")]
13867 (clobber (match_scratch:XF 3 ""))])]
13868 "TARGET_USE_FANCY_MATH_387
13869 && flag_unsafe_math_optimizations"
13871 operands[2] = gen_reg_rtx (XFmode);
13872 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
13875 (define_expand "atan<mode>2"
13876 [(use (match_operand:MODEF 0 "register_operand" ""))
13877 (use (match_operand:MODEF 1 "register_operand" ""))]
13878 "TARGET_USE_FANCY_MATH_387
13879 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13880 || TARGET_MIX_SSE_I387)
13881 && flag_unsafe_math_optimizations"
13883 rtx op0 = gen_reg_rtx (XFmode);
13885 rtx op2 = gen_reg_rtx (<MODE>mode);
13886 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
13888 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
13889 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13893 (define_expand "asinxf2"
13894 [(set (match_dup 2)
13895 (mult:XF (match_operand:XF 1 "register_operand" "")
13897 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13898 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13899 (parallel [(set (match_operand:XF 0 "register_operand" "")
13900 (unspec:XF [(match_dup 5) (match_dup 1)]
13902 (clobber (match_scratch:XF 6 ""))])]
13903 "TARGET_USE_FANCY_MATH_387
13904 && flag_unsafe_math_optimizations"
13908 if (optimize_insn_for_size_p ())
13911 for (i = 2; i < 6; i++)
13912 operands[i] = gen_reg_rtx (XFmode);
13914 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13917 (define_expand "asin<mode>2"
13918 [(use (match_operand:MODEF 0 "register_operand" ""))
13919 (use (match_operand:MODEF 1 "general_operand" ""))]
13920 "TARGET_USE_FANCY_MATH_387
13921 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13922 || TARGET_MIX_SSE_I387)
13923 && flag_unsafe_math_optimizations"
13925 rtx op0 = gen_reg_rtx (XFmode);
13926 rtx op1 = gen_reg_rtx (XFmode);
13928 if (optimize_insn_for_size_p ())
13931 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13932 emit_insn (gen_asinxf2 (op0, op1));
13933 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13937 (define_expand "acosxf2"
13938 [(set (match_dup 2)
13939 (mult:XF (match_operand:XF 1 "register_operand" "")
13941 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
13942 (set (match_dup 5) (sqrt:XF (match_dup 4)))
13943 (parallel [(set (match_operand:XF 0 "register_operand" "")
13944 (unspec:XF [(match_dup 1) (match_dup 5)]
13946 (clobber (match_scratch:XF 6 ""))])]
13947 "TARGET_USE_FANCY_MATH_387
13948 && flag_unsafe_math_optimizations"
13952 if (optimize_insn_for_size_p ())
13955 for (i = 2; i < 6; i++)
13956 operands[i] = gen_reg_rtx (XFmode);
13958 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
13961 (define_expand "acos<mode>2"
13962 [(use (match_operand:MODEF 0 "register_operand" ""))
13963 (use (match_operand:MODEF 1 "general_operand" ""))]
13964 "TARGET_USE_FANCY_MATH_387
13965 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
13966 || TARGET_MIX_SSE_I387)
13967 && flag_unsafe_math_optimizations"
13969 rtx op0 = gen_reg_rtx (XFmode);
13970 rtx op1 = gen_reg_rtx (XFmode);
13972 if (optimize_insn_for_size_p ())
13975 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
13976 emit_insn (gen_acosxf2 (op0, op1));
13977 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
13981 (define_insn "fyl2xxf3_i387"
13982 [(set (match_operand:XF 0 "register_operand" "=f")
13983 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
13984 (match_operand:XF 2 "register_operand" "u")]
13986 (clobber (match_scratch:XF 3 "=2"))]
13987 "TARGET_USE_FANCY_MATH_387
13988 && flag_unsafe_math_optimizations"
13990 [(set_attr "type" "fpspc")
13991 (set_attr "mode" "XF")])
13993 (define_insn "fyl2x_extend<mode>xf3_i387"
13994 [(set (match_operand:XF 0 "register_operand" "=f")
13995 (unspec:XF [(float_extend:XF
13996 (match_operand:MODEF 1 "register_operand" "0"))
13997 (match_operand:XF 2 "register_operand" "u")]
13999 (clobber (match_scratch:XF 3 "=2"))]
14000 "TARGET_USE_FANCY_MATH_387
14001 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14002 || TARGET_MIX_SSE_I387)
14003 && flag_unsafe_math_optimizations"
14005 [(set_attr "type" "fpspc")
14006 (set_attr "mode" "XF")])
14008 (define_expand "logxf2"
14009 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14010 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14011 (match_dup 2)] UNSPEC_FYL2X))
14012 (clobber (match_scratch:XF 3 ""))])]
14013 "TARGET_USE_FANCY_MATH_387
14014 && flag_unsafe_math_optimizations"
14016 operands[2] = gen_reg_rtx (XFmode);
14017 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
14020 (define_expand "log<mode>2"
14021 [(use (match_operand:MODEF 0 "register_operand" ""))
14022 (use (match_operand:MODEF 1 "register_operand" ""))]
14023 "TARGET_USE_FANCY_MATH_387
14024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14025 || TARGET_MIX_SSE_I387)
14026 && flag_unsafe_math_optimizations"
14028 rtx op0 = gen_reg_rtx (XFmode);
14030 rtx op2 = gen_reg_rtx (XFmode);
14031 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
14033 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14034 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14038 (define_expand "log10xf2"
14039 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14040 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14041 (match_dup 2)] UNSPEC_FYL2X))
14042 (clobber (match_scratch:XF 3 ""))])]
14043 "TARGET_USE_FANCY_MATH_387
14044 && flag_unsafe_math_optimizations"
14046 operands[2] = gen_reg_rtx (XFmode);
14047 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
14050 (define_expand "log10<mode>2"
14051 [(use (match_operand:MODEF 0 "register_operand" ""))
14052 (use (match_operand:MODEF 1 "register_operand" ""))]
14053 "TARGET_USE_FANCY_MATH_387
14054 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14055 || TARGET_MIX_SSE_I387)
14056 && flag_unsafe_math_optimizations"
14058 rtx op0 = gen_reg_rtx (XFmode);
14060 rtx op2 = gen_reg_rtx (XFmode);
14061 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
14063 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14064 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14068 (define_expand "log2xf2"
14069 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14070 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14071 (match_dup 2)] UNSPEC_FYL2X))
14072 (clobber (match_scratch:XF 3 ""))])]
14073 "TARGET_USE_FANCY_MATH_387
14074 && flag_unsafe_math_optimizations"
14076 operands[2] = gen_reg_rtx (XFmode);
14077 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
14080 (define_expand "log2<mode>2"
14081 [(use (match_operand:MODEF 0 "register_operand" ""))
14082 (use (match_operand:MODEF 1 "register_operand" ""))]
14083 "TARGET_USE_FANCY_MATH_387
14084 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14085 || TARGET_MIX_SSE_I387)
14086 && flag_unsafe_math_optimizations"
14088 rtx op0 = gen_reg_rtx (XFmode);
14090 rtx op2 = gen_reg_rtx (XFmode);
14091 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14093 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
14094 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14098 (define_insn "fyl2xp1xf3_i387"
14099 [(set (match_operand:XF 0 "register_operand" "=f")
14100 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
14101 (match_operand:XF 2 "register_operand" "u")]
14103 (clobber (match_scratch:XF 3 "=2"))]
14104 "TARGET_USE_FANCY_MATH_387
14105 && flag_unsafe_math_optimizations"
14107 [(set_attr "type" "fpspc")
14108 (set_attr "mode" "XF")])
14110 (define_insn "fyl2xp1_extend<mode>xf3_i387"
14111 [(set (match_operand:XF 0 "register_operand" "=f")
14112 (unspec:XF [(float_extend:XF
14113 (match_operand:MODEF 1 "register_operand" "0"))
14114 (match_operand:XF 2 "register_operand" "u")]
14116 (clobber (match_scratch:XF 3 "=2"))]
14117 "TARGET_USE_FANCY_MATH_387
14118 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14119 || TARGET_MIX_SSE_I387)
14120 && flag_unsafe_math_optimizations"
14122 [(set_attr "type" "fpspc")
14123 (set_attr "mode" "XF")])
14125 (define_expand "log1pxf2"
14126 [(use (match_operand:XF 0 "register_operand" ""))
14127 (use (match_operand:XF 1 "register_operand" ""))]
14128 "TARGET_USE_FANCY_MATH_387
14129 && flag_unsafe_math_optimizations"
14131 if (optimize_insn_for_size_p ())
14134 ix86_emit_i387_log1p (operands[0], operands[1]);
14138 (define_expand "log1p<mode>2"
14139 [(use (match_operand:MODEF 0 "register_operand" ""))
14140 (use (match_operand:MODEF 1 "register_operand" ""))]
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"
14148 if (optimize_insn_for_size_p ())
14151 op0 = gen_reg_rtx (XFmode);
14153 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
14155 ix86_emit_i387_log1p (op0, operands[1]);
14156 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14160 (define_insn "fxtractxf3_i387"
14161 [(set (match_operand:XF 0 "register_operand" "=f")
14162 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
14163 UNSPEC_XTRACT_FRACT))
14164 (set (match_operand:XF 1 "register_operand" "=u")
14165 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
14166 "TARGET_USE_FANCY_MATH_387
14167 && flag_unsafe_math_optimizations"
14169 [(set_attr "type" "fpspc")
14170 (set_attr "mode" "XF")])
14172 (define_insn "fxtract_extend<mode>xf3_i387"
14173 [(set (match_operand:XF 0 "register_operand" "=f")
14174 (unspec:XF [(float_extend:XF
14175 (match_operand:MODEF 2 "register_operand" "0"))]
14176 UNSPEC_XTRACT_FRACT))
14177 (set (match_operand:XF 1 "register_operand" "=u")
14178 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
14179 "TARGET_USE_FANCY_MATH_387
14180 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14181 || TARGET_MIX_SSE_I387)
14182 && flag_unsafe_math_optimizations"
14184 [(set_attr "type" "fpspc")
14185 (set_attr "mode" "XF")])
14187 (define_expand "logbxf2"
14188 [(parallel [(set (match_dup 2)
14189 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14190 UNSPEC_XTRACT_FRACT))
14191 (set (match_operand:XF 0 "register_operand" "")
14192 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14193 "TARGET_USE_FANCY_MATH_387
14194 && flag_unsafe_math_optimizations"
14195 "operands[2] = gen_reg_rtx (XFmode);")
14197 (define_expand "logb<mode>2"
14198 [(use (match_operand:MODEF 0 "register_operand" ""))
14199 (use (match_operand:MODEF 1 "register_operand" ""))]
14200 "TARGET_USE_FANCY_MATH_387
14201 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14202 || TARGET_MIX_SSE_I387)
14203 && flag_unsafe_math_optimizations"
14205 rtx op0 = gen_reg_rtx (XFmode);
14206 rtx op1 = gen_reg_rtx (XFmode);
14208 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14209 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
14213 (define_expand "ilogbxf2"
14214 [(use (match_operand:SI 0 "register_operand" ""))
14215 (use (match_operand:XF 1 "register_operand" ""))]
14216 "TARGET_USE_FANCY_MATH_387
14217 && flag_unsafe_math_optimizations"
14221 if (optimize_insn_for_size_p ())
14224 op0 = gen_reg_rtx (XFmode);
14225 op1 = gen_reg_rtx (XFmode);
14227 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
14228 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14232 (define_expand "ilogb<mode>2"
14233 [(use (match_operand:SI 0 "register_operand" ""))
14234 (use (match_operand:MODEF 1 "register_operand" ""))]
14235 "TARGET_USE_FANCY_MATH_387
14236 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14237 || TARGET_MIX_SSE_I387)
14238 && flag_unsafe_math_optimizations"
14242 if (optimize_insn_for_size_p ())
14245 op0 = gen_reg_rtx (XFmode);
14246 op1 = gen_reg_rtx (XFmode);
14248 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14249 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
14253 (define_insn "*f2xm1xf2_i387"
14254 [(set (match_operand:XF 0 "register_operand" "=f")
14255 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14257 "TARGET_USE_FANCY_MATH_387
14258 && flag_unsafe_math_optimizations"
14260 [(set_attr "type" "fpspc")
14261 (set_attr "mode" "XF")])
14263 (define_insn "*fscalexf4_i387"
14264 [(set (match_operand:XF 0 "register_operand" "=f")
14265 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
14266 (match_operand:XF 3 "register_operand" "1")]
14267 UNSPEC_FSCALE_FRACT))
14268 (set (match_operand:XF 1 "register_operand" "=u")
14269 (unspec:XF [(match_dup 2) (match_dup 3)]
14270 UNSPEC_FSCALE_EXP))]
14271 "TARGET_USE_FANCY_MATH_387
14272 && flag_unsafe_math_optimizations"
14274 [(set_attr "type" "fpspc")
14275 (set_attr "mode" "XF")])
14277 (define_expand "expNcorexf3"
14278 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14279 (match_operand:XF 2 "register_operand" "")))
14280 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14281 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14282 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14283 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
14284 (parallel [(set (match_operand:XF 0 "register_operand" "")
14285 (unspec:XF [(match_dup 8) (match_dup 4)]
14286 UNSPEC_FSCALE_FRACT))
14288 (unspec:XF [(match_dup 8) (match_dup 4)]
14289 UNSPEC_FSCALE_EXP))])]
14290 "TARGET_USE_FANCY_MATH_387
14291 && flag_unsafe_math_optimizations"
14295 if (optimize_insn_for_size_p ())
14298 for (i = 3; i < 10; i++)
14299 operands[i] = gen_reg_rtx (XFmode);
14301 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
14304 (define_expand "expxf2"
14305 [(use (match_operand:XF 0 "register_operand" ""))
14306 (use (match_operand:XF 1 "register_operand" ""))]
14307 "TARGET_USE_FANCY_MATH_387
14308 && flag_unsafe_math_optimizations"
14312 if (optimize_insn_for_size_p ())
14315 op2 = gen_reg_rtx (XFmode);
14316 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
14318 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14322 (define_expand "exp<mode>2"
14323 [(use (match_operand:MODEF 0 "register_operand" ""))
14324 (use (match_operand:MODEF 1 "general_operand" ""))]
14325 "TARGET_USE_FANCY_MATH_387
14326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14327 || TARGET_MIX_SSE_I387)
14328 && flag_unsafe_math_optimizations"
14332 if (optimize_insn_for_size_p ())
14335 op0 = gen_reg_rtx (XFmode);
14336 op1 = gen_reg_rtx (XFmode);
14338 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14339 emit_insn (gen_expxf2 (op0, op1));
14340 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14344 (define_expand "exp10xf2"
14345 [(use (match_operand:XF 0 "register_operand" ""))
14346 (use (match_operand:XF 1 "register_operand" ""))]
14347 "TARGET_USE_FANCY_MATH_387
14348 && flag_unsafe_math_optimizations"
14352 if (optimize_insn_for_size_p ())
14355 op2 = gen_reg_rtx (XFmode);
14356 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
14358 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14362 (define_expand "exp10<mode>2"
14363 [(use (match_operand:MODEF 0 "register_operand" ""))
14364 (use (match_operand:MODEF 1 "general_operand" ""))]
14365 "TARGET_USE_FANCY_MATH_387
14366 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14367 || TARGET_MIX_SSE_I387)
14368 && flag_unsafe_math_optimizations"
14372 if (optimize_insn_for_size_p ())
14375 op0 = gen_reg_rtx (XFmode);
14376 op1 = gen_reg_rtx (XFmode);
14378 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14379 emit_insn (gen_exp10xf2 (op0, op1));
14380 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14384 (define_expand "exp2xf2"
14385 [(use (match_operand:XF 0 "register_operand" ""))
14386 (use (match_operand:XF 1 "register_operand" ""))]
14387 "TARGET_USE_FANCY_MATH_387
14388 && flag_unsafe_math_optimizations"
14392 if (optimize_insn_for_size_p ())
14395 op2 = gen_reg_rtx (XFmode);
14396 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
14398 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
14402 (define_expand "exp2<mode>2"
14403 [(use (match_operand:MODEF 0 "register_operand" ""))
14404 (use (match_operand:MODEF 1 "general_operand" ""))]
14405 "TARGET_USE_FANCY_MATH_387
14406 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14407 || TARGET_MIX_SSE_I387)
14408 && flag_unsafe_math_optimizations"
14412 if (optimize_insn_for_size_p ())
14415 op0 = gen_reg_rtx (XFmode);
14416 op1 = gen_reg_rtx (XFmode);
14418 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14419 emit_insn (gen_exp2xf2 (op0, op1));
14420 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14424 (define_expand "expm1xf2"
14425 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
14427 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
14428 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
14429 (set (match_dup 9) (float_extend:XF (match_dup 13)))
14430 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
14431 (parallel [(set (match_dup 7)
14432 (unspec:XF [(match_dup 6) (match_dup 4)]
14433 UNSPEC_FSCALE_FRACT))
14435 (unspec:XF [(match_dup 6) (match_dup 4)]
14436 UNSPEC_FSCALE_EXP))])
14437 (parallel [(set (match_dup 10)
14438 (unspec:XF [(match_dup 9) (match_dup 8)]
14439 UNSPEC_FSCALE_FRACT))
14440 (set (match_dup 11)
14441 (unspec:XF [(match_dup 9) (match_dup 8)]
14442 UNSPEC_FSCALE_EXP))])
14443 (set (match_dup 12) (minus:XF (match_dup 10)
14444 (float_extend:XF (match_dup 13))))
14445 (set (match_operand:XF 0 "register_operand" "")
14446 (plus:XF (match_dup 12) (match_dup 7)))]
14447 "TARGET_USE_FANCY_MATH_387
14448 && flag_unsafe_math_optimizations"
14452 if (optimize_insn_for_size_p ())
14455 for (i = 2; i < 13; i++)
14456 operands[i] = gen_reg_rtx (XFmode);
14459 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
14461 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
14464 (define_expand "expm1<mode>2"
14465 [(use (match_operand:MODEF 0 "register_operand" ""))
14466 (use (match_operand:MODEF 1 "general_operand" ""))]
14467 "TARGET_USE_FANCY_MATH_387
14468 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14469 || TARGET_MIX_SSE_I387)
14470 && flag_unsafe_math_optimizations"
14474 if (optimize_insn_for_size_p ())
14477 op0 = gen_reg_rtx (XFmode);
14478 op1 = gen_reg_rtx (XFmode);
14480 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14481 emit_insn (gen_expm1xf2 (op0, op1));
14482 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14486 (define_expand "ldexpxf3"
14487 [(set (match_dup 3)
14488 (float:XF (match_operand:SI 2 "register_operand" "")))
14489 (parallel [(set (match_operand:XF 0 " register_operand" "")
14490 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14492 UNSPEC_FSCALE_FRACT))
14494 (unspec:XF [(match_dup 1) (match_dup 3)]
14495 UNSPEC_FSCALE_EXP))])]
14496 "TARGET_USE_FANCY_MATH_387
14497 && flag_unsafe_math_optimizations"
14499 if (optimize_insn_for_size_p ())
14502 operands[3] = gen_reg_rtx (XFmode);
14503 operands[4] = gen_reg_rtx (XFmode);
14506 (define_expand "ldexp<mode>3"
14507 [(use (match_operand:MODEF 0 "register_operand" ""))
14508 (use (match_operand:MODEF 1 "general_operand" ""))
14509 (use (match_operand:SI 2 "register_operand" ""))]
14510 "TARGET_USE_FANCY_MATH_387
14511 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14512 || TARGET_MIX_SSE_I387)
14513 && flag_unsafe_math_optimizations"
14517 if (optimize_insn_for_size_p ())
14520 op0 = gen_reg_rtx (XFmode);
14521 op1 = gen_reg_rtx (XFmode);
14523 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14524 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
14525 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14529 (define_expand "scalbxf3"
14530 [(parallel [(set (match_operand:XF 0 " register_operand" "")
14531 (unspec:XF [(match_operand:XF 1 "register_operand" "")
14532 (match_operand:XF 2 "register_operand" "")]
14533 UNSPEC_FSCALE_FRACT))
14535 (unspec:XF [(match_dup 1) (match_dup 2)]
14536 UNSPEC_FSCALE_EXP))])]
14537 "TARGET_USE_FANCY_MATH_387
14538 && flag_unsafe_math_optimizations"
14540 if (optimize_insn_for_size_p ())
14543 operands[3] = gen_reg_rtx (XFmode);
14546 (define_expand "scalb<mode>3"
14547 [(use (match_operand:MODEF 0 "register_operand" ""))
14548 (use (match_operand:MODEF 1 "general_operand" ""))
14549 (use (match_operand:MODEF 2 "general_operand" ""))]
14550 "TARGET_USE_FANCY_MATH_387
14551 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14552 || TARGET_MIX_SSE_I387)
14553 && flag_unsafe_math_optimizations"
14557 if (optimize_insn_for_size_p ())
14560 op0 = gen_reg_rtx (XFmode);
14561 op1 = gen_reg_rtx (XFmode);
14562 op2 = gen_reg_rtx (XFmode);
14564 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14565 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
14566 emit_insn (gen_scalbxf3 (op0, op1, op2));
14567 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14571 (define_expand "significandxf2"
14572 [(parallel [(set (match_operand:XF 0 "register_operand" "")
14573 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14574 UNSPEC_XTRACT_FRACT))
14576 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
14577 "TARGET_USE_FANCY_MATH_387
14578 && flag_unsafe_math_optimizations"
14579 "operands[2] = gen_reg_rtx (XFmode);")
14581 (define_expand "significand<mode>2"
14582 [(use (match_operand:MODEF 0 "register_operand" ""))
14583 (use (match_operand:MODEF 1 "register_operand" ""))]
14584 "TARGET_USE_FANCY_MATH_387
14585 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14586 || TARGET_MIX_SSE_I387)
14587 && flag_unsafe_math_optimizations"
14589 rtx op0 = gen_reg_rtx (XFmode);
14590 rtx op1 = gen_reg_rtx (XFmode);
14592 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
14593 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14598 (define_insn "sse4_1_round<mode>2"
14599 [(set (match_operand:MODEF 0 "register_operand" "=x")
14600 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
14601 (match_operand:SI 2 "const_0_to_15_operand" "n")]
14604 "%vround<ssemodesuffix>\t{%2, %1, %d0|%d0, %1, %2}"
14605 [(set_attr "type" "ssecvt")
14606 (set_attr "prefix_extra" "1")
14607 (set_attr "prefix" "maybe_vex")
14608 (set_attr "mode" "<MODE>")])
14610 (define_insn "rintxf2"
14611 [(set (match_operand:XF 0 "register_operand" "=f")
14612 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14614 "TARGET_USE_FANCY_MATH_387
14615 && flag_unsafe_math_optimizations"
14617 [(set_attr "type" "fpspc")
14618 (set_attr "mode" "XF")])
14620 (define_expand "rint<mode>2"
14621 [(use (match_operand:MODEF 0 "register_operand" ""))
14622 (use (match_operand:MODEF 1 "register_operand" ""))]
14623 "(TARGET_USE_FANCY_MATH_387
14624 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14625 || TARGET_MIX_SSE_I387)
14626 && flag_unsafe_math_optimizations)
14627 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14628 && !flag_trapping_math)"
14630 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14631 && !flag_trapping_math)
14634 emit_insn (gen_sse4_1_round<mode>2
14635 (operands[0], operands[1], GEN_INT (ROUND_MXCSR)));
14636 else if (optimize_insn_for_size_p ())
14639 ix86_expand_rint (operands[0], operands[1]);
14643 rtx op0 = gen_reg_rtx (XFmode);
14644 rtx op1 = gen_reg_rtx (XFmode);
14646 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14647 emit_insn (gen_rintxf2 (op0, op1));
14649 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14654 (define_expand "round<mode>2"
14655 [(match_operand:X87MODEF 0 "register_operand" "")
14656 (match_operand:X87MODEF 1 "nonimmediate_operand" "")]
14657 "(TARGET_USE_FANCY_MATH_387
14658 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14659 || TARGET_MIX_SSE_I387)
14660 && flag_unsafe_math_optimizations)
14661 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14662 && !flag_trapping_math && !flag_rounding_math)"
14664 if (optimize_insn_for_size_p ())
14667 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14668 && !flag_trapping_math && !flag_rounding_math)
14672 operands[1] = force_reg (<MODE>mode, operands[1]);
14673 ix86_expand_round_sse4 (operands[0], operands[1]);
14675 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14676 ix86_expand_round (operands[0], operands[1]);
14678 ix86_expand_rounddf_32 (operands[0], operands[1]);
14682 operands[1] = force_reg (<MODE>mode, operands[1]);
14683 ix86_emit_i387_round (operands[0], operands[1]);
14688 (define_insn_and_split "*fistdi2_1"
14689 [(set (match_operand:DI 0 "nonimmediate_operand" "")
14690 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14692 "TARGET_USE_FANCY_MATH_387
14693 && can_create_pseudo_p ()"
14698 if (memory_operand (operands[0], VOIDmode))
14699 emit_insn (gen_fistdi2 (operands[0], operands[1]));
14702 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
14703 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
14708 [(set_attr "type" "fpspc")
14709 (set_attr "mode" "DI")])
14711 (define_insn "fistdi2"
14712 [(set (match_operand:DI 0 "memory_operand" "=m")
14713 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14715 (clobber (match_scratch:XF 2 "=&1f"))]
14716 "TARGET_USE_FANCY_MATH_387"
14717 "* return output_fix_trunc (insn, operands, false);"
14718 [(set_attr "type" "fpspc")
14719 (set_attr "mode" "DI")])
14721 (define_insn "fistdi2_with_temp"
14722 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14723 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14725 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
14726 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
14727 "TARGET_USE_FANCY_MATH_387"
14729 [(set_attr "type" "fpspc")
14730 (set_attr "mode" "DI")])
14733 [(set (match_operand:DI 0 "register_operand" "")
14734 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14736 (clobber (match_operand:DI 2 "memory_operand" ""))
14737 (clobber (match_scratch 3 ""))]
14739 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14740 (clobber (match_dup 3))])
14741 (set (match_dup 0) (match_dup 2))])
14744 [(set (match_operand:DI 0 "memory_operand" "")
14745 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
14747 (clobber (match_operand:DI 2 "memory_operand" ""))
14748 (clobber (match_scratch 3 ""))]
14750 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
14751 (clobber (match_dup 3))])])
14753 (define_insn_and_split "*fist<mode>2_1"
14754 [(set (match_operand:SWI24 0 "register_operand" "")
14755 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14757 "TARGET_USE_FANCY_MATH_387
14758 && can_create_pseudo_p ()"
14763 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14764 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
14768 [(set_attr "type" "fpspc")
14769 (set_attr "mode" "<MODE>")])
14771 (define_insn "fist<mode>2"
14772 [(set (match_operand:SWI24 0 "memory_operand" "=m")
14773 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14775 "TARGET_USE_FANCY_MATH_387"
14776 "* return output_fix_trunc (insn, operands, false);"
14777 [(set_attr "type" "fpspc")
14778 (set_attr "mode" "<MODE>")])
14780 (define_insn "fist<mode>2_with_temp"
14781 [(set (match_operand:SWI24 0 "register_operand" "=r")
14782 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
14784 (clobber (match_operand:SWI24 2 "memory_operand" "=m"))]
14785 "TARGET_USE_FANCY_MATH_387"
14787 [(set_attr "type" "fpspc")
14788 (set_attr "mode" "<MODE>")])
14791 [(set (match_operand:SWI24 0 "register_operand" "")
14792 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14794 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14796 [(set (match_dup 2) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))
14797 (set (match_dup 0) (match_dup 2))])
14800 [(set (match_operand:SWI24 0 "memory_operand" "")
14801 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
14803 (clobber (match_operand:SWI24 2 "memory_operand" ""))]
14805 [(set (match_dup 0) (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST))])
14807 (define_expand "lrintxf<mode>2"
14808 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14809 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14811 "TARGET_USE_FANCY_MATH_387")
14813 (define_expand "lrint<MODEF:mode><SWI48x:mode>2"
14814 [(set (match_operand:SWI48x 0 "nonimmediate_operand" "")
14815 (unspec:SWI48x [(match_operand:MODEF 1 "register_operand" "")]
14816 UNSPEC_FIX_NOTRUNC))]
14817 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
14818 && ((<SWI48x:MODE>mode != DImode) || TARGET_64BIT)")
14820 (define_expand "lround<X87MODEF:mode><SWI248x:mode>2"
14821 [(match_operand:SWI248x 0 "nonimmediate_operand" "")
14822 (match_operand:X87MODEF 1 "register_operand" "")]
14823 "(TARGET_USE_FANCY_MATH_387
14824 && (!(SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
14825 || TARGET_MIX_SSE_I387)
14826 && flag_unsafe_math_optimizations)
14827 || (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14828 && <SWI248x:MODE>mode != HImode
14829 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14830 && !flag_trapping_math && !flag_rounding_math)"
14832 if (optimize_insn_for_size_p ())
14835 if (SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
14836 && <SWI248x:MODE>mode != HImode
14837 && ((<SWI248x:MODE>mode != DImode) || TARGET_64BIT)
14838 && !flag_trapping_math && !flag_rounding_math)
14839 ix86_expand_lround (operands[0], operands[1]);
14841 ix86_emit_i387_round (operands[0], operands[1]);
14845 ;; Rounding mode control word calculation could clobber FLAGS_REG.
14846 (define_insn_and_split "frndintxf2_floor"
14847 [(set (match_operand:XF 0 "register_operand" "")
14848 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
14849 UNSPEC_FRNDINT_FLOOR))
14850 (clobber (reg:CC FLAGS_REG))]
14851 "TARGET_USE_FANCY_MATH_387
14852 && flag_unsafe_math_optimizations
14853 && can_create_pseudo_p ()"
14858 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14860 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14861 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14863 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
14864 operands[2], operands[3]));
14867 [(set_attr "type" "frndint")
14868 (set_attr "i387_cw" "floor")
14869 (set_attr "mode" "XF")])
14871 (define_insn "frndintxf2_floor_i387"
14872 [(set (match_operand:XF 0 "register_operand" "=f")
14873 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
14874 UNSPEC_FRNDINT_FLOOR))
14875 (use (match_operand:HI 2 "memory_operand" "m"))
14876 (use (match_operand:HI 3 "memory_operand" "m"))]
14877 "TARGET_USE_FANCY_MATH_387
14878 && flag_unsafe_math_optimizations"
14879 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
14880 [(set_attr "type" "frndint")
14881 (set_attr "i387_cw" "floor")
14882 (set_attr "mode" "XF")])
14884 (define_expand "floorxf2"
14885 [(use (match_operand:XF 0 "register_operand" ""))
14886 (use (match_operand:XF 1 "register_operand" ""))]
14887 "TARGET_USE_FANCY_MATH_387
14888 && flag_unsafe_math_optimizations"
14890 if (optimize_insn_for_size_p ())
14892 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
14896 (define_expand "floor<mode>2"
14897 [(use (match_operand:MODEF 0 "register_operand" ""))
14898 (use (match_operand:MODEF 1 "register_operand" ""))]
14899 "(TARGET_USE_FANCY_MATH_387
14900 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14901 || TARGET_MIX_SSE_I387)
14902 && flag_unsafe_math_optimizations)
14903 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14904 && !flag_trapping_math)"
14906 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14907 && !flag_trapping_math)
14910 emit_insn (gen_sse4_1_round<mode>2
14911 (operands[0], operands[1], GEN_INT (ROUND_FLOOR)));
14912 else if (optimize_insn_for_size_p ())
14914 else if (TARGET_64BIT || (<MODE>mode != DFmode))
14915 ix86_expand_floorceil (operands[0], operands[1], true);
14917 ix86_expand_floorceildf_32 (operands[0], operands[1], true);
14923 if (optimize_insn_for_size_p ())
14926 op0 = gen_reg_rtx (XFmode);
14927 op1 = gen_reg_rtx (XFmode);
14928 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
14929 emit_insn (gen_frndintxf2_floor (op0, op1));
14931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
14936 (define_insn_and_split "*fist<mode>2_floor_1"
14937 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
14938 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
14939 UNSPEC_FIST_FLOOR))
14940 (clobber (reg:CC FLAGS_REG))]
14941 "TARGET_USE_FANCY_MATH_387
14942 && flag_unsafe_math_optimizations
14943 && can_create_pseudo_p ()"
14948 ix86_optimize_mode_switching[I387_FLOOR] = 1;
14950 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
14951 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
14952 if (memory_operand (operands[0], VOIDmode))
14953 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
14954 operands[2], operands[3]));
14957 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
14958 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
14959 operands[2], operands[3],
14964 [(set_attr "type" "fistp")
14965 (set_attr "i387_cw" "floor")
14966 (set_attr "mode" "<MODE>")])
14968 (define_insn "fistdi2_floor"
14969 [(set (match_operand:DI 0 "memory_operand" "=m")
14970 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
14971 UNSPEC_FIST_FLOOR))
14972 (use (match_operand:HI 2 "memory_operand" "m"))
14973 (use (match_operand:HI 3 "memory_operand" "m"))
14974 (clobber (match_scratch:XF 4 "=&1f"))]
14975 "TARGET_USE_FANCY_MATH_387
14976 && flag_unsafe_math_optimizations"
14977 "* return output_fix_trunc (insn, operands, false);"
14978 [(set_attr "type" "fistp")
14979 (set_attr "i387_cw" "floor")
14980 (set_attr "mode" "DI")])
14982 (define_insn "fistdi2_floor_with_temp"
14983 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
14984 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
14985 UNSPEC_FIST_FLOOR))
14986 (use (match_operand:HI 2 "memory_operand" "m,m"))
14987 (use (match_operand:HI 3 "memory_operand" "m,m"))
14988 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
14989 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
14990 "TARGET_USE_FANCY_MATH_387
14991 && flag_unsafe_math_optimizations"
14993 [(set_attr "type" "fistp")
14994 (set_attr "i387_cw" "floor")
14995 (set_attr "mode" "DI")])
14998 [(set (match_operand:DI 0 "register_operand" "")
14999 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15000 UNSPEC_FIST_FLOOR))
15001 (use (match_operand:HI 2 "memory_operand" ""))
15002 (use (match_operand:HI 3 "memory_operand" ""))
15003 (clobber (match_operand:DI 4 "memory_operand" ""))
15004 (clobber (match_scratch 5 ""))]
15006 [(parallel [(set (match_dup 4)
15007 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15008 (use (match_dup 2))
15009 (use (match_dup 3))
15010 (clobber (match_dup 5))])
15011 (set (match_dup 0) (match_dup 4))])
15014 [(set (match_operand:DI 0 "memory_operand" "")
15015 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15016 UNSPEC_FIST_FLOOR))
15017 (use (match_operand:HI 2 "memory_operand" ""))
15018 (use (match_operand:HI 3 "memory_operand" ""))
15019 (clobber (match_operand:DI 4 "memory_operand" ""))
15020 (clobber (match_scratch 5 ""))]
15022 [(parallel [(set (match_dup 0)
15023 (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
15024 (use (match_dup 2))
15025 (use (match_dup 3))
15026 (clobber (match_dup 5))])])
15028 (define_insn "fist<mode>2_floor"
15029 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15030 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15031 UNSPEC_FIST_FLOOR))
15032 (use (match_operand:HI 2 "memory_operand" "m"))
15033 (use (match_operand:HI 3 "memory_operand" "m"))]
15034 "TARGET_USE_FANCY_MATH_387
15035 && flag_unsafe_math_optimizations"
15036 "* return output_fix_trunc (insn, operands, false);"
15037 [(set_attr "type" "fistp")
15038 (set_attr "i387_cw" "floor")
15039 (set_attr "mode" "<MODE>")])
15041 (define_insn "fist<mode>2_floor_with_temp"
15042 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15043 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15044 UNSPEC_FIST_FLOOR))
15045 (use (match_operand:HI 2 "memory_operand" "m,m"))
15046 (use (match_operand:HI 3 "memory_operand" "m,m"))
15047 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15048 "TARGET_USE_FANCY_MATH_387
15049 && flag_unsafe_math_optimizations"
15051 [(set_attr "type" "fistp")
15052 (set_attr "i387_cw" "floor")
15053 (set_attr "mode" "<MODE>")])
15056 [(set (match_operand:SWI24 0 "register_operand" "")
15057 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15058 UNSPEC_FIST_FLOOR))
15059 (use (match_operand:HI 2 "memory_operand" ""))
15060 (use (match_operand:HI 3 "memory_operand" ""))
15061 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15063 [(parallel [(set (match_dup 4)
15064 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15065 (use (match_dup 2))
15066 (use (match_dup 3))])
15067 (set (match_dup 0) (match_dup 4))])
15070 [(set (match_operand:SWI24 0 "memory_operand" "")
15071 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15072 UNSPEC_FIST_FLOOR))
15073 (use (match_operand:HI 2 "memory_operand" ""))
15074 (use (match_operand:HI 3 "memory_operand" ""))
15075 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15077 [(parallel [(set (match_dup 0)
15078 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_FLOOR))
15079 (use (match_dup 2))
15080 (use (match_dup 3))])])
15082 (define_expand "lfloorxf<mode>2"
15083 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15084 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15085 UNSPEC_FIST_FLOOR))
15086 (clobber (reg:CC FLAGS_REG))])]
15087 "TARGET_USE_FANCY_MATH_387
15088 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15089 && flag_unsafe_math_optimizations")
15091 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
15092 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15093 (match_operand:MODEF 1 "register_operand" "")]
15094 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15095 && !flag_trapping_math"
15097 if (TARGET_64BIT && optimize_insn_for_size_p ())
15099 ix86_expand_lfloorceil (operands[0], operands[1], true);
15103 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15104 (define_insn_and_split "frndintxf2_ceil"
15105 [(set (match_operand:XF 0 "register_operand" "")
15106 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15107 UNSPEC_FRNDINT_CEIL))
15108 (clobber (reg:CC FLAGS_REG))]
15109 "TARGET_USE_FANCY_MATH_387
15110 && flag_unsafe_math_optimizations
15111 && can_create_pseudo_p ()"
15116 ix86_optimize_mode_switching[I387_CEIL] = 1;
15118 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15119 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15121 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
15122 operands[2], operands[3]));
15125 [(set_attr "type" "frndint")
15126 (set_attr "i387_cw" "ceil")
15127 (set_attr "mode" "XF")])
15129 (define_insn "frndintxf2_ceil_i387"
15130 [(set (match_operand:XF 0 "register_operand" "=f")
15131 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15132 UNSPEC_FRNDINT_CEIL))
15133 (use (match_operand:HI 2 "memory_operand" "m"))
15134 (use (match_operand:HI 3 "memory_operand" "m"))]
15135 "TARGET_USE_FANCY_MATH_387
15136 && flag_unsafe_math_optimizations"
15137 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15138 [(set_attr "type" "frndint")
15139 (set_attr "i387_cw" "ceil")
15140 (set_attr "mode" "XF")])
15142 (define_expand "ceilxf2"
15143 [(use (match_operand:XF 0 "register_operand" ""))
15144 (use (match_operand:XF 1 "register_operand" ""))]
15145 "TARGET_USE_FANCY_MATH_387
15146 && flag_unsafe_math_optimizations"
15148 if (optimize_insn_for_size_p ())
15150 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
15154 (define_expand "ceil<mode>2"
15155 [(use (match_operand:MODEF 0 "register_operand" ""))
15156 (use (match_operand:MODEF 1 "register_operand" ""))]
15157 "(TARGET_USE_FANCY_MATH_387
15158 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15159 || TARGET_MIX_SSE_I387)
15160 && flag_unsafe_math_optimizations)
15161 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15162 && !flag_trapping_math)"
15164 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15165 && !flag_trapping_math)
15168 emit_insn (gen_sse4_1_round<mode>2
15169 (operands[0], operands[1], GEN_INT (ROUND_CEIL)));
15170 else if (optimize_insn_for_size_p ())
15172 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15173 ix86_expand_floorceil (operands[0], operands[1], false);
15175 ix86_expand_floorceildf_32 (operands[0], operands[1], false);
15181 if (optimize_insn_for_size_p ())
15184 op0 = gen_reg_rtx (XFmode);
15185 op1 = gen_reg_rtx (XFmode);
15186 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15187 emit_insn (gen_frndintxf2_ceil (op0, op1));
15189 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15194 (define_insn_and_split "*fist<mode>2_ceil_1"
15195 [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15196 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15198 (clobber (reg:CC FLAGS_REG))]
15199 "TARGET_USE_FANCY_MATH_387
15200 && flag_unsafe_math_optimizations
15201 && can_create_pseudo_p ()"
15206 ix86_optimize_mode_switching[I387_CEIL] = 1;
15208 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15209 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
15210 if (memory_operand (operands[0], VOIDmode))
15211 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
15212 operands[2], operands[3]));
15215 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
15216 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
15217 operands[2], operands[3],
15222 [(set_attr "type" "fistp")
15223 (set_attr "i387_cw" "ceil")
15224 (set_attr "mode" "<MODE>")])
15226 (define_insn "fistdi2_ceil"
15227 [(set (match_operand:DI 0 "memory_operand" "=m")
15228 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
15230 (use (match_operand:HI 2 "memory_operand" "m"))
15231 (use (match_operand:HI 3 "memory_operand" "m"))
15232 (clobber (match_scratch:XF 4 "=&1f"))]
15233 "TARGET_USE_FANCY_MATH_387
15234 && flag_unsafe_math_optimizations"
15235 "* return output_fix_trunc (insn, operands, false);"
15236 [(set_attr "type" "fistp")
15237 (set_attr "i387_cw" "ceil")
15238 (set_attr "mode" "DI")])
15240 (define_insn "fistdi2_ceil_with_temp"
15241 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
15242 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
15244 (use (match_operand:HI 2 "memory_operand" "m,m"))
15245 (use (match_operand:HI 3 "memory_operand" "m,m"))
15246 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
15247 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
15248 "TARGET_USE_FANCY_MATH_387
15249 && flag_unsafe_math_optimizations"
15251 [(set_attr "type" "fistp")
15252 (set_attr "i387_cw" "ceil")
15253 (set_attr "mode" "DI")])
15256 [(set (match_operand:DI 0 "register_operand" "")
15257 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15259 (use (match_operand:HI 2 "memory_operand" ""))
15260 (use (match_operand:HI 3 "memory_operand" ""))
15261 (clobber (match_operand:DI 4 "memory_operand" ""))
15262 (clobber (match_scratch 5 ""))]
15264 [(parallel [(set (match_dup 4)
15265 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15266 (use (match_dup 2))
15267 (use (match_dup 3))
15268 (clobber (match_dup 5))])
15269 (set (match_dup 0) (match_dup 4))])
15272 [(set (match_operand:DI 0 "memory_operand" "")
15273 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
15275 (use (match_operand:HI 2 "memory_operand" ""))
15276 (use (match_operand:HI 3 "memory_operand" ""))
15277 (clobber (match_operand:DI 4 "memory_operand" ""))
15278 (clobber (match_scratch 5 ""))]
15280 [(parallel [(set (match_dup 0)
15281 (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
15282 (use (match_dup 2))
15283 (use (match_dup 3))
15284 (clobber (match_dup 5))])])
15286 (define_insn "fist<mode>2_ceil"
15287 [(set (match_operand:SWI24 0 "memory_operand" "=m")
15288 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f")]
15290 (use (match_operand:HI 2 "memory_operand" "m"))
15291 (use (match_operand:HI 3 "memory_operand" "m"))]
15292 "TARGET_USE_FANCY_MATH_387
15293 && flag_unsafe_math_optimizations"
15294 "* return output_fix_trunc (insn, operands, false);"
15295 [(set_attr "type" "fistp")
15296 (set_attr "i387_cw" "ceil")
15297 (set_attr "mode" "<MODE>")])
15299 (define_insn "fist<mode>2_ceil_with_temp"
15300 [(set (match_operand:SWI24 0 "nonimmediate_operand" "=m,?r")
15301 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "f,f")]
15303 (use (match_operand:HI 2 "memory_operand" "m,m"))
15304 (use (match_operand:HI 3 "memory_operand" "m,m"))
15305 (clobber (match_operand:SWI24 4 "memory_operand" "=X,m"))]
15306 "TARGET_USE_FANCY_MATH_387
15307 && flag_unsafe_math_optimizations"
15309 [(set_attr "type" "fistp")
15310 (set_attr "i387_cw" "ceil")
15311 (set_attr "mode" "<MODE>")])
15314 [(set (match_operand:SWI24 0 "register_operand" "")
15315 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15317 (use (match_operand:HI 2 "memory_operand" ""))
15318 (use (match_operand:HI 3 "memory_operand" ""))
15319 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15321 [(parallel [(set (match_dup 4)
15322 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15323 (use (match_dup 2))
15324 (use (match_dup 3))])
15325 (set (match_dup 0) (match_dup 4))])
15328 [(set (match_operand:SWI24 0 "memory_operand" "")
15329 (unspec:SWI24 [(match_operand:XF 1 "register_operand" "")]
15331 (use (match_operand:HI 2 "memory_operand" ""))
15332 (use (match_operand:HI 3 "memory_operand" ""))
15333 (clobber (match_operand:SWI24 4 "memory_operand" ""))]
15335 [(parallel [(set (match_dup 0)
15336 (unspec:SWI24 [(match_dup 1)] UNSPEC_FIST_CEIL))
15337 (use (match_dup 2))
15338 (use (match_dup 3))])])
15340 (define_expand "lceilxf<mode>2"
15341 [(parallel [(set (match_operand:SWI248x 0 "nonimmediate_operand" "")
15342 (unspec:SWI248x [(match_operand:XF 1 "register_operand" "")]
15344 (clobber (reg:CC FLAGS_REG))])]
15345 "TARGET_USE_FANCY_MATH_387
15346 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
15347 && flag_unsafe_math_optimizations")
15349 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
15350 [(match_operand:SWI48 0 "nonimmediate_operand" "")
15351 (match_operand:MODEF 1 "register_operand" "")]
15352 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
15353 && !flag_trapping_math"
15355 ix86_expand_lfloorceil (operands[0], operands[1], false);
15359 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15360 (define_insn_and_split "frndintxf2_trunc"
15361 [(set (match_operand:XF 0 "register_operand" "")
15362 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15363 UNSPEC_FRNDINT_TRUNC))
15364 (clobber (reg:CC FLAGS_REG))]
15365 "TARGET_USE_FANCY_MATH_387
15366 && flag_unsafe_math_optimizations
15367 && can_create_pseudo_p ()"
15372 ix86_optimize_mode_switching[I387_TRUNC] = 1;
15374 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15375 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
15377 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
15378 operands[2], operands[3]));
15381 [(set_attr "type" "frndint")
15382 (set_attr "i387_cw" "trunc")
15383 (set_attr "mode" "XF")])
15385 (define_insn "frndintxf2_trunc_i387"
15386 [(set (match_operand:XF 0 "register_operand" "=f")
15387 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15388 UNSPEC_FRNDINT_TRUNC))
15389 (use (match_operand:HI 2 "memory_operand" "m"))
15390 (use (match_operand:HI 3 "memory_operand" "m"))]
15391 "TARGET_USE_FANCY_MATH_387
15392 && flag_unsafe_math_optimizations"
15393 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
15394 [(set_attr "type" "frndint")
15395 (set_attr "i387_cw" "trunc")
15396 (set_attr "mode" "XF")])
15398 (define_expand "btruncxf2"
15399 [(use (match_operand:XF 0 "register_operand" ""))
15400 (use (match_operand:XF 1 "register_operand" ""))]
15401 "TARGET_USE_FANCY_MATH_387
15402 && flag_unsafe_math_optimizations"
15404 if (optimize_insn_for_size_p ())
15406 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
15410 (define_expand "btrunc<mode>2"
15411 [(use (match_operand:MODEF 0 "register_operand" ""))
15412 (use (match_operand:MODEF 1 "register_operand" ""))]
15413 "(TARGET_USE_FANCY_MATH_387
15414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15415 || TARGET_MIX_SSE_I387)
15416 && flag_unsafe_math_optimizations)
15417 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15418 && !flag_trapping_math)"
15420 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15421 && !flag_trapping_math)
15424 emit_insn (gen_sse4_1_round<mode>2
15425 (operands[0], operands[1], GEN_INT (ROUND_TRUNC)));
15426 else if (optimize_insn_for_size_p ())
15428 else if (TARGET_64BIT || (<MODE>mode != DFmode))
15429 ix86_expand_trunc (operands[0], operands[1]);
15431 ix86_expand_truncdf_32 (operands[0], operands[1]);
15437 if (optimize_insn_for_size_p ())
15440 op0 = gen_reg_rtx (XFmode);
15441 op1 = gen_reg_rtx (XFmode);
15442 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15443 emit_insn (gen_frndintxf2_trunc (op0, op1));
15445 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15450 ;; Rounding mode control word calculation could clobber FLAGS_REG.
15451 (define_insn_and_split "frndintxf2_mask_pm"
15452 [(set (match_operand:XF 0 "register_operand" "")
15453 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15454 UNSPEC_FRNDINT_MASK_PM))
15455 (clobber (reg:CC FLAGS_REG))]
15456 "TARGET_USE_FANCY_MATH_387
15457 && flag_unsafe_math_optimizations
15458 && can_create_pseudo_p ()"
15463 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
15465 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
15466 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
15468 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
15469 operands[2], operands[3]));
15472 [(set_attr "type" "frndint")
15473 (set_attr "i387_cw" "mask_pm")
15474 (set_attr "mode" "XF")])
15476 (define_insn "frndintxf2_mask_pm_i387"
15477 [(set (match_operand:XF 0 "register_operand" "=f")
15478 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
15479 UNSPEC_FRNDINT_MASK_PM))
15480 (use (match_operand:HI 2 "memory_operand" "m"))
15481 (use (match_operand:HI 3 "memory_operand" "m"))]
15482 "TARGET_USE_FANCY_MATH_387
15483 && flag_unsafe_math_optimizations"
15484 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
15485 [(set_attr "type" "frndint")
15486 (set_attr "i387_cw" "mask_pm")
15487 (set_attr "mode" "XF")])
15489 (define_expand "nearbyintxf2"
15490 [(use (match_operand:XF 0 "register_operand" ""))
15491 (use (match_operand:XF 1 "register_operand" ""))]
15492 "TARGET_USE_FANCY_MATH_387
15493 && flag_unsafe_math_optimizations"
15495 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
15499 (define_expand "nearbyint<mode>2"
15500 [(use (match_operand:MODEF 0 "register_operand" ""))
15501 (use (match_operand:MODEF 1 "register_operand" ""))]
15502 "TARGET_USE_FANCY_MATH_387
15503 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15504 || TARGET_MIX_SSE_I387)
15505 && flag_unsafe_math_optimizations"
15507 rtx op0 = gen_reg_rtx (XFmode);
15508 rtx op1 = gen_reg_rtx (XFmode);
15510 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15511 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
15513 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15517 (define_insn "fxam<mode>2_i387"
15518 [(set (match_operand:HI 0 "register_operand" "=a")
15520 [(match_operand:X87MODEF 1 "register_operand" "f")]
15522 "TARGET_USE_FANCY_MATH_387"
15523 "fxam\n\tfnstsw\t%0"
15524 [(set_attr "type" "multi")
15525 (set_attr "length" "4")
15526 (set_attr "unit" "i387")
15527 (set_attr "mode" "<MODE>")])
15529 (define_insn_and_split "fxam<mode>2_i387_with_temp"
15530 [(set (match_operand:HI 0 "register_operand" "")
15532 [(match_operand:MODEF 1 "memory_operand" "")]
15534 "TARGET_USE_FANCY_MATH_387
15535 && can_create_pseudo_p ()"
15538 [(set (match_dup 2)(match_dup 1))
15540 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
15542 operands[2] = gen_reg_rtx (<MODE>mode);
15544 MEM_VOLATILE_P (operands[1]) = 1;
15546 [(set_attr "type" "multi")
15547 (set_attr "unit" "i387")
15548 (set_attr "mode" "<MODE>")])
15550 (define_expand "isinfxf2"
15551 [(use (match_operand:SI 0 "register_operand" ""))
15552 (use (match_operand:XF 1 "register_operand" ""))]
15553 "TARGET_USE_FANCY_MATH_387
15554 && TARGET_C99_FUNCTIONS"
15556 rtx mask = GEN_INT (0x45);
15557 rtx val = GEN_INT (0x05);
15561 rtx scratch = gen_reg_rtx (HImode);
15562 rtx res = gen_reg_rtx (QImode);
15564 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15566 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15567 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15568 cond = gen_rtx_fmt_ee (EQ, QImode,
15569 gen_rtx_REG (CCmode, FLAGS_REG),
15571 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15572 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15576 (define_expand "isinf<mode>2"
15577 [(use (match_operand:SI 0 "register_operand" ""))
15578 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
15579 "TARGET_USE_FANCY_MATH_387
15580 && TARGET_C99_FUNCTIONS
15581 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15583 rtx mask = GEN_INT (0x45);
15584 rtx val = GEN_INT (0x05);
15588 rtx scratch = gen_reg_rtx (HImode);
15589 rtx res = gen_reg_rtx (QImode);
15591 /* Remove excess precision by forcing value through memory. */
15592 if (memory_operand (operands[1], VOIDmode))
15593 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
15596 enum ix86_stack_slot slot = (virtuals_instantiated
15599 rtx temp = assign_386_stack_local (<MODE>mode, slot);
15601 emit_move_insn (temp, operands[1]);
15602 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
15605 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
15606 emit_insn (gen_cmpqi_ext_3 (scratch, val));
15607 cond = gen_rtx_fmt_ee (EQ, QImode,
15608 gen_rtx_REG (CCmode, FLAGS_REG),
15610 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
15611 emit_insn (gen_zero_extendqisi2 (operands[0], res));
15615 (define_expand "signbitxf2"
15616 [(use (match_operand:SI 0 "register_operand" ""))
15617 (use (match_operand:XF 1 "register_operand" ""))]
15618 "TARGET_USE_FANCY_MATH_387"
15620 rtx scratch = gen_reg_rtx (HImode);
15622 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
15623 emit_insn (gen_andsi3 (operands[0],
15624 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15628 (define_insn "movmsk_df"
15629 [(set (match_operand:SI 0 "register_operand" "=r")
15631 [(match_operand:DF 1 "register_operand" "x")]
15633 "SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH"
15634 "%vmovmskpd\t{%1, %0|%0, %1}"
15635 [(set_attr "type" "ssemov")
15636 (set_attr "prefix" "maybe_vex")
15637 (set_attr "mode" "DF")])
15639 ;; Use movmskpd in SSE mode to avoid store forwarding stall
15640 ;; for 32bit targets and movq+shrq sequence for 64bit targets.
15641 (define_expand "signbitdf2"
15642 [(use (match_operand:SI 0 "register_operand" ""))
15643 (use (match_operand:DF 1 "register_operand" ""))]
15644 "TARGET_USE_FANCY_MATH_387
15645 || (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)"
15647 if (SSE_FLOAT_MODE_P (DFmode) && TARGET_SSE_MATH)
15649 emit_insn (gen_movmsk_df (operands[0], operands[1]));
15650 emit_insn (gen_andsi3 (operands[0], operands[0], const1_rtx));
15654 rtx scratch = gen_reg_rtx (HImode);
15656 emit_insn (gen_fxamdf2_i387 (scratch, operands[1]));
15657 emit_insn (gen_andsi3 (operands[0],
15658 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15663 (define_expand "signbitsf2"
15664 [(use (match_operand:SI 0 "register_operand" ""))
15665 (use (match_operand:SF 1 "register_operand" ""))]
15666 "TARGET_USE_FANCY_MATH_387
15667 && !(SSE_FLOAT_MODE_P (SFmode) && TARGET_SSE_MATH)"
15669 rtx scratch = gen_reg_rtx (HImode);
15671 emit_insn (gen_fxamsf2_i387 (scratch, operands[1]));
15672 emit_insn (gen_andsi3 (operands[0],
15673 gen_lowpart (SImode, scratch), GEN_INT (0x200)));
15677 ;; Block operation instructions
15680 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
15683 [(set_attr "length" "1")
15684 (set_attr "length_immediate" "0")
15685 (set_attr "modrm" "0")])
15687 (define_expand "movmem<mode>"
15688 [(use (match_operand:BLK 0 "memory_operand" ""))
15689 (use (match_operand:BLK 1 "memory_operand" ""))
15690 (use (match_operand:SWI48 2 "nonmemory_operand" ""))
15691 (use (match_operand:SWI48 3 "const_int_operand" ""))
15692 (use (match_operand:SI 4 "const_int_operand" ""))
15693 (use (match_operand:SI 5 "const_int_operand" ""))]
15696 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
15697 operands[4], operands[5]))
15703 ;; Most CPUs don't like single string operations
15704 ;; Handle this case here to simplify previous expander.
15706 (define_expand "strmov"
15707 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
15708 (set (match_operand 1 "memory_operand" "") (match_dup 4))
15709 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
15710 (clobber (reg:CC FLAGS_REG))])
15711 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
15712 (clobber (reg:CC FLAGS_REG))])]
15715 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
15717 /* If .md ever supports :P for Pmode, these can be directly
15718 in the pattern above. */
15719 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
15720 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
15722 /* Can't use this if the user has appropriated esi or edi. */
15723 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15724 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
15726 emit_insn (gen_strmov_singleop (operands[0], operands[1],
15727 operands[2], operands[3],
15728 operands[5], operands[6]));
15732 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
15735 (define_expand "strmov_singleop"
15736 [(parallel [(set (match_operand 1 "memory_operand" "")
15737 (match_operand 3 "memory_operand" ""))
15738 (set (match_operand 0 "register_operand" "")
15739 (match_operand 4 "" ""))
15740 (set (match_operand 2 "register_operand" "")
15741 (match_operand 5 "" ""))])]
15743 "ix86_current_function_needs_cld = 1;")
15745 (define_insn "*strmovdi_rex_1"
15746 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
15747 (mem:DI (match_operand:DI 3 "register_operand" "1")))
15748 (set (match_operand:DI 0 "register_operand" "=D")
15749 (plus:DI (match_dup 2)
15751 (set (match_operand:DI 1 "register_operand" "=S")
15752 (plus:DI (match_dup 3)
15755 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15757 [(set_attr "type" "str")
15758 (set_attr "memory" "both")
15759 (set_attr "mode" "DI")])
15761 (define_insn "*strmovsi_1"
15762 [(set (mem:SI (match_operand:P 2 "register_operand" "0"))
15763 (mem:SI (match_operand:P 3 "register_operand" "1")))
15764 (set (match_operand:P 0 "register_operand" "=D")
15765 (plus:P (match_dup 2)
15767 (set (match_operand:P 1 "register_operand" "=S")
15768 (plus:P (match_dup 3)
15770 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15772 [(set_attr "type" "str")
15773 (set_attr "memory" "both")
15774 (set_attr "mode" "SI")])
15776 (define_insn "*strmovhi_1"
15777 [(set (mem:HI (match_operand:P 2 "register_operand" "0"))
15778 (mem:HI (match_operand:P 3 "register_operand" "1")))
15779 (set (match_operand:P 0 "register_operand" "=D")
15780 (plus:P (match_dup 2)
15782 (set (match_operand:P 1 "register_operand" "=S")
15783 (plus:P (match_dup 3)
15785 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15787 [(set_attr "type" "str")
15788 (set_attr "memory" "both")
15789 (set_attr "mode" "HI")])
15791 (define_insn "*strmovqi_1"
15792 [(set (mem:QI (match_operand:P 2 "register_operand" "0"))
15793 (mem:QI (match_operand:P 3 "register_operand" "1")))
15794 (set (match_operand:P 0 "register_operand" "=D")
15795 (plus:P (match_dup 2)
15797 (set (match_operand:P 1 "register_operand" "=S")
15798 (plus:P (match_dup 3)
15800 "!(fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15802 [(set_attr "type" "str")
15803 (set_attr "memory" "both")
15804 (set (attr "prefix_rex")
15806 (match_test "<P:MODE>mode == DImode")
15808 (const_string "*")))
15809 (set_attr "mode" "QI")])
15811 (define_expand "rep_mov"
15812 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
15813 (set (match_operand 0 "register_operand" "")
15814 (match_operand 5 "" ""))
15815 (set (match_operand 2 "register_operand" "")
15816 (match_operand 6 "" ""))
15817 (set (match_operand 1 "memory_operand" "")
15818 (match_operand 3 "memory_operand" ""))
15819 (use (match_dup 4))])]
15821 "ix86_current_function_needs_cld = 1;")
15823 (define_insn "*rep_movdi_rex64"
15824 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
15825 (set (match_operand:DI 0 "register_operand" "=D")
15826 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
15828 (match_operand:DI 3 "register_operand" "0")))
15829 (set (match_operand:DI 1 "register_operand" "=S")
15830 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
15831 (match_operand:DI 4 "register_operand" "1")))
15832 (set (mem:BLK (match_dup 3))
15833 (mem:BLK (match_dup 4)))
15834 (use (match_dup 5))]
15836 && !(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15838 [(set_attr "type" "str")
15839 (set_attr "prefix_rep" "1")
15840 (set_attr "memory" "both")
15841 (set_attr "mode" "DI")])
15843 (define_insn "*rep_movsi"
15844 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15845 (set (match_operand:P 0 "register_operand" "=D")
15846 (plus:P (ashift:P (match_operand:P 5 "register_operand" "2")
15848 (match_operand:P 3 "register_operand" "0")))
15849 (set (match_operand:P 1 "register_operand" "=S")
15850 (plus:P (ashift:P (match_dup 5) (const_int 2))
15851 (match_operand:P 4 "register_operand" "1")))
15852 (set (mem:BLK (match_dup 3))
15853 (mem:BLK (match_dup 4)))
15854 (use (match_dup 5))]
15855 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15856 "rep{%;} movs{l|d}"
15857 [(set_attr "type" "str")
15858 (set_attr "prefix_rep" "1")
15859 (set_attr "memory" "both")
15860 (set_attr "mode" "SI")])
15862 (define_insn "*rep_movqi"
15863 [(set (match_operand:P 2 "register_operand" "=c") (const_int 0))
15864 (set (match_operand:P 0 "register_operand" "=D")
15865 (plus:P (match_operand:P 3 "register_operand" "0")
15866 (match_operand:P 5 "register_operand" "2")))
15867 (set (match_operand:P 1 "register_operand" "=S")
15868 (plus:P (match_operand:P 4 "register_operand" "1") (match_dup 5)))
15869 (set (mem:BLK (match_dup 3))
15870 (mem:BLK (match_dup 4)))
15871 (use (match_dup 5))]
15872 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
15874 [(set_attr "type" "str")
15875 (set_attr "prefix_rep" "1")
15876 (set_attr "memory" "both")
15877 (set_attr "mode" "QI")])
15879 (define_expand "setmem<mode>"
15880 [(use (match_operand:BLK 0 "memory_operand" ""))
15881 (use (match_operand:SWI48 1 "nonmemory_operand" ""))
15882 (use (match_operand:QI 2 "nonmemory_operand" ""))
15883 (use (match_operand 3 "const_int_operand" ""))
15884 (use (match_operand:SI 4 "const_int_operand" ""))
15885 (use (match_operand:SI 5 "const_int_operand" ""))]
15888 if (ix86_expand_setmem (operands[0], operands[1],
15889 operands[2], operands[3],
15890 operands[4], operands[5]))
15896 ;; Most CPUs don't like single string operations
15897 ;; Handle this case here to simplify previous expander.
15899 (define_expand "strset"
15900 [(set (match_operand 1 "memory_operand" "")
15901 (match_operand 2 "register_operand" ""))
15902 (parallel [(set (match_operand 0 "register_operand" "")
15904 (clobber (reg:CC FLAGS_REG))])]
15907 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
15908 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
15910 /* If .md ever supports :P for Pmode, this can be directly
15911 in the pattern above. */
15912 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
15913 GEN_INT (GET_MODE_SIZE (GET_MODE
15915 /* Can't use this if the user has appropriated eax or edi. */
15916 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
15917 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG]))
15919 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
15925 (define_expand "strset_singleop"
15926 [(parallel [(set (match_operand 1 "memory_operand" "")
15927 (match_operand 2 "register_operand" ""))
15928 (set (match_operand 0 "register_operand" "")
15929 (match_operand 3 "" ""))])]
15931 "ix86_current_function_needs_cld = 1;")
15933 (define_insn "*strsetdi_rex_1"
15934 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
15935 (match_operand:DI 2 "register_operand" "a"))
15936 (set (match_operand:DI 0 "register_operand" "=D")
15937 (plus:DI (match_dup 1)
15940 && !(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15942 [(set_attr "type" "str")
15943 (set_attr "memory" "store")
15944 (set_attr "mode" "DI")])
15946 (define_insn "*strsetsi_1"
15947 [(set (mem:SI (match_operand:P 1 "register_operand" "0"))
15948 (match_operand:SI 2 "register_operand" "a"))
15949 (set (match_operand:P 0 "register_operand" "=D")
15950 (plus:P (match_dup 1)
15952 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15954 [(set_attr "type" "str")
15955 (set_attr "memory" "store")
15956 (set_attr "mode" "SI")])
15958 (define_insn "*strsethi_1"
15959 [(set (mem:HI (match_operand:P 1 "register_operand" "0"))
15960 (match_operand:HI 2 "register_operand" "a"))
15961 (set (match_operand:P 0 "register_operand" "=D")
15962 (plus:P (match_dup 1)
15964 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15966 [(set_attr "type" "str")
15967 (set_attr "memory" "store")
15968 (set_attr "mode" "HI")])
15970 (define_insn "*strsetqi_1"
15971 [(set (mem:QI (match_operand:P 1 "register_operand" "0"))
15972 (match_operand:QI 2 "register_operand" "a"))
15973 (set (match_operand:P 0 "register_operand" "=D")
15974 (plus:P (match_dup 1)
15976 "!(fixed_regs[AX_REG] || fixed_regs[DI_REG])"
15978 [(set_attr "type" "str")
15979 (set_attr "memory" "store")
15980 (set (attr "prefix_rex")
15982 (match_test "<P:MODE>mode == DImode")
15984 (const_string "*")))
15985 (set_attr "mode" "QI")])
15987 (define_expand "rep_stos"
15988 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
15989 (set (match_operand 0 "register_operand" "")
15990 (match_operand 4 "" ""))
15991 (set (match_operand 2 "memory_operand" "") (const_int 0))
15992 (use (match_operand 3 "register_operand" ""))
15993 (use (match_dup 1))])]
15995 "ix86_current_function_needs_cld = 1;")
15997 (define_insn "*rep_stosdi_rex64"
15998 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
15999 (set (match_operand:DI 0 "register_operand" "=D")
16000 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
16002 (match_operand:DI 3 "register_operand" "0")))
16003 (set (mem:BLK (match_dup 3))
16005 (use (match_operand:DI 2 "register_operand" "a"))
16006 (use (match_dup 4))]
16008 && !(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16010 [(set_attr "type" "str")
16011 (set_attr "prefix_rep" "1")
16012 (set_attr "memory" "store")
16013 (set_attr "mode" "DI")])
16015 (define_insn "*rep_stossi"
16016 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16017 (set (match_operand:P 0 "register_operand" "=D")
16018 (plus:P (ashift:P (match_operand:P 4 "register_operand" "1")
16020 (match_operand:P 3 "register_operand" "0")))
16021 (set (mem:BLK (match_dup 3))
16023 (use (match_operand:SI 2 "register_operand" "a"))
16024 (use (match_dup 4))]
16025 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16026 "rep{%;} stos{l|d}"
16027 [(set_attr "type" "str")
16028 (set_attr "prefix_rep" "1")
16029 (set_attr "memory" "store")
16030 (set_attr "mode" "SI")])
16032 (define_insn "*rep_stosqi"
16033 [(set (match_operand:P 1 "register_operand" "=c") (const_int 0))
16034 (set (match_operand:P 0 "register_operand" "=D")
16035 (plus:P (match_operand:P 3 "register_operand" "0")
16036 (match_operand:P 4 "register_operand" "1")))
16037 (set (mem:BLK (match_dup 3))
16039 (use (match_operand:QI 2 "register_operand" "a"))
16040 (use (match_dup 4))]
16041 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16043 [(set_attr "type" "str")
16044 (set_attr "prefix_rep" "1")
16045 (set_attr "memory" "store")
16046 (set (attr "prefix_rex")
16048 (match_test "<P:MODE>mode == DImode")
16050 (const_string "*")))
16051 (set_attr "mode" "QI")])
16053 (define_expand "cmpstrnsi"
16054 [(set (match_operand:SI 0 "register_operand" "")
16055 (compare:SI (match_operand:BLK 1 "general_operand" "")
16056 (match_operand:BLK 2 "general_operand" "")))
16057 (use (match_operand 3 "general_operand" ""))
16058 (use (match_operand 4 "immediate_operand" ""))]
16061 rtx addr1, addr2, out, outlow, count, countreg, align;
16063 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
16066 /* Can't use this if the user has appropriated ecx, esi or edi. */
16067 if (fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])
16072 out = gen_reg_rtx (SImode);
16074 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
16075 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
16076 if (addr1 != XEXP (operands[1], 0))
16077 operands[1] = replace_equiv_address_nv (operands[1], addr1);
16078 if (addr2 != XEXP (operands[2], 0))
16079 operands[2] = replace_equiv_address_nv (operands[2], addr2);
16081 count = operands[3];
16082 countreg = ix86_zero_extend_to_Pmode (count);
16084 /* %%% Iff we are testing strict equality, we can use known alignment
16085 to good advantage. This may be possible with combine, particularly
16086 once cc0 is dead. */
16087 align = operands[4];
16089 if (CONST_INT_P (count))
16091 if (INTVAL (count) == 0)
16093 emit_move_insn (operands[0], const0_rtx);
16096 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
16097 operands[1], operands[2]));
16101 rtx (*gen_cmp) (rtx, rtx);
16103 gen_cmp = (TARGET_64BIT
16104 ? gen_cmpdi_1 : gen_cmpsi_1);
16106 emit_insn (gen_cmp (countreg, countreg));
16107 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
16108 operands[1], operands[2]));
16111 outlow = gen_lowpart (QImode, out);
16112 emit_insn (gen_cmpintqi (outlow));
16113 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
16115 if (operands[0] != out)
16116 emit_move_insn (operands[0], out);
16121 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
16123 (define_expand "cmpintqi"
16124 [(set (match_dup 1)
16125 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16127 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16128 (parallel [(set (match_operand:QI 0 "register_operand" "")
16129 (minus:QI (match_dup 1)
16131 (clobber (reg:CC FLAGS_REG))])]
16134 operands[1] = gen_reg_rtx (QImode);
16135 operands[2] = gen_reg_rtx (QImode);
16138 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
16139 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
16141 (define_expand "cmpstrnqi_nz_1"
16142 [(parallel [(set (reg:CC FLAGS_REG)
16143 (compare:CC (match_operand 4 "memory_operand" "")
16144 (match_operand 5 "memory_operand" "")))
16145 (use (match_operand 2 "register_operand" ""))
16146 (use (match_operand:SI 3 "immediate_operand" ""))
16147 (clobber (match_operand 0 "register_operand" ""))
16148 (clobber (match_operand 1 "register_operand" ""))
16149 (clobber (match_dup 2))])]
16151 "ix86_current_function_needs_cld = 1;")
16153 (define_insn "*cmpstrnqi_nz_1"
16154 [(set (reg:CC FLAGS_REG)
16155 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16156 (mem:BLK (match_operand:P 5 "register_operand" "1"))))
16157 (use (match_operand:P 6 "register_operand" "2"))
16158 (use (match_operand:SI 3 "immediate_operand" "i"))
16159 (clobber (match_operand:P 0 "register_operand" "=S"))
16160 (clobber (match_operand:P 1 "register_operand" "=D"))
16161 (clobber (match_operand:P 2 "register_operand" "=c"))]
16162 "!(fixed_regs[CX_REG] || fixed_regs[SI_REG] || fixed_regs[DI_REG])"
16164 [(set_attr "type" "str")
16165 (set_attr "mode" "QI")
16166 (set (attr "prefix_rex")
16168 (match_test "<P:MODE>mode == DImode")
16170 (const_string "*")))
16171 (set_attr "prefix_rep" "1")])
16173 ;; The same, but the count is not known to not be zero.
16175 (define_expand "cmpstrnqi_1"
16176 [(parallel [(set (reg:CC FLAGS_REG)
16177 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
16179 (compare:CC (match_operand 4 "memory_operand" "")
16180 (match_operand 5 "memory_operand" ""))
16182 (use (match_operand:SI 3 "immediate_operand" ""))
16183 (use (reg:CC FLAGS_REG))
16184 (clobber (match_operand 0 "register_operand" ""))
16185 (clobber (match_operand 1 "register_operand" ""))
16186 (clobber (match_dup 2))])]
16188 "ix86_current_function_needs_cld = 1;")
16190 (define_insn "*cmpstrnqi_1"
16191 [(set (reg:CC FLAGS_REG)
16192 (if_then_else:CC (ne (match_operand:P 6 "register_operand" "2")
16194 (compare:CC (mem:BLK (match_operand:P 4 "register_operand" "0"))
16195 (mem:BLK (match_operand:P 5 "register_operand" "1")))
16197 (use (match_operand:SI 3 "immediate_operand" "i"))
16198 (use (reg:CC FLAGS_REG))
16199 (clobber (match_operand:P 0 "register_operand" "=S"))
16200 (clobber (match_operand:P 1 "register_operand" "=D"))
16201 (clobber (match_operand:P 2 "register_operand" "=c"))]
16202 "!(fixed_regs[CX_REG] || fixed_regs[SI_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 (define_expand "strlen<mode>"
16214 [(set (match_operand:P 0 "register_operand" "")
16215 (unspec:P [(match_operand:BLK 1 "general_operand" "")
16216 (match_operand:QI 2 "immediate_operand" "")
16217 (match_operand 3 "immediate_operand" "")]
16221 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
16227 (define_expand "strlenqi_1"
16228 [(parallel [(set (match_operand 0 "register_operand" "")
16229 (match_operand 2 "" ""))
16230 (clobber (match_operand 1 "register_operand" ""))
16231 (clobber (reg:CC FLAGS_REG))])]
16233 "ix86_current_function_needs_cld = 1;")
16235 (define_insn "*strlenqi_1"
16236 [(set (match_operand:P 0 "register_operand" "=&c")
16237 (unspec:P [(mem:BLK (match_operand:P 5 "register_operand" "1"))
16238 (match_operand:QI 2 "register_operand" "a")
16239 (match_operand:P 3 "immediate_operand" "i")
16240 (match_operand:P 4 "register_operand" "0")] UNSPEC_SCAS))
16241 (clobber (match_operand:P 1 "register_operand" "=D"))
16242 (clobber (reg:CC FLAGS_REG))]
16243 "!(fixed_regs[AX_REG] || fixed_regs[CX_REG] || fixed_regs[DI_REG])"
16245 [(set_attr "type" "str")
16246 (set_attr "mode" "QI")
16247 (set (attr "prefix_rex")
16249 (match_test "<P:MODE>mode == DImode")
16251 (const_string "*")))
16252 (set_attr "prefix_rep" "1")])
16254 ;; Peephole optimizations to clean up after cmpstrn*. This should be
16255 ;; handled in combine, but it is not currently up to the task.
16256 ;; When used for their truth value, the cmpstrn* expanders generate
16265 ;; The intermediate three instructions are unnecessary.
16267 ;; This one handles cmpstrn*_nz_1...
16270 (set (reg:CC FLAGS_REG)
16271 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16272 (mem:BLK (match_operand 5 "register_operand" ""))))
16273 (use (match_operand 6 "register_operand" ""))
16274 (use (match_operand:SI 3 "immediate_operand" ""))
16275 (clobber (match_operand 0 "register_operand" ""))
16276 (clobber (match_operand 1 "register_operand" ""))
16277 (clobber (match_operand 2 "register_operand" ""))])
16278 (set (match_operand:QI 7 "register_operand" "")
16279 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16280 (set (match_operand:QI 8 "register_operand" "")
16281 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16282 (set (reg FLAGS_REG)
16283 (compare (match_dup 7) (match_dup 8)))
16285 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16287 (set (reg:CC FLAGS_REG)
16288 (compare:CC (mem:BLK (match_dup 4))
16289 (mem:BLK (match_dup 5))))
16290 (use (match_dup 6))
16291 (use (match_dup 3))
16292 (clobber (match_dup 0))
16293 (clobber (match_dup 1))
16294 (clobber (match_dup 2))])])
16296 ;; ...and this one handles cmpstrn*_1.
16299 (set (reg:CC FLAGS_REG)
16300 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
16302 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
16303 (mem:BLK (match_operand 5 "register_operand" "")))
16305 (use (match_operand:SI 3 "immediate_operand" ""))
16306 (use (reg:CC FLAGS_REG))
16307 (clobber (match_operand 0 "register_operand" ""))
16308 (clobber (match_operand 1 "register_operand" ""))
16309 (clobber (match_operand 2 "register_operand" ""))])
16310 (set (match_operand:QI 7 "register_operand" "")
16311 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
16312 (set (match_operand:QI 8 "register_operand" "")
16313 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
16314 (set (reg FLAGS_REG)
16315 (compare (match_dup 7) (match_dup 8)))
16317 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
16319 (set (reg:CC FLAGS_REG)
16320 (if_then_else:CC (ne (match_dup 6)
16322 (compare:CC (mem:BLK (match_dup 4))
16323 (mem:BLK (match_dup 5)))
16325 (use (match_dup 3))
16326 (use (reg:CC FLAGS_REG))
16327 (clobber (match_dup 0))
16328 (clobber (match_dup 1))
16329 (clobber (match_dup 2))])])
16331 ;; Conditional move instructions.
16333 (define_expand "mov<mode>cc"
16334 [(set (match_operand:SWIM 0 "register_operand" "")
16335 (if_then_else:SWIM (match_operand 1 "ordered_comparison_operator" "")
16336 (match_operand:SWIM 2 "<general_operand>" "")
16337 (match_operand:SWIM 3 "<general_operand>" "")))]
16339 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
16341 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
16342 ;; the register first winds up with `sbbl $0,reg', which is also weird.
16343 ;; So just document what we're doing explicitly.
16345 (define_expand "x86_mov<mode>cc_0_m1"
16347 [(set (match_operand:SWI48 0 "register_operand" "")
16348 (if_then_else:SWI48
16349 (match_operator:SWI48 2 "ix86_carry_flag_operator"
16350 [(match_operand 1 "flags_reg_operand" "")
16354 (clobber (reg:CC FLAGS_REG))])])
16356 (define_insn "*x86_mov<mode>cc_0_m1"
16357 [(set (match_operand:SWI48 0 "register_operand" "=r")
16358 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16359 [(reg FLAGS_REG) (const_int 0)])
16362 (clobber (reg:CC FLAGS_REG))]
16364 "sbb{<imodesuffix>}\t%0, %0"
16365 ; Since we don't have the proper number of operands for an alu insn,
16366 ; fill in all the blanks.
16367 [(set_attr "type" "alu")
16368 (set_attr "use_carry" "1")
16369 (set_attr "pent_pair" "pu")
16370 (set_attr "memory" "none")
16371 (set_attr "imm_disp" "false")
16372 (set_attr "mode" "<MODE>")
16373 (set_attr "length_immediate" "0")])
16375 (define_insn "*x86_mov<mode>cc_0_m1_se"
16376 [(set (match_operand:SWI48 0 "register_operand" "=r")
16377 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16378 [(reg FLAGS_REG) (const_int 0)])
16381 (clobber (reg:CC FLAGS_REG))]
16383 "sbb{<imodesuffix>}\t%0, %0"
16384 [(set_attr "type" "alu")
16385 (set_attr "use_carry" "1")
16386 (set_attr "pent_pair" "pu")
16387 (set_attr "memory" "none")
16388 (set_attr "imm_disp" "false")
16389 (set_attr "mode" "<MODE>")
16390 (set_attr "length_immediate" "0")])
16392 (define_insn "*x86_mov<mode>cc_0_m1_neg"
16393 [(set (match_operand:SWI48 0 "register_operand" "=r")
16394 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
16395 [(reg FLAGS_REG) (const_int 0)])))
16396 (clobber (reg:CC FLAGS_REG))]
16398 "sbb{<imodesuffix>}\t%0, %0"
16399 [(set_attr "type" "alu")
16400 (set_attr "use_carry" "1")
16401 (set_attr "pent_pair" "pu")
16402 (set_attr "memory" "none")
16403 (set_attr "imm_disp" "false")
16404 (set_attr "mode" "<MODE>")
16405 (set_attr "length_immediate" "0")])
16407 (define_insn "*mov<mode>cc_noc"
16408 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
16409 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
16410 [(reg FLAGS_REG) (const_int 0)])
16411 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
16412 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
16413 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16415 cmov%O2%C1\t{%2, %0|%0, %2}
16416 cmov%O2%c1\t{%3, %0|%0, %3}"
16417 [(set_attr "type" "icmov")
16418 (set_attr "mode" "<MODE>")])
16420 (define_insn "*movqicc_noc"
16421 [(set (match_operand:QI 0 "register_operand" "=r,r")
16422 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
16423 [(reg FLAGS_REG) (const_int 0)])
16424 (match_operand:QI 2 "register_operand" "r,0")
16425 (match_operand:QI 3 "register_operand" "0,r")))]
16426 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
16428 [(set_attr "type" "icmov")
16429 (set_attr "mode" "QI")])
16432 [(set (match_operand 0 "register_operand")
16433 (if_then_else (match_operator 1 "ix86_comparison_operator"
16434 [(reg FLAGS_REG) (const_int 0)])
16435 (match_operand 2 "register_operand")
16436 (match_operand 3 "register_operand")))]
16437 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL
16438 && (GET_MODE (operands[0]) == QImode
16439 || GET_MODE (operands[0]) == HImode)
16440 && reload_completed"
16441 [(set (match_dup 0)
16442 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
16444 operands[0] = gen_lowpart (SImode, operands[0]);
16445 operands[2] = gen_lowpart (SImode, operands[2]);
16446 operands[3] = gen_lowpart (SImode, operands[3]);
16449 (define_expand "mov<mode>cc"
16450 [(set (match_operand:X87MODEF 0 "register_operand" "")
16451 (if_then_else:X87MODEF
16452 (match_operand 1 "ix86_fp_comparison_operator" "")
16453 (match_operand:X87MODEF 2 "register_operand" "")
16454 (match_operand:X87MODEF 3 "register_operand" "")))]
16455 "(TARGET_80387 && TARGET_CMOVE)
16456 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16457 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
16459 (define_insn "*movxfcc_1"
16460 [(set (match_operand:XF 0 "register_operand" "=f,f")
16461 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
16462 [(reg FLAGS_REG) (const_int 0)])
16463 (match_operand:XF 2 "register_operand" "f,0")
16464 (match_operand:XF 3 "register_operand" "0,f")))]
16465 "TARGET_80387 && TARGET_CMOVE"
16467 fcmov%F1\t{%2, %0|%0, %2}
16468 fcmov%f1\t{%3, %0|%0, %3}"
16469 [(set_attr "type" "fcmov")
16470 (set_attr "mode" "XF")])
16472 (define_insn "*movdfcc_1_rex64"
16473 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
16474 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16475 [(reg FLAGS_REG) (const_int 0)])
16476 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16477 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16478 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16479 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16481 fcmov%F1\t{%2, %0|%0, %2}
16482 fcmov%f1\t{%3, %0|%0, %3}
16483 cmov%O2%C1\t{%2, %0|%0, %2}
16484 cmov%O2%c1\t{%3, %0|%0, %3}"
16485 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16486 (set_attr "mode" "DF,DF,DI,DI")])
16488 (define_insn "*movdfcc_1"
16489 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
16490 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16491 [(reg FLAGS_REG) (const_int 0)])
16492 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
16493 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
16494 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
16495 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16497 fcmov%F1\t{%2, %0|%0, %2}
16498 fcmov%f1\t{%3, %0|%0, %3}
16501 [(set_attr "type" "fcmov,fcmov,multi,multi")
16502 (set_attr "mode" "DF,DF,DI,DI")])
16505 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand")
16506 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
16507 [(reg FLAGS_REG) (const_int 0)])
16508 (match_operand:DF 2 "nonimmediate_operand")
16509 (match_operand:DF 3 "nonimmediate_operand")))]
16510 "!TARGET_64BIT && reload_completed"
16511 [(set (match_dup 2)
16512 (if_then_else:SI (match_dup 1) (match_dup 4) (match_dup 5)))
16514 (if_then_else:SI (match_dup 1) (match_dup 6) (match_dup 7)))]
16516 split_double_mode (DImode, &operands[2], 2, &operands[4], &operands[6]);
16517 split_double_mode (DImode, &operands[0], 1, &operands[2], &operands[3]);
16520 (define_insn "*movsfcc_1_387"
16521 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
16522 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
16523 [(reg FLAGS_REG) (const_int 0)])
16524 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
16525 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
16526 "TARGET_80387 && TARGET_CMOVE
16527 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
16529 fcmov%F1\t{%2, %0|%0, %2}
16530 fcmov%f1\t{%3, %0|%0, %3}
16531 cmov%O2%C1\t{%2, %0|%0, %2}
16532 cmov%O2%c1\t{%3, %0|%0, %3}"
16533 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
16534 (set_attr "mode" "SF,SF,SI,SI")])
16536 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
16537 ;; the scalar versions to have only XMM registers as operands.
16539 ;; XOP conditional move
16540 (define_insn "*xop_pcmov_<mode>"
16541 [(set (match_operand:MODEF 0 "register_operand" "=x")
16542 (if_then_else:MODEF
16543 (match_operand:MODEF 1 "register_operand" "x")
16544 (match_operand:MODEF 2 "register_operand" "x")
16545 (match_operand:MODEF 3 "register_operand" "x")))]
16547 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
16548 [(set_attr "type" "sse4arg")])
16550 ;; These versions of the min/max patterns are intentionally ignorant of
16551 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
16552 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
16553 ;; are undefined in this condition, we're certain this is correct.
16555 (define_insn "<code><mode>3"
16556 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16558 (match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16559 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")))]
16560 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16562 <maxmin_float><ssemodesuffix>\t{%2, %0|%0, %2}
16563 v<maxmin_float><ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16564 [(set_attr "isa" "noavx,avx")
16565 (set_attr "prefix" "orig,vex")
16566 (set_attr "type" "sseadd")
16567 (set_attr "mode" "<MODE>")])
16569 ;; These versions of the min/max patterns implement exactly the operations
16570 ;; min = (op1 < op2 ? op1 : op2)
16571 ;; max = (!(op1 < op2) ? op1 : op2)
16572 ;; Their operands are not commutative, and thus they may be used in the
16573 ;; presence of -0.0 and NaN.
16575 (define_insn "*ieee_smin<mode>3"
16576 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16578 [(match_operand:MODEF 1 "register_operand" "0,x")
16579 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16581 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16583 min<ssemodesuffix>\t{%2, %0|%0, %2}
16584 vmin<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16585 [(set_attr "isa" "noavx,avx")
16586 (set_attr "prefix" "orig,vex")
16587 (set_attr "type" "sseadd")
16588 (set_attr "mode" "<MODE>")])
16590 (define_insn "*ieee_smax<mode>3"
16591 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
16593 [(match_operand:MODEF 1 "register_operand" "0,x")
16594 (match_operand:MODEF 2 "nonimmediate_operand" "xm,xm")]
16596 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16598 max<ssemodesuffix>\t{%2, %0|%0, %2}
16599 vmax<ssemodesuffix>\t{%2, %1, %0|%0, %1, %2}"
16600 [(set_attr "isa" "noavx,avx")
16601 (set_attr "prefix" "orig,vex")
16602 (set_attr "type" "sseadd")
16603 (set_attr "mode" "<MODE>")])
16605 ;; Make two stack loads independent:
16607 ;; fld %st(0) -> fld bb
16608 ;; fmul bb fmul %st(1), %st
16610 ;; Actually we only match the last two instructions for simplicity.
16612 [(set (match_operand 0 "fp_register_operand" "")
16613 (match_operand 1 "fp_register_operand" ""))
16615 (match_operator 2 "binary_fp_operator"
16617 (match_operand 3 "memory_operand" "")]))]
16618 "REGNO (operands[0]) != REGNO (operands[1])"
16619 [(set (match_dup 0) (match_dup 3))
16620 (set (match_dup 0) (match_dup 4))]
16622 ;; The % modifier is not operational anymore in peephole2's, so we have to
16623 ;; swap the operands manually in the case of addition and multiplication.
16627 if (COMMUTATIVE_ARITH_P (operands[2]))
16628 op0 = operands[0], op1 = operands[1];
16630 op0 = operands[1], op1 = operands[0];
16632 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]),
16633 GET_MODE (operands[2]),
16637 ;; Conditional addition patterns
16638 (define_expand "add<mode>cc"
16639 [(match_operand:SWI 0 "register_operand" "")
16640 (match_operand 1 "ordered_comparison_operator" "")
16641 (match_operand:SWI 2 "register_operand" "")
16642 (match_operand:SWI 3 "const_int_operand" "")]
16644 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
16646 ;; Misc patterns (?)
16648 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
16649 ;; Otherwise there will be nothing to keep
16651 ;; [(set (reg ebp) (reg esp))]
16652 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
16653 ;; (clobber (eflags)]
16654 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
16656 ;; in proper program order.
16658 (define_insn "pro_epilogue_adjust_stack_<mode>_add"
16659 [(set (match_operand:P 0 "register_operand" "=r,r")
16660 (plus:P (match_operand:P 1 "register_operand" "0,r")
16661 (match_operand:P 2 "<nonmemory_operand>" "r<i>,l<i>")))
16662 (clobber (reg:CC FLAGS_REG))
16663 (clobber (mem:BLK (scratch)))]
16666 switch (get_attr_type (insn))
16669 return "mov{<imodesuffix>}\t{%1, %0|%0, %1}";
16672 gcc_assert (rtx_equal_p (operands[0], operands[1]));
16673 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
16674 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
16676 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
16679 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
16680 return "lea{<imodesuffix>}\t{%E2, %0|%0, %E2}";
16683 [(set (attr "type")
16684 (cond [(and (eq_attr "alternative" "0")
16685 (not (match_test "TARGET_OPT_AGU")))
16686 (const_string "alu")
16687 (match_operand:<MODE> 2 "const0_operand" "")
16688 (const_string "imov")
16690 (const_string "lea")))
16691 (set (attr "length_immediate")
16692 (cond [(eq_attr "type" "imov")
16694 (and (eq_attr "type" "alu")
16695 (match_operand 2 "const128_operand" ""))
16698 (const_string "*")))
16699 (set_attr "mode" "<MODE>")])
16701 (define_insn "pro_epilogue_adjust_stack_<mode>_sub"
16702 [(set (match_operand:P 0 "register_operand" "=r")
16703 (minus:P (match_operand:P 1 "register_operand" "0")
16704 (match_operand:P 2 "register_operand" "r")))
16705 (clobber (reg:CC FLAGS_REG))
16706 (clobber (mem:BLK (scratch)))]
16708 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
16709 [(set_attr "type" "alu")
16710 (set_attr "mode" "<MODE>")])
16712 (define_insn "allocate_stack_worker_probe_<mode>"
16713 [(set (match_operand:P 0 "register_operand" "=a")
16714 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16715 UNSPECV_STACK_PROBE))
16716 (clobber (reg:CC FLAGS_REG))]
16717 "ix86_target_stack_probe ()"
16718 "call\t___chkstk_ms"
16719 [(set_attr "type" "multi")
16720 (set_attr "length" "5")])
16722 (define_expand "allocate_stack"
16723 [(match_operand 0 "register_operand" "")
16724 (match_operand 1 "general_operand" "")]
16725 "ix86_target_stack_probe ()"
16729 #ifndef CHECK_STACK_LIMIT
16730 #define CHECK_STACK_LIMIT 0
16733 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
16734 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
16736 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
16737 stack_pointer_rtx, 0, OPTAB_DIRECT);
16738 if (x != stack_pointer_rtx)
16739 emit_move_insn (stack_pointer_rtx, x);
16743 x = copy_to_mode_reg (Pmode, operands[1]);
16745 emit_insn (gen_allocate_stack_worker_probe_di (x, x));
16747 emit_insn (gen_allocate_stack_worker_probe_si (x, x));
16748 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, x,
16749 stack_pointer_rtx, 0, OPTAB_DIRECT);
16750 if (x != stack_pointer_rtx)
16751 emit_move_insn (stack_pointer_rtx, x);
16754 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
16758 ;; Use IOR for stack probes, this is shorter.
16759 (define_expand "probe_stack"
16760 [(match_operand 0 "memory_operand" "")]
16763 rtx (*gen_ior3) (rtx, rtx, rtx);
16765 gen_ior3 = (GET_MODE (operands[0]) == DImode
16766 ? gen_iordi3 : gen_iorsi3);
16768 emit_insn (gen_ior3 (operands[0], operands[0], const0_rtx));
16772 (define_insn "adjust_stack_and_probe<mode>"
16773 [(set (match_operand:P 0 "register_operand" "=r")
16774 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")]
16775 UNSPECV_PROBE_STACK_RANGE))
16776 (set (reg:P SP_REG)
16777 (minus:P (reg:P SP_REG) (match_operand:P 2 "const_int_operand" "n")))
16778 (clobber (reg:CC FLAGS_REG))
16779 (clobber (mem:BLK (scratch)))]
16781 "* return output_adjust_stack_and_probe (operands[0]);"
16782 [(set_attr "type" "multi")])
16784 (define_insn "probe_stack_range<mode>"
16785 [(set (match_operand:P 0 "register_operand" "=r")
16786 (unspec_volatile:P [(match_operand:P 1 "register_operand" "0")
16787 (match_operand:P 2 "const_int_operand" "n")]
16788 UNSPECV_PROBE_STACK_RANGE))
16789 (clobber (reg:CC FLAGS_REG))]
16791 "* return output_probe_stack_range (operands[0], operands[2]);"
16792 [(set_attr "type" "multi")])
16794 (define_expand "builtin_setjmp_receiver"
16795 [(label_ref (match_operand 0 "" ""))]
16796 "!TARGET_64BIT && flag_pic"
16802 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
16803 rtx label_rtx = gen_label_rtx ();
16804 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
16805 xops[0] = xops[1] = picreg;
16806 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
16807 ix86_expand_binary_operator (MINUS, SImode, xops);
16811 emit_insn (gen_set_got (pic_offset_table_rtx));
16815 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
16818 [(set (match_operand 0 "register_operand" "")
16819 (match_operator 3 "promotable_binary_operator"
16820 [(match_operand 1 "register_operand" "")
16821 (match_operand 2 "aligned_operand" "")]))
16822 (clobber (reg:CC FLAGS_REG))]
16823 "! TARGET_PARTIAL_REG_STALL && reload_completed
16824 && ((GET_MODE (operands[0]) == HImode
16825 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
16826 /* ??? next two lines just !satisfies_constraint_K (...) */
16827 || !CONST_INT_P (operands[2])
16828 || satisfies_constraint_K (operands[2])))
16829 || (GET_MODE (operands[0]) == QImode
16830 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
16831 [(parallel [(set (match_dup 0)
16832 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
16833 (clobber (reg:CC FLAGS_REG))])]
16835 operands[0] = gen_lowpart (SImode, operands[0]);
16836 operands[1] = gen_lowpart (SImode, operands[1]);
16837 if (GET_CODE (operands[3]) != ASHIFT)
16838 operands[2] = gen_lowpart (SImode, operands[2]);
16839 PUT_MODE (operands[3], SImode);
16842 ; Promote the QImode tests, as i386 has encoding of the AND
16843 ; instruction with 32-bit sign-extended immediate and thus the
16844 ; instruction size is unchanged, except in the %eax case for
16845 ; which it is increased by one byte, hence the ! optimize_size.
16847 [(set (match_operand 0 "flags_reg_operand" "")
16848 (match_operator 2 "compare_operator"
16849 [(and (match_operand 3 "aligned_operand" "")
16850 (match_operand 4 "const_int_operand" ""))
16852 (set (match_operand 1 "register_operand" "")
16853 (and (match_dup 3) (match_dup 4)))]
16854 "! TARGET_PARTIAL_REG_STALL && reload_completed
16855 && optimize_insn_for_speed_p ()
16856 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
16857 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
16858 /* Ensure that the operand will remain sign-extended immediate. */
16859 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
16860 [(parallel [(set (match_dup 0)
16861 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
16864 (and:SI (match_dup 3) (match_dup 4)))])]
16867 = gen_int_mode (INTVAL (operands[4])
16868 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
16869 operands[1] = gen_lowpart (SImode, operands[1]);
16870 operands[3] = gen_lowpart (SImode, operands[3]);
16873 ; Don't promote the QImode tests, as i386 doesn't have encoding of
16874 ; the TEST instruction with 32-bit sign-extended immediate and thus
16875 ; the instruction size would at least double, which is not what we
16876 ; want even with ! optimize_size.
16878 [(set (match_operand 0 "flags_reg_operand" "")
16879 (match_operator 1 "compare_operator"
16880 [(and (match_operand:HI 2 "aligned_operand" "")
16881 (match_operand:HI 3 "const_int_operand" ""))
16883 "! TARGET_PARTIAL_REG_STALL && reload_completed
16884 && ! TARGET_FAST_PREFIX
16885 && optimize_insn_for_speed_p ()
16886 /* Ensure that the operand will remain sign-extended immediate. */
16887 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
16888 [(set (match_dup 0)
16889 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
16893 = gen_int_mode (INTVAL (operands[3])
16894 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
16895 operands[2] = gen_lowpart (SImode, operands[2]);
16899 [(set (match_operand 0 "register_operand" "")
16900 (neg (match_operand 1 "register_operand" "")))
16901 (clobber (reg:CC FLAGS_REG))]
16902 "! TARGET_PARTIAL_REG_STALL && reload_completed
16903 && (GET_MODE (operands[0]) == HImode
16904 || (GET_MODE (operands[0]) == QImode
16905 && (TARGET_PROMOTE_QImode
16906 || optimize_insn_for_size_p ())))"
16907 [(parallel [(set (match_dup 0)
16908 (neg:SI (match_dup 1)))
16909 (clobber (reg:CC FLAGS_REG))])]
16911 operands[0] = gen_lowpart (SImode, operands[0]);
16912 operands[1] = gen_lowpart (SImode, operands[1]);
16916 [(set (match_operand 0 "register_operand" "")
16917 (not (match_operand 1 "register_operand" "")))]
16918 "! TARGET_PARTIAL_REG_STALL && reload_completed
16919 && (GET_MODE (operands[0]) == HImode
16920 || (GET_MODE (operands[0]) == QImode
16921 && (TARGET_PROMOTE_QImode
16922 || optimize_insn_for_size_p ())))"
16923 [(set (match_dup 0)
16924 (not:SI (match_dup 1)))]
16926 operands[0] = gen_lowpart (SImode, operands[0]);
16927 operands[1] = gen_lowpart (SImode, operands[1]);
16930 ;; RTL Peephole optimizations, run before sched2. These primarily look to
16931 ;; transform a complex memory operation into two memory to register operations.
16933 ;; Don't push memory operands
16935 [(set (match_operand:SWI 0 "push_operand" "")
16936 (match_operand:SWI 1 "memory_operand" ""))
16937 (match_scratch:SWI 2 "<r>")]
16938 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16939 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16940 [(set (match_dup 2) (match_dup 1))
16941 (set (match_dup 0) (match_dup 2))])
16943 ;; We need to handle SFmode only, because DFmode and XFmode are split to
16946 [(set (match_operand:SF 0 "push_operand" "")
16947 (match_operand:SF 1 "memory_operand" ""))
16948 (match_scratch:SF 2 "r")]
16949 "!(TARGET_PUSH_MEMORY || optimize_insn_for_size_p ())
16950 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
16951 [(set (match_dup 2) (match_dup 1))
16952 (set (match_dup 0) (match_dup 2))])
16954 ;; Don't move an immediate directly to memory when the instruction
16957 [(match_scratch:SWI124 1 "<r>")
16958 (set (match_operand:SWI124 0 "memory_operand" "")
16960 "optimize_insn_for_speed_p ()
16961 && !TARGET_USE_MOV0
16962 && TARGET_SPLIT_LONG_MOVES
16963 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
16964 && peep2_regno_dead_p (0, FLAGS_REG)"
16965 [(parallel [(set (match_dup 2) (const_int 0))
16966 (clobber (reg:CC FLAGS_REG))])
16967 (set (match_dup 0) (match_dup 1))]
16968 "operands[2] = gen_lowpart (SImode, operands[1]);")
16971 [(match_scratch:SWI124 2 "<r>")
16972 (set (match_operand:SWI124 0 "memory_operand" "")
16973 (match_operand:SWI124 1 "immediate_operand" ""))]
16974 "optimize_insn_for_speed_p ()
16975 && TARGET_SPLIT_LONG_MOVES
16976 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
16977 [(set (match_dup 2) (match_dup 1))
16978 (set (match_dup 0) (match_dup 2))])
16980 ;; Don't compare memory with zero, load and use a test instead.
16982 [(set (match_operand 0 "flags_reg_operand" "")
16983 (match_operator 1 "compare_operator"
16984 [(match_operand:SI 2 "memory_operand" "")
16986 (match_scratch:SI 3 "r")]
16987 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
16988 [(set (match_dup 3) (match_dup 2))
16989 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))])
16991 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
16992 ;; Don't split NOTs with a displacement operand, because resulting XOR
16993 ;; will not be pairable anyway.
16995 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
16996 ;; represented using a modRM byte. The XOR replacement is long decoded,
16997 ;; so this split helps here as well.
16999 ;; Note: Can't do this as a regular split because we can't get proper
17000 ;; lifetime information then.
17003 [(set (match_operand:SWI124 0 "nonimmediate_operand" "")
17004 (not:SWI124 (match_operand:SWI124 1 "nonimmediate_operand" "")))]
17005 "optimize_insn_for_speed_p ()
17006 && ((TARGET_NOT_UNPAIRABLE
17007 && (!MEM_P (operands[0])
17008 || !memory_displacement_operand (operands[0], <MODE>mode)))
17009 || (TARGET_NOT_VECTORMODE
17010 && long_memory_operand (operands[0], <MODE>mode)))
17011 && peep2_regno_dead_p (0, FLAGS_REG)"
17012 [(parallel [(set (match_dup 0)
17013 (xor:SWI124 (match_dup 1) (const_int -1)))
17014 (clobber (reg:CC FLAGS_REG))])])
17016 ;; Non pairable "test imm, reg" instructions can be translated to
17017 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
17018 ;; byte opcode instead of two, have a short form for byte operands),
17019 ;; so do it for other CPUs as well. Given that the value was dead,
17020 ;; this should not create any new dependencies. Pass on the sub-word
17021 ;; versions if we're concerned about partial register stalls.
17024 [(set (match_operand 0 "flags_reg_operand" "")
17025 (match_operator 1 "compare_operator"
17026 [(and:SI (match_operand:SI 2 "register_operand" "")
17027 (match_operand:SI 3 "immediate_operand" ""))
17029 "ix86_match_ccmode (insn, CCNOmode)
17030 && (true_regnum (operands[2]) != AX_REG
17031 || satisfies_constraint_K (operands[3]))
17032 && peep2_reg_dead_p (1, operands[2])"
17034 [(set (match_dup 0)
17035 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
17038 (and:SI (match_dup 2) (match_dup 3)))])])
17040 ;; We don't need to handle HImode case, because it will be promoted to SImode
17041 ;; on ! TARGET_PARTIAL_REG_STALL
17044 [(set (match_operand 0 "flags_reg_operand" "")
17045 (match_operator 1 "compare_operator"
17046 [(and:QI (match_operand:QI 2 "register_operand" "")
17047 (match_operand:QI 3 "immediate_operand" ""))
17049 "! TARGET_PARTIAL_REG_STALL
17050 && ix86_match_ccmode (insn, CCNOmode)
17051 && true_regnum (operands[2]) != AX_REG
17052 && peep2_reg_dead_p (1, operands[2])"
17054 [(set (match_dup 0)
17055 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
17058 (and:QI (match_dup 2) (match_dup 3)))])])
17061 [(set (match_operand 0 "flags_reg_operand" "")
17062 (match_operator 1 "compare_operator"
17065 (match_operand 2 "ext_register_operand" "")
17068 (match_operand 3 "const_int_operand" ""))
17070 "! TARGET_PARTIAL_REG_STALL
17071 && ix86_match_ccmode (insn, CCNOmode)
17072 && true_regnum (operands[2]) != AX_REG
17073 && peep2_reg_dead_p (1, operands[2])"
17074 [(parallel [(set (match_dup 0)
17083 (set (zero_extract:SI (match_dup 2)
17091 (match_dup 3)))])])
17093 ;; Don't do logical operations with memory inputs.
17095 [(match_scratch:SI 2 "r")
17096 (parallel [(set (match_operand:SI 0 "register_operand" "")
17097 (match_operator:SI 3 "arith_or_logical_operator"
17099 (match_operand:SI 1 "memory_operand" "")]))
17100 (clobber (reg:CC FLAGS_REG))])]
17101 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17102 [(set (match_dup 2) (match_dup 1))
17103 (parallel [(set (match_dup 0)
17104 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
17105 (clobber (reg:CC FLAGS_REG))])])
17108 [(match_scratch:SI 2 "r")
17109 (parallel [(set (match_operand:SI 0 "register_operand" "")
17110 (match_operator:SI 3 "arith_or_logical_operator"
17111 [(match_operand:SI 1 "memory_operand" "")
17113 (clobber (reg:CC FLAGS_REG))])]
17114 "!(TARGET_READ_MODIFY || optimize_insn_for_size_p ())"
17115 [(set (match_dup 2) (match_dup 1))
17116 (parallel [(set (match_dup 0)
17117 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
17118 (clobber (reg:CC FLAGS_REG))])])
17120 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
17121 ;; refers to the destination of the load!
17124 [(set (match_operand:SI 0 "register_operand" "")
17125 (match_operand:SI 1 "register_operand" ""))
17126 (parallel [(set (match_dup 0)
17127 (match_operator:SI 3 "commutative_operator"
17129 (match_operand:SI 2 "memory_operand" "")]))
17130 (clobber (reg:CC FLAGS_REG))])]
17131 "REGNO (operands[0]) != REGNO (operands[1])
17132 && GENERAL_REGNO_P (REGNO (operands[0]))
17133 && GENERAL_REGNO_P (REGNO (operands[1]))"
17134 [(set (match_dup 0) (match_dup 4))
17135 (parallel [(set (match_dup 0)
17136 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
17137 (clobber (reg:CC FLAGS_REG))])]
17138 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
17141 [(set (match_operand 0 "register_operand" "")
17142 (match_operand 1 "register_operand" ""))
17144 (match_operator 3 "commutative_operator"
17146 (match_operand 2 "memory_operand" "")]))]
17147 "REGNO (operands[0]) != REGNO (operands[1])
17148 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
17149 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
17150 [(set (match_dup 0) (match_dup 2))
17152 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))])
17154 ; Don't do logical operations with memory outputs
17156 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
17157 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
17158 ; the same decoder scheduling characteristics as the original.
17161 [(match_scratch:SI 2 "r")
17162 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17163 (match_operator:SI 3 "arith_or_logical_operator"
17165 (match_operand:SI 1 "nonmemory_operand" "")]))
17166 (clobber (reg:CC FLAGS_REG))])]
17167 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17168 /* Do not split stack checking probes. */
17169 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17170 [(set (match_dup 2) (match_dup 0))
17171 (parallel [(set (match_dup 2)
17172 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
17173 (clobber (reg:CC FLAGS_REG))])
17174 (set (match_dup 0) (match_dup 2))])
17177 [(match_scratch:SI 2 "r")
17178 (parallel [(set (match_operand:SI 0 "memory_operand" "")
17179 (match_operator:SI 3 "arith_or_logical_operator"
17180 [(match_operand:SI 1 "nonmemory_operand" "")
17182 (clobber (reg:CC FLAGS_REG))])]
17183 "!(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17184 /* Do not split stack checking probes. */
17185 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
17186 [(set (match_dup 2) (match_dup 0))
17187 (parallel [(set (match_dup 2)
17188 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
17189 (clobber (reg:CC FLAGS_REG))])
17190 (set (match_dup 0) (match_dup 2))])
17192 ;; Attempt to use arith or logical operations with memory outputs with
17193 ;; setting of flags.
17195 [(set (match_operand:SWI 0 "register_operand" "")
17196 (match_operand:SWI 1 "memory_operand" ""))
17197 (parallel [(set (match_dup 0)
17198 (match_operator:SWI 3 "plusminuslogic_operator"
17200 (match_operand:SWI 2 "<nonmemory_operand>" "")]))
17201 (clobber (reg:CC FLAGS_REG))])
17202 (set (match_dup 1) (match_dup 0))
17203 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17204 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17205 && peep2_reg_dead_p (4, operands[0])
17206 && !reg_overlap_mentioned_p (operands[0], operands[1])
17207 && (<MODE>mode != QImode
17208 || immediate_operand (operands[2], QImode)
17209 || q_regs_operand (operands[2], QImode))
17210 && ix86_match_ccmode (peep2_next_insn (3),
17211 (GET_CODE (operands[3]) == PLUS
17212 || GET_CODE (operands[3]) == MINUS)
17213 ? CCGOCmode : CCNOmode)"
17214 [(parallel [(set (match_dup 4) (match_dup 5))
17215 (set (match_dup 1) (match_op_dup 3 [(match_dup 1)
17216 (match_dup 2)]))])]
17218 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17219 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17220 copy_rtx (operands[1]),
17221 copy_rtx (operands[2]));
17222 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17223 operands[5], const0_rtx);
17227 [(parallel [(set (match_operand:SWI 0 "register_operand" "")
17228 (match_operator:SWI 2 "plusminuslogic_operator"
17230 (match_operand:SWI 1 "memory_operand" "")]))
17231 (clobber (reg:CC FLAGS_REG))])
17232 (set (match_dup 1) (match_dup 0))
17233 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17234 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17235 && GET_CODE (operands[2]) != MINUS
17236 && peep2_reg_dead_p (3, operands[0])
17237 && !reg_overlap_mentioned_p (operands[0], operands[1])
17238 && ix86_match_ccmode (peep2_next_insn (2),
17239 GET_CODE (operands[2]) == PLUS
17240 ? CCGOCmode : CCNOmode)"
17241 [(parallel [(set (match_dup 3) (match_dup 4))
17242 (set (match_dup 1) (match_op_dup 2 [(match_dup 1)
17243 (match_dup 0)]))])]
17245 operands[3] = SET_DEST (PATTERN (peep2_next_insn (2)));
17246 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), <MODE>mode,
17247 copy_rtx (operands[1]),
17248 copy_rtx (operands[0]));
17249 operands[4] = gen_rtx_COMPARE (GET_MODE (operands[3]),
17250 operands[4], const0_rtx);
17254 [(set (match_operand:SWI12 0 "register_operand" "")
17255 (match_operand:SWI12 1 "memory_operand" ""))
17256 (parallel [(set (match_operand:SI 4 "register_operand" "")
17257 (match_operator:SI 3 "plusminuslogic_operator"
17259 (match_operand:SI 2 "nonmemory_operand" "")]))
17260 (clobber (reg:CC FLAGS_REG))])
17261 (set (match_dup 1) (match_dup 0))
17262 (set (reg FLAGS_REG) (compare (match_dup 0) (const_int 0)))]
17263 "(TARGET_READ_MODIFY_WRITE || optimize_insn_for_size_p ())
17264 && REG_P (operands[0]) && REG_P (operands[4])
17265 && REGNO (operands[0]) == REGNO (operands[4])
17266 && peep2_reg_dead_p (4, operands[0])
17267 && (<MODE>mode != QImode
17268 || immediate_operand (operands[2], SImode)
17269 || q_regs_operand (operands[2], SImode))
17270 && !reg_overlap_mentioned_p (operands[0], operands[1])
17271 && ix86_match_ccmode (peep2_next_insn (3),
17272 (GET_CODE (operands[3]) == PLUS
17273 || GET_CODE (operands[3]) == MINUS)
17274 ? CCGOCmode : CCNOmode)"
17275 [(parallel [(set (match_dup 4) (match_dup 5))
17276 (set (match_dup 1) (match_dup 6))])]
17278 operands[2] = gen_lowpart (<MODE>mode, operands[2]);
17279 operands[4] = SET_DEST (PATTERN (peep2_next_insn (3)));
17280 operands[5] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17281 copy_rtx (operands[1]), operands[2]);
17282 operands[5] = gen_rtx_COMPARE (GET_MODE (operands[4]),
17283 operands[5], const0_rtx);
17284 operands[6] = gen_rtx_fmt_ee (GET_CODE (operands[3]), <MODE>mode,
17285 copy_rtx (operands[1]),
17286 copy_rtx (operands[2]));
17289 ;; Attempt to always use XOR for zeroing registers.
17291 [(set (match_operand 0 "register_operand" "")
17292 (match_operand 1 "const0_operand" ""))]
17293 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
17294 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17295 && GENERAL_REG_P (operands[0])
17296 && peep2_regno_dead_p (0, FLAGS_REG)"
17297 [(parallel [(set (match_dup 0) (const_int 0))
17298 (clobber (reg:CC FLAGS_REG))])]
17299 "operands[0] = gen_lowpart (word_mode, operands[0]);")
17302 [(set (strict_low_part (match_operand 0 "register_operand" ""))
17304 "(GET_MODE (operands[0]) == QImode
17305 || GET_MODE (operands[0]) == HImode)
17306 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
17307 && peep2_regno_dead_p (0, FLAGS_REG)"
17308 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
17309 (clobber (reg:CC FLAGS_REG))])])
17311 ;; For HI, SI and DI modes, or $-1,reg is smaller than mov $-1,reg.
17313 [(set (match_operand:SWI248 0 "register_operand" "")
17315 "(optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
17316 && peep2_regno_dead_p (0, FLAGS_REG)"
17317 [(parallel [(set (match_dup 0) (const_int -1))
17318 (clobber (reg:CC FLAGS_REG))])]
17320 if (GET_MODE_SIZE (<MODE>mode) < GET_MODE_SIZE (SImode))
17321 operands[0] = gen_lowpart (SImode, operands[0]);
17324 ;; Attempt to convert simple lea to add/shift.
17325 ;; These can be created by move expanders.
17328 [(set (match_operand:SWI48 0 "register_operand" "")
17329 (plus:SWI48 (match_dup 0)
17330 (match_operand:SWI48 1 "<nonmemory_operand>" "")))]
17331 "peep2_regno_dead_p (0, FLAGS_REG)"
17332 [(parallel [(set (match_dup 0) (plus:SWI48 (match_dup 0) (match_dup 1)))
17333 (clobber (reg:CC FLAGS_REG))])])
17336 [(set (match_operand:SI 0 "register_operand" "")
17337 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
17338 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
17340 && peep2_regno_dead_p (0, FLAGS_REG)
17341 && REGNO (operands[0]) == REGNO (operands[1])"
17342 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
17343 (clobber (reg:CC FLAGS_REG))])]
17344 "operands[2] = gen_lowpart (SImode, operands[2]);")
17347 [(set (match_operand:SWI48 0 "register_operand" "")
17348 (mult:SWI48 (match_dup 0)
17349 (match_operand:SWI48 1 "const_int_operand" "")))]
17350 "exact_log2 (INTVAL (operands[1])) >= 0
17351 && peep2_regno_dead_p (0, FLAGS_REG)"
17352 [(parallel [(set (match_dup 0) (ashift:SWI48 (match_dup 0) (match_dup 2)))
17353 (clobber (reg:CC FLAGS_REG))])]
17354 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
17357 [(set (match_operand:SI 0 "register_operand" "")
17358 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
17359 (match_operand:DI 2 "const_int_operand" "")) 0))]
17361 && exact_log2 (INTVAL (operands[2])) >= 0
17362 && REGNO (operands[0]) == REGNO (operands[1])
17363 && peep2_regno_dead_p (0, FLAGS_REG)"
17364 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
17365 (clobber (reg:CC FLAGS_REG))])]
17366 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
17368 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
17369 ;; code is shorter, since push is only 1 byte, while add imm, %esp is 3 bytes.
17370 ;; On many CPUs it is also faster, since special hardware to avoid esp
17371 ;; dependencies is present.
17373 ;; While some of these conversions may be done using splitters, we use
17374 ;; peepholes in order to allow combine_stack_adjustments pass to see
17375 ;; nonobfuscated RTL.
17377 ;; Convert prologue esp subtractions to push.
17378 ;; We need register to push. In order to keep verify_flow_info happy we have
17380 ;; - use scratch and clobber it in order to avoid dependencies
17381 ;; - use already live register
17382 ;; We can't use the second way right now, since there is no reliable way how to
17383 ;; verify that given register is live. First choice will also most likely in
17384 ;; fewer dependencies. On the place of esp adjustments it is very likely that
17385 ;; call clobbered registers are dead. We may want to use base pointer as an
17386 ;; alternative when no register is available later.
17389 [(match_scratch:P 1 "r")
17390 (parallel [(set (reg:P SP_REG)
17391 (plus:P (reg:P SP_REG)
17392 (match_operand:P 0 "const_int_operand" "")))
17393 (clobber (reg:CC FLAGS_REG))
17394 (clobber (mem:BLK (scratch)))])]
17395 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17396 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17397 [(clobber (match_dup 1))
17398 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17399 (clobber (mem:BLK (scratch)))])])
17402 [(match_scratch:P 1 "r")
17403 (parallel [(set (reg:P SP_REG)
17404 (plus:P (reg:P SP_REG)
17405 (match_operand:P 0 "const_int_operand" "")))
17406 (clobber (reg:CC FLAGS_REG))
17407 (clobber (mem:BLK (scratch)))])]
17408 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17409 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17410 [(clobber (match_dup 1))
17411 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17412 (parallel [(set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17413 (clobber (mem:BLK (scratch)))])])
17415 ;; Convert esp subtractions to push.
17417 [(match_scratch:P 1 "r")
17418 (parallel [(set (reg:P SP_REG)
17419 (plus:P (reg:P SP_REG)
17420 (match_operand:P 0 "const_int_operand" "")))
17421 (clobber (reg:CC FLAGS_REG))])]
17422 "(TARGET_SINGLE_PUSH || optimize_insn_for_size_p ())
17423 && INTVAL (operands[0]) == -GET_MODE_SIZE (Pmode)"
17424 [(clobber (match_dup 1))
17425 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
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 "(TARGET_DOUBLE_PUSH || optimize_insn_for_size_p ())
17434 && INTVAL (operands[0]) == -2*GET_MODE_SIZE (Pmode)"
17435 [(clobber (match_dup 1))
17436 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))
17437 (set (mem:P (pre_dec:P (reg:P SP_REG))) (match_dup 1))])
17439 ;; Convert epilogue deallocator to pop.
17441 [(match_scratch:P 1 "r")
17442 (parallel [(set (reg:P SP_REG)
17443 (plus:P (reg:P SP_REG)
17444 (match_operand:P 0 "const_int_operand" "")))
17445 (clobber (reg:CC FLAGS_REG))
17446 (clobber (mem:BLK (scratch)))])]
17447 "(TARGET_SINGLE_POP || optimize_insn_for_size_p ())
17448 && INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17449 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17450 (clobber (mem:BLK (scratch)))])])
17452 ;; Two pops case is tricky, since pop causes dependency
17453 ;; on destination register. We use two registers if available.
17455 [(match_scratch:P 1 "r")
17456 (match_scratch:P 2 "r")
17457 (parallel [(set (reg:P SP_REG)
17458 (plus:P (reg:P SP_REG)
17459 (match_operand:P 0 "const_int_operand" "")))
17460 (clobber (reg:CC FLAGS_REG))
17461 (clobber (mem:BLK (scratch)))])]
17462 "(TARGET_DOUBLE_POP || optimize_insn_for_size_p ())
17463 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17464 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17465 (clobber (mem:BLK (scratch)))])
17466 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17469 [(match_scratch:P 1 "r")
17470 (parallel [(set (reg:P SP_REG)
17471 (plus:P (reg:P SP_REG)
17472 (match_operand:P 0 "const_int_operand" "")))
17473 (clobber (reg:CC FLAGS_REG))
17474 (clobber (mem:BLK (scratch)))])]
17475 "optimize_insn_for_size_p ()
17476 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17477 [(parallel [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17478 (clobber (mem:BLK (scratch)))])
17479 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17481 ;; Convert esp additions to pop.
17483 [(match_scratch:P 1 "r")
17484 (parallel [(set (reg:P SP_REG)
17485 (plus:P (reg:P SP_REG)
17486 (match_operand:P 0 "const_int_operand" "")))
17487 (clobber (reg:CC FLAGS_REG))])]
17488 "INTVAL (operands[0]) == GET_MODE_SIZE (Pmode)"
17489 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17491 ;; Two pops case is tricky, since pop causes dependency
17492 ;; on destination register. We use two registers if available.
17494 [(match_scratch:P 1 "r")
17495 (match_scratch:P 2 "r")
17496 (parallel [(set (reg:P SP_REG)
17497 (plus:P (reg:P SP_REG)
17498 (match_operand:P 0 "const_int_operand" "")))
17499 (clobber (reg:CC FLAGS_REG))])]
17500 "INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17501 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17502 (set (match_dup 2) (mem:P (post_inc:P (reg:P SP_REG))))])
17505 [(match_scratch:P 1 "r")
17506 (parallel [(set (reg:P SP_REG)
17507 (plus:P (reg:P SP_REG)
17508 (match_operand:P 0 "const_int_operand" "")))
17509 (clobber (reg:CC FLAGS_REG))])]
17510 "optimize_insn_for_size_p ()
17511 && INTVAL (operands[0]) == 2*GET_MODE_SIZE (Pmode)"
17512 [(set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))
17513 (set (match_dup 1) (mem:P (post_inc:P (reg:P SP_REG))))])
17515 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
17516 ;; required and register dies. Similarly for 128 to -128.
17518 [(set (match_operand 0 "flags_reg_operand" "")
17519 (match_operator 1 "compare_operator"
17520 [(match_operand 2 "register_operand" "")
17521 (match_operand 3 "const_int_operand" "")]))]
17522 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
17523 && incdec_operand (operands[3], GET_MODE (operands[3])))
17524 || (!TARGET_FUSE_CMP_AND_BRANCH
17525 && INTVAL (operands[3]) == 128))
17526 && ix86_match_ccmode (insn, CCGCmode)
17527 && peep2_reg_dead_p (1, operands[2])"
17528 [(parallel [(set (match_dup 0)
17529 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
17530 (clobber (match_dup 2))])])
17532 ;; Convert imul by three, five and nine into lea
17535 [(set (match_operand:SWI48 0 "register_operand" "")
17536 (mult:SWI48 (match_operand:SWI48 1 "register_operand" "")
17537 (match_operand:SWI48 2 "const359_operand" "")))
17538 (clobber (reg:CC FLAGS_REG))])]
17539 "!TARGET_PARTIAL_REG_STALL
17540 || <MODE>mode == SImode
17541 || optimize_function_for_size_p (cfun)"
17542 [(set (match_dup 0)
17543 (plus:SWI48 (mult:SWI48 (match_dup 1) (match_dup 2))
17545 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17549 [(set (match_operand:SWI48 0 "register_operand" "")
17550 (mult:SWI48 (match_operand:SWI48 1 "nonimmediate_operand" "")
17551 (match_operand:SWI48 2 "const359_operand" "")))
17552 (clobber (reg:CC FLAGS_REG))])]
17553 "optimize_insn_for_speed_p ()
17554 && (!TARGET_PARTIAL_REG_STALL || <MODE>mode == SImode)"
17555 [(set (match_dup 0) (match_dup 1))
17557 (plus:SWI48 (mult:SWI48 (match_dup 0) (match_dup 2))
17559 "operands[2] = GEN_INT (INTVAL (operands[2]) - 1);")
17561 ;; imul $32bit_imm, mem, reg is vector decoded, while
17562 ;; imul $32bit_imm, reg, reg is direct decoded.
17564 [(match_scratch:SWI48 3 "r")
17565 (parallel [(set (match_operand:SWI48 0 "register_operand" "")
17566 (mult:SWI48 (match_operand:SWI48 1 "memory_operand" "")
17567 (match_operand:SWI48 2 "immediate_operand" "")))
17568 (clobber (reg:CC FLAGS_REG))])]
17569 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17570 && !satisfies_constraint_K (operands[2])"
17571 [(set (match_dup 3) (match_dup 1))
17572 (parallel [(set (match_dup 0) (mult:SWI48 (match_dup 3) (match_dup 2)))
17573 (clobber (reg:CC FLAGS_REG))])])
17576 [(match_scratch:SI 3 "r")
17577 (parallel [(set (match_operand:DI 0 "register_operand" "")
17579 (mult:SI (match_operand:SI 1 "memory_operand" "")
17580 (match_operand:SI 2 "immediate_operand" ""))))
17581 (clobber (reg:CC FLAGS_REG))])]
17583 && TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
17584 && !satisfies_constraint_K (operands[2])"
17585 [(set (match_dup 3) (match_dup 1))
17586 (parallel [(set (match_dup 0)
17587 (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
17588 (clobber (reg:CC FLAGS_REG))])])
17590 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
17591 ;; Convert it into imul reg, reg
17592 ;; It would be better to force assembler to encode instruction using long
17593 ;; immediate, but there is apparently no way to do so.
17595 [(parallel [(set (match_operand:SWI248 0 "register_operand" "")
17597 (match_operand:SWI248 1 "nonimmediate_operand" "")
17598 (match_operand:SWI248 2 "const_int_operand" "")))
17599 (clobber (reg:CC FLAGS_REG))])
17600 (match_scratch:SWI248 3 "r")]
17601 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
17602 && satisfies_constraint_K (operands[2])"
17603 [(set (match_dup 3) (match_dup 2))
17604 (parallel [(set (match_dup 0) (mult:SWI248 (match_dup 0) (match_dup 3)))
17605 (clobber (reg:CC FLAGS_REG))])]
17607 if (!rtx_equal_p (operands[0], operands[1]))
17608 emit_move_insn (operands[0], operands[1]);
17611 ;; After splitting up read-modify operations, array accesses with memory
17612 ;; operands might end up in form:
17614 ;; movl 4(%esp), %edx
17616 ;; instead of pre-splitting:
17618 ;; addl 4(%esp), %eax
17620 ;; movl 4(%esp), %edx
17621 ;; leal (%edx,%eax,4), %eax
17624 [(match_scratch:P 5 "r")
17625 (parallel [(set (match_operand 0 "register_operand" "")
17626 (ashift (match_operand 1 "register_operand" "")
17627 (match_operand 2 "const_int_operand" "")))
17628 (clobber (reg:CC FLAGS_REG))])
17629 (parallel [(set (match_operand 3 "register_operand" "")
17630 (plus (match_dup 0)
17631 (match_operand 4 "x86_64_general_operand" "")))
17632 (clobber (reg:CC FLAGS_REG))])]
17633 "IN_RANGE (INTVAL (operands[2]), 1, 3)
17634 /* Validate MODE for lea. */
17635 && ((!TARGET_PARTIAL_REG_STALL
17636 && (GET_MODE (operands[0]) == QImode
17637 || GET_MODE (operands[0]) == HImode))
17638 || GET_MODE (operands[0]) == SImode
17639 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
17640 && (rtx_equal_p (operands[0], operands[3])
17641 || peep2_reg_dead_p (2, operands[0]))
17642 /* We reorder load and the shift. */
17643 && !reg_overlap_mentioned_p (operands[0], operands[4])"
17644 [(set (match_dup 5) (match_dup 4))
17645 (set (match_dup 0) (match_dup 1))]
17647 enum machine_mode op1mode = GET_MODE (operands[1]);
17648 enum machine_mode mode = op1mode == DImode ? DImode : SImode;
17649 int scale = 1 << INTVAL (operands[2]);
17650 rtx index = gen_lowpart (Pmode, operands[1]);
17651 rtx base = gen_lowpart (Pmode, operands[5]);
17652 rtx dest = gen_lowpart (mode, operands[3]);
17654 operands[1] = gen_rtx_PLUS (Pmode, base,
17655 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
17656 operands[5] = base;
17658 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
17659 if (op1mode != Pmode)
17660 operands[5] = gen_rtx_SUBREG (op1mode, operands[5], 0);
17661 operands[0] = dest;
17664 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
17665 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
17666 ;; caught for use by garbage collectors and the like. Using an insn that
17667 ;; maps to SIGILL makes it more likely the program will rightfully die.
17668 ;; Keeping with tradition, "6" is in honor of #UD.
17669 (define_insn "trap"
17670 [(trap_if (const_int 1) (const_int 6))]
17672 { return ASM_SHORT "0x0b0f"; }
17673 [(set_attr "length" "2")])
17675 (define_expand "prefetch"
17676 [(prefetch (match_operand 0 "address_operand" "")
17677 (match_operand:SI 1 "const_int_operand" "")
17678 (match_operand:SI 2 "const_int_operand" ""))]
17679 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
17681 int rw = INTVAL (operands[1]);
17682 int locality = INTVAL (operands[2]);
17684 gcc_assert (rw == 0 || rw == 1);
17685 gcc_assert (locality >= 0 && locality <= 3);
17686 gcc_assert (GET_MODE (operands[0]) == Pmode
17687 || GET_MODE (operands[0]) == VOIDmode);
17689 /* Use 3dNOW prefetch in case we are asking for write prefetch not
17690 supported by SSE counterpart or the SSE prefetch is not available
17691 (K6 machines). Otherwise use SSE prefetch as it allows specifying
17693 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
17694 operands[2] = GEN_INT (3);
17696 operands[1] = const0_rtx;
17699 (define_insn "*prefetch_sse_<mode>"
17700 [(prefetch (match_operand:P 0 "address_operand" "p")
17702 (match_operand:SI 1 "const_int_operand" ""))]
17703 "TARGET_PREFETCH_SSE"
17705 static const char * const patterns[4] = {
17706 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
17709 int locality = INTVAL (operands[1]);
17710 gcc_assert (locality >= 0 && locality <= 3);
17712 return patterns[locality];
17714 [(set_attr "type" "sse")
17715 (set_attr "atom_sse_attr" "prefetch")
17716 (set (attr "length_address")
17717 (symbol_ref "memory_address_length (operands[0])"))
17718 (set_attr "memory" "none")])
17720 (define_insn "*prefetch_3dnow_<mode>"
17721 [(prefetch (match_operand:P 0 "address_operand" "p")
17722 (match_operand:SI 1 "const_int_operand" "n")
17726 if (INTVAL (operands[1]) == 0)
17727 return "prefetch\t%a0";
17729 return "prefetchw\t%a0";
17731 [(set_attr "type" "mmx")
17732 (set (attr "length_address")
17733 (symbol_ref "memory_address_length (operands[0])"))
17734 (set_attr "memory" "none")])
17736 (define_expand "stack_protect_set"
17737 [(match_operand 0 "memory_operand" "")
17738 (match_operand 1 "memory_operand" "")]
17741 rtx (*insn)(rtx, rtx);
17743 #ifdef TARGET_THREAD_SSP_OFFSET
17744 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17745 insn = (TARGET_LP64
17746 ? gen_stack_tls_protect_set_di
17747 : gen_stack_tls_protect_set_si);
17749 insn = (TARGET_LP64
17750 ? gen_stack_protect_set_di
17751 : gen_stack_protect_set_si);
17754 emit_insn (insn (operands[0], operands[1]));
17758 (define_insn "stack_protect_set_<mode>"
17759 [(set (match_operand:PTR 0 "memory_operand" "=m")
17760 (unspec:PTR [(match_operand:PTR 1 "memory_operand" "m")]
17762 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17763 (clobber (reg:CC FLAGS_REG))]
17765 "mov{<imodesuffix>}\t{%1, %2|%2, %1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17766 [(set_attr "type" "multi")])
17768 (define_insn "stack_tls_protect_set_<mode>"
17769 [(set (match_operand:PTR 0 "memory_operand" "=m")
17770 (unspec:PTR [(match_operand:PTR 1 "const_int_operand" "i")]
17771 UNSPEC_SP_TLS_SET))
17772 (set (match_scratch:PTR 2 "=&r") (const_int 0))
17773 (clobber (reg:CC FLAGS_REG))]
17775 "mov{<imodesuffix>}\t{%@:%P1, %2|%2, <iptrsize> PTR %@:%P1}\;mov{<imodesuffix>}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
17776 [(set_attr "type" "multi")])
17778 (define_expand "stack_protect_test"
17779 [(match_operand 0 "memory_operand" "")
17780 (match_operand 1 "memory_operand" "")
17781 (match_operand 2 "" "")]
17784 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
17786 rtx (*insn)(rtx, rtx, rtx);
17788 #ifdef TARGET_THREAD_SSP_OFFSET
17789 operands[1] = GEN_INT (TARGET_THREAD_SSP_OFFSET);
17790 insn = (TARGET_LP64
17791 ? gen_stack_tls_protect_test_di
17792 : gen_stack_tls_protect_test_si);
17794 insn = (TARGET_LP64
17795 ? gen_stack_protect_test_di
17796 : gen_stack_protect_test_si);
17799 emit_insn (insn (flags, operands[0], operands[1]));
17801 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
17802 flags, const0_rtx, operands[2]));
17806 (define_insn "stack_protect_test_<mode>"
17807 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17808 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17809 (match_operand:PTR 2 "memory_operand" "m")]
17811 (clobber (match_scratch:PTR 3 "=&r"))]
17813 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%2, %3|%3, %2}"
17814 [(set_attr "type" "multi")])
17816 (define_insn "stack_tls_protect_test_<mode>"
17817 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
17818 (unspec:CCZ [(match_operand:PTR 1 "memory_operand" "m")
17819 (match_operand:PTR 2 "const_int_operand" "i")]
17820 UNSPEC_SP_TLS_TEST))
17821 (clobber (match_scratch:PTR 3 "=r"))]
17823 "mov{<imodesuffix>}\t{%1, %3|%3, %1}\;xor{<imodesuffix>}\t{%@:%P2, %3|%3, <iptrsize> PTR %@:%P2}"
17824 [(set_attr "type" "multi")])
17826 (define_insn "sse4_2_crc32<mode>"
17827 [(set (match_operand:SI 0 "register_operand" "=r")
17829 [(match_operand:SI 1 "register_operand" "0")
17830 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
17832 "TARGET_SSE4_2 || TARGET_CRC32"
17833 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
17834 [(set_attr "type" "sselog1")
17835 (set_attr "prefix_rep" "1")
17836 (set_attr "prefix_extra" "1")
17837 (set (attr "prefix_data16")
17838 (if_then_else (match_operand:HI 2 "" "")
17840 (const_string "*")))
17841 (set (attr "prefix_rex")
17842 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
17844 (const_string "*")))
17845 (set_attr "mode" "SI")])
17847 (define_insn "sse4_2_crc32di"
17848 [(set (match_operand:DI 0 "register_operand" "=r")
17850 [(match_operand:DI 1 "register_operand" "0")
17851 (match_operand:DI 2 "nonimmediate_operand" "rm")]
17853 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
17854 "crc32{q}\t{%2, %0|%0, %2}"
17855 [(set_attr "type" "sselog1")
17856 (set_attr "prefix_rep" "1")
17857 (set_attr "prefix_extra" "1")
17858 (set_attr "mode" "DI")])
17860 (define_expand "rdpmc"
17861 [(match_operand:DI 0 "register_operand" "")
17862 (match_operand:SI 1 "register_operand" "")]
17865 rtx reg = gen_reg_rtx (DImode);
17868 /* Force operand 1 into ECX. */
17869 rtx ecx = gen_rtx_REG (SImode, CX_REG);
17870 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
17871 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
17876 rtvec vec = rtvec_alloc (2);
17877 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17878 rtx upper = gen_reg_rtx (DImode);
17879 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17880 gen_rtvec (1, const0_rtx),
17882 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
17883 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17885 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17886 NULL, 1, OPTAB_DIRECT);
17887 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17891 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
17892 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17896 (define_insn "*rdpmc"
17897 [(set (match_operand:DI 0 "register_operand" "=A")
17898 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
17902 [(set_attr "type" "other")
17903 (set_attr "length" "2")])
17905 (define_insn "*rdpmc_rex64"
17906 [(set (match_operand:DI 0 "register_operand" "=a")
17907 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
17909 (set (match_operand:DI 1 "register_operand" "=d")
17910 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
17913 [(set_attr "type" "other")
17914 (set_attr "length" "2")])
17916 (define_expand "rdtsc"
17917 [(set (match_operand:DI 0 "register_operand" "")
17918 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17923 rtvec vec = rtvec_alloc (2);
17924 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17925 rtx upper = gen_reg_rtx (DImode);
17926 rtx lower = gen_reg_rtx (DImode);
17927 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
17928 gen_rtvec (1, const0_rtx),
17930 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
17931 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
17933 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17934 NULL, 1, OPTAB_DIRECT);
17935 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
17937 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
17942 (define_insn "*rdtsc"
17943 [(set (match_operand:DI 0 "register_operand" "=A")
17944 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17947 [(set_attr "type" "other")
17948 (set_attr "length" "2")])
17950 (define_insn "*rdtsc_rex64"
17951 [(set (match_operand:DI 0 "register_operand" "=a")
17952 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
17953 (set (match_operand:DI 1 "register_operand" "=d")
17954 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
17957 [(set_attr "type" "other")
17958 (set_attr "length" "2")])
17960 (define_expand "rdtscp"
17961 [(match_operand:DI 0 "register_operand" "")
17962 (match_operand:SI 1 "memory_operand" "")]
17965 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
17966 gen_rtvec (1, const0_rtx),
17968 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
17969 gen_rtvec (1, const0_rtx),
17971 rtx reg = gen_reg_rtx (DImode);
17972 rtx tmp = gen_reg_rtx (SImode);
17976 rtvec vec = rtvec_alloc (3);
17977 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17978 rtx upper = gen_reg_rtx (DImode);
17979 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17980 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
17981 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
17983 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
17984 NULL, 1, OPTAB_DIRECT);
17985 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
17990 rtvec vec = rtvec_alloc (2);
17991 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
17992 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
17993 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
17996 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
17997 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
18001 (define_insn "*rdtscp"
18002 [(set (match_operand:DI 0 "register_operand" "=A")
18003 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18004 (set (match_operand:SI 1 "register_operand" "=c")
18005 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18008 [(set_attr "type" "other")
18009 (set_attr "length" "3")])
18011 (define_insn "*rdtscp_rex64"
18012 [(set (match_operand:DI 0 "register_operand" "=a")
18013 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18014 (set (match_operand:DI 1 "register_operand" "=d")
18015 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
18016 (set (match_operand:SI 2 "register_operand" "=c")
18017 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
18020 [(set_attr "type" "other")
18021 (set_attr "length" "3")])
18023 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18025 ;; LWP instructions
18027 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
18029 (define_expand "lwp_llwpcb"
18030 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
18031 UNSPECV_LLWP_INTRINSIC)]
18034 (define_insn "*lwp_llwpcb<mode>1"
18035 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
18036 UNSPECV_LLWP_INTRINSIC)]
18039 [(set_attr "type" "lwp")
18040 (set_attr "mode" "<MODE>")
18041 (set_attr "length" "5")])
18043 (define_expand "lwp_slwpcb"
18044 [(set (match_operand 0 "register_operand" "=r")
18045 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18050 insn = (TARGET_64BIT
18052 : gen_lwp_slwpcbsi);
18054 emit_insn (insn (operands[0]));
18058 (define_insn "lwp_slwpcb<mode>"
18059 [(set (match_operand:P 0 "register_operand" "=r")
18060 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
18063 [(set_attr "type" "lwp")
18064 (set_attr "mode" "<MODE>")
18065 (set_attr "length" "5")])
18067 (define_expand "lwp_lwpval<mode>3"
18068 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
18069 (match_operand:SI 2 "nonimmediate_operand" "rm")
18070 (match_operand:SI 3 "const_int_operand" "i")]
18071 UNSPECV_LWPVAL_INTRINSIC)]
18073 ;; Avoid unused variable warning.
18074 "(void) operands[0];")
18076 (define_insn "*lwp_lwpval<mode>3_1"
18077 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
18078 (match_operand:SI 1 "nonimmediate_operand" "rm")
18079 (match_operand:SI 2 "const_int_operand" "i")]
18080 UNSPECV_LWPVAL_INTRINSIC)]
18082 "lwpval\t{%2, %1, %0|%0, %1, %2}"
18083 [(set_attr "type" "lwp")
18084 (set_attr "mode" "<MODE>")
18085 (set (attr "length")
18086 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18088 (define_expand "lwp_lwpins<mode>3"
18089 [(set (reg:CCC FLAGS_REG)
18090 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
18091 (match_operand:SI 2 "nonimmediate_operand" "rm")
18092 (match_operand:SI 3 "const_int_operand" "i")]
18093 UNSPECV_LWPINS_INTRINSIC))
18094 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
18095 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
18098 (define_insn "*lwp_lwpins<mode>3_1"
18099 [(set (reg:CCC FLAGS_REG)
18100 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
18101 (match_operand:SI 1 "nonimmediate_operand" "rm")
18102 (match_operand:SI 2 "const_int_operand" "i")]
18103 UNSPECV_LWPINS_INTRINSIC))]
18105 "lwpins\t{%2, %1, %0|%0, %1, %2}"
18106 [(set_attr "type" "lwp")
18107 (set_attr "mode" "<MODE>")
18108 (set (attr "length")
18109 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
18111 (define_insn "rdfsbase<mode>"
18112 [(set (match_operand:SWI48 0 "register_operand" "=r")
18113 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDFSBASE))]
18114 "TARGET_64BIT && TARGET_FSGSBASE"
18116 [(set_attr "type" "other")
18117 (set_attr "prefix_extra" "2")])
18119 (define_insn "rdgsbase<mode>"
18120 [(set (match_operand:SWI48 0 "register_operand" "=r")
18121 (unspec_volatile:SWI48 [(const_int 0)] UNSPECV_RDGSBASE))]
18122 "TARGET_64BIT && TARGET_FSGSBASE"
18124 [(set_attr "type" "other")
18125 (set_attr "prefix_extra" "2")])
18127 (define_insn "wrfsbase<mode>"
18128 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18130 "TARGET_64BIT && TARGET_FSGSBASE"
18132 [(set_attr "type" "other")
18133 (set_attr "prefix_extra" "2")])
18135 (define_insn "wrgsbase<mode>"
18136 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")]
18138 "TARGET_64BIT && TARGET_FSGSBASE"
18140 [(set_attr "type" "other")
18141 (set_attr "prefix_extra" "2")])
18143 (define_insn "rdrand<mode>_1"
18144 [(set (match_operand:SWI248 0 "register_operand" "=r")
18145 (unspec_volatile:SWI248 [(const_int 0)] UNSPECV_RDRAND))
18146 (set (reg:CCC FLAGS_REG)
18147 (unspec_volatile:CCC [(const_int 0)] UNSPECV_RDRAND))]
18150 [(set_attr "type" "other")
18151 (set_attr "prefix_extra" "1")])
18153 (define_expand "pause"
18154 [(set (match_dup 0)
18155 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18158 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
18159 MEM_VOLATILE_P (operands[0]) = 1;
18162 ;; Use "rep; nop", instead of "pause", to support older assemblers.
18163 ;; They have the same encoding.
18164 (define_insn "*pause"
18165 [(set (match_operand:BLK 0 "" "")
18166 (unspec:BLK [(match_dup 0)] UNSPEC_PAUSE))]
18169 [(set_attr "length" "2")
18170 (set_attr "memory" "unknown")])
18174 (include "sync.md")