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
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 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
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 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
67 [; Relocation specifiers
78 (UNSPEC_MACHOPIC_OFFSET 10)
81 (UNSPEC_STACK_ALLOC 11)
83 (UNSPEC_SSE_PROLOGUE_SAVE 13)
87 (UNSPEC_SET_GOT_OFFSET 17)
88 (UNSPEC_MEMORY_BLOCKAGE 18)
93 (UNSPEC_TLS_LD_BASE 22)
96 ; Other random patterns
101 (UNSPEC_ADD_CARRY 34)
104 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
105 (UNSPEC_TRUNC_NOOP 39)
107 ; For SSE/MMX support:
108 (UNSPEC_FIX_NOTRUNC 40)
125 (UNSPEC_MS_TO_SYSV_CALL 48)
127 ; Generic math support
129 (UNSPEC_IEEE_MIN 51) ; not commutative
130 (UNSPEC_IEEE_MAX 52) ; not commutative
145 (UNSPEC_FRNDINT_FLOOR 70)
146 (UNSPEC_FRNDINT_CEIL 71)
147 (UNSPEC_FRNDINT_TRUNC 72)
148 (UNSPEC_FRNDINT_MASK_PM 73)
149 (UNSPEC_FIST_FLOOR 74)
150 (UNSPEC_FIST_CEIL 75)
152 ; x87 Double output FP
153 (UNSPEC_SINCOS_COS 80)
154 (UNSPEC_SINCOS_SIN 81)
155 (UNSPEC_XTRACT_FRACT 84)
156 (UNSPEC_XTRACT_EXP 85)
157 (UNSPEC_FSCALE_FRACT 86)
158 (UNSPEC_FSCALE_EXP 87)
170 (UNSPEC_SP_TLS_SET 102)
171 (UNSPEC_SP_TLS_TEST 103)
181 (UNSPEC_INSERTQI 132)
186 (UNSPEC_INSERTPS 135)
188 (UNSPEC_MOVNTDQA 137)
190 (UNSPEC_PHMINPOSUW 139)
196 (UNSPEC_PCMPESTR 144)
197 (UNSPEC_PCMPISTR 145)
200 (UNSPEC_FMA4_INTRINSIC 150)
201 (UNSPEC_FMA4_FMADDSUB 151)
202 (UNSPEC_FMA4_FMSUBADD 152)
203 (UNSPEC_XOP_UNSIGNED_CMP 151)
204 (UNSPEC_XOP_TRUEFALSE 152)
205 (UNSPEC_XOP_PERMUTE 153)
207 (UNSPEC_LLWP_INTRINSIC 155)
208 (UNSPEC_SLWP_INTRINSIC 156)
209 (UNSPECV_LWPVAL_INTRINSIC 157)
210 (UNSPECV_LWPINS_INTRINSIC 158)
214 (UNSPEC_AESENCLAST 160)
216 (UNSPEC_AESDECLAST 162)
218 (UNSPEC_AESKEYGENASSIST 164)
226 (UNSPEC_VPERMIL2F128 168)
227 (UNSPEC_MASKLOAD 169)
228 (UNSPEC_MASKSTORE 170)
234 [(UNSPECV_BLOCKAGE 0)
235 (UNSPECV_STACK_PROBE 1)
247 (UNSPECV_PROLOGUE_USE 14)
249 (UNSPECV_VZEROALL 16)
250 (UNSPECV_VZEROUPPER 17)
254 (UNSPECV_VSWAPMOV 21)
257 ;; Constants to represent pcomtrue/pcomfalse variants
267 ;; Constants used in the XOP pperm instruction
269 [(PPERM_SRC 0x00) /* copy source */
270 (PPERM_INVERT 0x20) /* invert source */
271 (PPERM_REVERSE 0x40) /* bit reverse source */
272 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
273 (PPERM_ZERO 0x80) /* all 0's */
274 (PPERM_ONES 0xa0) /* all 1's */
275 (PPERM_SIGN 0xc0) /* propagate sign bit */
276 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
277 (PPERM_SRC1 0x00) /* use first source byte */
278 (PPERM_SRC2 0x10) /* use second source byte */
281 ;; Registers by name.
334 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
337 ;; In C guard expressions, put expressions which may be compile-time
338 ;; constants first. This allows for better optimization. For
339 ;; example, write "TARGET_64BIT && reload_completed", not
340 ;; "reload_completed && TARGET_64BIT".
344 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
346 (const (symbol_ref "ix86_schedule")))
348 ;; A basic instruction type. Refinements due to arguments to be
349 ;; provided in other attributes.
352 alu,alu1,negnot,imov,imovx,lea,
353 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
354 icmp,test,ibr,setcc,icmov,
355 push,pop,call,callv,leave,
357 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
358 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
359 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
360 ssemuladd,sse4arg,lwp,
361 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
362 (const_string "other"))
364 ;; Main data type used by the insn
366 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
367 (const_string "unknown"))
369 ;; The CPU unit operations uses.
370 (define_attr "unit" "integer,i387,sse,mmx,unknown"
371 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
372 (const_string "i387")
373 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
374 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
375 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
377 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
379 (eq_attr "type" "other")
380 (const_string "unknown")]
381 (const_string "integer")))
383 ;; The (bounding maximum) length of an instruction immediate.
384 (define_attr "length_immediate" ""
385 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
388 (eq_attr "unit" "i387,sse,mmx")
390 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
392 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
393 (eq_attr "type" "imov,test")
394 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
395 (eq_attr "type" "call")
396 (if_then_else (match_operand 0 "constant_call_address_operand" "")
399 (eq_attr "type" "callv")
400 (if_then_else (match_operand 1 "constant_call_address_operand" "")
403 ;; We don't know the size before shorten_branches. Expect
404 ;; the instruction to fit for better scheduling.
405 (eq_attr "type" "ibr")
408 (symbol_ref "/* Update immediate_length and other attributes! */
409 gcc_unreachable (),1")))
411 ;; The (bounding maximum) length of an instruction address.
412 (define_attr "length_address" ""
413 (cond [(eq_attr "type" "str,other,multi,fxch")
415 (and (eq_attr "type" "call")
416 (match_operand 0 "constant_call_address_operand" ""))
418 (and (eq_attr "type" "callv")
419 (match_operand 1 "constant_call_address_operand" ""))
422 (symbol_ref "ix86_attr_length_address_default (insn)")))
424 ;; Set when length prefix is used.
425 (define_attr "prefix_data16" ""
426 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
428 (eq_attr "mode" "HI")
430 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
435 ;; Set when string REP prefix is used.
436 (define_attr "prefix_rep" ""
437 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
444 ;; Set when 0f opcode prefix is used.
445 (define_attr "prefix_0f" ""
447 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
448 (eq_attr "unit" "sse,mmx"))
452 ;; Set when REX opcode prefix is used.
453 (define_attr "prefix_rex" ""
454 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
456 (and (eq_attr "mode" "DI")
457 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
458 (eq_attr "unit" "!mmx")))
460 (and (eq_attr "mode" "QI")
461 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
464 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
467 (and (eq_attr "type" "imovx")
468 (match_operand:QI 1 "ext_QIreg_operand" ""))
473 ;; There are also additional prefixes in 3DNOW, SSSE3.
474 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
475 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
476 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
477 (define_attr "prefix_extra" ""
478 (cond [(eq_attr "type" "ssemuladd,sse4arg")
480 (eq_attr "type" "sseiadd1,ssecvt1")
485 ;; Prefix used: original, VEX or maybe VEX.
486 (define_attr "prefix" "orig,vex,maybe_vex"
487 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
489 (const_string "orig")))
491 ;; VEX W bit is used.
492 (define_attr "prefix_vex_w" "" (const_int 0))
494 ;; The length of VEX prefix
495 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
496 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
497 ;; still prefix_0f 1, with prefix_extra 1.
498 (define_attr "length_vex" ""
499 (if_then_else (and (eq_attr "prefix_0f" "1")
500 (eq_attr "prefix_extra" "0"))
501 (if_then_else (eq_attr "prefix_vex_w" "1")
502 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
503 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
504 (if_then_else (eq_attr "prefix_vex_w" "1")
505 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
506 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
508 ;; Set when modrm byte is used.
509 (define_attr "modrm" ""
510 (cond [(eq_attr "type" "str,leave")
512 (eq_attr "unit" "i387")
514 (and (eq_attr "type" "incdec")
515 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
516 (ior (match_operand:SI 1 "register_operand" "")
517 (match_operand:HI 1 "register_operand" ""))))
519 (and (eq_attr "type" "push")
520 (not (match_operand 1 "memory_operand" "")))
522 (and (eq_attr "type" "pop")
523 (not (match_operand 0 "memory_operand" "")))
525 (and (eq_attr "type" "imov")
526 (and (not (eq_attr "mode" "DI"))
527 (ior (and (match_operand 0 "register_operand" "")
528 (match_operand 1 "immediate_operand" ""))
529 (ior (and (match_operand 0 "ax_reg_operand" "")
530 (match_operand 1 "memory_displacement_only_operand" ""))
531 (and (match_operand 0 "memory_displacement_only_operand" "")
532 (match_operand 1 "ax_reg_operand" ""))))))
534 (and (eq_attr "type" "call")
535 (match_operand 0 "constant_call_address_operand" ""))
537 (and (eq_attr "type" "callv")
538 (match_operand 1 "constant_call_address_operand" ""))
540 (and (eq_attr "type" "alu,alu1,icmp,test")
541 (match_operand 0 "ax_reg_operand" ""))
542 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
546 ;; The (bounding maximum) length of an instruction in bytes.
547 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
548 ;; Later we may want to split them and compute proper length as for
550 (define_attr "length" ""
551 (cond [(eq_attr "type" "other,multi,fistp,frndint")
553 (eq_attr "type" "fcmp")
555 (eq_attr "unit" "i387")
557 (plus (attr "prefix_data16")
558 (attr "length_address")))
559 (ior (eq_attr "prefix" "vex")
560 (and (eq_attr "prefix" "maybe_vex")
561 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
562 (plus (attr "length_vex")
563 (plus (attr "length_immediate")
565 (attr "length_address"))))]
566 (plus (plus (attr "modrm")
567 (plus (attr "prefix_0f")
568 (plus (attr "prefix_rex")
569 (plus (attr "prefix_extra")
571 (plus (attr "prefix_rep")
572 (plus (attr "prefix_data16")
573 (plus (attr "length_immediate")
574 (attr "length_address")))))))
576 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
577 ;; `store' if there is a simple memory reference therein, or `unknown'
578 ;; if the instruction is complex.
580 (define_attr "memory" "none,load,store,both,unknown"
581 (cond [(eq_attr "type" "other,multi,str")
582 (const_string "unknown")
583 (eq_attr "type" "lea,fcmov,fpspc")
584 (const_string "none")
585 (eq_attr "type" "fistp,leave")
586 (const_string "both")
587 (eq_attr "type" "frndint")
588 (const_string "load")
589 (eq_attr "type" "push")
590 (if_then_else (match_operand 1 "memory_operand" "")
591 (const_string "both")
592 (const_string "store"))
593 (eq_attr "type" "pop")
594 (if_then_else (match_operand 0 "memory_operand" "")
595 (const_string "both")
596 (const_string "load"))
597 (eq_attr "type" "setcc")
598 (if_then_else (match_operand 0 "memory_operand" "")
599 (const_string "store")
600 (const_string "none"))
601 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
602 (if_then_else (ior (match_operand 0 "memory_operand" "")
603 (match_operand 1 "memory_operand" ""))
604 (const_string "load")
605 (const_string "none"))
606 (eq_attr "type" "ibr")
607 (if_then_else (match_operand 0 "memory_operand" "")
608 (const_string "load")
609 (const_string "none"))
610 (eq_attr "type" "call")
611 (if_then_else (match_operand 0 "constant_call_address_operand" "")
612 (const_string "none")
613 (const_string "load"))
614 (eq_attr "type" "callv")
615 (if_then_else (match_operand 1 "constant_call_address_operand" "")
616 (const_string "none")
617 (const_string "load"))
618 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
619 (match_operand 1 "memory_operand" ""))
620 (const_string "both")
621 (and (match_operand 0 "memory_operand" "")
622 (match_operand 1 "memory_operand" ""))
623 (const_string "both")
624 (match_operand 0 "memory_operand" "")
625 (const_string "store")
626 (match_operand 1 "memory_operand" "")
627 (const_string "load")
629 "!alu1,negnot,ishift1,
630 imov,imovx,icmp,test,bitmanip,
632 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
633 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
634 (match_operand 2 "memory_operand" ""))
635 (const_string "load")
636 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
637 (match_operand 3 "memory_operand" ""))
638 (const_string "load")
640 (const_string "none")))
642 ;; Indicates if an instruction has both an immediate and a displacement.
644 (define_attr "imm_disp" "false,true,unknown"
645 (cond [(eq_attr "type" "other,multi")
646 (const_string "unknown")
647 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
648 (and (match_operand 0 "memory_displacement_operand" "")
649 (match_operand 1 "immediate_operand" "")))
650 (const_string "true")
651 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
652 (and (match_operand 0 "memory_displacement_operand" "")
653 (match_operand 2 "immediate_operand" "")))
654 (const_string "true")
656 (const_string "false")))
658 ;; Indicates if an FP operation has an integer source.
660 (define_attr "fp_int_src" "false,true"
661 (const_string "false"))
663 ;; Defines rounding mode of an FP operation.
665 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
666 (const_string "any"))
668 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
669 (define_attr "use_carry" "0,1" (const_string "0"))
671 ;; Define attribute to indicate unaligned ssemov insns
672 (define_attr "movu" "0,1" (const_string "0"))
674 ;; Describe a user's asm statement.
675 (define_asm_attributes
676 [(set_attr "length" "128")
677 (set_attr "type" "multi")])
679 ;; All integer comparison codes.
680 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
682 ;; All floating-point comparison codes.
683 (define_code_iterator fp_cond [unordered ordered
684 uneq unge ungt unle unlt ltgt ])
686 (define_code_iterator plusminus [plus minus])
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697 [(plus "add") (ss_plus "adds") (us_plus "addus")
698 (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700 [(plus "adc") (minus "sbb")])
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704 (minus "") (ss_minus "") (us_minus "")])
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
717 (umax "maxu") (umin "minu")])
718 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
720 ;; Mapping of parallel logic operators
721 (define_code_iterator plogic [and ior xor])
723 ;; Base name for insn mnemonic.
724 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
726 ;; Mapping of abs neg operators
727 (define_code_iterator absneg [abs neg])
729 ;; Base name for x87 insn mnemonic.
730 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
732 ;; Used in signed and unsigned widening multiplications.
733 (define_code_iterator any_extend [sign_extend zero_extend])
735 ;; Used in signed and unsigned divisions.
736 (define_code_iterator any_div [div udiv])
738 ;; Various insn prefixes for signed and unsigned operations.
739 (define_code_attr u [(sign_extend "") (zero_extend "u")
740 (div "") (udiv "u")])
741 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
743 ;; Instruction prefix for signed and unsigned operations.
744 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
745 (div "i") (udiv "")])
747 ;; All single word integer modes.
748 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
750 ;; Single word integer modes without DImode.
751 (define_mode_iterator SWI124 [QI HI SI])
753 ;; Single word integer modes without QImode.
754 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
756 ;; Single word integer modes without QImode and HImode.
757 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
759 ;; All math-dependant single and double word integer modes.
760 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
761 (HI "TARGET_HIMODE_MATH")
762 SI DI (TI "TARGET_64BIT")])
764 ;; Math-dependant single word integer modes.
765 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
766 (HI "TARGET_HIMODE_MATH")
767 SI (DI "TARGET_64BIT")])
769 ;; Math-dependant single word integer modes without QImode.
770 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
771 SI (DI "TARGET_64BIT")])
773 ;; Half mode for double word integer modes.
774 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
775 (DI "TARGET_64BIT")])
777 ;; Double word integer modes.
778 (define_mode_attr DWI [(SI "DI") (DI "TI")])
779 (define_mode_attr dwi [(SI "di") (DI "ti")])
781 ;; Instruction suffix for integer modes.
782 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
784 ;; Register class for integer modes.
785 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
787 ;; Immediate operand constraint for integer modes.
788 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
790 ;; General operand constraint for word modes.
791 (define_mode_attr g [(SI "g") (DI "rme")])
793 ;; Immediate operand constraint for double integer modes.
794 (define_mode_attr di [(SI "iF") (DI "e")])
796 ;; General operand predicate for integer modes.
797 (define_mode_attr general_operand
798 [(QI "general_operand")
799 (HI "general_operand")
800 (SI "general_operand")
801 (DI "x86_64_general_operand")
802 (TI "x86_64_general_operand")])
804 ;; SSE and x87 SFmode and DFmode floating point modes
805 (define_mode_iterator MODEF [SF DF])
807 ;; All x87 floating point modes
808 (define_mode_iterator X87MODEF [SF DF XF])
810 ;; All integer modes handled by x87 fisttp operator.
811 (define_mode_iterator X87MODEI [HI SI DI])
813 ;; All integer modes handled by integer x87 operators.
814 (define_mode_iterator X87MODEI12 [HI SI])
816 ;; All integer modes handled by SSE cvtts?2si* operators.
817 (define_mode_iterator SSEMODEI24 [SI DI])
819 ;; SSE asm suffix for floating point modes
820 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
822 ;; SSE vector mode corresponding to a scalar mode
823 (define_mode_attr ssevecmode
824 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
826 ;; Instruction suffix for REX 64bit operators.
827 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
829 ;; This mode iterator allows :P to be used for patterns that operate on
830 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
831 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
833 ;; Scheduling descriptions
835 (include "pentium.md")
838 (include "athlon.md")
843 ;; Operand and operator predicates and constraints
845 (include "predicates.md")
846 (include "constraints.md")
849 ;; Compare and branch/compare and store instructions.
851 (define_expand "cbranch<mode>4"
852 [(set (reg:CC FLAGS_REG)
853 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
854 (match_operand:SDWIM 2 "<general_operand>" "")))
855 (set (pc) (if_then_else
856 (match_operator 0 "comparison_operator"
857 [(reg:CC FLAGS_REG) (const_int 0)])
858 (label_ref (match_operand 3 "" ""))
862 if (MEM_P (operands[1]) && MEM_P (operands[2]))
863 operands[1] = force_reg (<MODE>mode, operands[1]);
864 ix86_compare_op0 = operands[1];
865 ix86_compare_op1 = operands[2];
866 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
870 (define_expand "cstore<mode>4"
871 [(set (reg:CC FLAGS_REG)
872 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
873 (match_operand:SWIM 3 "<general_operand>" "")))
874 (set (match_operand:QI 0 "register_operand" "")
875 (match_operator 1 "comparison_operator"
876 [(reg:CC FLAGS_REG) (const_int 0)]))]
879 if (MEM_P (operands[2]) && MEM_P (operands[3]))
880 operands[2] = force_reg (<MODE>mode, operands[2]);
881 ix86_compare_op0 = operands[2];
882 ix86_compare_op1 = operands[3];
883 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
887 (define_expand "cmp<mode>_1"
888 [(set (reg:CC FLAGS_REG)
889 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
890 (match_operand:SWI48 1 "<general_operand>" "")))]
894 (define_insn "*cmp<mode>_ccno_1"
895 [(set (reg FLAGS_REG)
896 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
897 (match_operand:SWI 1 "const0_operand" "")))]
898 "ix86_match_ccmode (insn, CCNOmode)"
900 test{<imodesuffix>}\t%0, %0
901 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
902 [(set_attr "type" "test,icmp")
903 (set_attr "length_immediate" "0,1")
904 (set_attr "mode" "<MODE>")])
906 (define_insn "*cmp<mode>_1"
907 [(set (reg FLAGS_REG)
908 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
909 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
910 "ix86_match_ccmode (insn, CCmode)"
911 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
912 [(set_attr "type" "icmp")
913 (set_attr "mode" "<MODE>")])
915 (define_insn "*cmp<mode>_minus_1"
916 [(set (reg FLAGS_REG)
918 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
919 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
921 "ix86_match_ccmode (insn, CCGOCmode)"
922 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
923 [(set_attr "type" "icmp")
924 (set_attr "mode" "<MODE>")])
926 (define_insn "*cmpqi_ext_1"
927 [(set (reg FLAGS_REG)
929 (match_operand:QI 0 "general_operand" "Qm")
932 (match_operand 1 "ext_register_operand" "Q")
935 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
936 "cmp{b}\t{%h1, %0|%0, %h1}"
937 [(set_attr "type" "icmp")
938 (set_attr "mode" "QI")])
940 (define_insn "*cmpqi_ext_1_rex64"
941 [(set (reg FLAGS_REG)
943 (match_operand:QI 0 "register_operand" "Q")
946 (match_operand 1 "ext_register_operand" "Q")
949 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
950 "cmp{b}\t{%h1, %0|%0, %h1}"
951 [(set_attr "type" "icmp")
952 (set_attr "mode" "QI")])
954 (define_insn "*cmpqi_ext_2"
955 [(set (reg FLAGS_REG)
959 (match_operand 0 "ext_register_operand" "Q")
962 (match_operand:QI 1 "const0_operand" "")))]
963 "ix86_match_ccmode (insn, CCNOmode)"
965 [(set_attr "type" "test")
966 (set_attr "length_immediate" "0")
967 (set_attr "mode" "QI")])
969 (define_expand "cmpqi_ext_3"
970 [(set (reg:CC FLAGS_REG)
974 (match_operand 0 "ext_register_operand" "")
977 (match_operand:QI 1 "immediate_operand" "")))]
981 (define_insn "*cmpqi_ext_3_insn"
982 [(set (reg FLAGS_REG)
986 (match_operand 0 "ext_register_operand" "Q")
989 (match_operand:QI 1 "general_operand" "Qmn")))]
990 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
991 "cmp{b}\t{%1, %h0|%h0, %1}"
992 [(set_attr "type" "icmp")
993 (set_attr "modrm" "1")
994 (set_attr "mode" "QI")])
996 (define_insn "*cmpqi_ext_3_insn_rex64"
997 [(set (reg FLAGS_REG)
1001 (match_operand 0 "ext_register_operand" "Q")
1004 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1005 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1006 "cmp{b}\t{%1, %h0|%h0, %1}"
1007 [(set_attr "type" "icmp")
1008 (set_attr "modrm" "1")
1009 (set_attr "mode" "QI")])
1011 (define_insn "*cmpqi_ext_4"
1012 [(set (reg FLAGS_REG)
1016 (match_operand 0 "ext_register_operand" "Q")
1021 (match_operand 1 "ext_register_operand" "Q")
1023 (const_int 8)) 0)))]
1024 "ix86_match_ccmode (insn, CCmode)"
1025 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1026 [(set_attr "type" "icmp")
1027 (set_attr "mode" "QI")])
1029 ;; These implement float point compares.
1030 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1031 ;; which would allow mix and match FP modes on the compares. Which is what
1032 ;; the old patterns did, but with many more of them.
1034 (define_expand "cbranchxf4"
1035 [(set (reg:CC FLAGS_REG)
1036 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1037 (match_operand:XF 2 "nonmemory_operand" "")))
1038 (set (pc) (if_then_else
1039 (match_operator 0 "ix86_fp_comparison_operator"
1042 (label_ref (match_operand 3 "" ""))
1046 ix86_compare_op0 = operands[1];
1047 ix86_compare_op1 = operands[2];
1048 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1052 (define_expand "cstorexf4"
1053 [(set (reg:CC FLAGS_REG)
1054 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1055 (match_operand:XF 3 "nonmemory_operand" "")))
1056 (set (match_operand:QI 0 "register_operand" "")
1057 (match_operator 1 "ix86_fp_comparison_operator"
1062 ix86_compare_op0 = operands[2];
1063 ix86_compare_op1 = operands[3];
1064 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1068 (define_expand "cbranch<mode>4"
1069 [(set (reg:CC FLAGS_REG)
1070 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1071 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1072 (set (pc) (if_then_else
1073 (match_operator 0 "ix86_fp_comparison_operator"
1076 (label_ref (match_operand 3 "" ""))
1078 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1080 ix86_compare_op0 = operands[1];
1081 ix86_compare_op1 = operands[2];
1082 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1086 (define_expand "cstore<mode>4"
1087 [(set (reg:CC FLAGS_REG)
1088 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1089 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1090 (set (match_operand:QI 0 "register_operand" "")
1091 (match_operator 1 "ix86_fp_comparison_operator"
1094 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1096 ix86_compare_op0 = operands[2];
1097 ix86_compare_op1 = operands[3];
1098 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1102 (define_expand "cbranchcc4"
1103 [(set (pc) (if_then_else
1104 (match_operator 0 "comparison_operator"
1105 [(match_operand 1 "flags_reg_operand" "")
1106 (match_operand 2 "const0_operand" "")])
1107 (label_ref (match_operand 3 "" ""))
1111 ix86_compare_op0 = operands[1];
1112 ix86_compare_op1 = operands[2];
1113 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1117 (define_expand "cstorecc4"
1118 [(set (match_operand:QI 0 "register_operand" "")
1119 (match_operator 1 "comparison_operator"
1120 [(match_operand 2 "flags_reg_operand" "")
1121 (match_operand 3 "const0_operand" "")]))]
1124 ix86_compare_op0 = operands[2];
1125 ix86_compare_op1 = operands[3];
1126 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1131 ;; FP compares, step 1:
1132 ;; Set the FP condition codes.
1134 ;; CCFPmode compare with exceptions
1135 ;; CCFPUmode compare with no exceptions
1137 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1138 ;; used to manage the reg stack popping would not be preserved.
1140 (define_insn "*cmpfp_0"
1141 [(set (match_operand:HI 0 "register_operand" "=a")
1144 (match_operand 1 "register_operand" "f")
1145 (match_operand 2 "const0_operand" ""))]
1147 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1148 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1149 "* return output_fp_compare (insn, operands, 0, 0);"
1150 [(set_attr "type" "multi")
1151 (set_attr "unit" "i387")
1153 (cond [(match_operand:SF 1 "" "")
1155 (match_operand:DF 1 "" "")
1158 (const_string "XF")))])
1160 (define_insn_and_split "*cmpfp_0_cc"
1161 [(set (reg:CCFP FLAGS_REG)
1163 (match_operand 1 "register_operand" "f")
1164 (match_operand 2 "const0_operand" "")))
1165 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1166 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1167 && TARGET_SAHF && !TARGET_CMOVE
1168 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1170 "&& reload_completed"
1173 [(compare:CCFP (match_dup 1)(match_dup 2))]
1175 (set (reg:CC FLAGS_REG)
1176 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1178 [(set_attr "type" "multi")
1179 (set_attr "unit" "i387")
1181 (cond [(match_operand:SF 1 "" "")
1183 (match_operand:DF 1 "" "")
1186 (const_string "XF")))])
1188 (define_insn "*cmpfp_xf"
1189 [(set (match_operand:HI 0 "register_operand" "=a")
1192 (match_operand:XF 1 "register_operand" "f")
1193 (match_operand:XF 2 "register_operand" "f"))]
1196 "* return output_fp_compare (insn, operands, 0, 0);"
1197 [(set_attr "type" "multi")
1198 (set_attr "unit" "i387")
1199 (set_attr "mode" "XF")])
1201 (define_insn_and_split "*cmpfp_xf_cc"
1202 [(set (reg:CCFP FLAGS_REG)
1204 (match_operand:XF 1 "register_operand" "f")
1205 (match_operand:XF 2 "register_operand" "f")))
1206 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1208 && TARGET_SAHF && !TARGET_CMOVE"
1210 "&& reload_completed"
1213 [(compare:CCFP (match_dup 1)(match_dup 2))]
1215 (set (reg:CC FLAGS_REG)
1216 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1218 [(set_attr "type" "multi")
1219 (set_attr "unit" "i387")
1220 (set_attr "mode" "XF")])
1222 (define_insn "*cmpfp_<mode>"
1223 [(set (match_operand:HI 0 "register_operand" "=a")
1226 (match_operand:MODEF 1 "register_operand" "f")
1227 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1230 "* return output_fp_compare (insn, operands, 0, 0);"
1231 [(set_attr "type" "multi")
1232 (set_attr "unit" "i387")
1233 (set_attr "mode" "<MODE>")])
1235 (define_insn_and_split "*cmpfp_<mode>_cc"
1236 [(set (reg:CCFP FLAGS_REG)
1238 (match_operand:MODEF 1 "register_operand" "f")
1239 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1240 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1242 && TARGET_SAHF && !TARGET_CMOVE"
1244 "&& reload_completed"
1247 [(compare:CCFP (match_dup 1)(match_dup 2))]
1249 (set (reg:CC FLAGS_REG)
1250 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1252 [(set_attr "type" "multi")
1253 (set_attr "unit" "i387")
1254 (set_attr "mode" "<MODE>")])
1256 (define_insn "*cmpfp_u"
1257 [(set (match_operand:HI 0 "register_operand" "=a")
1260 (match_operand 1 "register_operand" "f")
1261 (match_operand 2 "register_operand" "f"))]
1263 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1264 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1265 "* return output_fp_compare (insn, operands, 0, 1);"
1266 [(set_attr "type" "multi")
1267 (set_attr "unit" "i387")
1269 (cond [(match_operand:SF 1 "" "")
1271 (match_operand:DF 1 "" "")
1274 (const_string "XF")))])
1276 (define_insn_and_split "*cmpfp_u_cc"
1277 [(set (reg:CCFPU FLAGS_REG)
1279 (match_operand 1 "register_operand" "f")
1280 (match_operand 2 "register_operand" "f")))
1281 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1282 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1283 && TARGET_SAHF && !TARGET_CMOVE
1284 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1286 "&& reload_completed"
1289 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1291 (set (reg:CC FLAGS_REG)
1292 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1294 [(set_attr "type" "multi")
1295 (set_attr "unit" "i387")
1297 (cond [(match_operand:SF 1 "" "")
1299 (match_operand:DF 1 "" "")
1302 (const_string "XF")))])
1304 (define_insn "*cmpfp_<mode>"
1305 [(set (match_operand:HI 0 "register_operand" "=a")
1308 (match_operand 1 "register_operand" "f")
1309 (match_operator 3 "float_operator"
1310 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1312 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1313 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1314 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1315 "* return output_fp_compare (insn, operands, 0, 0);"
1316 [(set_attr "type" "multi")
1317 (set_attr "unit" "i387")
1318 (set_attr "fp_int_src" "true")
1319 (set_attr "mode" "<MODE>")])
1321 (define_insn_and_split "*cmpfp_<mode>_cc"
1322 [(set (reg:CCFP FLAGS_REG)
1324 (match_operand 1 "register_operand" "f")
1325 (match_operator 3 "float_operator"
1326 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1327 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1328 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1329 && TARGET_SAHF && !TARGET_CMOVE
1330 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1331 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1333 "&& reload_completed"
1338 (match_op_dup 3 [(match_dup 2)]))]
1340 (set (reg:CC FLAGS_REG)
1341 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1343 [(set_attr "type" "multi")
1344 (set_attr "unit" "i387")
1345 (set_attr "fp_int_src" "true")
1346 (set_attr "mode" "<MODE>")])
1348 ;; FP compares, step 2
1349 ;; Move the fpsw to ax.
1351 (define_insn "x86_fnstsw_1"
1352 [(set (match_operand:HI 0 "register_operand" "=a")
1353 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1356 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1357 (set_attr "mode" "SI")
1358 (set_attr "unit" "i387")])
1360 ;; FP compares, step 3
1361 ;; Get ax into flags, general case.
1363 (define_insn "x86_sahf_1"
1364 [(set (reg:CC FLAGS_REG)
1365 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1369 #ifdef HAVE_AS_IX86_SAHF
1372 return ASM_BYTE "0x9e";
1375 [(set_attr "length" "1")
1376 (set_attr "athlon_decode" "vector")
1377 (set_attr "amdfam10_decode" "direct")
1378 (set_attr "mode" "SI")])
1380 ;; Pentium Pro can do steps 1 through 3 in one go.
1381 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1382 (define_insn "*cmpfp_i_mixed"
1383 [(set (reg:CCFP FLAGS_REG)
1384 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1385 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1386 "TARGET_MIX_SSE_I387
1387 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1388 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1389 "* return output_fp_compare (insn, operands, 1, 0);"
1390 [(set_attr "type" "fcmp,ssecomi")
1391 (set_attr "prefix" "orig,maybe_vex")
1393 (if_then_else (match_operand:SF 1 "" "")
1395 (const_string "DF")))
1396 (set (attr "prefix_rep")
1397 (if_then_else (eq_attr "type" "ssecomi")
1399 (const_string "*")))
1400 (set (attr "prefix_data16")
1401 (cond [(eq_attr "type" "fcmp")
1403 (eq_attr "mode" "DF")
1406 (const_string "0")))
1407 (set_attr "athlon_decode" "vector")
1408 (set_attr "amdfam10_decode" "direct")])
1410 (define_insn "*cmpfp_i_sse"
1411 [(set (reg:CCFP FLAGS_REG)
1412 (compare:CCFP (match_operand 0 "register_operand" "x")
1413 (match_operand 1 "nonimmediate_operand" "xm")))]
1415 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1416 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1417 "* return output_fp_compare (insn, operands, 1, 0);"
1418 [(set_attr "type" "ssecomi")
1419 (set_attr "prefix" "maybe_vex")
1421 (if_then_else (match_operand:SF 1 "" "")
1423 (const_string "DF")))
1424 (set_attr "prefix_rep" "0")
1425 (set (attr "prefix_data16")
1426 (if_then_else (eq_attr "mode" "DF")
1428 (const_string "0")))
1429 (set_attr "athlon_decode" "vector")
1430 (set_attr "amdfam10_decode" "direct")])
1432 (define_insn "*cmpfp_i_i387"
1433 [(set (reg:CCFP FLAGS_REG)
1434 (compare:CCFP (match_operand 0 "register_operand" "f")
1435 (match_operand 1 "register_operand" "f")))]
1436 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1438 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1439 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1440 "* return output_fp_compare (insn, operands, 1, 0);"
1441 [(set_attr "type" "fcmp")
1443 (cond [(match_operand:SF 1 "" "")
1445 (match_operand:DF 1 "" "")
1448 (const_string "XF")))
1449 (set_attr "athlon_decode" "vector")
1450 (set_attr "amdfam10_decode" "direct")])
1452 (define_insn "*cmpfp_iu_mixed"
1453 [(set (reg:CCFPU FLAGS_REG)
1454 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1455 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1456 "TARGET_MIX_SSE_I387
1457 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1458 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1459 "* return output_fp_compare (insn, operands, 1, 1);"
1460 [(set_attr "type" "fcmp,ssecomi")
1461 (set_attr "prefix" "orig,maybe_vex")
1463 (if_then_else (match_operand:SF 1 "" "")
1465 (const_string "DF")))
1466 (set (attr "prefix_rep")
1467 (if_then_else (eq_attr "type" "ssecomi")
1469 (const_string "*")))
1470 (set (attr "prefix_data16")
1471 (cond [(eq_attr "type" "fcmp")
1473 (eq_attr "mode" "DF")
1476 (const_string "0")))
1477 (set_attr "athlon_decode" "vector")
1478 (set_attr "amdfam10_decode" "direct")])
1480 (define_insn "*cmpfp_iu_sse"
1481 [(set (reg:CCFPU FLAGS_REG)
1482 (compare:CCFPU (match_operand 0 "register_operand" "x")
1483 (match_operand 1 "nonimmediate_operand" "xm")))]
1485 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1486 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1487 "* return output_fp_compare (insn, operands, 1, 1);"
1488 [(set_attr "type" "ssecomi")
1489 (set_attr "prefix" "maybe_vex")
1491 (if_then_else (match_operand:SF 1 "" "")
1493 (const_string "DF")))
1494 (set_attr "prefix_rep" "0")
1495 (set (attr "prefix_data16")
1496 (if_then_else (eq_attr "mode" "DF")
1498 (const_string "0")))
1499 (set_attr "athlon_decode" "vector")
1500 (set_attr "amdfam10_decode" "direct")])
1502 (define_insn "*cmpfp_iu_387"
1503 [(set (reg:CCFPU FLAGS_REG)
1504 (compare:CCFPU (match_operand 0 "register_operand" "f")
1505 (match_operand 1 "register_operand" "f")))]
1506 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1508 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1509 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1510 "* return output_fp_compare (insn, operands, 1, 1);"
1511 [(set_attr "type" "fcmp")
1513 (cond [(match_operand:SF 1 "" "")
1515 (match_operand:DF 1 "" "")
1518 (const_string "XF")))
1519 (set_attr "athlon_decode" "vector")
1520 (set_attr "amdfam10_decode" "direct")])
1522 ;; Move instructions.
1524 ;; General case of fullword move.
1526 (define_expand "movsi"
1527 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1528 (match_operand:SI 1 "general_operand" ""))]
1530 "ix86_expand_move (SImode, operands); DONE;")
1532 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1535 ;; %%% We don't use a post-inc memory reference because x86 is not a
1536 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1537 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1538 ;; targets without our curiosities, and it is just as easy to represent
1539 ;; this differently.
1541 (define_insn "*pushsi2"
1542 [(set (match_operand:SI 0 "push_operand" "=<")
1543 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1546 [(set_attr "type" "push")
1547 (set_attr "mode" "SI")])
1549 ;; For 64BIT abi we always round up to 8 bytes.
1550 (define_insn "*pushsi2_rex64"
1551 [(set (match_operand:SI 0 "push_operand" "=X")
1552 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1555 [(set_attr "type" "push")
1556 (set_attr "mode" "SI")])
1558 (define_insn "*pushsi2_prologue"
1559 [(set (match_operand:SI 0 "push_operand" "=<")
1560 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1561 (clobber (mem:BLK (scratch)))]
1564 [(set_attr "type" "push")
1565 (set_attr "mode" "SI")])
1567 (define_insn "*popsi1_epilogue"
1568 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1569 (mem:SI (reg:SI SP_REG)))
1570 (set (reg:SI SP_REG)
1571 (plus:SI (reg:SI SP_REG) (const_int 4)))
1572 (clobber (mem:BLK (scratch)))]
1575 [(set_attr "type" "pop")
1576 (set_attr "mode" "SI")])
1578 (define_insn "popsi1"
1579 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1580 (mem:SI (reg:SI SP_REG)))
1581 (set (reg:SI SP_REG)
1582 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1585 [(set_attr "type" "pop")
1586 (set_attr "mode" "SI")])
1588 (define_insn "*movsi_xor"
1589 [(set (match_operand:SI 0 "register_operand" "=r")
1590 (match_operand:SI 1 "const0_operand" ""))
1591 (clobber (reg:CC FLAGS_REG))]
1594 [(set_attr "type" "alu1")
1595 (set_attr "mode" "SI")
1596 (set_attr "length_immediate" "0")])
1598 (define_insn "*movsi_or"
1599 [(set (match_operand:SI 0 "register_operand" "=r")
1600 (match_operand:SI 1 "immediate_operand" "i"))
1601 (clobber (reg:CC FLAGS_REG))]
1603 && operands[1] == constm1_rtx"
1605 operands[1] = constm1_rtx;
1606 return "or{l}\t{%1, %0|%0, %1}";
1608 [(set_attr "type" "alu1")
1609 (set_attr "mode" "SI")
1610 (set_attr "length_immediate" "1")])
1612 (define_insn "*movsi_1"
1613 [(set (match_operand:SI 0 "nonimmediate_operand"
1614 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1615 (match_operand:SI 1 "general_operand"
1616 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1617 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1619 switch (get_attr_type (insn))
1622 if (get_attr_mode (insn) == MODE_TI)
1623 return "%vpxor\t%0, %d0";
1624 return "%vxorps\t%0, %d0";
1627 switch (get_attr_mode (insn))
1630 return "%vmovdqa\t{%1, %0|%0, %1}";
1632 return "%vmovaps\t{%1, %0|%0, %1}";
1634 return "%vmovd\t{%1, %0|%0, %1}";
1636 return "%vmovss\t{%1, %0|%0, %1}";
1642 return "pxor\t%0, %0";
1645 if (get_attr_mode (insn) == MODE_DI)
1646 return "movq\t{%1, %0|%0, %1}";
1647 return "movd\t{%1, %0|%0, %1}";
1650 return "lea{l}\t{%1, %0|%0, %1}";
1653 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1654 return "mov{l}\t{%1, %0|%0, %1}";
1658 (cond [(eq_attr "alternative" "2")
1659 (const_string "mmx")
1660 (eq_attr "alternative" "3,4,5")
1661 (const_string "mmxmov")
1662 (eq_attr "alternative" "6")
1663 (const_string "sselog1")
1664 (eq_attr "alternative" "7,8,9,10,11")
1665 (const_string "ssemov")
1666 (match_operand:DI 1 "pic_32bit_operand" "")
1667 (const_string "lea")
1669 (const_string "imov")))
1670 (set (attr "prefix")
1671 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1672 (const_string "orig")
1673 (const_string "maybe_vex")))
1674 (set (attr "prefix_data16")
1675 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1677 (const_string "*")))
1679 (cond [(eq_attr "alternative" "2,3")
1681 (eq_attr "alternative" "6,7")
1683 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1684 (const_string "V4SF")
1685 (const_string "TI"))
1686 (and (eq_attr "alternative" "8,9,10,11")
1687 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1690 (const_string "SI")))])
1692 ;; Stores and loads of ax to arbitrary constant address.
1693 ;; We fake an second form of instruction to force reload to load address
1694 ;; into register when rax is not available
1695 (define_insn "*movabssi_1_rex64"
1696 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1697 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1698 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1700 movabs{l}\t{%1, %P0|%P0, %1}
1701 mov{l}\t{%1, %a0|%a0, %1}"
1702 [(set_attr "type" "imov")
1703 (set_attr "modrm" "0,*")
1704 (set_attr "length_address" "8,0")
1705 (set_attr "length_immediate" "0,*")
1706 (set_attr "memory" "store")
1707 (set_attr "mode" "SI")])
1709 (define_insn "*movabssi_2_rex64"
1710 [(set (match_operand:SI 0 "register_operand" "=a,r")
1711 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1712 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1714 movabs{l}\t{%P1, %0|%0, %P1}
1715 mov{l}\t{%a1, %0|%0, %a1}"
1716 [(set_attr "type" "imov")
1717 (set_attr "modrm" "0,*")
1718 (set_attr "length_address" "8,0")
1719 (set_attr "length_immediate" "0")
1720 (set_attr "memory" "load")
1721 (set_attr "mode" "SI")])
1723 (define_insn "*swapsi"
1724 [(set (match_operand:SI 0 "register_operand" "+r")
1725 (match_operand:SI 1 "register_operand" "+r"))
1730 [(set_attr "type" "imov")
1731 (set_attr "mode" "SI")
1732 (set_attr "pent_pair" "np")
1733 (set_attr "athlon_decode" "vector")
1734 (set_attr "amdfam10_decode" "double")])
1736 (define_expand "movhi"
1737 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1738 (match_operand:HI 1 "general_operand" ""))]
1740 "ix86_expand_move (HImode, operands); DONE;")
1742 (define_insn "*pushhi2"
1743 [(set (match_operand:HI 0 "push_operand" "=X")
1744 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1747 [(set_attr "type" "push")
1748 (set_attr "mode" "SI")])
1750 ;; For 64BIT abi we always round up to 8 bytes.
1751 (define_insn "*pushhi2_rex64"
1752 [(set (match_operand:HI 0 "push_operand" "=X")
1753 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1756 [(set_attr "type" "push")
1757 (set_attr "mode" "DI")])
1759 (define_insn "*movhi_1"
1760 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1761 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1762 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1764 switch (get_attr_type (insn))
1767 /* movzwl is faster than movw on p2 due to partial word stalls,
1768 though not as fast as an aligned movl. */
1769 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1771 if (get_attr_mode (insn) == MODE_SI)
1772 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1774 return "mov{w}\t{%1, %0|%0, %1}";
1778 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1779 (const_string "imov")
1780 (and (eq_attr "alternative" "0")
1781 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1783 (eq (symbol_ref "TARGET_HIMODE_MATH")
1785 (const_string "imov")
1786 (and (eq_attr "alternative" "1,2")
1787 (match_operand:HI 1 "aligned_operand" ""))
1788 (const_string "imov")
1789 (and (ne (symbol_ref "TARGET_MOVX")
1791 (eq_attr "alternative" "0,2"))
1792 (const_string "imovx")
1794 (const_string "imov")))
1796 (cond [(eq_attr "type" "imovx")
1798 (and (eq_attr "alternative" "1,2")
1799 (match_operand:HI 1 "aligned_operand" ""))
1801 (and (eq_attr "alternative" "0")
1802 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1804 (eq (symbol_ref "TARGET_HIMODE_MATH")
1808 (const_string "HI")))])
1810 ;; Stores and loads of ax to arbitrary constant address.
1811 ;; We fake an second form of instruction to force reload to load address
1812 ;; into register when rax is not available
1813 (define_insn "*movabshi_1_rex64"
1814 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1815 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1816 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1818 movabs{w}\t{%1, %P0|%P0, %1}
1819 mov{w}\t{%1, %a0|%a0, %1}"
1820 [(set_attr "type" "imov")
1821 (set_attr "modrm" "0,*")
1822 (set_attr "length_address" "8,0")
1823 (set_attr "length_immediate" "0,*")
1824 (set_attr "memory" "store")
1825 (set_attr "mode" "HI")])
1827 (define_insn "*movabshi_2_rex64"
1828 [(set (match_operand:HI 0 "register_operand" "=a,r")
1829 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1830 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1832 movabs{w}\t{%P1, %0|%0, %P1}
1833 mov{w}\t{%a1, %0|%0, %a1}"
1834 [(set_attr "type" "imov")
1835 (set_attr "modrm" "0,*")
1836 (set_attr "length_address" "8,0")
1837 (set_attr "length_immediate" "0")
1838 (set_attr "memory" "load")
1839 (set_attr "mode" "HI")])
1841 (define_insn "*swaphi_1"
1842 [(set (match_operand:HI 0 "register_operand" "+r")
1843 (match_operand:HI 1 "register_operand" "+r"))
1846 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1848 [(set_attr "type" "imov")
1849 (set_attr "mode" "SI")
1850 (set_attr "pent_pair" "np")
1851 (set_attr "athlon_decode" "vector")
1852 (set_attr "amdfam10_decode" "double")])
1854 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1855 (define_insn "*swaphi_2"
1856 [(set (match_operand:HI 0 "register_operand" "+r")
1857 (match_operand:HI 1 "register_operand" "+r"))
1860 "TARGET_PARTIAL_REG_STALL"
1862 [(set_attr "type" "imov")
1863 (set_attr "mode" "HI")
1864 (set_attr "pent_pair" "np")
1865 (set_attr "athlon_decode" "vector")])
1867 (define_expand "movstricthi"
1868 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1869 (match_operand:HI 1 "general_operand" ""))]
1872 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1874 /* Don't generate memory->memory moves, go through a register */
1875 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1876 operands[1] = force_reg (HImode, operands[1]);
1879 (define_insn "*movstricthi_1"
1880 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1881 (match_operand:HI 1 "general_operand" "rn,m"))]
1882 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1883 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1884 "mov{w}\t{%1, %0|%0, %1}"
1885 [(set_attr "type" "imov")
1886 (set_attr "mode" "HI")])
1888 (define_insn "*movstricthi_xor"
1889 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1890 (match_operand:HI 1 "const0_operand" ""))
1891 (clobber (reg:CC FLAGS_REG))]
1894 [(set_attr "type" "alu1")
1895 (set_attr "mode" "HI")
1896 (set_attr "length_immediate" "0")])
1898 (define_expand "movqi"
1899 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1900 (match_operand:QI 1 "general_operand" ""))]
1902 "ix86_expand_move (QImode, operands); DONE;")
1904 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1905 ;; "push a byte". But actually we use pushl, which has the effect
1906 ;; of rounding the amount pushed up to a word.
1908 (define_insn "*pushqi2"
1909 [(set (match_operand:QI 0 "push_operand" "=X")
1910 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1913 [(set_attr "type" "push")
1914 (set_attr "mode" "SI")])
1916 ;; For 64BIT abi we always round up to 8 bytes.
1917 (define_insn "*pushqi2_rex64"
1918 [(set (match_operand:QI 0 "push_operand" "=X")
1919 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1922 [(set_attr "type" "push")
1923 (set_attr "mode" "DI")])
1925 ;; Situation is quite tricky about when to choose full sized (SImode) move
1926 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1927 ;; partial register dependency machines (such as AMD Athlon), where QImode
1928 ;; moves issue extra dependency and for partial register stalls machines
1929 ;; that don't use QImode patterns (and QImode move cause stall on the next
1932 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1933 ;; register stall machines with, where we use QImode instructions, since
1934 ;; partial register stall can be caused there. Then we use movzx.
1935 (define_insn "*movqi_1"
1936 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1937 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1938 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1940 switch (get_attr_type (insn))
1943 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1944 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1946 if (get_attr_mode (insn) == MODE_SI)
1947 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1949 return "mov{b}\t{%1, %0|%0, %1}";
1953 (cond [(and (eq_attr "alternative" "5")
1954 (not (match_operand:QI 1 "aligned_operand" "")))
1955 (const_string "imovx")
1956 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1957 (const_string "imov")
1958 (and (eq_attr "alternative" "3")
1959 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1961 (eq (symbol_ref "TARGET_QIMODE_MATH")
1963 (const_string "imov")
1964 (eq_attr "alternative" "3,5")
1965 (const_string "imovx")
1966 (and (ne (symbol_ref "TARGET_MOVX")
1968 (eq_attr "alternative" "2"))
1969 (const_string "imovx")
1971 (const_string "imov")))
1973 (cond [(eq_attr "alternative" "3,4,5")
1975 (eq_attr "alternative" "6")
1977 (eq_attr "type" "imovx")
1979 (and (eq_attr "type" "imov")
1980 (and (eq_attr "alternative" "0,1")
1981 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1983 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1985 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1988 ;; Avoid partial register stalls when not using QImode arithmetic
1989 (and (eq_attr "type" "imov")
1990 (and (eq_attr "alternative" "0,1")
1991 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1993 (eq (symbol_ref "TARGET_QIMODE_MATH")
1997 (const_string "QI")))])
1999 (define_insn "*swapqi_1"
2000 [(set (match_operand:QI 0 "register_operand" "+r")
2001 (match_operand:QI 1 "register_operand" "+r"))
2004 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2006 [(set_attr "type" "imov")
2007 (set_attr "mode" "SI")
2008 (set_attr "pent_pair" "np")
2009 (set_attr "athlon_decode" "vector")
2010 (set_attr "amdfam10_decode" "vector")])
2012 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2013 (define_insn "*swapqi_2"
2014 [(set (match_operand:QI 0 "register_operand" "+q")
2015 (match_operand:QI 1 "register_operand" "+q"))
2018 "TARGET_PARTIAL_REG_STALL"
2020 [(set_attr "type" "imov")
2021 (set_attr "mode" "QI")
2022 (set_attr "pent_pair" "np")
2023 (set_attr "athlon_decode" "vector")])
2025 (define_expand "movstrictqi"
2026 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2027 (match_operand:QI 1 "general_operand" ""))]
2030 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2032 /* Don't generate memory->memory moves, go through a register. */
2033 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2034 operands[1] = force_reg (QImode, operands[1]);
2037 (define_insn "*movstrictqi_1"
2038 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2039 (match_operand:QI 1 "general_operand" "*qn,m"))]
2040 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2041 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2042 "mov{b}\t{%1, %0|%0, %1}"
2043 [(set_attr "type" "imov")
2044 (set_attr "mode" "QI")])
2046 (define_insn "*movstrictqi_xor"
2047 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2048 (match_operand:QI 1 "const0_operand" ""))
2049 (clobber (reg:CC FLAGS_REG))]
2052 [(set_attr "type" "alu1")
2053 (set_attr "mode" "QI")
2054 (set_attr "length_immediate" "0")])
2056 (define_insn "*movsi_extv_1"
2057 [(set (match_operand:SI 0 "register_operand" "=R")
2058 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2062 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2063 [(set_attr "type" "imovx")
2064 (set_attr "mode" "SI")])
2066 (define_insn "*movhi_extv_1"
2067 [(set (match_operand:HI 0 "register_operand" "=R")
2068 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2072 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2073 [(set_attr "type" "imovx")
2074 (set_attr "mode" "SI")])
2076 (define_insn "*movqi_extv_1"
2077 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2078 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2083 switch (get_attr_type (insn))
2086 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2088 return "mov{b}\t{%h1, %0|%0, %h1}";
2092 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2093 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2094 (ne (symbol_ref "TARGET_MOVX")
2096 (const_string "imovx")
2097 (const_string "imov")))
2099 (if_then_else (eq_attr "type" "imovx")
2101 (const_string "QI")))])
2103 (define_insn "*movqi_extv_1_rex64"
2104 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2105 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2110 switch (get_attr_type (insn))
2113 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2115 return "mov{b}\t{%h1, %0|%0, %h1}";
2119 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2120 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2121 (ne (symbol_ref "TARGET_MOVX")
2123 (const_string "imovx")
2124 (const_string "imov")))
2126 (if_then_else (eq_attr "type" "imovx")
2128 (const_string "QI")))])
2130 ;; Stores and loads of ax to arbitrary constant address.
2131 ;; We fake an second form of instruction to force reload to load address
2132 ;; into register when rax is not available
2133 (define_insn "*movabsqi_1_rex64"
2134 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2135 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2136 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2138 movabs{b}\t{%1, %P0|%P0, %1}
2139 mov{b}\t{%1, %a0|%a0, %1}"
2140 [(set_attr "type" "imov")
2141 (set_attr "modrm" "0,*")
2142 (set_attr "length_address" "8,0")
2143 (set_attr "length_immediate" "0,*")
2144 (set_attr "memory" "store")
2145 (set_attr "mode" "QI")])
2147 (define_insn "*movabsqi_2_rex64"
2148 [(set (match_operand:QI 0 "register_operand" "=a,r")
2149 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2150 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2152 movabs{b}\t{%P1, %0|%0, %P1}
2153 mov{b}\t{%a1, %0|%0, %a1}"
2154 [(set_attr "type" "imov")
2155 (set_attr "modrm" "0,*")
2156 (set_attr "length_address" "8,0")
2157 (set_attr "length_immediate" "0")
2158 (set_attr "memory" "load")
2159 (set_attr "mode" "QI")])
2161 (define_insn "*movdi_extzv_1"
2162 [(set (match_operand:DI 0 "register_operand" "=R")
2163 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2167 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2168 [(set_attr "type" "imovx")
2169 (set_attr "mode" "SI")])
2171 (define_insn "*movsi_extzv_1"
2172 [(set (match_operand:SI 0 "register_operand" "=R")
2173 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2177 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2178 [(set_attr "type" "imovx")
2179 (set_attr "mode" "SI")])
2181 (define_insn "*movqi_extzv_2"
2182 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2183 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2188 switch (get_attr_type (insn))
2191 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2193 return "mov{b}\t{%h1, %0|%0, %h1}";
2197 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2198 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2199 (ne (symbol_ref "TARGET_MOVX")
2201 (const_string "imovx")
2202 (const_string "imov")))
2204 (if_then_else (eq_attr "type" "imovx")
2206 (const_string "QI")))])
2208 (define_insn "*movqi_extzv_2_rex64"
2209 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2210 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2215 switch (get_attr_type (insn))
2218 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2220 return "mov{b}\t{%h1, %0|%0, %h1}";
2224 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2225 (ne (symbol_ref "TARGET_MOVX")
2227 (const_string "imovx")
2228 (const_string "imov")))
2230 (if_then_else (eq_attr "type" "imovx")
2232 (const_string "QI")))])
2234 (define_insn "movsi_insv_1"
2235 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2238 (match_operand:SI 1 "general_operand" "Qmn"))]
2240 "mov{b}\t{%b1, %h0|%h0, %b1}"
2241 [(set_attr "type" "imov")
2242 (set_attr "mode" "QI")])
2244 (define_insn "*movsi_insv_1_rex64"
2245 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2248 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2250 "mov{b}\t{%b1, %h0|%h0, %b1}"
2251 [(set_attr "type" "imov")
2252 (set_attr "mode" "QI")])
2254 (define_insn "movdi_insv_1_rex64"
2255 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2258 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2260 "mov{b}\t{%b1, %h0|%h0, %b1}"
2261 [(set_attr "type" "imov")
2262 (set_attr "mode" "QI")])
2264 (define_insn "*movqi_insv_2"
2265 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2268 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2271 "mov{b}\t{%h1, %h0|%h0, %h1}"
2272 [(set_attr "type" "imov")
2273 (set_attr "mode" "QI")])
2275 (define_expand "movdi"
2276 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2277 (match_operand:DI 1 "general_operand" ""))]
2279 "ix86_expand_move (DImode, operands); DONE;")
2281 (define_insn "*pushdi"
2282 [(set (match_operand:DI 0 "push_operand" "=<")
2283 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2287 (define_insn "*pushdi2_rex64"
2288 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2289 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2294 [(set_attr "type" "push,multi")
2295 (set_attr "mode" "DI")])
2297 ;; Convert impossible pushes of immediate to existing instructions.
2298 ;; First try to get scratch register and go through it. In case this
2299 ;; fails, push sign extended lower part first and then overwrite
2300 ;; upper part by 32bit move.
2302 [(match_scratch:DI 2 "r")
2303 (set (match_operand:DI 0 "push_operand" "")
2304 (match_operand:DI 1 "immediate_operand" ""))]
2305 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2306 && !x86_64_immediate_operand (operands[1], DImode)"
2307 [(set (match_dup 2) (match_dup 1))
2308 (set (match_dup 0) (match_dup 2))]
2311 ;; We need to define this as both peepholer and splitter for case
2312 ;; peephole2 pass is not run.
2313 ;; "&& 1" is needed to keep it from matching the previous pattern.
2315 [(set (match_operand:DI 0 "push_operand" "")
2316 (match_operand:DI 1 "immediate_operand" ""))]
2317 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2318 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2319 [(set (match_dup 0) (match_dup 1))
2320 (set (match_dup 2) (match_dup 3))]
2321 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2322 operands[1] = gen_lowpart (DImode, operands[2]);
2323 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2328 [(set (match_operand:DI 0 "push_operand" "")
2329 (match_operand:DI 1 "immediate_operand" ""))]
2330 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2331 ? epilogue_completed : reload_completed)
2332 && !symbolic_operand (operands[1], DImode)
2333 && !x86_64_immediate_operand (operands[1], DImode)"
2334 [(set (match_dup 0) (match_dup 1))
2335 (set (match_dup 2) (match_dup 3))]
2336 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2337 operands[1] = gen_lowpart (DImode, operands[2]);
2338 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2342 (define_insn "*pushdi2_prologue_rex64"
2343 [(set (match_operand:DI 0 "push_operand" "=<")
2344 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2345 (clobber (mem:BLK (scratch)))]
2348 [(set_attr "type" "push")
2349 (set_attr "mode" "DI")])
2351 (define_insn "*popdi1_epilogue_rex64"
2352 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2353 (mem:DI (reg:DI SP_REG)))
2354 (set (reg:DI SP_REG)
2355 (plus:DI (reg:DI SP_REG) (const_int 8)))
2356 (clobber (mem:BLK (scratch)))]
2359 [(set_attr "type" "pop")
2360 (set_attr "mode" "DI")])
2362 (define_insn "popdi1"
2363 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2364 (mem:DI (reg:DI SP_REG)))
2365 (set (reg:DI SP_REG)
2366 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2369 [(set_attr "type" "pop")
2370 (set_attr "mode" "DI")])
2372 (define_insn "*movdi_xor_rex64"
2373 [(set (match_operand:DI 0 "register_operand" "=r")
2374 (match_operand:DI 1 "const0_operand" ""))
2375 (clobber (reg:CC FLAGS_REG))]
2377 && reload_completed"
2379 [(set_attr "type" "alu1")
2380 (set_attr "mode" "SI")
2381 (set_attr "length_immediate" "0")])
2383 (define_insn "*movdi_or_rex64"
2384 [(set (match_operand:DI 0 "register_operand" "=r")
2385 (match_operand:DI 1 "const_int_operand" "i"))
2386 (clobber (reg:CC FLAGS_REG))]
2389 && operands[1] == constm1_rtx"
2391 operands[1] = constm1_rtx;
2392 return "or{q}\t{%1, %0|%0, %1}";
2394 [(set_attr "type" "alu1")
2395 (set_attr "mode" "DI")
2396 (set_attr "length_immediate" "1")])
2398 (define_insn "*movdi_2"
2399 [(set (match_operand:DI 0 "nonimmediate_operand"
2400 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2401 (match_operand:DI 1 "general_operand"
2402 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2403 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2408 movq\t{%1, %0|%0, %1}
2409 movq\t{%1, %0|%0, %1}
2411 %vmovq\t{%1, %0|%0, %1}
2412 %vmovdqa\t{%1, %0|%0, %1}
2413 %vmovq\t{%1, %0|%0, %1}
2415 movlps\t{%1, %0|%0, %1}
2416 movaps\t{%1, %0|%0, %1}
2417 movlps\t{%1, %0|%0, %1}"
2418 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2419 (set (attr "prefix")
2420 (if_then_else (eq_attr "alternative" "5,6,7,8")
2421 (const_string "vex")
2422 (const_string "orig")))
2423 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2426 [(set (match_operand:DI 0 "push_operand" "")
2427 (match_operand:DI 1 "general_operand" ""))]
2428 "!TARGET_64BIT && reload_completed
2429 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2431 "ix86_split_long_move (operands); DONE;")
2433 ;; %%% This multiword shite has got to go.
2435 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2436 (match_operand:DI 1 "general_operand" ""))]
2437 "!TARGET_64BIT && reload_completed
2438 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2439 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2441 "ix86_split_long_move (operands); DONE;")
2443 (define_insn "*movdi_1_rex64"
2444 [(set (match_operand:DI 0 "nonimmediate_operand"
2445 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2446 (match_operand:DI 1 "general_operand"
2447 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2448 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2450 switch (get_attr_type (insn))
2453 if (SSE_REG_P (operands[0]))
2454 return "movq2dq\t{%1, %0|%0, %1}";
2456 return "movdq2q\t{%1, %0|%0, %1}";
2461 if (get_attr_mode (insn) == MODE_TI)
2462 return "vmovdqa\t{%1, %0|%0, %1}";
2464 return "vmovq\t{%1, %0|%0, %1}";
2467 if (get_attr_mode (insn) == MODE_TI)
2468 return "movdqa\t{%1, %0|%0, %1}";
2472 /* Moves from and into integer register is done using movd
2473 opcode with REX prefix. */
2474 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2475 return "movd\t{%1, %0|%0, %1}";
2476 return "movq\t{%1, %0|%0, %1}";
2479 return "%vpxor\t%0, %d0";
2482 return "pxor\t%0, %0";
2488 return "lea{q}\t{%a1, %0|%0, %a1}";
2491 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2492 if (get_attr_mode (insn) == MODE_SI)
2493 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2494 else if (which_alternative == 2)
2495 return "movabs{q}\t{%1, %0|%0, %1}";
2497 return "mov{q}\t{%1, %0|%0, %1}";
2501 (cond [(eq_attr "alternative" "5")
2502 (const_string "mmx")
2503 (eq_attr "alternative" "6,7,8,9,10")
2504 (const_string "mmxmov")
2505 (eq_attr "alternative" "11")
2506 (const_string "sselog1")
2507 (eq_attr "alternative" "12,13,14,15,16")
2508 (const_string "ssemov")
2509 (eq_attr "alternative" "17,18")
2510 (const_string "ssecvt")
2511 (eq_attr "alternative" "4")
2512 (const_string "multi")
2513 (match_operand:DI 1 "pic_32bit_operand" "")
2514 (const_string "lea")
2516 (const_string "imov")))
2519 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2521 (const_string "*")))
2522 (set (attr "length_immediate")
2524 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2526 (const_string "*")))
2527 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2528 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2529 (set (attr "prefix")
2530 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2531 (const_string "maybe_vex")
2532 (const_string "orig")))
2533 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2535 ;; Stores and loads of ax to arbitrary constant address.
2536 ;; We fake an second form of instruction to force reload to load address
2537 ;; into register when rax is not available
2538 (define_insn "*movabsdi_1_rex64"
2539 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2540 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2541 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2543 movabs{q}\t{%1, %P0|%P0, %1}
2544 mov{q}\t{%1, %a0|%a0, %1}"
2545 [(set_attr "type" "imov")
2546 (set_attr "modrm" "0,*")
2547 (set_attr "length_address" "8,0")
2548 (set_attr "length_immediate" "0,*")
2549 (set_attr "memory" "store")
2550 (set_attr "mode" "DI")])
2552 (define_insn "*movabsdi_2_rex64"
2553 [(set (match_operand:DI 0 "register_operand" "=a,r")
2554 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2555 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2557 movabs{q}\t{%P1, %0|%0, %P1}
2558 mov{q}\t{%a1, %0|%0, %a1}"
2559 [(set_attr "type" "imov")
2560 (set_attr "modrm" "0,*")
2561 (set_attr "length_address" "8,0")
2562 (set_attr "length_immediate" "0")
2563 (set_attr "memory" "load")
2564 (set_attr "mode" "DI")])
2566 ;; Convert impossible stores of immediate to existing instructions.
2567 ;; First try to get scratch register and go through it. In case this
2568 ;; fails, move by 32bit parts.
2570 [(match_scratch:DI 2 "r")
2571 (set (match_operand:DI 0 "memory_operand" "")
2572 (match_operand:DI 1 "immediate_operand" ""))]
2573 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2574 && !x86_64_immediate_operand (operands[1], DImode)"
2575 [(set (match_dup 2) (match_dup 1))
2576 (set (match_dup 0) (match_dup 2))]
2579 ;; We need to define this as both peepholer and splitter for case
2580 ;; peephole2 pass is not run.
2581 ;; "&& 1" is needed to keep it from matching the previous pattern.
2583 [(set (match_operand:DI 0 "memory_operand" "")
2584 (match_operand:DI 1 "immediate_operand" ""))]
2585 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2586 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2587 [(set (match_dup 2) (match_dup 3))
2588 (set (match_dup 4) (match_dup 5))]
2589 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2592 [(set (match_operand:DI 0 "memory_operand" "")
2593 (match_operand:DI 1 "immediate_operand" ""))]
2594 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2595 ? epilogue_completed : reload_completed)
2596 && !symbolic_operand (operands[1], DImode)
2597 && !x86_64_immediate_operand (operands[1], DImode)"
2598 [(set (match_dup 2) (match_dup 3))
2599 (set (match_dup 4) (match_dup 5))]
2600 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2602 (define_insn "*swapdi_rex64"
2603 [(set (match_operand:DI 0 "register_operand" "+r")
2604 (match_operand:DI 1 "register_operand" "+r"))
2609 [(set_attr "type" "imov")
2610 (set_attr "mode" "DI")
2611 (set_attr "pent_pair" "np")
2612 (set_attr "athlon_decode" "vector")
2613 (set_attr "amdfam10_decode" "double")])
2615 (define_expand "movoi"
2616 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2617 (match_operand:OI 1 "general_operand" ""))]
2619 "ix86_expand_move (OImode, operands); DONE;")
2621 (define_insn "*movoi_internal"
2622 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2623 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2625 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2627 switch (which_alternative)
2630 return "vxorps\t%0, %0, %0";
2633 if (misaligned_operand (operands[0], OImode)
2634 || misaligned_operand (operands[1], OImode))
2635 return "vmovdqu\t{%1, %0|%0, %1}";
2637 return "vmovdqa\t{%1, %0|%0, %1}";
2642 [(set_attr "type" "sselog1,ssemov,ssemov")
2643 (set_attr "prefix" "vex")
2644 (set_attr "mode" "OI")])
2646 (define_expand "movti"
2647 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2648 (match_operand:TI 1 "nonimmediate_operand" ""))]
2649 "TARGET_SSE || TARGET_64BIT"
2652 ix86_expand_move (TImode, operands);
2653 else if (push_operand (operands[0], TImode))
2654 ix86_expand_push (TImode, operands[1]);
2656 ix86_expand_vector_move (TImode, operands);
2660 (define_insn "*movti_internal"
2661 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2662 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2663 "TARGET_SSE && !TARGET_64BIT
2664 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2666 switch (which_alternative)
2669 if (get_attr_mode (insn) == MODE_V4SF)
2670 return "%vxorps\t%0, %d0";
2672 return "%vpxor\t%0, %d0";
2675 /* TDmode values are passed as TImode on the stack. Moving them
2676 to stack may result in unaligned memory access. */
2677 if (misaligned_operand (operands[0], TImode)
2678 || misaligned_operand (operands[1], TImode))
2680 if (get_attr_mode (insn) == MODE_V4SF)
2681 return "%vmovups\t{%1, %0|%0, %1}";
2683 return "%vmovdqu\t{%1, %0|%0, %1}";
2687 if (get_attr_mode (insn) == MODE_V4SF)
2688 return "%vmovaps\t{%1, %0|%0, %1}";
2690 return "%vmovdqa\t{%1, %0|%0, %1}";
2696 [(set_attr "type" "sselog1,ssemov,ssemov")
2697 (set_attr "prefix" "maybe_vex")
2699 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2700 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2701 (const_string "V4SF")
2702 (and (eq_attr "alternative" "2")
2703 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2705 (const_string "V4SF")]
2706 (const_string "TI")))])
2708 (define_insn "*movti_rex64"
2709 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2710 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2712 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2714 switch (which_alternative)
2720 if (get_attr_mode (insn) == MODE_V4SF)
2721 return "%vxorps\t%0, %d0";
2723 return "%vpxor\t%0, %d0";
2726 /* TDmode values are passed as TImode on the stack. Moving them
2727 to stack may result in unaligned memory access. */
2728 if (misaligned_operand (operands[0], TImode)
2729 || misaligned_operand (operands[1], TImode))
2731 if (get_attr_mode (insn) == MODE_V4SF)
2732 return "%vmovups\t{%1, %0|%0, %1}";
2734 return "%vmovdqu\t{%1, %0|%0, %1}";
2738 if (get_attr_mode (insn) == MODE_V4SF)
2739 return "%vmovaps\t{%1, %0|%0, %1}";
2741 return "%vmovdqa\t{%1, %0|%0, %1}";
2747 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2748 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2750 (cond [(eq_attr "alternative" "2,3")
2752 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2754 (const_string "V4SF")
2755 (const_string "TI"))
2756 (eq_attr "alternative" "4")
2758 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2760 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2762 (const_string "V4SF")
2763 (const_string "TI"))]
2764 (const_string "DI")))])
2767 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2768 (match_operand:TI 1 "general_operand" ""))]
2769 "reload_completed && !SSE_REG_P (operands[0])
2770 && !SSE_REG_P (operands[1])"
2772 "ix86_split_long_move (operands); DONE;")
2774 ;; This expands to what emit_move_complex would generate if we didn't
2775 ;; have a movti pattern. Having this avoids problems with reload on
2776 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2777 ;; to have around all the time.
2778 (define_expand "movcdi"
2779 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2780 (match_operand:CDI 1 "general_operand" ""))]
2783 if (push_operand (operands[0], CDImode))
2784 emit_move_complex_push (CDImode, operands[0], operands[1]);
2786 emit_move_complex_parts (operands[0], operands[1]);
2790 (define_expand "movsf"
2791 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2792 (match_operand:SF 1 "general_operand" ""))]
2794 "ix86_expand_move (SFmode, operands); DONE;")
2796 (define_insn "*pushsf"
2797 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2798 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2801 /* Anything else should be already split before reg-stack. */
2802 gcc_assert (which_alternative == 1);
2803 return "push{l}\t%1";
2805 [(set_attr "type" "multi,push,multi")
2806 (set_attr "unit" "i387,*,*")
2807 (set_attr "mode" "SF,SI,SF")])
2809 (define_insn "*pushsf_rex64"
2810 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2811 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2814 /* Anything else should be already split before reg-stack. */
2815 gcc_assert (which_alternative == 1);
2816 return "push{q}\t%q1";
2818 [(set_attr "type" "multi,push,multi")
2819 (set_attr "unit" "i387,*,*")
2820 (set_attr "mode" "SF,DI,SF")])
2823 [(set (match_operand:SF 0 "push_operand" "")
2824 (match_operand:SF 1 "memory_operand" ""))]
2826 && MEM_P (operands[1])
2827 && (operands[2] = find_constant_src (insn))"
2831 ;; %%% Kill this when call knows how to work this out.
2833 [(set (match_operand:SF 0 "push_operand" "")
2834 (match_operand:SF 1 "any_fp_register_operand" ""))]
2836 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2837 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2840 [(set (match_operand:SF 0 "push_operand" "")
2841 (match_operand:SF 1 "any_fp_register_operand" ""))]
2843 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2844 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2846 (define_insn "*movsf_1"
2847 [(set (match_operand:SF 0 "nonimmediate_operand"
2848 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2849 (match_operand:SF 1 "general_operand"
2850 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2851 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2852 && (reload_in_progress || reload_completed
2853 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2854 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2855 && standard_80387_constant_p (operands[1]))
2856 || GET_CODE (operands[1]) != CONST_DOUBLE
2857 || memory_operand (operands[0], SFmode))"
2859 switch (which_alternative)
2863 return output_387_reg_move (insn, operands);
2866 return standard_80387_constant_opcode (operands[1]);
2870 return "mov{l}\t{%1, %0|%0, %1}";
2872 if (get_attr_mode (insn) == MODE_TI)
2873 return "%vpxor\t%0, %d0";
2875 return "%vxorps\t%0, %d0";
2877 if (get_attr_mode (insn) == MODE_V4SF)
2878 return "%vmovaps\t{%1, %0|%0, %1}";
2880 return "%vmovss\t{%1, %d0|%d0, %1}";
2883 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2884 : "vmovss\t{%1, %0|%0, %1}";
2886 return "movss\t{%1, %0|%0, %1}";
2888 return "%vmovss\t{%1, %0|%0, %1}";
2890 case 9: case 10: case 14: case 15:
2891 return "movd\t{%1, %0|%0, %1}";
2893 return "%vmovd\t{%1, %0|%0, %1}";
2896 return "movq\t{%1, %0|%0, %1}";
2902 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2903 (set (attr "prefix")
2904 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2905 (const_string "maybe_vex")
2906 (const_string "orig")))
2908 (cond [(eq_attr "alternative" "3,4,9,10")
2910 (eq_attr "alternative" "5")
2912 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2914 (ne (symbol_ref "TARGET_SSE2")
2916 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2919 (const_string "V4SF"))
2920 /* For architectures resolving dependencies on
2921 whole SSE registers use APS move to break dependency
2922 chains, otherwise use short move to avoid extra work.
2924 Do the same for architectures resolving dependencies on
2925 the parts. While in DF mode it is better to always handle
2926 just register parts, the SF mode is different due to lack
2927 of instructions to load just part of the register. It is
2928 better to maintain the whole registers in single format
2929 to avoid problems on using packed logical operations. */
2930 (eq_attr "alternative" "6")
2932 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2934 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2936 (const_string "V4SF")
2937 (const_string "SF"))
2938 (eq_attr "alternative" "11")
2939 (const_string "DI")]
2940 (const_string "SF")))])
2942 (define_insn "*swapsf"
2943 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2944 (match_operand:SF 1 "fp_register_operand" "+f"))
2947 "reload_completed || TARGET_80387"
2949 if (STACK_TOP_P (operands[0]))
2954 [(set_attr "type" "fxch")
2955 (set_attr "mode" "SF")])
2957 (define_expand "movdf"
2958 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2959 (match_operand:DF 1 "general_operand" ""))]
2961 "ix86_expand_move (DFmode, operands); DONE;")
2963 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2964 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2965 ;; On the average, pushdf using integers can be still shorter. Allow this
2966 ;; pattern for optimize_size too.
2968 (define_insn "*pushdf_nointeger"
2969 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2970 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2971 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2973 /* This insn should be already split before reg-stack. */
2976 [(set_attr "type" "multi")
2977 (set_attr "unit" "i387,*,*,*")
2978 (set_attr "mode" "DF,SI,SI,DF")])
2980 (define_insn "*pushdf_integer"
2981 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2982 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2983 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2985 /* This insn should be already split before reg-stack. */
2988 [(set_attr "type" "multi")
2989 (set_attr "unit" "i387,*,*")
2990 (set_attr "mode" "DF,SI,DF")])
2992 ;; %%% Kill this when call knows how to work this out.
2994 [(set (match_operand:DF 0 "push_operand" "")
2995 (match_operand:DF 1 "any_fp_register_operand" ""))]
2997 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2998 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3002 [(set (match_operand:DF 0 "push_operand" "")
3003 (match_operand:DF 1 "general_operand" ""))]
3006 "ix86_split_long_move (operands); DONE;")
3008 ;; Moving is usually shorter when only FP registers are used. This separate
3009 ;; movdf pattern avoids the use of integer registers for FP operations
3010 ;; when optimizing for size.
3012 (define_insn "*movdf_nointeger"
3013 [(set (match_operand:DF 0 "nonimmediate_operand"
3014 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3015 (match_operand:DF 1 "general_operand"
3016 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3017 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3018 && ((optimize_function_for_size_p (cfun)
3019 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3020 && (reload_in_progress || reload_completed
3021 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3022 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3023 && optimize_function_for_size_p (cfun)
3024 && !memory_operand (operands[0], DFmode)
3025 && standard_80387_constant_p (operands[1]))
3026 || GET_CODE (operands[1]) != CONST_DOUBLE
3027 || ((optimize_function_for_size_p (cfun)
3028 || !TARGET_MEMORY_MISMATCH_STALL
3029 || reload_in_progress || reload_completed)
3030 && memory_operand (operands[0], DFmode)))"
3032 switch (which_alternative)
3036 return output_387_reg_move (insn, operands);
3039 return standard_80387_constant_opcode (operands[1]);
3045 switch (get_attr_mode (insn))
3048 return "%vxorps\t%0, %d0";
3050 return "%vxorpd\t%0, %d0";
3052 return "%vpxor\t%0, %d0";
3059 switch (get_attr_mode (insn))
3062 return "%vmovaps\t{%1, %0|%0, %1}";
3064 return "%vmovapd\t{%1, %0|%0, %1}";
3066 return "%vmovdqa\t{%1, %0|%0, %1}";
3068 return "%vmovq\t{%1, %0|%0, %1}";
3072 if (REG_P (operands[0]) && REG_P (operands[1]))
3073 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3075 return "vmovsd\t{%1, %0|%0, %1}";
3078 return "movsd\t{%1, %0|%0, %1}";
3082 if (REG_P (operands[0]))
3083 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3085 return "vmovlpd\t{%1, %0|%0, %1}";
3088 return "movlpd\t{%1, %0|%0, %1}";
3092 if (REG_P (operands[0]))
3093 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3095 return "vmovlps\t{%1, %0|%0, %1}";
3098 return "movlps\t{%1, %0|%0, %1}";
3107 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3108 (set (attr "prefix")
3109 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3110 (const_string "orig")
3111 (const_string "maybe_vex")))
3112 (set (attr "prefix_data16")
3113 (if_then_else (eq_attr "mode" "V1DF")
3115 (const_string "*")))
3117 (cond [(eq_attr "alternative" "0,1,2")
3119 (eq_attr "alternative" "3,4")
3122 /* For SSE1, we have many fewer alternatives. */
3123 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3124 (cond [(eq_attr "alternative" "5,6")
3125 (const_string "V4SF")
3127 (const_string "V2SF"))
3129 /* xorps is one byte shorter. */
3130 (eq_attr "alternative" "5")
3131 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3133 (const_string "V4SF")
3134 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3138 (const_string "V2DF"))
3140 /* For architectures resolving dependencies on
3141 whole SSE registers use APD move to break dependency
3142 chains, otherwise use short move to avoid extra work.
3144 movaps encodes one byte shorter. */
3145 (eq_attr "alternative" "6")
3147 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3149 (const_string "V4SF")
3150 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3152 (const_string "V2DF")
3154 (const_string "DF"))
3155 /* For architectures resolving dependencies on register
3156 parts we may avoid extra work to zero out upper part
3158 (eq_attr "alternative" "7")
3160 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3162 (const_string "V1DF")
3163 (const_string "DF"))
3165 (const_string "DF")))])
3167 (define_insn "*movdf_integer_rex64"
3168 [(set (match_operand:DF 0 "nonimmediate_operand"
3169 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3170 (match_operand:DF 1 "general_operand"
3171 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3172 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3173 && (reload_in_progress || reload_completed
3174 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3175 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3176 && optimize_function_for_size_p (cfun)
3177 && standard_80387_constant_p (operands[1]))
3178 || GET_CODE (operands[1]) != CONST_DOUBLE
3179 || memory_operand (operands[0], DFmode))"
3181 switch (which_alternative)
3185 return output_387_reg_move (insn, operands);
3188 return standard_80387_constant_opcode (operands[1]);
3195 switch (get_attr_mode (insn))
3198 return "%vxorps\t%0, %d0";
3200 return "%vxorpd\t%0, %d0";
3202 return "%vpxor\t%0, %d0";
3209 switch (get_attr_mode (insn))
3212 return "%vmovaps\t{%1, %0|%0, %1}";
3214 return "%vmovapd\t{%1, %0|%0, %1}";
3216 return "%vmovdqa\t{%1, %0|%0, %1}";
3218 return "%vmovq\t{%1, %0|%0, %1}";
3222 if (REG_P (operands[0]) && REG_P (operands[1]))
3223 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3225 return "vmovsd\t{%1, %0|%0, %1}";
3228 return "movsd\t{%1, %0|%0, %1}";
3230 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3232 return "%vmovlps\t{%1, %d0|%d0, %1}";
3239 return "%vmovd\t{%1, %0|%0, %1}";
3245 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3246 (set (attr "prefix")
3247 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3248 (const_string "orig")
3249 (const_string "maybe_vex")))
3250 (set (attr "prefix_data16")
3251 (if_then_else (eq_attr "mode" "V1DF")
3253 (const_string "*")))
3255 (cond [(eq_attr "alternative" "0,1,2")
3257 (eq_attr "alternative" "3,4,9,10")
3260 /* For SSE1, we have many fewer alternatives. */
3261 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3262 (cond [(eq_attr "alternative" "5,6")
3263 (const_string "V4SF")
3265 (const_string "V2SF"))
3267 /* xorps is one byte shorter. */
3268 (eq_attr "alternative" "5")
3269 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3271 (const_string "V4SF")
3272 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3276 (const_string "V2DF"))
3278 /* For architectures resolving dependencies on
3279 whole SSE registers use APD move to break dependency
3280 chains, otherwise use short move to avoid extra work.
3282 movaps encodes one byte shorter. */
3283 (eq_attr "alternative" "6")
3285 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3287 (const_string "V4SF")
3288 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3290 (const_string "V2DF")
3292 (const_string "DF"))
3293 /* For architectures resolving dependencies on register
3294 parts we may avoid extra work to zero out upper part
3296 (eq_attr "alternative" "7")
3298 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3300 (const_string "V1DF")
3301 (const_string "DF"))
3303 (const_string "DF")))])
3305 (define_insn "*movdf_integer"
3306 [(set (match_operand:DF 0 "nonimmediate_operand"
3307 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3308 (match_operand:DF 1 "general_operand"
3309 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3310 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3311 && optimize_function_for_speed_p (cfun)
3312 && TARGET_INTEGER_DFMODE_MOVES
3313 && (reload_in_progress || reload_completed
3314 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3315 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3316 && optimize_function_for_size_p (cfun)
3317 && standard_80387_constant_p (operands[1]))
3318 || GET_CODE (operands[1]) != CONST_DOUBLE
3319 || memory_operand (operands[0], DFmode))"
3321 switch (which_alternative)
3325 return output_387_reg_move (insn, operands);
3328 return standard_80387_constant_opcode (operands[1]);
3335 switch (get_attr_mode (insn))
3338 return "xorps\t%0, %0";
3340 return "xorpd\t%0, %0";
3342 return "pxor\t%0, %0";
3349 switch (get_attr_mode (insn))
3352 return "movaps\t{%1, %0|%0, %1}";
3354 return "movapd\t{%1, %0|%0, %1}";
3356 return "movdqa\t{%1, %0|%0, %1}";
3358 return "movq\t{%1, %0|%0, %1}";
3360 return "movsd\t{%1, %0|%0, %1}";
3362 return "movlpd\t{%1, %0|%0, %1}";
3364 return "movlps\t{%1, %0|%0, %1}";
3373 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3374 (set (attr "prefix_data16")
3375 (if_then_else (eq_attr "mode" "V1DF")
3377 (const_string "*")))
3379 (cond [(eq_attr "alternative" "0,1,2")
3381 (eq_attr "alternative" "3,4")
3384 /* For SSE1, we have many fewer alternatives. */
3385 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3386 (cond [(eq_attr "alternative" "5,6")
3387 (const_string "V4SF")
3389 (const_string "V2SF"))
3391 /* xorps is one byte shorter. */
3392 (eq_attr "alternative" "5")
3393 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3395 (const_string "V4SF")
3396 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3400 (const_string "V2DF"))
3402 /* For architectures resolving dependencies on
3403 whole SSE registers use APD move to break dependency
3404 chains, otherwise use short move to avoid extra work.
3406 movaps encodes one byte shorter. */
3407 (eq_attr "alternative" "6")
3409 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3411 (const_string "V4SF")
3412 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3414 (const_string "V2DF")
3416 (const_string "DF"))
3417 /* For architectures resolving dependencies on register
3418 parts we may avoid extra work to zero out upper part
3420 (eq_attr "alternative" "7")
3422 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3424 (const_string "V1DF")
3425 (const_string "DF"))
3427 (const_string "DF")))])
3430 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3431 (match_operand:DF 1 "general_operand" ""))]
3433 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3434 && ! (ANY_FP_REG_P (operands[0]) ||
3435 (GET_CODE (operands[0]) == SUBREG
3436 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3437 && ! (ANY_FP_REG_P (operands[1]) ||
3438 (GET_CODE (operands[1]) == SUBREG
3439 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3441 "ix86_split_long_move (operands); DONE;")
3443 (define_insn "*swapdf"
3444 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3445 (match_operand:DF 1 "fp_register_operand" "+f"))
3448 "reload_completed || TARGET_80387"
3450 if (STACK_TOP_P (operands[0]))
3455 [(set_attr "type" "fxch")
3456 (set_attr "mode" "DF")])
3458 (define_expand "movxf"
3459 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3460 (match_operand:XF 1 "general_operand" ""))]
3462 "ix86_expand_move (XFmode, operands); DONE;")
3464 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3465 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3466 ;; Pushing using integer instructions is longer except for constants
3467 ;; and direct memory references.
3468 ;; (assuming that any given constant is pushed only once, but this ought to be
3469 ;; handled elsewhere).
3471 (define_insn "*pushxf_nointeger"
3472 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3473 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3474 "optimize_function_for_size_p (cfun)"
3476 /* This insn should be already split before reg-stack. */
3479 [(set_attr "type" "multi")
3480 (set_attr "unit" "i387,*,*")
3481 (set_attr "mode" "XF,SI,SI")])
3483 (define_insn "*pushxf_integer"
3484 [(set (match_operand:XF 0 "push_operand" "=<,<")
3485 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3486 "optimize_function_for_speed_p (cfun)"
3488 /* This insn should be already split before reg-stack. */
3491 [(set_attr "type" "multi")
3492 (set_attr "unit" "i387,*")
3493 (set_attr "mode" "XF,SI")])
3496 [(set (match_operand 0 "push_operand" "")
3497 (match_operand 1 "general_operand" ""))]
3499 && (GET_MODE (operands[0]) == XFmode
3500 || GET_MODE (operands[0]) == DFmode)
3501 && !ANY_FP_REG_P (operands[1])"
3503 "ix86_split_long_move (operands); DONE;")
3506 [(set (match_operand:XF 0 "push_operand" "")
3507 (match_operand:XF 1 "any_fp_register_operand" ""))]
3509 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3510 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3511 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3513 ;; Do not use integer registers when optimizing for size
3514 (define_insn "*movxf_nointeger"
3515 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3516 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3517 "optimize_function_for_size_p (cfun)
3518 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3519 && (reload_in_progress || reload_completed
3520 || standard_80387_constant_p (operands[1])
3521 || GET_CODE (operands[1]) != CONST_DOUBLE
3522 || memory_operand (operands[0], XFmode))"
3524 switch (which_alternative)
3528 return output_387_reg_move (insn, operands);
3531 return standard_80387_constant_opcode (operands[1]);
3539 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3540 (set_attr "mode" "XF,XF,XF,SI,SI")])
3542 (define_insn "*movxf_integer"
3543 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3544 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3545 "optimize_function_for_speed_p (cfun)
3546 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3547 && (reload_in_progress || reload_completed
3548 || GET_CODE (operands[1]) != CONST_DOUBLE
3549 || memory_operand (operands[0], XFmode))"
3551 switch (which_alternative)
3555 return output_387_reg_move (insn, operands);
3558 return standard_80387_constant_opcode (operands[1]);
3567 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3568 (set_attr "mode" "XF,XF,XF,SI,SI")])
3570 (define_expand "movtf"
3571 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3572 (match_operand:TF 1 "nonimmediate_operand" ""))]
3575 ix86_expand_move (TFmode, operands);
3579 (define_insn "*movtf_internal"
3580 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3581 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3583 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3585 switch (which_alternative)
3589 if (get_attr_mode (insn) == MODE_V4SF)
3590 return "%vmovaps\t{%1, %0|%0, %1}";
3592 return "%vmovdqa\t{%1, %0|%0, %1}";
3594 if (get_attr_mode (insn) == MODE_V4SF)
3595 return "%vxorps\t%0, %d0";
3597 return "%vpxor\t%0, %d0";
3605 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3606 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3608 (cond [(eq_attr "alternative" "0,2")
3610 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3612 (const_string "V4SF")
3613 (const_string "TI"))
3614 (eq_attr "alternative" "1")
3616 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3618 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3620 (const_string "V4SF")
3621 (const_string "TI"))]
3622 (const_string "DI")))])
3624 (define_insn "*pushtf_sse"
3625 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3626 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3629 /* This insn should be already split before reg-stack. */
3632 [(set_attr "type" "multi")
3633 (set_attr "unit" "sse,*,*")
3634 (set_attr "mode" "TF,SI,SI")])
3637 [(set (match_operand:TF 0 "push_operand" "")
3638 (match_operand:TF 1 "general_operand" ""))]
3639 "TARGET_SSE2 && reload_completed
3640 && !SSE_REG_P (operands[1])"
3642 "ix86_split_long_move (operands); DONE;")
3645 [(set (match_operand:TF 0 "push_operand" "")
3646 (match_operand:TF 1 "any_fp_register_operand" ""))]
3648 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3649 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3653 [(set (match_operand 0 "nonimmediate_operand" "")
3654 (match_operand 1 "general_operand" ""))]
3656 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3657 && GET_MODE (operands[0]) == XFmode
3658 && ! (ANY_FP_REG_P (operands[0]) ||
3659 (GET_CODE (operands[0]) == SUBREG
3660 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3661 && ! (ANY_FP_REG_P (operands[1]) ||
3662 (GET_CODE (operands[1]) == SUBREG
3663 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3665 "ix86_split_long_move (operands); DONE;")
3668 [(set (match_operand 0 "register_operand" "")
3669 (match_operand 1 "memory_operand" ""))]
3671 && MEM_P (operands[1])
3672 && (GET_MODE (operands[0]) == TFmode
3673 || GET_MODE (operands[0]) == XFmode
3674 || GET_MODE (operands[0]) == SFmode
3675 || GET_MODE (operands[0]) == DFmode)
3676 && (operands[2] = find_constant_src (insn))"
3677 [(set (match_dup 0) (match_dup 2))]
3679 rtx c = operands[2];
3680 rtx r = operands[0];
3682 if (GET_CODE (r) == SUBREG)
3687 if (!standard_sse_constant_p (c))
3690 else if (FP_REG_P (r))
3692 if (!standard_80387_constant_p (c))
3695 else if (MMX_REG_P (r))
3700 [(set (match_operand 0 "register_operand" "")
3701 (float_extend (match_operand 1 "memory_operand" "")))]
3703 && MEM_P (operands[1])
3704 && (GET_MODE (operands[0]) == TFmode
3705 || GET_MODE (operands[0]) == XFmode
3706 || GET_MODE (operands[0]) == SFmode
3707 || GET_MODE (operands[0]) == DFmode)
3708 && (operands[2] = find_constant_src (insn))"
3709 [(set (match_dup 0) (match_dup 2))]
3711 rtx c = operands[2];
3712 rtx r = operands[0];
3714 if (GET_CODE (r) == SUBREG)
3719 if (!standard_sse_constant_p (c))
3722 else if (FP_REG_P (r))
3724 if (!standard_80387_constant_p (c))
3727 else if (MMX_REG_P (r))
3731 (define_insn "swapxf"
3732 [(set (match_operand:XF 0 "register_operand" "+f")
3733 (match_operand:XF 1 "register_operand" "+f"))
3738 if (STACK_TOP_P (operands[0]))
3743 [(set_attr "type" "fxch")
3744 (set_attr "mode" "XF")])
3746 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3748 [(set (match_operand:X87MODEF 0 "register_operand" "")
3749 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3750 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3751 && (standard_80387_constant_p (operands[1]) == 8
3752 || standard_80387_constant_p (operands[1]) == 9)"
3753 [(set (match_dup 0)(match_dup 1))
3755 (neg:X87MODEF (match_dup 0)))]
3759 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3760 if (real_isnegzero (&r))
3761 operands[1] = CONST0_RTX (<MODE>mode);
3763 operands[1] = CONST1_RTX (<MODE>mode);
3767 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3768 (match_operand:TF 1 "general_operand" ""))]
3770 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3772 "ix86_split_long_move (operands); DONE;")
3774 ;; Zero extension instructions
3776 (define_expand "zero_extendhisi2"
3777 [(set (match_operand:SI 0 "register_operand" "")
3778 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3781 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3783 operands[1] = force_reg (HImode, operands[1]);
3784 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3789 (define_insn "zero_extendhisi2_and"
3790 [(set (match_operand:SI 0 "register_operand" "=r")
3791 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3792 (clobber (reg:CC FLAGS_REG))]
3793 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3795 [(set_attr "type" "alu1")
3796 (set_attr "mode" "SI")])
3799 [(set (match_operand:SI 0 "register_operand" "")
3800 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3801 (clobber (reg:CC FLAGS_REG))]
3802 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3803 && optimize_function_for_speed_p (cfun)"
3804 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3805 (clobber (reg:CC FLAGS_REG))])]
3808 (define_insn "*zero_extendhisi2_movzwl"
3809 [(set (match_operand:SI 0 "register_operand" "=r")
3810 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3811 "!TARGET_ZERO_EXTEND_WITH_AND
3812 || optimize_function_for_size_p (cfun)"
3813 "movz{wl|x}\t{%1, %0|%0, %1}"
3814 [(set_attr "type" "imovx")
3815 (set_attr "mode" "SI")])
3817 (define_expand "zero_extendqihi2"
3819 [(set (match_operand:HI 0 "register_operand" "")
3820 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3821 (clobber (reg:CC FLAGS_REG))])]
3825 (define_insn "*zero_extendqihi2_and"
3826 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3827 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3828 (clobber (reg:CC FLAGS_REG))]
3829 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3831 [(set_attr "type" "alu1")
3832 (set_attr "mode" "HI")])
3834 (define_insn "*zero_extendqihi2_movzbw_and"
3835 [(set (match_operand:HI 0 "register_operand" "=r,r")
3836 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3837 (clobber (reg:CC FLAGS_REG))]
3838 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3840 [(set_attr "type" "imovx,alu1")
3841 (set_attr "mode" "HI")])
3843 ; zero extend to SImode here to avoid partial register stalls
3844 (define_insn "*zero_extendqihi2_movzbl"
3845 [(set (match_operand:HI 0 "register_operand" "=r")
3846 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3847 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3848 && reload_completed"
3849 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3850 [(set_attr "type" "imovx")
3851 (set_attr "mode" "SI")])
3853 ;; For the movzbw case strip only the clobber
3855 [(set (match_operand:HI 0 "register_operand" "")
3856 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3857 (clobber (reg:CC FLAGS_REG))]
3859 && (!TARGET_ZERO_EXTEND_WITH_AND
3860 || optimize_function_for_size_p (cfun))
3861 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3862 [(set (match_operand:HI 0 "register_operand" "")
3863 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3865 ;; When source and destination does not overlap, clear destination
3866 ;; first and then do the movb
3868 [(set (match_operand:HI 0 "register_operand" "")
3869 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3870 (clobber (reg:CC FLAGS_REG))]
3872 && ANY_QI_REG_P (operands[0])
3873 && (TARGET_ZERO_EXTEND_WITH_AND
3874 && optimize_function_for_speed_p (cfun))
3875 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3876 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3878 operands[2] = gen_lowpart (QImode, operands[0]);
3879 ix86_expand_clear (operands[0]);
3882 ;; Rest is handled by single and.
3884 [(set (match_operand:HI 0 "register_operand" "")
3885 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3886 (clobber (reg:CC FLAGS_REG))]
3888 && true_regnum (operands[0]) == true_regnum (operands[1])"
3889 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3890 (clobber (reg:CC FLAGS_REG))])]
3893 (define_expand "zero_extendqisi2"
3895 [(set (match_operand:SI 0 "register_operand" "")
3896 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3897 (clobber (reg:CC FLAGS_REG))])]
3901 (define_insn "*zero_extendqisi2_and"
3902 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3903 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3904 (clobber (reg:CC FLAGS_REG))]
3905 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3907 [(set_attr "type" "alu1")
3908 (set_attr "mode" "SI")])
3910 (define_insn "*zero_extendqisi2_movzbl_and"
3911 [(set (match_operand:SI 0 "register_operand" "=r,r")
3912 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3913 (clobber (reg:CC FLAGS_REG))]
3914 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3916 [(set_attr "type" "imovx,alu1")
3917 (set_attr "mode" "SI")])
3919 (define_insn "*zero_extendqisi2_movzbl"
3920 [(set (match_operand:SI 0 "register_operand" "=r")
3921 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3922 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3923 && reload_completed"
3924 "movz{bl|x}\t{%1, %0|%0, %1}"
3925 [(set_attr "type" "imovx")
3926 (set_attr "mode" "SI")])
3928 ;; For the movzbl case strip only the clobber
3930 [(set (match_operand:SI 0 "register_operand" "")
3931 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3932 (clobber (reg:CC FLAGS_REG))]
3934 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3935 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3937 (zero_extend:SI (match_dup 1)))])
3939 ;; When source and destination does not overlap, clear destination
3940 ;; first and then do the movb
3942 [(set (match_operand:SI 0 "register_operand" "")
3943 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3944 (clobber (reg:CC FLAGS_REG))]
3946 && ANY_QI_REG_P (operands[0])
3947 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3948 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3949 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3950 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3952 operands[2] = gen_lowpart (QImode, operands[0]);
3953 ix86_expand_clear (operands[0]);
3956 ;; Rest is handled by single and.
3958 [(set (match_operand:SI 0 "register_operand" "")
3959 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3960 (clobber (reg:CC FLAGS_REG))]
3962 && true_regnum (operands[0]) == true_regnum (operands[1])"
3963 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3964 (clobber (reg:CC FLAGS_REG))])]
3967 ;; %%% Kill me once multi-word ops are sane.
3968 (define_expand "zero_extendsidi2"
3969 [(set (match_operand:DI 0 "register_operand" "")
3970 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3975 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3980 (define_insn "zero_extendsidi2_32"
3981 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3983 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3984 (clobber (reg:CC FLAGS_REG))]
3990 movd\t{%1, %0|%0, %1}
3991 movd\t{%1, %0|%0, %1}
3992 %vmovd\t{%1, %0|%0, %1}
3993 %vmovd\t{%1, %0|%0, %1}"
3994 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3995 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3996 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3998 (define_insn "zero_extendsidi2_rex64"
3999 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4001 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4004 mov\t{%k1, %k0|%k0, %k1}
4006 movd\t{%1, %0|%0, %1}
4007 movd\t{%1, %0|%0, %1}
4008 %vmovd\t{%1, %0|%0, %1}
4009 %vmovd\t{%1, %0|%0, %1}"
4010 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4011 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4012 (set_attr "prefix_0f" "0,*,*,*,*,*")
4013 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4016 [(set (match_operand:DI 0 "memory_operand" "")
4017 (zero_extend:DI (match_dup 0)))]
4019 [(set (match_dup 4) (const_int 0))]
4020 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4023 [(set (match_operand:DI 0 "register_operand" "")
4024 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4025 (clobber (reg:CC FLAGS_REG))]
4026 "!TARGET_64BIT && reload_completed
4027 && true_regnum (operands[0]) == true_regnum (operands[1])"
4028 [(set (match_dup 4) (const_int 0))]
4029 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4032 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4033 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4034 (clobber (reg:CC FLAGS_REG))]
4035 "!TARGET_64BIT && reload_completed
4036 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4037 [(set (match_dup 3) (match_dup 1))
4038 (set (match_dup 4) (const_int 0))]
4039 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4041 (define_insn "zero_extendhidi2"
4042 [(set (match_operand:DI 0 "register_operand" "=r")
4043 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4045 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4046 [(set_attr "type" "imovx")
4047 (set_attr "mode" "SI")])
4049 (define_insn "zero_extendqidi2"
4050 [(set (match_operand:DI 0 "register_operand" "=r")
4051 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4053 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4054 [(set_attr "type" "imovx")
4055 (set_attr "mode" "SI")])
4057 ;; Sign extension instructions
4059 (define_expand "extendsidi2"
4060 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4061 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4062 (clobber (reg:CC FLAGS_REG))
4063 (clobber (match_scratch:SI 2 ""))])]
4068 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4073 (define_insn "*extendsidi2_1"
4074 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4075 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4076 (clobber (reg:CC FLAGS_REG))
4077 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4081 (define_insn "extendsidi2_rex64"
4082 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4083 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4087 movs{lq|x}\t{%1, %0|%0, %1}"
4088 [(set_attr "type" "imovx")
4089 (set_attr "mode" "DI")
4090 (set_attr "prefix_0f" "0")
4091 (set_attr "modrm" "0,1")])
4093 (define_insn "extendhidi2"
4094 [(set (match_operand:DI 0 "register_operand" "=r")
4095 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4097 "movs{wq|x}\t{%1, %0|%0, %1}"
4098 [(set_attr "type" "imovx")
4099 (set_attr "mode" "DI")])
4101 (define_insn "extendqidi2"
4102 [(set (match_operand:DI 0 "register_operand" "=r")
4103 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4105 "movs{bq|x}\t{%1, %0|%0, %1}"
4106 [(set_attr "type" "imovx")
4107 (set_attr "mode" "DI")])
4109 ;; Extend to memory case when source register does die.
4111 [(set (match_operand:DI 0 "memory_operand" "")
4112 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4113 (clobber (reg:CC FLAGS_REG))
4114 (clobber (match_operand:SI 2 "register_operand" ""))]
4116 && dead_or_set_p (insn, operands[1])
4117 && !reg_mentioned_p (operands[1], operands[0]))"
4118 [(set (match_dup 3) (match_dup 1))
4119 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4120 (clobber (reg:CC FLAGS_REG))])
4121 (set (match_dup 4) (match_dup 1))]
4122 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4124 ;; Extend to memory case when source register does not die.
4126 [(set (match_operand:DI 0 "memory_operand" "")
4127 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4128 (clobber (reg:CC FLAGS_REG))
4129 (clobber (match_operand:SI 2 "register_operand" ""))]
4133 split_di (&operands[0], 1, &operands[3], &operands[4]);
4135 emit_move_insn (operands[3], operands[1]);
4137 /* Generate a cltd if possible and doing so it profitable. */
4138 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4139 && true_regnum (operands[1]) == AX_REG
4140 && true_regnum (operands[2]) == DX_REG)
4142 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4146 emit_move_insn (operands[2], operands[1]);
4147 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4149 emit_move_insn (operands[4], operands[2]);
4153 ;; Extend to register case. Optimize case where source and destination
4154 ;; registers match and cases where we can use cltd.
4156 [(set (match_operand:DI 0 "register_operand" "")
4157 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4158 (clobber (reg:CC FLAGS_REG))
4159 (clobber (match_scratch:SI 2 ""))]
4163 split_di (&operands[0], 1, &operands[3], &operands[4]);
4165 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4166 emit_move_insn (operands[3], operands[1]);
4168 /* Generate a cltd if possible and doing so it profitable. */
4169 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4170 && true_regnum (operands[3]) == AX_REG)
4172 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4176 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4177 emit_move_insn (operands[4], operands[1]);
4179 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4183 (define_insn "extendhisi2"
4184 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4185 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4188 switch (get_attr_prefix_0f (insn))
4191 return "{cwtl|cwde}";
4193 return "movs{wl|x}\t{%1, %0|%0, %1}";
4196 [(set_attr "type" "imovx")
4197 (set_attr "mode" "SI")
4198 (set (attr "prefix_0f")
4199 ;; movsx is short decodable while cwtl is vector decoded.
4200 (if_then_else (and (eq_attr "cpu" "!k6")
4201 (eq_attr "alternative" "0"))
4203 (const_string "1")))
4205 (if_then_else (eq_attr "prefix_0f" "0")
4207 (const_string "1")))])
4209 (define_insn "*extendhisi2_zext"
4210 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4212 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4215 switch (get_attr_prefix_0f (insn))
4218 return "{cwtl|cwde}";
4220 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4223 [(set_attr "type" "imovx")
4224 (set_attr "mode" "SI")
4225 (set (attr "prefix_0f")
4226 ;; movsx is short decodable while cwtl is vector decoded.
4227 (if_then_else (and (eq_attr "cpu" "!k6")
4228 (eq_attr "alternative" "0"))
4230 (const_string "1")))
4232 (if_then_else (eq_attr "prefix_0f" "0")
4234 (const_string "1")))])
4236 (define_insn "extendqihi2"
4237 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4238 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4241 switch (get_attr_prefix_0f (insn))
4244 return "{cbtw|cbw}";
4246 return "movs{bw|x}\t{%1, %0|%0, %1}";
4249 [(set_attr "type" "imovx")
4250 (set_attr "mode" "HI")
4251 (set (attr "prefix_0f")
4252 ;; movsx is short decodable while cwtl is vector decoded.
4253 (if_then_else (and (eq_attr "cpu" "!k6")
4254 (eq_attr "alternative" "0"))
4256 (const_string "1")))
4258 (if_then_else (eq_attr "prefix_0f" "0")
4260 (const_string "1")))])
4262 (define_insn "extendqisi2"
4263 [(set (match_operand:SI 0 "register_operand" "=r")
4264 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4266 "movs{bl|x}\t{%1, %0|%0, %1}"
4267 [(set_attr "type" "imovx")
4268 (set_attr "mode" "SI")])
4270 (define_insn "*extendqisi2_zext"
4271 [(set (match_operand:DI 0 "register_operand" "=r")
4273 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4275 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4276 [(set_attr "type" "imovx")
4277 (set_attr "mode" "SI")])
4279 ;; Conversions between float and double.
4281 ;; These are all no-ops in the model used for the 80387. So just
4284 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4285 (define_insn "*dummy_extendsfdf2"
4286 [(set (match_operand:DF 0 "push_operand" "=<")
4287 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4292 [(set (match_operand:DF 0 "push_operand" "")
4293 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4295 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4296 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4298 (define_insn "*dummy_extendsfxf2"
4299 [(set (match_operand:XF 0 "push_operand" "=<")
4300 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4305 [(set (match_operand:XF 0 "push_operand" "")
4306 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4308 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4309 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4310 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4313 [(set (match_operand:XF 0 "push_operand" "")
4314 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4316 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4317 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4318 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4320 (define_expand "extendsfdf2"
4321 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4322 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4323 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4325 /* ??? Needed for compress_float_constant since all fp constants
4326 are LEGITIMATE_CONSTANT_P. */
4327 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4329 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4330 && standard_80387_constant_p (operands[1]) > 0)
4332 operands[1] = simplify_const_unary_operation
4333 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4334 emit_move_insn_1 (operands[0], operands[1]);
4337 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4341 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4343 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4345 We do the conversion post reload to avoid producing of 128bit spills
4346 that might lead to ICE on 32bit target. The sequence unlikely combine
4349 [(set (match_operand:DF 0 "register_operand" "")
4351 (match_operand:SF 1 "nonimmediate_operand" "")))]
4352 "TARGET_USE_VECTOR_FP_CONVERTS
4353 && optimize_insn_for_speed_p ()
4354 && reload_completed && SSE_REG_P (operands[0])"
4359 (parallel [(const_int 0) (const_int 1)]))))]
4361 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4362 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4363 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4364 Try to avoid move when unpacking can be done in source. */
4365 if (REG_P (operands[1]))
4367 /* If it is unsafe to overwrite upper half of source, we need
4368 to move to destination and unpack there. */
4369 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4370 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4371 && true_regnum (operands[0]) != true_regnum (operands[1]))
4373 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4374 emit_move_insn (tmp, operands[1]);
4377 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4378 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4382 emit_insn (gen_vec_setv4sf_0 (operands[3],
4383 CONST0_RTX (V4SFmode), operands[1]));
4386 (define_insn "*extendsfdf2_mixed"
4387 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4389 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4390 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4392 switch (which_alternative)
4396 return output_387_reg_move (insn, operands);
4399 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4405 [(set_attr "type" "fmov,fmov,ssecvt")
4406 (set_attr "prefix" "orig,orig,maybe_vex")
4407 (set_attr "mode" "SF,XF,DF")])
4409 (define_insn "*extendsfdf2_sse"
4410 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4411 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4412 "TARGET_SSE2 && TARGET_SSE_MATH"
4413 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4414 [(set_attr "type" "ssecvt")
4415 (set_attr "prefix" "maybe_vex")
4416 (set_attr "mode" "DF")])
4418 (define_insn "*extendsfdf2_i387"
4419 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4420 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4422 "* return output_387_reg_move (insn, operands);"
4423 [(set_attr "type" "fmov")
4424 (set_attr "mode" "SF,XF")])
4426 (define_expand "extend<mode>xf2"
4427 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4428 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4431 /* ??? Needed for compress_float_constant since all fp constants
4432 are LEGITIMATE_CONSTANT_P. */
4433 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4435 if (standard_80387_constant_p (operands[1]) > 0)
4437 operands[1] = simplify_const_unary_operation
4438 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4439 emit_move_insn_1 (operands[0], operands[1]);
4442 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4446 (define_insn "*extend<mode>xf2_i387"
4447 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4449 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4451 "* return output_387_reg_move (insn, operands);"
4452 [(set_attr "type" "fmov")
4453 (set_attr "mode" "<MODE>,XF")])
4455 ;; %%% This seems bad bad news.
4456 ;; This cannot output into an f-reg because there is no way to be sure
4457 ;; of truncating in that case. Otherwise this is just like a simple move
4458 ;; insn. So we pretend we can output to a reg in order to get better
4459 ;; register preferencing, but we really use a stack slot.
4461 ;; Conversion from DFmode to SFmode.
4463 (define_expand "truncdfsf2"
4464 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4466 (match_operand:DF 1 "nonimmediate_operand" "")))]
4467 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4469 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4471 else if (flag_unsafe_math_optimizations)
4475 enum ix86_stack_slot slot = (virtuals_instantiated
4478 rtx temp = assign_386_stack_local (SFmode, slot);
4479 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4484 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4486 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4488 We do the conversion post reload to avoid producing of 128bit spills
4489 that might lead to ICE on 32bit target. The sequence unlikely combine
4492 [(set (match_operand:SF 0 "register_operand" "")
4494 (match_operand:DF 1 "nonimmediate_operand" "")))]
4495 "TARGET_USE_VECTOR_FP_CONVERTS
4496 && optimize_insn_for_speed_p ()
4497 && reload_completed && SSE_REG_P (operands[0])"
4500 (float_truncate:V2SF
4504 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4505 operands[3] = CONST0_RTX (V2SFmode);
4506 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4507 /* Use movsd for loading from memory, unpcklpd for registers.
4508 Try to avoid move when unpacking can be done in source, or SSE3
4509 movddup is available. */
4510 if (REG_P (operands[1]))
4513 && true_regnum (operands[0]) != true_regnum (operands[1])
4514 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4515 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4517 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4518 emit_move_insn (tmp, operands[1]);
4521 else if (!TARGET_SSE3)
4522 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4523 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4526 emit_insn (gen_sse2_loadlpd (operands[4],
4527 CONST0_RTX (V2DFmode), operands[1]));
4530 (define_expand "truncdfsf2_with_temp"
4531 [(parallel [(set (match_operand:SF 0 "" "")
4532 (float_truncate:SF (match_operand:DF 1 "" "")))
4533 (clobber (match_operand:SF 2 "" ""))])]
4536 (define_insn "*truncdfsf_fast_mixed"
4537 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4539 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4540 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4542 switch (which_alternative)
4545 return output_387_reg_move (insn, operands);
4547 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4552 [(set_attr "type" "fmov,ssecvt")
4553 (set_attr "prefix" "orig,maybe_vex")
4554 (set_attr "mode" "SF")])
4556 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4557 ;; because nothing we do here is unsafe.
4558 (define_insn "*truncdfsf_fast_sse"
4559 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4561 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4562 "TARGET_SSE2 && TARGET_SSE_MATH"
4563 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4564 [(set_attr "type" "ssecvt")
4565 (set_attr "prefix" "maybe_vex")
4566 (set_attr "mode" "SF")])
4568 (define_insn "*truncdfsf_fast_i387"
4569 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4571 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4572 "TARGET_80387 && flag_unsafe_math_optimizations"
4573 "* return output_387_reg_move (insn, operands);"
4574 [(set_attr "type" "fmov")
4575 (set_attr "mode" "SF")])
4577 (define_insn "*truncdfsf_mixed"
4578 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4580 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4581 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4582 "TARGET_MIX_SSE_I387"
4584 switch (which_alternative)
4587 return output_387_reg_move (insn, operands);
4589 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4595 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4596 (set_attr "unit" "*,*,i387,i387,i387")
4597 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4598 (set_attr "mode" "SF")])
4600 (define_insn "*truncdfsf_i387"
4601 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4603 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4604 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4607 switch (which_alternative)
4610 return output_387_reg_move (insn, operands);
4616 [(set_attr "type" "fmov,multi,multi,multi")
4617 (set_attr "unit" "*,i387,i387,i387")
4618 (set_attr "mode" "SF")])
4620 (define_insn "*truncdfsf2_i387_1"
4621 [(set (match_operand:SF 0 "memory_operand" "=m")
4623 (match_operand:DF 1 "register_operand" "f")))]
4625 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4626 && !TARGET_MIX_SSE_I387"
4627 "* return output_387_reg_move (insn, operands);"
4628 [(set_attr "type" "fmov")
4629 (set_attr "mode" "SF")])
4632 [(set (match_operand:SF 0 "register_operand" "")
4634 (match_operand:DF 1 "fp_register_operand" "")))
4635 (clobber (match_operand 2 "" ""))]
4637 [(set (match_dup 2) (match_dup 1))
4638 (set (match_dup 0) (match_dup 2))]
4640 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4643 ;; Conversion from XFmode to {SF,DF}mode
4645 (define_expand "truncxf<mode>2"
4646 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4647 (float_truncate:MODEF
4648 (match_operand:XF 1 "register_operand" "")))
4649 (clobber (match_dup 2))])]
4652 if (flag_unsafe_math_optimizations)
4654 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4655 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4656 if (reg != operands[0])
4657 emit_move_insn (operands[0], reg);
4662 enum ix86_stack_slot slot = (virtuals_instantiated
4665 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4669 (define_insn "*truncxfsf2_mixed"
4670 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4672 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4673 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4676 gcc_assert (!which_alternative);
4677 return output_387_reg_move (insn, operands);
4679 [(set_attr "type" "fmov,multi,multi,multi")
4680 (set_attr "unit" "*,i387,i387,i387")
4681 (set_attr "mode" "SF")])
4683 (define_insn "*truncxfdf2_mixed"
4684 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4686 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4687 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4690 gcc_assert (!which_alternative);
4691 return output_387_reg_move (insn, operands);
4693 [(set_attr "type" "fmov,multi,multi,multi")
4694 (set_attr "unit" "*,i387,i387,i387")
4695 (set_attr "mode" "DF")])
4697 (define_insn "truncxf<mode>2_i387_noop"
4698 [(set (match_operand:MODEF 0 "register_operand" "=f")
4699 (float_truncate:MODEF
4700 (match_operand:XF 1 "register_operand" "f")))]
4701 "TARGET_80387 && flag_unsafe_math_optimizations"
4702 "* return output_387_reg_move (insn, operands);"
4703 [(set_attr "type" "fmov")
4704 (set_attr "mode" "<MODE>")])
4706 (define_insn "*truncxf<mode>2_i387"
4707 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4708 (float_truncate:MODEF
4709 (match_operand:XF 1 "register_operand" "f")))]
4711 "* return output_387_reg_move (insn, operands);"
4712 [(set_attr "type" "fmov")
4713 (set_attr "mode" "<MODE>")])
4716 [(set (match_operand:MODEF 0 "register_operand" "")
4717 (float_truncate:MODEF
4718 (match_operand:XF 1 "register_operand" "")))
4719 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4720 "TARGET_80387 && reload_completed"
4721 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4722 (set (match_dup 0) (match_dup 2))]
4726 [(set (match_operand:MODEF 0 "memory_operand" "")
4727 (float_truncate:MODEF
4728 (match_operand:XF 1 "register_operand" "")))
4729 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4731 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4734 ;; Signed conversion to DImode.
4736 (define_expand "fix_truncxfdi2"
4737 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4738 (fix:DI (match_operand:XF 1 "register_operand" "")))
4739 (clobber (reg:CC FLAGS_REG))])]
4744 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4749 (define_expand "fix_trunc<mode>di2"
4750 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4751 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4752 (clobber (reg:CC FLAGS_REG))])]
4753 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4756 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4758 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4761 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4763 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4764 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4765 if (out != operands[0])
4766 emit_move_insn (operands[0], out);
4771 ;; Signed conversion to SImode.
4773 (define_expand "fix_truncxfsi2"
4774 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4775 (fix:SI (match_operand:XF 1 "register_operand" "")))
4776 (clobber (reg:CC FLAGS_REG))])]
4781 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4786 (define_expand "fix_trunc<mode>si2"
4787 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4788 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4789 (clobber (reg:CC FLAGS_REG))])]
4790 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4793 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4795 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4798 if (SSE_FLOAT_MODE_P (<MODE>mode))
4800 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4801 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4802 if (out != operands[0])
4803 emit_move_insn (operands[0], out);
4808 ;; Signed conversion to HImode.
4810 (define_expand "fix_trunc<mode>hi2"
4811 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4812 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4813 (clobber (reg:CC FLAGS_REG))])]
4815 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4819 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4824 ;; Unsigned conversion to SImode.
4826 (define_expand "fixuns_trunc<mode>si2"
4828 [(set (match_operand:SI 0 "register_operand" "")
4830 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4832 (clobber (match_scratch:<ssevecmode> 3 ""))
4833 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4834 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4836 enum machine_mode mode = <MODE>mode;
4837 enum machine_mode vecmode = <ssevecmode>mode;
4838 REAL_VALUE_TYPE TWO31r;
4841 if (optimize_insn_for_size_p ())
4844 real_ldexp (&TWO31r, &dconst1, 31);
4845 two31 = const_double_from_real_value (TWO31r, mode);
4846 two31 = ix86_build_const_vector (mode, true, two31);
4847 operands[2] = force_reg (vecmode, two31);
4850 (define_insn_and_split "*fixuns_trunc<mode>_1"
4851 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4853 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4854 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4855 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4856 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4857 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4858 && optimize_function_for_speed_p (cfun)"
4860 "&& reload_completed"
4863 ix86_split_convert_uns_si_sse (operands);
4867 ;; Unsigned conversion to HImode.
4868 ;; Without these patterns, we'll try the unsigned SI conversion which
4869 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4871 (define_expand "fixuns_trunc<mode>hi2"
4873 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4874 (set (match_operand:HI 0 "nonimmediate_operand" "")
4875 (subreg:HI (match_dup 2) 0))]
4876 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4877 "operands[2] = gen_reg_rtx (SImode);")
4879 ;; When SSE is available, it is always faster to use it!
4880 (define_insn "fix_trunc<mode>di_sse"
4881 [(set (match_operand:DI 0 "register_operand" "=r,r")
4882 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4883 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4884 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4885 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4886 [(set_attr "type" "sseicvt")
4887 (set_attr "prefix" "maybe_vex")
4888 (set_attr "prefix_rex" "1")
4889 (set_attr "mode" "<MODE>")
4890 (set_attr "athlon_decode" "double,vector")
4891 (set_attr "amdfam10_decode" "double,double")])
4893 (define_insn "fix_trunc<mode>si_sse"
4894 [(set (match_operand:SI 0 "register_operand" "=r,r")
4895 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4896 "SSE_FLOAT_MODE_P (<MODE>mode)
4897 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4898 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4899 [(set_attr "type" "sseicvt")
4900 (set_attr "prefix" "maybe_vex")
4901 (set_attr "mode" "<MODE>")
4902 (set_attr "athlon_decode" "double,vector")
4903 (set_attr "amdfam10_decode" "double,double")])
4905 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4907 [(set (match_operand:MODEF 0 "register_operand" "")
4908 (match_operand:MODEF 1 "memory_operand" ""))
4909 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4910 (fix:SSEMODEI24 (match_dup 0)))]
4911 "TARGET_SHORTEN_X87_SSE
4912 && peep2_reg_dead_p (2, operands[0])"
4913 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4916 ;; Avoid vector decoded forms of the instruction.
4918 [(match_scratch:DF 2 "Y2")
4919 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4920 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4921 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4922 [(set (match_dup 2) (match_dup 1))
4923 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4927 [(match_scratch:SF 2 "x")
4928 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4929 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4930 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4931 [(set (match_dup 2) (match_dup 1))
4932 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4935 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4936 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4937 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4938 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4940 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4941 && (TARGET_64BIT || <MODE>mode != DImode))
4943 && can_create_pseudo_p ()"
4948 if (memory_operand (operands[0], VOIDmode))
4949 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4952 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4953 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4959 [(set_attr "type" "fisttp")
4960 (set_attr "mode" "<MODE>")])
4962 (define_insn "fix_trunc<mode>_i387_fisttp"
4963 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4964 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4965 (clobber (match_scratch:XF 2 "=&1f"))]
4966 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4968 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4969 && (TARGET_64BIT || <MODE>mode != DImode))
4970 && TARGET_SSE_MATH)"
4971 "* return output_fix_trunc (insn, operands, 1);"
4972 [(set_attr "type" "fisttp")
4973 (set_attr "mode" "<MODE>")])
4975 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4976 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4977 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4978 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4979 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4980 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4982 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4983 && (TARGET_64BIT || <MODE>mode != DImode))
4984 && TARGET_SSE_MATH)"
4986 [(set_attr "type" "fisttp")
4987 (set_attr "mode" "<MODE>")])
4990 [(set (match_operand:X87MODEI 0 "register_operand" "")
4991 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4992 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4993 (clobber (match_scratch 3 ""))]
4995 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4996 (clobber (match_dup 3))])
4997 (set (match_dup 0) (match_dup 2))]
5001 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5002 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5003 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5004 (clobber (match_scratch 3 ""))]
5006 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5007 (clobber (match_dup 3))])]
5010 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5011 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5012 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5013 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5014 ;; function in i386.c.
5015 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5016 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5017 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5018 (clobber (reg:CC FLAGS_REG))]
5019 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5021 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5022 && (TARGET_64BIT || <MODE>mode != DImode))
5023 && can_create_pseudo_p ()"
5028 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5030 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5031 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5032 if (memory_operand (operands[0], VOIDmode))
5033 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5034 operands[2], operands[3]));
5037 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5038 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5039 operands[2], operands[3],
5044 [(set_attr "type" "fistp")
5045 (set_attr "i387_cw" "trunc")
5046 (set_attr "mode" "<MODE>")])
5048 (define_insn "fix_truncdi_i387"
5049 [(set (match_operand:DI 0 "memory_operand" "=m")
5050 (fix:DI (match_operand 1 "register_operand" "f")))
5051 (use (match_operand:HI 2 "memory_operand" "m"))
5052 (use (match_operand:HI 3 "memory_operand" "m"))
5053 (clobber (match_scratch:XF 4 "=&1f"))]
5054 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5056 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5057 "* return output_fix_trunc (insn, operands, 0);"
5058 [(set_attr "type" "fistp")
5059 (set_attr "i387_cw" "trunc")
5060 (set_attr "mode" "DI")])
5062 (define_insn "fix_truncdi_i387_with_temp"
5063 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5064 (fix:DI (match_operand 1 "register_operand" "f,f")))
5065 (use (match_operand:HI 2 "memory_operand" "m,m"))
5066 (use (match_operand:HI 3 "memory_operand" "m,m"))
5067 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5068 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5069 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5071 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5073 [(set_attr "type" "fistp")
5074 (set_attr "i387_cw" "trunc")
5075 (set_attr "mode" "DI")])
5078 [(set (match_operand:DI 0 "register_operand" "")
5079 (fix:DI (match_operand 1 "register_operand" "")))
5080 (use (match_operand:HI 2 "memory_operand" ""))
5081 (use (match_operand:HI 3 "memory_operand" ""))
5082 (clobber (match_operand:DI 4 "memory_operand" ""))
5083 (clobber (match_scratch 5 ""))]
5085 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5088 (clobber (match_dup 5))])
5089 (set (match_dup 0) (match_dup 4))]
5093 [(set (match_operand:DI 0 "memory_operand" "")
5094 (fix:DI (match_operand 1 "register_operand" "")))
5095 (use (match_operand:HI 2 "memory_operand" ""))
5096 (use (match_operand:HI 3 "memory_operand" ""))
5097 (clobber (match_operand:DI 4 "memory_operand" ""))
5098 (clobber (match_scratch 5 ""))]
5100 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5103 (clobber (match_dup 5))])]
5106 (define_insn "fix_trunc<mode>_i387"
5107 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5108 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5109 (use (match_operand:HI 2 "memory_operand" "m"))
5110 (use (match_operand:HI 3 "memory_operand" "m"))]
5111 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5113 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5114 "* return output_fix_trunc (insn, operands, 0);"
5115 [(set_attr "type" "fistp")
5116 (set_attr "i387_cw" "trunc")
5117 (set_attr "mode" "<MODE>")])
5119 (define_insn "fix_trunc<mode>_i387_with_temp"
5120 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5121 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5122 (use (match_operand:HI 2 "memory_operand" "m,m"))
5123 (use (match_operand:HI 3 "memory_operand" "m,m"))
5124 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5125 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5127 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5129 [(set_attr "type" "fistp")
5130 (set_attr "i387_cw" "trunc")
5131 (set_attr "mode" "<MODE>")])
5134 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5135 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5136 (use (match_operand:HI 2 "memory_operand" ""))
5137 (use (match_operand:HI 3 "memory_operand" ""))
5138 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5140 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5142 (use (match_dup 3))])
5143 (set (match_dup 0) (match_dup 4))]
5147 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5148 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5149 (use (match_operand:HI 2 "memory_operand" ""))
5150 (use (match_operand:HI 3 "memory_operand" ""))
5151 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5153 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5155 (use (match_dup 3))])]
5158 (define_insn "x86_fnstcw_1"
5159 [(set (match_operand:HI 0 "memory_operand" "=m")
5160 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5163 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5164 (set_attr "mode" "HI")
5165 (set_attr "unit" "i387")])
5167 (define_insn "x86_fldcw_1"
5168 [(set (reg:HI FPCR_REG)
5169 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5172 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5173 (set_attr "mode" "HI")
5174 (set_attr "unit" "i387")
5175 (set_attr "athlon_decode" "vector")
5176 (set_attr "amdfam10_decode" "vector")])
5178 ;; Conversion between fixed point and floating point.
5180 ;; Even though we only accept memory inputs, the backend _really_
5181 ;; wants to be able to do this between registers.
5183 (define_expand "floathi<mode>2"
5184 [(set (match_operand:X87MODEF 0 "register_operand" "")
5185 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5187 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5188 || TARGET_MIX_SSE_I387)"
5191 ;; Pre-reload splitter to add memory clobber to the pattern.
5192 (define_insn_and_split "*floathi<mode>2_1"
5193 [(set (match_operand:X87MODEF 0 "register_operand" "")
5194 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5196 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5197 || TARGET_MIX_SSE_I387)
5198 && can_create_pseudo_p ()"
5201 [(parallel [(set (match_dup 0)
5202 (float:X87MODEF (match_dup 1)))
5203 (clobber (match_dup 2))])]
5204 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5206 (define_insn "*floathi<mode>2_i387_with_temp"
5207 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5208 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5209 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5211 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5212 || TARGET_MIX_SSE_I387)"
5214 [(set_attr "type" "fmov,multi")
5215 (set_attr "mode" "<MODE>")
5216 (set_attr "unit" "*,i387")
5217 (set_attr "fp_int_src" "true")])
5219 (define_insn "*floathi<mode>2_i387"
5220 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5221 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5223 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5224 || TARGET_MIX_SSE_I387)"
5226 [(set_attr "type" "fmov")
5227 (set_attr "mode" "<MODE>")
5228 (set_attr "fp_int_src" "true")])
5231 [(set (match_operand:X87MODEF 0 "register_operand" "")
5232 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5233 (clobber (match_operand:HI 2 "memory_operand" ""))]
5235 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5236 || TARGET_MIX_SSE_I387)
5237 && reload_completed"
5238 [(set (match_dup 2) (match_dup 1))
5239 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5243 [(set (match_operand:X87MODEF 0 "register_operand" "")
5244 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5245 (clobber (match_operand:HI 2 "memory_operand" ""))]
5247 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5248 || TARGET_MIX_SSE_I387)
5249 && reload_completed"
5250 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5253 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5254 [(set (match_operand:X87MODEF 0 "register_operand" "")
5256 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5258 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5259 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5262 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5263 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5264 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5266 rtx reg = gen_reg_rtx (XFmode);
5269 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5271 if (<X87MODEF:MODE>mode == SFmode)
5272 insn = gen_truncxfsf2 (operands[0], reg);
5273 else if (<X87MODEF:MODE>mode == DFmode)
5274 insn = gen_truncxfdf2 (operands[0], reg);
5283 ;; Pre-reload splitter to add memory clobber to the pattern.
5284 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5285 [(set (match_operand:X87MODEF 0 "register_operand" "")
5286 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5288 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5289 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5290 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5291 || TARGET_MIX_SSE_I387))
5292 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5293 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5294 && ((<SSEMODEI24:MODE>mode == SImode
5295 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5296 && optimize_function_for_speed_p (cfun)
5297 && flag_trapping_math)
5298 || !(TARGET_INTER_UNIT_CONVERSIONS
5299 || optimize_function_for_size_p (cfun)))))
5300 && can_create_pseudo_p ()"
5303 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5304 (clobber (match_dup 2))])]
5306 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5308 /* Avoid store forwarding (partial memory) stall penalty
5309 by passing DImode value through XMM registers. */
5310 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5311 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5312 && optimize_function_for_speed_p (cfun))
5314 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5321 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5322 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5324 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5325 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5326 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5327 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5329 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5330 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5331 (set_attr "unit" "*,i387,*,*,*")
5332 (set_attr "athlon_decode" "*,*,double,direct,double")
5333 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5334 (set_attr "fp_int_src" "true")])
5336 (define_insn "*floatsi<mode>2_vector_mixed"
5337 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5338 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5339 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5340 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5344 [(set_attr "type" "fmov,sseicvt")
5345 (set_attr "mode" "<MODE>,<ssevecmode>")
5346 (set_attr "unit" "i387,*")
5347 (set_attr "athlon_decode" "*,direct")
5348 (set_attr "amdfam10_decode" "*,double")
5349 (set_attr "fp_int_src" "true")])
5351 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5352 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5354 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5355 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5356 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5357 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5359 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5360 (set_attr "mode" "<MODEF:MODE>")
5361 (set_attr "unit" "*,i387,*,*")
5362 (set_attr "athlon_decode" "*,*,double,direct")
5363 (set_attr "amdfam10_decode" "*,*,vector,double")
5364 (set_attr "fp_int_src" "true")])
5367 [(set (match_operand:MODEF 0 "register_operand" "")
5368 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5369 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5370 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5371 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5372 && TARGET_INTER_UNIT_CONVERSIONS
5374 && (SSE_REG_P (operands[0])
5375 || (GET_CODE (operands[0]) == SUBREG
5376 && SSE_REG_P (operands[0])))"
5377 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5381 [(set (match_operand:MODEF 0 "register_operand" "")
5382 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5383 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5384 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5385 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5386 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5388 && (SSE_REG_P (operands[0])
5389 || (GET_CODE (operands[0]) == SUBREG
5390 && SSE_REG_P (operands[0])))"
5391 [(set (match_dup 2) (match_dup 1))
5392 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5395 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5396 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5398 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5399 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5400 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5401 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5404 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5405 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5406 [(set_attr "type" "fmov,sseicvt,sseicvt")
5407 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5408 (set_attr "mode" "<MODEF:MODE>")
5409 (set (attr "prefix_rex")
5411 (and (eq_attr "prefix" "maybe_vex")
5412 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5414 (const_string "*")))
5415 (set_attr "unit" "i387,*,*")
5416 (set_attr "athlon_decode" "*,double,direct")
5417 (set_attr "amdfam10_decode" "*,vector,double")
5418 (set_attr "fp_int_src" "true")])
5420 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5421 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5423 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5424 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5425 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5426 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5429 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5430 [(set_attr "type" "fmov,sseicvt")
5431 (set_attr "prefix" "orig,maybe_vex")
5432 (set_attr "mode" "<MODEF:MODE>")
5433 (set (attr "prefix_rex")
5435 (and (eq_attr "prefix" "maybe_vex")
5436 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5438 (const_string "*")))
5439 (set_attr "athlon_decode" "*,direct")
5440 (set_attr "amdfam10_decode" "*,double")
5441 (set_attr "fp_int_src" "true")])
5443 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5444 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5446 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5447 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5448 "TARGET_SSE2 && TARGET_SSE_MATH
5449 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5451 [(set_attr "type" "sseicvt")
5452 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5453 (set_attr "athlon_decode" "double,direct,double")
5454 (set_attr "amdfam10_decode" "vector,double,double")
5455 (set_attr "fp_int_src" "true")])
5457 (define_insn "*floatsi<mode>2_vector_sse"
5458 [(set (match_operand:MODEF 0 "register_operand" "=x")
5459 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5460 "TARGET_SSE2 && TARGET_SSE_MATH
5461 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5463 [(set_attr "type" "sseicvt")
5464 (set_attr "mode" "<MODE>")
5465 (set_attr "athlon_decode" "direct")
5466 (set_attr "amdfam10_decode" "double")
5467 (set_attr "fp_int_src" "true")])
5470 [(set (match_operand:MODEF 0 "register_operand" "")
5471 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5472 (clobber (match_operand:SI 2 "memory_operand" ""))]
5473 "TARGET_SSE2 && TARGET_SSE_MATH
5474 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5476 && (SSE_REG_P (operands[0])
5477 || (GET_CODE (operands[0]) == SUBREG
5478 && SSE_REG_P (operands[0])))"
5481 rtx op1 = operands[1];
5483 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5485 if (GET_CODE (op1) == SUBREG)
5486 op1 = SUBREG_REG (op1);
5488 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5490 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5491 emit_insn (gen_sse2_loadld (operands[4],
5492 CONST0_RTX (V4SImode), operands[1]));
5494 /* We can ignore possible trapping value in the
5495 high part of SSE register for non-trapping math. */
5496 else if (SSE_REG_P (op1) && !flag_trapping_math)
5497 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5500 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5501 emit_move_insn (operands[2], operands[1]);
5502 emit_insn (gen_sse2_loadld (operands[4],
5503 CONST0_RTX (V4SImode), operands[2]));
5506 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5511 [(set (match_operand:MODEF 0 "register_operand" "")
5512 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5513 (clobber (match_operand:SI 2 "memory_operand" ""))]
5514 "TARGET_SSE2 && TARGET_SSE_MATH
5515 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5517 && (SSE_REG_P (operands[0])
5518 || (GET_CODE (operands[0]) == SUBREG
5519 && SSE_REG_P (operands[0])))"
5522 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5524 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5526 emit_insn (gen_sse2_loadld (operands[4],
5527 CONST0_RTX (V4SImode), operands[1]));
5529 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5534 [(set (match_operand:MODEF 0 "register_operand" "")
5535 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5536 "TARGET_SSE2 && TARGET_SSE_MATH
5537 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5539 && (SSE_REG_P (operands[0])
5540 || (GET_CODE (operands[0]) == SUBREG
5541 && SSE_REG_P (operands[0])))"
5544 rtx op1 = operands[1];
5546 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5548 if (GET_CODE (op1) == SUBREG)
5549 op1 = SUBREG_REG (op1);
5551 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5553 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5554 emit_insn (gen_sse2_loadld (operands[4],
5555 CONST0_RTX (V4SImode), operands[1]));
5557 /* We can ignore possible trapping value in the
5558 high part of SSE register for non-trapping math. */
5559 else if (SSE_REG_P (op1) && !flag_trapping_math)
5560 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5564 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5569 [(set (match_operand:MODEF 0 "register_operand" "")
5570 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5571 "TARGET_SSE2 && TARGET_SSE_MATH
5572 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5574 && (SSE_REG_P (operands[0])
5575 || (GET_CODE (operands[0]) == SUBREG
5576 && SSE_REG_P (operands[0])))"
5579 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5581 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5583 emit_insn (gen_sse2_loadld (operands[4],
5584 CONST0_RTX (V4SImode), operands[1]));
5586 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5590 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5591 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5593 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5594 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5595 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5596 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5598 [(set_attr "type" "sseicvt")
5599 (set_attr "mode" "<MODEF:MODE>")
5600 (set_attr "athlon_decode" "double,direct")
5601 (set_attr "amdfam10_decode" "vector,double")
5602 (set_attr "fp_int_src" "true")])
5604 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5605 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5607 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5608 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5609 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5610 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5611 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5612 [(set_attr "type" "sseicvt")
5613 (set_attr "prefix" "maybe_vex")
5614 (set_attr "mode" "<MODEF:MODE>")
5615 (set (attr "prefix_rex")
5617 (and (eq_attr "prefix" "maybe_vex")
5618 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5620 (const_string "*")))
5621 (set_attr "athlon_decode" "double,direct")
5622 (set_attr "amdfam10_decode" "vector,double")
5623 (set_attr "fp_int_src" "true")])
5626 [(set (match_operand:MODEF 0 "register_operand" "")
5627 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5628 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5629 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5630 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5631 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5633 && (SSE_REG_P (operands[0])
5634 || (GET_CODE (operands[0]) == SUBREG
5635 && SSE_REG_P (operands[0])))"
5636 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5639 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5640 [(set (match_operand:MODEF 0 "register_operand" "=x")
5642 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5643 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5644 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5645 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5646 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5647 [(set_attr "type" "sseicvt")
5648 (set_attr "prefix" "maybe_vex")
5649 (set_attr "mode" "<MODEF:MODE>")
5650 (set (attr "prefix_rex")
5652 (and (eq_attr "prefix" "maybe_vex")
5653 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5655 (const_string "*")))
5656 (set_attr "athlon_decode" "direct")
5657 (set_attr "amdfam10_decode" "double")
5658 (set_attr "fp_int_src" "true")])
5661 [(set (match_operand:MODEF 0 "register_operand" "")
5662 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5663 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5664 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5665 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5666 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5668 && (SSE_REG_P (operands[0])
5669 || (GET_CODE (operands[0]) == SUBREG
5670 && SSE_REG_P (operands[0])))"
5671 [(set (match_dup 2) (match_dup 1))
5672 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5676 [(set (match_operand:MODEF 0 "register_operand" "")
5677 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5678 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5679 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5680 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5682 && (SSE_REG_P (operands[0])
5683 || (GET_CODE (operands[0]) == SUBREG
5684 && SSE_REG_P (operands[0])))"
5685 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5688 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5689 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5691 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5692 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5694 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5698 [(set_attr "type" "fmov,multi")
5699 (set_attr "mode" "<X87MODEF:MODE>")
5700 (set_attr "unit" "*,i387")
5701 (set_attr "fp_int_src" "true")])
5703 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5704 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5706 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5708 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5710 [(set_attr "type" "fmov")
5711 (set_attr "mode" "<X87MODEF:MODE>")
5712 (set_attr "fp_int_src" "true")])
5715 [(set (match_operand:X87MODEF 0 "register_operand" "")
5716 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5717 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5719 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5721 && FP_REG_P (operands[0])"
5722 [(set (match_dup 2) (match_dup 1))
5723 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5727 [(set (match_operand:X87MODEF 0 "register_operand" "")
5728 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5729 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5731 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5733 && FP_REG_P (operands[0])"
5734 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5737 ;; Avoid store forwarding (partial memory) stall penalty
5738 ;; by passing DImode value through XMM registers. */
5740 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5741 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5743 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5744 (clobber (match_scratch:V4SI 3 "=X,x"))
5745 (clobber (match_scratch:V4SI 4 "=X,x"))
5746 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5747 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5748 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5749 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5751 [(set_attr "type" "multi")
5752 (set_attr "mode" "<X87MODEF:MODE>")
5753 (set_attr "unit" "i387")
5754 (set_attr "fp_int_src" "true")])
5757 [(set (match_operand:X87MODEF 0 "register_operand" "")
5758 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5759 (clobber (match_scratch:V4SI 3 ""))
5760 (clobber (match_scratch:V4SI 4 ""))
5761 (clobber (match_operand:DI 2 "memory_operand" ""))]
5762 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5763 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5764 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5766 && FP_REG_P (operands[0])"
5767 [(set (match_dup 2) (match_dup 3))
5768 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5770 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5771 Assemble the 64-bit DImode value in an xmm register. */
5772 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5773 gen_rtx_SUBREG (SImode, operands[1], 0)));
5774 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5775 gen_rtx_SUBREG (SImode, operands[1], 4)));
5776 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5779 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5783 [(set (match_operand:X87MODEF 0 "register_operand" "")
5784 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5785 (clobber (match_scratch:V4SI 3 ""))
5786 (clobber (match_scratch:V4SI 4 ""))
5787 (clobber (match_operand:DI 2 "memory_operand" ""))]
5788 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5789 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5790 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5792 && FP_REG_P (operands[0])"
5793 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5796 ;; Avoid store forwarding (partial memory) stall penalty by extending
5797 ;; SImode value to DImode through XMM register instead of pushing two
5798 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5799 ;; targets benefit from this optimization. Also note that fild
5800 ;; loads from memory only.
5802 (define_insn "*floatunssi<mode>2_1"
5803 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5804 (unsigned_float:X87MODEF
5805 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5806 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5807 (clobber (match_scratch:SI 3 "=X,x"))]
5809 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5812 [(set_attr "type" "multi")
5813 (set_attr "mode" "<MODE>")])
5816 [(set (match_operand:X87MODEF 0 "register_operand" "")
5817 (unsigned_float:X87MODEF
5818 (match_operand:SI 1 "register_operand" "")))
5819 (clobber (match_operand:DI 2 "memory_operand" ""))
5820 (clobber (match_scratch:SI 3 ""))]
5822 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5824 && reload_completed"
5825 [(set (match_dup 2) (match_dup 1))
5827 (float:X87MODEF (match_dup 2)))]
5828 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5831 [(set (match_operand:X87MODEF 0 "register_operand" "")
5832 (unsigned_float:X87MODEF
5833 (match_operand:SI 1 "memory_operand" "")))
5834 (clobber (match_operand:DI 2 "memory_operand" ""))
5835 (clobber (match_scratch:SI 3 ""))]
5837 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5839 && reload_completed"
5840 [(set (match_dup 2) (match_dup 3))
5842 (float:X87MODEF (match_dup 2)))]
5844 emit_move_insn (operands[3], operands[1]);
5845 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5848 (define_expand "floatunssi<mode>2"
5850 [(set (match_operand:X87MODEF 0 "register_operand" "")
5851 (unsigned_float:X87MODEF
5852 (match_operand:SI 1 "nonimmediate_operand" "")))
5853 (clobber (match_dup 2))
5854 (clobber (match_scratch:SI 3 ""))])]
5856 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5858 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5860 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5862 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5867 enum ix86_stack_slot slot = (virtuals_instantiated
5870 operands[2] = assign_386_stack_local (DImode, slot);
5874 (define_expand "floatunsdisf2"
5875 [(use (match_operand:SF 0 "register_operand" ""))
5876 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5877 "TARGET_64BIT && TARGET_SSE_MATH"
5878 "x86_emit_floatuns (operands); DONE;")
5880 (define_expand "floatunsdidf2"
5881 [(use (match_operand:DF 0 "register_operand" ""))
5882 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5883 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5884 && TARGET_SSE2 && TARGET_SSE_MATH"
5887 x86_emit_floatuns (operands);
5889 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5895 (define_expand "add<mode>3"
5896 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5897 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5898 (match_operand:SDWIM 2 "<general_operand>" "")))]
5900 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5902 (define_insn_and_split "*add<dwi>3_doubleword"
5903 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5905 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5906 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5907 (clobber (reg:CC FLAGS_REG))]
5908 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5911 [(parallel [(set (reg:CC FLAGS_REG)
5912 (unspec:CC [(match_dup 1) (match_dup 2)]
5915 (plus:DWIH (match_dup 1) (match_dup 2)))])
5916 (parallel [(set (match_dup 3)
5920 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5922 (clobber (reg:CC FLAGS_REG))])]
5923 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5925 (define_insn "*add<mode>3_cc"
5926 [(set (reg:CC FLAGS_REG)
5928 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5929 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5931 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5932 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5933 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5934 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5935 [(set_attr "type" "alu")
5936 (set_attr "mode" "<MODE>")])
5938 (define_insn "addqi3_cc"
5939 [(set (reg:CC FLAGS_REG)
5941 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5942 (match_operand:QI 2 "general_operand" "qn,qm")]
5944 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5945 (plus:QI (match_dup 1) (match_dup 2)))]
5946 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5947 "add{b}\t{%2, %0|%0, %2}"
5948 [(set_attr "type" "alu")
5949 (set_attr "mode" "QI")])
5951 (define_insn "*lea_1"
5952 [(set (match_operand:DWIH 0 "register_operand" "=r")
5953 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5955 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5956 [(set_attr "type" "lea")
5957 (set_attr "mode" "<MODE>")])
5959 (define_insn "*lea_2"
5960 [(set (match_operand:SI 0 "register_operand" "=r")
5961 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5963 "lea{l}\t{%a1, %0|%0, %a1}"
5964 [(set_attr "type" "lea")
5965 (set_attr "mode" "SI")])
5967 (define_insn "*lea_2_zext"
5968 [(set (match_operand:DI 0 "register_operand" "=r")
5970 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5972 "lea{l}\t{%a1, %k0|%k0, %a1}"
5973 [(set_attr "type" "lea")
5974 (set_attr "mode" "SI")])
5976 (define_insn "*add<mode>_1"
5977 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5979 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5980 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5981 (clobber (reg:CC FLAGS_REG))]
5982 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5984 switch (get_attr_type (insn))
5987 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5988 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5991 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5992 if (operands[2] == const1_rtx)
5993 return "inc{<imodesuffix>}\t%0";
5996 gcc_assert (operands[2] == constm1_rtx);
5997 return "dec{<imodesuffix>}\t%0";
6001 /* Use add as much as possible to replace lea for AGU optimization. */
6002 if (which_alternative == 2 && TARGET_OPT_AGU)
6003 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6005 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6007 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6008 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6009 if (CONST_INT_P (operands[2])
6010 /* Avoid overflows. */
6011 && (<MODE>mode != DImode
6012 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6013 && (INTVAL (operands[2]) == 128
6014 || (INTVAL (operands[2]) < 0
6015 && INTVAL (operands[2]) != -128)))
6017 operands[2] = GEN_INT (-INTVAL (operands[2]));
6018 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6020 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6024 (cond [(and (eq_attr "alternative" "2")
6025 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6026 (const_string "lea")
6027 (eq_attr "alternative" "3")
6028 (const_string "lea")
6029 ; Current assemblers are broken and do not allow @GOTOFF in
6030 ; ought but a memory context.
6031 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6032 (const_string "lea")
6033 (match_operand:SWI48 2 "incdec_operand" "")
6034 (const_string "incdec")
6036 (const_string "alu")))
6037 (set (attr "length_immediate")
6039 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6041 (const_string "*")))
6042 (set_attr "mode" "<MODE>")])
6044 ;; It may seem that nonimmediate operand is proper one for operand 1.
6045 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6046 ;; we take care in ix86_binary_operator_ok to not allow two memory
6047 ;; operands so proper swapping will be done in reload. This allow
6048 ;; patterns constructed from addsi_1 to match.
6050 (define_insn "*addsi_1_zext"
6051 [(set (match_operand:DI 0 "register_operand" "=r,r")
6053 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6054 (match_operand:SI 2 "general_operand" "g,li"))))
6055 (clobber (reg:CC FLAGS_REG))]
6056 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6058 switch (get_attr_type (insn))
6061 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6062 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6065 if (operands[2] == const1_rtx)
6066 return "inc{l}\t%k0";
6069 gcc_assert (operands[2] == constm1_rtx);
6070 return "dec{l}\t%k0";
6074 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6075 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6076 if (CONST_INT_P (operands[2])
6077 && (INTVAL (operands[2]) == 128
6078 || (INTVAL (operands[2]) < 0
6079 && INTVAL (operands[2]) != -128)))
6081 operands[2] = GEN_INT (-INTVAL (operands[2]));
6082 return "sub{l}\t{%2, %k0|%k0, %2}";
6084 return "add{l}\t{%2, %k0|%k0, %2}";
6088 (cond [(eq_attr "alternative" "1")
6089 (const_string "lea")
6090 ; Current assemblers are broken and do not allow @GOTOFF in
6091 ; ought but a memory context.
6092 (match_operand:SI 2 "pic_symbolic_operand" "")
6093 (const_string "lea")
6094 (match_operand:SI 2 "incdec_operand" "")
6095 (const_string "incdec")
6097 (const_string "alu")))
6098 (set (attr "length_immediate")
6100 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6102 (const_string "*")))
6103 (set_attr "mode" "SI")])
6105 (define_insn "*addhi_1"
6106 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6107 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6108 (match_operand:HI 2 "general_operand" "rn,rm")))
6109 (clobber (reg:CC FLAGS_REG))]
6110 "TARGET_PARTIAL_REG_STALL
6111 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6113 switch (get_attr_type (insn))
6116 if (operands[2] == const1_rtx)
6117 return "inc{w}\t%0";
6120 gcc_assert (operands[2] == constm1_rtx);
6121 return "dec{w}\t%0";
6125 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6126 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6127 if (CONST_INT_P (operands[2])
6128 && (INTVAL (operands[2]) == 128
6129 || (INTVAL (operands[2]) < 0
6130 && INTVAL (operands[2]) != -128)))
6132 operands[2] = GEN_INT (-INTVAL (operands[2]));
6133 return "sub{w}\t{%2, %0|%0, %2}";
6135 return "add{w}\t{%2, %0|%0, %2}";
6139 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6140 (const_string "incdec")
6141 (const_string "alu")))
6142 (set (attr "length_immediate")
6144 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6146 (const_string "*")))
6147 (set_attr "mode" "HI")])
6149 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6150 ;; type optimizations enabled by define-splits. This is not important
6151 ;; for PII, and in fact harmful because of partial register stalls.
6153 (define_insn "*addhi_1_lea"
6154 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6155 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6156 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6157 (clobber (reg:CC FLAGS_REG))]
6158 "!TARGET_PARTIAL_REG_STALL
6159 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6161 switch (get_attr_type (insn))
6166 if (operands[2] == const1_rtx)
6167 return "inc{w}\t%0";
6170 gcc_assert (operands[2] == constm1_rtx);
6171 return "dec{w}\t%0";
6175 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6176 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6177 if (CONST_INT_P (operands[2])
6178 && (INTVAL (operands[2]) == 128
6179 || (INTVAL (operands[2]) < 0
6180 && INTVAL (operands[2]) != -128)))
6182 operands[2] = GEN_INT (-INTVAL (operands[2]));
6183 return "sub{w}\t{%2, %0|%0, %2}";
6185 return "add{w}\t{%2, %0|%0, %2}";
6189 (if_then_else (eq_attr "alternative" "2")
6190 (const_string "lea")
6191 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6192 (const_string "incdec")
6193 (const_string "alu"))))
6194 (set (attr "length_immediate")
6196 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6198 (const_string "*")))
6199 (set_attr "mode" "HI,HI,SI")])
6201 (define_insn "*addqi_1"
6202 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6203 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6204 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6205 (clobber (reg:CC FLAGS_REG))]
6206 "TARGET_PARTIAL_REG_STALL
6207 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6209 int widen = (which_alternative == 2);
6210 switch (get_attr_type (insn))
6213 if (operands[2] == const1_rtx)
6214 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6217 gcc_assert (operands[2] == constm1_rtx);
6218 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6222 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6223 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6224 if (CONST_INT_P (operands[2])
6225 && (INTVAL (operands[2]) == 128
6226 || (INTVAL (operands[2]) < 0
6227 && INTVAL (operands[2]) != -128)))
6229 operands[2] = GEN_INT (-INTVAL (operands[2]));
6231 return "sub{l}\t{%2, %k0|%k0, %2}";
6233 return "sub{b}\t{%2, %0|%0, %2}";
6236 return "add{l}\t{%k2, %k0|%k0, %k2}";
6238 return "add{b}\t{%2, %0|%0, %2}";
6242 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6243 (const_string "incdec")
6244 (const_string "alu")))
6245 (set (attr "length_immediate")
6247 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6249 (const_string "*")))
6250 (set_attr "mode" "QI,QI,SI")])
6252 ;; %%% Potential partial reg stall on alternative 2. What to do?
6253 (define_insn "*addqi_1_lea"
6254 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6255 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6256 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6257 (clobber (reg:CC FLAGS_REG))]
6258 "!TARGET_PARTIAL_REG_STALL
6259 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6261 int widen = (which_alternative == 2);
6262 switch (get_attr_type (insn))
6267 if (operands[2] == const1_rtx)
6268 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6271 gcc_assert (operands[2] == constm1_rtx);
6272 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6276 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6277 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6278 if (CONST_INT_P (operands[2])
6279 && (INTVAL (operands[2]) == 128
6280 || (INTVAL (operands[2]) < 0
6281 && INTVAL (operands[2]) != -128)))
6283 operands[2] = GEN_INT (-INTVAL (operands[2]));
6285 return "sub{l}\t{%2, %k0|%k0, %2}";
6287 return "sub{b}\t{%2, %0|%0, %2}";
6290 return "add{l}\t{%k2, %k0|%k0, %k2}";
6292 return "add{b}\t{%2, %0|%0, %2}";
6296 (if_then_else (eq_attr "alternative" "3")
6297 (const_string "lea")
6298 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6299 (const_string "incdec")
6300 (const_string "alu"))))
6301 (set (attr "length_immediate")
6303 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6305 (const_string "*")))
6306 (set_attr "mode" "QI,QI,SI,SI")])
6308 (define_insn "*addqi_1_slp"
6309 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6310 (plus:QI (match_dup 0)
6311 (match_operand:QI 1 "general_operand" "qn,qnm")))
6312 (clobber (reg:CC FLAGS_REG))]
6313 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6314 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6316 switch (get_attr_type (insn))
6319 if (operands[1] == const1_rtx)
6320 return "inc{b}\t%0";
6323 gcc_assert (operands[1] == constm1_rtx);
6324 return "dec{b}\t%0";
6328 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6329 if (CONST_INT_P (operands[1])
6330 && INTVAL (operands[1]) < 0)
6332 operands[1] = GEN_INT (-INTVAL (operands[1]));
6333 return "sub{b}\t{%1, %0|%0, %1}";
6335 return "add{b}\t{%1, %0|%0, %1}";
6339 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6340 (const_string "incdec")
6341 (const_string "alu1")))
6342 (set (attr "memory")
6343 (if_then_else (match_operand 1 "memory_operand" "")
6344 (const_string "load")
6345 (const_string "none")))
6346 (set_attr "mode" "QI")])
6348 (define_insn "*add<mode>_2"
6349 [(set (reg FLAGS_REG)
6352 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6353 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6355 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6356 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6357 "ix86_match_ccmode (insn, CCGOCmode)
6358 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6359 /* Current assemblers are broken and do not allow @GOTOFF in
6360 ought but a memory context. */
6361 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6363 switch (get_attr_type (insn))
6366 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6367 if (operands[2] == const1_rtx)
6368 return "inc{<imodesuffix>}\t%0";
6371 gcc_assert (operands[2] == constm1_rtx);
6372 return "dec{<imodesuffix>}\t%0";
6376 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6377 /* ???? In DImode, we ought to handle there the 32bit case too
6378 - do we need new constraint? */
6379 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6380 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6381 if (CONST_INT_P (operands[2])
6382 /* Avoid overflows. */
6383 && (<MODE>mode != DImode
6384 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6385 && (INTVAL (operands[2]) == 128
6386 || (INTVAL (operands[2]) < 0
6387 && INTVAL (operands[2]) != -128)))
6389 operands[2] = GEN_INT (-INTVAL (operands[2]));
6390 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6392 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6396 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6397 (const_string "incdec")
6398 (const_string "alu")))
6399 (set (attr "length_immediate")
6401 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6403 (const_string "*")))
6404 (set_attr "mode" "<MODE>")])
6406 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6407 (define_insn "*addsi_2_zext"
6408 [(set (reg FLAGS_REG)
6410 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6411 (match_operand:SI 2 "general_operand" "g"))
6413 (set (match_operand:DI 0 "register_operand" "=r")
6414 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6415 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6416 && ix86_binary_operator_ok (PLUS, SImode, operands)
6417 /* Current assemblers are broken and do not allow @GOTOFF in
6418 ought but a memory context. */
6419 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6421 switch (get_attr_type (insn))
6424 if (operands[2] == const1_rtx)
6425 return "inc{l}\t%k0";
6428 gcc_assert (operands[2] == constm1_rtx);
6429 return "dec{l}\t%k0";
6433 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6434 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6435 if (CONST_INT_P (operands[2])
6436 && (INTVAL (operands[2]) == 128
6437 || (INTVAL (operands[2]) < 0
6438 && INTVAL (operands[2]) != -128)))
6440 operands[2] = GEN_INT (-INTVAL (operands[2]));
6441 return "sub{l}\t{%2, %k0|%k0, %2}";
6443 return "add{l}\t{%2, %k0|%k0, %2}";
6447 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6448 (const_string "incdec")
6449 (const_string "alu")))
6450 (set (attr "length_immediate")
6452 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6454 (const_string "*")))
6455 (set_attr "mode" "SI")])
6457 (define_insn "*addhi_2"
6458 [(set (reg FLAGS_REG)
6460 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6461 (match_operand:HI 2 "general_operand" "rmn,rn"))
6463 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6464 (plus:HI (match_dup 1) (match_dup 2)))]
6465 "ix86_match_ccmode (insn, CCGOCmode)
6466 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6468 switch (get_attr_type (insn))
6471 if (operands[2] == const1_rtx)
6472 return "inc{w}\t%0";
6475 gcc_assert (operands[2] == constm1_rtx);
6476 return "dec{w}\t%0";
6480 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6481 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6482 if (CONST_INT_P (operands[2])
6483 && (INTVAL (operands[2]) == 128
6484 || (INTVAL (operands[2]) < 0
6485 && INTVAL (operands[2]) != -128)))
6487 operands[2] = GEN_INT (-INTVAL (operands[2]));
6488 return "sub{w}\t{%2, %0|%0, %2}";
6490 return "add{w}\t{%2, %0|%0, %2}";
6494 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6495 (const_string "incdec")
6496 (const_string "alu")))
6497 (set (attr "length_immediate")
6499 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6501 (const_string "*")))
6502 (set_attr "mode" "HI")])
6504 (define_insn "*addqi_2"
6505 [(set (reg FLAGS_REG)
6507 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6508 (match_operand:QI 2 "general_operand" "qmn,qn"))
6510 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6511 (plus:QI (match_dup 1) (match_dup 2)))]
6512 "ix86_match_ccmode (insn, CCGOCmode)
6513 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6515 switch (get_attr_type (insn))
6518 if (operands[2] == const1_rtx)
6519 return "inc{b}\t%0";
6522 gcc_assert (operands[2] == constm1_rtx
6523 || (CONST_INT_P (operands[2])
6524 && INTVAL (operands[2]) == 255));
6525 return "dec{b}\t%0";
6529 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6530 if (CONST_INT_P (operands[2])
6531 && INTVAL (operands[2]) < 0)
6533 operands[2] = GEN_INT (-INTVAL (operands[2]));
6534 return "sub{b}\t{%2, %0|%0, %2}";
6536 return "add{b}\t{%2, %0|%0, %2}";
6540 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6541 (const_string "incdec")
6542 (const_string "alu")))
6543 (set_attr "mode" "QI")])
6545 (define_insn "*add<mode>_3"
6546 [(set (reg FLAGS_REG)
6548 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6549 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6550 (clobber (match_scratch:SWI48 0 "=r"))]
6551 "ix86_match_ccmode (insn, CCZmode)
6552 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6553 /* Current assemblers are broken and do not allow @GOTOFF in
6554 ought but a memory context. */
6555 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6557 switch (get_attr_type (insn))
6560 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6561 if (operands[2] == const1_rtx)
6562 return "inc{<imodesuffix>}\t%0";
6565 gcc_assert (operands[2] == constm1_rtx);
6566 return "dec{<imodesuffix>}\t%0";
6570 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6571 /* ???? In DImode, we ought to handle there the 32bit case too
6572 - do we need new constraint? */
6573 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6574 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6575 if (CONST_INT_P (operands[2])
6576 /* Avoid overflows. */
6577 && (<MODE>mode != DImode
6578 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6579 && (INTVAL (operands[2]) == 128
6580 || (INTVAL (operands[2]) < 0
6581 && INTVAL (operands[2]) != -128)))
6583 operands[2] = GEN_INT (-INTVAL (operands[2]));
6584 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6586 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6590 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6591 (const_string "incdec")
6592 (const_string "alu")))
6593 (set (attr "length_immediate")
6595 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6597 (const_string "*")))
6598 (set_attr "mode" "<MODE>")])
6600 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6601 (define_insn "*addsi_3_zext"
6602 [(set (reg FLAGS_REG)
6604 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6605 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6606 (set (match_operand:DI 0 "register_operand" "=r")
6607 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6608 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6609 && ix86_binary_operator_ok (PLUS, SImode, operands)
6610 /* Current assemblers are broken and do not allow @GOTOFF in
6611 ought but a memory context. */
6612 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6614 switch (get_attr_type (insn))
6617 if (operands[2] == const1_rtx)
6618 return "inc{l}\t%k0";
6621 gcc_assert (operands[2] == constm1_rtx);
6622 return "dec{l}\t%k0";
6626 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6627 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6628 if (CONST_INT_P (operands[2])
6629 && (INTVAL (operands[2]) == 128
6630 || (INTVAL (operands[2]) < 0
6631 && INTVAL (operands[2]) != -128)))
6633 operands[2] = GEN_INT (-INTVAL (operands[2]));
6634 return "sub{l}\t{%2, %k0|%k0, %2}";
6636 return "add{l}\t{%2, %k0|%k0, %2}";
6640 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6641 (const_string "incdec")
6642 (const_string "alu")))
6643 (set (attr "length_immediate")
6645 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6647 (const_string "*")))
6648 (set_attr "mode" "SI")])
6650 (define_insn "*addhi_3"
6651 [(set (reg FLAGS_REG)
6653 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6654 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6655 (clobber (match_scratch:HI 0 "=r"))]
6656 "ix86_match_ccmode (insn, CCZmode)
6657 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6659 switch (get_attr_type (insn))
6662 if (operands[2] == const1_rtx)
6663 return "inc{w}\t%0";
6666 gcc_assert (operands[2] == constm1_rtx);
6667 return "dec{w}\t%0";
6671 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6672 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6673 if (CONST_INT_P (operands[2])
6674 && (INTVAL (operands[2]) == 128
6675 || (INTVAL (operands[2]) < 0
6676 && INTVAL (operands[2]) != -128)))
6678 operands[2] = GEN_INT (-INTVAL (operands[2]));
6679 return "sub{w}\t{%2, %0|%0, %2}";
6681 return "add{w}\t{%2, %0|%0, %2}";
6685 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6686 (const_string "incdec")
6687 (const_string "alu")))
6688 (set (attr "length_immediate")
6690 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6692 (const_string "*")))
6693 (set_attr "mode" "HI")])
6695 (define_insn "*addqi_3"
6696 [(set (reg FLAGS_REG)
6698 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6699 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6700 (clobber (match_scratch:QI 0 "=q"))]
6701 "ix86_match_ccmode (insn, CCZmode)
6702 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6704 switch (get_attr_type (insn))
6707 if (operands[2] == const1_rtx)
6708 return "inc{b}\t%0";
6711 gcc_assert (operands[2] == constm1_rtx
6712 || (CONST_INT_P (operands[2])
6713 && INTVAL (operands[2]) == 255));
6714 return "dec{b}\t%0";
6718 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6719 if (CONST_INT_P (operands[2])
6720 && INTVAL (operands[2]) < 0)
6722 operands[2] = GEN_INT (-INTVAL (operands[2]));
6723 return "sub{b}\t{%2, %0|%0, %2}";
6725 return "add{b}\t{%2, %0|%0, %2}";
6729 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6730 (const_string "incdec")
6731 (const_string "alu")))
6732 (set_attr "mode" "QI")])
6734 ; For comparisons against 1, -1 and 128, we may generate better code
6735 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6736 ; is matched then. We can't accept general immediate, because for
6737 ; case of overflows, the result is messed up.
6738 ; This pattern also don't hold of 0x8000000000000000, since the value
6739 ; overflows when negated.
6740 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6741 ; only for comparisons not depending on it.
6743 (define_insn "*adddi_4"
6744 [(set (reg FLAGS_REG)
6746 (match_operand:DI 1 "nonimmediate_operand" "0")
6747 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6748 (clobber (match_scratch:DI 0 "=rm"))]
6750 && ix86_match_ccmode (insn, CCGCmode)"
6752 switch (get_attr_type (insn))
6755 if (operands[2] == constm1_rtx)
6756 return "inc{q}\t%0";
6759 gcc_assert (operands[2] == const1_rtx);
6760 return "dec{q}\t%0";
6764 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6765 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6766 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6767 if ((INTVAL (operands[2]) == -128
6768 || (INTVAL (operands[2]) > 0
6769 && INTVAL (operands[2]) != 128))
6770 /* Avoid overflows. */
6771 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6772 return "sub{q}\t{%2, %0|%0, %2}";
6773 operands[2] = GEN_INT (-INTVAL (operands[2]));
6774 return "add{q}\t{%2, %0|%0, %2}";
6778 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6779 (const_string "incdec")
6780 (const_string "alu")))
6781 (set (attr "length_immediate")
6783 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6785 (const_string "*")))
6786 (set_attr "mode" "DI")])
6788 ; For comparisons against 1, -1 and 128, we may generate better code
6789 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6790 ; is matched then. We can't accept general immediate, because for
6791 ; case of overflows, the result is messed up.
6792 ; This pattern also don't hold of 0x80000000, since the value overflows
6794 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6795 ; only for comparisons not depending on it.
6797 (define_insn "*addsi_4"
6798 [(set (reg FLAGS_REG)
6800 (match_operand:SI 1 "nonimmediate_operand" "0")
6801 (match_operand:SI 2 "const_int_operand" "n")))
6802 (clobber (match_scratch:SI 0 "=rm"))]
6803 "ix86_match_ccmode (insn, CCGCmode)
6804 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6806 switch (get_attr_type (insn))
6809 if (operands[2] == constm1_rtx)
6810 return "inc{l}\t%0";
6813 gcc_assert (operands[2] == const1_rtx);
6814 return "dec{l}\t%0";
6818 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6819 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6820 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6821 if ((INTVAL (operands[2]) == -128
6822 || (INTVAL (operands[2]) > 0
6823 && INTVAL (operands[2]) != 128)))
6824 return "sub{l}\t{%2, %0|%0, %2}";
6825 operands[2] = GEN_INT (-INTVAL (operands[2]));
6826 return "add{l}\t{%2, %0|%0, %2}";
6830 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6831 (const_string "incdec")
6832 (const_string "alu")))
6833 (set (attr "length_immediate")
6835 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6837 (const_string "*")))
6838 (set_attr "mode" "SI")])
6840 ; See comments above addsi_4 for details.
6842 (define_insn "*addhi_4"
6843 [(set (reg FLAGS_REG)
6845 (match_operand:HI 1 "nonimmediate_operand" "0")
6846 (match_operand:HI 2 "const_int_operand" "n")))
6847 (clobber (match_scratch:HI 0 "=rm"))]
6848 "ix86_match_ccmode (insn, CCGCmode)
6849 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6851 switch (get_attr_type (insn))
6854 if (operands[2] == constm1_rtx)
6855 return "inc{w}\t%0";
6858 gcc_assert (operands[2] == const1_rtx);
6859 return "dec{w}\t%0";
6863 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6864 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6865 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6866 if ((INTVAL (operands[2]) == -128
6867 || (INTVAL (operands[2]) > 0
6868 && INTVAL (operands[2]) != 128)))
6869 return "sub{w}\t{%2, %0|%0, %2}";
6870 operands[2] = GEN_INT (-INTVAL (operands[2]));
6871 return "add{w}\t{%2, %0|%0, %2}";
6875 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6876 (const_string "incdec")
6877 (const_string "alu")))
6878 (set (attr "length_immediate")
6880 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6882 (const_string "*")))
6883 (set_attr "mode" "HI")])
6885 ; See comments above addsi_4 for details.
6887 (define_insn "*addqi_4"
6888 [(set (reg FLAGS_REG)
6890 (match_operand:QI 1 "nonimmediate_operand" "0")
6891 (match_operand:QI 2 "const_int_operand" "n")))
6892 (clobber (match_scratch:QI 0 "=qm"))]
6893 "ix86_match_ccmode (insn, CCGCmode)
6894 && (INTVAL (operands[2]) & 0xff) != 0x80"
6896 switch (get_attr_type (insn))
6899 if (operands[2] == constm1_rtx
6900 || (CONST_INT_P (operands[2])
6901 && INTVAL (operands[2]) == 255))
6902 return "inc{b}\t%0";
6905 gcc_assert (operands[2] == const1_rtx);
6906 return "dec{b}\t%0";
6910 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6911 if (INTVAL (operands[2]) < 0)
6913 operands[2] = GEN_INT (-INTVAL (operands[2]));
6914 return "add{b}\t{%2, %0|%0, %2}";
6916 return "sub{b}\t{%2, %0|%0, %2}";
6920 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6921 (const_string "incdec")
6922 (const_string "alu")))
6923 (set_attr "mode" "QI")])
6925 (define_insn "*add<mode>_5"
6926 [(set (reg FLAGS_REG)
6929 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6930 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6932 (clobber (match_scratch:SWI48 0 "=r"))]
6933 "ix86_match_ccmode (insn, CCGOCmode)
6934 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6935 /* Current assemblers are broken and do not allow @GOTOFF in
6936 ought but a memory context. */
6937 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6939 switch (get_attr_type (insn))
6942 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6943 if (operands[2] == const1_rtx)
6944 return "inc{<imodesuffix>}\t%0";
6947 gcc_assert (operands[2] == constm1_rtx);
6948 return "dec{<imodesuffix>}\t%0";
6952 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6953 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6954 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6955 if (CONST_INT_P (operands[2])
6956 /* Avoid overflows. */
6957 && (<MODE>mode != DImode
6958 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6959 && (INTVAL (operands[2]) == 128
6960 || (INTVAL (operands[2]) < 0
6961 && INTVAL (operands[2]) != -128)))
6963 operands[2] = GEN_INT (-INTVAL (operands[2]));
6964 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6966 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6970 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6971 (const_string "incdec")
6972 (const_string "alu")))
6973 (set (attr "length_immediate")
6975 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6977 (const_string "*")))
6978 (set_attr "mode" "<MODE>")])
6980 (define_insn "*addhi_5"
6981 [(set (reg FLAGS_REG)
6983 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6984 (match_operand:HI 2 "general_operand" "rmn"))
6986 (clobber (match_scratch:HI 0 "=r"))]
6987 "ix86_match_ccmode (insn, CCGOCmode)
6988 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6990 switch (get_attr_type (insn))
6993 if (operands[2] == const1_rtx)
6994 return "inc{w}\t%0";
6997 gcc_assert (operands[2] == constm1_rtx);
6998 return "dec{w}\t%0";
7002 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7003 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7004 if (CONST_INT_P (operands[2])
7005 && (INTVAL (operands[2]) == 128
7006 || (INTVAL (operands[2]) < 0
7007 && INTVAL (operands[2]) != -128)))
7009 operands[2] = GEN_INT (-INTVAL (operands[2]));
7010 return "sub{w}\t{%2, %0|%0, %2}";
7012 return "add{w}\t{%2, %0|%0, %2}";
7016 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7017 (const_string "incdec")
7018 (const_string "alu")))
7019 (set (attr "length_immediate")
7021 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7023 (const_string "*")))
7024 (set_attr "mode" "HI")])
7026 (define_insn "*addqi_5"
7027 [(set (reg FLAGS_REG)
7029 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7030 (match_operand:QI 2 "general_operand" "qmn"))
7032 (clobber (match_scratch:QI 0 "=q"))]
7033 "ix86_match_ccmode (insn, CCGOCmode)
7034 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7036 switch (get_attr_type (insn))
7039 if (operands[2] == const1_rtx)
7040 return "inc{b}\t%0";
7043 gcc_assert (operands[2] == constm1_rtx
7044 || (CONST_INT_P (operands[2])
7045 && INTVAL (operands[2]) == 255));
7046 return "dec{b}\t%0";
7050 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
7051 if (CONST_INT_P (operands[2])
7052 && INTVAL (operands[2]) < 0)
7054 operands[2] = GEN_INT (-INTVAL (operands[2]));
7055 return "sub{b}\t{%2, %0|%0, %2}";
7057 return "add{b}\t{%2, %0|%0, %2}";
7061 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7062 (const_string "incdec")
7063 (const_string "alu")))
7064 (set_attr "mode" "QI")])
7066 (define_insn "*addqi_ext_1_rex64"
7067 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7072 (match_operand 1 "ext_register_operand" "0")
7075 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7076 (clobber (reg:CC FLAGS_REG))]
7079 switch (get_attr_type (insn))
7082 if (operands[2] == const1_rtx)
7083 return "inc{b}\t%h0";
7086 gcc_assert (operands[2] == constm1_rtx
7087 || (CONST_INT_P (operands[2])
7088 && INTVAL (operands[2]) == 255));
7089 return "dec{b}\t%h0";
7093 return "add{b}\t{%2, %h0|%h0, %2}";
7097 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7098 (const_string "incdec")
7099 (const_string "alu")))
7100 (set_attr "modrm" "1")
7101 (set_attr "mode" "QI")])
7103 (define_insn "addqi_ext_1"
7104 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7109 (match_operand 1 "ext_register_operand" "0")
7112 (match_operand:QI 2 "general_operand" "Qmn")))
7113 (clobber (reg:CC FLAGS_REG))]
7116 switch (get_attr_type (insn))
7119 if (operands[2] == const1_rtx)
7120 return "inc{b}\t%h0";
7123 gcc_assert (operands[2] == constm1_rtx
7124 || (CONST_INT_P (operands[2])
7125 && INTVAL (operands[2]) == 255));
7126 return "dec{b}\t%h0";
7130 return "add{b}\t{%2, %h0|%h0, %2}";
7134 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7135 (const_string "incdec")
7136 (const_string "alu")))
7137 (set_attr "modrm" "1")
7138 (set_attr "mode" "QI")])
7140 (define_insn "*addqi_ext_2"
7141 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7146 (match_operand 1 "ext_register_operand" "%0")
7150 (match_operand 2 "ext_register_operand" "Q")
7153 (clobber (reg:CC FLAGS_REG))]
7155 "add{b}\t{%h2, %h0|%h0, %h2}"
7156 [(set_attr "type" "alu")
7157 (set_attr "mode" "QI")])
7159 ;; The lea patterns for non-Pmodes needs to be matched by
7160 ;; several insns converted to real lea by splitters.
7162 (define_insn_and_split "*lea_general_1"
7163 [(set (match_operand 0 "register_operand" "=r")
7164 (plus (plus (match_operand 1 "index_register_operand" "l")
7165 (match_operand 2 "register_operand" "r"))
7166 (match_operand 3 "immediate_operand" "i")))]
7167 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7168 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7169 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7170 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7171 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7172 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7173 || GET_MODE (operands[3]) == VOIDmode)"
7175 "&& reload_completed"
7179 operands[0] = gen_lowpart (SImode, operands[0]);
7180 operands[1] = gen_lowpart (Pmode, operands[1]);
7181 operands[2] = gen_lowpart (Pmode, operands[2]);
7182 operands[3] = gen_lowpart (Pmode, operands[3]);
7183 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7185 if (Pmode != SImode)
7186 pat = gen_rtx_SUBREG (SImode, pat, 0);
7187 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7190 [(set_attr "type" "lea")
7191 (set_attr "mode" "SI")])
7193 (define_insn_and_split "*lea_general_1_zext"
7194 [(set (match_operand:DI 0 "register_operand" "=r")
7197 (match_operand:SI 1 "index_register_operand" "l")
7198 (match_operand:SI 2 "register_operand" "r"))
7199 (match_operand:SI 3 "immediate_operand" "i"))))]
7202 "&& reload_completed"
7204 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7206 (match_dup 3)) 0)))]
7208 operands[1] = gen_lowpart (Pmode, operands[1]);
7209 operands[2] = gen_lowpart (Pmode, operands[2]);
7210 operands[3] = gen_lowpart (Pmode, operands[3]);
7212 [(set_attr "type" "lea")
7213 (set_attr "mode" "SI")])
7215 (define_insn_and_split "*lea_general_2"
7216 [(set (match_operand 0 "register_operand" "=r")
7217 (plus (mult (match_operand 1 "index_register_operand" "l")
7218 (match_operand 2 "const248_operand" "i"))
7219 (match_operand 3 "nonmemory_operand" "ri")))]
7220 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7221 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7222 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7223 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7224 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7225 || GET_MODE (operands[3]) == VOIDmode)"
7227 "&& reload_completed"
7231 operands[0] = gen_lowpart (SImode, operands[0]);
7232 operands[1] = gen_lowpart (Pmode, operands[1]);
7233 operands[3] = gen_lowpart (Pmode, operands[3]);
7234 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7236 if (Pmode != SImode)
7237 pat = gen_rtx_SUBREG (SImode, pat, 0);
7238 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7241 [(set_attr "type" "lea")
7242 (set_attr "mode" "SI")])
7244 (define_insn_and_split "*lea_general_2_zext"
7245 [(set (match_operand:DI 0 "register_operand" "=r")
7248 (match_operand:SI 1 "index_register_operand" "l")
7249 (match_operand:SI 2 "const248_operand" "n"))
7250 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7253 "&& reload_completed"
7255 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7257 (match_dup 3)) 0)))]
7259 operands[1] = gen_lowpart (Pmode, operands[1]);
7260 operands[3] = gen_lowpart (Pmode, operands[3]);
7262 [(set_attr "type" "lea")
7263 (set_attr "mode" "SI")])
7265 (define_insn_and_split "*lea_general_3"
7266 [(set (match_operand 0 "register_operand" "=r")
7267 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7268 (match_operand 2 "const248_operand" "i"))
7269 (match_operand 3 "register_operand" "r"))
7270 (match_operand 4 "immediate_operand" "i")))]
7271 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7272 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7273 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7274 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7275 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7277 "&& reload_completed"
7281 operands[0] = gen_lowpart (SImode, operands[0]);
7282 operands[1] = gen_lowpart (Pmode, operands[1]);
7283 operands[3] = gen_lowpart (Pmode, operands[3]);
7284 operands[4] = gen_lowpart (Pmode, operands[4]);
7285 pat = gen_rtx_PLUS (Pmode,
7286 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7290 if (Pmode != SImode)
7291 pat = gen_rtx_SUBREG (SImode, pat, 0);
7292 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7295 [(set_attr "type" "lea")
7296 (set_attr "mode" "SI")])
7298 (define_insn_and_split "*lea_general_3_zext"
7299 [(set (match_operand:DI 0 "register_operand" "=r")
7303 (match_operand:SI 1 "index_register_operand" "l")
7304 (match_operand:SI 2 "const248_operand" "n"))
7305 (match_operand:SI 3 "register_operand" "r"))
7306 (match_operand:SI 4 "immediate_operand" "i"))))]
7309 "&& reload_completed"
7311 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7314 (match_dup 4)) 0)))]
7316 operands[1] = gen_lowpart (Pmode, operands[1]);
7317 operands[3] = gen_lowpart (Pmode, operands[3]);
7318 operands[4] = gen_lowpart (Pmode, operands[4]);
7320 [(set_attr "type" "lea")
7321 (set_attr "mode" "SI")])
7323 ;; Convert lea to the lea pattern to avoid flags dependency.
7325 [(set (match_operand:DI 0 "register_operand" "")
7326 (plus:DI (match_operand:DI 1 "register_operand" "")
7327 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7328 (clobber (reg:CC FLAGS_REG))]
7329 "TARGET_64BIT && reload_completed
7330 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7332 (plus:DI (match_dup 1)
7336 ;; Convert lea to the lea pattern to avoid flags dependency.
7338 [(set (match_operand 0 "register_operand" "")
7339 (plus (match_operand 1 "register_operand" "")
7340 (match_operand 2 "nonmemory_operand" "")))
7341 (clobber (reg:CC FLAGS_REG))]
7342 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7346 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7347 may confuse gen_lowpart. */
7348 if (GET_MODE (operands[0]) != Pmode)
7350 operands[1] = gen_lowpart (Pmode, operands[1]);
7351 operands[2] = gen_lowpart (Pmode, operands[2]);
7353 operands[0] = gen_lowpart (SImode, operands[0]);
7354 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7355 if (Pmode != SImode)
7356 pat = gen_rtx_SUBREG (SImode, pat, 0);
7357 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7361 ;; Convert lea to the lea pattern to avoid flags dependency.
7363 [(set (match_operand:DI 0 "register_operand" "")
7365 (plus:SI (match_operand:SI 1 "register_operand" "")
7366 (match_operand:SI 2 "nonmemory_operand" ""))))
7367 (clobber (reg:CC FLAGS_REG))]
7368 "TARGET_64BIT && reload_completed
7369 && true_regnum (operands[0]) != true_regnum (operands[1])"
7371 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7373 operands[1] = gen_lowpart (Pmode, operands[1]);
7374 operands[2] = gen_lowpart (Pmode, operands[2]);
7377 ;; Subtract instructions
7379 (define_expand "sub<mode>3"
7380 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7381 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7382 (match_operand:SDWIM 2 "<general_operand>" "")))]
7384 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7386 (define_insn_and_split "*sub<dwi>3_doubleword"
7387 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7389 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7390 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7391 (clobber (reg:CC FLAGS_REG))]
7392 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7395 [(parallel [(set (reg:CC FLAGS_REG)
7396 (compare:CC (match_dup 1) (match_dup 2)))
7398 (minus:DWIH (match_dup 1) (match_dup 2)))])
7399 (parallel [(set (match_dup 3)
7403 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7405 (clobber (reg:CC FLAGS_REG))])]
7406 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7408 (define_insn "*sub<mode>_1"
7409 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7411 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7412 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7413 (clobber (reg:CC FLAGS_REG))]
7414 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7415 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7416 [(set_attr "type" "alu")
7417 (set_attr "mode" "<MODE>")])
7419 (define_insn "*subsi_1_zext"
7420 [(set (match_operand:DI 0 "register_operand" "=r")
7422 (minus:SI (match_operand:SI 1 "register_operand" "0")
7423 (match_operand:SI 2 "general_operand" "g"))))
7424 (clobber (reg:CC FLAGS_REG))]
7425 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7426 "sub{l}\t{%2, %k0|%k0, %2}"
7427 [(set_attr "type" "alu")
7428 (set_attr "mode" "SI")])
7430 (define_insn "*subqi_1_slp"
7431 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7432 (minus:QI (match_dup 0)
7433 (match_operand:QI 1 "general_operand" "qn,qm")))
7434 (clobber (reg:CC FLAGS_REG))]
7435 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7436 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7437 "sub{b}\t{%1, %0|%0, %1}"
7438 [(set_attr "type" "alu1")
7439 (set_attr "mode" "QI")])
7441 (define_insn "*sub<mode>_2"
7442 [(set (reg FLAGS_REG)
7445 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7446 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7448 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7449 (minus:SWI (match_dup 1) (match_dup 2)))]
7450 "ix86_match_ccmode (insn, CCGOCmode)
7451 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7452 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7453 [(set_attr "type" "alu")
7454 (set_attr "mode" "<MODE>")])
7456 (define_insn "*subsi_2_zext"
7457 [(set (reg FLAGS_REG)
7459 (minus:SI (match_operand:SI 1 "register_operand" "0")
7460 (match_operand:SI 2 "general_operand" "g"))
7462 (set (match_operand:DI 0 "register_operand" "=r")
7464 (minus:SI (match_dup 1)
7466 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7467 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7468 "sub{l}\t{%2, %k0|%k0, %2}"
7469 [(set_attr "type" "alu")
7470 (set_attr "mode" "SI")])
7472 (define_insn "*sub<mode>_3"
7473 [(set (reg FLAGS_REG)
7474 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7475 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7476 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7477 (minus:SWI (match_dup 1) (match_dup 2)))]
7478 "ix86_match_ccmode (insn, CCmode)
7479 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7480 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7481 [(set_attr "type" "alu")
7482 (set_attr "mode" "<MODE>")])
7484 (define_insn "*subsi_3_zext"
7485 [(set (reg FLAGS_REG)
7486 (compare (match_operand:SI 1 "register_operand" "0")
7487 (match_operand:SI 2 "general_operand" "g")))
7488 (set (match_operand:DI 0 "register_operand" "=r")
7490 (minus:SI (match_dup 1)
7492 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7493 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7494 "sub{l}\t{%2, %1|%1, %2}"
7495 [(set_attr "type" "alu")
7496 (set_attr "mode" "SI")])
7498 ;; Add with carry and subtract with borrow
7500 (define_expand "<plusminus_insn><mode>3_carry"
7502 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7504 (match_operand:SWI 1 "nonimmediate_operand" "")
7505 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7506 [(match_operand 3 "flags_reg_operand" "")
7508 (match_operand:SWI 2 "<general_operand>" ""))))
7509 (clobber (reg:CC FLAGS_REG))])]
7510 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7513 (define_insn "*<plusminus_insn><mode>3_carry"
7514 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7516 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7518 (match_operator 3 "ix86_carry_flag_operator"
7519 [(reg FLAGS_REG) (const_int 0)])
7520 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7521 (clobber (reg:CC FLAGS_REG))]
7522 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7523 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7524 [(set_attr "type" "alu")
7525 (set_attr "use_carry" "1")
7526 (set_attr "pent_pair" "pu")
7527 (set_attr "mode" "<MODE>")])
7529 (define_insn "*addsi3_carry_zext"
7530 [(set (match_operand:DI 0 "register_operand" "=r")
7532 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7533 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7534 [(reg FLAGS_REG) (const_int 0)])
7535 (match_operand:SI 2 "general_operand" "g")))))
7536 (clobber (reg:CC FLAGS_REG))]
7537 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7538 "adc{l}\t{%2, %k0|%k0, %2}"
7539 [(set_attr "type" "alu")
7540 (set_attr "use_carry" "1")
7541 (set_attr "pent_pair" "pu")
7542 (set_attr "mode" "SI")])
7544 (define_insn "*subsi3_carry_zext"
7545 [(set (match_operand:DI 0 "register_operand" "=r")
7547 (minus:SI (match_operand:SI 1 "register_operand" "0")
7548 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7549 [(reg FLAGS_REG) (const_int 0)])
7550 (match_operand:SI 2 "general_operand" "g")))))
7551 (clobber (reg:CC FLAGS_REG))]
7552 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7553 "sbb{l}\t{%2, %k0|%k0, %2}"
7554 [(set_attr "type" "alu")
7555 (set_attr "pent_pair" "pu")
7556 (set_attr "mode" "SI")])
7558 ;; Overflow setting add and subtract instructions
7560 (define_insn "*add<mode>3_cconly_overflow"
7561 [(set (reg:CCC FLAGS_REG)
7564 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7565 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7567 (clobber (match_scratch:SWI 0 "=<r>"))]
7568 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7569 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7570 [(set_attr "type" "alu")
7571 (set_attr "mode" "<MODE>")])
7573 (define_insn "*sub<mode>3_cconly_overflow"
7574 [(set (reg:CCC FLAGS_REG)
7577 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7578 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7581 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7582 [(set_attr "type" "icmp")
7583 (set_attr "mode" "<MODE>")])
7585 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7586 [(set (reg:CCC FLAGS_REG)
7589 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7590 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7592 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7593 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7594 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7595 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7596 [(set_attr "type" "alu")
7597 (set_attr "mode" "<MODE>")])
7599 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7600 [(set (reg:CCC FLAGS_REG)
7603 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7604 (match_operand:SI 2 "general_operand" "g"))
7606 (set (match_operand:DI 0 "register_operand" "=r")
7607 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7608 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7609 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7610 [(set_attr "type" "alu")
7611 (set_attr "mode" "SI")])
7613 ;; The patterns that match these are at the end of this file.
7615 (define_expand "<plusminus_insn>xf3"
7616 [(set (match_operand:XF 0 "register_operand" "")
7618 (match_operand:XF 1 "register_operand" "")
7619 (match_operand:XF 2 "register_operand" "")))]
7623 (define_expand "<plusminus_insn><mode>3"
7624 [(set (match_operand:MODEF 0 "register_operand" "")
7626 (match_operand:MODEF 1 "register_operand" "")
7627 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7628 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7629 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7632 ;; Multiply instructions
7634 (define_expand "mul<mode>3"
7635 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7637 (match_operand:SWIM248 1 "register_operand" "")
7638 (match_operand:SWIM248 2 "<general_operand>" "")))
7639 (clobber (reg:CC FLAGS_REG))])]
7643 (define_expand "mulqi3"
7644 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7646 (match_operand:QI 1 "register_operand" "")
7647 (match_operand:QI 2 "nonimmediate_operand" "")))
7648 (clobber (reg:CC FLAGS_REG))])]
7649 "TARGET_QIMODE_MATH"
7653 ;; IMUL reg32/64, reg32/64, imm8 Direct
7654 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7655 ;; IMUL reg32/64, reg32/64, imm32 Direct
7656 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7657 ;; IMUL reg32/64, reg32/64 Direct
7658 ;; IMUL reg32/64, mem32/64 Direct
7660 (define_insn "*mul<mode>3_1"
7661 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7663 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7664 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7665 (clobber (reg:CC FLAGS_REG))]
7666 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7668 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7669 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7670 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7671 [(set_attr "type" "imul")
7672 (set_attr "prefix_0f" "0,0,1")
7673 (set (attr "athlon_decode")
7674 (cond [(eq_attr "cpu" "athlon")
7675 (const_string "vector")
7676 (eq_attr "alternative" "1")
7677 (const_string "vector")
7678 (and (eq_attr "alternative" "2")
7679 (match_operand 1 "memory_operand" ""))
7680 (const_string "vector")]
7681 (const_string "direct")))
7682 (set (attr "amdfam10_decode")
7683 (cond [(and (eq_attr "alternative" "0,1")
7684 (match_operand 1 "memory_operand" ""))
7685 (const_string "vector")]
7686 (const_string "direct")))
7687 (set_attr "mode" "<MODE>")])
7689 (define_insn "*mulsi3_1_zext"
7690 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7692 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7693 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7694 (clobber (reg:CC FLAGS_REG))]
7696 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7698 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7699 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7700 imul{l}\t{%2, %k0|%k0, %2}"
7701 [(set_attr "type" "imul")
7702 (set_attr "prefix_0f" "0,0,1")
7703 (set (attr "athlon_decode")
7704 (cond [(eq_attr "cpu" "athlon")
7705 (const_string "vector")
7706 (eq_attr "alternative" "1")
7707 (const_string "vector")
7708 (and (eq_attr "alternative" "2")
7709 (match_operand 1 "memory_operand" ""))
7710 (const_string "vector")]
7711 (const_string "direct")))
7712 (set (attr "amdfam10_decode")
7713 (cond [(and (eq_attr "alternative" "0,1")
7714 (match_operand 1 "memory_operand" ""))
7715 (const_string "vector")]
7716 (const_string "direct")))
7717 (set_attr "mode" "SI")])
7720 ;; IMUL reg16, reg16, imm8 VectorPath
7721 ;; IMUL reg16, mem16, imm8 VectorPath
7722 ;; IMUL reg16, reg16, imm16 VectorPath
7723 ;; IMUL reg16, mem16, imm16 VectorPath
7724 ;; IMUL reg16, reg16 Direct
7725 ;; IMUL reg16, mem16 Direct
7727 (define_insn "*mulhi3_1"
7728 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7729 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7730 (match_operand:HI 2 "general_operand" "K,n,mr")))
7731 (clobber (reg:CC FLAGS_REG))]
7733 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7735 imul{w}\t{%2, %1, %0|%0, %1, %2}
7736 imul{w}\t{%2, %1, %0|%0, %1, %2}
7737 imul{w}\t{%2, %0|%0, %2}"
7738 [(set_attr "type" "imul")
7739 (set_attr "prefix_0f" "0,0,1")
7740 (set (attr "athlon_decode")
7741 (cond [(eq_attr "cpu" "athlon")
7742 (const_string "vector")
7743 (eq_attr "alternative" "1,2")
7744 (const_string "vector")]
7745 (const_string "direct")))
7746 (set (attr "amdfam10_decode")
7747 (cond [(eq_attr "alternative" "0,1")
7748 (const_string "vector")]
7749 (const_string "direct")))
7750 (set_attr "mode" "HI")])
7756 (define_insn "*mulqi3_1"
7757 [(set (match_operand:QI 0 "register_operand" "=a")
7758 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7759 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7760 (clobber (reg:CC FLAGS_REG))]
7762 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7764 [(set_attr "type" "imul")
7765 (set_attr "length_immediate" "0")
7766 (set (attr "athlon_decode")
7767 (if_then_else (eq_attr "cpu" "athlon")
7768 (const_string "vector")
7769 (const_string "direct")))
7770 (set_attr "amdfam10_decode" "direct")
7771 (set_attr "mode" "QI")])
7773 (define_expand "<u>mul<mode><dwi>3"
7774 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7777 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7779 (match_operand:DWIH 2 "register_operand" ""))))
7780 (clobber (reg:CC FLAGS_REG))])]
7784 (define_expand "<u>mulqihi3"
7785 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7788 (match_operand:QI 1 "nonimmediate_operand" ""))
7790 (match_operand:QI 2 "register_operand" ""))))
7791 (clobber (reg:CC FLAGS_REG))])]
7792 "TARGET_QIMODE_MATH"
7795 (define_insn "*<u>mul<mode><dwi>3_1"
7796 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7799 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7801 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7802 (clobber (reg:CC FLAGS_REG))]
7803 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7804 "<sgnprefix>mul{<imodesuffix>}\t%2"
7805 [(set_attr "type" "imul")
7806 (set_attr "length_immediate" "0")
7807 (set (attr "athlon_decode")
7808 (if_then_else (eq_attr "cpu" "athlon")
7809 (const_string "vector")
7810 (const_string "double")))
7811 (set_attr "amdfam10_decode" "double")
7812 (set_attr "mode" "<MODE>")])
7814 (define_insn "*<u>mulqihi3_1"
7815 [(set (match_operand:HI 0 "register_operand" "=a")
7818 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7820 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7821 (clobber (reg:CC FLAGS_REG))]
7823 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7824 "<sgnprefix>mul{b}\t%2"
7825 [(set_attr "type" "imul")
7826 (set_attr "length_immediate" "0")
7827 (set (attr "athlon_decode")
7828 (if_then_else (eq_attr "cpu" "athlon")
7829 (const_string "vector")
7830 (const_string "direct")))
7831 (set_attr "amdfam10_decode" "direct")
7832 (set_attr "mode" "QI")])
7834 (define_expand "<s>mul<mode>3_highpart"
7835 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7840 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7842 (match_operand:SWI48 2 "register_operand" "")))
7844 (clobber (match_scratch:SWI48 3 ""))
7845 (clobber (reg:CC FLAGS_REG))])]
7847 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7849 (define_insn "*<s>muldi3_highpart_1"
7850 [(set (match_operand:DI 0 "register_operand" "=d")
7855 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7857 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7859 (clobber (match_scratch:DI 3 "=1"))
7860 (clobber (reg:CC FLAGS_REG))]
7862 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7863 "<sgnprefix>mul{q}\t%2"
7864 [(set_attr "type" "imul")
7865 (set_attr "length_immediate" "0")
7866 (set (attr "athlon_decode")
7867 (if_then_else (eq_attr "cpu" "athlon")
7868 (const_string "vector")
7869 (const_string "double")))
7870 (set_attr "amdfam10_decode" "double")
7871 (set_attr "mode" "DI")])
7873 (define_insn "*<s>mulsi3_highpart_1"
7874 [(set (match_operand:SI 0 "register_operand" "=d")
7879 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7881 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7883 (clobber (match_scratch:SI 3 "=1"))
7884 (clobber (reg:CC FLAGS_REG))]
7885 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7886 "<sgnprefix>mul{l}\t%2"
7887 [(set_attr "type" "imul")
7888 (set_attr "length_immediate" "0")
7889 (set (attr "athlon_decode")
7890 (if_then_else (eq_attr "cpu" "athlon")
7891 (const_string "vector")
7892 (const_string "double")))
7893 (set_attr "amdfam10_decode" "double")
7894 (set_attr "mode" "SI")])
7896 (define_insn "*<s>mulsi3_highpart_zext"
7897 [(set (match_operand:DI 0 "register_operand" "=d")
7898 (zero_extend:DI (truncate:SI
7900 (mult:DI (any_extend:DI
7901 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7903 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7905 (clobber (match_scratch:SI 3 "=1"))
7906 (clobber (reg:CC FLAGS_REG))]
7908 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7909 "<sgnprefix>mul{l}\t%2"
7910 [(set_attr "type" "imul")
7911 (set_attr "length_immediate" "0")
7912 (set (attr "athlon_decode")
7913 (if_then_else (eq_attr "cpu" "athlon")
7914 (const_string "vector")
7915 (const_string "double")))
7916 (set_attr "amdfam10_decode" "double")
7917 (set_attr "mode" "SI")])
7919 ;; The patterns that match these are at the end of this file.
7921 (define_expand "mulxf3"
7922 [(set (match_operand:XF 0 "register_operand" "")
7923 (mult:XF (match_operand:XF 1 "register_operand" "")
7924 (match_operand:XF 2 "register_operand" "")))]
7928 (define_expand "mul<mode>3"
7929 [(set (match_operand:MODEF 0 "register_operand" "")
7930 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7931 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7932 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7933 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7936 ;; Divide instructions
7938 (define_insn "<u>divqi3"
7939 [(set (match_operand:QI 0 "register_operand" "=a")
7941 (match_operand:HI 1 "register_operand" "0")
7942 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7943 (clobber (reg:CC FLAGS_REG))]
7944 "TARGET_QIMODE_MATH"
7945 "<sgnprefix>div{b}\t%2"
7946 [(set_attr "type" "idiv")
7947 (set_attr "mode" "QI")])
7949 ;; The patterns that match these are at the end of this file.
7951 (define_expand "divxf3"
7952 [(set (match_operand:XF 0 "register_operand" "")
7953 (div:XF (match_operand:XF 1 "register_operand" "")
7954 (match_operand:XF 2 "register_operand" "")))]
7958 (define_expand "divdf3"
7959 [(set (match_operand:DF 0 "register_operand" "")
7960 (div:DF (match_operand:DF 1 "register_operand" "")
7961 (match_operand:DF 2 "nonimmediate_operand" "")))]
7962 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7963 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7966 (define_expand "divsf3"
7967 [(set (match_operand:SF 0 "register_operand" "")
7968 (div:SF (match_operand:SF 1 "register_operand" "")
7969 (match_operand:SF 2 "nonimmediate_operand" "")))]
7970 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7973 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7974 && flag_finite_math_only && !flag_trapping_math
7975 && flag_unsafe_math_optimizations)
7977 ix86_emit_swdivsf (operands[0], operands[1],
7978 operands[2], SFmode);
7983 ;; Divmod instructions.
7985 (define_expand "divmod<mode>4"
7986 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7988 (match_operand:SWIM248 1 "register_operand" "")
7989 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7990 (set (match_operand:SWIM248 3 "register_operand" "")
7991 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7992 (clobber (reg:CC FLAGS_REG))])]
7996 (define_insn_and_split "*divmod<mode>4"
7997 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7998 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7999 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8000 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8001 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8002 (clobber (reg:CC FLAGS_REG))]
8005 "&& reload_completed"
8006 [(parallel [(set (match_dup 1)
8007 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8008 (clobber (reg:CC FLAGS_REG))])
8009 (parallel [(set (match_dup 0)
8010 (div:SWIM248 (match_dup 2) (match_dup 3)))
8012 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8014 (clobber (reg:CC FLAGS_REG))])]
8016 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8018 if (<MODE>mode != HImode
8019 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8020 operands[4] = operands[2];
8023 /* Avoid use of cltd in favor of a mov+shift. */
8024 emit_move_insn (operands[1], operands[2]);
8025 operands[4] = operands[1];
8028 [(set_attr "type" "multi")
8029 (set_attr "mode" "<MODE>")])
8031 (define_insn "*divmod<mode>4_noext"
8032 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8033 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8034 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8035 (set (match_operand:SWIM248 1 "register_operand" "=d")
8036 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8037 (use (match_operand:SWIM248 4 "register_operand" "1"))
8038 (clobber (reg:CC FLAGS_REG))]
8040 "idiv{<imodesuffix>}\t%3"
8041 [(set_attr "type" "idiv")
8042 (set_attr "mode" "<MODE>")])
8044 (define_expand "udivmod<mode>4"
8045 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8047 (match_operand:SWIM248 1 "register_operand" "")
8048 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8049 (set (match_operand:SWIM248 3 "register_operand" "")
8050 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8051 (clobber (reg:CC FLAGS_REG))])]
8055 (define_insn_and_split "*udivmod<mode>4"
8056 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8057 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8058 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8059 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8060 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8061 (clobber (reg:CC FLAGS_REG))]
8064 "&& reload_completed"
8065 [(set (match_dup 1) (const_int 0))
8066 (parallel [(set (match_dup 0)
8067 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8069 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8071 (clobber (reg:CC FLAGS_REG))])]
8073 [(set_attr "type" "multi")
8074 (set_attr "mode" "<MODE>")])
8076 (define_insn "*udivmod<mode>4_noext"
8077 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8078 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8079 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8080 (set (match_operand:SWIM248 1 "register_operand" "=d")
8081 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8082 (use (match_operand:SWIM248 4 "register_operand" "1"))
8083 (clobber (reg:CC FLAGS_REG))]
8085 "div{<imodesuffix>}\t%3"
8086 [(set_attr "type" "idiv")
8087 (set_attr "mode" "<MODE>")])
8089 ;; We cannot use div/idiv for double division, because it causes
8090 ;; "division by zero" on the overflow and that's not what we expect
8091 ;; from truncate. Because true (non truncating) double division is
8092 ;; never generated, we can't create this insn anyway.
8095 ; [(set (match_operand:SI 0 "register_operand" "=a")
8097 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8099 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8100 ; (set (match_operand:SI 3 "register_operand" "=d")
8102 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8103 ; (clobber (reg:CC FLAGS_REG))]
8105 ; "div{l}\t{%2, %0|%0, %2}"
8106 ; [(set_attr "type" "idiv")])
8108 ;;- Logical AND instructions
8110 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8111 ;; Note that this excludes ah.
8113 (define_insn "*testdi_1_rex64"
8114 [(set (reg FLAGS_REG)
8116 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8117 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8119 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8120 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8122 test{l}\t{%k1, %k0|%k0, %k1}
8123 test{l}\t{%k1, %k0|%k0, %k1}
8124 test{q}\t{%1, %0|%0, %1}
8125 test{q}\t{%1, %0|%0, %1}
8126 test{q}\t{%1, %0|%0, %1}"
8127 [(set_attr "type" "test")
8128 (set_attr "modrm" "0,1,0,1,1")
8129 (set_attr "mode" "SI,SI,DI,DI,DI")
8130 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8132 (define_insn "testsi_1"
8133 [(set (reg FLAGS_REG)
8135 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8136 (match_operand:SI 1 "general_operand" "i,i,ri"))
8138 "ix86_match_ccmode (insn, CCNOmode)
8139 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8140 "test{l}\t{%1, %0|%0, %1}"
8141 [(set_attr "type" "test")
8142 (set_attr "modrm" "0,1,1")
8143 (set_attr "mode" "SI")
8144 (set_attr "pent_pair" "uv,np,uv")])
8146 (define_expand "testsi_ccno_1"
8147 [(set (reg:CCNO FLAGS_REG)
8149 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8150 (match_operand:SI 1 "nonmemory_operand" ""))
8155 (define_insn "*testhi_1"
8156 [(set (reg FLAGS_REG)
8157 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8158 (match_operand:HI 1 "general_operand" "n,n,rn"))
8160 "ix86_match_ccmode (insn, CCNOmode)
8161 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8162 "test{w}\t{%1, %0|%0, %1}"
8163 [(set_attr "type" "test")
8164 (set_attr "modrm" "0,1,1")
8165 (set_attr "mode" "HI")
8166 (set_attr "pent_pair" "uv,np,uv")])
8168 (define_expand "testqi_ccz_1"
8169 [(set (reg:CCZ FLAGS_REG)
8170 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8171 (match_operand:QI 1 "nonmemory_operand" ""))
8176 (define_insn "*testqi_1_maybe_si"
8177 [(set (reg FLAGS_REG)
8180 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8181 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8183 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8184 && ix86_match_ccmode (insn,
8185 CONST_INT_P (operands[1])
8186 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8188 if (which_alternative == 3)
8190 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8191 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8192 return "test{l}\t{%1, %k0|%k0, %1}";
8194 return "test{b}\t{%1, %0|%0, %1}";
8196 [(set_attr "type" "test")
8197 (set_attr "modrm" "0,1,1,1")
8198 (set_attr "mode" "QI,QI,QI,SI")
8199 (set_attr "pent_pair" "uv,np,uv,np")])
8201 (define_insn "*testqi_1"
8202 [(set (reg FLAGS_REG)
8205 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8206 (match_operand:QI 1 "general_operand" "n,n,qn"))
8208 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8209 && ix86_match_ccmode (insn, CCNOmode)"
8210 "test{b}\t{%1, %0|%0, %1}"
8211 [(set_attr "type" "test")
8212 (set_attr "modrm" "0,1,1")
8213 (set_attr "mode" "QI")
8214 (set_attr "pent_pair" "uv,np,uv")])
8216 (define_expand "testqi_ext_ccno_0"
8217 [(set (reg:CCNO FLAGS_REG)
8221 (match_operand 0 "ext_register_operand" "")
8224 (match_operand 1 "const_int_operand" ""))
8229 (define_insn "*testqi_ext_0"
8230 [(set (reg FLAGS_REG)
8234 (match_operand 0 "ext_register_operand" "Q")
8237 (match_operand 1 "const_int_operand" "n"))
8239 "ix86_match_ccmode (insn, CCNOmode)"
8240 "test{b}\t{%1, %h0|%h0, %1}"
8241 [(set_attr "type" "test")
8242 (set_attr "mode" "QI")
8243 (set_attr "length_immediate" "1")
8244 (set_attr "modrm" "1")
8245 (set_attr "pent_pair" "np")])
8247 (define_insn "*testqi_ext_1"
8248 [(set (reg FLAGS_REG)
8252 (match_operand 0 "ext_register_operand" "Q")
8256 (match_operand:QI 1 "general_operand" "Qm")))
8258 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8259 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8260 "test{b}\t{%1, %h0|%h0, %1}"
8261 [(set_attr "type" "test")
8262 (set_attr "mode" "QI")])
8264 (define_insn "*testqi_ext_1_rex64"
8265 [(set (reg FLAGS_REG)
8269 (match_operand 0 "ext_register_operand" "Q")
8273 (match_operand:QI 1 "register_operand" "Q")))
8275 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8276 "test{b}\t{%1, %h0|%h0, %1}"
8277 [(set_attr "type" "test")
8278 (set_attr "mode" "QI")])
8280 (define_insn "*testqi_ext_2"
8281 [(set (reg FLAGS_REG)
8285 (match_operand 0 "ext_register_operand" "Q")
8289 (match_operand 1 "ext_register_operand" "Q")
8293 "ix86_match_ccmode (insn, CCNOmode)"
8294 "test{b}\t{%h1, %h0|%h0, %h1}"
8295 [(set_attr "type" "test")
8296 (set_attr "mode" "QI")])
8298 ;; Combine likes to form bit extractions for some tests. Humor it.
8299 (define_insn "*testqi_ext_3"
8300 [(set (reg FLAGS_REG)
8301 (compare (zero_extract:SI
8302 (match_operand 0 "nonimmediate_operand" "rm")
8303 (match_operand:SI 1 "const_int_operand" "")
8304 (match_operand:SI 2 "const_int_operand" ""))
8306 "ix86_match_ccmode (insn, CCNOmode)
8307 && INTVAL (operands[1]) > 0
8308 && INTVAL (operands[2]) >= 0
8309 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8310 && (GET_MODE (operands[0]) == SImode
8311 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8312 || GET_MODE (operands[0]) == HImode
8313 || GET_MODE (operands[0]) == QImode)"
8316 (define_insn "*testqi_ext_3_rex64"
8317 [(set (reg FLAGS_REG)
8318 (compare (zero_extract:DI
8319 (match_operand 0 "nonimmediate_operand" "rm")
8320 (match_operand:DI 1 "const_int_operand" "")
8321 (match_operand:DI 2 "const_int_operand" ""))
8324 && ix86_match_ccmode (insn, CCNOmode)
8325 && INTVAL (operands[1]) > 0
8326 && INTVAL (operands[2]) >= 0
8327 /* Ensure that resulting mask is zero or sign extended operand. */
8328 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8329 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8330 && INTVAL (operands[1]) > 32))
8331 && (GET_MODE (operands[0]) == SImode
8332 || GET_MODE (operands[0]) == DImode
8333 || GET_MODE (operands[0]) == HImode
8334 || GET_MODE (operands[0]) == QImode)"
8338 [(set (match_operand 0 "flags_reg_operand" "")
8339 (match_operator 1 "compare_operator"
8341 (match_operand 2 "nonimmediate_operand" "")
8342 (match_operand 3 "const_int_operand" "")
8343 (match_operand 4 "const_int_operand" ""))
8345 "ix86_match_ccmode (insn, CCNOmode)"
8346 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8348 rtx val = operands[2];
8349 HOST_WIDE_INT len = INTVAL (operands[3]);
8350 HOST_WIDE_INT pos = INTVAL (operands[4]);
8352 enum machine_mode mode, submode;
8354 mode = GET_MODE (val);
8357 /* ??? Combine likes to put non-volatile mem extractions in QImode
8358 no matter the size of the test. So find a mode that works. */
8359 if (! MEM_VOLATILE_P (val))
8361 mode = smallest_mode_for_size (pos + len, MODE_INT);
8362 val = adjust_address (val, mode, 0);
8365 else if (GET_CODE (val) == SUBREG
8366 && (submode = GET_MODE (SUBREG_REG (val)),
8367 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8368 && pos + len <= GET_MODE_BITSIZE (submode)
8369 && GET_MODE_CLASS (submode) == MODE_INT)
8371 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8373 val = SUBREG_REG (val);
8375 else if (mode == HImode && pos + len <= 8)
8377 /* Small HImode tests can be converted to QImode. */
8379 val = gen_lowpart (QImode, val);
8382 if (len == HOST_BITS_PER_WIDE_INT)
8385 mask = ((HOST_WIDE_INT)1 << len) - 1;
8388 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8391 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8392 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8393 ;; this is relatively important trick.
8394 ;; Do the conversion only post-reload to avoid limiting of the register class
8397 [(set (match_operand 0 "flags_reg_operand" "")
8398 (match_operator 1 "compare_operator"
8399 [(and (match_operand 2 "register_operand" "")
8400 (match_operand 3 "const_int_operand" ""))
8403 && QI_REG_P (operands[2])
8404 && GET_MODE (operands[2]) != QImode
8405 && ((ix86_match_ccmode (insn, CCZmode)
8406 && !(INTVAL (operands[3]) & ~(255 << 8)))
8407 || (ix86_match_ccmode (insn, CCNOmode)
8408 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8411 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8414 "operands[2] = gen_lowpart (SImode, operands[2]);
8415 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8418 [(set (match_operand 0 "flags_reg_operand" "")
8419 (match_operator 1 "compare_operator"
8420 [(and (match_operand 2 "nonimmediate_operand" "")
8421 (match_operand 3 "const_int_operand" ""))
8424 && GET_MODE (operands[2]) != QImode
8425 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8426 && ((ix86_match_ccmode (insn, CCZmode)
8427 && !(INTVAL (operands[3]) & ~255))
8428 || (ix86_match_ccmode (insn, CCNOmode)
8429 && !(INTVAL (operands[3]) & ~127)))"
8431 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8433 "operands[2] = gen_lowpart (QImode, operands[2]);
8434 operands[3] = gen_lowpart (QImode, operands[3]);")
8437 ;; %%% This used to optimize known byte-wide and operations to memory,
8438 ;; and sometimes to QImode registers. If this is considered useful,
8439 ;; it should be done with splitters.
8441 (define_expand "anddi3"
8442 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8443 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8444 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8446 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8448 (define_insn "*anddi_1_rex64"
8449 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8450 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8451 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8452 (clobber (reg:CC FLAGS_REG))]
8453 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8455 switch (get_attr_type (insn))
8459 enum machine_mode mode;
8461 gcc_assert (CONST_INT_P (operands[2]));
8462 if (INTVAL (operands[2]) == 0xff)
8466 gcc_assert (INTVAL (operands[2]) == 0xffff);
8470 operands[1] = gen_lowpart (mode, operands[1]);
8472 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8474 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8478 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8479 if (get_attr_mode (insn) == MODE_SI)
8480 return "and{l}\t{%k2, %k0|%k0, %k2}";
8482 return "and{q}\t{%2, %0|%0, %2}";
8485 [(set_attr "type" "alu,alu,alu,imovx")
8486 (set_attr "length_immediate" "*,*,*,0")
8487 (set (attr "prefix_rex")
8489 (and (eq_attr "type" "imovx")
8490 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8491 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8493 (const_string "*")))
8494 (set_attr "mode" "SI,DI,DI,SI")])
8496 (define_insn "*anddi_2"
8497 [(set (reg FLAGS_REG)
8498 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8499 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8501 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8502 (and:DI (match_dup 1) (match_dup 2)))]
8503 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8504 && ix86_binary_operator_ok (AND, DImode, operands)"
8506 and{l}\t{%k2, %k0|%k0, %k2}
8507 and{q}\t{%2, %0|%0, %2}
8508 and{q}\t{%2, %0|%0, %2}"
8509 [(set_attr "type" "alu")
8510 (set_attr "mode" "SI,DI,DI")])
8512 (define_expand "andsi3"
8513 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8514 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8515 (match_operand:SI 2 "general_operand" "")))]
8517 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8519 (define_insn "*andsi_1"
8520 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8521 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8522 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8523 (clobber (reg:CC FLAGS_REG))]
8524 "ix86_binary_operator_ok (AND, SImode, operands)"
8526 switch (get_attr_type (insn))
8530 enum machine_mode mode;
8532 gcc_assert (CONST_INT_P (operands[2]));
8533 if (INTVAL (operands[2]) == 0xff)
8537 gcc_assert (INTVAL (operands[2]) == 0xffff);
8541 operands[1] = gen_lowpart (mode, operands[1]);
8543 return "movz{bl|x}\t{%1, %0|%0, %1}";
8545 return "movz{wl|x}\t{%1, %0|%0, %1}";
8549 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8550 return "and{l}\t{%2, %0|%0, %2}";
8553 [(set_attr "type" "alu,alu,imovx")
8554 (set (attr "prefix_rex")
8556 (and (eq_attr "type" "imovx")
8557 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8558 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8560 (const_string "*")))
8561 (set_attr "length_immediate" "*,*,0")
8562 (set_attr "mode" "SI")])
8565 [(set (match_operand 0 "register_operand" "")
8567 (const_int -65536)))
8568 (clobber (reg:CC FLAGS_REG))]
8569 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8570 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8571 "operands[1] = gen_lowpart (HImode, operands[0]);")
8574 [(set (match_operand 0 "ext_register_operand" "")
8577 (clobber (reg:CC FLAGS_REG))]
8578 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8579 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8580 "operands[1] = gen_lowpart (QImode, operands[0]);")
8583 [(set (match_operand 0 "ext_register_operand" "")
8585 (const_int -65281)))
8586 (clobber (reg:CC FLAGS_REG))]
8587 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8588 [(parallel [(set (zero_extract:SI (match_dup 0)
8592 (zero_extract:SI (match_dup 0)
8595 (zero_extract:SI (match_dup 0)
8598 (clobber (reg:CC FLAGS_REG))])]
8599 "operands[0] = gen_lowpart (SImode, operands[0]);")
8601 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8602 (define_insn "*andsi_1_zext"
8603 [(set (match_operand:DI 0 "register_operand" "=r")
8605 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8606 (match_operand:SI 2 "general_operand" "g"))))
8607 (clobber (reg:CC FLAGS_REG))]
8608 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8609 "and{l}\t{%2, %k0|%k0, %2}"
8610 [(set_attr "type" "alu")
8611 (set_attr "mode" "SI")])
8613 (define_insn "*andsi_2"
8614 [(set (reg FLAGS_REG)
8615 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8616 (match_operand:SI 2 "general_operand" "g,ri"))
8618 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8619 (and:SI (match_dup 1) (match_dup 2)))]
8620 "ix86_match_ccmode (insn, CCNOmode)
8621 && ix86_binary_operator_ok (AND, SImode, operands)"
8622 "and{l}\t{%2, %0|%0, %2}"
8623 [(set_attr "type" "alu")
8624 (set_attr "mode" "SI")])
8626 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8627 (define_insn "*andsi_2_zext"
8628 [(set (reg FLAGS_REG)
8629 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8630 (match_operand:SI 2 "general_operand" "g"))
8632 (set (match_operand:DI 0 "register_operand" "=r")
8633 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8634 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8635 && ix86_binary_operator_ok (AND, SImode, operands)"
8636 "and{l}\t{%2, %k0|%k0, %2}"
8637 [(set_attr "type" "alu")
8638 (set_attr "mode" "SI")])
8640 (define_expand "andhi3"
8641 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8642 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8643 (match_operand:HI 2 "general_operand" "")))]
8644 "TARGET_HIMODE_MATH"
8645 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8647 (define_insn "*andhi_1"
8648 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8649 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8650 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8651 (clobber (reg:CC FLAGS_REG))]
8652 "ix86_binary_operator_ok (AND, HImode, operands)"
8654 switch (get_attr_type (insn))
8657 gcc_assert (CONST_INT_P (operands[2]));
8658 gcc_assert (INTVAL (operands[2]) == 0xff);
8659 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8662 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8664 return "and{w}\t{%2, %0|%0, %2}";
8667 [(set_attr "type" "alu,alu,imovx")
8668 (set_attr "length_immediate" "*,*,0")
8669 (set (attr "prefix_rex")
8671 (and (eq_attr "type" "imovx")
8672 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8674 (const_string "*")))
8675 (set_attr "mode" "HI,HI,SI")])
8677 (define_insn "*andhi_2"
8678 [(set (reg FLAGS_REG)
8679 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8680 (match_operand:HI 2 "general_operand" "rmn,rn"))
8682 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8683 (and:HI (match_dup 1) (match_dup 2)))]
8684 "ix86_match_ccmode (insn, CCNOmode)
8685 && ix86_binary_operator_ok (AND, HImode, operands)"
8686 "and{w}\t{%2, %0|%0, %2}"
8687 [(set_attr "type" "alu")
8688 (set_attr "mode" "HI")])
8690 (define_expand "andqi3"
8691 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8692 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8693 (match_operand:QI 2 "general_operand" "")))]
8694 "TARGET_QIMODE_MATH"
8695 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8697 ;; %%% Potential partial reg stall on alternative 2. What to do?
8698 (define_insn "*andqi_1"
8699 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8700 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8701 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8702 (clobber (reg:CC FLAGS_REG))]
8703 "ix86_binary_operator_ok (AND, QImode, operands)"
8705 and{b}\t{%2, %0|%0, %2}
8706 and{b}\t{%2, %0|%0, %2}
8707 and{l}\t{%k2, %k0|%k0, %k2}"
8708 [(set_attr "type" "alu")
8709 (set_attr "mode" "QI,QI,SI")])
8711 (define_insn "*andqi_1_slp"
8712 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8713 (and:QI (match_dup 0)
8714 (match_operand:QI 1 "general_operand" "qn,qmn")))
8715 (clobber (reg:CC FLAGS_REG))]
8716 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8717 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8718 "and{b}\t{%1, %0|%0, %1}"
8719 [(set_attr "type" "alu1")
8720 (set_attr "mode" "QI")])
8722 (define_insn "*andqi_2_maybe_si"
8723 [(set (reg FLAGS_REG)
8725 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8726 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8728 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8729 (and:QI (match_dup 1) (match_dup 2)))]
8730 "ix86_binary_operator_ok (AND, QImode, operands)
8731 && ix86_match_ccmode (insn,
8732 CONST_INT_P (operands[2])
8733 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8735 if (which_alternative == 2)
8737 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8738 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8739 return "and{l}\t{%2, %k0|%k0, %2}";
8741 return "and{b}\t{%2, %0|%0, %2}";
8743 [(set_attr "type" "alu")
8744 (set_attr "mode" "QI,QI,SI")])
8746 (define_insn "*andqi_2"
8747 [(set (reg FLAGS_REG)
8749 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8750 (match_operand:QI 2 "general_operand" "qmn,qn"))
8752 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8753 (and:QI (match_dup 1) (match_dup 2)))]
8754 "ix86_match_ccmode (insn, CCNOmode)
8755 && ix86_binary_operator_ok (AND, QImode, operands)"
8756 "and{b}\t{%2, %0|%0, %2}"
8757 [(set_attr "type" "alu")
8758 (set_attr "mode" "QI")])
8760 (define_insn "*andqi_2_slp"
8761 [(set (reg FLAGS_REG)
8763 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8764 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8766 (set (strict_low_part (match_dup 0))
8767 (and:QI (match_dup 0) (match_dup 1)))]
8768 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8769 && ix86_match_ccmode (insn, CCNOmode)
8770 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8771 "and{b}\t{%1, %0|%0, %1}"
8772 [(set_attr "type" "alu1")
8773 (set_attr "mode" "QI")])
8775 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8776 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8777 ;; for a QImode operand, which of course failed.
8779 (define_insn "andqi_ext_0"
8780 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8785 (match_operand 1 "ext_register_operand" "0")
8788 (match_operand 2 "const_int_operand" "n")))
8789 (clobber (reg:CC FLAGS_REG))]
8791 "and{b}\t{%2, %h0|%h0, %2}"
8792 [(set_attr "type" "alu")
8793 (set_attr "length_immediate" "1")
8794 (set_attr "modrm" "1")
8795 (set_attr "mode" "QI")])
8797 ;; Generated by peephole translating test to and. This shows up
8798 ;; often in fp comparisons.
8800 (define_insn "*andqi_ext_0_cc"
8801 [(set (reg FLAGS_REG)
8805 (match_operand 1 "ext_register_operand" "0")
8808 (match_operand 2 "const_int_operand" "n"))
8810 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8819 "ix86_match_ccmode (insn, CCNOmode)"
8820 "and{b}\t{%2, %h0|%h0, %2}"
8821 [(set_attr "type" "alu")
8822 (set_attr "length_immediate" "1")
8823 (set_attr "modrm" "1")
8824 (set_attr "mode" "QI")])
8826 (define_insn "*andqi_ext_1"
8827 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8832 (match_operand 1 "ext_register_operand" "0")
8836 (match_operand:QI 2 "general_operand" "Qm"))))
8837 (clobber (reg:CC FLAGS_REG))]
8839 "and{b}\t{%2, %h0|%h0, %2}"
8840 [(set_attr "type" "alu")
8841 (set_attr "length_immediate" "0")
8842 (set_attr "mode" "QI")])
8844 (define_insn "*andqi_ext_1_rex64"
8845 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8850 (match_operand 1 "ext_register_operand" "0")
8854 (match_operand 2 "ext_register_operand" "Q"))))
8855 (clobber (reg:CC FLAGS_REG))]
8857 "and{b}\t{%2, %h0|%h0, %2}"
8858 [(set_attr "type" "alu")
8859 (set_attr "length_immediate" "0")
8860 (set_attr "mode" "QI")])
8862 (define_insn "*andqi_ext_2"
8863 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8868 (match_operand 1 "ext_register_operand" "%0")
8872 (match_operand 2 "ext_register_operand" "Q")
8875 (clobber (reg:CC FLAGS_REG))]
8877 "and{b}\t{%h2, %h0|%h0, %h2}"
8878 [(set_attr "type" "alu")
8879 (set_attr "length_immediate" "0")
8880 (set_attr "mode" "QI")])
8882 ;; Convert wide AND instructions with immediate operand to shorter QImode
8883 ;; equivalents when possible.
8884 ;; Don't do the splitting with memory operands, since it introduces risk
8885 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8886 ;; for size, but that can (should?) be handled by generic code instead.
8888 [(set (match_operand 0 "register_operand" "")
8889 (and (match_operand 1 "register_operand" "")
8890 (match_operand 2 "const_int_operand" "")))
8891 (clobber (reg:CC FLAGS_REG))]
8893 && QI_REG_P (operands[0])
8894 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8895 && !(~INTVAL (operands[2]) & ~(255 << 8))
8896 && GET_MODE (operands[0]) != QImode"
8897 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8898 (and:SI (zero_extract:SI (match_dup 1)
8899 (const_int 8) (const_int 8))
8901 (clobber (reg:CC FLAGS_REG))])]
8902 "operands[0] = gen_lowpart (SImode, operands[0]);
8903 operands[1] = gen_lowpart (SImode, operands[1]);
8904 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8906 ;; Since AND can be encoded with sign extended immediate, this is only
8907 ;; profitable when 7th bit is not set.
8909 [(set (match_operand 0 "register_operand" "")
8910 (and (match_operand 1 "general_operand" "")
8911 (match_operand 2 "const_int_operand" "")))
8912 (clobber (reg:CC FLAGS_REG))]
8914 && ANY_QI_REG_P (operands[0])
8915 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8916 && !(~INTVAL (operands[2]) & ~255)
8917 && !(INTVAL (operands[2]) & 128)
8918 && GET_MODE (operands[0]) != QImode"
8919 [(parallel [(set (strict_low_part (match_dup 0))
8920 (and:QI (match_dup 1)
8922 (clobber (reg:CC FLAGS_REG))])]
8923 "operands[0] = gen_lowpart (QImode, operands[0]);
8924 operands[1] = gen_lowpart (QImode, operands[1]);
8925 operands[2] = gen_lowpart (QImode, operands[2]);")
8927 ;; Logical inclusive OR instructions
8929 ;; %%% This used to optimize known byte-wide and operations to memory.
8930 ;; If this is considered useful, it should be done with splitters.
8932 (define_expand "iordi3"
8933 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8934 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8935 (match_operand:DI 2 "x86_64_general_operand" "")))]
8937 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8939 (define_insn "*iordi_1_rex64"
8940 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8941 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8942 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8943 (clobber (reg:CC FLAGS_REG))]
8945 && ix86_binary_operator_ok (IOR, DImode, operands)"
8946 "or{q}\t{%2, %0|%0, %2}"
8947 [(set_attr "type" "alu")
8948 (set_attr "mode" "DI")])
8950 (define_insn "*iordi_2_rex64"
8951 [(set (reg FLAGS_REG)
8952 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8953 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8955 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8956 (ior:DI (match_dup 1) (match_dup 2)))]
8958 && ix86_match_ccmode (insn, CCNOmode)
8959 && ix86_binary_operator_ok (IOR, DImode, operands)"
8960 "or{q}\t{%2, %0|%0, %2}"
8961 [(set_attr "type" "alu")
8962 (set_attr "mode" "DI")])
8964 (define_insn "*iordi_3_rex64"
8965 [(set (reg FLAGS_REG)
8966 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8967 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8969 (clobber (match_scratch:DI 0 "=r"))]
8971 && ix86_match_ccmode (insn, CCNOmode)
8972 && ix86_binary_operator_ok (IOR, DImode, operands)"
8973 "or{q}\t{%2, %0|%0, %2}"
8974 [(set_attr "type" "alu")
8975 (set_attr "mode" "DI")])
8978 (define_expand "iorsi3"
8979 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8980 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8981 (match_operand:SI 2 "general_operand" "")))]
8983 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8985 (define_insn "*iorsi_1"
8986 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8987 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8988 (match_operand:SI 2 "general_operand" "ri,g")))
8989 (clobber (reg:CC FLAGS_REG))]
8990 "ix86_binary_operator_ok (IOR, SImode, operands)"
8991 "or{l}\t{%2, %0|%0, %2}"
8992 [(set_attr "type" "alu")
8993 (set_attr "mode" "SI")])
8995 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8996 (define_insn "*iorsi_1_zext"
8997 [(set (match_operand:DI 0 "register_operand" "=r")
8999 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9000 (match_operand:SI 2 "general_operand" "g"))))
9001 (clobber (reg:CC FLAGS_REG))]
9002 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
9003 "or{l}\t{%2, %k0|%k0, %2}"
9004 [(set_attr "type" "alu")
9005 (set_attr "mode" "SI")])
9007 (define_insn "*iorsi_1_zext_imm"
9008 [(set (match_operand:DI 0 "register_operand" "=r")
9009 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9010 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9011 (clobber (reg:CC FLAGS_REG))]
9013 "or{l}\t{%2, %k0|%k0, %2}"
9014 [(set_attr "type" "alu")
9015 (set_attr "mode" "SI")])
9017 (define_insn "*iorsi_2"
9018 [(set (reg FLAGS_REG)
9019 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9020 (match_operand:SI 2 "general_operand" "g,ri"))
9022 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9023 (ior:SI (match_dup 1) (match_dup 2)))]
9024 "ix86_match_ccmode (insn, CCNOmode)
9025 && ix86_binary_operator_ok (IOR, SImode, operands)"
9026 "or{l}\t{%2, %0|%0, %2}"
9027 [(set_attr "type" "alu")
9028 (set_attr "mode" "SI")])
9030 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9031 ;; ??? Special case for immediate operand is missing - it is tricky.
9032 (define_insn "*iorsi_2_zext"
9033 [(set (reg FLAGS_REG)
9034 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9035 (match_operand:SI 2 "general_operand" "g"))
9037 (set (match_operand:DI 0 "register_operand" "=r")
9038 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9039 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9040 && ix86_binary_operator_ok (IOR, SImode, operands)"
9041 "or{l}\t{%2, %k0|%k0, %2}"
9042 [(set_attr "type" "alu")
9043 (set_attr "mode" "SI")])
9045 (define_insn "*iorsi_2_zext_imm"
9046 [(set (reg FLAGS_REG)
9047 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9048 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9050 (set (match_operand:DI 0 "register_operand" "=r")
9051 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9052 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9053 && ix86_binary_operator_ok (IOR, SImode, operands)"
9054 "or{l}\t{%2, %k0|%k0, %2}"
9055 [(set_attr "type" "alu")
9056 (set_attr "mode" "SI")])
9058 (define_insn "*iorsi_3"
9059 [(set (reg FLAGS_REG)
9060 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9061 (match_operand:SI 2 "general_operand" "g"))
9063 (clobber (match_scratch:SI 0 "=r"))]
9064 "ix86_match_ccmode (insn, CCNOmode)
9065 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9066 "or{l}\t{%2, %0|%0, %2}"
9067 [(set_attr "type" "alu")
9068 (set_attr "mode" "SI")])
9070 (define_expand "iorhi3"
9071 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9072 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9073 (match_operand:HI 2 "general_operand" "")))]
9074 "TARGET_HIMODE_MATH"
9075 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9077 (define_insn "*iorhi_1"
9078 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9079 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9080 (match_operand:HI 2 "general_operand" "rmn,rn")))
9081 (clobber (reg:CC FLAGS_REG))]
9082 "ix86_binary_operator_ok (IOR, HImode, operands)"
9083 "or{w}\t{%2, %0|%0, %2}"
9084 [(set_attr "type" "alu")
9085 (set_attr "mode" "HI")])
9087 (define_insn "*iorhi_2"
9088 [(set (reg FLAGS_REG)
9089 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9090 (match_operand:HI 2 "general_operand" "rmn,rn"))
9092 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9093 (ior:HI (match_dup 1) (match_dup 2)))]
9094 "ix86_match_ccmode (insn, CCNOmode)
9095 && ix86_binary_operator_ok (IOR, HImode, operands)"
9096 "or{w}\t{%2, %0|%0, %2}"
9097 [(set_attr "type" "alu")
9098 (set_attr "mode" "HI")])
9100 (define_insn "*iorhi_3"
9101 [(set (reg FLAGS_REG)
9102 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9103 (match_operand:HI 2 "general_operand" "rmn"))
9105 (clobber (match_scratch:HI 0 "=r"))]
9106 "ix86_match_ccmode (insn, CCNOmode)
9107 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9108 "or{w}\t{%2, %0|%0, %2}"
9109 [(set_attr "type" "alu")
9110 (set_attr "mode" "HI")])
9112 (define_expand "iorqi3"
9113 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9114 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9115 (match_operand:QI 2 "general_operand" "")))]
9116 "TARGET_QIMODE_MATH"
9117 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9119 ;; %%% Potential partial reg stall on alternative 2. What to do?
9120 (define_insn "*iorqi_1"
9121 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9122 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9123 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9124 (clobber (reg:CC FLAGS_REG))]
9125 "ix86_binary_operator_ok (IOR, QImode, operands)"
9127 or{b}\t{%2, %0|%0, %2}
9128 or{b}\t{%2, %0|%0, %2}
9129 or{l}\t{%k2, %k0|%k0, %k2}"
9130 [(set_attr "type" "alu")
9131 (set_attr "mode" "QI,QI,SI")])
9133 (define_insn "*iorqi_1_slp"
9134 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9135 (ior:QI (match_dup 0)
9136 (match_operand:QI 1 "general_operand" "qmn,qn")))
9137 (clobber (reg:CC FLAGS_REG))]
9138 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9139 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9140 "or{b}\t{%1, %0|%0, %1}"
9141 [(set_attr "type" "alu1")
9142 (set_attr "mode" "QI")])
9144 (define_insn "*iorqi_2"
9145 [(set (reg FLAGS_REG)
9146 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9147 (match_operand:QI 2 "general_operand" "qmn,qn"))
9149 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9150 (ior:QI (match_dup 1) (match_dup 2)))]
9151 "ix86_match_ccmode (insn, CCNOmode)
9152 && ix86_binary_operator_ok (IOR, QImode, operands)"
9153 "or{b}\t{%2, %0|%0, %2}"
9154 [(set_attr "type" "alu")
9155 (set_attr "mode" "QI")])
9157 (define_insn "*iorqi_2_slp"
9158 [(set (reg FLAGS_REG)
9159 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9160 (match_operand:QI 1 "general_operand" "qmn,qn"))
9162 (set (strict_low_part (match_dup 0))
9163 (ior:QI (match_dup 0) (match_dup 1)))]
9164 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9165 && ix86_match_ccmode (insn, CCNOmode)
9166 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9167 "or{b}\t{%1, %0|%0, %1}"
9168 [(set_attr "type" "alu1")
9169 (set_attr "mode" "QI")])
9171 (define_insn "*iorqi_3"
9172 [(set (reg FLAGS_REG)
9173 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9174 (match_operand:QI 2 "general_operand" "qmn"))
9176 (clobber (match_scratch:QI 0 "=q"))]
9177 "ix86_match_ccmode (insn, CCNOmode)
9178 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9179 "or{b}\t{%2, %0|%0, %2}"
9180 [(set_attr "type" "alu")
9181 (set_attr "mode" "QI")])
9183 (define_insn "*iorqi_ext_0"
9184 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9189 (match_operand 1 "ext_register_operand" "0")
9192 (match_operand 2 "const_int_operand" "n")))
9193 (clobber (reg:CC FLAGS_REG))]
9194 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9195 "or{b}\t{%2, %h0|%h0, %2}"
9196 [(set_attr "type" "alu")
9197 (set_attr "length_immediate" "1")
9198 (set_attr "modrm" "1")
9199 (set_attr "mode" "QI")])
9201 (define_insn "*iorqi_ext_1"
9202 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9207 (match_operand 1 "ext_register_operand" "0")
9211 (match_operand:QI 2 "general_operand" "Qm"))))
9212 (clobber (reg:CC FLAGS_REG))]
9214 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9215 "or{b}\t{%2, %h0|%h0, %2}"
9216 [(set_attr "type" "alu")
9217 (set_attr "length_immediate" "0")
9218 (set_attr "mode" "QI")])
9220 (define_insn "*iorqi_ext_1_rex64"
9221 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9226 (match_operand 1 "ext_register_operand" "0")
9230 (match_operand 2 "ext_register_operand" "Q"))))
9231 (clobber (reg:CC FLAGS_REG))]
9233 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9234 "or{b}\t{%2, %h0|%h0, %2}"
9235 [(set_attr "type" "alu")
9236 (set_attr "length_immediate" "0")
9237 (set_attr "mode" "QI")])
9239 (define_insn "*iorqi_ext_2"
9240 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9244 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9247 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9250 (clobber (reg:CC FLAGS_REG))]
9251 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9252 "ior{b}\t{%h2, %h0|%h0, %h2}"
9253 [(set_attr "type" "alu")
9254 (set_attr "length_immediate" "0")
9255 (set_attr "mode" "QI")])
9258 [(set (match_operand 0 "register_operand" "")
9259 (ior (match_operand 1 "register_operand" "")
9260 (match_operand 2 "const_int_operand" "")))
9261 (clobber (reg:CC FLAGS_REG))]
9263 && QI_REG_P (operands[0])
9264 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9265 && !(INTVAL (operands[2]) & ~(255 << 8))
9266 && GET_MODE (operands[0]) != QImode"
9267 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9268 (ior:SI (zero_extract:SI (match_dup 1)
9269 (const_int 8) (const_int 8))
9271 (clobber (reg:CC FLAGS_REG))])]
9272 "operands[0] = gen_lowpart (SImode, operands[0]);
9273 operands[1] = gen_lowpart (SImode, operands[1]);
9274 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9276 ;; Since OR can be encoded with sign extended immediate, this is only
9277 ;; profitable when 7th bit is set.
9279 [(set (match_operand 0 "register_operand" "")
9280 (ior (match_operand 1 "general_operand" "")
9281 (match_operand 2 "const_int_operand" "")))
9282 (clobber (reg:CC FLAGS_REG))]
9284 && ANY_QI_REG_P (operands[0])
9285 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9286 && !(INTVAL (operands[2]) & ~255)
9287 && (INTVAL (operands[2]) & 128)
9288 && GET_MODE (operands[0]) != QImode"
9289 [(parallel [(set (strict_low_part (match_dup 0))
9290 (ior:QI (match_dup 1)
9292 (clobber (reg:CC FLAGS_REG))])]
9293 "operands[0] = gen_lowpart (QImode, operands[0]);
9294 operands[1] = gen_lowpart (QImode, operands[1]);
9295 operands[2] = gen_lowpart (QImode, operands[2]);")
9297 ;; Logical XOR instructions
9299 ;; %%% This used to optimize known byte-wide and operations to memory.
9300 ;; If this is considered useful, it should be done with splitters.
9302 (define_expand "xordi3"
9303 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9304 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9305 (match_operand:DI 2 "x86_64_general_operand" "")))]
9307 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9309 (define_insn "*xordi_1_rex64"
9310 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9311 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9312 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9313 (clobber (reg:CC FLAGS_REG))]
9315 && ix86_binary_operator_ok (XOR, DImode, operands)"
9316 "xor{q}\t{%2, %0|%0, %2}"
9317 [(set_attr "type" "alu")
9318 (set_attr "mode" "DI")])
9320 (define_insn "*xordi_2_rex64"
9321 [(set (reg FLAGS_REG)
9322 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9323 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9325 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9326 (xor:DI (match_dup 1) (match_dup 2)))]
9328 && ix86_match_ccmode (insn, CCNOmode)
9329 && ix86_binary_operator_ok (XOR, DImode, operands)"
9330 "xor{q}\t{%2, %0|%0, %2}"
9331 [(set_attr "type" "alu")
9332 (set_attr "mode" "DI")])
9334 (define_insn "*xordi_3_rex64"
9335 [(set (reg FLAGS_REG)
9336 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9337 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9339 (clobber (match_scratch:DI 0 "=r"))]
9341 && ix86_match_ccmode (insn, CCNOmode)
9342 && ix86_binary_operator_ok (XOR, DImode, operands)"
9343 "xor{q}\t{%2, %0|%0, %2}"
9344 [(set_attr "type" "alu")
9345 (set_attr "mode" "DI")])
9347 (define_expand "xorsi3"
9348 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9349 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9350 (match_operand:SI 2 "general_operand" "")))]
9352 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9354 (define_insn "*xorsi_1"
9355 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9356 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9357 (match_operand:SI 2 "general_operand" "ri,rm")))
9358 (clobber (reg:CC FLAGS_REG))]
9359 "ix86_binary_operator_ok (XOR, SImode, operands)"
9360 "xor{l}\t{%2, %0|%0, %2}"
9361 [(set_attr "type" "alu")
9362 (set_attr "mode" "SI")])
9364 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9365 ;; Add speccase for immediates
9366 (define_insn "*xorsi_1_zext"
9367 [(set (match_operand:DI 0 "register_operand" "=r")
9369 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9370 (match_operand:SI 2 "general_operand" "g"))))
9371 (clobber (reg:CC FLAGS_REG))]
9372 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9373 "xor{l}\t{%2, %k0|%k0, %2}"
9374 [(set_attr "type" "alu")
9375 (set_attr "mode" "SI")])
9377 (define_insn "*xorsi_1_zext_imm"
9378 [(set (match_operand:DI 0 "register_operand" "=r")
9379 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9380 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9381 (clobber (reg:CC FLAGS_REG))]
9382 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9383 "xor{l}\t{%2, %k0|%k0, %2}"
9384 [(set_attr "type" "alu")
9385 (set_attr "mode" "SI")])
9387 (define_insn "*xorsi_2"
9388 [(set (reg FLAGS_REG)
9389 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9390 (match_operand:SI 2 "general_operand" "g,ri"))
9392 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9393 (xor:SI (match_dup 1) (match_dup 2)))]
9394 "ix86_match_ccmode (insn, CCNOmode)
9395 && ix86_binary_operator_ok (XOR, SImode, operands)"
9396 "xor{l}\t{%2, %0|%0, %2}"
9397 [(set_attr "type" "alu")
9398 (set_attr "mode" "SI")])
9400 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9401 ;; ??? Special case for immediate operand is missing - it is tricky.
9402 (define_insn "*xorsi_2_zext"
9403 [(set (reg FLAGS_REG)
9404 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9405 (match_operand:SI 2 "general_operand" "g"))
9407 (set (match_operand:DI 0 "register_operand" "=r")
9408 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9409 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9410 && ix86_binary_operator_ok (XOR, SImode, operands)"
9411 "xor{l}\t{%2, %k0|%k0, %2}"
9412 [(set_attr "type" "alu")
9413 (set_attr "mode" "SI")])
9415 (define_insn "*xorsi_2_zext_imm"
9416 [(set (reg FLAGS_REG)
9417 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9418 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9420 (set (match_operand:DI 0 "register_operand" "=r")
9421 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9422 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9423 && ix86_binary_operator_ok (XOR, SImode, operands)"
9424 "xor{l}\t{%2, %k0|%k0, %2}"
9425 [(set_attr "type" "alu")
9426 (set_attr "mode" "SI")])
9428 (define_insn "*xorsi_3"
9429 [(set (reg FLAGS_REG)
9430 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9431 (match_operand:SI 2 "general_operand" "g"))
9433 (clobber (match_scratch:SI 0 "=r"))]
9434 "ix86_match_ccmode (insn, CCNOmode)
9435 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9436 "xor{l}\t{%2, %0|%0, %2}"
9437 [(set_attr "type" "alu")
9438 (set_attr "mode" "SI")])
9440 (define_expand "xorhi3"
9441 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9442 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9443 (match_operand:HI 2 "general_operand" "")))]
9444 "TARGET_HIMODE_MATH"
9445 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9447 (define_insn "*xorhi_1"
9448 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9449 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9450 (match_operand:HI 2 "general_operand" "rmn,rn")))
9451 (clobber (reg:CC FLAGS_REG))]
9452 "ix86_binary_operator_ok (XOR, HImode, operands)"
9453 "xor{w}\t{%2, %0|%0, %2}"
9454 [(set_attr "type" "alu")
9455 (set_attr "mode" "HI")])
9457 (define_insn "*xorhi_2"
9458 [(set (reg FLAGS_REG)
9459 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9460 (match_operand:HI 2 "general_operand" "rmn,rn"))
9462 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9463 (xor:HI (match_dup 1) (match_dup 2)))]
9464 "ix86_match_ccmode (insn, CCNOmode)
9465 && ix86_binary_operator_ok (XOR, HImode, operands)"
9466 "xor{w}\t{%2, %0|%0, %2}"
9467 [(set_attr "type" "alu")
9468 (set_attr "mode" "HI")])
9470 (define_insn "*xorhi_3"
9471 [(set (reg FLAGS_REG)
9472 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9473 (match_operand:HI 2 "general_operand" "rmn"))
9475 (clobber (match_scratch:HI 0 "=r"))]
9476 "ix86_match_ccmode (insn, CCNOmode)
9477 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9478 "xor{w}\t{%2, %0|%0, %2}"
9479 [(set_attr "type" "alu")
9480 (set_attr "mode" "HI")])
9482 (define_expand "xorqi3"
9483 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9484 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9485 (match_operand:QI 2 "general_operand" "")))]
9486 "TARGET_QIMODE_MATH"
9487 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9489 ;; %%% Potential partial reg stall on alternative 2. What to do?
9490 (define_insn "*xorqi_1"
9491 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9492 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9493 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9494 (clobber (reg:CC FLAGS_REG))]
9495 "ix86_binary_operator_ok (XOR, QImode, operands)"
9497 xor{b}\t{%2, %0|%0, %2}
9498 xor{b}\t{%2, %0|%0, %2}
9499 xor{l}\t{%k2, %k0|%k0, %k2}"
9500 [(set_attr "type" "alu")
9501 (set_attr "mode" "QI,QI,SI")])
9503 (define_insn "*xorqi_1_slp"
9504 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9505 (xor:QI (match_dup 0)
9506 (match_operand:QI 1 "general_operand" "qn,qmn")))
9507 (clobber (reg:CC FLAGS_REG))]
9508 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9509 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9510 "xor{b}\t{%1, %0|%0, %1}"
9511 [(set_attr "type" "alu1")
9512 (set_attr "mode" "QI")])
9514 (define_insn "*xorqi_ext_0"
9515 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9520 (match_operand 1 "ext_register_operand" "0")
9523 (match_operand 2 "const_int_operand" "n")))
9524 (clobber (reg:CC FLAGS_REG))]
9525 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9526 "xor{b}\t{%2, %h0|%h0, %2}"
9527 [(set_attr "type" "alu")
9528 (set_attr "length_immediate" "1")
9529 (set_attr "modrm" "1")
9530 (set_attr "mode" "QI")])
9532 (define_insn "*xorqi_ext_1"
9533 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9538 (match_operand 1 "ext_register_operand" "0")
9542 (match_operand:QI 2 "general_operand" "Qm"))))
9543 (clobber (reg:CC FLAGS_REG))]
9545 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9546 "xor{b}\t{%2, %h0|%h0, %2}"
9547 [(set_attr "type" "alu")
9548 (set_attr "length_immediate" "0")
9549 (set_attr "mode" "QI")])
9551 (define_insn "*xorqi_ext_1_rex64"
9552 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9557 (match_operand 1 "ext_register_operand" "0")
9561 (match_operand 2 "ext_register_operand" "Q"))))
9562 (clobber (reg:CC FLAGS_REG))]
9564 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9565 "xor{b}\t{%2, %h0|%h0, %2}"
9566 [(set_attr "type" "alu")
9567 (set_attr "length_immediate" "0")
9568 (set_attr "mode" "QI")])
9570 (define_insn "*xorqi_ext_2"
9571 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9575 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9578 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9581 (clobber (reg:CC FLAGS_REG))]
9582 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9583 "xor{b}\t{%h2, %h0|%h0, %h2}"
9584 [(set_attr "type" "alu")
9585 (set_attr "length_immediate" "0")
9586 (set_attr "mode" "QI")])
9588 (define_insn "*xorqi_cc_1"
9589 [(set (reg FLAGS_REG)
9591 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9592 (match_operand:QI 2 "general_operand" "qmn,qn"))
9594 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9595 (xor:QI (match_dup 1) (match_dup 2)))]
9596 "ix86_match_ccmode (insn, CCNOmode)
9597 && ix86_binary_operator_ok (XOR, QImode, operands)"
9598 "xor{b}\t{%2, %0|%0, %2}"
9599 [(set_attr "type" "alu")
9600 (set_attr "mode" "QI")])
9602 (define_insn "*xorqi_2_slp"
9603 [(set (reg FLAGS_REG)
9604 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9605 (match_operand:QI 1 "general_operand" "qmn,qn"))
9607 (set (strict_low_part (match_dup 0))
9608 (xor:QI (match_dup 0) (match_dup 1)))]
9609 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9610 && ix86_match_ccmode (insn, CCNOmode)
9611 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9612 "xor{b}\t{%1, %0|%0, %1}"
9613 [(set_attr "type" "alu1")
9614 (set_attr "mode" "QI")])
9616 (define_insn "*xorqi_cc_2"
9617 [(set (reg FLAGS_REG)
9619 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9620 (match_operand:QI 2 "general_operand" "qmn"))
9622 (clobber (match_scratch:QI 0 "=q"))]
9623 "ix86_match_ccmode (insn, CCNOmode)
9624 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9625 "xor{b}\t{%2, %0|%0, %2}"
9626 [(set_attr "type" "alu")
9627 (set_attr "mode" "QI")])
9629 (define_insn "*xorqi_cc_ext_1"
9630 [(set (reg FLAGS_REG)
9634 (match_operand 1 "ext_register_operand" "0")
9637 (match_operand:QI 2 "general_operand" "qmn"))
9639 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9643 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9645 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9646 "xor{b}\t{%2, %h0|%h0, %2}"
9647 [(set_attr "type" "alu")
9648 (set_attr "modrm" "1")
9649 (set_attr "mode" "QI")])
9651 (define_insn "*xorqi_cc_ext_1_rex64"
9652 [(set (reg FLAGS_REG)
9656 (match_operand 1 "ext_register_operand" "0")
9659 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9661 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9665 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9667 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9668 "xor{b}\t{%2, %h0|%h0, %2}"
9669 [(set_attr "type" "alu")
9670 (set_attr "modrm" "1")
9671 (set_attr "mode" "QI")])
9673 (define_expand "xorqi_cc_ext_1"
9675 (set (reg:CCNO FLAGS_REG)
9679 (match_operand 1 "ext_register_operand" "")
9682 (match_operand:QI 2 "general_operand" ""))
9684 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9688 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9694 [(set (match_operand 0 "register_operand" "")
9695 (xor (match_operand 1 "register_operand" "")
9696 (match_operand 2 "const_int_operand" "")))
9697 (clobber (reg:CC FLAGS_REG))]
9699 && QI_REG_P (operands[0])
9700 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9701 && !(INTVAL (operands[2]) & ~(255 << 8))
9702 && GET_MODE (operands[0]) != QImode"
9703 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9704 (xor:SI (zero_extract:SI (match_dup 1)
9705 (const_int 8) (const_int 8))
9707 (clobber (reg:CC FLAGS_REG))])]
9708 "operands[0] = gen_lowpart (SImode, operands[0]);
9709 operands[1] = gen_lowpart (SImode, operands[1]);
9710 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9712 ;; Since XOR can be encoded with sign extended immediate, this is only
9713 ;; profitable when 7th bit is set.
9715 [(set (match_operand 0 "register_operand" "")
9716 (xor (match_operand 1 "general_operand" "")
9717 (match_operand 2 "const_int_operand" "")))
9718 (clobber (reg:CC FLAGS_REG))]
9720 && ANY_QI_REG_P (operands[0])
9721 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9722 && !(INTVAL (operands[2]) & ~255)
9723 && (INTVAL (operands[2]) & 128)
9724 && GET_MODE (operands[0]) != QImode"
9725 [(parallel [(set (strict_low_part (match_dup 0))
9726 (xor:QI (match_dup 1)
9728 (clobber (reg:CC FLAGS_REG))])]
9729 "operands[0] = gen_lowpart (QImode, operands[0]);
9730 operands[1] = gen_lowpart (QImode, operands[1]);
9731 operands[2] = gen_lowpart (QImode, operands[2]);")
9733 ;; Negation instructions
9735 (define_expand "neg<mode>2"
9736 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9737 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9739 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9741 (define_insn_and_split "*neg<dwi>2_doubleword"
9742 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9743 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9744 (clobber (reg:CC FLAGS_REG))]
9745 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9749 [(set (reg:CCZ FLAGS_REG)
9750 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9751 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9754 (plus:DWIH (match_dup 3)
9755 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9757 (clobber (reg:CC FLAGS_REG))])
9760 (neg:DWIH (match_dup 2)))
9761 (clobber (reg:CC FLAGS_REG))])]
9762 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9764 (define_insn "*neg<mode>2_1"
9765 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9766 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9767 (clobber (reg:CC FLAGS_REG))]
9768 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9769 "neg{<imodesuffix>}\t%0"
9770 [(set_attr "type" "negnot")
9771 (set_attr "mode" "<MODE>")])
9773 ;; Combine is quite creative about this pattern.
9774 (define_insn "*negsi2_1_zext"
9775 [(set (match_operand:DI 0 "register_operand" "=r")
9777 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9780 (clobber (reg:CC FLAGS_REG))]
9781 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9783 [(set_attr "type" "negnot")
9784 (set_attr "mode" "SI")])
9786 ;; The problem with neg is that it does not perform (compare x 0),
9787 ;; it really performs (compare 0 x), which leaves us with the zero
9788 ;; flag being the only useful item.
9790 (define_insn "*neg<mode>2_cmpz"
9791 [(set (reg:CCZ FLAGS_REG)
9793 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9795 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9796 (neg:SWI (match_dup 1)))]
9797 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9798 "neg{<imodesuffix>}\t%0"
9799 [(set_attr "type" "negnot")
9800 (set_attr "mode" "<MODE>")])
9802 (define_insn "*negsi2_cmpz_zext"
9803 [(set (reg:CCZ FLAGS_REG)
9807 (match_operand:DI 1 "register_operand" "0")
9811 (set (match_operand:DI 0 "register_operand" "=r")
9812 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9815 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9817 [(set_attr "type" "negnot")
9818 (set_attr "mode" "SI")])
9820 ;; Changing of sign for FP values is doable using integer unit too.
9822 (define_expand "<code><mode>2"
9823 [(set (match_operand:X87MODEF 0 "register_operand" "")
9824 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9825 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9826 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9828 (define_insn "*absneg<mode>2_mixed"
9829 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9830 (match_operator:MODEF 3 "absneg_operator"
9831 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9832 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9833 (clobber (reg:CC FLAGS_REG))]
9834 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9837 (define_insn "*absneg<mode>2_sse"
9838 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9839 (match_operator:MODEF 3 "absneg_operator"
9840 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9841 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9842 (clobber (reg:CC FLAGS_REG))]
9843 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9846 (define_insn "*absneg<mode>2_i387"
9847 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9848 (match_operator:X87MODEF 3 "absneg_operator"
9849 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9850 (use (match_operand 2 "" ""))
9851 (clobber (reg:CC FLAGS_REG))]
9852 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9855 (define_expand "<code>tf2"
9856 [(set (match_operand:TF 0 "register_operand" "")
9857 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9859 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9861 (define_insn "*absnegtf2_sse"
9862 [(set (match_operand:TF 0 "register_operand" "=x,x")
9863 (match_operator:TF 3 "absneg_operator"
9864 [(match_operand:TF 1 "register_operand" "0,x")]))
9865 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9866 (clobber (reg:CC FLAGS_REG))]
9870 ;; Splitters for fp abs and neg.
9873 [(set (match_operand 0 "fp_register_operand" "")
9874 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9875 (use (match_operand 2 "" ""))
9876 (clobber (reg:CC FLAGS_REG))]
9878 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9881 [(set (match_operand 0 "register_operand" "")
9882 (match_operator 3 "absneg_operator"
9883 [(match_operand 1 "register_operand" "")]))
9884 (use (match_operand 2 "nonimmediate_operand" ""))
9885 (clobber (reg:CC FLAGS_REG))]
9886 "reload_completed && SSE_REG_P (operands[0])"
9887 [(set (match_dup 0) (match_dup 3))]
9889 enum machine_mode mode = GET_MODE (operands[0]);
9890 enum machine_mode vmode = GET_MODE (operands[2]);
9893 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9894 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9895 if (operands_match_p (operands[0], operands[2]))
9898 operands[1] = operands[2];
9901 if (GET_CODE (operands[3]) == ABS)
9902 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9904 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9909 [(set (match_operand:SF 0 "register_operand" "")
9910 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9911 (use (match_operand:V4SF 2 "" ""))
9912 (clobber (reg:CC FLAGS_REG))]
9914 [(parallel [(set (match_dup 0) (match_dup 1))
9915 (clobber (reg:CC FLAGS_REG))])]
9918 operands[0] = gen_lowpart (SImode, operands[0]);
9919 if (GET_CODE (operands[1]) == ABS)
9921 tmp = gen_int_mode (0x7fffffff, SImode);
9922 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9926 tmp = gen_int_mode (0x80000000, SImode);
9927 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9933 [(set (match_operand:DF 0 "register_operand" "")
9934 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9935 (use (match_operand 2 "" ""))
9936 (clobber (reg:CC FLAGS_REG))]
9938 [(parallel [(set (match_dup 0) (match_dup 1))
9939 (clobber (reg:CC FLAGS_REG))])]
9944 tmp = gen_lowpart (DImode, operands[0]);
9945 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9948 if (GET_CODE (operands[1]) == ABS)
9951 tmp = gen_rtx_NOT (DImode, tmp);
9955 operands[0] = gen_highpart (SImode, operands[0]);
9956 if (GET_CODE (operands[1]) == ABS)
9958 tmp = gen_int_mode (0x7fffffff, SImode);
9959 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9963 tmp = gen_int_mode (0x80000000, SImode);
9964 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9971 [(set (match_operand:XF 0 "register_operand" "")
9972 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9973 (use (match_operand 2 "" ""))
9974 (clobber (reg:CC FLAGS_REG))]
9976 [(parallel [(set (match_dup 0) (match_dup 1))
9977 (clobber (reg:CC FLAGS_REG))])]
9980 operands[0] = gen_rtx_REG (SImode,
9981 true_regnum (operands[0])
9982 + (TARGET_64BIT ? 1 : 2));
9983 if (GET_CODE (operands[1]) == ABS)
9985 tmp = GEN_INT (0x7fff);
9986 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9990 tmp = GEN_INT (0x8000);
9991 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9996 ;; Conditionalize these after reload. If they match before reload, we
9997 ;; lose the clobber and ability to use integer instructions.
9999 (define_insn "*<code><mode>2_1"
10000 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10001 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10003 && (reload_completed
10004 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10006 [(set_attr "type" "fsgn")
10007 (set_attr "mode" "<MODE>")])
10009 (define_insn "*<code>extendsfdf2"
10010 [(set (match_operand:DF 0 "register_operand" "=f")
10011 (absneg:DF (float_extend:DF
10012 (match_operand:SF 1 "register_operand" "0"))))]
10013 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10015 [(set_attr "type" "fsgn")
10016 (set_attr "mode" "DF")])
10018 (define_insn "*<code>extendsfxf2"
10019 [(set (match_operand:XF 0 "register_operand" "=f")
10020 (absneg:XF (float_extend:XF
10021 (match_operand:SF 1 "register_operand" "0"))))]
10024 [(set_attr "type" "fsgn")
10025 (set_attr "mode" "XF")])
10027 (define_insn "*<code>extenddfxf2"
10028 [(set (match_operand:XF 0 "register_operand" "=f")
10029 (absneg:XF (float_extend:XF
10030 (match_operand:DF 1 "register_operand" "0"))))]
10033 [(set_attr "type" "fsgn")
10034 (set_attr "mode" "XF")])
10036 ;; Copysign instructions
10038 (define_mode_iterator CSGNMODE [SF DF TF])
10039 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10041 (define_expand "copysign<mode>3"
10042 [(match_operand:CSGNMODE 0 "register_operand" "")
10043 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10044 (match_operand:CSGNMODE 2 "register_operand" "")]
10045 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10046 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10048 ix86_expand_copysign (operands);
10052 (define_insn_and_split "copysign<mode>3_const"
10053 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10055 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10056 (match_operand:CSGNMODE 2 "register_operand" "0")
10057 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10059 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10060 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10062 "&& reload_completed"
10065 ix86_split_copysign_const (operands);
10069 (define_insn "copysign<mode>3_var"
10070 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10072 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10073 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10074 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10075 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10077 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10078 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10079 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10083 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10085 [(match_operand:CSGNMODE 2 "register_operand" "")
10086 (match_operand:CSGNMODE 3 "register_operand" "")
10087 (match_operand:<CSGNVMODE> 4 "" "")
10088 (match_operand:<CSGNVMODE> 5 "" "")]
10090 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10091 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10092 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10093 && reload_completed"
10096 ix86_split_copysign_var (operands);
10100 ;; One complement instructions
10102 (define_expand "one_cmpl<mode>2"
10103 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
10104 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
10106 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10108 (define_insn "*one_cmpl<mode>2_1"
10109 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10110 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10111 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10112 "not{<imodesuffix>}\t%0"
10113 [(set_attr "type" "negnot")
10114 (set_attr "mode" "<MODE>")])
10116 ;; %%% Potential partial reg stall on alternative 1. What to do?
10117 (define_insn "*one_cmplqi2_1"
10118 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10119 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10120 "ix86_unary_operator_ok (NOT, QImode, operands)"
10124 [(set_attr "type" "negnot")
10125 (set_attr "mode" "QI,SI")])
10127 ;; ??? Currently never generated - xor is used instead.
10128 (define_insn "*one_cmplsi2_1_zext"
10129 [(set (match_operand:DI 0 "register_operand" "=r")
10131 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10132 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10134 [(set_attr "type" "negnot")
10135 (set_attr "mode" "SI")])
10137 (define_insn "*one_cmpl<mode>2_2"
10138 [(set (reg FLAGS_REG)
10139 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10141 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10142 (not:SWI (match_dup 1)))]
10143 "ix86_match_ccmode (insn, CCNOmode)
10144 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10146 [(set_attr "type" "alu1")
10147 (set_attr "mode" "<MODE>")])
10150 [(set (match_operand 0 "flags_reg_operand" "")
10151 (match_operator 2 "compare_operator"
10152 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
10154 (set (match_operand:SWI 1 "nonimmediate_operand" "")
10155 (not:SWI (match_dup 3)))]
10156 "ix86_match_ccmode (insn, CCNOmode)"
10157 [(parallel [(set (match_dup 0)
10158 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10161 (xor:SWI (match_dup 3) (const_int -1)))])]
10164 ;; ??? Currently never generated - xor is used instead.
10165 (define_insn "*one_cmplsi2_2_zext"
10166 [(set (reg FLAGS_REG)
10167 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10169 (set (match_operand:DI 0 "register_operand" "=r")
10170 (zero_extend:DI (not:SI (match_dup 1))))]
10171 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10172 && ix86_unary_operator_ok (NOT, SImode, operands)"
10174 [(set_attr "type" "alu1")
10175 (set_attr "mode" "SI")])
10178 [(set (match_operand 0 "flags_reg_operand" "")
10179 (match_operator 2 "compare_operator"
10180 [(not:SI (match_operand:SI 3 "register_operand" ""))
10182 (set (match_operand:DI 1 "register_operand" "")
10183 (zero_extend:DI (not:SI (match_dup 3))))]
10184 "ix86_match_ccmode (insn, CCNOmode)"
10185 [(parallel [(set (match_dup 0)
10186 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10189 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10192 ;; Arithmetic shift instructions
10194 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10195 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10196 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10197 ;; from the assembler input.
10199 ;; This instruction shifts the target reg/mem as usual, but instead of
10200 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10201 ;; is a left shift double, bits are taken from the high order bits of
10202 ;; reg, else if the insn is a shift right double, bits are taken from the
10203 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10204 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10206 ;; Since sh[lr]d does not change the `reg' operand, that is done
10207 ;; separately, making all shifts emit pairs of shift double and normal
10208 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10209 ;; support a 63 bit shift, each shift where the count is in a reg expands
10210 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10212 ;; If the shift count is a constant, we need never emit more than one
10213 ;; shift pair, instead using moves and sign extension for counts greater
10216 (define_expand "ashlti3"
10217 [(set (match_operand:TI 0 "register_operand" "")
10218 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10219 (match_operand:QI 2 "nonmemory_operand" "")))]
10221 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10223 ;; This pattern must be defined before *ashlti3_1 to prevent
10224 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10226 (define_insn "*avx_ashlti3"
10227 [(set (match_operand:TI 0 "register_operand" "=x")
10228 (ashift:TI (match_operand:TI 1 "register_operand" "x")
10229 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10232 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10233 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
10235 [(set_attr "type" "sseishft")
10236 (set_attr "prefix" "vex")
10237 (set_attr "length_immediate" "1")
10238 (set_attr "mode" "TI")])
10240 (define_insn "sse2_ashlti3"
10241 [(set (match_operand:TI 0 "register_operand" "=x")
10242 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10243 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10246 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10247 return "pslldq\t{%2, %0|%0, %2}";
10249 [(set_attr "type" "sseishft")
10250 (set_attr "prefix_data16" "1")
10251 (set_attr "length_immediate" "1")
10252 (set_attr "mode" "TI")])
10254 (define_insn "*ashlti3_1"
10255 [(set (match_operand:TI 0 "register_operand" "=&r,r")
10256 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10257 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10258 (clobber (reg:CC FLAGS_REG))]
10261 [(set_attr "type" "multi")])
10264 [(match_scratch:DI 3 "r")
10265 (parallel [(set (match_operand:TI 0 "register_operand" "")
10266 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10267 (match_operand:QI 2 "nonmemory_operand" "")))
10268 (clobber (reg:CC FLAGS_REG))])
10272 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10275 [(set (match_operand:TI 0 "register_operand" "")
10276 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10277 (match_operand:QI 2 "nonmemory_operand" "")))
10278 (clobber (reg:CC FLAGS_REG))]
10279 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10280 ? epilogue_completed : reload_completed)"
10282 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10284 (define_insn "x86_64_shld"
10285 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10286 (ior:DI (ashift:DI (match_dup 0)
10287 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10288 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10289 (minus:QI (const_int 64) (match_dup 2)))))
10290 (clobber (reg:CC FLAGS_REG))]
10292 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10293 [(set_attr "type" "ishift")
10294 (set_attr "prefix_0f" "1")
10295 (set_attr "mode" "DI")
10296 (set_attr "athlon_decode" "vector")
10297 (set_attr "amdfam10_decode" "vector")])
10299 (define_expand "x86_64_shift_adj_1"
10300 [(set (reg:CCZ FLAGS_REG)
10301 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10304 (set (match_operand:DI 0 "register_operand" "")
10305 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10306 (match_operand:DI 1 "register_operand" "")
10309 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10310 (match_operand:DI 3 "register_operand" "r")
10315 (define_expand "x86_64_shift_adj_2"
10316 [(use (match_operand:DI 0 "register_operand" ""))
10317 (use (match_operand:DI 1 "register_operand" ""))
10318 (use (match_operand:QI 2 "register_operand" ""))]
10321 rtx label = gen_label_rtx ();
10324 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10326 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10327 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10328 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10329 gen_rtx_LABEL_REF (VOIDmode, label),
10331 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10332 JUMP_LABEL (tmp) = label;
10334 emit_move_insn (operands[0], operands[1]);
10335 ix86_expand_clear (operands[1]);
10337 emit_label (label);
10338 LABEL_NUSES (label) = 1;
10343 (define_expand "ashldi3"
10344 [(set (match_operand:DI 0 "shiftdi_operand" "")
10345 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10346 (match_operand:QI 2 "nonmemory_operand" "")))]
10348 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10350 (define_insn "*ashldi3_1_rex64"
10351 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10352 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10353 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10354 (clobber (reg:CC FLAGS_REG))]
10355 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10357 switch (get_attr_type (insn))
10360 gcc_assert (operands[2] == const1_rtx);
10361 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10362 return "add{q}\t%0, %0";
10365 gcc_assert (CONST_INT_P (operands[2]));
10366 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10367 operands[1] = gen_rtx_MULT (DImode, operands[1],
10368 GEN_INT (1 << INTVAL (operands[2])));
10369 return "lea{q}\t{%a1, %0|%0, %a1}";
10372 if (REG_P (operands[2]))
10373 return "sal{q}\t{%b2, %0|%0, %b2}";
10374 else if (operands[2] == const1_rtx
10375 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10376 return "sal{q}\t%0";
10378 return "sal{q}\t{%2, %0|%0, %2}";
10381 [(set (attr "type")
10382 (cond [(eq_attr "alternative" "1")
10383 (const_string "lea")
10384 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10386 (match_operand 0 "register_operand" ""))
10387 (match_operand 2 "const1_operand" ""))
10388 (const_string "alu")
10390 (const_string "ishift")))
10391 (set (attr "length_immediate")
10393 (ior (eq_attr "type" "alu")
10394 (and (eq_attr "type" "ishift")
10395 (and (match_operand 2 "const1_operand" "")
10396 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10399 (const_string "*")))
10400 (set_attr "mode" "DI")])
10402 ;; Convert lea to the lea pattern to avoid flags dependency.
10404 [(set (match_operand:DI 0 "register_operand" "")
10405 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10406 (match_operand:QI 2 "immediate_operand" "")))
10407 (clobber (reg:CC FLAGS_REG))]
10408 "TARGET_64BIT && reload_completed
10409 && true_regnum (operands[0]) != true_regnum (operands[1])"
10410 [(set (match_dup 0)
10411 (mult:DI (match_dup 1)
10413 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10415 ;; This pattern can't accept a variable shift count, since shifts by
10416 ;; zero don't affect the flags. We assume that shifts by constant
10417 ;; zero are optimized away.
10418 (define_insn "*ashldi3_cmp_rex64"
10419 [(set (reg FLAGS_REG)
10421 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10422 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10424 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10425 (ashift:DI (match_dup 1) (match_dup 2)))]
10427 && (optimize_function_for_size_p (cfun)
10428 || !TARGET_PARTIAL_FLAG_REG_STALL
10429 || (operands[2] == const1_rtx
10431 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10432 && ix86_match_ccmode (insn, CCGOCmode)
10433 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10435 switch (get_attr_type (insn))
10438 gcc_assert (operands[2] == const1_rtx);
10439 return "add{q}\t%0, %0";
10442 if (REG_P (operands[2]))
10443 return "sal{q}\t{%b2, %0|%0, %b2}";
10444 else if (operands[2] == const1_rtx
10445 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10446 return "sal{q}\t%0";
10448 return "sal{q}\t{%2, %0|%0, %2}";
10451 [(set (attr "type")
10452 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10454 (match_operand 0 "register_operand" ""))
10455 (match_operand 2 "const1_operand" ""))
10456 (const_string "alu")
10458 (const_string "ishift")))
10459 (set (attr "length_immediate")
10461 (ior (eq_attr "type" "alu")
10462 (and (eq_attr "type" "ishift")
10463 (and (match_operand 2 "const1_operand" "")
10464 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10467 (const_string "*")))
10468 (set_attr "mode" "DI")])
10470 (define_insn "*ashldi3_cconly_rex64"
10471 [(set (reg FLAGS_REG)
10473 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10474 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10476 (clobber (match_scratch:DI 0 "=r"))]
10478 && (optimize_function_for_size_p (cfun)
10479 || !TARGET_PARTIAL_FLAG_REG_STALL
10480 || (operands[2] == const1_rtx
10482 || TARGET_DOUBLE_WITH_ADD)))
10483 && ix86_match_ccmode (insn, CCGOCmode)
10484 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10486 switch (get_attr_type (insn))
10489 gcc_assert (operands[2] == const1_rtx);
10490 return "add{q}\t%0, %0";
10493 if (REG_P (operands[2]))
10494 return "sal{q}\t{%b2, %0|%0, %b2}";
10495 else if (operands[2] == const1_rtx
10496 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10497 return "sal{q}\t%0";
10499 return "sal{q}\t{%2, %0|%0, %2}";
10502 [(set (attr "type")
10503 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10505 (match_operand 0 "register_operand" ""))
10506 (match_operand 2 "const1_operand" ""))
10507 (const_string "alu")
10509 (const_string "ishift")))
10510 (set (attr "length_immediate")
10512 (ior (eq_attr "type" "alu")
10513 (and (eq_attr "type" "ishift")
10514 (and (match_operand 2 "const1_operand" "")
10515 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10518 (const_string "*")))
10519 (set_attr "mode" "DI")])
10521 (define_insn "*ashldi3_1"
10522 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10523 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10524 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10525 (clobber (reg:CC FLAGS_REG))]
10528 [(set_attr "type" "multi")])
10530 ;; By default we don't ask for a scratch register, because when DImode
10531 ;; values are manipulated, registers are already at a premium. But if
10532 ;; we have one handy, we won't turn it away.
10534 [(match_scratch:SI 3 "r")
10535 (parallel [(set (match_operand:DI 0 "register_operand" "")
10536 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10537 (match_operand:QI 2 "nonmemory_operand" "")))
10538 (clobber (reg:CC FLAGS_REG))])
10540 "!TARGET_64BIT && TARGET_CMOVE"
10542 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10545 [(set (match_operand:DI 0 "register_operand" "")
10546 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10547 (match_operand:QI 2 "nonmemory_operand" "")))
10548 (clobber (reg:CC FLAGS_REG))]
10549 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10550 ? epilogue_completed : reload_completed)"
10552 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10554 (define_insn "x86_shld"
10555 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10556 (ior:SI (ashift:SI (match_dup 0)
10557 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10558 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10559 (minus:QI (const_int 32) (match_dup 2)))))
10560 (clobber (reg:CC FLAGS_REG))]
10562 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10563 [(set_attr "type" "ishift")
10564 (set_attr "prefix_0f" "1")
10565 (set_attr "mode" "SI")
10566 (set_attr "pent_pair" "np")
10567 (set_attr "athlon_decode" "vector")
10568 (set_attr "amdfam10_decode" "vector")])
10570 (define_expand "x86_shift_adj_1"
10571 [(set (reg:CCZ FLAGS_REG)
10572 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10575 (set (match_operand:SI 0 "register_operand" "")
10576 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10577 (match_operand:SI 1 "register_operand" "")
10580 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10581 (match_operand:SI 3 "register_operand" "r")
10586 (define_expand "x86_shift_adj_2"
10587 [(use (match_operand:SI 0 "register_operand" ""))
10588 (use (match_operand:SI 1 "register_operand" ""))
10589 (use (match_operand:QI 2 "register_operand" ""))]
10592 rtx label = gen_label_rtx ();
10595 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10597 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10598 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10599 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10600 gen_rtx_LABEL_REF (VOIDmode, label),
10602 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10603 JUMP_LABEL (tmp) = label;
10605 emit_move_insn (operands[0], operands[1]);
10606 ix86_expand_clear (operands[1]);
10608 emit_label (label);
10609 LABEL_NUSES (label) = 1;
10614 (define_expand "ashlsi3"
10615 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10616 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10617 (match_operand:QI 2 "nonmemory_operand" "")))]
10619 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10621 (define_insn "*ashlsi3_1"
10622 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10623 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10624 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10625 (clobber (reg:CC FLAGS_REG))]
10626 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10628 switch (get_attr_type (insn))
10631 gcc_assert (operands[2] == const1_rtx);
10632 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10633 return "add{l}\t%0, %0";
10639 if (REG_P (operands[2]))
10640 return "sal{l}\t{%b2, %0|%0, %b2}";
10641 else if (operands[2] == const1_rtx
10642 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10643 return "sal{l}\t%0";
10645 return "sal{l}\t{%2, %0|%0, %2}";
10648 [(set (attr "type")
10649 (cond [(eq_attr "alternative" "1")
10650 (const_string "lea")
10651 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10653 (match_operand 0 "register_operand" ""))
10654 (match_operand 2 "const1_operand" ""))
10655 (const_string "alu")
10657 (const_string "ishift")))
10658 (set (attr "length_immediate")
10660 (ior (eq_attr "type" "alu")
10661 (and (eq_attr "type" "ishift")
10662 (and (match_operand 2 "const1_operand" "")
10663 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10666 (const_string "*")))
10667 (set_attr "mode" "SI")])
10669 ;; Convert lea to the lea pattern to avoid flags dependency.
10671 [(set (match_operand 0 "register_operand" "")
10672 (ashift (match_operand 1 "index_register_operand" "")
10673 (match_operand:QI 2 "const_int_operand" "")))
10674 (clobber (reg:CC FLAGS_REG))]
10676 && true_regnum (operands[0]) != true_regnum (operands[1])
10677 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10681 enum machine_mode mode = GET_MODE (operands[0]);
10683 if (GET_MODE_SIZE (mode) < 4)
10684 operands[0] = gen_lowpart (SImode, operands[0]);
10686 operands[1] = gen_lowpart (Pmode, operands[1]);
10687 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10689 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10690 if (Pmode != SImode)
10691 pat = gen_rtx_SUBREG (SImode, pat, 0);
10692 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10696 ;; Rare case of shifting RSP is handled by generating move and shift
10698 [(set (match_operand 0 "register_operand" "")
10699 (ashift (match_operand 1 "register_operand" "")
10700 (match_operand:QI 2 "const_int_operand" "")))
10701 (clobber (reg:CC FLAGS_REG))]
10703 && true_regnum (operands[0]) != true_regnum (operands[1])"
10707 emit_move_insn (operands[0], operands[1]);
10708 pat = gen_rtx_SET (VOIDmode, operands[0],
10709 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10710 operands[0], operands[2]));
10711 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10712 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10716 (define_insn "*ashlsi3_1_zext"
10717 [(set (match_operand:DI 0 "register_operand" "=r,r")
10718 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10719 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10720 (clobber (reg:CC FLAGS_REG))]
10721 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10723 switch (get_attr_type (insn))
10726 gcc_assert (operands[2] == const1_rtx);
10727 return "add{l}\t%k0, %k0";
10733 if (REG_P (operands[2]))
10734 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10735 else if (operands[2] == const1_rtx
10736 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10737 return "sal{l}\t%k0";
10739 return "sal{l}\t{%2, %k0|%k0, %2}";
10742 [(set (attr "type")
10743 (cond [(eq_attr "alternative" "1")
10744 (const_string "lea")
10745 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10747 (match_operand 2 "const1_operand" ""))
10748 (const_string "alu")
10750 (const_string "ishift")))
10751 (set (attr "length_immediate")
10753 (ior (eq_attr "type" "alu")
10754 (and (eq_attr "type" "ishift")
10755 (and (match_operand 2 "const1_operand" "")
10756 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10759 (const_string "*")))
10760 (set_attr "mode" "SI")])
10762 ;; Convert lea to the lea pattern to avoid flags dependency.
10764 [(set (match_operand:DI 0 "register_operand" "")
10765 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10766 (match_operand:QI 2 "const_int_operand" ""))))
10767 (clobber (reg:CC FLAGS_REG))]
10768 "TARGET_64BIT && reload_completed
10769 && true_regnum (operands[0]) != true_regnum (operands[1])"
10770 [(set (match_dup 0) (zero_extend:DI
10771 (subreg:SI (mult:SI (match_dup 1)
10772 (match_dup 2)) 0)))]
10774 operands[1] = gen_lowpart (Pmode, operands[1]);
10775 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10778 ;; This pattern can't accept a variable shift count, since shifts by
10779 ;; zero don't affect the flags. We assume that shifts by constant
10780 ;; zero are optimized away.
10781 (define_insn "*ashlsi3_cmp"
10782 [(set (reg FLAGS_REG)
10784 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10785 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10787 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10788 (ashift:SI (match_dup 1) (match_dup 2)))]
10789 "(optimize_function_for_size_p (cfun)
10790 || !TARGET_PARTIAL_FLAG_REG_STALL
10791 || (operands[2] == const1_rtx
10793 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10794 && ix86_match_ccmode (insn, CCGOCmode)
10795 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10797 switch (get_attr_type (insn))
10800 gcc_assert (operands[2] == const1_rtx);
10801 return "add{l}\t%0, %0";
10804 if (REG_P (operands[2]))
10805 return "sal{l}\t{%b2, %0|%0, %b2}";
10806 else if (operands[2] == const1_rtx
10807 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10808 return "sal{l}\t%0";
10810 return "sal{l}\t{%2, %0|%0, %2}";
10813 [(set (attr "type")
10814 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10816 (match_operand 0 "register_operand" ""))
10817 (match_operand 2 "const1_operand" ""))
10818 (const_string "alu")
10820 (const_string "ishift")))
10821 (set (attr "length_immediate")
10823 (ior (eq_attr "type" "alu")
10824 (and (eq_attr "type" "ishift")
10825 (and (match_operand 2 "const1_operand" "")
10826 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10829 (const_string "*")))
10830 (set_attr "mode" "SI")])
10832 (define_insn "*ashlsi3_cconly"
10833 [(set (reg FLAGS_REG)
10835 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10836 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10838 (clobber (match_scratch:SI 0 "=r"))]
10839 "(optimize_function_for_size_p (cfun)
10840 || !TARGET_PARTIAL_FLAG_REG_STALL
10841 || (operands[2] == const1_rtx
10843 || TARGET_DOUBLE_WITH_ADD)))
10844 && ix86_match_ccmode (insn, CCGOCmode)
10845 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10847 switch (get_attr_type (insn))
10850 gcc_assert (operands[2] == const1_rtx);
10851 return "add{l}\t%0, %0";
10854 if (REG_P (operands[2]))
10855 return "sal{l}\t{%b2, %0|%0, %b2}";
10856 else if (operands[2] == const1_rtx
10857 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10858 return "sal{l}\t%0";
10860 return "sal{l}\t{%2, %0|%0, %2}";
10863 [(set (attr "type")
10864 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10866 (match_operand 0 "register_operand" ""))
10867 (match_operand 2 "const1_operand" ""))
10868 (const_string "alu")
10870 (const_string "ishift")))
10871 (set (attr "length_immediate")
10873 (ior (eq_attr "type" "alu")
10874 (and (eq_attr "type" "ishift")
10875 (and (match_operand 2 "const1_operand" "")
10876 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10879 (const_string "*")))
10880 (set_attr "mode" "SI")])
10882 (define_insn "*ashlsi3_cmp_zext"
10883 [(set (reg FLAGS_REG)
10885 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10886 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10888 (set (match_operand:DI 0 "register_operand" "=r")
10889 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10891 && (optimize_function_for_size_p (cfun)
10892 || !TARGET_PARTIAL_FLAG_REG_STALL
10893 || (operands[2] == const1_rtx
10895 || TARGET_DOUBLE_WITH_ADD)))
10896 && ix86_match_ccmode (insn, CCGOCmode)
10897 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10899 switch (get_attr_type (insn))
10902 gcc_assert (operands[2] == const1_rtx);
10903 return "add{l}\t%k0, %k0";
10906 if (REG_P (operands[2]))
10907 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10908 else if (operands[2] == const1_rtx
10909 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10910 return "sal{l}\t%k0";
10912 return "sal{l}\t{%2, %k0|%k0, %2}";
10915 [(set (attr "type")
10916 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10918 (match_operand 2 "const1_operand" ""))
10919 (const_string "alu")
10921 (const_string "ishift")))
10922 (set (attr "length_immediate")
10924 (ior (eq_attr "type" "alu")
10925 (and (eq_attr "type" "ishift")
10926 (and (match_operand 2 "const1_operand" "")
10927 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10930 (const_string "*")))
10931 (set_attr "mode" "SI")])
10933 (define_expand "ashlhi3"
10934 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10935 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10936 (match_operand:QI 2 "nonmemory_operand" "")))]
10937 "TARGET_HIMODE_MATH"
10938 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10940 (define_insn "*ashlhi3_1_lea"
10941 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10942 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10943 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10944 (clobber (reg:CC FLAGS_REG))]
10945 "!TARGET_PARTIAL_REG_STALL
10946 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10948 switch (get_attr_type (insn))
10953 gcc_assert (operands[2] == const1_rtx);
10954 return "add{w}\t%0, %0";
10957 if (REG_P (operands[2]))
10958 return "sal{w}\t{%b2, %0|%0, %b2}";
10959 else if (operands[2] == const1_rtx
10960 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10961 return "sal{w}\t%0";
10963 return "sal{w}\t{%2, %0|%0, %2}";
10966 [(set (attr "type")
10967 (cond [(eq_attr "alternative" "1")
10968 (const_string "lea")
10969 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10971 (match_operand 0 "register_operand" ""))
10972 (match_operand 2 "const1_operand" ""))
10973 (const_string "alu")
10975 (const_string "ishift")))
10976 (set (attr "length_immediate")
10978 (ior (eq_attr "type" "alu")
10979 (and (eq_attr "type" "ishift")
10980 (and (match_operand 2 "const1_operand" "")
10981 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10984 (const_string "*")))
10985 (set_attr "mode" "HI,SI")])
10987 (define_insn "*ashlhi3_1"
10988 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10989 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10990 (match_operand:QI 2 "nonmemory_operand" "cI")))
10991 (clobber (reg:CC FLAGS_REG))]
10992 "TARGET_PARTIAL_REG_STALL
10993 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10995 switch (get_attr_type (insn))
10998 gcc_assert (operands[2] == const1_rtx);
10999 return "add{w}\t%0, %0";
11002 if (REG_P (operands[2]))
11003 return "sal{w}\t{%b2, %0|%0, %b2}";
11004 else if (operands[2] == const1_rtx
11005 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11006 return "sal{w}\t%0";
11008 return "sal{w}\t{%2, %0|%0, %2}";
11011 [(set (attr "type")
11012 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11014 (match_operand 0 "register_operand" ""))
11015 (match_operand 2 "const1_operand" ""))
11016 (const_string "alu")
11018 (const_string "ishift")))
11019 (set (attr "length_immediate")
11021 (ior (eq_attr "type" "alu")
11022 (and (eq_attr "type" "ishift")
11023 (and (match_operand 2 "const1_operand" "")
11024 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11027 (const_string "*")))
11028 (set_attr "mode" "HI")])
11030 ;; This pattern can't accept a variable shift count, since shifts by
11031 ;; zero don't affect the flags. We assume that shifts by constant
11032 ;; zero are optimized away.
11033 (define_insn "*ashlhi3_cmp"
11034 [(set (reg FLAGS_REG)
11036 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11037 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11039 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11040 (ashift:HI (match_dup 1) (match_dup 2)))]
11041 "(optimize_function_for_size_p (cfun)
11042 || !TARGET_PARTIAL_FLAG_REG_STALL
11043 || (operands[2] == const1_rtx
11045 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11046 && ix86_match_ccmode (insn, CCGOCmode)
11047 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11049 switch (get_attr_type (insn))
11052 gcc_assert (operands[2] == const1_rtx);
11053 return "add{w}\t%0, %0";
11056 if (REG_P (operands[2]))
11057 return "sal{w}\t{%b2, %0|%0, %b2}";
11058 else if (operands[2] == const1_rtx
11059 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11060 return "sal{w}\t%0";
11062 return "sal{w}\t{%2, %0|%0, %2}";
11065 [(set (attr "type")
11066 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11068 (match_operand 0 "register_operand" ""))
11069 (match_operand 2 "const1_operand" ""))
11070 (const_string "alu")
11072 (const_string "ishift")))
11073 (set (attr "length_immediate")
11075 (ior (eq_attr "type" "alu")
11076 (and (eq_attr "type" "ishift")
11077 (and (match_operand 2 "const1_operand" "")
11078 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11081 (const_string "*")))
11082 (set_attr "mode" "HI")])
11084 (define_insn "*ashlhi3_cconly"
11085 [(set (reg FLAGS_REG)
11087 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11088 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11090 (clobber (match_scratch:HI 0 "=r"))]
11091 "(optimize_function_for_size_p (cfun)
11092 || !TARGET_PARTIAL_FLAG_REG_STALL
11093 || (operands[2] == const1_rtx
11095 || TARGET_DOUBLE_WITH_ADD)))
11096 && ix86_match_ccmode (insn, CCGOCmode)
11097 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11099 switch (get_attr_type (insn))
11102 gcc_assert (operands[2] == const1_rtx);
11103 return "add{w}\t%0, %0";
11106 if (REG_P (operands[2]))
11107 return "sal{w}\t{%b2, %0|%0, %b2}";
11108 else if (operands[2] == const1_rtx
11109 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11110 return "sal{w}\t%0";
11112 return "sal{w}\t{%2, %0|%0, %2}";
11115 [(set (attr "type")
11116 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11118 (match_operand 0 "register_operand" ""))
11119 (match_operand 2 "const1_operand" ""))
11120 (const_string "alu")
11122 (const_string "ishift")))
11123 (set (attr "length_immediate")
11125 (ior (eq_attr "type" "alu")
11126 (and (eq_attr "type" "ishift")
11127 (and (match_operand 2 "const1_operand" "")
11128 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11131 (const_string "*")))
11132 (set_attr "mode" "HI")])
11134 (define_expand "ashlqi3"
11135 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11136 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11137 (match_operand:QI 2 "nonmemory_operand" "")))]
11138 "TARGET_QIMODE_MATH"
11139 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11141 ;; %%% Potential partial reg stall on alternative 2. What to do?
11143 (define_insn "*ashlqi3_1_lea"
11144 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11145 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11146 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11147 (clobber (reg:CC FLAGS_REG))]
11148 "!TARGET_PARTIAL_REG_STALL
11149 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11151 switch (get_attr_type (insn))
11156 gcc_assert (operands[2] == const1_rtx);
11157 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11158 return "add{l}\t%k0, %k0";
11160 return "add{b}\t%0, %0";
11163 if (REG_P (operands[2]))
11165 if (get_attr_mode (insn) == MODE_SI)
11166 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11168 return "sal{b}\t{%b2, %0|%0, %b2}";
11170 else if (operands[2] == const1_rtx
11171 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11173 if (get_attr_mode (insn) == MODE_SI)
11174 return "sal{l}\t%0";
11176 return "sal{b}\t%0";
11180 if (get_attr_mode (insn) == MODE_SI)
11181 return "sal{l}\t{%2, %k0|%k0, %2}";
11183 return "sal{b}\t{%2, %0|%0, %2}";
11187 [(set (attr "type")
11188 (cond [(eq_attr "alternative" "2")
11189 (const_string "lea")
11190 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11192 (match_operand 0 "register_operand" ""))
11193 (match_operand 2 "const1_operand" ""))
11194 (const_string "alu")
11196 (const_string "ishift")))
11197 (set (attr "length_immediate")
11199 (ior (eq_attr "type" "alu")
11200 (and (eq_attr "type" "ishift")
11201 (and (match_operand 2 "const1_operand" "")
11202 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11205 (const_string "*")))
11206 (set_attr "mode" "QI,SI,SI")])
11208 (define_insn "*ashlqi3_1"
11209 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11210 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11211 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11212 (clobber (reg:CC FLAGS_REG))]
11213 "TARGET_PARTIAL_REG_STALL
11214 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11216 switch (get_attr_type (insn))
11219 gcc_assert (operands[2] == const1_rtx);
11220 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11221 return "add{l}\t%k0, %k0";
11223 return "add{b}\t%0, %0";
11226 if (REG_P (operands[2]))
11228 if (get_attr_mode (insn) == MODE_SI)
11229 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11231 return "sal{b}\t{%b2, %0|%0, %b2}";
11233 else if (operands[2] == const1_rtx
11234 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11236 if (get_attr_mode (insn) == MODE_SI)
11237 return "sal{l}\t%0";
11239 return "sal{b}\t%0";
11243 if (get_attr_mode (insn) == MODE_SI)
11244 return "sal{l}\t{%2, %k0|%k0, %2}";
11246 return "sal{b}\t{%2, %0|%0, %2}";
11250 [(set (attr "type")
11251 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11253 (match_operand 0 "register_operand" ""))
11254 (match_operand 2 "const1_operand" ""))
11255 (const_string "alu")
11257 (const_string "ishift")))
11258 (set (attr "length_immediate")
11260 (ior (eq_attr "type" "alu")
11261 (and (eq_attr "type" "ishift")
11262 (and (match_operand 2 "const1_operand" "")
11263 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11266 (const_string "*")))
11267 (set_attr "mode" "QI,SI")])
11269 ;; This pattern can't accept a variable shift count, since shifts by
11270 ;; zero don't affect the flags. We assume that shifts by constant
11271 ;; zero are optimized away.
11272 (define_insn "*ashlqi3_cmp"
11273 [(set (reg FLAGS_REG)
11275 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11276 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11278 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11279 (ashift:QI (match_dup 1) (match_dup 2)))]
11280 "(optimize_function_for_size_p (cfun)
11281 || !TARGET_PARTIAL_FLAG_REG_STALL
11282 || (operands[2] == const1_rtx
11284 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11285 && ix86_match_ccmode (insn, CCGOCmode)
11286 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11288 switch (get_attr_type (insn))
11291 gcc_assert (operands[2] == const1_rtx);
11292 return "add{b}\t%0, %0";
11295 if (REG_P (operands[2]))
11296 return "sal{b}\t{%b2, %0|%0, %b2}";
11297 else if (operands[2] == const1_rtx
11298 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11299 return "sal{b}\t%0";
11301 return "sal{b}\t{%2, %0|%0, %2}";
11304 [(set (attr "type")
11305 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11307 (match_operand 0 "register_operand" ""))
11308 (match_operand 2 "const1_operand" ""))
11309 (const_string "alu")
11311 (const_string "ishift")))
11312 (set (attr "length_immediate")
11314 (ior (eq_attr "type" "alu")
11315 (and (eq_attr "type" "ishift")
11316 (and (match_operand 2 "const1_operand" "")
11317 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11320 (const_string "*")))
11321 (set_attr "mode" "QI")])
11323 (define_insn "*ashlqi3_cconly"
11324 [(set (reg FLAGS_REG)
11326 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11327 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11329 (clobber (match_scratch:QI 0 "=q"))]
11330 "(optimize_function_for_size_p (cfun)
11331 || !TARGET_PARTIAL_FLAG_REG_STALL
11332 || (operands[2] == const1_rtx
11334 || TARGET_DOUBLE_WITH_ADD)))
11335 && ix86_match_ccmode (insn, CCGOCmode)
11336 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11338 switch (get_attr_type (insn))
11341 gcc_assert (operands[2] == const1_rtx);
11342 return "add{b}\t%0, %0";
11345 if (REG_P (operands[2]))
11346 return "sal{b}\t{%b2, %0|%0, %b2}";
11347 else if (operands[2] == const1_rtx
11348 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11349 return "sal{b}\t%0";
11351 return "sal{b}\t{%2, %0|%0, %2}";
11354 [(set (attr "type")
11355 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11357 (match_operand 0 "register_operand" ""))
11358 (match_operand 2 "const1_operand" ""))
11359 (const_string "alu")
11361 (const_string "ishift")))
11362 (set (attr "length_immediate")
11364 (ior (eq_attr "type" "alu")
11365 (and (eq_attr "type" "ishift")
11366 (and (match_operand 2 "const1_operand" "")
11367 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11370 (const_string "*")))
11371 (set_attr "mode" "QI")])
11373 ;; See comment above `ashldi3' about how this works.
11375 (define_expand "ashrti3"
11376 [(set (match_operand:TI 0 "register_operand" "")
11377 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11378 (match_operand:QI 2 "nonmemory_operand" "")))]
11380 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11382 (define_insn "*ashrti3_1"
11383 [(set (match_operand:TI 0 "register_operand" "=r")
11384 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11385 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11386 (clobber (reg:CC FLAGS_REG))]
11389 [(set_attr "type" "multi")])
11392 [(match_scratch:DI 3 "r")
11393 (parallel [(set (match_operand:TI 0 "register_operand" "")
11394 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11395 (match_operand:QI 2 "nonmemory_operand" "")))
11396 (clobber (reg:CC FLAGS_REG))])
11400 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11403 [(set (match_operand:TI 0 "register_operand" "")
11404 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11405 (match_operand:QI 2 "nonmemory_operand" "")))
11406 (clobber (reg:CC FLAGS_REG))]
11407 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11408 ? epilogue_completed : reload_completed)"
11410 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11412 (define_insn "x86_64_shrd"
11413 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11414 (ior:DI (ashiftrt:DI (match_dup 0)
11415 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11416 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11417 (minus:QI (const_int 64) (match_dup 2)))))
11418 (clobber (reg:CC FLAGS_REG))]
11420 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11421 [(set_attr "type" "ishift")
11422 (set_attr "prefix_0f" "1")
11423 (set_attr "mode" "DI")
11424 (set_attr "athlon_decode" "vector")
11425 (set_attr "amdfam10_decode" "vector")])
11427 (define_expand "ashrdi3"
11428 [(set (match_operand:DI 0 "shiftdi_operand" "")
11429 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11430 (match_operand:QI 2 "nonmemory_operand" "")))]
11432 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11434 (define_expand "x86_64_shift_adj_3"
11435 [(use (match_operand:DI 0 "register_operand" ""))
11436 (use (match_operand:DI 1 "register_operand" ""))
11437 (use (match_operand:QI 2 "register_operand" ""))]
11440 rtx label = gen_label_rtx ();
11443 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11445 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11446 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11447 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11448 gen_rtx_LABEL_REF (VOIDmode, label),
11450 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11451 JUMP_LABEL (tmp) = label;
11453 emit_move_insn (operands[0], operands[1]);
11454 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11456 emit_label (label);
11457 LABEL_NUSES (label) = 1;
11462 (define_insn "ashrdi3_63_rex64"
11463 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11464 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11465 (match_operand:DI 2 "const_int_operand" "i,i")))
11466 (clobber (reg:CC FLAGS_REG))]
11467 "TARGET_64BIT && INTVAL (operands[2]) == 63
11468 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11469 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11472 sar{q}\t{%2, %0|%0, %2}"
11473 [(set_attr "type" "imovx,ishift")
11474 (set_attr "prefix_0f" "0,*")
11475 (set_attr "length_immediate" "0,*")
11476 (set_attr "modrm" "0,1")
11477 (set_attr "mode" "DI")])
11479 (define_insn "*ashrdi3_1_one_bit_rex64"
11480 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11481 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11482 (match_operand:QI 2 "const1_operand" "")))
11483 (clobber (reg:CC FLAGS_REG))]
11485 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11486 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11488 [(set_attr "type" "ishift")
11489 (set_attr "length_immediate" "0")
11490 (set_attr "mode" "DI")])
11492 (define_insn "*ashrdi3_1_rex64"
11493 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11494 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11495 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11496 (clobber (reg:CC FLAGS_REG))]
11497 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11499 sar{q}\t{%2, %0|%0, %2}
11500 sar{q}\t{%b2, %0|%0, %b2}"
11501 [(set_attr "type" "ishift")
11502 (set_attr "mode" "DI")])
11504 ;; This pattern can't accept a variable shift count, since shifts by
11505 ;; zero don't affect the flags. We assume that shifts by constant
11506 ;; zero are optimized away.
11507 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11508 [(set (reg FLAGS_REG)
11510 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11511 (match_operand:QI 2 "const1_operand" ""))
11513 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11514 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11516 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11517 && ix86_match_ccmode (insn, CCGOCmode)
11518 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11520 [(set_attr "type" "ishift")
11521 (set_attr "length_immediate" "0")
11522 (set_attr "mode" "DI")])
11524 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11525 [(set (reg FLAGS_REG)
11527 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11528 (match_operand:QI 2 "const1_operand" ""))
11530 (clobber (match_scratch:DI 0 "=r"))]
11532 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11533 && ix86_match_ccmode (insn, CCGOCmode)
11534 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11536 [(set_attr "type" "ishift")
11537 (set_attr "length_immediate" "0")
11538 (set_attr "mode" "DI")])
11540 ;; This pattern can't accept a variable shift count, since shifts by
11541 ;; zero don't affect the flags. We assume that shifts by constant
11542 ;; zero are optimized away.
11543 (define_insn "*ashrdi3_cmp_rex64"
11544 [(set (reg FLAGS_REG)
11546 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11547 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11549 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11550 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11552 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11553 && ix86_match_ccmode (insn, CCGOCmode)
11554 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11555 "sar{q}\t{%2, %0|%0, %2}"
11556 [(set_attr "type" "ishift")
11557 (set_attr "mode" "DI")])
11559 (define_insn "*ashrdi3_cconly_rex64"
11560 [(set (reg FLAGS_REG)
11562 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11563 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11565 (clobber (match_scratch:DI 0 "=r"))]
11567 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11568 && ix86_match_ccmode (insn, CCGOCmode)
11569 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11570 "sar{q}\t{%2, %0|%0, %2}"
11571 [(set_attr "type" "ishift")
11572 (set_attr "mode" "DI")])
11574 (define_insn "*ashrdi3_1"
11575 [(set (match_operand:DI 0 "register_operand" "=r")
11576 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11577 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11578 (clobber (reg:CC FLAGS_REG))]
11581 [(set_attr "type" "multi")])
11583 ;; By default we don't ask for a scratch register, because when DImode
11584 ;; values are manipulated, registers are already at a premium. But if
11585 ;; we have one handy, we won't turn it away.
11587 [(match_scratch:SI 3 "r")
11588 (parallel [(set (match_operand:DI 0 "register_operand" "")
11589 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11590 (match_operand:QI 2 "nonmemory_operand" "")))
11591 (clobber (reg:CC FLAGS_REG))])
11593 "!TARGET_64BIT && TARGET_CMOVE"
11595 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11598 [(set (match_operand:DI 0 "register_operand" "")
11599 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11600 (match_operand:QI 2 "nonmemory_operand" "")))
11601 (clobber (reg:CC FLAGS_REG))]
11602 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11603 ? epilogue_completed : reload_completed)"
11605 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11607 (define_insn "x86_shrd"
11608 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11609 (ior:SI (ashiftrt:SI (match_dup 0)
11610 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11611 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11612 (minus:QI (const_int 32) (match_dup 2)))))
11613 (clobber (reg:CC FLAGS_REG))]
11615 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11616 [(set_attr "type" "ishift")
11617 (set_attr "prefix_0f" "1")
11618 (set_attr "pent_pair" "np")
11619 (set_attr "mode" "SI")])
11621 (define_expand "x86_shift_adj_3"
11622 [(use (match_operand:SI 0 "register_operand" ""))
11623 (use (match_operand:SI 1 "register_operand" ""))
11624 (use (match_operand:QI 2 "register_operand" ""))]
11627 rtx label = gen_label_rtx ();
11630 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11632 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11633 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11634 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11635 gen_rtx_LABEL_REF (VOIDmode, label),
11637 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11638 JUMP_LABEL (tmp) = label;
11640 emit_move_insn (operands[0], operands[1]);
11641 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11643 emit_label (label);
11644 LABEL_NUSES (label) = 1;
11649 (define_expand "ashrsi3_31"
11650 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11651 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11652 (match_operand:SI 2 "const_int_operand" "i,i")))
11653 (clobber (reg:CC FLAGS_REG))])]
11656 (define_insn "*ashrsi3_31"
11657 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11658 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11659 (match_operand:SI 2 "const_int_operand" "i,i")))
11660 (clobber (reg:CC FLAGS_REG))]
11661 "INTVAL (operands[2]) == 31
11662 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11663 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11666 sar{l}\t{%2, %0|%0, %2}"
11667 [(set_attr "type" "imovx,ishift")
11668 (set_attr "prefix_0f" "0,*")
11669 (set_attr "length_immediate" "0,*")
11670 (set_attr "modrm" "0,1")
11671 (set_attr "mode" "SI")])
11673 (define_insn "*ashrsi3_31_zext"
11674 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11675 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11676 (match_operand:SI 2 "const_int_operand" "i,i"))))
11677 (clobber (reg:CC FLAGS_REG))]
11678 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11679 && INTVAL (operands[2]) == 31
11680 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11683 sar{l}\t{%2, %k0|%k0, %2}"
11684 [(set_attr "type" "imovx,ishift")
11685 (set_attr "prefix_0f" "0,*")
11686 (set_attr "length_immediate" "0,*")
11687 (set_attr "modrm" "0,1")
11688 (set_attr "mode" "SI")])
11690 (define_expand "ashrsi3"
11691 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11692 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11693 (match_operand:QI 2 "nonmemory_operand" "")))]
11695 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11697 (define_insn "*ashrsi3_1_one_bit"
11698 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11699 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11700 (match_operand:QI 2 "const1_operand" "")))
11701 (clobber (reg:CC FLAGS_REG))]
11702 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11703 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11705 [(set_attr "type" "ishift")
11706 (set_attr "length_immediate" "0")
11707 (set_attr "mode" "SI")])
11709 (define_insn "*ashrsi3_1_one_bit_zext"
11710 [(set (match_operand:DI 0 "register_operand" "=r")
11711 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11712 (match_operand:QI 2 "const1_operand" ""))))
11713 (clobber (reg:CC FLAGS_REG))]
11715 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11716 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11718 [(set_attr "type" "ishift")
11719 (set_attr "length_immediate" "0")
11720 (set_attr "mode" "SI")])
11722 (define_insn "*ashrsi3_1"
11723 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11724 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11725 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11726 (clobber (reg:CC FLAGS_REG))]
11727 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11729 sar{l}\t{%2, %0|%0, %2}
11730 sar{l}\t{%b2, %0|%0, %b2}"
11731 [(set_attr "type" "ishift")
11732 (set_attr "mode" "SI")])
11734 (define_insn "*ashrsi3_1_zext"
11735 [(set (match_operand:DI 0 "register_operand" "=r,r")
11736 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11737 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11738 (clobber (reg:CC FLAGS_REG))]
11739 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11741 sar{l}\t{%2, %k0|%k0, %2}
11742 sar{l}\t{%b2, %k0|%k0, %b2}"
11743 [(set_attr "type" "ishift")
11744 (set_attr "mode" "SI")])
11746 ;; This pattern can't accept a variable shift count, since shifts by
11747 ;; zero don't affect the flags. We assume that shifts by constant
11748 ;; zero are optimized away.
11749 (define_insn "*ashrsi3_one_bit_cmp"
11750 [(set (reg FLAGS_REG)
11752 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11753 (match_operand:QI 2 "const1_operand" ""))
11755 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11756 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11757 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11758 && ix86_match_ccmode (insn, CCGOCmode)
11759 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11761 [(set_attr "type" "ishift")
11762 (set_attr "length_immediate" "0")
11763 (set_attr "mode" "SI")])
11765 (define_insn "*ashrsi3_one_bit_cconly"
11766 [(set (reg FLAGS_REG)
11768 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11769 (match_operand:QI 2 "const1_operand" ""))
11771 (clobber (match_scratch:SI 0 "=r"))]
11772 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11773 && ix86_match_ccmode (insn, CCGOCmode)
11774 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11776 [(set_attr "type" "ishift")
11777 (set_attr "length_immediate" "0")
11778 (set_attr "mode" "SI")])
11780 (define_insn "*ashrsi3_one_bit_cmp_zext"
11781 [(set (reg FLAGS_REG)
11783 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11784 (match_operand:QI 2 "const1_operand" ""))
11786 (set (match_operand:DI 0 "register_operand" "=r")
11787 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11789 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11790 && ix86_match_ccmode (insn, CCmode)
11791 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11793 [(set_attr "type" "ishift")
11794 (set_attr "length_immediate" "0")
11795 (set_attr "mode" "SI")])
11797 ;; This pattern can't accept a variable shift count, since shifts by
11798 ;; zero don't affect the flags. We assume that shifts by constant
11799 ;; zero are optimized away.
11800 (define_insn "*ashrsi3_cmp"
11801 [(set (reg FLAGS_REG)
11803 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11804 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11806 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11807 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11808 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11809 && ix86_match_ccmode (insn, CCGOCmode)
11810 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11811 "sar{l}\t{%2, %0|%0, %2}"
11812 [(set_attr "type" "ishift")
11813 (set_attr "mode" "SI")])
11815 (define_insn "*ashrsi3_cconly"
11816 [(set (reg FLAGS_REG)
11818 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11819 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11821 (clobber (match_scratch:SI 0 "=r"))]
11822 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11823 && ix86_match_ccmode (insn, CCGOCmode)
11824 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11825 "sar{l}\t{%2, %0|%0, %2}"
11826 [(set_attr "type" "ishift")
11827 (set_attr "mode" "SI")])
11829 (define_insn "*ashrsi3_cmp_zext"
11830 [(set (reg FLAGS_REG)
11832 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11833 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11835 (set (match_operand:DI 0 "register_operand" "=r")
11836 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11838 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11839 && ix86_match_ccmode (insn, CCGOCmode)
11840 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11841 "sar{l}\t{%2, %k0|%k0, %2}"
11842 [(set_attr "type" "ishift")
11843 (set_attr "mode" "SI")])
11845 (define_expand "ashrhi3"
11846 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11847 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11848 (match_operand:QI 2 "nonmemory_operand" "")))]
11849 "TARGET_HIMODE_MATH"
11850 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11852 (define_insn "*ashrhi3_1_one_bit"
11853 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11854 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11855 (match_operand:QI 2 "const1_operand" "")))
11856 (clobber (reg:CC FLAGS_REG))]
11857 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11858 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11860 [(set_attr "type" "ishift")
11861 (set_attr "length_immediate" "0")
11862 (set_attr "mode" "HI")])
11864 (define_insn "*ashrhi3_1"
11865 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11866 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11867 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11868 (clobber (reg:CC FLAGS_REG))]
11869 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11871 sar{w}\t{%2, %0|%0, %2}
11872 sar{w}\t{%b2, %0|%0, %b2}"
11873 [(set_attr "type" "ishift")
11874 (set_attr "mode" "HI")])
11876 ;; This pattern can't accept a variable shift count, since shifts by
11877 ;; zero don't affect the flags. We assume that shifts by constant
11878 ;; zero are optimized away.
11879 (define_insn "*ashrhi3_one_bit_cmp"
11880 [(set (reg FLAGS_REG)
11882 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11883 (match_operand:QI 2 "const1_operand" ""))
11885 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11886 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11887 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11888 && ix86_match_ccmode (insn, CCGOCmode)
11889 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11891 [(set_attr "type" "ishift")
11892 (set_attr "length_immediate" "0")
11893 (set_attr "mode" "HI")])
11895 (define_insn "*ashrhi3_one_bit_cconly"
11896 [(set (reg FLAGS_REG)
11898 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11899 (match_operand:QI 2 "const1_operand" ""))
11901 (clobber (match_scratch:HI 0 "=r"))]
11902 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11903 && ix86_match_ccmode (insn, CCGOCmode)
11904 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11906 [(set_attr "type" "ishift")
11907 (set_attr "length_immediate" "0")
11908 (set_attr "mode" "HI")])
11910 ;; This pattern can't accept a variable shift count, since shifts by
11911 ;; zero don't affect the flags. We assume that shifts by constant
11912 ;; zero are optimized away.
11913 (define_insn "*ashrhi3_cmp"
11914 [(set (reg FLAGS_REG)
11916 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11917 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11919 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11920 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11921 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11922 && ix86_match_ccmode (insn, CCGOCmode)
11923 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11924 "sar{w}\t{%2, %0|%0, %2}"
11925 [(set_attr "type" "ishift")
11926 (set_attr "mode" "HI")])
11928 (define_insn "*ashrhi3_cconly"
11929 [(set (reg FLAGS_REG)
11931 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11932 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11934 (clobber (match_scratch:HI 0 "=r"))]
11935 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11936 && ix86_match_ccmode (insn, CCGOCmode)
11937 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11938 "sar{w}\t{%2, %0|%0, %2}"
11939 [(set_attr "type" "ishift")
11940 (set_attr "mode" "HI")])
11942 (define_expand "ashrqi3"
11943 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11944 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11945 (match_operand:QI 2 "nonmemory_operand" "")))]
11946 "TARGET_QIMODE_MATH"
11947 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11949 (define_insn "*ashrqi3_1_one_bit"
11950 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11951 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11952 (match_operand:QI 2 "const1_operand" "")))
11953 (clobber (reg:CC FLAGS_REG))]
11954 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11955 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11957 [(set_attr "type" "ishift")
11958 (set_attr "length_immediate" "0")
11959 (set_attr "mode" "QI")])
11961 (define_insn "*ashrqi3_1_one_bit_slp"
11962 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11963 (ashiftrt:QI (match_dup 0)
11964 (match_operand:QI 1 "const1_operand" "")))
11965 (clobber (reg:CC FLAGS_REG))]
11966 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11967 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11968 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11970 [(set_attr "type" "ishift1")
11971 (set_attr "length_immediate" "0")
11972 (set_attr "mode" "QI")])
11974 (define_insn "*ashrqi3_1"
11975 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11976 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11977 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11978 (clobber (reg:CC FLAGS_REG))]
11979 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11981 sar{b}\t{%2, %0|%0, %2}
11982 sar{b}\t{%b2, %0|%0, %b2}"
11983 [(set_attr "type" "ishift")
11984 (set_attr "mode" "QI")])
11986 (define_insn "*ashrqi3_1_slp"
11987 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11988 (ashiftrt:QI (match_dup 0)
11989 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11990 (clobber (reg:CC FLAGS_REG))]
11991 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11992 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11994 sar{b}\t{%1, %0|%0, %1}
11995 sar{b}\t{%b1, %0|%0, %b1}"
11996 [(set_attr "type" "ishift1")
11997 (set_attr "mode" "QI")])
11999 ;; This pattern can't accept a variable shift count, since shifts by
12000 ;; zero don't affect the flags. We assume that shifts by constant
12001 ;; zero are optimized away.
12002 (define_insn "*ashrqi3_one_bit_cmp"
12003 [(set (reg FLAGS_REG)
12005 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12006 (match_operand:QI 2 "const1_operand" "I"))
12008 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12009 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12010 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12011 && ix86_match_ccmode (insn, CCGOCmode)
12012 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12014 [(set_attr "type" "ishift")
12015 (set_attr "length_immediate" "0")
12016 (set_attr "mode" "QI")])
12018 (define_insn "*ashrqi3_one_bit_cconly"
12019 [(set (reg FLAGS_REG)
12021 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12022 (match_operand:QI 2 "const1_operand" ""))
12024 (clobber (match_scratch:QI 0 "=q"))]
12025 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12026 && ix86_match_ccmode (insn, CCGOCmode)
12027 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12029 [(set_attr "type" "ishift")
12030 (set_attr "length_immediate" "0")
12031 (set_attr "mode" "QI")])
12033 ;; This pattern can't accept a variable shift count, since shifts by
12034 ;; zero don't affect the flags. We assume that shifts by constant
12035 ;; zero are optimized away.
12036 (define_insn "*ashrqi3_cmp"
12037 [(set (reg FLAGS_REG)
12039 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12040 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12042 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12043 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12044 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12045 && ix86_match_ccmode (insn, CCGOCmode)
12046 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12047 "sar{b}\t{%2, %0|%0, %2}"
12048 [(set_attr "type" "ishift")
12049 (set_attr "mode" "QI")])
12051 (define_insn "*ashrqi3_cconly"
12052 [(set (reg FLAGS_REG)
12054 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12055 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12057 (clobber (match_scratch:QI 0 "=q"))]
12058 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12059 && ix86_match_ccmode (insn, CCGOCmode)
12060 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12061 "sar{b}\t{%2, %0|%0, %2}"
12062 [(set_attr "type" "ishift")
12063 (set_attr "mode" "QI")])
12066 ;; Logical shift instructions
12068 ;; See comment above `ashldi3' about how this works.
12070 (define_expand "lshrti3"
12071 [(set (match_operand:TI 0 "register_operand" "")
12072 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12073 (match_operand:QI 2 "nonmemory_operand" "")))]
12075 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12077 ;; This pattern must be defined before *lshrti3_1 to prevent
12078 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12080 (define_insn "*avx_lshrti3"
12081 [(set (match_operand:TI 0 "register_operand" "=x")
12082 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12083 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12086 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12087 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12089 [(set_attr "type" "sseishft")
12090 (set_attr "prefix" "vex")
12091 (set_attr "length_immediate" "1")
12092 (set_attr "mode" "TI")])
12094 (define_insn "sse2_lshrti3"
12095 [(set (match_operand:TI 0 "register_operand" "=x")
12096 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12097 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12100 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12101 return "psrldq\t{%2, %0|%0, %2}";
12103 [(set_attr "type" "sseishft")
12104 (set_attr "prefix_data16" "1")
12105 (set_attr "length_immediate" "1")
12106 (set_attr "mode" "TI")])
12108 (define_insn "*lshrti3_1"
12109 [(set (match_operand:TI 0 "register_operand" "=r")
12110 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12111 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12112 (clobber (reg:CC FLAGS_REG))]
12115 [(set_attr "type" "multi")])
12118 [(match_scratch:DI 3 "r")
12119 (parallel [(set (match_operand:TI 0 "register_operand" "")
12120 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12121 (match_operand:QI 2 "nonmemory_operand" "")))
12122 (clobber (reg:CC FLAGS_REG))])
12126 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12129 [(set (match_operand:TI 0 "register_operand" "")
12130 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12131 (match_operand:QI 2 "nonmemory_operand" "")))
12132 (clobber (reg:CC FLAGS_REG))]
12133 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12134 ? epilogue_completed : reload_completed)"
12136 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12138 (define_expand "lshrdi3"
12139 [(set (match_operand:DI 0 "shiftdi_operand" "")
12140 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12141 (match_operand:QI 2 "nonmemory_operand" "")))]
12143 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12145 (define_insn "*lshrdi3_1_one_bit_rex64"
12146 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12147 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12148 (match_operand:QI 2 "const1_operand" "")))
12149 (clobber (reg:CC FLAGS_REG))]
12151 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12152 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12154 [(set_attr "type" "ishift")
12155 (set_attr "length_immediate" "0")
12156 (set_attr "mode" "DI")])
12158 (define_insn "*lshrdi3_1_rex64"
12159 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12160 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12161 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12162 (clobber (reg:CC FLAGS_REG))]
12163 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12165 shr{q}\t{%2, %0|%0, %2}
12166 shr{q}\t{%b2, %0|%0, %b2}"
12167 [(set_attr "type" "ishift")
12168 (set_attr "mode" "DI")])
12170 ;; This pattern can't accept a variable shift count, since shifts by
12171 ;; zero don't affect the flags. We assume that shifts by constant
12172 ;; zero are optimized away.
12173 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12174 [(set (reg FLAGS_REG)
12176 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12177 (match_operand:QI 2 "const1_operand" ""))
12179 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12180 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12182 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12183 && ix86_match_ccmode (insn, CCGOCmode)
12184 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12186 [(set_attr "type" "ishift")
12187 (set_attr "length_immediate" "0")
12188 (set_attr "mode" "DI")])
12190 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12191 [(set (reg FLAGS_REG)
12193 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12194 (match_operand:QI 2 "const1_operand" ""))
12196 (clobber (match_scratch:DI 0 "=r"))]
12198 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12199 && ix86_match_ccmode (insn, CCGOCmode)
12200 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12202 [(set_attr "type" "ishift")
12203 (set_attr "length_immediate" "0")
12204 (set_attr "mode" "DI")])
12206 ;; This pattern can't accept a variable shift count, since shifts by
12207 ;; zero don't affect the flags. We assume that shifts by constant
12208 ;; zero are optimized away.
12209 (define_insn "*lshrdi3_cmp_rex64"
12210 [(set (reg FLAGS_REG)
12212 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12213 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12215 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12216 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12218 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12219 && ix86_match_ccmode (insn, CCGOCmode)
12220 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12221 "shr{q}\t{%2, %0|%0, %2}"
12222 [(set_attr "type" "ishift")
12223 (set_attr "mode" "DI")])
12225 (define_insn "*lshrdi3_cconly_rex64"
12226 [(set (reg FLAGS_REG)
12228 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12229 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12231 (clobber (match_scratch:DI 0 "=r"))]
12233 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12234 && ix86_match_ccmode (insn, CCGOCmode)
12235 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12236 "shr{q}\t{%2, %0|%0, %2}"
12237 [(set_attr "type" "ishift")
12238 (set_attr "mode" "DI")])
12240 (define_insn "*lshrdi3_1"
12241 [(set (match_operand:DI 0 "register_operand" "=r")
12242 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12243 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12244 (clobber (reg:CC FLAGS_REG))]
12247 [(set_attr "type" "multi")])
12249 ;; By default we don't ask for a scratch register, because when DImode
12250 ;; values are manipulated, registers are already at a premium. But if
12251 ;; we have one handy, we won't turn it away.
12253 [(match_scratch:SI 3 "r")
12254 (parallel [(set (match_operand:DI 0 "register_operand" "")
12255 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12256 (match_operand:QI 2 "nonmemory_operand" "")))
12257 (clobber (reg:CC FLAGS_REG))])
12259 "!TARGET_64BIT && TARGET_CMOVE"
12261 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12264 [(set (match_operand:DI 0 "register_operand" "")
12265 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12266 (match_operand:QI 2 "nonmemory_operand" "")))
12267 (clobber (reg:CC FLAGS_REG))]
12268 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12269 ? epilogue_completed : reload_completed)"
12271 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12273 (define_expand "lshrsi3"
12274 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12275 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12276 (match_operand:QI 2 "nonmemory_operand" "")))]
12278 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12280 (define_insn "*lshrsi3_1_one_bit"
12281 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12282 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12283 (match_operand:QI 2 "const1_operand" "")))
12284 (clobber (reg:CC FLAGS_REG))]
12285 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12286 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12288 [(set_attr "type" "ishift")
12289 (set_attr "length_immediate" "0")
12290 (set_attr "mode" "SI")])
12292 (define_insn "*lshrsi3_1_one_bit_zext"
12293 [(set (match_operand:DI 0 "register_operand" "=r")
12294 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12295 (match_operand:QI 2 "const1_operand" "")))
12296 (clobber (reg:CC FLAGS_REG))]
12298 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12299 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12301 [(set_attr "type" "ishift")
12302 (set_attr "length_immediate" "0")
12303 (set_attr "mode" "SI")])
12305 (define_insn "*lshrsi3_1"
12306 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12307 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12308 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12309 (clobber (reg:CC FLAGS_REG))]
12310 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12312 shr{l}\t{%2, %0|%0, %2}
12313 shr{l}\t{%b2, %0|%0, %b2}"
12314 [(set_attr "type" "ishift")
12315 (set_attr "mode" "SI")])
12317 (define_insn "*lshrsi3_1_zext"
12318 [(set (match_operand:DI 0 "register_operand" "=r,r")
12320 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12321 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12322 (clobber (reg:CC FLAGS_REG))]
12323 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12325 shr{l}\t{%2, %k0|%k0, %2}
12326 shr{l}\t{%b2, %k0|%k0, %b2}"
12327 [(set_attr "type" "ishift")
12328 (set_attr "mode" "SI")])
12330 ;; This pattern can't accept a variable shift count, since shifts by
12331 ;; zero don't affect the flags. We assume that shifts by constant
12332 ;; zero are optimized away.
12333 (define_insn "*lshrsi3_one_bit_cmp"
12334 [(set (reg FLAGS_REG)
12336 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12337 (match_operand:QI 2 "const1_operand" ""))
12339 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12340 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12341 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12342 && ix86_match_ccmode (insn, CCGOCmode)
12343 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12345 [(set_attr "type" "ishift")
12346 (set_attr "length_immediate" "0")
12347 (set_attr "mode" "SI")])
12349 (define_insn "*lshrsi3_one_bit_cconly"
12350 [(set (reg FLAGS_REG)
12352 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12353 (match_operand:QI 2 "const1_operand" ""))
12355 (clobber (match_scratch:SI 0 "=r"))]
12356 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12357 && ix86_match_ccmode (insn, CCGOCmode)
12358 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12360 [(set_attr "type" "ishift")
12361 (set_attr "length_immediate" "0")
12362 (set_attr "mode" "SI")])
12364 (define_insn "*lshrsi3_cmp_one_bit_zext"
12365 [(set (reg FLAGS_REG)
12367 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12368 (match_operand:QI 2 "const1_operand" ""))
12370 (set (match_operand:DI 0 "register_operand" "=r")
12371 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12373 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12374 && ix86_match_ccmode (insn, CCGOCmode)
12375 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12377 [(set_attr "type" "ishift")
12378 (set_attr "length_immediate" "0")
12379 (set_attr "mode" "SI")])
12381 ;; This pattern can't accept a variable shift count, since shifts by
12382 ;; zero don't affect the flags. We assume that shifts by constant
12383 ;; zero are optimized away.
12384 (define_insn "*lshrsi3_cmp"
12385 [(set (reg FLAGS_REG)
12387 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12388 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12390 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12391 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12392 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12393 && ix86_match_ccmode (insn, CCGOCmode)
12394 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12395 "shr{l}\t{%2, %0|%0, %2}"
12396 [(set_attr "type" "ishift")
12397 (set_attr "mode" "SI")])
12399 (define_insn "*lshrsi3_cconly"
12400 [(set (reg FLAGS_REG)
12402 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12403 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12405 (clobber (match_scratch:SI 0 "=r"))]
12406 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12407 && ix86_match_ccmode (insn, CCGOCmode)
12408 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12409 "shr{l}\t{%2, %0|%0, %2}"
12410 [(set_attr "type" "ishift")
12411 (set_attr "mode" "SI")])
12413 (define_insn "*lshrsi3_cmp_zext"
12414 [(set (reg FLAGS_REG)
12416 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12417 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12419 (set (match_operand:DI 0 "register_operand" "=r")
12420 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12422 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12423 && ix86_match_ccmode (insn, CCGOCmode)
12424 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12425 "shr{l}\t{%2, %k0|%k0, %2}"
12426 [(set_attr "type" "ishift")
12427 (set_attr "mode" "SI")])
12429 (define_expand "lshrhi3"
12430 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12431 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12432 (match_operand:QI 2 "nonmemory_operand" "")))]
12433 "TARGET_HIMODE_MATH"
12434 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12436 (define_insn "*lshrhi3_1_one_bit"
12437 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12438 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12439 (match_operand:QI 2 "const1_operand" "")))
12440 (clobber (reg:CC FLAGS_REG))]
12441 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12442 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12444 [(set_attr "type" "ishift")
12445 (set_attr "length_immediate" "0")
12446 (set_attr "mode" "HI")])
12448 (define_insn "*lshrhi3_1"
12449 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12450 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12451 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12452 (clobber (reg:CC FLAGS_REG))]
12453 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12455 shr{w}\t{%2, %0|%0, %2}
12456 shr{w}\t{%b2, %0|%0, %b2}"
12457 [(set_attr "type" "ishift")
12458 (set_attr "mode" "HI")])
12460 ;; This pattern can't accept a variable shift count, since shifts by
12461 ;; zero don't affect the flags. We assume that shifts by constant
12462 ;; zero are optimized away.
12463 (define_insn "*lshrhi3_one_bit_cmp"
12464 [(set (reg FLAGS_REG)
12466 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12467 (match_operand:QI 2 "const1_operand" ""))
12469 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12470 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12471 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12472 && ix86_match_ccmode (insn, CCGOCmode)
12473 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12475 [(set_attr "type" "ishift")
12476 (set_attr "length_immediate" "0")
12477 (set_attr "mode" "HI")])
12479 (define_insn "*lshrhi3_one_bit_cconly"
12480 [(set (reg FLAGS_REG)
12482 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12483 (match_operand:QI 2 "const1_operand" ""))
12485 (clobber (match_scratch:HI 0 "=r"))]
12486 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12487 && ix86_match_ccmode (insn, CCGOCmode)
12488 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12490 [(set_attr "type" "ishift")
12491 (set_attr "length_immediate" "0")
12492 (set_attr "mode" "HI")])
12494 ;; This pattern can't accept a variable shift count, since shifts by
12495 ;; zero don't affect the flags. We assume that shifts by constant
12496 ;; zero are optimized away.
12497 (define_insn "*lshrhi3_cmp"
12498 [(set (reg FLAGS_REG)
12500 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12501 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12503 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12504 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12505 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12506 && ix86_match_ccmode (insn, CCGOCmode)
12507 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12508 "shr{w}\t{%2, %0|%0, %2}"
12509 [(set_attr "type" "ishift")
12510 (set_attr "mode" "HI")])
12512 (define_insn "*lshrhi3_cconly"
12513 [(set (reg FLAGS_REG)
12515 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12516 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12518 (clobber (match_scratch:HI 0 "=r"))]
12519 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12520 && ix86_match_ccmode (insn, CCGOCmode)
12521 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12522 "shr{w}\t{%2, %0|%0, %2}"
12523 [(set_attr "type" "ishift")
12524 (set_attr "mode" "HI")])
12526 (define_expand "lshrqi3"
12527 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12528 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12529 (match_operand:QI 2 "nonmemory_operand" "")))]
12530 "TARGET_QIMODE_MATH"
12531 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12533 (define_insn "*lshrqi3_1_one_bit"
12534 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12535 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12536 (match_operand:QI 2 "const1_operand" "")))
12537 (clobber (reg:CC FLAGS_REG))]
12538 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12539 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12541 [(set_attr "type" "ishift")
12542 (set_attr "length_immediate" "0")
12543 (set_attr "mode" "QI")])
12545 (define_insn "*lshrqi3_1_one_bit_slp"
12546 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12547 (lshiftrt:QI (match_dup 0)
12548 (match_operand:QI 1 "const1_operand" "")))
12549 (clobber (reg:CC FLAGS_REG))]
12550 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12551 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12553 [(set_attr "type" "ishift1")
12554 (set_attr "length_immediate" "0")
12555 (set_attr "mode" "QI")])
12557 (define_insn "*lshrqi3_1"
12558 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12559 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12560 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12561 (clobber (reg:CC FLAGS_REG))]
12562 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12564 shr{b}\t{%2, %0|%0, %2}
12565 shr{b}\t{%b2, %0|%0, %b2}"
12566 [(set_attr "type" "ishift")
12567 (set_attr "mode" "QI")])
12569 (define_insn "*lshrqi3_1_slp"
12570 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12571 (lshiftrt:QI (match_dup 0)
12572 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12573 (clobber (reg:CC FLAGS_REG))]
12574 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12575 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12577 shr{b}\t{%1, %0|%0, %1}
12578 shr{b}\t{%b1, %0|%0, %b1}"
12579 [(set_attr "type" "ishift1")
12580 (set_attr "mode" "QI")])
12582 ;; This pattern can't accept a variable shift count, since shifts by
12583 ;; zero don't affect the flags. We assume that shifts by constant
12584 ;; zero are optimized away.
12585 (define_insn "*lshrqi2_one_bit_cmp"
12586 [(set (reg FLAGS_REG)
12588 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12589 (match_operand:QI 2 "const1_operand" ""))
12591 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12592 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12593 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12594 && ix86_match_ccmode (insn, CCGOCmode)
12595 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12597 [(set_attr "type" "ishift")
12598 (set_attr "length_immediate" "0")
12599 (set_attr "mode" "QI")])
12601 (define_insn "*lshrqi2_one_bit_cconly"
12602 [(set (reg FLAGS_REG)
12604 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12605 (match_operand:QI 2 "const1_operand" ""))
12607 (clobber (match_scratch:QI 0 "=q"))]
12608 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12609 && ix86_match_ccmode (insn, CCGOCmode)
12610 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12612 [(set_attr "type" "ishift")
12613 (set_attr "length_immediate" "0")
12614 (set_attr "mode" "QI")])
12616 ;; This pattern can't accept a variable shift count, since shifts by
12617 ;; zero don't affect the flags. We assume that shifts by constant
12618 ;; zero are optimized away.
12619 (define_insn "*lshrqi2_cmp"
12620 [(set (reg FLAGS_REG)
12622 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12623 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12625 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12626 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12627 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12628 && ix86_match_ccmode (insn, CCGOCmode)
12629 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12630 "shr{b}\t{%2, %0|%0, %2}"
12631 [(set_attr "type" "ishift")
12632 (set_attr "mode" "QI")])
12634 (define_insn "*lshrqi2_cconly"
12635 [(set (reg FLAGS_REG)
12637 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12638 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12640 (clobber (match_scratch:QI 0 "=q"))]
12641 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12642 && ix86_match_ccmode (insn, CCGOCmode)
12643 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12644 "shr{b}\t{%2, %0|%0, %2}"
12645 [(set_attr "type" "ishift")
12646 (set_attr "mode" "QI")])
12648 ;; Rotate instructions
12650 (define_expand "rotldi3"
12651 [(set (match_operand:DI 0 "shiftdi_operand" "")
12652 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12653 (match_operand:QI 2 "nonmemory_operand" "")))]
12658 ix86_expand_binary_operator (ROTATE, DImode, operands);
12661 if (!const_1_to_31_operand (operands[2], VOIDmode))
12663 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12667 ;; Implement rotation using two double-precision shift instructions
12668 ;; and a scratch register.
12669 (define_insn_and_split "ix86_rotldi3"
12670 [(set (match_operand:DI 0 "register_operand" "=r")
12671 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12672 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12673 (clobber (reg:CC FLAGS_REG))
12674 (clobber (match_scratch:SI 3 "=&r"))]
12677 "&& reload_completed"
12678 [(set (match_dup 3) (match_dup 4))
12680 [(set (match_dup 4)
12681 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12682 (lshiftrt:SI (match_dup 5)
12683 (minus:QI (const_int 32) (match_dup 2)))))
12684 (clobber (reg:CC FLAGS_REG))])
12686 [(set (match_dup 5)
12687 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12688 (lshiftrt:SI (match_dup 3)
12689 (minus:QI (const_int 32) (match_dup 2)))))
12690 (clobber (reg:CC FLAGS_REG))])]
12691 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12693 (define_insn "*rotlsi3_1_one_bit_rex64"
12694 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12695 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12696 (match_operand:QI 2 "const1_operand" "")))
12697 (clobber (reg:CC FLAGS_REG))]
12699 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12700 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12702 [(set_attr "type" "rotate")
12703 (set_attr "length_immediate" "0")
12704 (set_attr "mode" "DI")])
12706 (define_insn "*rotldi3_1_rex64"
12707 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12708 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12709 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12710 (clobber (reg:CC FLAGS_REG))]
12711 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12713 rol{q}\t{%2, %0|%0, %2}
12714 rol{q}\t{%b2, %0|%0, %b2}"
12715 [(set_attr "type" "rotate")
12716 (set_attr "mode" "DI")])
12718 (define_expand "rotlsi3"
12719 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12720 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12721 (match_operand:QI 2 "nonmemory_operand" "")))]
12723 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12725 (define_insn "*rotlsi3_1_one_bit"
12726 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12727 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12728 (match_operand:QI 2 "const1_operand" "")))
12729 (clobber (reg:CC FLAGS_REG))]
12730 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12731 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12733 [(set_attr "type" "rotate")
12734 (set_attr "length_immediate" "0")
12735 (set_attr "mode" "SI")])
12737 (define_insn "*rotlsi3_1_one_bit_zext"
12738 [(set (match_operand:DI 0 "register_operand" "=r")
12740 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12741 (match_operand:QI 2 "const1_operand" ""))))
12742 (clobber (reg:CC FLAGS_REG))]
12744 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12745 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12747 [(set_attr "type" "rotate")
12748 (set_attr "length_immediate" "0")
12749 (set_attr "mode" "SI")])
12751 (define_insn "*rotlsi3_1"
12752 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12753 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12754 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12755 (clobber (reg:CC FLAGS_REG))]
12756 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12758 rol{l}\t{%2, %0|%0, %2}
12759 rol{l}\t{%b2, %0|%0, %b2}"
12760 [(set_attr "type" "rotate")
12761 (set_attr "mode" "SI")])
12763 (define_insn "*rotlsi3_1_zext"
12764 [(set (match_operand:DI 0 "register_operand" "=r,r")
12766 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12767 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12768 (clobber (reg:CC FLAGS_REG))]
12769 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12771 rol{l}\t{%2, %k0|%k0, %2}
12772 rol{l}\t{%b2, %k0|%k0, %b2}"
12773 [(set_attr "type" "rotate")
12774 (set_attr "mode" "SI")])
12776 (define_expand "rotlhi3"
12777 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12778 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12779 (match_operand:QI 2 "nonmemory_operand" "")))]
12780 "TARGET_HIMODE_MATH"
12781 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12783 (define_insn "*rotlhi3_1_one_bit"
12784 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12785 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12786 (match_operand:QI 2 "const1_operand" "")))
12787 (clobber (reg:CC FLAGS_REG))]
12788 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12789 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12791 [(set_attr "type" "rotate")
12792 (set_attr "length_immediate" "0")
12793 (set_attr "mode" "HI")])
12795 (define_insn "*rotlhi3_1"
12796 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12797 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12798 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12799 (clobber (reg:CC FLAGS_REG))]
12800 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12802 rol{w}\t{%2, %0|%0, %2}
12803 rol{w}\t{%b2, %0|%0, %b2}"
12804 [(set_attr "type" "rotate")
12805 (set_attr "mode" "HI")])
12808 [(set (match_operand:HI 0 "register_operand" "")
12809 (rotate:HI (match_dup 0) (const_int 8)))
12810 (clobber (reg:CC FLAGS_REG))]
12812 [(parallel [(set (strict_low_part (match_dup 0))
12813 (bswap:HI (match_dup 0)))
12814 (clobber (reg:CC FLAGS_REG))])]
12817 (define_expand "rotlqi3"
12818 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12819 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12820 (match_operand:QI 2 "nonmemory_operand" "")))]
12821 "TARGET_QIMODE_MATH"
12822 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12824 (define_insn "*rotlqi3_1_one_bit_slp"
12825 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12826 (rotate:QI (match_dup 0)
12827 (match_operand:QI 1 "const1_operand" "")))
12828 (clobber (reg:CC FLAGS_REG))]
12829 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12830 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12832 [(set_attr "type" "rotate1")
12833 (set_attr "length_immediate" "0")
12834 (set_attr "mode" "QI")])
12836 (define_insn "*rotlqi3_1_one_bit"
12837 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12838 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12839 (match_operand:QI 2 "const1_operand" "")))
12840 (clobber (reg:CC FLAGS_REG))]
12841 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12842 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12844 [(set_attr "type" "rotate")
12845 (set_attr "length_immediate" "0")
12846 (set_attr "mode" "QI")])
12848 (define_insn "*rotlqi3_1_slp"
12849 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12850 (rotate:QI (match_dup 0)
12851 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12852 (clobber (reg:CC FLAGS_REG))]
12853 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12854 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12856 rol{b}\t{%1, %0|%0, %1}
12857 rol{b}\t{%b1, %0|%0, %b1}"
12858 [(set_attr "type" "rotate1")
12859 (set_attr "mode" "QI")])
12861 (define_insn "*rotlqi3_1"
12862 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12863 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12864 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12865 (clobber (reg:CC FLAGS_REG))]
12866 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12868 rol{b}\t{%2, %0|%0, %2}
12869 rol{b}\t{%b2, %0|%0, %b2}"
12870 [(set_attr "type" "rotate")
12871 (set_attr "mode" "QI")])
12873 (define_expand "rotrdi3"
12874 [(set (match_operand:DI 0 "shiftdi_operand" "")
12875 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12876 (match_operand:QI 2 "nonmemory_operand" "")))]
12881 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12884 if (!const_1_to_31_operand (operands[2], VOIDmode))
12886 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12890 ;; Implement rotation using two double-precision shift instructions
12891 ;; and a scratch register.
12892 (define_insn_and_split "ix86_rotrdi3"
12893 [(set (match_operand:DI 0 "register_operand" "=r")
12894 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12895 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12896 (clobber (reg:CC FLAGS_REG))
12897 (clobber (match_scratch:SI 3 "=&r"))]
12900 "&& reload_completed"
12901 [(set (match_dup 3) (match_dup 4))
12903 [(set (match_dup 4)
12904 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12905 (ashift:SI (match_dup 5)
12906 (minus:QI (const_int 32) (match_dup 2)))))
12907 (clobber (reg:CC FLAGS_REG))])
12909 [(set (match_dup 5)
12910 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12911 (ashift:SI (match_dup 3)
12912 (minus:QI (const_int 32) (match_dup 2)))))
12913 (clobber (reg:CC FLAGS_REG))])]
12914 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12916 (define_insn "*rotrdi3_1_one_bit_rex64"
12917 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12918 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12919 (match_operand:QI 2 "const1_operand" "")))
12920 (clobber (reg:CC FLAGS_REG))]
12922 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12923 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12925 [(set_attr "type" "rotate")
12926 (set_attr "length_immediate" "0")
12927 (set_attr "mode" "DI")])
12929 (define_insn "*rotrdi3_1_rex64"
12930 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12931 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12932 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12933 (clobber (reg:CC FLAGS_REG))]
12934 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12936 ror{q}\t{%2, %0|%0, %2}
12937 ror{q}\t{%b2, %0|%0, %b2}"
12938 [(set_attr "type" "rotate")
12939 (set_attr "mode" "DI")])
12941 (define_expand "rotrsi3"
12942 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12943 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12944 (match_operand:QI 2 "nonmemory_operand" "")))]
12946 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12948 (define_insn "*rotrsi3_1_one_bit"
12949 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12950 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12951 (match_operand:QI 2 "const1_operand" "")))
12952 (clobber (reg:CC FLAGS_REG))]
12953 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12954 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12956 [(set_attr "type" "rotate")
12957 (set_attr "length_immediate" "0")
12958 (set_attr "mode" "SI")])
12960 (define_insn "*rotrsi3_1_one_bit_zext"
12961 [(set (match_operand:DI 0 "register_operand" "=r")
12963 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12964 (match_operand:QI 2 "const1_operand" ""))))
12965 (clobber (reg:CC FLAGS_REG))]
12967 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12968 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12970 [(set_attr "type" "rotate")
12971 (set_attr "length_immediate" "0")
12972 (set_attr "mode" "SI")])
12974 (define_insn "*rotrsi3_1"
12975 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12976 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12977 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12978 (clobber (reg:CC FLAGS_REG))]
12979 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12981 ror{l}\t{%2, %0|%0, %2}
12982 ror{l}\t{%b2, %0|%0, %b2}"
12983 [(set_attr "type" "rotate")
12984 (set_attr "mode" "SI")])
12986 (define_insn "*rotrsi3_1_zext"
12987 [(set (match_operand:DI 0 "register_operand" "=r,r")
12989 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12990 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12991 (clobber (reg:CC FLAGS_REG))]
12992 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12994 ror{l}\t{%2, %k0|%k0, %2}
12995 ror{l}\t{%b2, %k0|%k0, %b2}"
12996 [(set_attr "type" "rotate")
12997 (set_attr "mode" "SI")])
12999 (define_expand "rotrhi3"
13000 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13001 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13002 (match_operand:QI 2 "nonmemory_operand" "")))]
13003 "TARGET_HIMODE_MATH"
13004 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13006 (define_insn "*rotrhi3_one_bit"
13007 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13008 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13009 (match_operand:QI 2 "const1_operand" "")))
13010 (clobber (reg:CC FLAGS_REG))]
13011 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13012 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13014 [(set_attr "type" "rotate")
13015 (set_attr "length_immediate" "0")
13016 (set_attr "mode" "HI")])
13018 (define_insn "*rotrhi3_1"
13019 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13020 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13021 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13022 (clobber (reg:CC FLAGS_REG))]
13023 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13025 ror{w}\t{%2, %0|%0, %2}
13026 ror{w}\t{%b2, %0|%0, %b2}"
13027 [(set_attr "type" "rotate")
13028 (set_attr "mode" "HI")])
13031 [(set (match_operand:HI 0 "register_operand" "")
13032 (rotatert:HI (match_dup 0) (const_int 8)))
13033 (clobber (reg:CC FLAGS_REG))]
13035 [(parallel [(set (strict_low_part (match_dup 0))
13036 (bswap:HI (match_dup 0)))
13037 (clobber (reg:CC FLAGS_REG))])]
13040 (define_expand "rotrqi3"
13041 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13042 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13043 (match_operand:QI 2 "nonmemory_operand" "")))]
13044 "TARGET_QIMODE_MATH"
13045 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13047 (define_insn "*rotrqi3_1_one_bit"
13048 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13049 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13050 (match_operand:QI 2 "const1_operand" "")))
13051 (clobber (reg:CC FLAGS_REG))]
13052 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13053 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13055 [(set_attr "type" "rotate")
13056 (set_attr "length_immediate" "0")
13057 (set_attr "mode" "QI")])
13059 (define_insn "*rotrqi3_1_one_bit_slp"
13060 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13061 (rotatert:QI (match_dup 0)
13062 (match_operand:QI 1 "const1_operand" "")))
13063 (clobber (reg:CC FLAGS_REG))]
13064 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13065 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13067 [(set_attr "type" "rotate1")
13068 (set_attr "length_immediate" "0")
13069 (set_attr "mode" "QI")])
13071 (define_insn "*rotrqi3_1"
13072 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13073 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13074 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13075 (clobber (reg:CC FLAGS_REG))]
13076 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13078 ror{b}\t{%2, %0|%0, %2}
13079 ror{b}\t{%b2, %0|%0, %b2}"
13080 [(set_attr "type" "rotate")
13081 (set_attr "mode" "QI")])
13083 (define_insn "*rotrqi3_1_slp"
13084 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13085 (rotatert:QI (match_dup 0)
13086 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13087 (clobber (reg:CC FLAGS_REG))]
13088 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13089 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13091 ror{b}\t{%1, %0|%0, %1}
13092 ror{b}\t{%b1, %0|%0, %b1}"
13093 [(set_attr "type" "rotate1")
13094 (set_attr "mode" "QI")])
13096 ;; Bit set / bit test instructions
13098 (define_expand "extv"
13099 [(set (match_operand:SI 0 "register_operand" "")
13100 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13101 (match_operand:SI 2 "const8_operand" "")
13102 (match_operand:SI 3 "const8_operand" "")))]
13105 /* Handle extractions from %ah et al. */
13106 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13109 /* From mips.md: extract_bit_field doesn't verify that our source
13110 matches the predicate, so check it again here. */
13111 if (! ext_register_operand (operands[1], VOIDmode))
13115 (define_expand "extzv"
13116 [(set (match_operand:SI 0 "register_operand" "")
13117 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13118 (match_operand:SI 2 "const8_operand" "")
13119 (match_operand:SI 3 "const8_operand" "")))]
13122 /* Handle extractions from %ah et al. */
13123 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13126 /* From mips.md: extract_bit_field doesn't verify that our source
13127 matches the predicate, so check it again here. */
13128 if (! ext_register_operand (operands[1], VOIDmode))
13132 (define_expand "insv"
13133 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13134 (match_operand 1 "const8_operand" "")
13135 (match_operand 2 "const8_operand" ""))
13136 (match_operand 3 "register_operand" ""))]
13139 /* Handle insertions to %ah et al. */
13140 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13143 /* From mips.md: insert_bit_field doesn't verify that our source
13144 matches the predicate, so check it again here. */
13145 if (! ext_register_operand (operands[0], VOIDmode))
13149 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13151 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13156 ;; %%% bts, btr, btc, bt.
13157 ;; In general these instructions are *slow* when applied to memory,
13158 ;; since they enforce atomic operation. When applied to registers,
13159 ;; it depends on the cpu implementation. They're never faster than
13160 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13161 ;; no point. But in 64-bit, we can't hold the relevant immediates
13162 ;; within the instruction itself, so operating on bits in the high
13163 ;; 32-bits of a register becomes easier.
13165 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13166 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13167 ;; negdf respectively, so they can never be disabled entirely.
13169 (define_insn "*btsq"
13170 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13172 (match_operand:DI 1 "const_0_to_63_operand" ""))
13174 (clobber (reg:CC FLAGS_REG))]
13175 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13176 "bts{q}\t{%1, %0|%0, %1}"
13177 [(set_attr "type" "alu1")
13178 (set_attr "prefix_0f" "1")
13179 (set_attr "mode" "DI")])
13181 (define_insn "*btrq"
13182 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13184 (match_operand:DI 1 "const_0_to_63_operand" ""))
13186 (clobber (reg:CC FLAGS_REG))]
13187 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13188 "btr{q}\t{%1, %0|%0, %1}"
13189 [(set_attr "type" "alu1")
13190 (set_attr "prefix_0f" "1")
13191 (set_attr "mode" "DI")])
13193 (define_insn "*btcq"
13194 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13196 (match_operand:DI 1 "const_0_to_63_operand" ""))
13197 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13198 (clobber (reg:CC FLAGS_REG))]
13199 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13200 "btc{q}\t{%1, %0|%0, %1}"
13201 [(set_attr "type" "alu1")
13202 (set_attr "prefix_0f" "1")
13203 (set_attr "mode" "DI")])
13205 ;; Allow Nocona to avoid these instructions if a register is available.
13208 [(match_scratch:DI 2 "r")
13209 (parallel [(set (zero_extract:DI
13210 (match_operand:DI 0 "register_operand" "")
13212 (match_operand:DI 1 "const_0_to_63_operand" ""))
13214 (clobber (reg:CC FLAGS_REG))])]
13215 "TARGET_64BIT && !TARGET_USE_BT"
13218 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13221 if (HOST_BITS_PER_WIDE_INT >= 64)
13222 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13223 else if (i < HOST_BITS_PER_WIDE_INT)
13224 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13226 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13228 op1 = immed_double_const (lo, hi, DImode);
13231 emit_move_insn (operands[2], op1);
13235 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13240 [(match_scratch:DI 2 "r")
13241 (parallel [(set (zero_extract:DI
13242 (match_operand:DI 0 "register_operand" "")
13244 (match_operand:DI 1 "const_0_to_63_operand" ""))
13246 (clobber (reg:CC FLAGS_REG))])]
13247 "TARGET_64BIT && !TARGET_USE_BT"
13250 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13253 if (HOST_BITS_PER_WIDE_INT >= 64)
13254 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13255 else if (i < HOST_BITS_PER_WIDE_INT)
13256 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13258 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13260 op1 = immed_double_const (~lo, ~hi, DImode);
13263 emit_move_insn (operands[2], op1);
13267 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13272 [(match_scratch:DI 2 "r")
13273 (parallel [(set (zero_extract:DI
13274 (match_operand:DI 0 "register_operand" "")
13276 (match_operand:DI 1 "const_0_to_63_operand" ""))
13277 (not:DI (zero_extract:DI
13278 (match_dup 0) (const_int 1) (match_dup 1))))
13279 (clobber (reg:CC FLAGS_REG))])]
13280 "TARGET_64BIT && !TARGET_USE_BT"
13283 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13286 if (HOST_BITS_PER_WIDE_INT >= 64)
13287 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13288 else if (i < HOST_BITS_PER_WIDE_INT)
13289 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13291 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13293 op1 = immed_double_const (lo, hi, DImode);
13296 emit_move_insn (operands[2], op1);
13300 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13304 (define_insn "*btdi_rex64"
13305 [(set (reg:CCC FLAGS_REG)
13308 (match_operand:DI 0 "register_operand" "r")
13310 (match_operand:DI 1 "nonmemory_operand" "rN"))
13312 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13313 "bt{q}\t{%1, %0|%0, %1}"
13314 [(set_attr "type" "alu1")
13315 (set_attr "prefix_0f" "1")
13316 (set_attr "mode" "DI")])
13318 (define_insn "*btsi"
13319 [(set (reg:CCC FLAGS_REG)
13322 (match_operand:SI 0 "register_operand" "r")
13324 (match_operand:SI 1 "nonmemory_operand" "rN"))
13326 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13327 "bt{l}\t{%1, %0|%0, %1}"
13328 [(set_attr "type" "alu1")
13329 (set_attr "prefix_0f" "1")
13330 (set_attr "mode" "SI")])
13332 ;; Store-flag instructions.
13334 ;; For all sCOND expanders, also expand the compare or test insn that
13335 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13337 (define_insn_and_split "*setcc_di_1"
13338 [(set (match_operand:DI 0 "register_operand" "=q")
13339 (match_operator:DI 1 "ix86_comparison_operator"
13340 [(reg FLAGS_REG) (const_int 0)]))]
13341 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
13343 "&& reload_completed"
13344 [(set (match_dup 2) (match_dup 1))
13345 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
13347 PUT_MODE (operands[1], QImode);
13348 operands[2] = gen_lowpart (QImode, operands[0]);
13351 (define_insn_and_split "*setcc_si_1_and"
13352 [(set (match_operand:SI 0 "register_operand" "=q")
13353 (match_operator:SI 1 "ix86_comparison_operator"
13354 [(reg FLAGS_REG) (const_int 0)]))
13355 (clobber (reg:CC FLAGS_REG))]
13356 "!TARGET_PARTIAL_REG_STALL
13357 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
13359 "&& reload_completed"
13360 [(set (match_dup 2) (match_dup 1))
13361 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
13362 (clobber (reg:CC FLAGS_REG))])]
13364 PUT_MODE (operands[1], QImode);
13365 operands[2] = gen_lowpart (QImode, operands[0]);
13368 (define_insn_and_split "*setcc_si_1_movzbl"
13369 [(set (match_operand:SI 0 "register_operand" "=q")
13370 (match_operator:SI 1 "ix86_comparison_operator"
13371 [(reg FLAGS_REG) (const_int 0)]))]
13372 "!TARGET_PARTIAL_REG_STALL
13373 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
13375 "&& reload_completed"
13376 [(set (match_dup 2) (match_dup 1))
13377 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
13379 PUT_MODE (operands[1], QImode);
13380 operands[2] = gen_lowpart (QImode, operands[0]);
13383 (define_insn "*setcc_qi"
13384 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13385 (match_operator:QI 1 "ix86_comparison_operator"
13386 [(reg FLAGS_REG) (const_int 0)]))]
13389 [(set_attr "type" "setcc")
13390 (set_attr "mode" "QI")])
13392 (define_insn "*setcc_qi_slp"
13393 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13394 (match_operator:QI 1 "ix86_comparison_operator"
13395 [(reg FLAGS_REG) (const_int 0)]))]
13398 [(set_attr "type" "setcc")
13399 (set_attr "mode" "QI")])
13401 ;; In general it is not safe to assume too much about CCmode registers,
13402 ;; so simplify-rtx stops when it sees a second one. Under certain
13403 ;; conditions this is safe on x86, so help combine not create
13410 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13411 (ne:QI (match_operator 1 "ix86_comparison_operator"
13412 [(reg FLAGS_REG) (const_int 0)])
13415 [(set (match_dup 0) (match_dup 1))]
13417 PUT_MODE (operands[1], QImode);
13421 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13422 (ne:QI (match_operator 1 "ix86_comparison_operator"
13423 [(reg FLAGS_REG) (const_int 0)])
13426 [(set (match_dup 0) (match_dup 1))]
13428 PUT_MODE (operands[1], QImode);
13432 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13433 (eq:QI (match_operator 1 "ix86_comparison_operator"
13434 [(reg FLAGS_REG) (const_int 0)])
13437 [(set (match_dup 0) (match_dup 1))]
13439 rtx new_op1 = copy_rtx (operands[1]);
13440 operands[1] = new_op1;
13441 PUT_MODE (new_op1, QImode);
13442 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13443 GET_MODE (XEXP (new_op1, 0))));
13445 /* Make sure that (a) the CCmode we have for the flags is strong
13446 enough for the reversed compare or (b) we have a valid FP compare. */
13447 if (! ix86_comparison_operator (new_op1, VOIDmode))
13452 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13453 (eq:QI (match_operator 1 "ix86_comparison_operator"
13454 [(reg FLAGS_REG) (const_int 0)])
13457 [(set (match_dup 0) (match_dup 1))]
13459 rtx new_op1 = copy_rtx (operands[1]);
13460 operands[1] = new_op1;
13461 PUT_MODE (new_op1, QImode);
13462 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13463 GET_MODE (XEXP (new_op1, 0))));
13465 /* Make sure that (a) the CCmode we have for the flags is strong
13466 enough for the reversed compare or (b) we have a valid FP compare. */
13467 if (! ix86_comparison_operator (new_op1, VOIDmode))
13471 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13472 ;; subsequent logical operations are used to imitate conditional moves.
13473 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13476 (define_insn "*avx_setcc<mode>"
13477 [(set (match_operand:MODEF 0 "register_operand" "=x")
13478 (match_operator:MODEF 1 "avx_comparison_float_operator"
13479 [(match_operand:MODEF 2 "register_operand" "x")
13480 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13482 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13483 [(set_attr "type" "ssecmp")
13484 (set_attr "prefix" "vex")
13485 (set_attr "length_immediate" "1")
13486 (set_attr "mode" "<MODE>")])
13488 (define_insn "*sse_setcc<mode>"
13489 [(set (match_operand:MODEF 0 "register_operand" "=x")
13490 (match_operator:MODEF 1 "sse_comparison_operator"
13491 [(match_operand:MODEF 2 "register_operand" "0")
13492 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13493 "SSE_FLOAT_MODE_P (<MODE>mode)"
13494 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13495 [(set_attr "type" "ssecmp")
13496 (set_attr "length_immediate" "1")
13497 (set_attr "mode" "<MODE>")])
13499 ;; Basic conditional jump instructions.
13500 ;; We ignore the overflow flag for signed branch instructions.
13502 (define_insn "*jcc_1"
13504 (if_then_else (match_operator 1 "ix86_comparison_operator"
13505 [(reg FLAGS_REG) (const_int 0)])
13506 (label_ref (match_operand 0 "" ""))
13510 [(set_attr "type" "ibr")
13511 (set_attr "modrm" "0")
13512 (set (attr "length")
13513 (if_then_else (and (ge (minus (match_dup 0) (pc))
13515 (lt (minus (match_dup 0) (pc))
13520 (define_insn "*jcc_2"
13522 (if_then_else (match_operator 1 "ix86_comparison_operator"
13523 [(reg FLAGS_REG) (const_int 0)])
13525 (label_ref (match_operand 0 "" ""))))]
13528 [(set_attr "type" "ibr")
13529 (set_attr "modrm" "0")
13530 (set (attr "length")
13531 (if_then_else (and (ge (minus (match_dup 0) (pc))
13533 (lt (minus (match_dup 0) (pc))
13538 ;; In general it is not safe to assume too much about CCmode registers,
13539 ;; so simplify-rtx stops when it sees a second one. Under certain
13540 ;; conditions this is safe on x86, so help combine not create
13548 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13549 [(reg FLAGS_REG) (const_int 0)])
13551 (label_ref (match_operand 1 "" ""))
13555 (if_then_else (match_dup 0)
13556 (label_ref (match_dup 1))
13559 PUT_MODE (operands[0], VOIDmode);
13564 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13565 [(reg FLAGS_REG) (const_int 0)])
13567 (label_ref (match_operand 1 "" ""))
13571 (if_then_else (match_dup 0)
13572 (label_ref (match_dup 1))
13575 rtx new_op0 = copy_rtx (operands[0]);
13576 operands[0] = new_op0;
13577 PUT_MODE (new_op0, VOIDmode);
13578 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13579 GET_MODE (XEXP (new_op0, 0))));
13581 /* Make sure that (a) the CCmode we have for the flags is strong
13582 enough for the reversed compare or (b) we have a valid FP compare. */
13583 if (! ix86_comparison_operator (new_op0, VOIDmode))
13587 ;; zero_extend in SImode is correct, since this is what combine pass
13588 ;; generates from shift insn with QImode operand. Actually, the mode of
13589 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
13590 ;; appropriate modulo of the bit offset value.
13592 (define_insn_and_split "*jcc_btdi_rex64"
13594 (if_then_else (match_operator 0 "bt_comparison_operator"
13596 (match_operand:DI 1 "register_operand" "r")
13599 (match_operand:QI 2 "register_operand" "r")))
13601 (label_ref (match_operand 3 "" ""))
13603 (clobber (reg:CC FLAGS_REG))]
13604 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13607 [(set (reg:CCC FLAGS_REG)
13615 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13616 (label_ref (match_dup 3))
13619 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13621 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13624 ;; avoid useless masking of bit offset operand
13625 (define_insn_and_split "*jcc_btdi_mask_rex64"
13627 (if_then_else (match_operator 0 "bt_comparison_operator"
13629 (match_operand:DI 1 "register_operand" "r")
13632 (match_operand:SI 2 "register_operand" "r")
13633 (match_operand:SI 3 "const_int_operand" "n")))])
13634 (label_ref (match_operand 4 "" ""))
13636 (clobber (reg:CC FLAGS_REG))]
13637 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13638 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13641 [(set (reg:CCC FLAGS_REG)
13649 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13650 (label_ref (match_dup 4))
13653 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13655 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13658 (define_insn_and_split "*jcc_btsi"
13660 (if_then_else (match_operator 0 "bt_comparison_operator"
13662 (match_operand:SI 1 "register_operand" "r")
13665 (match_operand:QI 2 "register_operand" "r")))
13667 (label_ref (match_operand 3 "" ""))
13669 (clobber (reg:CC FLAGS_REG))]
13670 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13673 [(set (reg:CCC FLAGS_REG)
13681 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13682 (label_ref (match_dup 3))
13685 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13687 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13690 ;; avoid useless masking of bit offset operand
13691 (define_insn_and_split "*jcc_btsi_mask"
13693 (if_then_else (match_operator 0 "bt_comparison_operator"
13695 (match_operand:SI 1 "register_operand" "r")
13698 (match_operand:SI 2 "register_operand" "r")
13699 (match_operand:SI 3 "const_int_operand" "n")))])
13700 (label_ref (match_operand 4 "" ""))
13702 (clobber (reg:CC FLAGS_REG))]
13703 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13704 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13707 [(set (reg:CCC FLAGS_REG)
13715 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13716 (label_ref (match_dup 4))
13718 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13720 (define_insn_and_split "*jcc_btsi_1"
13722 (if_then_else (match_operator 0 "bt_comparison_operator"
13725 (match_operand:SI 1 "register_operand" "r")
13726 (match_operand:QI 2 "register_operand" "r"))
13729 (label_ref (match_operand 3 "" ""))
13731 (clobber (reg:CC FLAGS_REG))]
13732 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13735 [(set (reg:CCC FLAGS_REG)
13743 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13744 (label_ref (match_dup 3))
13747 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13749 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13752 ;; avoid useless masking of bit offset operand
13753 (define_insn_and_split "*jcc_btsi_mask_1"
13756 (match_operator 0 "bt_comparison_operator"
13759 (match_operand:SI 1 "register_operand" "r")
13762 (match_operand:SI 2 "register_operand" "r")
13763 (match_operand:SI 3 "const_int_operand" "n")) 0))
13766 (label_ref (match_operand 4 "" ""))
13768 (clobber (reg:CC FLAGS_REG))]
13769 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13770 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13773 [(set (reg:CCC FLAGS_REG)
13781 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13782 (label_ref (match_dup 4))
13784 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13786 ;; Define combination compare-and-branch fp compare instructions to help
13789 (define_insn "*fp_jcc_3_387"
13791 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13792 [(match_operand 1 "register_operand" "f")
13793 (match_operand 2 "nonimmediate_operand" "fm")])
13794 (label_ref (match_operand 3 "" ""))
13796 (clobber (reg:CCFP FPSR_REG))
13797 (clobber (reg:CCFP FLAGS_REG))
13798 (clobber (match_scratch:HI 4 "=a"))]
13800 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13801 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13802 && SELECT_CC_MODE (GET_CODE (operands[0]),
13803 operands[1], operands[2]) == CCFPmode
13807 (define_insn "*fp_jcc_4_387"
13809 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13810 [(match_operand 1 "register_operand" "f")
13811 (match_operand 2 "nonimmediate_operand" "fm")])
13813 (label_ref (match_operand 3 "" ""))))
13814 (clobber (reg:CCFP FPSR_REG))
13815 (clobber (reg:CCFP FLAGS_REG))
13816 (clobber (match_scratch:HI 4 "=a"))]
13818 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13819 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13820 && SELECT_CC_MODE (GET_CODE (operands[0]),
13821 operands[1], operands[2]) == CCFPmode
13825 (define_insn "*fp_jcc_5_387"
13827 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13828 [(match_operand 1 "register_operand" "f")
13829 (match_operand 2 "register_operand" "f")])
13830 (label_ref (match_operand 3 "" ""))
13832 (clobber (reg:CCFP FPSR_REG))
13833 (clobber (reg:CCFP FLAGS_REG))
13834 (clobber (match_scratch:HI 4 "=a"))]
13835 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13836 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13840 (define_insn "*fp_jcc_6_387"
13842 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13843 [(match_operand 1 "register_operand" "f")
13844 (match_operand 2 "register_operand" "f")])
13846 (label_ref (match_operand 3 "" ""))))
13847 (clobber (reg:CCFP FPSR_REG))
13848 (clobber (reg:CCFP FLAGS_REG))
13849 (clobber (match_scratch:HI 4 "=a"))]
13850 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13851 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13855 (define_insn "*fp_jcc_7_387"
13857 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13858 [(match_operand 1 "register_operand" "f")
13859 (match_operand 2 "const0_operand" "")])
13860 (label_ref (match_operand 3 "" ""))
13862 (clobber (reg:CCFP FPSR_REG))
13863 (clobber (reg:CCFP FLAGS_REG))
13864 (clobber (match_scratch:HI 4 "=a"))]
13865 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13866 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13867 && SELECT_CC_MODE (GET_CODE (operands[0]),
13868 operands[1], operands[2]) == CCFPmode
13872 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13873 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13874 ;; with a precedence over other operators and is always put in the first
13875 ;; place. Swap condition and operands to match ficom instruction.
13877 (define_insn "*fp_jcc_8<mode>_387"
13879 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13880 [(match_operator 1 "float_operator"
13881 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13882 (match_operand 3 "register_operand" "f,f")])
13883 (label_ref (match_operand 4 "" ""))
13885 (clobber (reg:CCFP FPSR_REG))
13886 (clobber (reg:CCFP FLAGS_REG))
13887 (clobber (match_scratch:HI 5 "=a,a"))]
13888 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13889 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13890 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13891 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13897 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13898 [(match_operand 1 "register_operand" "")
13899 (match_operand 2 "nonimmediate_operand" "")])
13900 (match_operand 3 "" "")
13901 (match_operand 4 "" "")))
13902 (clobber (reg:CCFP FPSR_REG))
13903 (clobber (reg:CCFP FLAGS_REG))]
13907 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13908 operands[3], operands[4], NULL_RTX, NULL_RTX);
13914 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13915 [(match_operand 1 "register_operand" "")
13916 (match_operand 2 "general_operand" "")])
13917 (match_operand 3 "" "")
13918 (match_operand 4 "" "")))
13919 (clobber (reg:CCFP FPSR_REG))
13920 (clobber (reg:CCFP FLAGS_REG))
13921 (clobber (match_scratch:HI 5 "=a"))]
13925 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13926 operands[3], operands[4], operands[5], NULL_RTX);
13932 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13933 [(match_operator 1 "float_operator"
13934 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13935 (match_operand 3 "register_operand" "")])
13936 (match_operand 4 "" "")
13937 (match_operand 5 "" "")))
13938 (clobber (reg:CCFP FPSR_REG))
13939 (clobber (reg:CCFP FLAGS_REG))
13940 (clobber (match_scratch:HI 6 "=a"))]
13944 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13945 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13946 operands[3], operands[7],
13947 operands[4], operands[5], operands[6], NULL_RTX);
13951 ;; %%% Kill this when reload knows how to do it.
13954 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13955 [(match_operator 1 "float_operator"
13956 [(match_operand:X87MODEI12 2 "register_operand" "")])
13957 (match_operand 3 "register_operand" "")])
13958 (match_operand 4 "" "")
13959 (match_operand 5 "" "")))
13960 (clobber (reg:CCFP FPSR_REG))
13961 (clobber (reg:CCFP FLAGS_REG))
13962 (clobber (match_scratch:HI 6 "=a"))]
13966 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13967 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13968 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13969 operands[3], operands[7],
13970 operands[4], operands[5], operands[6], operands[2]);
13974 ;; Unconditional and other jump instructions
13976 (define_insn "jump"
13978 (label_ref (match_operand 0 "" "")))]
13981 [(set_attr "type" "ibr")
13982 (set (attr "length")
13983 (if_then_else (and (ge (minus (match_dup 0) (pc))
13985 (lt (minus (match_dup 0) (pc))
13989 (set_attr "modrm" "0")])
13991 (define_expand "indirect_jump"
13992 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13996 (define_insn "*indirect_jump"
13997 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14000 [(set_attr "type" "ibr")
14001 (set_attr "length_immediate" "0")])
14003 (define_expand "tablejump"
14004 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14005 (use (label_ref (match_operand 1 "" "")))])]
14008 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14009 relative. Convert the relative address to an absolute address. */
14013 enum rtx_code code;
14015 /* We can't use @GOTOFF for text labels on VxWorks;
14016 see gotoff_operand. */
14017 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14021 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14023 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14027 op1 = pic_offset_table_rtx;
14032 op0 = pic_offset_table_rtx;
14036 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14041 (define_insn "*tablejump_1"
14042 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14043 (use (label_ref (match_operand 1 "" "")))]
14046 [(set_attr "type" "ibr")
14047 (set_attr "length_immediate" "0")])
14049 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14052 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14053 (set (match_operand:QI 1 "register_operand" "")
14054 (match_operator:QI 2 "ix86_comparison_operator"
14055 [(reg FLAGS_REG) (const_int 0)]))
14056 (set (match_operand 3 "q_regs_operand" "")
14057 (zero_extend (match_dup 1)))]
14058 "(peep2_reg_dead_p (3, operands[1])
14059 || operands_match_p (operands[1], operands[3]))
14060 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14061 [(set (match_dup 4) (match_dup 0))
14062 (set (strict_low_part (match_dup 5))
14065 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14066 operands[5] = gen_lowpart (QImode, operands[3]);
14067 ix86_expand_clear (operands[3]);
14070 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14073 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14074 (set (match_operand:QI 1 "register_operand" "")
14075 (match_operator:QI 2 "ix86_comparison_operator"
14076 [(reg FLAGS_REG) (const_int 0)]))
14077 (parallel [(set (match_operand 3 "q_regs_operand" "")
14078 (zero_extend (match_dup 1)))
14079 (clobber (reg:CC FLAGS_REG))])]
14080 "(peep2_reg_dead_p (3, operands[1])
14081 || operands_match_p (operands[1], operands[3]))
14082 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14083 [(set (match_dup 4) (match_dup 0))
14084 (set (strict_low_part (match_dup 5))
14087 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14088 operands[5] = gen_lowpart (QImode, operands[3]);
14089 ix86_expand_clear (operands[3]);
14092 ;; Call instructions.
14094 ;; The predicates normally associated with named expanders are not properly
14095 ;; checked for calls. This is a bug in the generic code, but it isn't that
14096 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14098 ;; P6 processors will jump to the address after the decrement when %esp
14099 ;; is used as a call operand, so they will execute return address as a code.
14100 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
14102 ;; Call subroutine returning no value.
14104 (define_expand "call_pop"
14105 [(parallel [(call (match_operand:QI 0 "" "")
14106 (match_operand:SI 1 "" ""))
14107 (set (reg:SI SP_REG)
14108 (plus:SI (reg:SI SP_REG)
14109 (match_operand:SI 3 "" "")))])]
14112 ix86_expand_call (NULL, operands[0], operands[1],
14113 operands[2], operands[3], 0);
14117 (define_insn "*call_pop_0"
14118 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14119 (match_operand:SI 1 "" ""))
14120 (set (reg:SI SP_REG)
14121 (plus:SI (reg:SI SP_REG)
14122 (match_operand:SI 2 "immediate_operand" "")))]
14125 if (SIBLING_CALL_P (insn))
14128 return "call\t%P0";
14130 [(set_attr "type" "call")])
14132 (define_insn "*call_pop_1"
14133 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14134 (match_operand:SI 1 "" ""))
14135 (set (reg:SI SP_REG)
14136 (plus:SI (reg:SI SP_REG)
14137 (match_operand:SI 2 "immediate_operand" "i")))]
14138 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14140 if (constant_call_address_operand (operands[0], Pmode))
14141 return "call\t%P0";
14142 return "call\t%A0";
14144 [(set_attr "type" "call")])
14146 (define_insn "*sibcall_pop_1"
14147 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14148 (match_operand:SI 1 "" ""))
14149 (set (reg:SI SP_REG)
14150 (plus:SI (reg:SI SP_REG)
14151 (match_operand:SI 2 "immediate_operand" "i,i")))]
14152 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14156 [(set_attr "type" "call")])
14158 (define_expand "call"
14159 [(call (match_operand:QI 0 "" "")
14160 (match_operand 1 "" ""))
14161 (use (match_operand 2 "" ""))]
14164 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14168 (define_expand "sibcall"
14169 [(call (match_operand:QI 0 "" "")
14170 (match_operand 1 "" ""))
14171 (use (match_operand 2 "" ""))]
14174 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14178 (define_insn "*call_0"
14179 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14180 (match_operand 1 "" ""))]
14183 if (SIBLING_CALL_P (insn))
14186 return "call\t%P0";
14188 [(set_attr "type" "call")])
14190 (define_insn "*call_1"
14191 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14192 (match_operand 1 "" ""))]
14193 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14195 if (constant_call_address_operand (operands[0], Pmode))
14196 return "call\t%P0";
14197 return "call\t%A0";
14199 [(set_attr "type" "call")])
14201 (define_insn "*sibcall_1"
14202 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14203 (match_operand 1 "" ""))]
14204 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14208 [(set_attr "type" "call")])
14210 (define_insn "*call_1_rex64"
14211 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14212 (match_operand 1 "" ""))]
14213 "TARGET_64BIT && !SIBLING_CALL_P (insn)
14214 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14216 if (constant_call_address_operand (operands[0], Pmode))
14217 return "call\t%P0";
14218 return "call\t%A0";
14220 [(set_attr "type" "call")])
14222 (define_insn "*call_1_rex64_ms_sysv"
14223 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14224 (match_operand 1 "" ""))
14225 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
14226 (clobber (reg:TI XMM6_REG))
14227 (clobber (reg:TI XMM7_REG))
14228 (clobber (reg:TI XMM8_REG))
14229 (clobber (reg:TI XMM9_REG))
14230 (clobber (reg:TI XMM10_REG))
14231 (clobber (reg:TI XMM11_REG))
14232 (clobber (reg:TI XMM12_REG))
14233 (clobber (reg:TI XMM13_REG))
14234 (clobber (reg:TI XMM14_REG))
14235 (clobber (reg:TI XMM15_REG))
14236 (clobber (reg:DI SI_REG))
14237 (clobber (reg:DI DI_REG))]
14238 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14240 if (constant_call_address_operand (operands[0], Pmode))
14241 return "call\t%P0";
14242 return "call\t%A0";
14244 [(set_attr "type" "call")])
14246 (define_insn "*call_1_rex64_large"
14247 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14248 (match_operand 1 "" ""))]
14249 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14251 [(set_attr "type" "call")])
14253 (define_insn "*sibcall_1_rex64"
14254 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
14255 (match_operand 1 "" ""))]
14256 "TARGET_64BIT && SIBLING_CALL_P (insn)"
14260 [(set_attr "type" "call")])
14262 ;; Call subroutine, returning value in operand 0
14263 (define_expand "call_value_pop"
14264 [(parallel [(set (match_operand 0 "" "")
14265 (call (match_operand:QI 1 "" "")
14266 (match_operand:SI 2 "" "")))
14267 (set (reg:SI SP_REG)
14268 (plus:SI (reg:SI SP_REG)
14269 (match_operand:SI 4 "" "")))])]
14272 ix86_expand_call (operands[0], operands[1], operands[2],
14273 operands[3], operands[4], 0);
14277 (define_expand "call_value"
14278 [(set (match_operand 0 "" "")
14279 (call (match_operand:QI 1 "" "")
14280 (match_operand:SI 2 "" "")))
14281 (use (match_operand:SI 3 "" ""))]
14282 ;; Operand 3 is not used on the i386.
14285 ix86_expand_call (operands[0], operands[1], operands[2],
14286 operands[3], NULL, 0);
14290 (define_expand "sibcall_value"
14291 [(set (match_operand 0 "" "")
14292 (call (match_operand:QI 1 "" "")
14293 (match_operand:SI 2 "" "")))
14294 (use (match_operand:SI 3 "" ""))]
14295 ;; Operand 3 is not used on the i386.
14298 ix86_expand_call (operands[0], operands[1], operands[2],
14299 operands[3], NULL, 1);
14303 ;; Call subroutine returning any type.
14305 (define_expand "untyped_call"
14306 [(parallel [(call (match_operand 0 "" "")
14308 (match_operand 1 "" "")
14309 (match_operand 2 "" "")])]
14314 /* In order to give reg-stack an easier job in validating two
14315 coprocessor registers as containing a possible return value,
14316 simply pretend the untyped call returns a complex long double
14319 We can't use SSE_REGPARM_MAX here since callee is unprototyped
14320 and should have the default ABI. */
14322 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14323 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14324 operands[0], const0_rtx,
14325 GEN_INT ((TARGET_64BIT
14326 ? (ix86_abi == SYSV_ABI
14327 ? X86_64_SSE_REGPARM_MAX
14328 : X86_64_MS_SSE_REGPARM_MAX)
14329 : X86_32_SSE_REGPARM_MAX)
14333 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14335 rtx set = XVECEXP (operands[2], 0, i);
14336 emit_move_insn (SET_DEST (set), SET_SRC (set));
14339 /* The optimizer does not know that the call sets the function value
14340 registers we stored in the result block. We avoid problems by
14341 claiming that all hard registers are used and clobbered at this
14343 emit_insn (gen_blockage ());
14348 ;; Prologue and epilogue instructions
14350 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14351 ;; all of memory. This blocks insns from being moved across this point.
14353 (define_insn "blockage"
14354 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14357 [(set_attr "length" "0")])
14359 ;; Do not schedule instructions accessing memory across this point.
14361 (define_expand "memory_blockage"
14362 [(set (match_dup 0)
14363 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14366 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14367 MEM_VOLATILE_P (operands[0]) = 1;
14370 (define_insn "*memory_blockage"
14371 [(set (match_operand:BLK 0 "" "")
14372 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14375 [(set_attr "length" "0")])
14377 ;; As USE insns aren't meaningful after reload, this is used instead
14378 ;; to prevent deleting instructions setting registers for PIC code
14379 (define_insn "prologue_use"
14380 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14383 [(set_attr "length" "0")])
14385 ;; Insn emitted into the body of a function to return from a function.
14386 ;; This is only done if the function's epilogue is known to be simple.
14387 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14389 (define_expand "return"
14391 "ix86_can_use_return_insn_p ()"
14393 if (crtl->args.pops_args)
14395 rtx popc = GEN_INT (crtl->args.pops_args);
14396 emit_jump_insn (gen_return_pop_internal (popc));
14401 (define_insn "return_internal"
14405 [(set_attr "length" "1")
14406 (set_attr "atom_unit" "jeu")
14407 (set_attr "length_immediate" "0")
14408 (set_attr "modrm" "0")])
14410 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14411 ;; instruction Athlon and K8 have.
14413 (define_insn "return_internal_long"
14415 (unspec [(const_int 0)] UNSPEC_REP)]
14418 [(set_attr "length" "2")
14419 (set_attr "atom_unit" "jeu")
14420 (set_attr "length_immediate" "0")
14421 (set_attr "prefix_rep" "1")
14422 (set_attr "modrm" "0")])
14424 (define_insn "return_pop_internal"
14426 (use (match_operand:SI 0 "const_int_operand" ""))]
14429 [(set_attr "length" "3")
14430 (set_attr "atom_unit" "jeu")
14431 (set_attr "length_immediate" "2")
14432 (set_attr "modrm" "0")])
14434 (define_insn "return_indirect_internal"
14436 (use (match_operand:SI 0 "register_operand" "r"))]
14439 [(set_attr "type" "ibr")
14440 (set_attr "length_immediate" "0")])
14446 [(set_attr "length" "1")
14447 (set_attr "length_immediate" "0")
14448 (set_attr "modrm" "0")])
14450 (define_insn "vswapmov"
14451 [(set (match_operand:SI 0 "register_operand" "=r")
14452 (match_operand:SI 1 "register_operand" "r"))
14453 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
14455 "movl.s\t{%1, %0|%0, %1}"
14456 [(set_attr "length" "2")
14457 (set_attr "length_immediate" "0")
14458 (set_attr "modrm" "0")])
14460 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
14461 ;; branch prediction penalty for the third jump in a 16-byte
14465 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14468 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
14469 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
14471 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14472 The align insn is used to avoid 3 jump instructions in the row to improve
14473 branch prediction and the benefits hardly outweigh the cost of extra 8
14474 nops on the average inserted by full alignment pseudo operation. */
14478 [(set_attr "length" "16")])
14480 (define_expand "prologue"
14483 "ix86_expand_prologue (); DONE;")
14485 (define_insn "set_got"
14486 [(set (match_operand:SI 0 "register_operand" "=r")
14487 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14488 (clobber (reg:CC FLAGS_REG))]
14490 { return output_set_got (operands[0], NULL_RTX); }
14491 [(set_attr "type" "multi")
14492 (set_attr "length" "12")])
14494 (define_insn "set_got_labelled"
14495 [(set (match_operand:SI 0 "register_operand" "=r")
14496 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14498 (clobber (reg:CC FLAGS_REG))]
14500 { return output_set_got (operands[0], operands[1]); }
14501 [(set_attr "type" "multi")
14502 (set_attr "length" "12")])
14504 (define_insn "set_got_rex64"
14505 [(set (match_operand:DI 0 "register_operand" "=r")
14506 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14508 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14509 [(set_attr "type" "lea")
14510 (set_attr "length_address" "4")
14511 (set_attr "mode" "DI")])
14513 (define_insn "set_rip_rex64"
14514 [(set (match_operand:DI 0 "register_operand" "=r")
14515 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
14517 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14518 [(set_attr "type" "lea")
14519 (set_attr "length_address" "4")
14520 (set_attr "mode" "DI")])
14522 (define_insn "set_got_offset_rex64"
14523 [(set (match_operand:DI 0 "register_operand" "=r")
14525 [(label_ref (match_operand 1 "" ""))]
14526 UNSPEC_SET_GOT_OFFSET))]
14528 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14529 [(set_attr "type" "imov")
14530 (set_attr "length_immediate" "0")
14531 (set_attr "length_address" "8")
14532 (set_attr "mode" "DI")])
14534 (define_expand "epilogue"
14537 "ix86_expand_epilogue (1); DONE;")
14539 (define_expand "sibcall_epilogue"
14542 "ix86_expand_epilogue (0); DONE;")
14544 (define_expand "eh_return"
14545 [(use (match_operand 0 "register_operand" ""))]
14548 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14550 /* Tricky bit: we write the address of the handler to which we will
14551 be returning into someone else's stack frame, one word below the
14552 stack address we wish to restore. */
14553 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14554 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14555 tmp = gen_rtx_MEM (Pmode, tmp);
14556 emit_move_insn (tmp, ra);
14558 emit_jump_insn (gen_eh_return_internal ());
14563 (define_insn_and_split "eh_return_internal"
14567 "epilogue_completed"
14569 "ix86_expand_epilogue (2); DONE;")
14571 (define_insn "leave"
14572 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14573 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14574 (clobber (mem:BLK (scratch)))]
14577 [(set_attr "type" "leave")])
14579 (define_insn "leave_rex64"
14580 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14581 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14582 (clobber (mem:BLK (scratch)))]
14585 [(set_attr "type" "leave")])
14587 (define_expand "ffssi2"
14589 [(set (match_operand:SI 0 "register_operand" "")
14590 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14591 (clobber (match_scratch:SI 2 ""))
14592 (clobber (reg:CC FLAGS_REG))])]
14597 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14602 (define_expand "ffs_cmove"
14603 [(set (match_dup 2) (const_int -1))
14604 (parallel [(set (reg:CCZ FLAGS_REG)
14605 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14607 (set (match_operand:SI 0 "register_operand" "")
14608 (ctz:SI (match_dup 1)))])
14609 (set (match_dup 0) (if_then_else:SI
14610 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14613 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14614 (clobber (reg:CC FLAGS_REG))])]
14616 "operands[2] = gen_reg_rtx (SImode);")
14618 (define_insn_and_split "*ffs_no_cmove"
14619 [(set (match_operand:SI 0 "register_operand" "=r")
14620 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14621 (clobber (match_scratch:SI 2 "=&q"))
14622 (clobber (reg:CC FLAGS_REG))]
14625 "&& reload_completed"
14626 [(parallel [(set (reg:CCZ FLAGS_REG)
14627 (compare:CCZ (match_dup 1) (const_int 0)))
14628 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14629 (set (strict_low_part (match_dup 3))
14630 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14631 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14632 (clobber (reg:CC FLAGS_REG))])
14633 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14634 (clobber (reg:CC FLAGS_REG))])
14635 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14636 (clobber (reg:CC FLAGS_REG))])]
14638 operands[3] = gen_lowpart (QImode, operands[2]);
14639 ix86_expand_clear (operands[2]);
14642 (define_insn "*ffssi_1"
14643 [(set (reg:CCZ FLAGS_REG)
14644 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14646 (set (match_operand:SI 0 "register_operand" "=r")
14647 (ctz:SI (match_dup 1)))]
14649 "bsf{l}\t{%1, %0|%0, %1}"
14650 [(set_attr "type" "alu1")
14651 (set_attr "prefix_0f" "1")
14652 (set_attr "mode" "SI")])
14654 (define_expand "ffsdi2"
14655 [(set (match_dup 2) (const_int -1))
14656 (parallel [(set (reg:CCZ FLAGS_REG)
14657 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14659 (set (match_operand:DI 0 "register_operand" "")
14660 (ctz:DI (match_dup 1)))])
14661 (set (match_dup 0) (if_then_else:DI
14662 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14665 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14666 (clobber (reg:CC FLAGS_REG))])]
14668 "operands[2] = gen_reg_rtx (DImode);")
14670 (define_insn "*ffsdi_1"
14671 [(set (reg:CCZ FLAGS_REG)
14672 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14674 (set (match_operand:DI 0 "register_operand" "=r")
14675 (ctz:DI (match_dup 1)))]
14677 "bsf{q}\t{%1, %0|%0, %1}"
14678 [(set_attr "type" "alu1")
14679 (set_attr "prefix_0f" "1")
14680 (set_attr "mode" "DI")])
14682 (define_insn "ctzsi2"
14683 [(set (match_operand:SI 0 "register_operand" "=r")
14684 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14685 (clobber (reg:CC FLAGS_REG))]
14687 "bsf{l}\t{%1, %0|%0, %1}"
14688 [(set_attr "type" "alu1")
14689 (set_attr "prefix_0f" "1")
14690 (set_attr "mode" "SI")])
14692 (define_insn "ctzdi2"
14693 [(set (match_operand:DI 0 "register_operand" "=r")
14694 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14695 (clobber (reg:CC FLAGS_REG))]
14697 "bsf{q}\t{%1, %0|%0, %1}"
14698 [(set_attr "type" "alu1")
14699 (set_attr "prefix_0f" "1")
14700 (set_attr "mode" "DI")])
14702 (define_expand "clzsi2"
14704 [(set (match_operand:SI 0 "register_operand" "")
14705 (minus:SI (const_int 31)
14706 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14707 (clobber (reg:CC FLAGS_REG))])
14709 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14710 (clobber (reg:CC FLAGS_REG))])]
14715 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14720 (define_insn "clzsi2_abm"
14721 [(set (match_operand:SI 0 "register_operand" "=r")
14722 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14723 (clobber (reg:CC FLAGS_REG))]
14725 "lzcnt{l}\t{%1, %0|%0, %1}"
14726 [(set_attr "prefix_rep" "1")
14727 (set_attr "type" "bitmanip")
14728 (set_attr "mode" "SI")])
14731 [(set (match_operand:SI 0 "register_operand" "=r")
14732 (minus:SI (const_int 31)
14733 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14734 (clobber (reg:CC FLAGS_REG))]
14736 "bsr{l}\t{%1, %0|%0, %1}"
14737 [(set_attr "type" "alu1")
14738 (set_attr "prefix_0f" "1")
14739 (set_attr "mode" "SI")])
14741 (define_insn "popcount<mode>2"
14742 [(set (match_operand:SWI248 0 "register_operand" "=r")
14744 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14745 (clobber (reg:CC FLAGS_REG))]
14749 return "popcnt\t{%1, %0|%0, %1}";
14751 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14754 [(set_attr "prefix_rep" "1")
14755 (set_attr "type" "bitmanip")
14756 (set_attr "mode" "<MODE>")])
14758 (define_insn "*popcount<mode>2_cmp"
14759 [(set (reg FLAGS_REG)
14762 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14764 (set (match_operand:SWI248 0 "register_operand" "=r")
14765 (popcount:SWI248 (match_dup 1)))]
14766 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14769 return "popcnt\t{%1, %0|%0, %1}";
14771 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14774 [(set_attr "prefix_rep" "1")
14775 (set_attr "type" "bitmanip")
14776 (set_attr "mode" "<MODE>")])
14778 (define_insn "*popcountsi2_cmp_zext"
14779 [(set (reg FLAGS_REG)
14781 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14783 (set (match_operand:DI 0 "register_operand" "=r")
14784 (zero_extend:DI(popcount:SI (match_dup 1))))]
14785 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14788 return "popcnt\t{%1, %0|%0, %1}";
14790 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14793 [(set_attr "prefix_rep" "1")
14794 (set_attr "type" "bitmanip")
14795 (set_attr "mode" "SI")])
14797 (define_expand "bswapsi2"
14798 [(set (match_operand:SI 0 "register_operand" "")
14799 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14802 if (!(TARGET_BSWAP || TARGET_MOVBE))
14804 rtx x = operands[0];
14806 emit_move_insn (x, operands[1]);
14807 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14808 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14809 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14814 (define_insn "*bswapsi_movbe"
14815 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14816 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14817 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14820 movbe\t{%1, %0|%0, %1}
14821 movbe\t{%1, %0|%0, %1}"
14822 [(set_attr "type" "*,imov,imov")
14823 (set_attr "modrm" "*,1,1")
14824 (set_attr "prefix_0f" "1")
14825 (set_attr "prefix_extra" "*,1,1")
14826 (set_attr "length" "2,*,*")
14827 (set_attr "mode" "SI")])
14829 (define_insn "*bswapsi_1"
14830 [(set (match_operand:SI 0 "register_operand" "=r")
14831 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14834 [(set_attr "prefix_0f" "1")
14835 (set_attr "length" "2")])
14837 (define_insn "*bswaphi_lowpart_1"
14838 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14839 (bswap:HI (match_dup 0)))
14840 (clobber (reg:CC FLAGS_REG))]
14841 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14843 xchg{b}\t{%h0, %b0|%b0, %h0}
14844 rol{w}\t{$8, %0|%0, 8}"
14845 [(set_attr "length" "2,4")
14846 (set_attr "mode" "QI,HI")])
14848 (define_insn "bswaphi_lowpart"
14849 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14850 (bswap:HI (match_dup 0)))
14851 (clobber (reg:CC FLAGS_REG))]
14853 "rol{w}\t{$8, %0|%0, 8}"
14854 [(set_attr "length" "4")
14855 (set_attr "mode" "HI")])
14857 (define_expand "bswapdi2"
14858 [(set (match_operand:DI 0 "register_operand" "")
14859 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14863 (define_insn "*bswapdi_movbe"
14864 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14865 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14866 "TARGET_64BIT && TARGET_MOVBE
14867 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14870 movbe\t{%1, %0|%0, %1}
14871 movbe\t{%1, %0|%0, %1}"
14872 [(set_attr "type" "*,imov,imov")
14873 (set_attr "modrm" "*,1,1")
14874 (set_attr "prefix_0f" "1")
14875 (set_attr "prefix_extra" "*,1,1")
14876 (set_attr "length" "3,*,*")
14877 (set_attr "mode" "DI")])
14879 (define_insn "*bswapdi_1"
14880 [(set (match_operand:DI 0 "register_operand" "=r")
14881 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14884 [(set_attr "prefix_0f" "1")
14885 (set_attr "length" "3")])
14887 (define_expand "clzdi2"
14889 [(set (match_operand:DI 0 "register_operand" "")
14890 (minus:DI (const_int 63)
14891 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14892 (clobber (reg:CC FLAGS_REG))])
14894 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14895 (clobber (reg:CC FLAGS_REG))])]
14900 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14905 (define_insn "clzdi2_abm"
14906 [(set (match_operand:DI 0 "register_operand" "=r")
14907 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14908 (clobber (reg:CC FLAGS_REG))]
14909 "TARGET_64BIT && TARGET_ABM"
14910 "lzcnt{q}\t{%1, %0|%0, %1}"
14911 [(set_attr "prefix_rep" "1")
14912 (set_attr "type" "bitmanip")
14913 (set_attr "mode" "DI")])
14915 (define_insn "bsr_rex64"
14916 [(set (match_operand:DI 0 "register_operand" "=r")
14917 (minus:DI (const_int 63)
14918 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14919 (clobber (reg:CC FLAGS_REG))]
14921 "bsr{q}\t{%1, %0|%0, %1}"
14922 [(set_attr "type" "alu1")
14923 (set_attr "prefix_0f" "1")
14924 (set_attr "mode" "DI")])
14926 (define_expand "clzhi2"
14928 [(set (match_operand:HI 0 "register_operand" "")
14929 (minus:HI (const_int 15)
14930 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14931 (clobber (reg:CC FLAGS_REG))])
14933 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14934 (clobber (reg:CC FLAGS_REG))])]
14939 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14944 (define_insn "clzhi2_abm"
14945 [(set (match_operand:HI 0 "register_operand" "=r")
14946 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14947 (clobber (reg:CC FLAGS_REG))]
14949 "lzcnt{w}\t{%1, %0|%0, %1}"
14950 [(set_attr "prefix_rep" "1")
14951 (set_attr "type" "bitmanip")
14952 (set_attr "mode" "HI")])
14954 (define_insn "*bsrhi"
14955 [(set (match_operand:HI 0 "register_operand" "=r")
14956 (minus:HI (const_int 15)
14957 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14958 (clobber (reg:CC FLAGS_REG))]
14960 "bsr{w}\t{%1, %0|%0, %1}"
14961 [(set_attr "type" "alu1")
14962 (set_attr "prefix_0f" "1")
14963 (set_attr "mode" "HI")])
14965 (define_expand "paritydi2"
14966 [(set (match_operand:DI 0 "register_operand" "")
14967 (parity:DI (match_operand:DI 1 "register_operand" "")))]
14970 rtx scratch = gen_reg_rtx (QImode);
14973 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14974 NULL_RTX, operands[1]));
14976 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14977 gen_rtx_REG (CCmode, FLAGS_REG),
14979 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14982 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14985 rtx tmp = gen_reg_rtx (SImode);
14987 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14988 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14993 (define_insn_and_split "paritydi2_cmp"
14994 [(set (reg:CC FLAGS_REG)
14995 (parity:CC (match_operand:DI 3 "register_operand" "0")))
14996 (clobber (match_scratch:DI 0 "=r"))
14997 (clobber (match_scratch:SI 1 "=&r"))
14998 (clobber (match_scratch:HI 2 "=Q"))]
15001 "&& reload_completed"
15003 [(set (match_dup 1)
15004 (xor:SI (match_dup 1) (match_dup 4)))
15005 (clobber (reg:CC FLAGS_REG))])
15007 [(set (reg:CC FLAGS_REG)
15008 (parity:CC (match_dup 1)))
15009 (clobber (match_dup 1))
15010 (clobber (match_dup 2))])]
15012 operands[4] = gen_lowpart (SImode, operands[3]);
15016 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15017 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15020 operands[1] = gen_highpart (SImode, operands[3]);
15023 (define_expand "paritysi2"
15024 [(set (match_operand:SI 0 "register_operand" "")
15025 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15028 rtx scratch = gen_reg_rtx (QImode);
15031 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15033 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15034 gen_rtx_REG (CCmode, FLAGS_REG),
15036 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15038 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15042 (define_insn_and_split "paritysi2_cmp"
15043 [(set (reg:CC FLAGS_REG)
15044 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15045 (clobber (match_scratch:SI 0 "=r"))
15046 (clobber (match_scratch:HI 1 "=&Q"))]
15049 "&& reload_completed"
15051 [(set (match_dup 1)
15052 (xor:HI (match_dup 1) (match_dup 3)))
15053 (clobber (reg:CC FLAGS_REG))])
15055 [(set (reg:CC FLAGS_REG)
15056 (parity:CC (match_dup 1)))
15057 (clobber (match_dup 1))])]
15059 operands[3] = gen_lowpart (HImode, operands[2]);
15061 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15062 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15065 (define_insn "*parityhi2_cmp"
15066 [(set (reg:CC FLAGS_REG)
15067 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15068 (clobber (match_scratch:HI 0 "=Q"))]
15070 "xor{b}\t{%h0, %b0|%b0, %h0}"
15071 [(set_attr "length" "2")
15072 (set_attr "mode" "HI")])
15074 (define_insn "*parityqi2_cmp"
15075 [(set (reg:CC FLAGS_REG)
15076 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15079 [(set_attr "length" "2")
15080 (set_attr "mode" "QI")])
15082 ;; Thread-local storage patterns for ELF.
15084 ;; Note that these code sequences must appear exactly as shown
15085 ;; in order to allow linker relaxation.
15087 (define_insn "*tls_global_dynamic_32_gnu"
15088 [(set (match_operand:SI 0 "register_operand" "=a")
15089 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15090 (match_operand:SI 2 "tls_symbolic_operand" "")
15091 (match_operand:SI 3 "call_insn_operand" "")]
15093 (clobber (match_scratch:SI 4 "=d"))
15094 (clobber (match_scratch:SI 5 "=c"))
15095 (clobber (reg:CC FLAGS_REG))]
15096 "!TARGET_64BIT && TARGET_GNU_TLS"
15097 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15098 [(set_attr "type" "multi")
15099 (set_attr "length" "12")])
15101 (define_insn "*tls_global_dynamic_32_sun"
15102 [(set (match_operand:SI 0 "register_operand" "=a")
15103 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15104 (match_operand:SI 2 "tls_symbolic_operand" "")
15105 (match_operand:SI 3 "call_insn_operand" "")]
15107 (clobber (match_scratch:SI 4 "=d"))
15108 (clobber (match_scratch:SI 5 "=c"))
15109 (clobber (reg:CC FLAGS_REG))]
15110 "!TARGET_64BIT && TARGET_SUN_TLS"
15111 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15112 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15113 [(set_attr "type" "multi")
15114 (set_attr "length" "14")])
15116 (define_expand "tls_global_dynamic_32"
15117 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15120 (match_operand:SI 1 "tls_symbolic_operand" "")
15123 (clobber (match_scratch:SI 4 ""))
15124 (clobber (match_scratch:SI 5 ""))
15125 (clobber (reg:CC FLAGS_REG))])]
15129 operands[2] = pic_offset_table_rtx;
15132 operands[2] = gen_reg_rtx (Pmode);
15133 emit_insn (gen_set_got (operands[2]));
15135 if (TARGET_GNU2_TLS)
15137 emit_insn (gen_tls_dynamic_gnu2_32
15138 (operands[0], operands[1], operands[2]));
15141 operands[3] = ix86_tls_get_addr ();
15144 (define_insn "*tls_global_dynamic_64"
15145 [(set (match_operand:DI 0 "register_operand" "=a")
15146 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15147 (match_operand:DI 3 "" "")))
15148 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15151 { return ASM_BYTE "0x66\n\tlea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\n" ASM_SHORT "0x6666\n\trex64\n\tcall\t%P2"; }
15152 [(set_attr "type" "multi")
15153 (set_attr "length" "16")])
15155 (define_expand "tls_global_dynamic_64"
15156 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15157 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15158 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15162 if (TARGET_GNU2_TLS)
15164 emit_insn (gen_tls_dynamic_gnu2_64
15165 (operands[0], operands[1]));
15168 operands[2] = ix86_tls_get_addr ();
15171 (define_insn "*tls_local_dynamic_base_32_gnu"
15172 [(set (match_operand:SI 0 "register_operand" "=a")
15173 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15174 (match_operand:SI 2 "call_insn_operand" "")]
15175 UNSPEC_TLS_LD_BASE))
15176 (clobber (match_scratch:SI 3 "=d"))
15177 (clobber (match_scratch:SI 4 "=c"))
15178 (clobber (reg:CC FLAGS_REG))]
15179 "!TARGET_64BIT && TARGET_GNU_TLS"
15180 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15181 [(set_attr "type" "multi")
15182 (set_attr "length" "11")])
15184 (define_insn "*tls_local_dynamic_base_32_sun"
15185 [(set (match_operand:SI 0 "register_operand" "=a")
15186 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15187 (match_operand:SI 2 "call_insn_operand" "")]
15188 UNSPEC_TLS_LD_BASE))
15189 (clobber (match_scratch:SI 3 "=d"))
15190 (clobber (match_scratch:SI 4 "=c"))
15191 (clobber (reg:CC FLAGS_REG))]
15192 "!TARGET_64BIT && TARGET_SUN_TLS"
15193 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15194 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15195 [(set_attr "type" "multi")
15196 (set_attr "length" "13")])
15198 (define_expand "tls_local_dynamic_base_32"
15199 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15200 (unspec:SI [(match_dup 1) (match_dup 2)]
15201 UNSPEC_TLS_LD_BASE))
15202 (clobber (match_scratch:SI 3 ""))
15203 (clobber (match_scratch:SI 4 ""))
15204 (clobber (reg:CC FLAGS_REG))])]
15208 operands[1] = pic_offset_table_rtx;
15211 operands[1] = gen_reg_rtx (Pmode);
15212 emit_insn (gen_set_got (operands[1]));
15214 if (TARGET_GNU2_TLS)
15216 emit_insn (gen_tls_dynamic_gnu2_32
15217 (operands[0], ix86_tls_module_base (), operands[1]));
15220 operands[2] = ix86_tls_get_addr ();
15223 (define_insn "*tls_local_dynamic_base_64"
15224 [(set (match_operand:DI 0 "register_operand" "=a")
15225 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15226 (match_operand:DI 2 "" "")))
15227 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15229 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15230 [(set_attr "type" "multi")
15231 (set_attr "length" "12")])
15233 (define_expand "tls_local_dynamic_base_64"
15234 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15235 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15236 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15239 if (TARGET_GNU2_TLS)
15241 emit_insn (gen_tls_dynamic_gnu2_64
15242 (operands[0], ix86_tls_module_base ()));
15245 operands[1] = ix86_tls_get_addr ();
15248 ;; Local dynamic of a single variable is a lose. Show combine how
15249 ;; to convert that back to global dynamic.
15251 (define_insn_and_split "*tls_local_dynamic_32_once"
15252 [(set (match_operand:SI 0 "register_operand" "=a")
15253 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15254 (match_operand:SI 2 "call_insn_operand" "")]
15255 UNSPEC_TLS_LD_BASE)
15256 (const:SI (unspec:SI
15257 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15259 (clobber (match_scratch:SI 4 "=d"))
15260 (clobber (match_scratch:SI 5 "=c"))
15261 (clobber (reg:CC FLAGS_REG))]
15265 [(parallel [(set (match_dup 0)
15266 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15268 (clobber (match_dup 4))
15269 (clobber (match_dup 5))
15270 (clobber (reg:CC FLAGS_REG))])]
15273 ;; Load and add the thread base pointer from %gs:0.
15275 (define_insn "*load_tp_si"
15276 [(set (match_operand:SI 0 "register_operand" "=r")
15277 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15279 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15280 [(set_attr "type" "imov")
15281 (set_attr "modrm" "0")
15282 (set_attr "length" "7")
15283 (set_attr "memory" "load")
15284 (set_attr "imm_disp" "false")])
15286 (define_insn "*add_tp_si"
15287 [(set (match_operand:SI 0 "register_operand" "=r")
15288 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15289 (match_operand:SI 1 "register_operand" "0")))
15290 (clobber (reg:CC FLAGS_REG))]
15292 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15293 [(set_attr "type" "alu")
15294 (set_attr "modrm" "0")
15295 (set_attr "length" "7")
15296 (set_attr "memory" "load")
15297 (set_attr "imm_disp" "false")])
15299 (define_insn "*load_tp_di"
15300 [(set (match_operand:DI 0 "register_operand" "=r")
15301 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15303 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15304 [(set_attr "type" "imov")
15305 (set_attr "modrm" "0")
15306 (set_attr "length" "7")
15307 (set_attr "memory" "load")
15308 (set_attr "imm_disp" "false")])
15310 (define_insn "*add_tp_di"
15311 [(set (match_operand:DI 0 "register_operand" "=r")
15312 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15313 (match_operand:DI 1 "register_operand" "0")))
15314 (clobber (reg:CC FLAGS_REG))]
15316 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15317 [(set_attr "type" "alu")
15318 (set_attr "modrm" "0")
15319 (set_attr "length" "7")
15320 (set_attr "memory" "load")
15321 (set_attr "imm_disp" "false")])
15323 ;; GNU2 TLS patterns can be split.
15325 (define_expand "tls_dynamic_gnu2_32"
15326 [(set (match_dup 3)
15327 (plus:SI (match_operand:SI 2 "register_operand" "")
15329 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15332 [(set (match_operand:SI 0 "register_operand" "")
15333 (unspec:SI [(match_dup 1) (match_dup 3)
15334 (match_dup 2) (reg:SI SP_REG)]
15336 (clobber (reg:CC FLAGS_REG))])]
15337 "!TARGET_64BIT && TARGET_GNU2_TLS"
15339 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15340 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15343 (define_insn "*tls_dynamic_lea_32"
15344 [(set (match_operand:SI 0 "register_operand" "=r")
15345 (plus:SI (match_operand:SI 1 "register_operand" "b")
15347 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15348 UNSPEC_TLSDESC))))]
15349 "!TARGET_64BIT && TARGET_GNU2_TLS"
15350 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15351 [(set_attr "type" "lea")
15352 (set_attr "mode" "SI")
15353 (set_attr "length" "6")
15354 (set_attr "length_address" "4")])
15356 (define_insn "*tls_dynamic_call_32"
15357 [(set (match_operand:SI 0 "register_operand" "=a")
15358 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15359 (match_operand:SI 2 "register_operand" "0")
15360 ;; we have to make sure %ebx still points to the GOT
15361 (match_operand:SI 3 "register_operand" "b")
15364 (clobber (reg:CC FLAGS_REG))]
15365 "!TARGET_64BIT && TARGET_GNU2_TLS"
15366 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15367 [(set_attr "type" "call")
15368 (set_attr "length" "2")
15369 (set_attr "length_address" "0")])
15371 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15372 [(set (match_operand:SI 0 "register_operand" "=&a")
15374 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15375 (match_operand:SI 4 "" "")
15376 (match_operand:SI 2 "register_operand" "b")
15379 (const:SI (unspec:SI
15380 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15382 (clobber (reg:CC FLAGS_REG))]
15383 "!TARGET_64BIT && TARGET_GNU2_TLS"
15386 [(set (match_dup 0) (match_dup 5))]
15388 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15389 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15392 (define_expand "tls_dynamic_gnu2_64"
15393 [(set (match_dup 2)
15394 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15397 [(set (match_operand:DI 0 "register_operand" "")
15398 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15400 (clobber (reg:CC FLAGS_REG))])]
15401 "TARGET_64BIT && TARGET_GNU2_TLS"
15403 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15404 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15407 (define_insn "*tls_dynamic_lea_64"
15408 [(set (match_operand:DI 0 "register_operand" "=r")
15409 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15411 "TARGET_64BIT && TARGET_GNU2_TLS"
15412 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15413 [(set_attr "type" "lea")
15414 (set_attr "mode" "DI")
15415 (set_attr "length" "7")
15416 (set_attr "length_address" "4")])
15418 (define_insn "*tls_dynamic_call_64"
15419 [(set (match_operand:DI 0 "register_operand" "=a")
15420 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15421 (match_operand:DI 2 "register_operand" "0")
15424 (clobber (reg:CC FLAGS_REG))]
15425 "TARGET_64BIT && TARGET_GNU2_TLS"
15426 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15427 [(set_attr "type" "call")
15428 (set_attr "length" "2")
15429 (set_attr "length_address" "0")])
15431 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15432 [(set (match_operand:DI 0 "register_operand" "=&a")
15434 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15435 (match_operand:DI 3 "" "")
15438 (const:DI (unspec:DI
15439 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15441 (clobber (reg:CC FLAGS_REG))]
15442 "TARGET_64BIT && TARGET_GNU2_TLS"
15445 [(set (match_dup 0) (match_dup 4))]
15447 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15448 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15453 ;; These patterns match the binary 387 instructions for addM3, subM3,
15454 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15455 ;; SFmode. The first is the normal insn, the second the same insn but
15456 ;; with one operand a conversion, and the third the same insn but with
15457 ;; the other operand a conversion. The conversion may be SFmode or
15458 ;; SImode if the target mode DFmode, but only SImode if the target mode
15461 ;; Gcc is slightly more smart about handling normal two address instructions
15462 ;; so use special patterns for add and mull.
15464 (define_insn "*fop_<mode>_comm_mixed_avx"
15465 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15466 (match_operator:MODEF 3 "binary_fp_operator"
15467 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15468 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15469 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15470 && COMMUTATIVE_ARITH_P (operands[3])
15471 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15472 "* return output_387_binary_op (insn, operands);"
15473 [(set (attr "type")
15474 (if_then_else (eq_attr "alternative" "1")
15475 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15476 (const_string "ssemul")
15477 (const_string "sseadd"))
15478 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15479 (const_string "fmul")
15480 (const_string "fop"))))
15481 (set_attr "prefix" "orig,maybe_vex")
15482 (set_attr "mode" "<MODE>")])
15484 (define_insn "*fop_<mode>_comm_mixed"
15485 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15486 (match_operator:MODEF 3 "binary_fp_operator"
15487 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15488 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15489 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15490 && COMMUTATIVE_ARITH_P (operands[3])
15491 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15492 "* return output_387_binary_op (insn, operands);"
15493 [(set (attr "type")
15494 (if_then_else (eq_attr "alternative" "1")
15495 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15496 (const_string "ssemul")
15497 (const_string "sseadd"))
15498 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15499 (const_string "fmul")
15500 (const_string "fop"))))
15501 (set_attr "mode" "<MODE>")])
15503 (define_insn "*fop_<mode>_comm_avx"
15504 [(set (match_operand:MODEF 0 "register_operand" "=x")
15505 (match_operator:MODEF 3 "binary_fp_operator"
15506 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
15507 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15508 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15509 && COMMUTATIVE_ARITH_P (operands[3])
15510 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15511 "* return output_387_binary_op (insn, operands);"
15512 [(set (attr "type")
15513 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15514 (const_string "ssemul")
15515 (const_string "sseadd")))
15516 (set_attr "prefix" "vex")
15517 (set_attr "mode" "<MODE>")])
15519 (define_insn "*fop_<mode>_comm_sse"
15520 [(set (match_operand:MODEF 0 "register_operand" "=x")
15521 (match_operator:MODEF 3 "binary_fp_operator"
15522 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15523 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15524 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15525 && COMMUTATIVE_ARITH_P (operands[3])
15526 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15527 "* return output_387_binary_op (insn, operands);"
15528 [(set (attr "type")
15529 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15530 (const_string "ssemul")
15531 (const_string "sseadd")))
15532 (set_attr "mode" "<MODE>")])
15534 (define_insn "*fop_<mode>_comm_i387"
15535 [(set (match_operand:MODEF 0 "register_operand" "=f")
15536 (match_operator:MODEF 3 "binary_fp_operator"
15537 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15538 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15539 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15540 && COMMUTATIVE_ARITH_P (operands[3])
15541 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15542 "* return output_387_binary_op (insn, operands);"
15543 [(set (attr "type")
15544 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15545 (const_string "fmul")
15546 (const_string "fop")))
15547 (set_attr "mode" "<MODE>")])
15549 (define_insn "*fop_<mode>_1_mixed_avx"
15550 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15551 (match_operator:MODEF 3 "binary_fp_operator"
15552 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
15553 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15554 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15555 && !COMMUTATIVE_ARITH_P (operands[3])
15556 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15557 "* return output_387_binary_op (insn, operands);"
15558 [(set (attr "type")
15559 (cond [(and (eq_attr "alternative" "2")
15560 (match_operand:MODEF 3 "mult_operator" ""))
15561 (const_string "ssemul")
15562 (and (eq_attr "alternative" "2")
15563 (match_operand:MODEF 3 "div_operator" ""))
15564 (const_string "ssediv")
15565 (eq_attr "alternative" "2")
15566 (const_string "sseadd")
15567 (match_operand:MODEF 3 "mult_operator" "")
15568 (const_string "fmul")
15569 (match_operand:MODEF 3 "div_operator" "")
15570 (const_string "fdiv")
15572 (const_string "fop")))
15573 (set_attr "prefix" "orig,orig,maybe_vex")
15574 (set_attr "mode" "<MODE>")])
15576 (define_insn "*fop_<mode>_1_mixed"
15577 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15578 (match_operator:MODEF 3 "binary_fp_operator"
15579 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15580 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15581 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15582 && !COMMUTATIVE_ARITH_P (operands[3])
15583 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15584 "* return output_387_binary_op (insn, operands);"
15585 [(set (attr "type")
15586 (cond [(and (eq_attr "alternative" "2")
15587 (match_operand:MODEF 3 "mult_operator" ""))
15588 (const_string "ssemul")
15589 (and (eq_attr "alternative" "2")
15590 (match_operand:MODEF 3 "div_operator" ""))
15591 (const_string "ssediv")
15592 (eq_attr "alternative" "2")
15593 (const_string "sseadd")
15594 (match_operand:MODEF 3 "mult_operator" "")
15595 (const_string "fmul")
15596 (match_operand:MODEF 3 "div_operator" "")
15597 (const_string "fdiv")
15599 (const_string "fop")))
15600 (set_attr "mode" "<MODE>")])
15602 (define_insn "*rcpsf2_sse"
15603 [(set (match_operand:SF 0 "register_operand" "=x")
15604 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15607 "%vrcpss\t{%1, %d0|%d0, %1}"
15608 [(set_attr "type" "sse")
15609 (set_attr "atom_sse_attr" "rcp")
15610 (set_attr "prefix" "maybe_vex")
15611 (set_attr "mode" "SF")])
15613 (define_insn "*fop_<mode>_1_avx"
15614 [(set (match_operand:MODEF 0 "register_operand" "=x")
15615 (match_operator:MODEF 3 "binary_fp_operator"
15616 [(match_operand:MODEF 1 "register_operand" "x")
15617 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15618 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15619 && !COMMUTATIVE_ARITH_P (operands[3])"
15620 "* return output_387_binary_op (insn, operands);"
15621 [(set (attr "type")
15622 (cond [(match_operand:MODEF 3 "mult_operator" "")
15623 (const_string "ssemul")
15624 (match_operand:MODEF 3 "div_operator" "")
15625 (const_string "ssediv")
15627 (const_string "sseadd")))
15628 (set_attr "prefix" "vex")
15629 (set_attr "mode" "<MODE>")])
15631 (define_insn "*fop_<mode>_1_sse"
15632 [(set (match_operand:MODEF 0 "register_operand" "=x")
15633 (match_operator:MODEF 3 "binary_fp_operator"
15634 [(match_operand:MODEF 1 "register_operand" "0")
15635 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15636 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15637 && !COMMUTATIVE_ARITH_P (operands[3])"
15638 "* return output_387_binary_op (insn, operands);"
15639 [(set (attr "type")
15640 (cond [(match_operand:MODEF 3 "mult_operator" "")
15641 (const_string "ssemul")
15642 (match_operand:MODEF 3 "div_operator" "")
15643 (const_string "ssediv")
15645 (const_string "sseadd")))
15646 (set_attr "mode" "<MODE>")])
15648 ;; This pattern is not fully shadowed by the pattern above.
15649 (define_insn "*fop_<mode>_1_i387"
15650 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15651 (match_operator:MODEF 3 "binary_fp_operator"
15652 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15653 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15654 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15655 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15656 && !COMMUTATIVE_ARITH_P (operands[3])
15657 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15658 "* return output_387_binary_op (insn, operands);"
15659 [(set (attr "type")
15660 (cond [(match_operand:MODEF 3 "mult_operator" "")
15661 (const_string "fmul")
15662 (match_operand:MODEF 3 "div_operator" "")
15663 (const_string "fdiv")
15665 (const_string "fop")))
15666 (set_attr "mode" "<MODE>")])
15668 ;; ??? Add SSE splitters for these!
15669 (define_insn "*fop_<MODEF:mode>_2_i387"
15670 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15671 (match_operator:MODEF 3 "binary_fp_operator"
15673 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15674 (match_operand:MODEF 2 "register_operand" "0,0")]))]
15675 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15676 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15677 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15678 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15679 [(set (attr "type")
15680 (cond [(match_operand:MODEF 3 "mult_operator" "")
15681 (const_string "fmul")
15682 (match_operand:MODEF 3 "div_operator" "")
15683 (const_string "fdiv")
15685 (const_string "fop")))
15686 (set_attr "fp_int_src" "true")
15687 (set_attr "mode" "<X87MODEI12:MODE>")])
15689 (define_insn "*fop_<MODEF:mode>_3_i387"
15690 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15691 (match_operator:MODEF 3 "binary_fp_operator"
15692 [(match_operand:MODEF 1 "register_operand" "0,0")
15694 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15695 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15696 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15697 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15698 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15699 [(set (attr "type")
15700 (cond [(match_operand:MODEF 3 "mult_operator" "")
15701 (const_string "fmul")
15702 (match_operand:MODEF 3 "div_operator" "")
15703 (const_string "fdiv")
15705 (const_string "fop")))
15706 (set_attr "fp_int_src" "true")
15707 (set_attr "mode" "<MODE>")])
15709 (define_insn "*fop_df_4_i387"
15710 [(set (match_operand:DF 0 "register_operand" "=f,f")
15711 (match_operator:DF 3 "binary_fp_operator"
15713 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15714 (match_operand:DF 2 "register_operand" "0,f")]))]
15715 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15716 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15717 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15718 "* return output_387_binary_op (insn, operands);"
15719 [(set (attr "type")
15720 (cond [(match_operand:DF 3 "mult_operator" "")
15721 (const_string "fmul")
15722 (match_operand:DF 3 "div_operator" "")
15723 (const_string "fdiv")
15725 (const_string "fop")))
15726 (set_attr "mode" "SF")])
15728 (define_insn "*fop_df_5_i387"
15729 [(set (match_operand:DF 0 "register_operand" "=f,f")
15730 (match_operator:DF 3 "binary_fp_operator"
15731 [(match_operand:DF 1 "register_operand" "0,f")
15733 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15734 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15735 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15736 "* return output_387_binary_op (insn, operands);"
15737 [(set (attr "type")
15738 (cond [(match_operand:DF 3 "mult_operator" "")
15739 (const_string "fmul")
15740 (match_operand:DF 3 "div_operator" "")
15741 (const_string "fdiv")
15743 (const_string "fop")))
15744 (set_attr "mode" "SF")])
15746 (define_insn "*fop_df_6_i387"
15747 [(set (match_operand:DF 0 "register_operand" "=f,f")
15748 (match_operator:DF 3 "binary_fp_operator"
15750 (match_operand:SF 1 "register_operand" "0,f"))
15752 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15753 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15754 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15755 "* return output_387_binary_op (insn, operands);"
15756 [(set (attr "type")
15757 (cond [(match_operand:DF 3 "mult_operator" "")
15758 (const_string "fmul")
15759 (match_operand:DF 3 "div_operator" "")
15760 (const_string "fdiv")
15762 (const_string "fop")))
15763 (set_attr "mode" "SF")])
15765 (define_insn "*fop_xf_comm_i387"
15766 [(set (match_operand:XF 0 "register_operand" "=f")
15767 (match_operator:XF 3 "binary_fp_operator"
15768 [(match_operand:XF 1 "register_operand" "%0")
15769 (match_operand:XF 2 "register_operand" "f")]))]
15771 && COMMUTATIVE_ARITH_P (operands[3])"
15772 "* return output_387_binary_op (insn, operands);"
15773 [(set (attr "type")
15774 (if_then_else (match_operand:XF 3 "mult_operator" "")
15775 (const_string "fmul")
15776 (const_string "fop")))
15777 (set_attr "mode" "XF")])
15779 (define_insn "*fop_xf_1_i387"
15780 [(set (match_operand:XF 0 "register_operand" "=f,f")
15781 (match_operator:XF 3 "binary_fp_operator"
15782 [(match_operand:XF 1 "register_operand" "0,f")
15783 (match_operand:XF 2 "register_operand" "f,0")]))]
15785 && !COMMUTATIVE_ARITH_P (operands[3])"
15786 "* return output_387_binary_op (insn, operands);"
15787 [(set (attr "type")
15788 (cond [(match_operand:XF 3 "mult_operator" "")
15789 (const_string "fmul")
15790 (match_operand:XF 3 "div_operator" "")
15791 (const_string "fdiv")
15793 (const_string "fop")))
15794 (set_attr "mode" "XF")])
15796 (define_insn "*fop_xf_2_i387"
15797 [(set (match_operand:XF 0 "register_operand" "=f,f")
15798 (match_operator:XF 3 "binary_fp_operator"
15800 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15801 (match_operand:XF 2 "register_operand" "0,0")]))]
15802 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15803 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15804 [(set (attr "type")
15805 (cond [(match_operand:XF 3 "mult_operator" "")
15806 (const_string "fmul")
15807 (match_operand:XF 3 "div_operator" "")
15808 (const_string "fdiv")
15810 (const_string "fop")))
15811 (set_attr "fp_int_src" "true")
15812 (set_attr "mode" "<MODE>")])
15814 (define_insn "*fop_xf_3_i387"
15815 [(set (match_operand:XF 0 "register_operand" "=f,f")
15816 (match_operator:XF 3 "binary_fp_operator"
15817 [(match_operand:XF 1 "register_operand" "0,0")
15819 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15820 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15821 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15822 [(set (attr "type")
15823 (cond [(match_operand:XF 3 "mult_operator" "")
15824 (const_string "fmul")
15825 (match_operand:XF 3 "div_operator" "")
15826 (const_string "fdiv")
15828 (const_string "fop")))
15829 (set_attr "fp_int_src" "true")
15830 (set_attr "mode" "<MODE>")])
15832 (define_insn "*fop_xf_4_i387"
15833 [(set (match_operand:XF 0 "register_operand" "=f,f")
15834 (match_operator:XF 3 "binary_fp_operator"
15836 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15837 (match_operand:XF 2 "register_operand" "0,f")]))]
15839 "* return output_387_binary_op (insn, operands);"
15840 [(set (attr "type")
15841 (cond [(match_operand:XF 3 "mult_operator" "")
15842 (const_string "fmul")
15843 (match_operand:XF 3 "div_operator" "")
15844 (const_string "fdiv")
15846 (const_string "fop")))
15847 (set_attr "mode" "<MODE>")])
15849 (define_insn "*fop_xf_5_i387"
15850 [(set (match_operand:XF 0 "register_operand" "=f,f")
15851 (match_operator:XF 3 "binary_fp_operator"
15852 [(match_operand:XF 1 "register_operand" "0,f")
15854 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15856 "* return output_387_binary_op (insn, operands);"
15857 [(set (attr "type")
15858 (cond [(match_operand:XF 3 "mult_operator" "")
15859 (const_string "fmul")
15860 (match_operand:XF 3 "div_operator" "")
15861 (const_string "fdiv")
15863 (const_string "fop")))
15864 (set_attr "mode" "<MODE>")])
15866 (define_insn "*fop_xf_6_i387"
15867 [(set (match_operand:XF 0 "register_operand" "=f,f")
15868 (match_operator:XF 3 "binary_fp_operator"
15870 (match_operand:MODEF 1 "register_operand" "0,f"))
15872 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15874 "* return output_387_binary_op (insn, operands);"
15875 [(set (attr "type")
15876 (cond [(match_operand:XF 3 "mult_operator" "")
15877 (const_string "fmul")
15878 (match_operand:XF 3 "div_operator" "")
15879 (const_string "fdiv")
15881 (const_string "fop")))
15882 (set_attr "mode" "<MODE>")])
15885 [(set (match_operand 0 "register_operand" "")
15886 (match_operator 3 "binary_fp_operator"
15887 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15888 (match_operand 2 "register_operand" "")]))]
15890 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15891 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15894 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15895 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15896 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15897 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15898 GET_MODE (operands[3]),
15901 ix86_free_from_memory (GET_MODE (operands[1]));
15906 [(set (match_operand 0 "register_operand" "")
15907 (match_operator 3 "binary_fp_operator"
15908 [(match_operand 1 "register_operand" "")
15909 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15911 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15912 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15915 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15916 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15917 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15918 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15919 GET_MODE (operands[3]),
15922 ix86_free_from_memory (GET_MODE (operands[2]));
15926 ;; FPU special functions.
15928 ;; This pattern implements a no-op XFmode truncation for
15929 ;; all fancy i386 XFmode math functions.
15931 (define_insn "truncxf<mode>2_i387_noop_unspec"
15932 [(set (match_operand:MODEF 0 "register_operand" "=f")
15933 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15934 UNSPEC_TRUNC_NOOP))]
15935 "TARGET_USE_FANCY_MATH_387"
15936 "* return output_387_reg_move (insn, operands);"
15937 [(set_attr "type" "fmov")
15938 (set_attr "mode" "<MODE>")])
15940 (define_insn "sqrtxf2"
15941 [(set (match_operand:XF 0 "register_operand" "=f")
15942 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15943 "TARGET_USE_FANCY_MATH_387"
15945 [(set_attr "type" "fpspc")
15946 (set_attr "mode" "XF")
15947 (set_attr "athlon_decode" "direct")
15948 (set_attr "amdfam10_decode" "direct")])
15950 (define_insn "sqrt_extend<mode>xf2_i387"
15951 [(set (match_operand:XF 0 "register_operand" "=f")
15954 (match_operand:MODEF 1 "register_operand" "0"))))]
15955 "TARGET_USE_FANCY_MATH_387"
15957 [(set_attr "type" "fpspc")
15958 (set_attr "mode" "XF")
15959 (set_attr "athlon_decode" "direct")
15960 (set_attr "amdfam10_decode" "direct")])
15962 (define_insn "*rsqrtsf2_sse"
15963 [(set (match_operand:SF 0 "register_operand" "=x")
15964 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15967 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15968 [(set_attr "type" "sse")
15969 (set_attr "atom_sse_attr" "rcp")
15970 (set_attr "prefix" "maybe_vex")
15971 (set_attr "mode" "SF")])
15973 (define_expand "rsqrtsf2"
15974 [(set (match_operand:SF 0 "register_operand" "")
15975 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15979 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15983 (define_insn "*sqrt<mode>2_sse"
15984 [(set (match_operand:MODEF 0 "register_operand" "=x")
15986 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15987 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15988 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15989 [(set_attr "type" "sse")
15990 (set_attr "atom_sse_attr" "sqrt")
15991 (set_attr "prefix" "maybe_vex")
15992 (set_attr "mode" "<MODE>")
15993 (set_attr "athlon_decode" "*")
15994 (set_attr "amdfam10_decode" "*")])
15996 (define_expand "sqrt<mode>2"
15997 [(set (match_operand:MODEF 0 "register_operand" "")
15999 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16000 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16001 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16003 if (<MODE>mode == SFmode
16004 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16005 && flag_finite_math_only && !flag_trapping_math
16006 && flag_unsafe_math_optimizations)
16008 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16012 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16014 rtx op0 = gen_reg_rtx (XFmode);
16015 rtx op1 = force_reg (<MODE>mode, operands[1]);
16017 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16018 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16023 (define_insn "fpremxf4_i387"
16024 [(set (match_operand:XF 0 "register_operand" "=f")
16025 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16026 (match_operand:XF 3 "register_operand" "1")]
16028 (set (match_operand:XF 1 "register_operand" "=u")
16029 (unspec:XF [(match_dup 2) (match_dup 3)]
16031 (set (reg:CCFP FPSR_REG)
16032 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16034 "TARGET_USE_FANCY_MATH_387"
16036 [(set_attr "type" "fpspc")
16037 (set_attr "mode" "XF")])
16039 (define_expand "fmodxf3"
16040 [(use (match_operand:XF 0 "register_operand" ""))
16041 (use (match_operand:XF 1 "general_operand" ""))
16042 (use (match_operand:XF 2 "general_operand" ""))]
16043 "TARGET_USE_FANCY_MATH_387"
16045 rtx label = gen_label_rtx ();
16047 rtx op1 = gen_reg_rtx (XFmode);
16048 rtx op2 = gen_reg_rtx (XFmode);
16050 emit_move_insn (op2, operands[2]);
16051 emit_move_insn (op1, operands[1]);
16053 emit_label (label);
16054 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16055 ix86_emit_fp_unordered_jump (label);
16056 LABEL_NUSES (label) = 1;
16058 emit_move_insn (operands[0], op1);
16062 (define_expand "fmod<mode>3"
16063 [(use (match_operand:MODEF 0 "register_operand" ""))
16064 (use (match_operand:MODEF 1 "general_operand" ""))
16065 (use (match_operand:MODEF 2 "general_operand" ""))]
16066 "TARGET_USE_FANCY_MATH_387"
16068 rtx label = gen_label_rtx ();
16070 rtx op1 = gen_reg_rtx (XFmode);
16071 rtx op2 = gen_reg_rtx (XFmode);
16073 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16074 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16076 emit_label (label);
16077 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16078 ix86_emit_fp_unordered_jump (label);
16079 LABEL_NUSES (label) = 1;
16081 /* Truncate the result properly for strict SSE math. */
16082 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16083 && !TARGET_MIX_SSE_I387)
16084 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16086 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16091 (define_insn "fprem1xf4_i387"
16092 [(set (match_operand:XF 0 "register_operand" "=f")
16093 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16094 (match_operand:XF 3 "register_operand" "1")]
16096 (set (match_operand:XF 1 "register_operand" "=u")
16097 (unspec:XF [(match_dup 2) (match_dup 3)]
16099 (set (reg:CCFP FPSR_REG)
16100 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16102 "TARGET_USE_FANCY_MATH_387"
16104 [(set_attr "type" "fpspc")
16105 (set_attr "mode" "XF")])
16107 (define_expand "remainderxf3"
16108 [(use (match_operand:XF 0 "register_operand" ""))
16109 (use (match_operand:XF 1 "general_operand" ""))
16110 (use (match_operand:XF 2 "general_operand" ""))]
16111 "TARGET_USE_FANCY_MATH_387"
16113 rtx label = gen_label_rtx ();
16115 rtx op1 = gen_reg_rtx (XFmode);
16116 rtx op2 = gen_reg_rtx (XFmode);
16118 emit_move_insn (op2, operands[2]);
16119 emit_move_insn (op1, operands[1]);
16121 emit_label (label);
16122 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16123 ix86_emit_fp_unordered_jump (label);
16124 LABEL_NUSES (label) = 1;
16126 emit_move_insn (operands[0], op1);
16130 (define_expand "remainder<mode>3"
16131 [(use (match_operand:MODEF 0 "register_operand" ""))
16132 (use (match_operand:MODEF 1 "general_operand" ""))
16133 (use (match_operand:MODEF 2 "general_operand" ""))]
16134 "TARGET_USE_FANCY_MATH_387"
16136 rtx label = gen_label_rtx ();
16138 rtx op1 = gen_reg_rtx (XFmode);
16139 rtx op2 = gen_reg_rtx (XFmode);
16141 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16142 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16144 emit_label (label);
16146 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16147 ix86_emit_fp_unordered_jump (label);
16148 LABEL_NUSES (label) = 1;
16150 /* Truncate the result properly for strict SSE math. */
16151 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16152 && !TARGET_MIX_SSE_I387)
16153 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16155 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16160 (define_insn "*sinxf2_i387"
16161 [(set (match_operand:XF 0 "register_operand" "=f")
16162 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16163 "TARGET_USE_FANCY_MATH_387
16164 && flag_unsafe_math_optimizations"
16166 [(set_attr "type" "fpspc")
16167 (set_attr "mode" "XF")])
16169 (define_insn "*sin_extend<mode>xf2_i387"
16170 [(set (match_operand:XF 0 "register_operand" "=f")
16171 (unspec:XF [(float_extend:XF
16172 (match_operand:MODEF 1 "register_operand" "0"))]
16174 "TARGET_USE_FANCY_MATH_387
16175 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16176 || TARGET_MIX_SSE_I387)
16177 && flag_unsafe_math_optimizations"
16179 [(set_attr "type" "fpspc")
16180 (set_attr "mode" "XF")])
16182 (define_insn "*cosxf2_i387"
16183 [(set (match_operand:XF 0 "register_operand" "=f")
16184 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16185 "TARGET_USE_FANCY_MATH_387
16186 && flag_unsafe_math_optimizations"
16188 [(set_attr "type" "fpspc")
16189 (set_attr "mode" "XF")])
16191 (define_insn "*cos_extend<mode>xf2_i387"
16192 [(set (match_operand:XF 0 "register_operand" "=f")
16193 (unspec:XF [(float_extend:XF
16194 (match_operand:MODEF 1 "register_operand" "0"))]
16196 "TARGET_USE_FANCY_MATH_387
16197 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16198 || TARGET_MIX_SSE_I387)
16199 && flag_unsafe_math_optimizations"
16201 [(set_attr "type" "fpspc")
16202 (set_attr "mode" "XF")])
16204 ;; When sincos pattern is defined, sin and cos builtin functions will be
16205 ;; expanded to sincos pattern with one of its outputs left unused.
16206 ;; CSE pass will figure out if two sincos patterns can be combined,
16207 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16208 ;; depending on the unused output.
16210 (define_insn "sincosxf3"
16211 [(set (match_operand:XF 0 "register_operand" "=f")
16212 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16213 UNSPEC_SINCOS_COS))
16214 (set (match_operand:XF 1 "register_operand" "=u")
16215 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16216 "TARGET_USE_FANCY_MATH_387
16217 && flag_unsafe_math_optimizations"
16219 [(set_attr "type" "fpspc")
16220 (set_attr "mode" "XF")])
16223 [(set (match_operand:XF 0 "register_operand" "")
16224 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16225 UNSPEC_SINCOS_COS))
16226 (set (match_operand:XF 1 "register_operand" "")
16227 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16228 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16229 && !(reload_completed || reload_in_progress)"
16230 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16234 [(set (match_operand:XF 0 "register_operand" "")
16235 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16236 UNSPEC_SINCOS_COS))
16237 (set (match_operand:XF 1 "register_operand" "")
16238 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16239 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16240 && !(reload_completed || reload_in_progress)"
16241 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16244 (define_insn "sincos_extend<mode>xf3_i387"
16245 [(set (match_operand:XF 0 "register_operand" "=f")
16246 (unspec:XF [(float_extend:XF
16247 (match_operand:MODEF 2 "register_operand" "0"))]
16248 UNSPEC_SINCOS_COS))
16249 (set (match_operand:XF 1 "register_operand" "=u")
16250 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16251 "TARGET_USE_FANCY_MATH_387
16252 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16253 || TARGET_MIX_SSE_I387)
16254 && flag_unsafe_math_optimizations"
16256 [(set_attr "type" "fpspc")
16257 (set_attr "mode" "XF")])
16260 [(set (match_operand:XF 0 "register_operand" "")
16261 (unspec:XF [(float_extend:XF
16262 (match_operand:MODEF 2 "register_operand" ""))]
16263 UNSPEC_SINCOS_COS))
16264 (set (match_operand:XF 1 "register_operand" "")
16265 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16266 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16267 && !(reload_completed || reload_in_progress)"
16268 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16272 [(set (match_operand:XF 0 "register_operand" "")
16273 (unspec:XF [(float_extend:XF
16274 (match_operand:MODEF 2 "register_operand" ""))]
16275 UNSPEC_SINCOS_COS))
16276 (set (match_operand:XF 1 "register_operand" "")
16277 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16278 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16279 && !(reload_completed || reload_in_progress)"
16280 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16283 (define_expand "sincos<mode>3"
16284 [(use (match_operand:MODEF 0 "register_operand" ""))
16285 (use (match_operand:MODEF 1 "register_operand" ""))
16286 (use (match_operand:MODEF 2 "register_operand" ""))]
16287 "TARGET_USE_FANCY_MATH_387
16288 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16289 || TARGET_MIX_SSE_I387)
16290 && flag_unsafe_math_optimizations"
16292 rtx op0 = gen_reg_rtx (XFmode);
16293 rtx op1 = gen_reg_rtx (XFmode);
16295 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16296 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16297 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16301 (define_insn "fptanxf4_i387"
16302 [(set (match_operand:XF 0 "register_operand" "=f")
16303 (match_operand:XF 3 "const_double_operand" "F"))
16304 (set (match_operand:XF 1 "register_operand" "=u")
16305 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16307 "TARGET_USE_FANCY_MATH_387
16308 && flag_unsafe_math_optimizations
16309 && standard_80387_constant_p (operands[3]) == 2"
16311 [(set_attr "type" "fpspc")
16312 (set_attr "mode" "XF")])
16314 (define_insn "fptan_extend<mode>xf4_i387"
16315 [(set (match_operand:MODEF 0 "register_operand" "=f")
16316 (match_operand:MODEF 3 "const_double_operand" "F"))
16317 (set (match_operand:XF 1 "register_operand" "=u")
16318 (unspec:XF [(float_extend:XF
16319 (match_operand:MODEF 2 "register_operand" "0"))]
16321 "TARGET_USE_FANCY_MATH_387
16322 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16323 || TARGET_MIX_SSE_I387)
16324 && flag_unsafe_math_optimizations
16325 && standard_80387_constant_p (operands[3]) == 2"
16327 [(set_attr "type" "fpspc")
16328 (set_attr "mode" "XF")])
16330 (define_expand "tanxf2"
16331 [(use (match_operand:XF 0 "register_operand" ""))
16332 (use (match_operand:XF 1 "register_operand" ""))]
16333 "TARGET_USE_FANCY_MATH_387
16334 && flag_unsafe_math_optimizations"
16336 rtx one = gen_reg_rtx (XFmode);
16337 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16339 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16343 (define_expand "tan<mode>2"
16344 [(use (match_operand:MODEF 0 "register_operand" ""))
16345 (use (match_operand:MODEF 1 "register_operand" ""))]
16346 "TARGET_USE_FANCY_MATH_387
16347 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16348 || TARGET_MIX_SSE_I387)
16349 && flag_unsafe_math_optimizations"
16351 rtx op0 = gen_reg_rtx (XFmode);
16353 rtx one = gen_reg_rtx (<MODE>mode);
16354 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16356 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16357 operands[1], op2));
16358 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16362 (define_insn "*fpatanxf3_i387"
16363 [(set (match_operand:XF 0 "register_operand" "=f")
16364 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16365 (match_operand:XF 2 "register_operand" "u")]
16367 (clobber (match_scratch:XF 3 "=2"))]
16368 "TARGET_USE_FANCY_MATH_387
16369 && flag_unsafe_math_optimizations"
16371 [(set_attr "type" "fpspc")
16372 (set_attr "mode" "XF")])
16374 (define_insn "fpatan_extend<mode>xf3_i387"
16375 [(set (match_operand:XF 0 "register_operand" "=f")
16376 (unspec:XF [(float_extend:XF
16377 (match_operand:MODEF 1 "register_operand" "0"))
16379 (match_operand:MODEF 2 "register_operand" "u"))]
16381 (clobber (match_scratch:XF 3 "=2"))]
16382 "TARGET_USE_FANCY_MATH_387
16383 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16384 || TARGET_MIX_SSE_I387)
16385 && flag_unsafe_math_optimizations"
16387 [(set_attr "type" "fpspc")
16388 (set_attr "mode" "XF")])
16390 (define_expand "atan2xf3"
16391 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16392 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16393 (match_operand:XF 1 "register_operand" "")]
16395 (clobber (match_scratch:XF 3 ""))])]
16396 "TARGET_USE_FANCY_MATH_387
16397 && flag_unsafe_math_optimizations"
16400 (define_expand "atan2<mode>3"
16401 [(use (match_operand:MODEF 0 "register_operand" ""))
16402 (use (match_operand:MODEF 1 "register_operand" ""))
16403 (use (match_operand:MODEF 2 "register_operand" ""))]
16404 "TARGET_USE_FANCY_MATH_387
16405 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16406 || TARGET_MIX_SSE_I387)
16407 && flag_unsafe_math_optimizations"
16409 rtx op0 = gen_reg_rtx (XFmode);
16411 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16412 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16416 (define_expand "atanxf2"
16417 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16418 (unspec:XF [(match_dup 2)
16419 (match_operand:XF 1 "register_operand" "")]
16421 (clobber (match_scratch:XF 3 ""))])]
16422 "TARGET_USE_FANCY_MATH_387
16423 && flag_unsafe_math_optimizations"
16425 operands[2] = gen_reg_rtx (XFmode);
16426 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16429 (define_expand "atan<mode>2"
16430 [(use (match_operand:MODEF 0 "register_operand" ""))
16431 (use (match_operand:MODEF 1 "register_operand" ""))]
16432 "TARGET_USE_FANCY_MATH_387
16433 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16434 || TARGET_MIX_SSE_I387)
16435 && flag_unsafe_math_optimizations"
16437 rtx op0 = gen_reg_rtx (XFmode);
16439 rtx op2 = gen_reg_rtx (<MODE>mode);
16440 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16442 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16443 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16447 (define_expand "asinxf2"
16448 [(set (match_dup 2)
16449 (mult:XF (match_operand:XF 1 "register_operand" "")
16451 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16452 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16453 (parallel [(set (match_operand:XF 0 "register_operand" "")
16454 (unspec:XF [(match_dup 5) (match_dup 1)]
16456 (clobber (match_scratch:XF 6 ""))])]
16457 "TARGET_USE_FANCY_MATH_387
16458 && flag_unsafe_math_optimizations"
16462 if (optimize_insn_for_size_p ())
16465 for (i = 2; i < 6; i++)
16466 operands[i] = gen_reg_rtx (XFmode);
16468 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16471 (define_expand "asin<mode>2"
16472 [(use (match_operand:MODEF 0 "register_operand" ""))
16473 (use (match_operand:MODEF 1 "general_operand" ""))]
16474 "TARGET_USE_FANCY_MATH_387
16475 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16476 || TARGET_MIX_SSE_I387)
16477 && flag_unsafe_math_optimizations"
16479 rtx op0 = gen_reg_rtx (XFmode);
16480 rtx op1 = gen_reg_rtx (XFmode);
16482 if (optimize_insn_for_size_p ())
16485 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16486 emit_insn (gen_asinxf2 (op0, op1));
16487 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16491 (define_expand "acosxf2"
16492 [(set (match_dup 2)
16493 (mult:XF (match_operand:XF 1 "register_operand" "")
16495 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16496 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16497 (parallel [(set (match_operand:XF 0 "register_operand" "")
16498 (unspec:XF [(match_dup 1) (match_dup 5)]
16500 (clobber (match_scratch:XF 6 ""))])]
16501 "TARGET_USE_FANCY_MATH_387
16502 && flag_unsafe_math_optimizations"
16506 if (optimize_insn_for_size_p ())
16509 for (i = 2; i < 6; i++)
16510 operands[i] = gen_reg_rtx (XFmode);
16512 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16515 (define_expand "acos<mode>2"
16516 [(use (match_operand:MODEF 0 "register_operand" ""))
16517 (use (match_operand:MODEF 1 "general_operand" ""))]
16518 "TARGET_USE_FANCY_MATH_387
16519 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16520 || TARGET_MIX_SSE_I387)
16521 && flag_unsafe_math_optimizations"
16523 rtx op0 = gen_reg_rtx (XFmode);
16524 rtx op1 = gen_reg_rtx (XFmode);
16526 if (optimize_insn_for_size_p ())
16529 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16530 emit_insn (gen_acosxf2 (op0, op1));
16531 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16535 (define_insn "fyl2xxf3_i387"
16536 [(set (match_operand:XF 0 "register_operand" "=f")
16537 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16538 (match_operand:XF 2 "register_operand" "u")]
16540 (clobber (match_scratch:XF 3 "=2"))]
16541 "TARGET_USE_FANCY_MATH_387
16542 && flag_unsafe_math_optimizations"
16544 [(set_attr "type" "fpspc")
16545 (set_attr "mode" "XF")])
16547 (define_insn "fyl2x_extend<mode>xf3_i387"
16548 [(set (match_operand:XF 0 "register_operand" "=f")
16549 (unspec:XF [(float_extend:XF
16550 (match_operand:MODEF 1 "register_operand" "0"))
16551 (match_operand:XF 2 "register_operand" "u")]
16553 (clobber (match_scratch:XF 3 "=2"))]
16554 "TARGET_USE_FANCY_MATH_387
16555 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16556 || TARGET_MIX_SSE_I387)
16557 && flag_unsafe_math_optimizations"
16559 [(set_attr "type" "fpspc")
16560 (set_attr "mode" "XF")])
16562 (define_expand "logxf2"
16563 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16564 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16565 (match_dup 2)] UNSPEC_FYL2X))
16566 (clobber (match_scratch:XF 3 ""))])]
16567 "TARGET_USE_FANCY_MATH_387
16568 && flag_unsafe_math_optimizations"
16570 operands[2] = gen_reg_rtx (XFmode);
16571 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16574 (define_expand "log<mode>2"
16575 [(use (match_operand:MODEF 0 "register_operand" ""))
16576 (use (match_operand:MODEF 1 "register_operand" ""))]
16577 "TARGET_USE_FANCY_MATH_387
16578 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16579 || TARGET_MIX_SSE_I387)
16580 && flag_unsafe_math_optimizations"
16582 rtx op0 = gen_reg_rtx (XFmode);
16584 rtx op2 = gen_reg_rtx (XFmode);
16585 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16587 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16588 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16592 (define_expand "log10xf2"
16593 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16594 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16595 (match_dup 2)] UNSPEC_FYL2X))
16596 (clobber (match_scratch:XF 3 ""))])]
16597 "TARGET_USE_FANCY_MATH_387
16598 && flag_unsafe_math_optimizations"
16600 operands[2] = gen_reg_rtx (XFmode);
16601 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16604 (define_expand "log10<mode>2"
16605 [(use (match_operand:MODEF 0 "register_operand" ""))
16606 (use (match_operand:MODEF 1 "register_operand" ""))]
16607 "TARGET_USE_FANCY_MATH_387
16608 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16609 || TARGET_MIX_SSE_I387)
16610 && flag_unsafe_math_optimizations"
16612 rtx op0 = gen_reg_rtx (XFmode);
16614 rtx op2 = gen_reg_rtx (XFmode);
16615 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16617 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16618 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16622 (define_expand "log2xf2"
16623 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16624 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16625 (match_dup 2)] UNSPEC_FYL2X))
16626 (clobber (match_scratch:XF 3 ""))])]
16627 "TARGET_USE_FANCY_MATH_387
16628 && flag_unsafe_math_optimizations"
16630 operands[2] = gen_reg_rtx (XFmode);
16631 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16634 (define_expand "log2<mode>2"
16635 [(use (match_operand:MODEF 0 "register_operand" ""))
16636 (use (match_operand:MODEF 1 "register_operand" ""))]
16637 "TARGET_USE_FANCY_MATH_387
16638 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16639 || TARGET_MIX_SSE_I387)
16640 && flag_unsafe_math_optimizations"
16642 rtx op0 = gen_reg_rtx (XFmode);
16644 rtx op2 = gen_reg_rtx (XFmode);
16645 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16647 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16648 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16652 (define_insn "fyl2xp1xf3_i387"
16653 [(set (match_operand:XF 0 "register_operand" "=f")
16654 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16655 (match_operand:XF 2 "register_operand" "u")]
16657 (clobber (match_scratch:XF 3 "=2"))]
16658 "TARGET_USE_FANCY_MATH_387
16659 && flag_unsafe_math_optimizations"
16661 [(set_attr "type" "fpspc")
16662 (set_attr "mode" "XF")])
16664 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16665 [(set (match_operand:XF 0 "register_operand" "=f")
16666 (unspec:XF [(float_extend:XF
16667 (match_operand:MODEF 1 "register_operand" "0"))
16668 (match_operand:XF 2 "register_operand" "u")]
16670 (clobber (match_scratch:XF 3 "=2"))]
16671 "TARGET_USE_FANCY_MATH_387
16672 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16673 || TARGET_MIX_SSE_I387)
16674 && flag_unsafe_math_optimizations"
16676 [(set_attr "type" "fpspc")
16677 (set_attr "mode" "XF")])
16679 (define_expand "log1pxf2"
16680 [(use (match_operand:XF 0 "register_operand" ""))
16681 (use (match_operand:XF 1 "register_operand" ""))]
16682 "TARGET_USE_FANCY_MATH_387
16683 && flag_unsafe_math_optimizations"
16685 if (optimize_insn_for_size_p ())
16688 ix86_emit_i387_log1p (operands[0], operands[1]);
16692 (define_expand "log1p<mode>2"
16693 [(use (match_operand:MODEF 0 "register_operand" ""))
16694 (use (match_operand:MODEF 1 "register_operand" ""))]
16695 "TARGET_USE_FANCY_MATH_387
16696 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16697 || TARGET_MIX_SSE_I387)
16698 && flag_unsafe_math_optimizations"
16702 if (optimize_insn_for_size_p ())
16705 op0 = gen_reg_rtx (XFmode);
16707 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16709 ix86_emit_i387_log1p (op0, operands[1]);
16710 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16714 (define_insn "fxtractxf3_i387"
16715 [(set (match_operand:XF 0 "register_operand" "=f")
16716 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16717 UNSPEC_XTRACT_FRACT))
16718 (set (match_operand:XF 1 "register_operand" "=u")
16719 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16720 "TARGET_USE_FANCY_MATH_387
16721 && flag_unsafe_math_optimizations"
16723 [(set_attr "type" "fpspc")
16724 (set_attr "mode" "XF")])
16726 (define_insn "fxtract_extend<mode>xf3_i387"
16727 [(set (match_operand:XF 0 "register_operand" "=f")
16728 (unspec:XF [(float_extend:XF
16729 (match_operand:MODEF 2 "register_operand" "0"))]
16730 UNSPEC_XTRACT_FRACT))
16731 (set (match_operand:XF 1 "register_operand" "=u")
16732 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16733 "TARGET_USE_FANCY_MATH_387
16734 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16735 || TARGET_MIX_SSE_I387)
16736 && flag_unsafe_math_optimizations"
16738 [(set_attr "type" "fpspc")
16739 (set_attr "mode" "XF")])
16741 (define_expand "logbxf2"
16742 [(parallel [(set (match_dup 2)
16743 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16744 UNSPEC_XTRACT_FRACT))
16745 (set (match_operand:XF 0 "register_operand" "")
16746 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16747 "TARGET_USE_FANCY_MATH_387
16748 && flag_unsafe_math_optimizations"
16750 operands[2] = gen_reg_rtx (XFmode);
16753 (define_expand "logb<mode>2"
16754 [(use (match_operand:MODEF 0 "register_operand" ""))
16755 (use (match_operand:MODEF 1 "register_operand" ""))]
16756 "TARGET_USE_FANCY_MATH_387
16757 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16758 || TARGET_MIX_SSE_I387)
16759 && flag_unsafe_math_optimizations"
16761 rtx op0 = gen_reg_rtx (XFmode);
16762 rtx op1 = gen_reg_rtx (XFmode);
16764 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16765 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16769 (define_expand "ilogbxf2"
16770 [(use (match_operand:SI 0 "register_operand" ""))
16771 (use (match_operand:XF 1 "register_operand" ""))]
16772 "TARGET_USE_FANCY_MATH_387
16773 && flag_unsafe_math_optimizations"
16777 if (optimize_insn_for_size_p ())
16780 op0 = gen_reg_rtx (XFmode);
16781 op1 = gen_reg_rtx (XFmode);
16783 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16784 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16788 (define_expand "ilogb<mode>2"
16789 [(use (match_operand:SI 0 "register_operand" ""))
16790 (use (match_operand:MODEF 1 "register_operand" ""))]
16791 "TARGET_USE_FANCY_MATH_387
16792 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16793 || TARGET_MIX_SSE_I387)
16794 && flag_unsafe_math_optimizations"
16798 if (optimize_insn_for_size_p ())
16801 op0 = gen_reg_rtx (XFmode);
16802 op1 = gen_reg_rtx (XFmode);
16804 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16805 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16809 (define_insn "*f2xm1xf2_i387"
16810 [(set (match_operand:XF 0 "register_operand" "=f")
16811 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16813 "TARGET_USE_FANCY_MATH_387
16814 && flag_unsafe_math_optimizations"
16816 [(set_attr "type" "fpspc")
16817 (set_attr "mode" "XF")])
16819 (define_insn "*fscalexf4_i387"
16820 [(set (match_operand:XF 0 "register_operand" "=f")
16821 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16822 (match_operand:XF 3 "register_operand" "1")]
16823 UNSPEC_FSCALE_FRACT))
16824 (set (match_operand:XF 1 "register_operand" "=u")
16825 (unspec:XF [(match_dup 2) (match_dup 3)]
16826 UNSPEC_FSCALE_EXP))]
16827 "TARGET_USE_FANCY_MATH_387
16828 && flag_unsafe_math_optimizations"
16830 [(set_attr "type" "fpspc")
16831 (set_attr "mode" "XF")])
16833 (define_expand "expNcorexf3"
16834 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16835 (match_operand:XF 2 "register_operand" "")))
16836 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16837 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16838 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16839 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16840 (parallel [(set (match_operand:XF 0 "register_operand" "")
16841 (unspec:XF [(match_dup 8) (match_dup 4)]
16842 UNSPEC_FSCALE_FRACT))
16844 (unspec:XF [(match_dup 8) (match_dup 4)]
16845 UNSPEC_FSCALE_EXP))])]
16846 "TARGET_USE_FANCY_MATH_387
16847 && flag_unsafe_math_optimizations"
16851 if (optimize_insn_for_size_p ())
16854 for (i = 3; i < 10; i++)
16855 operands[i] = gen_reg_rtx (XFmode);
16857 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16860 (define_expand "expxf2"
16861 [(use (match_operand:XF 0 "register_operand" ""))
16862 (use (match_operand:XF 1 "register_operand" ""))]
16863 "TARGET_USE_FANCY_MATH_387
16864 && flag_unsafe_math_optimizations"
16868 if (optimize_insn_for_size_p ())
16871 op2 = gen_reg_rtx (XFmode);
16872 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16874 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16878 (define_expand "exp<mode>2"
16879 [(use (match_operand:MODEF 0 "register_operand" ""))
16880 (use (match_operand:MODEF 1 "general_operand" ""))]
16881 "TARGET_USE_FANCY_MATH_387
16882 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16883 || TARGET_MIX_SSE_I387)
16884 && flag_unsafe_math_optimizations"
16888 if (optimize_insn_for_size_p ())
16891 op0 = gen_reg_rtx (XFmode);
16892 op1 = gen_reg_rtx (XFmode);
16894 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16895 emit_insn (gen_expxf2 (op0, op1));
16896 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16900 (define_expand "exp10xf2"
16901 [(use (match_operand:XF 0 "register_operand" ""))
16902 (use (match_operand:XF 1 "register_operand" ""))]
16903 "TARGET_USE_FANCY_MATH_387
16904 && flag_unsafe_math_optimizations"
16908 if (optimize_insn_for_size_p ())
16911 op2 = gen_reg_rtx (XFmode);
16912 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16914 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16918 (define_expand "exp10<mode>2"
16919 [(use (match_operand:MODEF 0 "register_operand" ""))
16920 (use (match_operand:MODEF 1 "general_operand" ""))]
16921 "TARGET_USE_FANCY_MATH_387
16922 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16923 || TARGET_MIX_SSE_I387)
16924 && flag_unsafe_math_optimizations"
16928 if (optimize_insn_for_size_p ())
16931 op0 = gen_reg_rtx (XFmode);
16932 op1 = gen_reg_rtx (XFmode);
16934 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16935 emit_insn (gen_exp10xf2 (op0, op1));
16936 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16940 (define_expand "exp2xf2"
16941 [(use (match_operand:XF 0 "register_operand" ""))
16942 (use (match_operand:XF 1 "register_operand" ""))]
16943 "TARGET_USE_FANCY_MATH_387
16944 && flag_unsafe_math_optimizations"
16948 if (optimize_insn_for_size_p ())
16951 op2 = gen_reg_rtx (XFmode);
16952 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16954 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16958 (define_expand "exp2<mode>2"
16959 [(use (match_operand:MODEF 0 "register_operand" ""))
16960 (use (match_operand:MODEF 1 "general_operand" ""))]
16961 "TARGET_USE_FANCY_MATH_387
16962 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16963 || TARGET_MIX_SSE_I387)
16964 && flag_unsafe_math_optimizations"
16968 if (optimize_insn_for_size_p ())
16971 op0 = gen_reg_rtx (XFmode);
16972 op1 = gen_reg_rtx (XFmode);
16974 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16975 emit_insn (gen_exp2xf2 (op0, op1));
16976 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16980 (define_expand "expm1xf2"
16981 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16983 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16984 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16985 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16986 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16987 (parallel [(set (match_dup 7)
16988 (unspec:XF [(match_dup 6) (match_dup 4)]
16989 UNSPEC_FSCALE_FRACT))
16991 (unspec:XF [(match_dup 6) (match_dup 4)]
16992 UNSPEC_FSCALE_EXP))])
16993 (parallel [(set (match_dup 10)
16994 (unspec:XF [(match_dup 9) (match_dup 8)]
16995 UNSPEC_FSCALE_FRACT))
16996 (set (match_dup 11)
16997 (unspec:XF [(match_dup 9) (match_dup 8)]
16998 UNSPEC_FSCALE_EXP))])
16999 (set (match_dup 12) (minus:XF (match_dup 10)
17000 (float_extend:XF (match_dup 13))))
17001 (set (match_operand:XF 0 "register_operand" "")
17002 (plus:XF (match_dup 12) (match_dup 7)))]
17003 "TARGET_USE_FANCY_MATH_387
17004 && flag_unsafe_math_optimizations"
17008 if (optimize_insn_for_size_p ())
17011 for (i = 2; i < 13; i++)
17012 operands[i] = gen_reg_rtx (XFmode);
17015 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17017 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17020 (define_expand "expm1<mode>2"
17021 [(use (match_operand:MODEF 0 "register_operand" ""))
17022 (use (match_operand:MODEF 1 "general_operand" ""))]
17023 "TARGET_USE_FANCY_MATH_387
17024 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17025 || TARGET_MIX_SSE_I387)
17026 && flag_unsafe_math_optimizations"
17030 if (optimize_insn_for_size_p ())
17033 op0 = gen_reg_rtx (XFmode);
17034 op1 = gen_reg_rtx (XFmode);
17036 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17037 emit_insn (gen_expm1xf2 (op0, op1));
17038 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17042 (define_expand "ldexpxf3"
17043 [(set (match_dup 3)
17044 (float:XF (match_operand:SI 2 "register_operand" "")))
17045 (parallel [(set (match_operand:XF 0 " register_operand" "")
17046 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17048 UNSPEC_FSCALE_FRACT))
17050 (unspec:XF [(match_dup 1) (match_dup 3)]
17051 UNSPEC_FSCALE_EXP))])]
17052 "TARGET_USE_FANCY_MATH_387
17053 && flag_unsafe_math_optimizations"
17055 if (optimize_insn_for_size_p ())
17058 operands[3] = gen_reg_rtx (XFmode);
17059 operands[4] = gen_reg_rtx (XFmode);
17062 (define_expand "ldexp<mode>3"
17063 [(use (match_operand:MODEF 0 "register_operand" ""))
17064 (use (match_operand:MODEF 1 "general_operand" ""))
17065 (use (match_operand:SI 2 "register_operand" ""))]
17066 "TARGET_USE_FANCY_MATH_387
17067 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17068 || TARGET_MIX_SSE_I387)
17069 && flag_unsafe_math_optimizations"
17073 if (optimize_insn_for_size_p ())
17076 op0 = gen_reg_rtx (XFmode);
17077 op1 = gen_reg_rtx (XFmode);
17079 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17080 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17081 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17085 (define_expand "scalbxf3"
17086 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17087 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17088 (match_operand:XF 2 "register_operand" "")]
17089 UNSPEC_FSCALE_FRACT))
17091 (unspec:XF [(match_dup 1) (match_dup 2)]
17092 UNSPEC_FSCALE_EXP))])]
17093 "TARGET_USE_FANCY_MATH_387
17094 && flag_unsafe_math_optimizations"
17096 if (optimize_insn_for_size_p ())
17099 operands[3] = gen_reg_rtx (XFmode);
17102 (define_expand "scalb<mode>3"
17103 [(use (match_operand:MODEF 0 "register_operand" ""))
17104 (use (match_operand:MODEF 1 "general_operand" ""))
17105 (use (match_operand:MODEF 2 "general_operand" ""))]
17106 "TARGET_USE_FANCY_MATH_387
17107 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17108 || TARGET_MIX_SSE_I387)
17109 && flag_unsafe_math_optimizations"
17113 if (optimize_insn_for_size_p ())
17116 op0 = gen_reg_rtx (XFmode);
17117 op1 = gen_reg_rtx (XFmode);
17118 op2 = gen_reg_rtx (XFmode);
17120 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17121 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17122 emit_insn (gen_scalbxf3 (op0, op1, op2));
17123 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17127 (define_expand "significandxf2"
17128 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17129 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17130 UNSPEC_XTRACT_FRACT))
17132 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17133 "TARGET_USE_FANCY_MATH_387
17134 && flag_unsafe_math_optimizations"
17136 operands[2] = gen_reg_rtx (XFmode);
17139 (define_expand "significand<mode>2"
17140 [(use (match_operand:MODEF 0 "register_operand" ""))
17141 (use (match_operand:MODEF 1 "register_operand" ""))]
17142 "TARGET_USE_FANCY_MATH_387
17143 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17144 || TARGET_MIX_SSE_I387)
17145 && flag_unsafe_math_optimizations"
17147 rtx op0 = gen_reg_rtx (XFmode);
17148 rtx op1 = gen_reg_rtx (XFmode);
17150 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17151 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17156 (define_insn "sse4_1_round<mode>2"
17157 [(set (match_operand:MODEF 0 "register_operand" "=x")
17158 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17159 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17162 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17163 [(set_attr "type" "ssecvt")
17164 (set_attr "prefix_extra" "1")
17165 (set_attr "prefix" "maybe_vex")
17166 (set_attr "mode" "<MODE>")])
17168 (define_insn "rintxf2"
17169 [(set (match_operand:XF 0 "register_operand" "=f")
17170 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17172 "TARGET_USE_FANCY_MATH_387
17173 && flag_unsafe_math_optimizations"
17175 [(set_attr "type" "fpspc")
17176 (set_attr "mode" "XF")])
17178 (define_expand "rint<mode>2"
17179 [(use (match_operand:MODEF 0 "register_operand" ""))
17180 (use (match_operand:MODEF 1 "register_operand" ""))]
17181 "(TARGET_USE_FANCY_MATH_387
17182 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17183 || TARGET_MIX_SSE_I387)
17184 && flag_unsafe_math_optimizations)
17185 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17186 && !flag_trapping_math)"
17188 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17189 && !flag_trapping_math)
17191 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17194 emit_insn (gen_sse4_1_round<mode>2
17195 (operands[0], operands[1], GEN_INT (0x04)));
17197 ix86_expand_rint (operand0, operand1);
17201 rtx op0 = gen_reg_rtx (XFmode);
17202 rtx op1 = gen_reg_rtx (XFmode);
17204 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17205 emit_insn (gen_rintxf2 (op0, op1));
17207 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17212 (define_expand "round<mode>2"
17213 [(match_operand:MODEF 0 "register_operand" "")
17214 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17215 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17216 && !flag_trapping_math && !flag_rounding_math"
17218 if (optimize_insn_for_size_p ())
17220 if (TARGET_64BIT || (<MODE>mode != DFmode))
17221 ix86_expand_round (operand0, operand1);
17223 ix86_expand_rounddf_32 (operand0, operand1);
17227 (define_insn_and_split "*fistdi2_1"
17228 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17229 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17231 "TARGET_USE_FANCY_MATH_387
17232 && can_create_pseudo_p ()"
17237 if (memory_operand (operands[0], VOIDmode))
17238 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17241 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17242 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17247 [(set_attr "type" "fpspc")
17248 (set_attr "mode" "DI")])
17250 (define_insn "fistdi2"
17251 [(set (match_operand:DI 0 "memory_operand" "=m")
17252 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17254 (clobber (match_scratch:XF 2 "=&1f"))]
17255 "TARGET_USE_FANCY_MATH_387"
17256 "* return output_fix_trunc (insn, operands, 0);"
17257 [(set_attr "type" "fpspc")
17258 (set_attr "mode" "DI")])
17260 (define_insn "fistdi2_with_temp"
17261 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17262 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17264 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17265 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17266 "TARGET_USE_FANCY_MATH_387"
17268 [(set_attr "type" "fpspc")
17269 (set_attr "mode" "DI")])
17272 [(set (match_operand:DI 0 "register_operand" "")
17273 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17275 (clobber (match_operand:DI 2 "memory_operand" ""))
17276 (clobber (match_scratch 3 ""))]
17278 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17279 (clobber (match_dup 3))])
17280 (set (match_dup 0) (match_dup 2))]
17284 [(set (match_operand:DI 0 "memory_operand" "")
17285 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17287 (clobber (match_operand:DI 2 "memory_operand" ""))
17288 (clobber (match_scratch 3 ""))]
17290 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17291 (clobber (match_dup 3))])]
17294 (define_insn_and_split "*fist<mode>2_1"
17295 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17296 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17298 "TARGET_USE_FANCY_MATH_387
17299 && can_create_pseudo_p ()"
17304 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17305 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17309 [(set_attr "type" "fpspc")
17310 (set_attr "mode" "<MODE>")])
17312 (define_insn "fist<mode>2"
17313 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17314 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17316 "TARGET_USE_FANCY_MATH_387"
17317 "* return output_fix_trunc (insn, operands, 0);"
17318 [(set_attr "type" "fpspc")
17319 (set_attr "mode" "<MODE>")])
17321 (define_insn "fist<mode>2_with_temp"
17322 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17323 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17325 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17326 "TARGET_USE_FANCY_MATH_387"
17328 [(set_attr "type" "fpspc")
17329 (set_attr "mode" "<MODE>")])
17332 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17333 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17335 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17337 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17338 (set (match_dup 0) (match_dup 2))]
17342 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17343 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17345 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17347 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17350 (define_expand "lrintxf<mode>2"
17351 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17352 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17354 "TARGET_USE_FANCY_MATH_387"
17357 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17358 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17359 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17360 UNSPEC_FIX_NOTRUNC))]
17361 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17362 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17365 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17366 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17367 (match_operand:MODEF 1 "register_operand" "")]
17368 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17369 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17370 && !flag_trapping_math && !flag_rounding_math"
17372 if (optimize_insn_for_size_p ())
17374 ix86_expand_lround (operand0, operand1);
17378 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17379 (define_insn_and_split "frndintxf2_floor"
17380 [(set (match_operand:XF 0 "register_operand" "")
17381 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17382 UNSPEC_FRNDINT_FLOOR))
17383 (clobber (reg:CC FLAGS_REG))]
17384 "TARGET_USE_FANCY_MATH_387
17385 && flag_unsafe_math_optimizations
17386 && can_create_pseudo_p ()"
17391 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17393 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17394 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17396 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17397 operands[2], operands[3]));
17400 [(set_attr "type" "frndint")
17401 (set_attr "i387_cw" "floor")
17402 (set_attr "mode" "XF")])
17404 (define_insn "frndintxf2_floor_i387"
17405 [(set (match_operand:XF 0 "register_operand" "=f")
17406 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17407 UNSPEC_FRNDINT_FLOOR))
17408 (use (match_operand:HI 2 "memory_operand" "m"))
17409 (use (match_operand:HI 3 "memory_operand" "m"))]
17410 "TARGET_USE_FANCY_MATH_387
17411 && flag_unsafe_math_optimizations"
17412 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17413 [(set_attr "type" "frndint")
17414 (set_attr "i387_cw" "floor")
17415 (set_attr "mode" "XF")])
17417 (define_expand "floorxf2"
17418 [(use (match_operand:XF 0 "register_operand" ""))
17419 (use (match_operand:XF 1 "register_operand" ""))]
17420 "TARGET_USE_FANCY_MATH_387
17421 && flag_unsafe_math_optimizations"
17423 if (optimize_insn_for_size_p ())
17425 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17429 (define_expand "floor<mode>2"
17430 [(use (match_operand:MODEF 0 "register_operand" ""))
17431 (use (match_operand:MODEF 1 "register_operand" ""))]
17432 "(TARGET_USE_FANCY_MATH_387
17433 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17434 || TARGET_MIX_SSE_I387)
17435 && flag_unsafe_math_optimizations)
17436 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17437 && !flag_trapping_math)"
17439 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17440 && !flag_trapping_math
17441 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17443 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17446 emit_insn (gen_sse4_1_round<mode>2
17447 (operands[0], operands[1], GEN_INT (0x01)));
17448 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17449 ix86_expand_floorceil (operand0, operand1, true);
17451 ix86_expand_floorceildf_32 (operand0, operand1, true);
17457 if (optimize_insn_for_size_p ())
17460 op0 = gen_reg_rtx (XFmode);
17461 op1 = gen_reg_rtx (XFmode);
17462 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17463 emit_insn (gen_frndintxf2_floor (op0, op1));
17465 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17470 (define_insn_and_split "*fist<mode>2_floor_1"
17471 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17472 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17473 UNSPEC_FIST_FLOOR))
17474 (clobber (reg:CC FLAGS_REG))]
17475 "TARGET_USE_FANCY_MATH_387
17476 && flag_unsafe_math_optimizations
17477 && can_create_pseudo_p ()"
17482 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17484 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17485 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17486 if (memory_operand (operands[0], VOIDmode))
17487 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17488 operands[2], operands[3]));
17491 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17492 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17493 operands[2], operands[3],
17498 [(set_attr "type" "fistp")
17499 (set_attr "i387_cw" "floor")
17500 (set_attr "mode" "<MODE>")])
17502 (define_insn "fistdi2_floor"
17503 [(set (match_operand:DI 0 "memory_operand" "=m")
17504 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17505 UNSPEC_FIST_FLOOR))
17506 (use (match_operand:HI 2 "memory_operand" "m"))
17507 (use (match_operand:HI 3 "memory_operand" "m"))
17508 (clobber (match_scratch:XF 4 "=&1f"))]
17509 "TARGET_USE_FANCY_MATH_387
17510 && flag_unsafe_math_optimizations"
17511 "* return output_fix_trunc (insn, operands, 0);"
17512 [(set_attr "type" "fistp")
17513 (set_attr "i387_cw" "floor")
17514 (set_attr "mode" "DI")])
17516 (define_insn "fistdi2_floor_with_temp"
17517 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17518 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17519 UNSPEC_FIST_FLOOR))
17520 (use (match_operand:HI 2 "memory_operand" "m,m"))
17521 (use (match_operand:HI 3 "memory_operand" "m,m"))
17522 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17523 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17524 "TARGET_USE_FANCY_MATH_387
17525 && flag_unsafe_math_optimizations"
17527 [(set_attr "type" "fistp")
17528 (set_attr "i387_cw" "floor")
17529 (set_attr "mode" "DI")])
17532 [(set (match_operand:DI 0 "register_operand" "")
17533 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17534 UNSPEC_FIST_FLOOR))
17535 (use (match_operand:HI 2 "memory_operand" ""))
17536 (use (match_operand:HI 3 "memory_operand" ""))
17537 (clobber (match_operand:DI 4 "memory_operand" ""))
17538 (clobber (match_scratch 5 ""))]
17540 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17541 (use (match_dup 2))
17542 (use (match_dup 3))
17543 (clobber (match_dup 5))])
17544 (set (match_dup 0) (match_dup 4))]
17548 [(set (match_operand:DI 0 "memory_operand" "")
17549 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17550 UNSPEC_FIST_FLOOR))
17551 (use (match_operand:HI 2 "memory_operand" ""))
17552 (use (match_operand:HI 3 "memory_operand" ""))
17553 (clobber (match_operand:DI 4 "memory_operand" ""))
17554 (clobber (match_scratch 5 ""))]
17556 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17557 (use (match_dup 2))
17558 (use (match_dup 3))
17559 (clobber (match_dup 5))])]
17562 (define_insn "fist<mode>2_floor"
17563 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17564 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17565 UNSPEC_FIST_FLOOR))
17566 (use (match_operand:HI 2 "memory_operand" "m"))
17567 (use (match_operand:HI 3 "memory_operand" "m"))]
17568 "TARGET_USE_FANCY_MATH_387
17569 && flag_unsafe_math_optimizations"
17570 "* return output_fix_trunc (insn, operands, 0);"
17571 [(set_attr "type" "fistp")
17572 (set_attr "i387_cw" "floor")
17573 (set_attr "mode" "<MODE>")])
17575 (define_insn "fist<mode>2_floor_with_temp"
17576 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17577 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17578 UNSPEC_FIST_FLOOR))
17579 (use (match_operand:HI 2 "memory_operand" "m,m"))
17580 (use (match_operand:HI 3 "memory_operand" "m,m"))
17581 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17582 "TARGET_USE_FANCY_MATH_387
17583 && flag_unsafe_math_optimizations"
17585 [(set_attr "type" "fistp")
17586 (set_attr "i387_cw" "floor")
17587 (set_attr "mode" "<MODE>")])
17590 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17591 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17592 UNSPEC_FIST_FLOOR))
17593 (use (match_operand:HI 2 "memory_operand" ""))
17594 (use (match_operand:HI 3 "memory_operand" ""))
17595 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17597 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17598 UNSPEC_FIST_FLOOR))
17599 (use (match_dup 2))
17600 (use (match_dup 3))])
17601 (set (match_dup 0) (match_dup 4))]
17605 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17606 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17607 UNSPEC_FIST_FLOOR))
17608 (use (match_operand:HI 2 "memory_operand" ""))
17609 (use (match_operand:HI 3 "memory_operand" ""))
17610 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17612 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17613 UNSPEC_FIST_FLOOR))
17614 (use (match_dup 2))
17615 (use (match_dup 3))])]
17618 (define_expand "lfloorxf<mode>2"
17619 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17620 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17621 UNSPEC_FIST_FLOOR))
17622 (clobber (reg:CC FLAGS_REG))])]
17623 "TARGET_USE_FANCY_MATH_387
17624 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17625 && flag_unsafe_math_optimizations"
17628 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17629 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17630 (match_operand:MODEF 1 "register_operand" "")]
17631 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17632 && !flag_trapping_math"
17634 if (TARGET_64BIT && optimize_insn_for_size_p ())
17636 ix86_expand_lfloorceil (operand0, operand1, true);
17640 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17641 (define_insn_and_split "frndintxf2_ceil"
17642 [(set (match_operand:XF 0 "register_operand" "")
17643 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17644 UNSPEC_FRNDINT_CEIL))
17645 (clobber (reg:CC FLAGS_REG))]
17646 "TARGET_USE_FANCY_MATH_387
17647 && flag_unsafe_math_optimizations
17648 && can_create_pseudo_p ()"
17653 ix86_optimize_mode_switching[I387_CEIL] = 1;
17655 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17656 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17658 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17659 operands[2], operands[3]));
17662 [(set_attr "type" "frndint")
17663 (set_attr "i387_cw" "ceil")
17664 (set_attr "mode" "XF")])
17666 (define_insn "frndintxf2_ceil_i387"
17667 [(set (match_operand:XF 0 "register_operand" "=f")
17668 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17669 UNSPEC_FRNDINT_CEIL))
17670 (use (match_operand:HI 2 "memory_operand" "m"))
17671 (use (match_operand:HI 3 "memory_operand" "m"))]
17672 "TARGET_USE_FANCY_MATH_387
17673 && flag_unsafe_math_optimizations"
17674 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17675 [(set_attr "type" "frndint")
17676 (set_attr "i387_cw" "ceil")
17677 (set_attr "mode" "XF")])
17679 (define_expand "ceilxf2"
17680 [(use (match_operand:XF 0 "register_operand" ""))
17681 (use (match_operand:XF 1 "register_operand" ""))]
17682 "TARGET_USE_FANCY_MATH_387
17683 && flag_unsafe_math_optimizations"
17685 if (optimize_insn_for_size_p ())
17687 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17691 (define_expand "ceil<mode>2"
17692 [(use (match_operand:MODEF 0 "register_operand" ""))
17693 (use (match_operand:MODEF 1 "register_operand" ""))]
17694 "(TARGET_USE_FANCY_MATH_387
17695 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17696 || TARGET_MIX_SSE_I387)
17697 && flag_unsafe_math_optimizations)
17698 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17699 && !flag_trapping_math)"
17701 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17702 && !flag_trapping_math
17703 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17706 emit_insn (gen_sse4_1_round<mode>2
17707 (operands[0], operands[1], GEN_INT (0x02)));
17708 else if (optimize_insn_for_size_p ())
17710 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17711 ix86_expand_floorceil (operand0, operand1, false);
17713 ix86_expand_floorceildf_32 (operand0, operand1, false);
17719 if (optimize_insn_for_size_p ())
17722 op0 = gen_reg_rtx (XFmode);
17723 op1 = gen_reg_rtx (XFmode);
17724 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17725 emit_insn (gen_frndintxf2_ceil (op0, op1));
17727 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17732 (define_insn_and_split "*fist<mode>2_ceil_1"
17733 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17734 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17736 (clobber (reg:CC FLAGS_REG))]
17737 "TARGET_USE_FANCY_MATH_387
17738 && flag_unsafe_math_optimizations
17739 && can_create_pseudo_p ()"
17744 ix86_optimize_mode_switching[I387_CEIL] = 1;
17746 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17747 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17748 if (memory_operand (operands[0], VOIDmode))
17749 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17750 operands[2], operands[3]));
17753 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17754 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17755 operands[2], operands[3],
17760 [(set_attr "type" "fistp")
17761 (set_attr "i387_cw" "ceil")
17762 (set_attr "mode" "<MODE>")])
17764 (define_insn "fistdi2_ceil"
17765 [(set (match_operand:DI 0 "memory_operand" "=m")
17766 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17768 (use (match_operand:HI 2 "memory_operand" "m"))
17769 (use (match_operand:HI 3 "memory_operand" "m"))
17770 (clobber (match_scratch:XF 4 "=&1f"))]
17771 "TARGET_USE_FANCY_MATH_387
17772 && flag_unsafe_math_optimizations"
17773 "* return output_fix_trunc (insn, operands, 0);"
17774 [(set_attr "type" "fistp")
17775 (set_attr "i387_cw" "ceil")
17776 (set_attr "mode" "DI")])
17778 (define_insn "fistdi2_ceil_with_temp"
17779 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17780 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17782 (use (match_operand:HI 2 "memory_operand" "m,m"))
17783 (use (match_operand:HI 3 "memory_operand" "m,m"))
17784 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17785 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17786 "TARGET_USE_FANCY_MATH_387
17787 && flag_unsafe_math_optimizations"
17789 [(set_attr "type" "fistp")
17790 (set_attr "i387_cw" "ceil")
17791 (set_attr "mode" "DI")])
17794 [(set (match_operand:DI 0 "register_operand" "")
17795 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17797 (use (match_operand:HI 2 "memory_operand" ""))
17798 (use (match_operand:HI 3 "memory_operand" ""))
17799 (clobber (match_operand:DI 4 "memory_operand" ""))
17800 (clobber (match_scratch 5 ""))]
17802 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17803 (use (match_dup 2))
17804 (use (match_dup 3))
17805 (clobber (match_dup 5))])
17806 (set (match_dup 0) (match_dup 4))]
17810 [(set (match_operand:DI 0 "memory_operand" "")
17811 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17813 (use (match_operand:HI 2 "memory_operand" ""))
17814 (use (match_operand:HI 3 "memory_operand" ""))
17815 (clobber (match_operand:DI 4 "memory_operand" ""))
17816 (clobber (match_scratch 5 ""))]
17818 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17819 (use (match_dup 2))
17820 (use (match_dup 3))
17821 (clobber (match_dup 5))])]
17824 (define_insn "fist<mode>2_ceil"
17825 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17826 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17828 (use (match_operand:HI 2 "memory_operand" "m"))
17829 (use (match_operand:HI 3 "memory_operand" "m"))]
17830 "TARGET_USE_FANCY_MATH_387
17831 && flag_unsafe_math_optimizations"
17832 "* return output_fix_trunc (insn, operands, 0);"
17833 [(set_attr "type" "fistp")
17834 (set_attr "i387_cw" "ceil")
17835 (set_attr "mode" "<MODE>")])
17837 (define_insn "fist<mode>2_ceil_with_temp"
17838 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17839 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17841 (use (match_operand:HI 2 "memory_operand" "m,m"))
17842 (use (match_operand:HI 3 "memory_operand" "m,m"))
17843 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17844 "TARGET_USE_FANCY_MATH_387
17845 && flag_unsafe_math_optimizations"
17847 [(set_attr "type" "fistp")
17848 (set_attr "i387_cw" "ceil")
17849 (set_attr "mode" "<MODE>")])
17852 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17853 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17855 (use (match_operand:HI 2 "memory_operand" ""))
17856 (use (match_operand:HI 3 "memory_operand" ""))
17857 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17859 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17861 (use (match_dup 2))
17862 (use (match_dup 3))])
17863 (set (match_dup 0) (match_dup 4))]
17867 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17868 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17870 (use (match_operand:HI 2 "memory_operand" ""))
17871 (use (match_operand:HI 3 "memory_operand" ""))
17872 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17874 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17876 (use (match_dup 2))
17877 (use (match_dup 3))])]
17880 (define_expand "lceilxf<mode>2"
17881 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17882 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17884 (clobber (reg:CC FLAGS_REG))])]
17885 "TARGET_USE_FANCY_MATH_387
17886 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17887 && flag_unsafe_math_optimizations"
17890 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17891 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17892 (match_operand:MODEF 1 "register_operand" "")]
17893 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17894 && !flag_trapping_math"
17896 ix86_expand_lfloorceil (operand0, operand1, false);
17900 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17901 (define_insn_and_split "frndintxf2_trunc"
17902 [(set (match_operand:XF 0 "register_operand" "")
17903 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17904 UNSPEC_FRNDINT_TRUNC))
17905 (clobber (reg:CC FLAGS_REG))]
17906 "TARGET_USE_FANCY_MATH_387
17907 && flag_unsafe_math_optimizations
17908 && can_create_pseudo_p ()"
17913 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17915 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17916 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17918 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17919 operands[2], operands[3]));
17922 [(set_attr "type" "frndint")
17923 (set_attr "i387_cw" "trunc")
17924 (set_attr "mode" "XF")])
17926 (define_insn "frndintxf2_trunc_i387"
17927 [(set (match_operand:XF 0 "register_operand" "=f")
17928 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17929 UNSPEC_FRNDINT_TRUNC))
17930 (use (match_operand:HI 2 "memory_operand" "m"))
17931 (use (match_operand:HI 3 "memory_operand" "m"))]
17932 "TARGET_USE_FANCY_MATH_387
17933 && flag_unsafe_math_optimizations"
17934 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17935 [(set_attr "type" "frndint")
17936 (set_attr "i387_cw" "trunc")
17937 (set_attr "mode" "XF")])
17939 (define_expand "btruncxf2"
17940 [(use (match_operand:XF 0 "register_operand" ""))
17941 (use (match_operand:XF 1 "register_operand" ""))]
17942 "TARGET_USE_FANCY_MATH_387
17943 && flag_unsafe_math_optimizations"
17945 if (optimize_insn_for_size_p ())
17947 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17951 (define_expand "btrunc<mode>2"
17952 [(use (match_operand:MODEF 0 "register_operand" ""))
17953 (use (match_operand:MODEF 1 "register_operand" ""))]
17954 "(TARGET_USE_FANCY_MATH_387
17955 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17956 || TARGET_MIX_SSE_I387)
17957 && flag_unsafe_math_optimizations)
17958 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17959 && !flag_trapping_math)"
17961 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17962 && !flag_trapping_math
17963 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17966 emit_insn (gen_sse4_1_round<mode>2
17967 (operands[0], operands[1], GEN_INT (0x03)));
17968 else if (optimize_insn_for_size_p ())
17970 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17971 ix86_expand_trunc (operand0, operand1);
17973 ix86_expand_truncdf_32 (operand0, operand1);
17979 if (optimize_insn_for_size_p ())
17982 op0 = gen_reg_rtx (XFmode);
17983 op1 = gen_reg_rtx (XFmode);
17984 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17985 emit_insn (gen_frndintxf2_trunc (op0, op1));
17987 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17992 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17993 (define_insn_and_split "frndintxf2_mask_pm"
17994 [(set (match_operand:XF 0 "register_operand" "")
17995 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17996 UNSPEC_FRNDINT_MASK_PM))
17997 (clobber (reg:CC FLAGS_REG))]
17998 "TARGET_USE_FANCY_MATH_387
17999 && flag_unsafe_math_optimizations
18000 && can_create_pseudo_p ()"
18005 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18007 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18008 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18010 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18011 operands[2], operands[3]));
18014 [(set_attr "type" "frndint")
18015 (set_attr "i387_cw" "mask_pm")
18016 (set_attr "mode" "XF")])
18018 (define_insn "frndintxf2_mask_pm_i387"
18019 [(set (match_operand:XF 0 "register_operand" "=f")
18020 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18021 UNSPEC_FRNDINT_MASK_PM))
18022 (use (match_operand:HI 2 "memory_operand" "m"))
18023 (use (match_operand:HI 3 "memory_operand" "m"))]
18024 "TARGET_USE_FANCY_MATH_387
18025 && flag_unsafe_math_optimizations"
18026 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18027 [(set_attr "type" "frndint")
18028 (set_attr "i387_cw" "mask_pm")
18029 (set_attr "mode" "XF")])
18031 (define_expand "nearbyintxf2"
18032 [(use (match_operand:XF 0 "register_operand" ""))
18033 (use (match_operand:XF 1 "register_operand" ""))]
18034 "TARGET_USE_FANCY_MATH_387
18035 && flag_unsafe_math_optimizations"
18037 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18042 (define_expand "nearbyint<mode>2"
18043 [(use (match_operand:MODEF 0 "register_operand" ""))
18044 (use (match_operand:MODEF 1 "register_operand" ""))]
18045 "TARGET_USE_FANCY_MATH_387
18046 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18047 || TARGET_MIX_SSE_I387)
18048 && flag_unsafe_math_optimizations"
18050 rtx op0 = gen_reg_rtx (XFmode);
18051 rtx op1 = gen_reg_rtx (XFmode);
18053 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18054 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18056 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18060 (define_insn "fxam<mode>2_i387"
18061 [(set (match_operand:HI 0 "register_operand" "=a")
18063 [(match_operand:X87MODEF 1 "register_operand" "f")]
18065 "TARGET_USE_FANCY_MATH_387"
18066 "fxam\n\tfnstsw\t%0"
18067 [(set_attr "type" "multi")
18068 (set_attr "length" "4")
18069 (set_attr "unit" "i387")
18070 (set_attr "mode" "<MODE>")])
18072 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18073 [(set (match_operand:HI 0 "register_operand" "")
18075 [(match_operand:MODEF 1 "memory_operand" "")]
18077 "TARGET_USE_FANCY_MATH_387
18078 && can_create_pseudo_p ()"
18081 [(set (match_dup 2)(match_dup 1))
18083 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18085 operands[2] = gen_reg_rtx (<MODE>mode);
18087 MEM_VOLATILE_P (operands[1]) = 1;
18089 [(set_attr "type" "multi")
18090 (set_attr "unit" "i387")
18091 (set_attr "mode" "<MODE>")])
18093 (define_expand "isinfxf2"
18094 [(use (match_operand:SI 0 "register_operand" ""))
18095 (use (match_operand:XF 1 "register_operand" ""))]
18096 "TARGET_USE_FANCY_MATH_387
18097 && TARGET_C99_FUNCTIONS"
18099 rtx mask = GEN_INT (0x45);
18100 rtx val = GEN_INT (0x05);
18104 rtx scratch = gen_reg_rtx (HImode);
18105 rtx res = gen_reg_rtx (QImode);
18107 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18109 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18110 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18111 cond = gen_rtx_fmt_ee (EQ, QImode,
18112 gen_rtx_REG (CCmode, FLAGS_REG),
18114 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18115 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18119 (define_expand "isinf<mode>2"
18120 [(use (match_operand:SI 0 "register_operand" ""))
18121 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18122 "TARGET_USE_FANCY_MATH_387
18123 && TARGET_C99_FUNCTIONS
18124 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18126 rtx mask = GEN_INT (0x45);
18127 rtx val = GEN_INT (0x05);
18131 rtx scratch = gen_reg_rtx (HImode);
18132 rtx res = gen_reg_rtx (QImode);
18134 /* Remove excess precision by forcing value through memory. */
18135 if (memory_operand (operands[1], VOIDmode))
18136 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18139 enum ix86_stack_slot slot = (virtuals_instantiated
18142 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18144 emit_move_insn (temp, operands[1]);
18145 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18148 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18149 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18150 cond = gen_rtx_fmt_ee (EQ, QImode,
18151 gen_rtx_REG (CCmode, FLAGS_REG),
18153 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18154 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18158 (define_expand "signbit<mode>2"
18159 [(use (match_operand:SI 0 "register_operand" ""))
18160 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18161 "TARGET_USE_FANCY_MATH_387
18162 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18164 rtx mask = GEN_INT (0x0200);
18166 rtx scratch = gen_reg_rtx (HImode);
18168 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18169 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18173 ;; Block operation instructions
18176 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18179 [(set_attr "length" "1")
18180 (set_attr "length_immediate" "0")
18181 (set_attr "modrm" "0")])
18183 (define_expand "movmemsi"
18184 [(use (match_operand:BLK 0 "memory_operand" ""))
18185 (use (match_operand:BLK 1 "memory_operand" ""))
18186 (use (match_operand:SI 2 "nonmemory_operand" ""))
18187 (use (match_operand:SI 3 "const_int_operand" ""))
18188 (use (match_operand:SI 4 "const_int_operand" ""))
18189 (use (match_operand:SI 5 "const_int_operand" ""))]
18192 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18193 operands[4], operands[5]))
18199 (define_expand "movmemdi"
18200 [(use (match_operand:BLK 0 "memory_operand" ""))
18201 (use (match_operand:BLK 1 "memory_operand" ""))
18202 (use (match_operand:DI 2 "nonmemory_operand" ""))
18203 (use (match_operand:DI 3 "const_int_operand" ""))
18204 (use (match_operand:SI 4 "const_int_operand" ""))
18205 (use (match_operand:SI 5 "const_int_operand" ""))]
18208 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18209 operands[4], operands[5]))
18215 ;; Most CPUs don't like single string operations
18216 ;; Handle this case here to simplify previous expander.
18218 (define_expand "strmov"
18219 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18220 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18221 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18222 (clobber (reg:CC FLAGS_REG))])
18223 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18224 (clobber (reg:CC FLAGS_REG))])]
18227 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18229 /* If .md ever supports :P for Pmode, these can be directly
18230 in the pattern above. */
18231 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18232 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18234 /* Can't use this if the user has appropriated esi or edi. */
18235 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18236 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18238 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18239 operands[2], operands[3],
18240 operands[5], operands[6]));
18244 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18247 (define_expand "strmov_singleop"
18248 [(parallel [(set (match_operand 1 "memory_operand" "")
18249 (match_operand 3 "memory_operand" ""))
18250 (set (match_operand 0 "register_operand" "")
18251 (match_operand 4 "" ""))
18252 (set (match_operand 2 "register_operand" "")
18253 (match_operand 5 "" ""))])]
18255 "ix86_current_function_needs_cld = 1;")
18257 (define_insn "*strmovdi_rex_1"
18258 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18259 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18260 (set (match_operand:DI 0 "register_operand" "=D")
18261 (plus:DI (match_dup 2)
18263 (set (match_operand:DI 1 "register_operand" "=S")
18264 (plus:DI (match_dup 3)
18268 [(set_attr "type" "str")
18269 (set_attr "mode" "DI")
18270 (set_attr "memory" "both")])
18272 (define_insn "*strmovsi_1"
18273 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18274 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18275 (set (match_operand:SI 0 "register_operand" "=D")
18276 (plus:SI (match_dup 2)
18278 (set (match_operand:SI 1 "register_operand" "=S")
18279 (plus:SI (match_dup 3)
18283 [(set_attr "type" "str")
18284 (set_attr "mode" "SI")
18285 (set_attr "memory" "both")])
18287 (define_insn "*strmovsi_rex_1"
18288 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18289 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18290 (set (match_operand:DI 0 "register_operand" "=D")
18291 (plus:DI (match_dup 2)
18293 (set (match_operand:DI 1 "register_operand" "=S")
18294 (plus:DI (match_dup 3)
18298 [(set_attr "type" "str")
18299 (set_attr "mode" "SI")
18300 (set_attr "memory" "both")])
18302 (define_insn "*strmovhi_1"
18303 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18304 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18305 (set (match_operand:SI 0 "register_operand" "=D")
18306 (plus:SI (match_dup 2)
18308 (set (match_operand:SI 1 "register_operand" "=S")
18309 (plus:SI (match_dup 3)
18313 [(set_attr "type" "str")
18314 (set_attr "memory" "both")
18315 (set_attr "mode" "HI")])
18317 (define_insn "*strmovhi_rex_1"
18318 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18319 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18320 (set (match_operand:DI 0 "register_operand" "=D")
18321 (plus:DI (match_dup 2)
18323 (set (match_operand:DI 1 "register_operand" "=S")
18324 (plus:DI (match_dup 3)
18328 [(set_attr "type" "str")
18329 (set_attr "memory" "both")
18330 (set_attr "mode" "HI")])
18332 (define_insn "*strmovqi_1"
18333 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18334 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18335 (set (match_operand:SI 0 "register_operand" "=D")
18336 (plus:SI (match_dup 2)
18338 (set (match_operand:SI 1 "register_operand" "=S")
18339 (plus:SI (match_dup 3)
18343 [(set_attr "type" "str")
18344 (set_attr "memory" "both")
18345 (set_attr "mode" "QI")])
18347 (define_insn "*strmovqi_rex_1"
18348 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18349 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18350 (set (match_operand:DI 0 "register_operand" "=D")
18351 (plus:DI (match_dup 2)
18353 (set (match_operand:DI 1 "register_operand" "=S")
18354 (plus:DI (match_dup 3)
18358 [(set_attr "type" "str")
18359 (set_attr "memory" "both")
18360 (set_attr "prefix_rex" "0")
18361 (set_attr "mode" "QI")])
18363 (define_expand "rep_mov"
18364 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18365 (set (match_operand 0 "register_operand" "")
18366 (match_operand 5 "" ""))
18367 (set (match_operand 2 "register_operand" "")
18368 (match_operand 6 "" ""))
18369 (set (match_operand 1 "memory_operand" "")
18370 (match_operand 3 "memory_operand" ""))
18371 (use (match_dup 4))])]
18373 "ix86_current_function_needs_cld = 1;")
18375 (define_insn "*rep_movdi_rex64"
18376 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18377 (set (match_operand:DI 0 "register_operand" "=D")
18378 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18380 (match_operand:DI 3 "register_operand" "0")))
18381 (set (match_operand:DI 1 "register_operand" "=S")
18382 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18383 (match_operand:DI 4 "register_operand" "1")))
18384 (set (mem:BLK (match_dup 3))
18385 (mem:BLK (match_dup 4)))
18386 (use (match_dup 5))]
18389 [(set_attr "type" "str")
18390 (set_attr "prefix_rep" "1")
18391 (set_attr "memory" "both")
18392 (set_attr "mode" "DI")])
18394 (define_insn "*rep_movsi"
18395 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18396 (set (match_operand:SI 0 "register_operand" "=D")
18397 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18399 (match_operand:SI 3 "register_operand" "0")))
18400 (set (match_operand:SI 1 "register_operand" "=S")
18401 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18402 (match_operand:SI 4 "register_operand" "1")))
18403 (set (mem:BLK (match_dup 3))
18404 (mem:BLK (match_dup 4)))
18405 (use (match_dup 5))]
18408 [(set_attr "type" "str")
18409 (set_attr "prefix_rep" "1")
18410 (set_attr "memory" "both")
18411 (set_attr "mode" "SI")])
18413 (define_insn "*rep_movsi_rex64"
18414 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18415 (set (match_operand:DI 0 "register_operand" "=D")
18416 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18418 (match_operand:DI 3 "register_operand" "0")))
18419 (set (match_operand:DI 1 "register_operand" "=S")
18420 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18421 (match_operand:DI 4 "register_operand" "1")))
18422 (set (mem:BLK (match_dup 3))
18423 (mem:BLK (match_dup 4)))
18424 (use (match_dup 5))]
18427 [(set_attr "type" "str")
18428 (set_attr "prefix_rep" "1")
18429 (set_attr "memory" "both")
18430 (set_attr "mode" "SI")])
18432 (define_insn "*rep_movqi"
18433 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18434 (set (match_operand:SI 0 "register_operand" "=D")
18435 (plus:SI (match_operand:SI 3 "register_operand" "0")
18436 (match_operand:SI 5 "register_operand" "2")))
18437 (set (match_operand:SI 1 "register_operand" "=S")
18438 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18439 (set (mem:BLK (match_dup 3))
18440 (mem:BLK (match_dup 4)))
18441 (use (match_dup 5))]
18444 [(set_attr "type" "str")
18445 (set_attr "prefix_rep" "1")
18446 (set_attr "memory" "both")
18447 (set_attr "mode" "SI")])
18449 (define_insn "*rep_movqi_rex64"
18450 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18451 (set (match_operand:DI 0 "register_operand" "=D")
18452 (plus:DI (match_operand:DI 3 "register_operand" "0")
18453 (match_operand:DI 5 "register_operand" "2")))
18454 (set (match_operand:DI 1 "register_operand" "=S")
18455 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18456 (set (mem:BLK (match_dup 3))
18457 (mem:BLK (match_dup 4)))
18458 (use (match_dup 5))]
18461 [(set_attr "type" "str")
18462 (set_attr "prefix_rep" "1")
18463 (set_attr "memory" "both")
18464 (set_attr "mode" "SI")])
18466 (define_expand "setmemsi"
18467 [(use (match_operand:BLK 0 "memory_operand" ""))
18468 (use (match_operand:SI 1 "nonmemory_operand" ""))
18469 (use (match_operand 2 "const_int_operand" ""))
18470 (use (match_operand 3 "const_int_operand" ""))
18471 (use (match_operand:SI 4 "const_int_operand" ""))
18472 (use (match_operand:SI 5 "const_int_operand" ""))]
18475 if (ix86_expand_setmem (operands[0], operands[1],
18476 operands[2], operands[3],
18477 operands[4], operands[5]))
18483 (define_expand "setmemdi"
18484 [(use (match_operand:BLK 0 "memory_operand" ""))
18485 (use (match_operand:DI 1 "nonmemory_operand" ""))
18486 (use (match_operand 2 "const_int_operand" ""))
18487 (use (match_operand 3 "const_int_operand" ""))
18488 (use (match_operand 4 "const_int_operand" ""))
18489 (use (match_operand 5 "const_int_operand" ""))]
18492 if (ix86_expand_setmem (operands[0], operands[1],
18493 operands[2], operands[3],
18494 operands[4], operands[5]))
18500 ;; Most CPUs don't like single string operations
18501 ;; Handle this case here to simplify previous expander.
18503 (define_expand "strset"
18504 [(set (match_operand 1 "memory_operand" "")
18505 (match_operand 2 "register_operand" ""))
18506 (parallel [(set (match_operand 0 "register_operand" "")
18508 (clobber (reg:CC FLAGS_REG))])]
18511 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18512 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18514 /* If .md ever supports :P for Pmode, this can be directly
18515 in the pattern above. */
18516 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18517 GEN_INT (GET_MODE_SIZE (GET_MODE
18519 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18521 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18527 (define_expand "strset_singleop"
18528 [(parallel [(set (match_operand 1 "memory_operand" "")
18529 (match_operand 2 "register_operand" ""))
18530 (set (match_operand 0 "register_operand" "")
18531 (match_operand 3 "" ""))])]
18533 "ix86_current_function_needs_cld = 1;")
18535 (define_insn "*strsetdi_rex_1"
18536 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18537 (match_operand:DI 2 "register_operand" "a"))
18538 (set (match_operand:DI 0 "register_operand" "=D")
18539 (plus:DI (match_dup 1)
18543 [(set_attr "type" "str")
18544 (set_attr "memory" "store")
18545 (set_attr "mode" "DI")])
18547 (define_insn "*strsetsi_1"
18548 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18549 (match_operand:SI 2 "register_operand" "a"))
18550 (set (match_operand:SI 0 "register_operand" "=D")
18551 (plus:SI (match_dup 1)
18555 [(set_attr "type" "str")
18556 (set_attr "memory" "store")
18557 (set_attr "mode" "SI")])
18559 (define_insn "*strsetsi_rex_1"
18560 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18561 (match_operand:SI 2 "register_operand" "a"))
18562 (set (match_operand:DI 0 "register_operand" "=D")
18563 (plus:DI (match_dup 1)
18567 [(set_attr "type" "str")
18568 (set_attr "memory" "store")
18569 (set_attr "mode" "SI")])
18571 (define_insn "*strsethi_1"
18572 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18573 (match_operand:HI 2 "register_operand" "a"))
18574 (set (match_operand:SI 0 "register_operand" "=D")
18575 (plus:SI (match_dup 1)
18579 [(set_attr "type" "str")
18580 (set_attr "memory" "store")
18581 (set_attr "mode" "HI")])
18583 (define_insn "*strsethi_rex_1"
18584 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18585 (match_operand:HI 2 "register_operand" "a"))
18586 (set (match_operand:DI 0 "register_operand" "=D")
18587 (plus:DI (match_dup 1)
18591 [(set_attr "type" "str")
18592 (set_attr "memory" "store")
18593 (set_attr "mode" "HI")])
18595 (define_insn "*strsetqi_1"
18596 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18597 (match_operand:QI 2 "register_operand" "a"))
18598 (set (match_operand:SI 0 "register_operand" "=D")
18599 (plus:SI (match_dup 1)
18603 [(set_attr "type" "str")
18604 (set_attr "memory" "store")
18605 (set_attr "mode" "QI")])
18607 (define_insn "*strsetqi_rex_1"
18608 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18609 (match_operand:QI 2 "register_operand" "a"))
18610 (set (match_operand:DI 0 "register_operand" "=D")
18611 (plus:DI (match_dup 1)
18615 [(set_attr "type" "str")
18616 (set_attr "memory" "store")
18617 (set_attr "prefix_rex" "0")
18618 (set_attr "mode" "QI")])
18620 (define_expand "rep_stos"
18621 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18622 (set (match_operand 0 "register_operand" "")
18623 (match_operand 4 "" ""))
18624 (set (match_operand 2 "memory_operand" "") (const_int 0))
18625 (use (match_operand 3 "register_operand" ""))
18626 (use (match_dup 1))])]
18628 "ix86_current_function_needs_cld = 1;")
18630 (define_insn "*rep_stosdi_rex64"
18631 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18632 (set (match_operand:DI 0 "register_operand" "=D")
18633 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18635 (match_operand:DI 3 "register_operand" "0")))
18636 (set (mem:BLK (match_dup 3))
18638 (use (match_operand:DI 2 "register_operand" "a"))
18639 (use (match_dup 4))]
18642 [(set_attr "type" "str")
18643 (set_attr "prefix_rep" "1")
18644 (set_attr "memory" "store")
18645 (set_attr "mode" "DI")])
18647 (define_insn "*rep_stossi"
18648 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18649 (set (match_operand:SI 0 "register_operand" "=D")
18650 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18652 (match_operand:SI 3 "register_operand" "0")))
18653 (set (mem:BLK (match_dup 3))
18655 (use (match_operand:SI 2 "register_operand" "a"))
18656 (use (match_dup 4))]
18659 [(set_attr "type" "str")
18660 (set_attr "prefix_rep" "1")
18661 (set_attr "memory" "store")
18662 (set_attr "mode" "SI")])
18664 (define_insn "*rep_stossi_rex64"
18665 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18666 (set (match_operand:DI 0 "register_operand" "=D")
18667 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18669 (match_operand:DI 3 "register_operand" "0")))
18670 (set (mem:BLK (match_dup 3))
18672 (use (match_operand:SI 2 "register_operand" "a"))
18673 (use (match_dup 4))]
18676 [(set_attr "type" "str")
18677 (set_attr "prefix_rep" "1")
18678 (set_attr "memory" "store")
18679 (set_attr "mode" "SI")])
18681 (define_insn "*rep_stosqi"
18682 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18683 (set (match_operand:SI 0 "register_operand" "=D")
18684 (plus:SI (match_operand:SI 3 "register_operand" "0")
18685 (match_operand:SI 4 "register_operand" "1")))
18686 (set (mem:BLK (match_dup 3))
18688 (use (match_operand:QI 2 "register_operand" "a"))
18689 (use (match_dup 4))]
18692 [(set_attr "type" "str")
18693 (set_attr "prefix_rep" "1")
18694 (set_attr "memory" "store")
18695 (set_attr "mode" "QI")])
18697 (define_insn "*rep_stosqi_rex64"
18698 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18699 (set (match_operand:DI 0 "register_operand" "=D")
18700 (plus:DI (match_operand:DI 3 "register_operand" "0")
18701 (match_operand:DI 4 "register_operand" "1")))
18702 (set (mem:BLK (match_dup 3))
18704 (use (match_operand:QI 2 "register_operand" "a"))
18705 (use (match_dup 4))]
18708 [(set_attr "type" "str")
18709 (set_attr "prefix_rep" "1")
18710 (set_attr "memory" "store")
18711 (set_attr "prefix_rex" "0")
18712 (set_attr "mode" "QI")])
18714 (define_expand "cmpstrnsi"
18715 [(set (match_operand:SI 0 "register_operand" "")
18716 (compare:SI (match_operand:BLK 1 "general_operand" "")
18717 (match_operand:BLK 2 "general_operand" "")))
18718 (use (match_operand 3 "general_operand" ""))
18719 (use (match_operand 4 "immediate_operand" ""))]
18722 rtx addr1, addr2, out, outlow, count, countreg, align;
18724 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18727 /* Can't use this if the user has appropriated esi or edi. */
18728 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18733 out = gen_reg_rtx (SImode);
18735 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18736 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18737 if (addr1 != XEXP (operands[1], 0))
18738 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18739 if (addr2 != XEXP (operands[2], 0))
18740 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18742 count = operands[3];
18743 countreg = ix86_zero_extend_to_Pmode (count);
18745 /* %%% Iff we are testing strict equality, we can use known alignment
18746 to good advantage. This may be possible with combine, particularly
18747 once cc0 is dead. */
18748 align = operands[4];
18750 if (CONST_INT_P (count))
18752 if (INTVAL (count) == 0)
18754 emit_move_insn (operands[0], const0_rtx);
18757 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18758 operands[1], operands[2]));
18762 rtx (*cmp_insn)(rtx, rtx);
18765 cmp_insn = gen_cmpdi_1;
18767 cmp_insn = gen_cmpsi_1;
18768 emit_insn (cmp_insn (countreg, countreg));
18769 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18770 operands[1], operands[2]));
18773 outlow = gen_lowpart (QImode, out);
18774 emit_insn (gen_cmpintqi (outlow));
18775 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18777 if (operands[0] != out)
18778 emit_move_insn (operands[0], out);
18783 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18785 (define_expand "cmpintqi"
18786 [(set (match_dup 1)
18787 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18789 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18790 (parallel [(set (match_operand:QI 0 "register_operand" "")
18791 (minus:QI (match_dup 1)
18793 (clobber (reg:CC FLAGS_REG))])]
18795 "operands[1] = gen_reg_rtx (QImode);
18796 operands[2] = gen_reg_rtx (QImode);")
18798 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18799 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18801 (define_expand "cmpstrnqi_nz_1"
18802 [(parallel [(set (reg:CC FLAGS_REG)
18803 (compare:CC (match_operand 4 "memory_operand" "")
18804 (match_operand 5 "memory_operand" "")))
18805 (use (match_operand 2 "register_operand" ""))
18806 (use (match_operand:SI 3 "immediate_operand" ""))
18807 (clobber (match_operand 0 "register_operand" ""))
18808 (clobber (match_operand 1 "register_operand" ""))
18809 (clobber (match_dup 2))])]
18811 "ix86_current_function_needs_cld = 1;")
18813 (define_insn "*cmpstrnqi_nz_1"
18814 [(set (reg:CC FLAGS_REG)
18815 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18816 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18817 (use (match_operand:SI 6 "register_operand" "2"))
18818 (use (match_operand:SI 3 "immediate_operand" "i"))
18819 (clobber (match_operand:SI 0 "register_operand" "=S"))
18820 (clobber (match_operand:SI 1 "register_operand" "=D"))
18821 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18824 [(set_attr "type" "str")
18825 (set_attr "mode" "QI")
18826 (set_attr "prefix_rep" "1")])
18828 (define_insn "*cmpstrnqi_nz_rex_1"
18829 [(set (reg:CC FLAGS_REG)
18830 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18831 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18832 (use (match_operand:DI 6 "register_operand" "2"))
18833 (use (match_operand:SI 3 "immediate_operand" "i"))
18834 (clobber (match_operand:DI 0 "register_operand" "=S"))
18835 (clobber (match_operand:DI 1 "register_operand" "=D"))
18836 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18839 [(set_attr "type" "str")
18840 (set_attr "mode" "QI")
18841 (set_attr "prefix_rex" "0")
18842 (set_attr "prefix_rep" "1")])
18844 ;; The same, but the count is not known to not be zero.
18846 (define_expand "cmpstrnqi_1"
18847 [(parallel [(set (reg:CC FLAGS_REG)
18848 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18850 (compare:CC (match_operand 4 "memory_operand" "")
18851 (match_operand 5 "memory_operand" ""))
18853 (use (match_operand:SI 3 "immediate_operand" ""))
18854 (use (reg:CC FLAGS_REG))
18855 (clobber (match_operand 0 "register_operand" ""))
18856 (clobber (match_operand 1 "register_operand" ""))
18857 (clobber (match_dup 2))])]
18859 "ix86_current_function_needs_cld = 1;")
18861 (define_insn "*cmpstrnqi_1"
18862 [(set (reg:CC FLAGS_REG)
18863 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18865 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18866 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18868 (use (match_operand:SI 3 "immediate_operand" "i"))
18869 (use (reg:CC FLAGS_REG))
18870 (clobber (match_operand:SI 0 "register_operand" "=S"))
18871 (clobber (match_operand:SI 1 "register_operand" "=D"))
18872 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18875 [(set_attr "type" "str")
18876 (set_attr "mode" "QI")
18877 (set_attr "prefix_rep" "1")])
18879 (define_insn "*cmpstrnqi_rex_1"
18880 [(set (reg:CC FLAGS_REG)
18881 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18883 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18884 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18886 (use (match_operand:SI 3 "immediate_operand" "i"))
18887 (use (reg:CC FLAGS_REG))
18888 (clobber (match_operand:DI 0 "register_operand" "=S"))
18889 (clobber (match_operand:DI 1 "register_operand" "=D"))
18890 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18893 [(set_attr "type" "str")
18894 (set_attr "mode" "QI")
18895 (set_attr "prefix_rex" "0")
18896 (set_attr "prefix_rep" "1")])
18898 (define_expand "strlensi"
18899 [(set (match_operand:SI 0 "register_operand" "")
18900 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18901 (match_operand:QI 2 "immediate_operand" "")
18902 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18905 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18911 (define_expand "strlendi"
18912 [(set (match_operand:DI 0 "register_operand" "")
18913 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18914 (match_operand:QI 2 "immediate_operand" "")
18915 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18918 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18924 (define_expand "strlenqi_1"
18925 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18926 (clobber (match_operand 1 "register_operand" ""))
18927 (clobber (reg:CC FLAGS_REG))])]
18929 "ix86_current_function_needs_cld = 1;")
18931 (define_insn "*strlenqi_1"
18932 [(set (match_operand:SI 0 "register_operand" "=&c")
18933 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18934 (match_operand:QI 2 "register_operand" "a")
18935 (match_operand:SI 3 "immediate_operand" "i")
18936 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18937 (clobber (match_operand:SI 1 "register_operand" "=D"))
18938 (clobber (reg:CC FLAGS_REG))]
18941 [(set_attr "type" "str")
18942 (set_attr "mode" "QI")
18943 (set_attr "prefix_rep" "1")])
18945 (define_insn "*strlenqi_rex_1"
18946 [(set (match_operand:DI 0 "register_operand" "=&c")
18947 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18948 (match_operand:QI 2 "register_operand" "a")
18949 (match_operand:DI 3 "immediate_operand" "i")
18950 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18951 (clobber (match_operand:DI 1 "register_operand" "=D"))
18952 (clobber (reg:CC FLAGS_REG))]
18955 [(set_attr "type" "str")
18956 (set_attr "mode" "QI")
18957 (set_attr "prefix_rex" "0")
18958 (set_attr "prefix_rep" "1")])
18960 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18961 ;; handled in combine, but it is not currently up to the task.
18962 ;; When used for their truth value, the cmpstrn* expanders generate
18971 ;; The intermediate three instructions are unnecessary.
18973 ;; This one handles cmpstrn*_nz_1...
18976 (set (reg:CC FLAGS_REG)
18977 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18978 (mem:BLK (match_operand 5 "register_operand" ""))))
18979 (use (match_operand 6 "register_operand" ""))
18980 (use (match_operand:SI 3 "immediate_operand" ""))
18981 (clobber (match_operand 0 "register_operand" ""))
18982 (clobber (match_operand 1 "register_operand" ""))
18983 (clobber (match_operand 2 "register_operand" ""))])
18984 (set (match_operand:QI 7 "register_operand" "")
18985 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18986 (set (match_operand:QI 8 "register_operand" "")
18987 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18988 (set (reg FLAGS_REG)
18989 (compare (match_dup 7) (match_dup 8)))
18991 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18993 (set (reg:CC FLAGS_REG)
18994 (compare:CC (mem:BLK (match_dup 4))
18995 (mem:BLK (match_dup 5))))
18996 (use (match_dup 6))
18997 (use (match_dup 3))
18998 (clobber (match_dup 0))
18999 (clobber (match_dup 1))
19000 (clobber (match_dup 2))])]
19003 ;; ...and this one handles cmpstrn*_1.
19006 (set (reg:CC FLAGS_REG)
19007 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19009 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19010 (mem:BLK (match_operand 5 "register_operand" "")))
19012 (use (match_operand:SI 3 "immediate_operand" ""))
19013 (use (reg:CC FLAGS_REG))
19014 (clobber (match_operand 0 "register_operand" ""))
19015 (clobber (match_operand 1 "register_operand" ""))
19016 (clobber (match_operand 2 "register_operand" ""))])
19017 (set (match_operand:QI 7 "register_operand" "")
19018 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19019 (set (match_operand:QI 8 "register_operand" "")
19020 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19021 (set (reg FLAGS_REG)
19022 (compare (match_dup 7) (match_dup 8)))
19024 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19026 (set (reg:CC FLAGS_REG)
19027 (if_then_else:CC (ne (match_dup 6)
19029 (compare:CC (mem:BLK (match_dup 4))
19030 (mem:BLK (match_dup 5)))
19032 (use (match_dup 3))
19033 (use (reg:CC FLAGS_REG))
19034 (clobber (match_dup 0))
19035 (clobber (match_dup 1))
19036 (clobber (match_dup 2))])]
19041 ;; Conditional move instructions.
19043 (define_expand "mov<mode>cc"
19044 [(set (match_operand:SWIM 0 "register_operand" "")
19045 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
19046 (match_operand:SWIM 2 "general_operand" "")
19047 (match_operand:SWIM 3 "general_operand" "")))]
19049 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19051 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19052 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19053 ;; So just document what we're doing explicitly.
19055 (define_expand "x86_mov<mode>cc_0_m1"
19057 [(set (match_operand:SWI48 0 "register_operand" "")
19058 (if_then_else:SWI48
19059 (match_operator:SWI48 2 "ix86_carry_flag_operator"
19060 [(match_operand 1 "flags_reg_operand" "")
19064 (clobber (reg:CC FLAGS_REG))])]
19068 (define_insn "*x86_mov<mode>cc_0_m1"
19069 [(set (match_operand:SWI48 0 "register_operand" "=r")
19070 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19071 [(reg FLAGS_REG) (const_int 0)])
19074 (clobber (reg:CC FLAGS_REG))]
19076 "sbb{<imodesuffix>}\t%0, %0"
19077 ; Since we don't have the proper number of operands for an alu insn,
19078 ; fill in all the blanks.
19079 [(set_attr "type" "alu")
19080 (set_attr "use_carry" "1")
19081 (set_attr "pent_pair" "pu")
19082 (set_attr "memory" "none")
19083 (set_attr "imm_disp" "false")
19084 (set_attr "mode" "<MODE>")
19085 (set_attr "length_immediate" "0")])
19087 (define_insn "*x86_mov<mode>cc_0_m1_se"
19088 [(set (match_operand:SWI48 0 "register_operand" "=r")
19089 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19090 [(reg FLAGS_REG) (const_int 0)])
19093 (clobber (reg:CC FLAGS_REG))]
19095 "sbb{<imodesuffix>}\t%0, %0"
19096 [(set_attr "type" "alu")
19097 (set_attr "use_carry" "1")
19098 (set_attr "pent_pair" "pu")
19099 (set_attr "memory" "none")
19100 (set_attr "imm_disp" "false")
19101 (set_attr "mode" "<MODE>")
19102 (set_attr "length_immediate" "0")])
19104 (define_insn "*x86_mov<mode>cc_0_m1_neg"
19105 [(set (match_operand:SWI48 0 "register_operand" "=r")
19106 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19107 [(reg FLAGS_REG) (const_int 0)])))]
19109 "sbb{<imodesuffix>}\t%0, %0"
19110 [(set_attr "type" "alu")
19111 (set_attr "use_carry" "1")
19112 (set_attr "pent_pair" "pu")
19113 (set_attr "memory" "none")
19114 (set_attr "imm_disp" "false")
19115 (set_attr "mode" "<MODE>")
19116 (set_attr "length_immediate" "0")])
19118 (define_insn "*mov<mode>cc_noc"
19119 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
19120 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
19121 [(reg FLAGS_REG) (const_int 0)])
19122 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
19123 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
19124 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19126 cmov%O2%C1\t{%2, %0|%0, %2}
19127 cmov%O2%c1\t{%3, %0|%0, %3}"
19128 [(set_attr "type" "icmov")
19129 (set_attr "mode" "<MODE>")])
19131 (define_insn_and_split "*movqicc_noc"
19132 [(set (match_operand:QI 0 "register_operand" "=r,r")
19133 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19134 [(match_operand 4 "flags_reg_operand" "")
19136 (match_operand:QI 2 "register_operand" "r,0")
19137 (match_operand:QI 3 "register_operand" "0,r")))]
19138 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19140 "&& reload_completed"
19141 [(set (match_dup 0)
19142 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19145 "operands[0] = gen_lowpart (SImode, operands[0]);
19146 operands[2] = gen_lowpart (SImode, operands[2]);
19147 operands[3] = gen_lowpart (SImode, operands[3]);"
19148 [(set_attr "type" "icmov")
19149 (set_attr "mode" "SI")])
19151 (define_expand "mov<mode>cc"
19152 [(set (match_operand:X87MODEF 0 "register_operand" "")
19153 (if_then_else:X87MODEF
19154 (match_operand 1 "ix86_fp_comparison_operator" "")
19155 (match_operand:X87MODEF 2 "register_operand" "")
19156 (match_operand:X87MODEF 3 "register_operand" "")))]
19157 "(TARGET_80387 && TARGET_CMOVE)
19158 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19159 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19161 (define_insn "*movsfcc_1_387"
19162 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19163 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19164 [(reg FLAGS_REG) (const_int 0)])
19165 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19166 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19167 "TARGET_80387 && TARGET_CMOVE
19168 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19170 fcmov%F1\t{%2, %0|%0, %2}
19171 fcmov%f1\t{%3, %0|%0, %3}
19172 cmov%O2%C1\t{%2, %0|%0, %2}
19173 cmov%O2%c1\t{%3, %0|%0, %3}"
19174 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19175 (set_attr "mode" "SF,SF,SI,SI")])
19177 (define_insn "*movdfcc_1"
19178 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19179 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19180 [(reg FLAGS_REG) (const_int 0)])
19181 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19182 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19183 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19184 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19186 fcmov%F1\t{%2, %0|%0, %2}
19187 fcmov%f1\t{%3, %0|%0, %3}
19190 [(set_attr "type" "fcmov,fcmov,multi,multi")
19191 (set_attr "mode" "DF")])
19193 (define_insn "*movdfcc_1_rex64"
19194 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19195 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19196 [(reg FLAGS_REG) (const_int 0)])
19197 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19198 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19199 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19200 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19202 fcmov%F1\t{%2, %0|%0, %2}
19203 fcmov%f1\t{%3, %0|%0, %3}
19204 cmov%O2%C1\t{%2, %0|%0, %2}
19205 cmov%O2%c1\t{%3, %0|%0, %3}"
19206 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19207 (set_attr "mode" "DF")])
19210 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19211 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19212 [(match_operand 4 "flags_reg_operand" "")
19214 (match_operand:DF 2 "nonimmediate_operand" "")
19215 (match_operand:DF 3 "nonimmediate_operand" "")))]
19216 "!TARGET_64BIT && reload_completed"
19217 [(set (match_dup 2)
19218 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19222 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19225 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19226 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19228 (define_insn "*movxfcc_1"
19229 [(set (match_operand:XF 0 "register_operand" "=f,f")
19230 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19231 [(reg FLAGS_REG) (const_int 0)])
19232 (match_operand:XF 2 "register_operand" "f,0")
19233 (match_operand:XF 3 "register_operand" "0,f")))]
19234 "TARGET_80387 && TARGET_CMOVE"
19236 fcmov%F1\t{%2, %0|%0, %2}
19237 fcmov%f1\t{%3, %0|%0, %3}"
19238 [(set_attr "type" "fcmov")
19239 (set_attr "mode" "XF")])
19241 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
19242 ;; the scalar versions to have only XMM registers as operands.
19244 ;; XOP conditional move
19245 (define_insn "*xop_pcmov_<mode>"
19246 [(set (match_operand:MODEF 0 "register_operand" "=x")
19247 (if_then_else:MODEF
19248 (match_operand:MODEF 1 "register_operand" "x")
19249 (match_operand:MODEF 2 "register_operand" "x")
19250 (match_operand:MODEF 3 "register_operand" "x")))]
19252 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19253 [(set_attr "type" "sse4arg")])
19255 ;; These versions of the min/max patterns are intentionally ignorant of
19256 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19257 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19258 ;; are undefined in this condition, we're certain this is correct.
19260 (define_insn "*avx_<code><mode>3"
19261 [(set (match_operand:MODEF 0 "register_operand" "=x")
19263 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19264 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19265 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19266 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19267 [(set_attr "type" "sseadd")
19268 (set_attr "prefix" "vex")
19269 (set_attr "mode" "<MODE>")])
19271 (define_insn "<code><mode>3"
19272 [(set (match_operand:MODEF 0 "register_operand" "=x")
19274 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19275 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19276 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19277 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19278 [(set_attr "type" "sseadd")
19279 (set_attr "mode" "<MODE>")])
19281 ;; These versions of the min/max patterns implement exactly the operations
19282 ;; min = (op1 < op2 ? op1 : op2)
19283 ;; max = (!(op1 < op2) ? op1 : op2)
19284 ;; Their operands are not commutative, and thus they may be used in the
19285 ;; presence of -0.0 and NaN.
19287 (define_insn "*avx_ieee_smin<mode>3"
19288 [(set (match_operand:MODEF 0 "register_operand" "=x")
19290 [(match_operand:MODEF 1 "register_operand" "x")
19291 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19293 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19294 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19295 [(set_attr "type" "sseadd")
19296 (set_attr "prefix" "vex")
19297 (set_attr "mode" "<MODE>")])
19299 (define_insn "*ieee_smin<mode>3"
19300 [(set (match_operand:MODEF 0 "register_operand" "=x")
19302 [(match_operand:MODEF 1 "register_operand" "0")
19303 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19305 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19306 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19307 [(set_attr "type" "sseadd")
19308 (set_attr "mode" "<MODE>")])
19310 (define_insn "*avx_ieee_smax<mode>3"
19311 [(set (match_operand:MODEF 0 "register_operand" "=x")
19313 [(match_operand:MODEF 1 "register_operand" "0")
19314 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19316 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19317 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19318 [(set_attr "type" "sseadd")
19319 (set_attr "prefix" "vex")
19320 (set_attr "mode" "<MODE>")])
19322 (define_insn "*ieee_smax<mode>3"
19323 [(set (match_operand:MODEF 0 "register_operand" "=x")
19325 [(match_operand:MODEF 1 "register_operand" "0")
19326 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19328 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19329 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19330 [(set_attr "type" "sseadd")
19331 (set_attr "mode" "<MODE>")])
19333 ;; Make two stack loads independent:
19335 ;; fld %st(0) -> fld bb
19336 ;; fmul bb fmul %st(1), %st
19338 ;; Actually we only match the last two instructions for simplicity.
19340 [(set (match_operand 0 "fp_register_operand" "")
19341 (match_operand 1 "fp_register_operand" ""))
19343 (match_operator 2 "binary_fp_operator"
19345 (match_operand 3 "memory_operand" "")]))]
19346 "REGNO (operands[0]) != REGNO (operands[1])"
19347 [(set (match_dup 0) (match_dup 3))
19348 (set (match_dup 0) (match_dup 4))]
19350 ;; The % modifier is not operational anymore in peephole2's, so we have to
19351 ;; swap the operands manually in the case of addition and multiplication.
19352 "if (COMMUTATIVE_ARITH_P (operands[2]))
19353 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19354 operands[0], operands[1]);
19356 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19357 operands[1], operands[0]);")
19359 ;; Conditional addition patterns
19360 (define_expand "add<mode>cc"
19361 [(match_operand:SWI 0 "register_operand" "")
19362 (match_operand 1 "comparison_operator" "")
19363 (match_operand:SWI 2 "register_operand" "")
19364 (match_operand:SWI 3 "const_int_operand" "")]
19366 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19369 ;; Misc patterns (?)
19371 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19372 ;; Otherwise there will be nothing to keep
19374 ;; [(set (reg ebp) (reg esp))]
19375 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19376 ;; (clobber (eflags)]
19377 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19379 ;; in proper program order.
19380 (define_insn "pro_epilogue_adjust_stack_1"
19381 [(set (match_operand:SI 0 "register_operand" "=r,r")
19382 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19383 (match_operand:SI 2 "immediate_operand" "i,i")))
19384 (clobber (reg:CC FLAGS_REG))
19385 (clobber (mem:BLK (scratch)))]
19388 switch (get_attr_type (insn))
19391 return "mov{l}\t{%1, %0|%0, %1}";
19394 if (CONST_INT_P (operands[2])
19395 && (INTVAL (operands[2]) == 128
19396 || (INTVAL (operands[2]) < 0
19397 && INTVAL (operands[2]) != -128)))
19399 operands[2] = GEN_INT (-INTVAL (operands[2]));
19400 return "sub{l}\t{%2, %0|%0, %2}";
19402 return "add{l}\t{%2, %0|%0, %2}";
19405 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19406 return "lea{l}\t{%a2, %0|%0, %a2}";
19409 gcc_unreachable ();
19412 [(set (attr "type")
19413 (cond [(and (eq_attr "alternative" "0")
19414 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19415 (const_string "alu")
19416 (match_operand:SI 2 "const0_operand" "")
19417 (const_string "imov")
19419 (const_string "lea")))
19420 (set (attr "length_immediate")
19421 (cond [(eq_attr "type" "imov")
19423 (and (eq_attr "type" "alu")
19424 (match_operand 2 "const128_operand" ""))
19427 (const_string "*")))
19428 (set_attr "mode" "SI")])
19430 (define_insn "pro_epilogue_adjust_stack_rex64"
19431 [(set (match_operand:DI 0 "register_operand" "=r,r")
19432 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19433 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19434 (clobber (reg:CC FLAGS_REG))
19435 (clobber (mem:BLK (scratch)))]
19438 switch (get_attr_type (insn))
19441 return "mov{q}\t{%1, %0|%0, %1}";
19444 if (CONST_INT_P (operands[2])
19445 /* Avoid overflows. */
19446 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19447 && (INTVAL (operands[2]) == 128
19448 || (INTVAL (operands[2]) < 0
19449 && INTVAL (operands[2]) != -128)))
19451 operands[2] = GEN_INT (-INTVAL (operands[2]));
19452 return "sub{q}\t{%2, %0|%0, %2}";
19454 return "add{q}\t{%2, %0|%0, %2}";
19457 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19458 return "lea{q}\t{%a2, %0|%0, %a2}";
19461 gcc_unreachable ();
19464 [(set (attr "type")
19465 (cond [(and (eq_attr "alternative" "0")
19466 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19467 (const_string "alu")
19468 (match_operand:DI 2 "const0_operand" "")
19469 (const_string "imov")
19471 (const_string "lea")))
19472 (set (attr "length_immediate")
19473 (cond [(eq_attr "type" "imov")
19475 (and (eq_attr "type" "alu")
19476 (match_operand 2 "const128_operand" ""))
19479 (const_string "*")))
19480 (set_attr "mode" "DI")])
19482 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19483 [(set (match_operand:DI 0 "register_operand" "=r,r")
19484 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19485 (match_operand:DI 3 "immediate_operand" "i,i")))
19486 (use (match_operand:DI 2 "register_operand" "r,r"))
19487 (clobber (reg:CC FLAGS_REG))
19488 (clobber (mem:BLK (scratch)))]
19491 switch (get_attr_type (insn))
19494 return "add{q}\t{%2, %0|%0, %2}";
19497 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19498 return "lea{q}\t{%a2, %0|%0, %a2}";
19501 gcc_unreachable ();
19504 [(set_attr "type" "alu,lea")
19505 (set_attr "mode" "DI")])
19507 (define_insn "allocate_stack_worker_32"
19508 [(set (match_operand:SI 0 "register_operand" "=a")
19509 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
19510 UNSPECV_STACK_PROBE))
19511 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
19512 (clobber (reg:CC FLAGS_REG))]
19513 "!TARGET_64BIT && TARGET_STACK_PROBE"
19515 [(set_attr "type" "multi")
19516 (set_attr "length" "5")])
19518 (define_insn "allocate_stack_worker_64"
19519 [(set (match_operand:DI 0 "register_operand" "=a")
19520 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
19521 UNSPECV_STACK_PROBE))
19522 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
19523 (clobber (reg:DI R10_REG))
19524 (clobber (reg:DI R11_REG))
19525 (clobber (reg:CC FLAGS_REG))]
19526 "TARGET_64BIT && TARGET_STACK_PROBE"
19528 [(set_attr "type" "multi")
19529 (set_attr "length" "5")])
19531 (define_expand "allocate_stack"
19532 [(match_operand 0 "register_operand" "")
19533 (match_operand 1 "general_operand" "")]
19534 "TARGET_STACK_PROBE"
19538 #ifndef CHECK_STACK_LIMIT
19539 #define CHECK_STACK_LIMIT 0
19542 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19543 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19545 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19546 stack_pointer_rtx, 0, OPTAB_DIRECT);
19547 if (x != stack_pointer_rtx)
19548 emit_move_insn (stack_pointer_rtx, x);
19552 x = copy_to_mode_reg (Pmode, operands[1]);
19554 x = gen_allocate_stack_worker_64 (x, x);
19556 x = gen_allocate_stack_worker_32 (x, x);
19560 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19564 ;; Use IOR for stack probes, this is shorter.
19565 (define_expand "probe_stack"
19566 [(match_operand 0 "memory_operand" "")]
19569 if (GET_MODE (operands[0]) == DImode)
19570 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
19572 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
19576 (define_expand "builtin_setjmp_receiver"
19577 [(label_ref (match_operand 0 "" ""))]
19578 "!TARGET_64BIT && flag_pic"
19584 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19585 rtx label_rtx = gen_label_rtx ();
19586 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19587 xops[0] = xops[1] = picreg;
19588 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19589 ix86_expand_binary_operator (MINUS, SImode, xops);
19593 emit_insn (gen_set_got (pic_offset_table_rtx));
19597 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19600 [(set (match_operand 0 "register_operand" "")
19601 (match_operator 3 "promotable_binary_operator"
19602 [(match_operand 1 "register_operand" "")
19603 (match_operand 2 "aligned_operand" "")]))
19604 (clobber (reg:CC FLAGS_REG))]
19605 "! TARGET_PARTIAL_REG_STALL && reload_completed
19606 && ((GET_MODE (operands[0]) == HImode
19607 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19608 /* ??? next two lines just !satisfies_constraint_K (...) */
19609 || !CONST_INT_P (operands[2])
19610 || satisfies_constraint_K (operands[2])))
19611 || (GET_MODE (operands[0]) == QImode
19612 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19613 [(parallel [(set (match_dup 0)
19614 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19615 (clobber (reg:CC FLAGS_REG))])]
19616 "operands[0] = gen_lowpart (SImode, operands[0]);
19617 operands[1] = gen_lowpart (SImode, operands[1]);
19618 if (GET_CODE (operands[3]) != ASHIFT)
19619 operands[2] = gen_lowpart (SImode, operands[2]);
19620 PUT_MODE (operands[3], SImode);")
19622 ; Promote the QImode tests, as i386 has encoding of the AND
19623 ; instruction with 32-bit sign-extended immediate and thus the
19624 ; instruction size is unchanged, except in the %eax case for
19625 ; which it is increased by one byte, hence the ! optimize_size.
19627 [(set (match_operand 0 "flags_reg_operand" "")
19628 (match_operator 2 "compare_operator"
19629 [(and (match_operand 3 "aligned_operand" "")
19630 (match_operand 4 "const_int_operand" ""))
19632 (set (match_operand 1 "register_operand" "")
19633 (and (match_dup 3) (match_dup 4)))]
19634 "! TARGET_PARTIAL_REG_STALL && reload_completed
19635 && optimize_insn_for_speed_p ()
19636 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19637 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19638 /* Ensure that the operand will remain sign-extended immediate. */
19639 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19640 [(parallel [(set (match_dup 0)
19641 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19644 (and:SI (match_dup 3) (match_dup 4)))])]
19647 = gen_int_mode (INTVAL (operands[4])
19648 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19649 operands[1] = gen_lowpart (SImode, operands[1]);
19650 operands[3] = gen_lowpart (SImode, operands[3]);
19653 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19654 ; the TEST instruction with 32-bit sign-extended immediate and thus
19655 ; the instruction size would at least double, which is not what we
19656 ; want even with ! optimize_size.
19658 [(set (match_operand 0 "flags_reg_operand" "")
19659 (match_operator 1 "compare_operator"
19660 [(and (match_operand:HI 2 "aligned_operand" "")
19661 (match_operand:HI 3 "const_int_operand" ""))
19663 "! TARGET_PARTIAL_REG_STALL && reload_completed
19664 && ! TARGET_FAST_PREFIX
19665 && optimize_insn_for_speed_p ()
19666 /* Ensure that the operand will remain sign-extended immediate. */
19667 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19668 [(set (match_dup 0)
19669 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19673 = gen_int_mode (INTVAL (operands[3])
19674 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19675 operands[2] = gen_lowpart (SImode, operands[2]);
19679 [(set (match_operand 0 "register_operand" "")
19680 (neg (match_operand 1 "register_operand" "")))
19681 (clobber (reg:CC FLAGS_REG))]
19682 "! TARGET_PARTIAL_REG_STALL && reload_completed
19683 && (GET_MODE (operands[0]) == HImode
19684 || (GET_MODE (operands[0]) == QImode
19685 && (TARGET_PROMOTE_QImode
19686 || optimize_insn_for_size_p ())))"
19687 [(parallel [(set (match_dup 0)
19688 (neg:SI (match_dup 1)))
19689 (clobber (reg:CC FLAGS_REG))])]
19690 "operands[0] = gen_lowpart (SImode, operands[0]);
19691 operands[1] = gen_lowpart (SImode, operands[1]);")
19694 [(set (match_operand 0 "register_operand" "")
19695 (not (match_operand 1 "register_operand" "")))]
19696 "! TARGET_PARTIAL_REG_STALL && reload_completed
19697 && (GET_MODE (operands[0]) == HImode
19698 || (GET_MODE (operands[0]) == QImode
19699 && (TARGET_PROMOTE_QImode
19700 || optimize_insn_for_size_p ())))"
19701 [(set (match_dup 0)
19702 (not:SI (match_dup 1)))]
19703 "operands[0] = gen_lowpart (SImode, operands[0]);
19704 operands[1] = gen_lowpart (SImode, operands[1]);")
19707 [(set (match_operand 0 "register_operand" "")
19708 (if_then_else (match_operator 1 "comparison_operator"
19709 [(reg FLAGS_REG) (const_int 0)])
19710 (match_operand 2 "register_operand" "")
19711 (match_operand 3 "register_operand" "")))]
19712 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19713 && (GET_MODE (operands[0]) == HImode
19714 || (GET_MODE (operands[0]) == QImode
19715 && (TARGET_PROMOTE_QImode
19716 || optimize_insn_for_size_p ())))"
19717 [(set (match_dup 0)
19718 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19719 "operands[0] = gen_lowpart (SImode, operands[0]);
19720 operands[2] = gen_lowpart (SImode, operands[2]);
19721 operands[3] = gen_lowpart (SImode, operands[3]);")
19724 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19725 ;; transform a complex memory operation into two memory to register operations.
19727 ;; Don't push memory operands
19729 [(set (match_operand:SI 0 "push_operand" "")
19730 (match_operand:SI 1 "memory_operand" ""))
19731 (match_scratch:SI 2 "r")]
19732 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19733 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19734 [(set (match_dup 2) (match_dup 1))
19735 (set (match_dup 0) (match_dup 2))]
19739 [(set (match_operand:DI 0 "push_operand" "")
19740 (match_operand:DI 1 "memory_operand" ""))
19741 (match_scratch:DI 2 "r")]
19742 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19743 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19744 [(set (match_dup 2) (match_dup 1))
19745 (set (match_dup 0) (match_dup 2))]
19748 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19751 [(set (match_operand:SF 0 "push_operand" "")
19752 (match_operand:SF 1 "memory_operand" ""))
19753 (match_scratch:SF 2 "r")]
19754 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19755 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19756 [(set (match_dup 2) (match_dup 1))
19757 (set (match_dup 0) (match_dup 2))]
19761 [(set (match_operand:HI 0 "push_operand" "")
19762 (match_operand:HI 1 "memory_operand" ""))
19763 (match_scratch:HI 2 "r")]
19764 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19765 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19766 [(set (match_dup 2) (match_dup 1))
19767 (set (match_dup 0) (match_dup 2))]
19771 [(set (match_operand:QI 0 "push_operand" "")
19772 (match_operand:QI 1 "memory_operand" ""))
19773 (match_scratch:QI 2 "q")]
19774 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19775 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19776 [(set (match_dup 2) (match_dup 1))
19777 (set (match_dup 0) (match_dup 2))]
19780 ;; Don't move an immediate directly to memory when the instruction
19783 [(match_scratch:SI 1 "r")
19784 (set (match_operand:SI 0 "memory_operand" "")
19786 "optimize_insn_for_speed_p ()
19787 && ! TARGET_USE_MOV0
19788 && TARGET_SPLIT_LONG_MOVES
19789 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19790 && peep2_regno_dead_p (0, FLAGS_REG)"
19791 [(parallel [(set (match_dup 1) (const_int 0))
19792 (clobber (reg:CC FLAGS_REG))])
19793 (set (match_dup 0) (match_dup 1))]
19797 [(match_scratch:HI 1 "r")
19798 (set (match_operand:HI 0 "memory_operand" "")
19800 "optimize_insn_for_speed_p ()
19801 && ! TARGET_USE_MOV0
19802 && TARGET_SPLIT_LONG_MOVES
19803 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19804 && peep2_regno_dead_p (0, FLAGS_REG)"
19805 [(parallel [(set (match_dup 2) (const_int 0))
19806 (clobber (reg:CC FLAGS_REG))])
19807 (set (match_dup 0) (match_dup 1))]
19808 "operands[2] = gen_lowpart (SImode, operands[1]);")
19811 [(match_scratch:QI 1 "q")
19812 (set (match_operand:QI 0 "memory_operand" "")
19814 "optimize_insn_for_speed_p ()
19815 && ! TARGET_USE_MOV0
19816 && TARGET_SPLIT_LONG_MOVES
19817 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19818 && peep2_regno_dead_p (0, FLAGS_REG)"
19819 [(parallel [(set (match_dup 2) (const_int 0))
19820 (clobber (reg:CC FLAGS_REG))])
19821 (set (match_dup 0) (match_dup 1))]
19822 "operands[2] = gen_lowpart (SImode, operands[1]);")
19825 [(match_scratch:SI 2 "r")
19826 (set (match_operand:SI 0 "memory_operand" "")
19827 (match_operand:SI 1 "immediate_operand" ""))]
19828 "optimize_insn_for_speed_p ()
19829 && TARGET_SPLIT_LONG_MOVES
19830 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19831 [(set (match_dup 2) (match_dup 1))
19832 (set (match_dup 0) (match_dup 2))]
19836 [(match_scratch:HI 2 "r")
19837 (set (match_operand:HI 0 "memory_operand" "")
19838 (match_operand:HI 1 "immediate_operand" ""))]
19839 "optimize_insn_for_speed_p ()
19840 && TARGET_SPLIT_LONG_MOVES
19841 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19842 [(set (match_dup 2) (match_dup 1))
19843 (set (match_dup 0) (match_dup 2))]
19847 [(match_scratch:QI 2 "q")
19848 (set (match_operand:QI 0 "memory_operand" "")
19849 (match_operand:QI 1 "immediate_operand" ""))]
19850 "optimize_insn_for_speed_p ()
19851 && TARGET_SPLIT_LONG_MOVES
19852 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19853 [(set (match_dup 2) (match_dup 1))
19854 (set (match_dup 0) (match_dup 2))]
19857 ;; Don't compare memory with zero, load and use a test instead.
19859 [(set (match_operand 0 "flags_reg_operand" "")
19860 (match_operator 1 "compare_operator"
19861 [(match_operand:SI 2 "memory_operand" "")
19863 (match_scratch:SI 3 "r")]
19864 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19865 [(set (match_dup 3) (match_dup 2))
19866 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19869 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19870 ;; Don't split NOTs with a displacement operand, because resulting XOR
19871 ;; will not be pairable anyway.
19873 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19874 ;; represented using a modRM byte. The XOR replacement is long decoded,
19875 ;; so this split helps here as well.
19877 ;; Note: Can't do this as a regular split because we can't get proper
19878 ;; lifetime information then.
19881 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19882 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19883 "optimize_insn_for_speed_p ()
19884 && ((TARGET_NOT_UNPAIRABLE
19885 && (!MEM_P (operands[0])
19886 || !memory_displacement_operand (operands[0], SImode)))
19887 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19888 && peep2_regno_dead_p (0, FLAGS_REG)"
19889 [(parallel [(set (match_dup 0)
19890 (xor:SI (match_dup 1) (const_int -1)))
19891 (clobber (reg:CC FLAGS_REG))])]
19895 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19896 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19897 "optimize_insn_for_speed_p ()
19898 && ((TARGET_NOT_UNPAIRABLE
19899 && (!MEM_P (operands[0])
19900 || !memory_displacement_operand (operands[0], HImode)))
19901 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19902 && peep2_regno_dead_p (0, FLAGS_REG)"
19903 [(parallel [(set (match_dup 0)
19904 (xor:HI (match_dup 1) (const_int -1)))
19905 (clobber (reg:CC FLAGS_REG))])]
19909 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19910 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19911 "optimize_insn_for_speed_p ()
19912 && ((TARGET_NOT_UNPAIRABLE
19913 && (!MEM_P (operands[0])
19914 || !memory_displacement_operand (operands[0], QImode)))
19915 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19916 && peep2_regno_dead_p (0, FLAGS_REG)"
19917 [(parallel [(set (match_dup 0)
19918 (xor:QI (match_dup 1) (const_int -1)))
19919 (clobber (reg:CC FLAGS_REG))])]
19922 ;; Non pairable "test imm, reg" instructions can be translated to
19923 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19924 ;; byte opcode instead of two, have a short form for byte operands),
19925 ;; so do it for other CPUs as well. Given that the value was dead,
19926 ;; this should not create any new dependencies. Pass on the sub-word
19927 ;; versions if we're concerned about partial register stalls.
19930 [(set (match_operand 0 "flags_reg_operand" "")
19931 (match_operator 1 "compare_operator"
19932 [(and:SI (match_operand:SI 2 "register_operand" "")
19933 (match_operand:SI 3 "immediate_operand" ""))
19935 "ix86_match_ccmode (insn, CCNOmode)
19936 && (true_regnum (operands[2]) != AX_REG
19937 || satisfies_constraint_K (operands[3]))
19938 && peep2_reg_dead_p (1, operands[2])"
19940 [(set (match_dup 0)
19941 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19944 (and:SI (match_dup 2) (match_dup 3)))])]
19947 ;; We don't need to handle HImode case, because it will be promoted to SImode
19948 ;; on ! TARGET_PARTIAL_REG_STALL
19951 [(set (match_operand 0 "flags_reg_operand" "")
19952 (match_operator 1 "compare_operator"
19953 [(and:QI (match_operand:QI 2 "register_operand" "")
19954 (match_operand:QI 3 "immediate_operand" ""))
19956 "! TARGET_PARTIAL_REG_STALL
19957 && ix86_match_ccmode (insn, CCNOmode)
19958 && true_regnum (operands[2]) != AX_REG
19959 && peep2_reg_dead_p (1, operands[2])"
19961 [(set (match_dup 0)
19962 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19965 (and:QI (match_dup 2) (match_dup 3)))])]
19969 [(set (match_operand 0 "flags_reg_operand" "")
19970 (match_operator 1 "compare_operator"
19973 (match_operand 2 "ext_register_operand" "")
19976 (match_operand 3 "const_int_operand" ""))
19978 "! TARGET_PARTIAL_REG_STALL
19979 && ix86_match_ccmode (insn, CCNOmode)
19980 && true_regnum (operands[2]) != AX_REG
19981 && peep2_reg_dead_p (1, operands[2])"
19982 [(parallel [(set (match_dup 0)
19991 (set (zero_extract:SI (match_dup 2)
20002 ;; Don't do logical operations with memory inputs.
20004 [(match_scratch:SI 2 "r")
20005 (parallel [(set (match_operand:SI 0 "register_operand" "")
20006 (match_operator:SI 3 "arith_or_logical_operator"
20008 (match_operand:SI 1 "memory_operand" "")]))
20009 (clobber (reg:CC FLAGS_REG))])]
20010 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20011 [(set (match_dup 2) (match_dup 1))
20012 (parallel [(set (match_dup 0)
20013 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20014 (clobber (reg:CC FLAGS_REG))])]
20018 [(match_scratch:SI 2 "r")
20019 (parallel [(set (match_operand:SI 0 "register_operand" "")
20020 (match_operator:SI 3 "arith_or_logical_operator"
20021 [(match_operand:SI 1 "memory_operand" "")
20023 (clobber (reg:CC FLAGS_REG))])]
20024 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20025 [(set (match_dup 2) (match_dup 1))
20026 (parallel [(set (match_dup 0)
20027 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20028 (clobber (reg:CC FLAGS_REG))])]
20031 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20032 ;; refers to the destination of the load!
20035 [(set (match_operand:SI 0 "register_operand" "")
20036 (match_operand:SI 1 "register_operand" ""))
20037 (parallel [(set (match_dup 0)
20038 (match_operator:SI 3 "commutative_operator"
20040 (match_operand:SI 2 "memory_operand" "")]))
20041 (clobber (reg:CC FLAGS_REG))])]
20042 "REGNO (operands[0]) != REGNO (operands[1])
20043 && GENERAL_REGNO_P (REGNO (operands[0]))
20044 && GENERAL_REGNO_P (REGNO (operands[1]))"
20045 [(set (match_dup 0) (match_dup 4))
20046 (parallel [(set (match_dup 0)
20047 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20048 (clobber (reg:CC FLAGS_REG))])]
20049 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20052 [(set (match_operand 0 "register_operand" "")
20053 (match_operand 1 "register_operand" ""))
20055 (match_operator 3 "commutative_operator"
20057 (match_operand 2 "memory_operand" "")]))]
20058 "REGNO (operands[0]) != REGNO (operands[1])
20059 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20060 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20061 [(set (match_dup 0) (match_dup 2))
20063 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20066 ; Don't do logical operations with memory outputs
20068 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20069 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20070 ; the same decoder scheduling characteristics as the original.
20073 [(match_scratch:SI 2 "r")
20074 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20075 (match_operator:SI 3 "arith_or_logical_operator"
20077 (match_operand:SI 1 "nonmemory_operand" "")]))
20078 (clobber (reg:CC FLAGS_REG))])]
20079 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20080 /* Do not split stack checking probes. */
20081 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20082 [(set (match_dup 2) (match_dup 0))
20083 (parallel [(set (match_dup 2)
20084 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20085 (clobber (reg:CC FLAGS_REG))])
20086 (set (match_dup 0) (match_dup 2))]
20090 [(match_scratch:SI 2 "r")
20091 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20092 (match_operator:SI 3 "arith_or_logical_operator"
20093 [(match_operand:SI 1 "nonmemory_operand" "")
20095 (clobber (reg:CC FLAGS_REG))])]
20096 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20097 /* Do not split stack checking probes. */
20098 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20099 [(set (match_dup 2) (match_dup 0))
20100 (parallel [(set (match_dup 2)
20101 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20102 (clobber (reg:CC FLAGS_REG))])
20103 (set (match_dup 0) (match_dup 2))]
20106 ;; Attempt to always use XOR for zeroing registers.
20108 [(set (match_operand 0 "register_operand" "")
20109 (match_operand 1 "const0_operand" ""))]
20110 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20111 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20112 && GENERAL_REG_P (operands[0])
20113 && peep2_regno_dead_p (0, FLAGS_REG)"
20114 [(parallel [(set (match_dup 0) (const_int 0))
20115 (clobber (reg:CC FLAGS_REG))])]
20117 operands[0] = gen_lowpart (word_mode, operands[0]);
20121 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20123 "(GET_MODE (operands[0]) == QImode
20124 || GET_MODE (operands[0]) == HImode)
20125 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20126 && peep2_regno_dead_p (0, FLAGS_REG)"
20127 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20128 (clobber (reg:CC FLAGS_REG))])])
20130 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20132 [(set (match_operand 0 "register_operand" "")
20134 "(GET_MODE (operands[0]) == HImode
20135 || GET_MODE (operands[0]) == SImode
20136 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20137 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20138 && peep2_regno_dead_p (0, FLAGS_REG)"
20139 [(parallel [(set (match_dup 0) (const_int -1))
20140 (clobber (reg:CC FLAGS_REG))])]
20141 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20144 ;; Attempt to convert simple leas to adds. These can be created by
20147 [(set (match_operand:SI 0 "register_operand" "")
20148 (plus:SI (match_dup 0)
20149 (match_operand:SI 1 "nonmemory_operand" "")))]
20150 "peep2_regno_dead_p (0, FLAGS_REG)"
20151 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20152 (clobber (reg:CC FLAGS_REG))])]
20156 [(set (match_operand:SI 0 "register_operand" "")
20157 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20158 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20159 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20160 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20161 (clobber (reg:CC FLAGS_REG))])]
20162 "operands[2] = gen_lowpart (SImode, operands[2]);")
20165 [(set (match_operand:DI 0 "register_operand" "")
20166 (plus:DI (match_dup 0)
20167 (match_operand:DI 1 "x86_64_general_operand" "")))]
20168 "peep2_regno_dead_p (0, FLAGS_REG)"
20169 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20170 (clobber (reg:CC FLAGS_REG))])]
20174 [(set (match_operand:SI 0 "register_operand" "")
20175 (mult:SI (match_dup 0)
20176 (match_operand:SI 1 "const_int_operand" "")))]
20177 "exact_log2 (INTVAL (operands[1])) >= 0
20178 && peep2_regno_dead_p (0, FLAGS_REG)"
20179 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20180 (clobber (reg:CC FLAGS_REG))])]
20181 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20184 [(set (match_operand:DI 0 "register_operand" "")
20185 (mult:DI (match_dup 0)
20186 (match_operand:DI 1 "const_int_operand" "")))]
20187 "exact_log2 (INTVAL (operands[1])) >= 0
20188 && peep2_regno_dead_p (0, FLAGS_REG)"
20189 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20190 (clobber (reg:CC FLAGS_REG))])]
20191 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20194 [(set (match_operand:SI 0 "register_operand" "")
20195 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20196 (match_operand:DI 2 "const_int_operand" "")) 0))]
20197 "exact_log2 (INTVAL (operands[2])) >= 0
20198 && REGNO (operands[0]) == REGNO (operands[1])
20199 && peep2_regno_dead_p (0, FLAGS_REG)"
20200 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20201 (clobber (reg:CC FLAGS_REG))])]
20202 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20204 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20205 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20206 ;; many CPUs it is also faster, since special hardware to avoid esp
20207 ;; dependencies is present.
20209 ;; While some of these conversions may be done using splitters, we use peepholes
20210 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20212 ;; Convert prologue esp subtractions to push.
20213 ;; We need register to push. In order to keep verify_flow_info happy we have
20215 ;; - use scratch and clobber it in order to avoid dependencies
20216 ;; - use already live register
20217 ;; We can't use the second way right now, since there is no reliable way how to
20218 ;; verify that given register is live. First choice will also most likely in
20219 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20220 ;; call clobbered registers are dead. We may want to use base pointer as an
20221 ;; alternative when no register is available later.
20224 [(match_scratch:SI 0 "r")
20225 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20226 (clobber (reg:CC FLAGS_REG))
20227 (clobber (mem:BLK (scratch)))])]
20228 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20229 [(clobber (match_dup 0))
20230 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20231 (clobber (mem:BLK (scratch)))])])
20234 [(match_scratch:SI 0 "r")
20235 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20236 (clobber (reg:CC FLAGS_REG))
20237 (clobber (mem:BLK (scratch)))])]
20238 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20239 [(clobber (match_dup 0))
20240 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20241 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20242 (clobber (mem:BLK (scratch)))])])
20244 ;; Convert esp subtractions to push.
20246 [(match_scratch:SI 0 "r")
20247 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20248 (clobber (reg:CC FLAGS_REG))])]
20249 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20250 [(clobber (match_dup 0))
20251 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20254 [(match_scratch:SI 0 "r")
20255 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20256 (clobber (reg:CC FLAGS_REG))])]
20257 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20258 [(clobber (match_dup 0))
20259 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20260 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20262 ;; Convert epilogue deallocator to pop.
20264 [(match_scratch:SI 0 "r")
20265 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20266 (clobber (reg:CC FLAGS_REG))
20267 (clobber (mem:BLK (scratch)))])]
20268 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20269 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20270 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20271 (clobber (mem:BLK (scratch)))])]
20274 ;; Two pops case is tricky, since pop causes dependency on destination register.
20275 ;; We use two registers if available.
20277 [(match_scratch:SI 0 "r")
20278 (match_scratch:SI 1 "r")
20279 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20280 (clobber (reg:CC FLAGS_REG))
20281 (clobber (mem:BLK (scratch)))])]
20282 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20283 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20284 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20285 (clobber (mem:BLK (scratch)))])
20286 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20287 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20291 [(match_scratch:SI 0 "r")
20292 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20293 (clobber (reg:CC FLAGS_REG))
20294 (clobber (mem:BLK (scratch)))])]
20295 "optimize_insn_for_size_p ()"
20296 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20297 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20298 (clobber (mem:BLK (scratch)))])
20299 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20300 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20303 ;; Convert esp additions to pop.
20305 [(match_scratch:SI 0 "r")
20306 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20307 (clobber (reg:CC FLAGS_REG))])]
20309 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20310 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20313 ;; Two pops case is tricky, since pop causes dependency on destination register.
20314 ;; We use two registers if available.
20316 [(match_scratch:SI 0 "r")
20317 (match_scratch:SI 1 "r")
20318 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20319 (clobber (reg:CC FLAGS_REG))])]
20321 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20322 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20323 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20324 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20328 [(match_scratch:SI 0 "r")
20329 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20330 (clobber (reg:CC FLAGS_REG))])]
20331 "optimize_insn_for_size_p ()"
20332 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20333 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20334 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20335 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20338 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20339 ;; required and register dies. Similarly for 128 to -128.
20341 [(set (match_operand 0 "flags_reg_operand" "")
20342 (match_operator 1 "compare_operator"
20343 [(match_operand 2 "register_operand" "")
20344 (match_operand 3 "const_int_operand" "")]))]
20345 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20346 && incdec_operand (operands[3], GET_MODE (operands[3])))
20347 || (!TARGET_FUSE_CMP_AND_BRANCH
20348 && INTVAL (operands[3]) == 128))
20349 && ix86_match_ccmode (insn, CCGCmode)
20350 && peep2_reg_dead_p (1, operands[2])"
20351 [(parallel [(set (match_dup 0)
20352 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20353 (clobber (match_dup 2))])]
20357 [(match_scratch:DI 0 "r")
20358 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20359 (clobber (reg:CC FLAGS_REG))
20360 (clobber (mem:BLK (scratch)))])]
20361 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20362 [(clobber (match_dup 0))
20363 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20364 (clobber (mem:BLK (scratch)))])])
20367 [(match_scratch:DI 0 "r")
20368 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20369 (clobber (reg:CC FLAGS_REG))
20370 (clobber (mem:BLK (scratch)))])]
20371 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20372 [(clobber (match_dup 0))
20373 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20374 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20375 (clobber (mem:BLK (scratch)))])])
20377 ;; Convert esp subtractions to push.
20379 [(match_scratch:DI 0 "r")
20380 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20381 (clobber (reg:CC FLAGS_REG))])]
20382 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20383 [(clobber (match_dup 0))
20384 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20387 [(match_scratch:DI 0 "r")
20388 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20389 (clobber (reg:CC FLAGS_REG))])]
20390 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20391 [(clobber (match_dup 0))
20392 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20393 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20395 ;; Convert epilogue deallocator to pop.
20397 [(match_scratch:DI 0 "r")
20398 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20399 (clobber (reg:CC FLAGS_REG))
20400 (clobber (mem:BLK (scratch)))])]
20401 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20402 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20403 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20404 (clobber (mem:BLK (scratch)))])]
20407 ;; Two pops case is tricky, since pop causes dependency on destination register.
20408 ;; We use two registers if available.
20410 [(match_scratch:DI 0 "r")
20411 (match_scratch:DI 1 "r")
20412 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20413 (clobber (reg:CC FLAGS_REG))
20414 (clobber (mem:BLK (scratch)))])]
20415 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20416 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20417 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20418 (clobber (mem:BLK (scratch)))])
20419 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20420 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20424 [(match_scratch:DI 0 "r")
20425 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20426 (clobber (reg:CC FLAGS_REG))
20427 (clobber (mem:BLK (scratch)))])]
20428 "optimize_insn_for_size_p ()"
20429 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20430 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20431 (clobber (mem:BLK (scratch)))])
20432 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20433 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20436 ;; Convert esp additions to pop.
20438 [(match_scratch:DI 0 "r")
20439 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20440 (clobber (reg:CC FLAGS_REG))])]
20442 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20443 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20446 ;; Two pops case is tricky, since pop causes dependency on destination register.
20447 ;; We use two registers if available.
20449 [(match_scratch:DI 0 "r")
20450 (match_scratch:DI 1 "r")
20451 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20452 (clobber (reg:CC FLAGS_REG))])]
20454 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20455 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20456 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20457 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20461 [(match_scratch:DI 0 "r")
20462 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20463 (clobber (reg:CC FLAGS_REG))])]
20464 "optimize_insn_for_size_p ()"
20465 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20466 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20467 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20468 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20471 ;; Convert imul by three, five and nine into lea
20474 [(set (match_operand:SI 0 "register_operand" "")
20475 (mult:SI (match_operand:SI 1 "register_operand" "")
20476 (match_operand:SI 2 "const_int_operand" "")))
20477 (clobber (reg:CC FLAGS_REG))])]
20478 "INTVAL (operands[2]) == 3
20479 || INTVAL (operands[2]) == 5
20480 || INTVAL (operands[2]) == 9"
20481 [(set (match_dup 0)
20482 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20484 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20488 [(set (match_operand:SI 0 "register_operand" "")
20489 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20490 (match_operand:SI 2 "const_int_operand" "")))
20491 (clobber (reg:CC FLAGS_REG))])]
20492 "optimize_insn_for_speed_p ()
20493 && (INTVAL (operands[2]) == 3
20494 || INTVAL (operands[2]) == 5
20495 || INTVAL (operands[2]) == 9)"
20496 [(set (match_dup 0) (match_dup 1))
20498 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20500 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20504 [(set (match_operand:DI 0 "register_operand" "")
20505 (mult:DI (match_operand:DI 1 "register_operand" "")
20506 (match_operand:DI 2 "const_int_operand" "")))
20507 (clobber (reg:CC FLAGS_REG))])]
20509 && (INTVAL (operands[2]) == 3
20510 || INTVAL (operands[2]) == 5
20511 || INTVAL (operands[2]) == 9)"
20512 [(set (match_dup 0)
20513 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20515 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20519 [(set (match_operand:DI 0 "register_operand" "")
20520 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20521 (match_operand:DI 2 "const_int_operand" "")))
20522 (clobber (reg:CC FLAGS_REG))])]
20524 && optimize_insn_for_speed_p ()
20525 && (INTVAL (operands[2]) == 3
20526 || INTVAL (operands[2]) == 5
20527 || INTVAL (operands[2]) == 9)"
20528 [(set (match_dup 0) (match_dup 1))
20530 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20532 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20534 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20535 ;; imul $32bit_imm, reg, reg is direct decoded.
20537 [(match_scratch:DI 3 "r")
20538 (parallel [(set (match_operand:DI 0 "register_operand" "")
20539 (mult:DI (match_operand:DI 1 "memory_operand" "")
20540 (match_operand:DI 2 "immediate_operand" "")))
20541 (clobber (reg:CC FLAGS_REG))])]
20542 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20543 && !satisfies_constraint_K (operands[2])"
20544 [(set (match_dup 3) (match_dup 1))
20545 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20546 (clobber (reg:CC FLAGS_REG))])]
20550 [(match_scratch:SI 3 "r")
20551 (parallel [(set (match_operand:SI 0 "register_operand" "")
20552 (mult:SI (match_operand:SI 1 "memory_operand" "")
20553 (match_operand:SI 2 "immediate_operand" "")))
20554 (clobber (reg:CC FLAGS_REG))])]
20555 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20556 && !satisfies_constraint_K (operands[2])"
20557 [(set (match_dup 3) (match_dup 1))
20558 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20559 (clobber (reg:CC FLAGS_REG))])]
20563 [(match_scratch:SI 3 "r")
20564 (parallel [(set (match_operand:DI 0 "register_operand" "")
20566 (mult:SI (match_operand:SI 1 "memory_operand" "")
20567 (match_operand:SI 2 "immediate_operand" ""))))
20568 (clobber (reg:CC FLAGS_REG))])]
20569 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20570 && !satisfies_constraint_K (operands[2])"
20571 [(set (match_dup 3) (match_dup 1))
20572 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20573 (clobber (reg:CC FLAGS_REG))])]
20576 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20577 ;; Convert it into imul reg, reg
20578 ;; It would be better to force assembler to encode instruction using long
20579 ;; immediate, but there is apparently no way to do so.
20581 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20582 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20583 (match_operand:DI 2 "const_int_operand" "")))
20584 (clobber (reg:CC FLAGS_REG))])
20585 (match_scratch:DI 3 "r")]
20586 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20587 && satisfies_constraint_K (operands[2])"
20588 [(set (match_dup 3) (match_dup 2))
20589 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20590 (clobber (reg:CC FLAGS_REG))])]
20592 if (!rtx_equal_p (operands[0], operands[1]))
20593 emit_move_insn (operands[0], operands[1]);
20597 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20598 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20599 (match_operand:SI 2 "const_int_operand" "")))
20600 (clobber (reg:CC FLAGS_REG))])
20601 (match_scratch:SI 3 "r")]
20602 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20603 && satisfies_constraint_K (operands[2])"
20604 [(set (match_dup 3) (match_dup 2))
20605 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20606 (clobber (reg:CC FLAGS_REG))])]
20608 if (!rtx_equal_p (operands[0], operands[1]))
20609 emit_move_insn (operands[0], operands[1]);
20613 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20614 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20615 (match_operand:HI 2 "immediate_operand" "")))
20616 (clobber (reg:CC FLAGS_REG))])
20617 (match_scratch:HI 3 "r")]
20618 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20619 [(set (match_dup 3) (match_dup 2))
20620 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20621 (clobber (reg:CC FLAGS_REG))])]
20623 if (!rtx_equal_p (operands[0], operands[1]))
20624 emit_move_insn (operands[0], operands[1]);
20627 ;; After splitting up read-modify operations, array accesses with memory
20628 ;; operands might end up in form:
20630 ;; movl 4(%esp), %edx
20632 ;; instead of pre-splitting:
20634 ;; addl 4(%esp), %eax
20636 ;; movl 4(%esp), %edx
20637 ;; leal (%edx,%eax,4), %eax
20640 [(parallel [(set (match_operand 0 "register_operand" "")
20641 (ashift (match_operand 1 "register_operand" "")
20642 (match_operand 2 "const_int_operand" "")))
20643 (clobber (reg:CC FLAGS_REG))])
20644 (set (match_operand 3 "register_operand")
20645 (match_operand 4 "x86_64_general_operand" ""))
20646 (parallel [(set (match_operand 5 "register_operand" "")
20647 (plus (match_operand 6 "register_operand" "")
20648 (match_operand 7 "register_operand" "")))
20649 (clobber (reg:CC FLAGS_REG))])]
20650 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20651 /* Validate MODE for lea. */
20652 && ((!TARGET_PARTIAL_REG_STALL
20653 && (GET_MODE (operands[0]) == QImode
20654 || GET_MODE (operands[0]) == HImode))
20655 || GET_MODE (operands[0]) == SImode
20656 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20657 /* We reorder load and the shift. */
20658 && !rtx_equal_p (operands[1], operands[3])
20659 && !reg_overlap_mentioned_p (operands[0], operands[4])
20660 /* Last PLUS must consist of operand 0 and 3. */
20661 && !rtx_equal_p (operands[0], operands[3])
20662 && (rtx_equal_p (operands[3], operands[6])
20663 || rtx_equal_p (operands[3], operands[7]))
20664 && (rtx_equal_p (operands[0], operands[6])
20665 || rtx_equal_p (operands[0], operands[7]))
20666 /* The intermediate operand 0 must die or be same as output. */
20667 && (rtx_equal_p (operands[0], operands[5])
20668 || peep2_reg_dead_p (3, operands[0]))"
20669 [(set (match_dup 3) (match_dup 4))
20670 (set (match_dup 0) (match_dup 1))]
20672 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20673 int scale = 1 << INTVAL (operands[2]);
20674 rtx index = gen_lowpart (Pmode, operands[1]);
20675 rtx base = gen_lowpart (Pmode, operands[3]);
20676 rtx dest = gen_lowpart (mode, operands[5]);
20678 operands[1] = gen_rtx_PLUS (Pmode, base,
20679 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20681 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20682 operands[0] = dest;
20685 ;; Call-value patterns last so that the wildcard operand does not
20686 ;; disrupt insn-recog's switch tables.
20688 (define_insn "*call_value_pop_0"
20689 [(set (match_operand 0 "" "")
20690 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20691 (match_operand:SI 2 "" "")))
20692 (set (reg:SI SP_REG)
20693 (plus:SI (reg:SI SP_REG)
20694 (match_operand:SI 3 "immediate_operand" "")))]
20697 if (SIBLING_CALL_P (insn))
20700 return "call\t%P1";
20702 [(set_attr "type" "callv")])
20704 (define_insn "*call_value_pop_1"
20705 [(set (match_operand 0 "" "")
20706 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20707 (match_operand:SI 2 "" "")))
20708 (set (reg:SI SP_REG)
20709 (plus:SI (reg:SI SP_REG)
20710 (match_operand:SI 3 "immediate_operand" "i")))]
20711 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20713 if (constant_call_address_operand (operands[1], Pmode))
20714 return "call\t%P1";
20715 return "call\t%A1";
20717 [(set_attr "type" "callv")])
20719 (define_insn "*sibcall_value_pop_1"
20720 [(set (match_operand 0 "" "")
20721 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20722 (match_operand:SI 2 "" "")))
20723 (set (reg:SI SP_REG)
20724 (plus:SI (reg:SI SP_REG)
20725 (match_operand:SI 3 "immediate_operand" "i,i")))]
20726 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20730 [(set_attr "type" "callv")])
20732 (define_insn "*call_value_0"
20733 [(set (match_operand 0 "" "")
20734 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20735 (match_operand:SI 2 "" "")))]
20738 if (SIBLING_CALL_P (insn))
20741 return "call\t%P1";
20743 [(set_attr "type" "callv")])
20745 (define_insn "*call_value_0_rex64"
20746 [(set (match_operand 0 "" "")
20747 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20748 (match_operand:DI 2 "const_int_operand" "")))]
20751 if (SIBLING_CALL_P (insn))
20754 return "call\t%P1";
20756 [(set_attr "type" "callv")])
20758 (define_insn "*call_value_0_rex64_ms_sysv"
20759 [(set (match_operand 0 "" "")
20760 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20761 (match_operand:DI 2 "const_int_operand" "")))
20762 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20763 (clobber (reg:TI XMM6_REG))
20764 (clobber (reg:TI XMM7_REG))
20765 (clobber (reg:TI XMM8_REG))
20766 (clobber (reg:TI XMM9_REG))
20767 (clobber (reg:TI XMM10_REG))
20768 (clobber (reg:TI XMM11_REG))
20769 (clobber (reg:TI XMM12_REG))
20770 (clobber (reg:TI XMM13_REG))
20771 (clobber (reg:TI XMM14_REG))
20772 (clobber (reg:TI XMM15_REG))
20773 (clobber (reg:DI SI_REG))
20774 (clobber (reg:DI DI_REG))]
20775 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20777 if (SIBLING_CALL_P (insn))
20780 return "call\t%P1";
20782 [(set_attr "type" "callv")])
20784 (define_insn "*call_value_1"
20785 [(set (match_operand 0 "" "")
20786 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20787 (match_operand:SI 2 "" "")))]
20788 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20790 if (constant_call_address_operand (operands[1], Pmode))
20791 return "call\t%P1";
20792 return "call\t%A1";
20794 [(set_attr "type" "callv")])
20796 (define_insn "*sibcall_value_1"
20797 [(set (match_operand 0 "" "")
20798 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20799 (match_operand:SI 2 "" "")))]
20800 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20804 [(set_attr "type" "callv")])
20806 (define_insn "*call_value_1_rex64"
20807 [(set (match_operand 0 "" "")
20808 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20809 (match_operand:DI 2 "" "")))]
20810 "TARGET_64BIT && !SIBLING_CALL_P (insn)
20811 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20813 if (constant_call_address_operand (operands[1], Pmode))
20814 return "call\t%P1";
20815 return "call\t%A1";
20817 [(set_attr "type" "callv")])
20819 (define_insn "*call_value_1_rex64_ms_sysv"
20820 [(set (match_operand 0 "" "")
20821 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20822 (match_operand:DI 2 "" "")))
20823 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20824 (clobber (reg:TI XMM6_REG))
20825 (clobber (reg:TI XMM7_REG))
20826 (clobber (reg:TI XMM8_REG))
20827 (clobber (reg:TI XMM9_REG))
20828 (clobber (reg:TI XMM10_REG))
20829 (clobber (reg:TI XMM11_REG))
20830 (clobber (reg:TI XMM12_REG))
20831 (clobber (reg:TI XMM13_REG))
20832 (clobber (reg:TI XMM14_REG))
20833 (clobber (reg:TI XMM15_REG))
20834 (clobber (reg:DI SI_REG))
20835 (clobber (reg:DI DI_REG))]
20836 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20838 if (constant_call_address_operand (operands[1], Pmode))
20839 return "call\t%P1";
20840 return "call\t%A1";
20842 [(set_attr "type" "callv")])
20844 (define_insn "*call_value_1_rex64_large"
20845 [(set (match_operand 0 "" "")
20846 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20847 (match_operand:DI 2 "" "")))]
20848 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20850 [(set_attr "type" "callv")])
20852 (define_insn "*sibcall_value_1_rex64"
20853 [(set (match_operand 0 "" "")
20854 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20855 (match_operand:DI 2 "" "")))]
20856 "TARGET_64BIT && SIBLING_CALL_P (insn)"
20860 [(set_attr "type" "callv")])
20862 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20863 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20864 ;; caught for use by garbage collectors and the like. Using an insn that
20865 ;; maps to SIGILL makes it more likely the program will rightfully die.
20866 ;; Keeping with tradition, "6" is in honor of #UD.
20867 (define_insn "trap"
20868 [(trap_if (const_int 1) (const_int 6))]
20870 { return ASM_SHORT "0x0b0f"; }
20871 [(set_attr "length" "2")])
20873 (define_expand "sse_prologue_save"
20874 [(parallel [(set (match_operand:BLK 0 "" "")
20875 (unspec:BLK [(reg:DI XMM0_REG)
20882 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20883 (use (match_operand:DI 1 "register_operand" ""))
20884 (use (match_operand:DI 2 "immediate_operand" ""))
20885 (use (label_ref:DI (match_operand 3 "" "")))])]
20889 (define_insn "*sse_prologue_save_insn"
20890 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20891 (match_operand:DI 4 "const_int_operand" "n")))
20892 (unspec:BLK [(reg:DI XMM0_REG)
20899 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20900 (use (match_operand:DI 1 "register_operand" "r"))
20901 (use (match_operand:DI 2 "const_int_operand" "i"))
20902 (use (label_ref:DI (match_operand 3 "" "X")))]
20904 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20905 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20908 operands[0] = gen_rtx_MEM (Pmode,
20909 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20910 /* VEX instruction with a REX prefix will #UD. */
20911 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20912 gcc_unreachable ();
20914 output_asm_insn ("jmp\t%A1", operands);
20915 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20917 operands[4] = adjust_address (operands[0], DImode, i*16);
20918 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20919 PUT_MODE (operands[4], TImode);
20920 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20921 output_asm_insn ("rex", operands);
20922 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20924 (*targetm.asm_out.internal_label) (asm_out_file, "L",
20925 CODE_LABEL_NUMBER (operands[3]));
20928 [(set_attr "type" "other")
20929 (set_attr "length_immediate" "0")
20930 (set_attr "length_address" "0")
20931 (set (attr "length")
20933 (eq (symbol_ref "TARGET_AVX") (const_int 0))
20934 (const_string "34")
20935 (const_string "42")))
20936 (set_attr "memory" "store")
20937 (set_attr "modrm" "0")
20938 (set_attr "prefix" "maybe_vex")
20939 (set_attr "mode" "DI")])
20941 (define_expand "prefetch"
20942 [(prefetch (match_operand 0 "address_operand" "")
20943 (match_operand:SI 1 "const_int_operand" "")
20944 (match_operand:SI 2 "const_int_operand" ""))]
20945 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20947 int rw = INTVAL (operands[1]);
20948 int locality = INTVAL (operands[2]);
20950 gcc_assert (rw == 0 || rw == 1);
20951 gcc_assert (locality >= 0 && locality <= 3);
20952 gcc_assert (GET_MODE (operands[0]) == Pmode
20953 || GET_MODE (operands[0]) == VOIDmode);
20955 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20956 supported by SSE counterpart or the SSE prefetch is not available
20957 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20959 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20960 operands[2] = GEN_INT (3);
20962 operands[1] = const0_rtx;
20965 (define_insn "*prefetch_sse"
20966 [(prefetch (match_operand:SI 0 "address_operand" "p")
20968 (match_operand:SI 1 "const_int_operand" ""))]
20969 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20971 static const char * const patterns[4] = {
20972 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20975 int locality = INTVAL (operands[1]);
20976 gcc_assert (locality >= 0 && locality <= 3);
20978 return patterns[locality];
20980 [(set_attr "type" "sse")
20981 (set_attr "atom_sse_attr" "prefetch")
20982 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20983 (set_attr "memory" "none")])
20985 (define_insn "*prefetch_sse_rex"
20986 [(prefetch (match_operand:DI 0 "address_operand" "p")
20988 (match_operand:SI 1 "const_int_operand" ""))]
20989 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20991 static const char * const patterns[4] = {
20992 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20995 int locality = INTVAL (operands[1]);
20996 gcc_assert (locality >= 0 && locality <= 3);
20998 return patterns[locality];
21000 [(set_attr "type" "sse")
21001 (set_attr "atom_sse_attr" "prefetch")
21002 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21003 (set_attr "memory" "none")])
21005 (define_insn "*prefetch_3dnow"
21006 [(prefetch (match_operand:SI 0 "address_operand" "p")
21007 (match_operand:SI 1 "const_int_operand" "n")
21009 "TARGET_3DNOW && !TARGET_64BIT"
21011 if (INTVAL (operands[1]) == 0)
21012 return "prefetch\t%a0";
21014 return "prefetchw\t%a0";
21016 [(set_attr "type" "mmx")
21017 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21018 (set_attr "memory" "none")])
21020 (define_insn "*prefetch_3dnow_rex"
21021 [(prefetch (match_operand:DI 0 "address_operand" "p")
21022 (match_operand:SI 1 "const_int_operand" "n")
21024 "TARGET_3DNOW && TARGET_64BIT"
21026 if (INTVAL (operands[1]) == 0)
21027 return "prefetch\t%a0";
21029 return "prefetchw\t%a0";
21031 [(set_attr "type" "mmx")
21032 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21033 (set_attr "memory" "none")])
21035 (define_expand "stack_protect_set"
21036 [(match_operand 0 "memory_operand" "")
21037 (match_operand 1 "memory_operand" "")]
21040 #ifdef TARGET_THREAD_SSP_OFFSET
21042 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21043 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21045 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21046 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21049 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21051 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21056 (define_insn "stack_protect_set_si"
21057 [(set (match_operand:SI 0 "memory_operand" "=m")
21058 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21059 (set (match_scratch:SI 2 "=&r") (const_int 0))
21060 (clobber (reg:CC FLAGS_REG))]
21062 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21063 [(set_attr "type" "multi")])
21065 (define_insn "stack_protect_set_di"
21066 [(set (match_operand:DI 0 "memory_operand" "=m")
21067 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21068 (set (match_scratch:DI 2 "=&r") (const_int 0))
21069 (clobber (reg:CC FLAGS_REG))]
21071 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21072 [(set_attr "type" "multi")])
21074 (define_insn "stack_tls_protect_set_si"
21075 [(set (match_operand:SI 0 "memory_operand" "=m")
21076 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21077 (set (match_scratch:SI 2 "=&r") (const_int 0))
21078 (clobber (reg:CC FLAGS_REG))]
21080 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21081 [(set_attr "type" "multi")])
21083 (define_insn "stack_tls_protect_set_di"
21084 [(set (match_operand:DI 0 "memory_operand" "=m")
21085 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21086 (set (match_scratch:DI 2 "=&r") (const_int 0))
21087 (clobber (reg:CC FLAGS_REG))]
21090 /* The kernel uses a different segment register for performance reasons; a
21091 system call would not have to trash the userspace segment register,
21092 which would be expensive */
21093 if (ix86_cmodel != CM_KERNEL)
21094 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21096 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21098 [(set_attr "type" "multi")])
21100 (define_expand "stack_protect_test"
21101 [(match_operand 0 "memory_operand" "")
21102 (match_operand 1 "memory_operand" "")
21103 (match_operand 2 "" "")]
21106 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21108 #ifdef TARGET_THREAD_SSP_OFFSET
21110 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21111 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21113 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21114 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21117 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21119 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21122 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
21123 flags, const0_rtx, operands[2]));
21127 (define_insn "stack_protect_test_si"
21128 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21129 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21130 (match_operand:SI 2 "memory_operand" "m")]
21132 (clobber (match_scratch:SI 3 "=&r"))]
21134 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21135 [(set_attr "type" "multi")])
21137 (define_insn "stack_protect_test_di"
21138 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21139 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21140 (match_operand:DI 2 "memory_operand" "m")]
21142 (clobber (match_scratch:DI 3 "=&r"))]
21144 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21145 [(set_attr "type" "multi")])
21147 (define_insn "stack_tls_protect_test_si"
21148 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21149 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21150 (match_operand:SI 2 "const_int_operand" "i")]
21151 UNSPEC_SP_TLS_TEST))
21152 (clobber (match_scratch:SI 3 "=r"))]
21154 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21155 [(set_attr "type" "multi")])
21157 (define_insn "stack_tls_protect_test_di"
21158 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21159 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21160 (match_operand:DI 2 "const_int_operand" "i")]
21161 UNSPEC_SP_TLS_TEST))
21162 (clobber (match_scratch:DI 3 "=r"))]
21165 /* The kernel uses a different segment register for performance reasons; a
21166 system call would not have to trash the userspace segment register,
21167 which would be expensive */
21168 if (ix86_cmodel != CM_KERNEL)
21169 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21171 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21173 [(set_attr "type" "multi")])
21175 (define_insn "sse4_2_crc32<mode>"
21176 [(set (match_operand:SI 0 "register_operand" "=r")
21178 [(match_operand:SI 1 "register_operand" "0")
21179 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
21181 "TARGET_SSE4_2 || TARGET_CRC32"
21182 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
21183 [(set_attr "type" "sselog1")
21184 (set_attr "prefix_rep" "1")
21185 (set_attr "prefix_extra" "1")
21186 (set (attr "prefix_data16")
21187 (if_then_else (match_operand:HI 2 "" "")
21189 (const_string "*")))
21190 (set (attr "prefix_rex")
21191 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
21193 (const_string "*")))
21194 (set_attr "mode" "SI")])
21196 (define_insn "sse4_2_crc32di"
21197 [(set (match_operand:DI 0 "register_operand" "=r")
21199 [(match_operand:DI 1 "register_operand" "0")
21200 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21202 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21203 "crc32{q}\t{%2, %0|%0, %2}"
21204 [(set_attr "type" "sselog1")
21205 (set_attr "prefix_rep" "1")
21206 (set_attr "prefix_extra" "1")
21207 (set_attr "mode" "DI")])
21209 (define_expand "rdpmc"
21210 [(match_operand:DI 0 "register_operand" "")
21211 (match_operand:SI 1 "register_operand" "")]
21214 rtx reg = gen_reg_rtx (DImode);
21217 /* Force operand 1 into ECX. */
21218 rtx ecx = gen_rtx_REG (SImode, CX_REG);
21219 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
21220 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
21225 rtvec vec = rtvec_alloc (2);
21226 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21227 rtx upper = gen_reg_rtx (DImode);
21228 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21229 gen_rtvec (1, const0_rtx),
21231 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
21232 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21234 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21235 NULL, 1, OPTAB_DIRECT);
21236 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21240 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
21241 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21245 (define_insn "*rdpmc"
21246 [(set (match_operand:DI 0 "register_operand" "=A")
21247 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21251 [(set_attr "type" "other")
21252 (set_attr "length" "2")])
21254 (define_insn "*rdpmc_rex64"
21255 [(set (match_operand:DI 0 "register_operand" "=a")
21256 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21258 (set (match_operand:DI 1 "register_operand" "=d")
21259 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
21262 [(set_attr "type" "other")
21263 (set_attr "length" "2")])
21265 (define_expand "rdtsc"
21266 [(set (match_operand:DI 0 "register_operand" "")
21267 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21272 rtvec vec = rtvec_alloc (2);
21273 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21274 rtx upper = gen_reg_rtx (DImode);
21275 rtx lower = gen_reg_rtx (DImode);
21276 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
21277 gen_rtvec (1, const0_rtx),
21279 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
21280 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
21282 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21283 NULL, 1, OPTAB_DIRECT);
21284 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
21286 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
21291 (define_insn "*rdtsc"
21292 [(set (match_operand:DI 0 "register_operand" "=A")
21293 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21296 [(set_attr "type" "other")
21297 (set_attr "length" "2")])
21299 (define_insn "*rdtsc_rex64"
21300 [(set (match_operand:DI 0 "register_operand" "=a")
21301 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21302 (set (match_operand:DI 1 "register_operand" "=d")
21303 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21306 [(set_attr "type" "other")
21307 (set_attr "length" "2")])
21309 (define_expand "rdtscp"
21310 [(match_operand:DI 0 "register_operand" "")
21311 (match_operand:SI 1 "memory_operand" "")]
21314 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21315 gen_rtvec (1, const0_rtx),
21317 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21318 gen_rtvec (1, const0_rtx),
21320 rtx reg = gen_reg_rtx (DImode);
21321 rtx tmp = gen_reg_rtx (SImode);
21325 rtvec vec = rtvec_alloc (3);
21326 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21327 rtx upper = gen_reg_rtx (DImode);
21328 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21329 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21330 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
21332 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21333 NULL, 1, OPTAB_DIRECT);
21334 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21339 rtvec vec = rtvec_alloc (2);
21340 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21341 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21342 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
21345 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21346 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
21350 (define_insn "*rdtscp"
21351 [(set (match_operand:DI 0 "register_operand" "=A")
21352 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21353 (set (match_operand:SI 1 "register_operand" "=c")
21354 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21357 [(set_attr "type" "other")
21358 (set_attr "length" "3")])
21360 (define_insn "*rdtscp_rex64"
21361 [(set (match_operand:DI 0 "register_operand" "=a")
21362 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21363 (set (match_operand:DI 1 "register_operand" "=d")
21364 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21365 (set (match_operand:SI 2 "register_operand" "=c")
21366 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21369 [(set_attr "type" "other")
21370 (set_attr "length" "3")])
21372 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21374 ;; LWP instructions
21376 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21378 (define_insn "lwp_llwpcbhi1"
21379 [(unspec [(match_operand:HI 0 "register_operand" "r")]
21380 UNSPEC_LLWP_INTRINSIC)]
21383 [(set_attr "type" "lwp")
21384 (set_attr "mode" "HI")])
21386 (define_insn "lwp_llwpcbsi1"
21387 [(unspec [(match_operand:SI 0 "register_operand" "r")]
21388 UNSPEC_LLWP_INTRINSIC)]
21391 [(set_attr "type" "lwp")
21392 (set_attr "mode" "SI")])
21394 (define_insn "lwp_llwpcbdi1"
21395 [(unspec [(match_operand:DI 0 "register_operand" "r")]
21396 UNSPEC_LLWP_INTRINSIC)]
21399 [(set_attr "type" "lwp")
21400 (set_attr "mode" "DI")])
21402 (define_insn "lwp_slwpcbhi1"
21403 [(unspec [(match_operand:HI 0 "register_operand" "r")]
21404 UNSPEC_SLWP_INTRINSIC)]
21407 [(set_attr "type" "lwp")
21408 (set_attr "mode" "HI")])
21410 (define_insn "lwp_slwpcbsi1"
21411 [(unspec [(match_operand:SI 0 "register_operand" "r")]
21412 UNSPEC_SLWP_INTRINSIC)]
21415 [(set_attr "type" "lwp")
21416 (set_attr "mode" "SI")])
21418 (define_insn "lwp_slwpcbdi1"
21419 [(unspec [(match_operand:DI 0 "register_operand" "r")]
21420 UNSPEC_SLWP_INTRINSIC)]
21423 [(set_attr "type" "lwp")
21424 (set_attr "mode" "DI")])
21426 (define_insn "lwp_lwpvalhi3"
21427 [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21428 (match_operand:SI 1 "nonimmediate_operand" "rm")
21429 (match_operand:HI 2 "const_int_operand" "")]
21430 UNSPECV_LWPVAL_INTRINSIC)]
21432 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21433 [(set_attr "type" "lwp")
21434 (set_attr "mode" "HI")])
21436 (define_insn "lwp_lwpvalsi3"
21437 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21438 (match_operand:SI 1 "nonimmediate_operand" "rm")
21439 (match_operand:SI 2 "const_int_operand" "")]
21440 UNSPECV_LWPVAL_INTRINSIC)]
21442 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21443 [(set_attr "type" "lwp")
21444 (set_attr "mode" "SI")])
21446 (define_insn "lwp_lwpvaldi3"
21447 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21448 (match_operand:SI 1 "nonimmediate_operand" "rm")
21449 (match_operand:SI 2 "const_int_operand" "")]
21450 UNSPECV_LWPVAL_INTRINSIC)]
21452 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21453 [(set_attr "type" "lwp")
21454 (set_attr "mode" "DI")])
21456 (define_insn "lwp_lwpinshi3"
21457 [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21458 (match_operand:SI 1 "nonimmediate_operand" "rm")
21459 (match_operand:HI 2 "const_int_operand" "")]
21460 UNSPECV_LWPINS_INTRINSIC)]
21462 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21463 [(set_attr "type" "lwp")
21464 (set_attr "mode" "HI")])
21466 (define_insn "lwp_lwpinssi3"
21467 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21468 (match_operand:SI 1 "nonimmediate_operand" "rm")
21469 (match_operand:SI 2 "const_int_operand" "")]
21470 UNSPECV_LWPINS_INTRINSIC)]
21472 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21473 [(set_attr "type" "lwp")
21474 (set_attr "mode" "SI")])
21476 (define_insn "lwp_lwpinsdi3"
21477 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21478 (match_operand:SI 1 "nonimmediate_operand" "rm")
21479 (match_operand:SI 2 "const_int_operand" "")]
21480 UNSPECV_LWPINS_INTRINSIC)]
21482 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21483 [(set_attr "type" "lwp")
21484 (set_attr "mode" "DI")])
21488 (include "sync.md")