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")])
700 ;; Mark commutative operators as such in constraints.
701 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
702 (minus "") (ss_minus "") (us_minus "")])
704 ;; Mapping of signed max and min
705 (define_code_iterator smaxmin [smax smin])
707 ;; Mapping of unsigned max and min
708 (define_code_iterator umaxmin [umax umin])
710 ;; Mapping of signed/unsigned max and min
711 (define_code_iterator maxmin [smax smin umax umin])
713 ;; Base name for integer and FP insn mnemonic
714 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
715 (umax "maxu") (umin "minu")])
716 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
718 ;; Mapping of parallel logic operators
719 (define_code_iterator plogic [and ior xor])
721 ;; Base name for insn mnemonic.
722 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
724 ;; Mapping of abs neg operators
725 (define_code_iterator absneg [abs neg])
727 ;; Base name for x87 insn mnemonic.
728 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
730 ;; Used in signed and unsigned widening multiplications.
731 (define_code_iterator any_extend [sign_extend zero_extend])
733 ;; Used in signed and unsigned divisions.
734 (define_code_iterator any_div [div udiv])
736 ;; Various insn prefixes for signed and unsigned operations.
737 (define_code_attr u [(sign_extend "") (zero_extend "u")
738 (div "") (udiv "u")])
739 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
741 ;; Instruction prefix for signed and unsigned operations.
742 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
743 (div "i") (udiv "")])
745 ;; All single word integer modes.
746 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
748 ;; Single word integer modes without QImode.
749 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
751 ;; Single word integer modes without QImode and HImode.
752 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
754 ;; All math-dependant single and double word integer modes.
755 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
756 (HI "TARGET_HIMODE_MATH")
757 SI DI (TI "TARGET_64BIT")])
759 ;; Math-dependant single word integer modes.
760 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
761 (HI "TARGET_HIMODE_MATH")
762 SI (DI "TARGET_64BIT")])
764 ;; Math-dependant single word integer modes without QImode.
765 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
766 SI (DI "TARGET_64BIT")])
768 ;; Half mode for double word integer modes.
769 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
770 (DI "TARGET_64BIT")])
772 ;; Double word integer modes.
773 (define_mode_attr DWI [(SI "DI") (DI "TI")])
774 (define_mode_attr dwi [(SI "di") (DI "ti")])
776 ;; Instruction suffix for integer modes.
777 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
779 ;; Register class for integer modes.
780 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
782 ;; Immediate operand constraint for integer modes.
783 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
785 ;; General operand constraint for word modes.
786 (define_mode_attr g [(SI "g") (DI "rme")])
788 ;; Immediate operand constraint for double integer modes.
789 (define_mode_attr di [(SI "iF") (DI "e")])
791 ;; General operand predicate for integer modes.
792 (define_mode_attr general_operand
793 [(QI "general_operand")
794 (HI "general_operand")
795 (SI "general_operand")
796 (DI "x86_64_general_operand")
797 (TI "x86_64_general_operand")])
799 ;; SSE and x87 SFmode and DFmode floating point modes
800 (define_mode_iterator MODEF [SF DF])
802 ;; All x87 floating point modes
803 (define_mode_iterator X87MODEF [SF DF XF])
805 ;; All integer modes handled by x87 fisttp operator.
806 (define_mode_iterator X87MODEI [HI SI DI])
808 ;; All integer modes handled by integer x87 operators.
809 (define_mode_iterator X87MODEI12 [HI SI])
811 ;; All integer modes handled by SSE cvtts?2si* operators.
812 (define_mode_iterator SSEMODEI24 [SI DI])
814 ;; SSE asm suffix for floating point modes
815 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
817 ;; SSE vector mode corresponding to a scalar mode
818 (define_mode_attr ssevecmode
819 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
821 ;; Instruction suffix for REX 64bit operators.
822 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
824 ;; This mode iterator allows :P to be used for patterns that operate on
825 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
826 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
828 ;; Scheduling descriptions
830 (include "pentium.md")
833 (include "athlon.md")
838 ;; Operand and operator predicates and constraints
840 (include "predicates.md")
841 (include "constraints.md")
844 ;; Compare and branch/compare and store instructions.
846 (define_expand "cbranch<mode>4"
847 [(set (reg:CC FLAGS_REG)
848 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
849 (match_operand:SDWIM 2 "<general_operand>" "")))
850 (set (pc) (if_then_else
851 (match_operator 0 "comparison_operator"
852 [(reg:CC FLAGS_REG) (const_int 0)])
853 (label_ref (match_operand 3 "" ""))
857 if (MEM_P (operands[1]) && MEM_P (operands[2]))
858 operands[1] = force_reg (<MODE>mode, operands[1]);
859 ix86_compare_op0 = operands[1];
860 ix86_compare_op1 = operands[2];
861 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
865 (define_expand "cstore<mode>4"
866 [(set (reg:CC FLAGS_REG)
867 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
868 (match_operand:SWIM 3 "<general_operand>" "")))
869 (set (match_operand:QI 0 "register_operand" "")
870 (match_operator 1 "comparison_operator"
871 [(reg:CC FLAGS_REG) (const_int 0)]))]
874 if (MEM_P (operands[2]) && MEM_P (operands[3]))
875 operands[2] = force_reg (<MODE>mode, operands[2]);
876 ix86_compare_op0 = operands[2];
877 ix86_compare_op1 = operands[3];
878 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
882 (define_expand "cmp<mode>_1"
883 [(set (reg:CC FLAGS_REG)
884 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
885 (match_operand:SWI48 1 "<general_operand>" "")))]
889 (define_insn "*cmp<mode>_ccno_1"
890 [(set (reg FLAGS_REG)
891 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
892 (match_operand:SWI 1 "const0_operand" "")))]
893 "ix86_match_ccmode (insn, CCNOmode)"
895 test{<imodesuffix>}\t%0, %0
896 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
897 [(set_attr "type" "test,icmp")
898 (set_attr "length_immediate" "0,1")
899 (set_attr "mode" "<MODE>")])
901 (define_insn "*cmp<mode>_1"
902 [(set (reg FLAGS_REG)
903 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
904 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
905 "ix86_match_ccmode (insn, CCmode)"
906 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
907 [(set_attr "type" "icmp")
908 (set_attr "mode" "<MODE>")])
910 (define_insn "*cmp<mode>_minus_1"
911 [(set (reg FLAGS_REG)
913 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
914 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
916 "ix86_match_ccmode (insn, CCGOCmode)"
917 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
918 [(set_attr "type" "icmp")
919 (set_attr "mode" "<MODE>")])
921 (define_insn "*cmpqi_ext_1"
922 [(set (reg FLAGS_REG)
924 (match_operand:QI 0 "general_operand" "Qm")
927 (match_operand 1 "ext_register_operand" "Q")
930 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
931 "cmp{b}\t{%h1, %0|%0, %h1}"
932 [(set_attr "type" "icmp")
933 (set_attr "mode" "QI")])
935 (define_insn "*cmpqi_ext_1_rex64"
936 [(set (reg FLAGS_REG)
938 (match_operand:QI 0 "register_operand" "Q")
941 (match_operand 1 "ext_register_operand" "Q")
944 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
945 "cmp{b}\t{%h1, %0|%0, %h1}"
946 [(set_attr "type" "icmp")
947 (set_attr "mode" "QI")])
949 (define_insn "*cmpqi_ext_2"
950 [(set (reg FLAGS_REG)
954 (match_operand 0 "ext_register_operand" "Q")
957 (match_operand:QI 1 "const0_operand" "")))]
958 "ix86_match_ccmode (insn, CCNOmode)"
960 [(set_attr "type" "test")
961 (set_attr "length_immediate" "0")
962 (set_attr "mode" "QI")])
964 (define_expand "cmpqi_ext_3"
965 [(set (reg:CC FLAGS_REG)
969 (match_operand 0 "ext_register_operand" "")
972 (match_operand:QI 1 "immediate_operand" "")))]
976 (define_insn "*cmpqi_ext_3_insn"
977 [(set (reg FLAGS_REG)
981 (match_operand 0 "ext_register_operand" "Q")
984 (match_operand:QI 1 "general_operand" "Qmn")))]
985 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
986 "cmp{b}\t{%1, %h0|%h0, %1}"
987 [(set_attr "type" "icmp")
988 (set_attr "modrm" "1")
989 (set_attr "mode" "QI")])
991 (define_insn "*cmpqi_ext_3_insn_rex64"
992 [(set (reg FLAGS_REG)
996 (match_operand 0 "ext_register_operand" "Q")
999 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1000 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001 "cmp{b}\t{%1, %h0|%h0, %1}"
1002 [(set_attr "type" "icmp")
1003 (set_attr "modrm" "1")
1004 (set_attr "mode" "QI")])
1006 (define_insn "*cmpqi_ext_4"
1007 [(set (reg FLAGS_REG)
1011 (match_operand 0 "ext_register_operand" "Q")
1016 (match_operand 1 "ext_register_operand" "Q")
1018 (const_int 8)) 0)))]
1019 "ix86_match_ccmode (insn, CCmode)"
1020 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1021 [(set_attr "type" "icmp")
1022 (set_attr "mode" "QI")])
1024 ;; These implement float point compares.
1025 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1026 ;; which would allow mix and match FP modes on the compares. Which is what
1027 ;; the old patterns did, but with many more of them.
1029 (define_expand "cbranchxf4"
1030 [(set (reg:CC FLAGS_REG)
1031 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1032 (match_operand:XF 2 "nonmemory_operand" "")))
1033 (set (pc) (if_then_else
1034 (match_operator 0 "ix86_fp_comparison_operator"
1037 (label_ref (match_operand 3 "" ""))
1041 ix86_compare_op0 = operands[1];
1042 ix86_compare_op1 = operands[2];
1043 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1047 (define_expand "cstorexf4"
1048 [(set (reg:CC FLAGS_REG)
1049 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1050 (match_operand:XF 3 "nonmemory_operand" "")))
1051 (set (match_operand:QI 0 "register_operand" "")
1052 (match_operator 1 "ix86_fp_comparison_operator"
1057 ix86_compare_op0 = operands[2];
1058 ix86_compare_op1 = operands[3];
1059 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1063 (define_expand "cbranch<mode>4"
1064 [(set (reg:CC FLAGS_REG)
1065 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1066 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1067 (set (pc) (if_then_else
1068 (match_operator 0 "ix86_fp_comparison_operator"
1071 (label_ref (match_operand 3 "" ""))
1073 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1075 ix86_compare_op0 = operands[1];
1076 ix86_compare_op1 = operands[2];
1077 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1081 (define_expand "cstore<mode>4"
1082 [(set (reg:CC FLAGS_REG)
1083 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1084 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1085 (set (match_operand:QI 0 "register_operand" "")
1086 (match_operator 1 "ix86_fp_comparison_operator"
1089 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1091 ix86_compare_op0 = operands[2];
1092 ix86_compare_op1 = operands[3];
1093 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1097 (define_expand "cbranchcc4"
1098 [(set (pc) (if_then_else
1099 (match_operator 0 "comparison_operator"
1100 [(match_operand 1 "flags_reg_operand" "")
1101 (match_operand 2 "const0_operand" "")])
1102 (label_ref (match_operand 3 "" ""))
1106 ix86_compare_op0 = operands[1];
1107 ix86_compare_op1 = operands[2];
1108 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1112 (define_expand "cstorecc4"
1113 [(set (match_operand:QI 0 "register_operand" "")
1114 (match_operator 1 "comparison_operator"
1115 [(match_operand 2 "flags_reg_operand" "")
1116 (match_operand 3 "const0_operand" "")]))]
1119 ix86_compare_op0 = operands[2];
1120 ix86_compare_op1 = operands[3];
1121 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1126 ;; FP compares, step 1:
1127 ;; Set the FP condition codes.
1129 ;; CCFPmode compare with exceptions
1130 ;; CCFPUmode compare with no exceptions
1132 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1133 ;; used to manage the reg stack popping would not be preserved.
1135 (define_insn "*cmpfp_0"
1136 [(set (match_operand:HI 0 "register_operand" "=a")
1139 (match_operand 1 "register_operand" "f")
1140 (match_operand 2 "const0_operand" ""))]
1142 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1143 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1144 "* return output_fp_compare (insn, operands, 0, 0);"
1145 [(set_attr "type" "multi")
1146 (set_attr "unit" "i387")
1148 (cond [(match_operand:SF 1 "" "")
1150 (match_operand:DF 1 "" "")
1153 (const_string "XF")))])
1155 (define_insn_and_split "*cmpfp_0_cc"
1156 [(set (reg:CCFP FLAGS_REG)
1158 (match_operand 1 "register_operand" "f")
1159 (match_operand 2 "const0_operand" "")))
1160 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1161 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1162 && TARGET_SAHF && !TARGET_CMOVE
1163 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1165 "&& reload_completed"
1168 [(compare:CCFP (match_dup 1)(match_dup 2))]
1170 (set (reg:CC FLAGS_REG)
1171 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1173 [(set_attr "type" "multi")
1174 (set_attr "unit" "i387")
1176 (cond [(match_operand:SF 1 "" "")
1178 (match_operand:DF 1 "" "")
1181 (const_string "XF")))])
1183 (define_insn "*cmpfp_xf"
1184 [(set (match_operand:HI 0 "register_operand" "=a")
1187 (match_operand:XF 1 "register_operand" "f")
1188 (match_operand:XF 2 "register_operand" "f"))]
1191 "* return output_fp_compare (insn, operands, 0, 0);"
1192 [(set_attr "type" "multi")
1193 (set_attr "unit" "i387")
1194 (set_attr "mode" "XF")])
1196 (define_insn_and_split "*cmpfp_xf_cc"
1197 [(set (reg:CCFP FLAGS_REG)
1199 (match_operand:XF 1 "register_operand" "f")
1200 (match_operand:XF 2 "register_operand" "f")))
1201 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1203 && TARGET_SAHF && !TARGET_CMOVE"
1205 "&& reload_completed"
1208 [(compare:CCFP (match_dup 1)(match_dup 2))]
1210 (set (reg:CC FLAGS_REG)
1211 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1213 [(set_attr "type" "multi")
1214 (set_attr "unit" "i387")
1215 (set_attr "mode" "XF")])
1217 (define_insn "*cmpfp_<mode>"
1218 [(set (match_operand:HI 0 "register_operand" "=a")
1221 (match_operand:MODEF 1 "register_operand" "f")
1222 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1225 "* return output_fp_compare (insn, operands, 0, 0);"
1226 [(set_attr "type" "multi")
1227 (set_attr "unit" "i387")
1228 (set_attr "mode" "<MODE>")])
1230 (define_insn_and_split "*cmpfp_<mode>_cc"
1231 [(set (reg:CCFP FLAGS_REG)
1233 (match_operand:MODEF 1 "register_operand" "f")
1234 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1235 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1237 && TARGET_SAHF && !TARGET_CMOVE"
1239 "&& reload_completed"
1242 [(compare:CCFP (match_dup 1)(match_dup 2))]
1244 (set (reg:CC FLAGS_REG)
1245 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1247 [(set_attr "type" "multi")
1248 (set_attr "unit" "i387")
1249 (set_attr "mode" "<MODE>")])
1251 (define_insn "*cmpfp_u"
1252 [(set (match_operand:HI 0 "register_operand" "=a")
1255 (match_operand 1 "register_operand" "f")
1256 (match_operand 2 "register_operand" "f"))]
1258 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1259 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1260 "* return output_fp_compare (insn, operands, 0, 1);"
1261 [(set_attr "type" "multi")
1262 (set_attr "unit" "i387")
1264 (cond [(match_operand:SF 1 "" "")
1266 (match_operand:DF 1 "" "")
1269 (const_string "XF")))])
1271 (define_insn_and_split "*cmpfp_u_cc"
1272 [(set (reg:CCFPU FLAGS_REG)
1274 (match_operand 1 "register_operand" "f")
1275 (match_operand 2 "register_operand" "f")))
1276 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1277 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1278 && TARGET_SAHF && !TARGET_CMOVE
1279 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1281 "&& reload_completed"
1284 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1286 (set (reg:CC FLAGS_REG)
1287 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1289 [(set_attr "type" "multi")
1290 (set_attr "unit" "i387")
1292 (cond [(match_operand:SF 1 "" "")
1294 (match_operand:DF 1 "" "")
1297 (const_string "XF")))])
1299 (define_insn "*cmpfp_<mode>"
1300 [(set (match_operand:HI 0 "register_operand" "=a")
1303 (match_operand 1 "register_operand" "f")
1304 (match_operator 3 "float_operator"
1305 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1307 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1308 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1309 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1310 "* return output_fp_compare (insn, operands, 0, 0);"
1311 [(set_attr "type" "multi")
1312 (set_attr "unit" "i387")
1313 (set_attr "fp_int_src" "true")
1314 (set_attr "mode" "<MODE>")])
1316 (define_insn_and_split "*cmpfp_<mode>_cc"
1317 [(set (reg:CCFP FLAGS_REG)
1319 (match_operand 1 "register_operand" "f")
1320 (match_operator 3 "float_operator"
1321 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1322 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1323 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1324 && TARGET_SAHF && !TARGET_CMOVE
1325 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1326 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1328 "&& reload_completed"
1333 (match_op_dup 3 [(match_dup 2)]))]
1335 (set (reg:CC FLAGS_REG)
1336 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1338 [(set_attr "type" "multi")
1339 (set_attr "unit" "i387")
1340 (set_attr "fp_int_src" "true")
1341 (set_attr "mode" "<MODE>")])
1343 ;; FP compares, step 2
1344 ;; Move the fpsw to ax.
1346 (define_insn "x86_fnstsw_1"
1347 [(set (match_operand:HI 0 "register_operand" "=a")
1348 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1351 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1352 (set_attr "mode" "SI")
1353 (set_attr "unit" "i387")])
1355 ;; FP compares, step 3
1356 ;; Get ax into flags, general case.
1358 (define_insn "x86_sahf_1"
1359 [(set (reg:CC FLAGS_REG)
1360 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1364 #ifdef HAVE_AS_IX86_SAHF
1367 return ASM_BYTE "0x9e";
1370 [(set_attr "length" "1")
1371 (set_attr "athlon_decode" "vector")
1372 (set_attr "amdfam10_decode" "direct")
1373 (set_attr "mode" "SI")])
1375 ;; Pentium Pro can do steps 1 through 3 in one go.
1376 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1377 (define_insn "*cmpfp_i_mixed"
1378 [(set (reg:CCFP FLAGS_REG)
1379 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1380 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1381 "TARGET_MIX_SSE_I387
1382 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1383 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1384 "* return output_fp_compare (insn, operands, 1, 0);"
1385 [(set_attr "type" "fcmp,ssecomi")
1386 (set_attr "prefix" "orig,maybe_vex")
1388 (if_then_else (match_operand:SF 1 "" "")
1390 (const_string "DF")))
1391 (set (attr "prefix_rep")
1392 (if_then_else (eq_attr "type" "ssecomi")
1394 (const_string "*")))
1395 (set (attr "prefix_data16")
1396 (cond [(eq_attr "type" "fcmp")
1398 (eq_attr "mode" "DF")
1401 (const_string "0")))
1402 (set_attr "athlon_decode" "vector")
1403 (set_attr "amdfam10_decode" "direct")])
1405 (define_insn "*cmpfp_i_sse"
1406 [(set (reg:CCFP FLAGS_REG)
1407 (compare:CCFP (match_operand 0 "register_operand" "x")
1408 (match_operand 1 "nonimmediate_operand" "xm")))]
1410 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1411 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1412 "* return output_fp_compare (insn, operands, 1, 0);"
1413 [(set_attr "type" "ssecomi")
1414 (set_attr "prefix" "maybe_vex")
1416 (if_then_else (match_operand:SF 1 "" "")
1418 (const_string "DF")))
1419 (set_attr "prefix_rep" "0")
1420 (set (attr "prefix_data16")
1421 (if_then_else (eq_attr "mode" "DF")
1423 (const_string "0")))
1424 (set_attr "athlon_decode" "vector")
1425 (set_attr "amdfam10_decode" "direct")])
1427 (define_insn "*cmpfp_i_i387"
1428 [(set (reg:CCFP FLAGS_REG)
1429 (compare:CCFP (match_operand 0 "register_operand" "f")
1430 (match_operand 1 "register_operand" "f")))]
1431 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1433 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1434 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1435 "* return output_fp_compare (insn, operands, 1, 0);"
1436 [(set_attr "type" "fcmp")
1438 (cond [(match_operand:SF 1 "" "")
1440 (match_operand:DF 1 "" "")
1443 (const_string "XF")))
1444 (set_attr "athlon_decode" "vector")
1445 (set_attr "amdfam10_decode" "direct")])
1447 (define_insn "*cmpfp_iu_mixed"
1448 [(set (reg:CCFPU FLAGS_REG)
1449 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1450 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1451 "TARGET_MIX_SSE_I387
1452 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1453 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1454 "* return output_fp_compare (insn, operands, 1, 1);"
1455 [(set_attr "type" "fcmp,ssecomi")
1456 (set_attr "prefix" "orig,maybe_vex")
1458 (if_then_else (match_operand:SF 1 "" "")
1460 (const_string "DF")))
1461 (set (attr "prefix_rep")
1462 (if_then_else (eq_attr "type" "ssecomi")
1464 (const_string "*")))
1465 (set (attr "prefix_data16")
1466 (cond [(eq_attr "type" "fcmp")
1468 (eq_attr "mode" "DF")
1471 (const_string "0")))
1472 (set_attr "athlon_decode" "vector")
1473 (set_attr "amdfam10_decode" "direct")])
1475 (define_insn "*cmpfp_iu_sse"
1476 [(set (reg:CCFPU FLAGS_REG)
1477 (compare:CCFPU (match_operand 0 "register_operand" "x")
1478 (match_operand 1 "nonimmediate_operand" "xm")))]
1480 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1481 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1482 "* return output_fp_compare (insn, operands, 1, 1);"
1483 [(set_attr "type" "ssecomi")
1484 (set_attr "prefix" "maybe_vex")
1486 (if_then_else (match_operand:SF 1 "" "")
1488 (const_string "DF")))
1489 (set_attr "prefix_rep" "0")
1490 (set (attr "prefix_data16")
1491 (if_then_else (eq_attr "mode" "DF")
1493 (const_string "0")))
1494 (set_attr "athlon_decode" "vector")
1495 (set_attr "amdfam10_decode" "direct")])
1497 (define_insn "*cmpfp_iu_387"
1498 [(set (reg:CCFPU FLAGS_REG)
1499 (compare:CCFPU (match_operand 0 "register_operand" "f")
1500 (match_operand 1 "register_operand" "f")))]
1501 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1503 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1504 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1505 "* return output_fp_compare (insn, operands, 1, 1);"
1506 [(set_attr "type" "fcmp")
1508 (cond [(match_operand:SF 1 "" "")
1510 (match_operand:DF 1 "" "")
1513 (const_string "XF")))
1514 (set_attr "athlon_decode" "vector")
1515 (set_attr "amdfam10_decode" "direct")])
1517 ;; Move instructions.
1519 ;; General case of fullword move.
1521 (define_expand "movsi"
1522 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1523 (match_operand:SI 1 "general_operand" ""))]
1525 "ix86_expand_move (SImode, operands); DONE;")
1527 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1530 ;; %%% We don't use a post-inc memory reference because x86 is not a
1531 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1532 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1533 ;; targets without our curiosities, and it is just as easy to represent
1534 ;; this differently.
1536 (define_insn "*pushsi2"
1537 [(set (match_operand:SI 0 "push_operand" "=<")
1538 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1541 [(set_attr "type" "push")
1542 (set_attr "mode" "SI")])
1544 ;; For 64BIT abi we always round up to 8 bytes.
1545 (define_insn "*pushsi2_rex64"
1546 [(set (match_operand:SI 0 "push_operand" "=X")
1547 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1550 [(set_attr "type" "push")
1551 (set_attr "mode" "SI")])
1553 (define_insn "*pushsi2_prologue"
1554 [(set (match_operand:SI 0 "push_operand" "=<")
1555 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1556 (clobber (mem:BLK (scratch)))]
1559 [(set_attr "type" "push")
1560 (set_attr "mode" "SI")])
1562 (define_insn "*popsi1_epilogue"
1563 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1564 (mem:SI (reg:SI SP_REG)))
1565 (set (reg:SI SP_REG)
1566 (plus:SI (reg:SI SP_REG) (const_int 4)))
1567 (clobber (mem:BLK (scratch)))]
1570 [(set_attr "type" "pop")
1571 (set_attr "mode" "SI")])
1573 (define_insn "popsi1"
1574 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1575 (mem:SI (reg:SI SP_REG)))
1576 (set (reg:SI SP_REG)
1577 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1580 [(set_attr "type" "pop")
1581 (set_attr "mode" "SI")])
1583 (define_insn "*movsi_xor"
1584 [(set (match_operand:SI 0 "register_operand" "=r")
1585 (match_operand:SI 1 "const0_operand" ""))
1586 (clobber (reg:CC FLAGS_REG))]
1589 [(set_attr "type" "alu1")
1590 (set_attr "mode" "SI")
1591 (set_attr "length_immediate" "0")])
1593 (define_insn "*movsi_or"
1594 [(set (match_operand:SI 0 "register_operand" "=r")
1595 (match_operand:SI 1 "immediate_operand" "i"))
1596 (clobber (reg:CC FLAGS_REG))]
1598 && operands[1] == constm1_rtx"
1600 operands[1] = constm1_rtx;
1601 return "or{l}\t{%1, %0|%0, %1}";
1603 [(set_attr "type" "alu1")
1604 (set_attr "mode" "SI")
1605 (set_attr "length_immediate" "1")])
1607 (define_insn "*movsi_1"
1608 [(set (match_operand:SI 0 "nonimmediate_operand"
1609 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1610 (match_operand:SI 1 "general_operand"
1611 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1612 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1614 switch (get_attr_type (insn))
1617 if (get_attr_mode (insn) == MODE_TI)
1618 return "%vpxor\t%0, %d0";
1619 return "%vxorps\t%0, %d0";
1622 switch (get_attr_mode (insn))
1625 return "%vmovdqa\t{%1, %0|%0, %1}";
1627 return "%vmovaps\t{%1, %0|%0, %1}";
1629 return "%vmovd\t{%1, %0|%0, %1}";
1631 return "%vmovss\t{%1, %0|%0, %1}";
1637 return "pxor\t%0, %0";
1640 if (get_attr_mode (insn) == MODE_DI)
1641 return "movq\t{%1, %0|%0, %1}";
1642 return "movd\t{%1, %0|%0, %1}";
1645 return "lea{l}\t{%1, %0|%0, %1}";
1648 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1649 return "mov{l}\t{%1, %0|%0, %1}";
1653 (cond [(eq_attr "alternative" "2")
1654 (const_string "mmx")
1655 (eq_attr "alternative" "3,4,5")
1656 (const_string "mmxmov")
1657 (eq_attr "alternative" "6")
1658 (const_string "sselog1")
1659 (eq_attr "alternative" "7,8,9,10,11")
1660 (const_string "ssemov")
1661 (match_operand:DI 1 "pic_32bit_operand" "")
1662 (const_string "lea")
1664 (const_string "imov")))
1665 (set (attr "prefix")
1666 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1667 (const_string "orig")
1668 (const_string "maybe_vex")))
1669 (set (attr "prefix_data16")
1670 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1672 (const_string "*")))
1674 (cond [(eq_attr "alternative" "2,3")
1676 (eq_attr "alternative" "6,7")
1678 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1679 (const_string "V4SF")
1680 (const_string "TI"))
1681 (and (eq_attr "alternative" "8,9,10,11")
1682 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1685 (const_string "SI")))])
1687 ;; Stores and loads of ax to arbitrary constant address.
1688 ;; We fake an second form of instruction to force reload to load address
1689 ;; into register when rax is not available
1690 (define_insn "*movabssi_1_rex64"
1691 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1692 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1693 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1695 movabs{l}\t{%1, %P0|%P0, %1}
1696 mov{l}\t{%1, %a0|%a0, %1}"
1697 [(set_attr "type" "imov")
1698 (set_attr "modrm" "0,*")
1699 (set_attr "length_address" "8,0")
1700 (set_attr "length_immediate" "0,*")
1701 (set_attr "memory" "store")
1702 (set_attr "mode" "SI")])
1704 (define_insn "*movabssi_2_rex64"
1705 [(set (match_operand:SI 0 "register_operand" "=a,r")
1706 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1707 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1709 movabs{l}\t{%P1, %0|%0, %P1}
1710 mov{l}\t{%a1, %0|%0, %a1}"
1711 [(set_attr "type" "imov")
1712 (set_attr "modrm" "0,*")
1713 (set_attr "length_address" "8,0")
1714 (set_attr "length_immediate" "0")
1715 (set_attr "memory" "load")
1716 (set_attr "mode" "SI")])
1718 (define_insn "*swapsi"
1719 [(set (match_operand:SI 0 "register_operand" "+r")
1720 (match_operand:SI 1 "register_operand" "+r"))
1725 [(set_attr "type" "imov")
1726 (set_attr "mode" "SI")
1727 (set_attr "pent_pair" "np")
1728 (set_attr "athlon_decode" "vector")
1729 (set_attr "amdfam10_decode" "double")])
1731 (define_expand "movhi"
1732 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1733 (match_operand:HI 1 "general_operand" ""))]
1735 "ix86_expand_move (HImode, operands); DONE;")
1737 (define_insn "*pushhi2"
1738 [(set (match_operand:HI 0 "push_operand" "=X")
1739 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1742 [(set_attr "type" "push")
1743 (set_attr "mode" "SI")])
1745 ;; For 64BIT abi we always round up to 8 bytes.
1746 (define_insn "*pushhi2_rex64"
1747 [(set (match_operand:HI 0 "push_operand" "=X")
1748 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1751 [(set_attr "type" "push")
1752 (set_attr "mode" "DI")])
1754 (define_insn "*movhi_1"
1755 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1756 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1757 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1759 switch (get_attr_type (insn))
1762 /* movzwl is faster than movw on p2 due to partial word stalls,
1763 though not as fast as an aligned movl. */
1764 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1766 if (get_attr_mode (insn) == MODE_SI)
1767 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1769 return "mov{w}\t{%1, %0|%0, %1}";
1773 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1774 (const_string "imov")
1775 (and (eq_attr "alternative" "0")
1776 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1778 (eq (symbol_ref "TARGET_HIMODE_MATH")
1780 (const_string "imov")
1781 (and (eq_attr "alternative" "1,2")
1782 (match_operand:HI 1 "aligned_operand" ""))
1783 (const_string "imov")
1784 (and (ne (symbol_ref "TARGET_MOVX")
1786 (eq_attr "alternative" "0,2"))
1787 (const_string "imovx")
1789 (const_string "imov")))
1791 (cond [(eq_attr "type" "imovx")
1793 (and (eq_attr "alternative" "1,2")
1794 (match_operand:HI 1 "aligned_operand" ""))
1796 (and (eq_attr "alternative" "0")
1797 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1799 (eq (symbol_ref "TARGET_HIMODE_MATH")
1803 (const_string "HI")))])
1805 ;; Stores and loads of ax to arbitrary constant address.
1806 ;; We fake an second form of instruction to force reload to load address
1807 ;; into register when rax is not available
1808 (define_insn "*movabshi_1_rex64"
1809 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1810 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1811 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1813 movabs{w}\t{%1, %P0|%P0, %1}
1814 mov{w}\t{%1, %a0|%a0, %1}"
1815 [(set_attr "type" "imov")
1816 (set_attr "modrm" "0,*")
1817 (set_attr "length_address" "8,0")
1818 (set_attr "length_immediate" "0,*")
1819 (set_attr "memory" "store")
1820 (set_attr "mode" "HI")])
1822 (define_insn "*movabshi_2_rex64"
1823 [(set (match_operand:HI 0 "register_operand" "=a,r")
1824 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1825 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1827 movabs{w}\t{%P1, %0|%0, %P1}
1828 mov{w}\t{%a1, %0|%0, %a1}"
1829 [(set_attr "type" "imov")
1830 (set_attr "modrm" "0,*")
1831 (set_attr "length_address" "8,0")
1832 (set_attr "length_immediate" "0")
1833 (set_attr "memory" "load")
1834 (set_attr "mode" "HI")])
1836 (define_insn "*swaphi_1"
1837 [(set (match_operand:HI 0 "register_operand" "+r")
1838 (match_operand:HI 1 "register_operand" "+r"))
1841 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1843 [(set_attr "type" "imov")
1844 (set_attr "mode" "SI")
1845 (set_attr "pent_pair" "np")
1846 (set_attr "athlon_decode" "vector")
1847 (set_attr "amdfam10_decode" "double")])
1849 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1850 (define_insn "*swaphi_2"
1851 [(set (match_operand:HI 0 "register_operand" "+r")
1852 (match_operand:HI 1 "register_operand" "+r"))
1855 "TARGET_PARTIAL_REG_STALL"
1857 [(set_attr "type" "imov")
1858 (set_attr "mode" "HI")
1859 (set_attr "pent_pair" "np")
1860 (set_attr "athlon_decode" "vector")])
1862 (define_expand "movstricthi"
1863 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1864 (match_operand:HI 1 "general_operand" ""))]
1867 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1869 /* Don't generate memory->memory moves, go through a register */
1870 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1871 operands[1] = force_reg (HImode, operands[1]);
1874 (define_insn "*movstricthi_1"
1875 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1876 (match_operand:HI 1 "general_operand" "rn,m"))]
1877 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1878 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1879 "mov{w}\t{%1, %0|%0, %1}"
1880 [(set_attr "type" "imov")
1881 (set_attr "mode" "HI")])
1883 (define_insn "*movstricthi_xor"
1884 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1885 (match_operand:HI 1 "const0_operand" ""))
1886 (clobber (reg:CC FLAGS_REG))]
1889 [(set_attr "type" "alu1")
1890 (set_attr "mode" "HI")
1891 (set_attr "length_immediate" "0")])
1893 (define_expand "movqi"
1894 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1895 (match_operand:QI 1 "general_operand" ""))]
1897 "ix86_expand_move (QImode, operands); DONE;")
1899 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1900 ;; "push a byte". But actually we use pushl, which has the effect
1901 ;; of rounding the amount pushed up to a word.
1903 (define_insn "*pushqi2"
1904 [(set (match_operand:QI 0 "push_operand" "=X")
1905 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1908 [(set_attr "type" "push")
1909 (set_attr "mode" "SI")])
1911 ;; For 64BIT abi we always round up to 8 bytes.
1912 (define_insn "*pushqi2_rex64"
1913 [(set (match_operand:QI 0 "push_operand" "=X")
1914 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1917 [(set_attr "type" "push")
1918 (set_attr "mode" "DI")])
1920 ;; Situation is quite tricky about when to choose full sized (SImode) move
1921 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1922 ;; partial register dependency machines (such as AMD Athlon), where QImode
1923 ;; moves issue extra dependency and for partial register stalls machines
1924 ;; that don't use QImode patterns (and QImode move cause stall on the next
1927 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1928 ;; register stall machines with, where we use QImode instructions, since
1929 ;; partial register stall can be caused there. Then we use movzx.
1930 (define_insn "*movqi_1"
1931 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1932 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1933 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1935 switch (get_attr_type (insn))
1938 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1939 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1941 if (get_attr_mode (insn) == MODE_SI)
1942 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1944 return "mov{b}\t{%1, %0|%0, %1}";
1948 (cond [(and (eq_attr "alternative" "5")
1949 (not (match_operand:QI 1 "aligned_operand" "")))
1950 (const_string "imovx")
1951 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1952 (const_string "imov")
1953 (and (eq_attr "alternative" "3")
1954 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1956 (eq (symbol_ref "TARGET_QIMODE_MATH")
1958 (const_string "imov")
1959 (eq_attr "alternative" "3,5")
1960 (const_string "imovx")
1961 (and (ne (symbol_ref "TARGET_MOVX")
1963 (eq_attr "alternative" "2"))
1964 (const_string "imovx")
1966 (const_string "imov")))
1968 (cond [(eq_attr "alternative" "3,4,5")
1970 (eq_attr "alternative" "6")
1972 (eq_attr "type" "imovx")
1974 (and (eq_attr "type" "imov")
1975 (and (eq_attr "alternative" "0,1")
1976 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1978 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1980 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1983 ;; Avoid partial register stalls when not using QImode arithmetic
1984 (and (eq_attr "type" "imov")
1985 (and (eq_attr "alternative" "0,1")
1986 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1988 (eq (symbol_ref "TARGET_QIMODE_MATH")
1992 (const_string "QI")))])
1994 (define_insn "*swapqi_1"
1995 [(set (match_operand:QI 0 "register_operand" "+r")
1996 (match_operand:QI 1 "register_operand" "+r"))
1999 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2001 [(set_attr "type" "imov")
2002 (set_attr "mode" "SI")
2003 (set_attr "pent_pair" "np")
2004 (set_attr "athlon_decode" "vector")
2005 (set_attr "amdfam10_decode" "vector")])
2007 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2008 (define_insn "*swapqi_2"
2009 [(set (match_operand:QI 0 "register_operand" "+q")
2010 (match_operand:QI 1 "register_operand" "+q"))
2013 "TARGET_PARTIAL_REG_STALL"
2015 [(set_attr "type" "imov")
2016 (set_attr "mode" "QI")
2017 (set_attr "pent_pair" "np")
2018 (set_attr "athlon_decode" "vector")])
2020 (define_expand "movstrictqi"
2021 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2022 (match_operand:QI 1 "general_operand" ""))]
2025 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2027 /* Don't generate memory->memory moves, go through a register. */
2028 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2029 operands[1] = force_reg (QImode, operands[1]);
2032 (define_insn "*movstrictqi_1"
2033 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2034 (match_operand:QI 1 "general_operand" "*qn,m"))]
2035 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2036 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2037 "mov{b}\t{%1, %0|%0, %1}"
2038 [(set_attr "type" "imov")
2039 (set_attr "mode" "QI")])
2041 (define_insn "*movstrictqi_xor"
2042 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2043 (match_operand:QI 1 "const0_operand" ""))
2044 (clobber (reg:CC FLAGS_REG))]
2047 [(set_attr "type" "alu1")
2048 (set_attr "mode" "QI")
2049 (set_attr "length_immediate" "0")])
2051 (define_insn "*movsi_extv_1"
2052 [(set (match_operand:SI 0 "register_operand" "=R")
2053 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2057 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2058 [(set_attr "type" "imovx")
2059 (set_attr "mode" "SI")])
2061 (define_insn "*movhi_extv_1"
2062 [(set (match_operand:HI 0 "register_operand" "=R")
2063 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2067 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2068 [(set_attr "type" "imovx")
2069 (set_attr "mode" "SI")])
2071 (define_insn "*movqi_extv_1"
2072 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2073 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2078 switch (get_attr_type (insn))
2081 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2083 return "mov{b}\t{%h1, %0|%0, %h1}";
2087 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2088 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2089 (ne (symbol_ref "TARGET_MOVX")
2091 (const_string "imovx")
2092 (const_string "imov")))
2094 (if_then_else (eq_attr "type" "imovx")
2096 (const_string "QI")))])
2098 (define_insn "*movqi_extv_1_rex64"
2099 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2100 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2105 switch (get_attr_type (insn))
2108 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2110 return "mov{b}\t{%h1, %0|%0, %h1}";
2114 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2115 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2116 (ne (symbol_ref "TARGET_MOVX")
2118 (const_string "imovx")
2119 (const_string "imov")))
2121 (if_then_else (eq_attr "type" "imovx")
2123 (const_string "QI")))])
2125 ;; Stores and loads of ax to arbitrary constant address.
2126 ;; We fake an second form of instruction to force reload to load address
2127 ;; into register when rax is not available
2128 (define_insn "*movabsqi_1_rex64"
2129 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2130 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2131 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2133 movabs{b}\t{%1, %P0|%P0, %1}
2134 mov{b}\t{%1, %a0|%a0, %1}"
2135 [(set_attr "type" "imov")
2136 (set_attr "modrm" "0,*")
2137 (set_attr "length_address" "8,0")
2138 (set_attr "length_immediate" "0,*")
2139 (set_attr "memory" "store")
2140 (set_attr "mode" "QI")])
2142 (define_insn "*movabsqi_2_rex64"
2143 [(set (match_operand:QI 0 "register_operand" "=a,r")
2144 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2145 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2147 movabs{b}\t{%P1, %0|%0, %P1}
2148 mov{b}\t{%a1, %0|%0, %a1}"
2149 [(set_attr "type" "imov")
2150 (set_attr "modrm" "0,*")
2151 (set_attr "length_address" "8,0")
2152 (set_attr "length_immediate" "0")
2153 (set_attr "memory" "load")
2154 (set_attr "mode" "QI")])
2156 (define_insn "*movdi_extzv_1"
2157 [(set (match_operand:DI 0 "register_operand" "=R")
2158 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2162 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2163 [(set_attr "type" "imovx")
2164 (set_attr "mode" "SI")])
2166 (define_insn "*movsi_extzv_1"
2167 [(set (match_operand:SI 0 "register_operand" "=R")
2168 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2172 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2173 [(set_attr "type" "imovx")
2174 (set_attr "mode" "SI")])
2176 (define_insn "*movqi_extzv_2"
2177 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2178 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2183 switch (get_attr_type (insn))
2186 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2188 return "mov{b}\t{%h1, %0|%0, %h1}";
2192 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2193 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2194 (ne (symbol_ref "TARGET_MOVX")
2196 (const_string "imovx")
2197 (const_string "imov")))
2199 (if_then_else (eq_attr "type" "imovx")
2201 (const_string "QI")))])
2203 (define_insn "*movqi_extzv_2_rex64"
2204 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2205 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2210 switch (get_attr_type (insn))
2213 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2215 return "mov{b}\t{%h1, %0|%0, %h1}";
2219 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2220 (ne (symbol_ref "TARGET_MOVX")
2222 (const_string "imovx")
2223 (const_string "imov")))
2225 (if_then_else (eq_attr "type" "imovx")
2227 (const_string "QI")))])
2229 (define_insn "movsi_insv_1"
2230 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2233 (match_operand:SI 1 "general_operand" "Qmn"))]
2235 "mov{b}\t{%b1, %h0|%h0, %b1}"
2236 [(set_attr "type" "imov")
2237 (set_attr "mode" "QI")])
2239 (define_insn "*movsi_insv_1_rex64"
2240 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2243 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2245 "mov{b}\t{%b1, %h0|%h0, %b1}"
2246 [(set_attr "type" "imov")
2247 (set_attr "mode" "QI")])
2249 (define_insn "movdi_insv_1_rex64"
2250 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2253 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2255 "mov{b}\t{%b1, %h0|%h0, %b1}"
2256 [(set_attr "type" "imov")
2257 (set_attr "mode" "QI")])
2259 (define_insn "*movqi_insv_2"
2260 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2263 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2266 "mov{b}\t{%h1, %h0|%h0, %h1}"
2267 [(set_attr "type" "imov")
2268 (set_attr "mode" "QI")])
2270 (define_expand "movdi"
2271 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2272 (match_operand:DI 1 "general_operand" ""))]
2274 "ix86_expand_move (DImode, operands); DONE;")
2276 (define_insn "*pushdi"
2277 [(set (match_operand:DI 0 "push_operand" "=<")
2278 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2282 (define_insn "*pushdi2_rex64"
2283 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2284 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2289 [(set_attr "type" "push,multi")
2290 (set_attr "mode" "DI")])
2292 ;; Convert impossible pushes of immediate to existing instructions.
2293 ;; First try to get scratch register and go through it. In case this
2294 ;; fails, push sign extended lower part first and then overwrite
2295 ;; upper part by 32bit move.
2297 [(match_scratch:DI 2 "r")
2298 (set (match_operand:DI 0 "push_operand" "")
2299 (match_operand:DI 1 "immediate_operand" ""))]
2300 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2301 && !x86_64_immediate_operand (operands[1], DImode)"
2302 [(set (match_dup 2) (match_dup 1))
2303 (set (match_dup 0) (match_dup 2))]
2306 ;; We need to define this as both peepholer and splitter for case
2307 ;; peephole2 pass is not run.
2308 ;; "&& 1" is needed to keep it from matching the previous pattern.
2310 [(set (match_operand:DI 0 "push_operand" "")
2311 (match_operand:DI 1 "immediate_operand" ""))]
2312 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2313 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2314 [(set (match_dup 0) (match_dup 1))
2315 (set (match_dup 2) (match_dup 3))]
2316 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2317 operands[1] = gen_lowpart (DImode, operands[2]);
2318 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2323 [(set (match_operand:DI 0 "push_operand" "")
2324 (match_operand:DI 1 "immediate_operand" ""))]
2325 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2326 ? epilogue_completed : reload_completed)
2327 && !symbolic_operand (operands[1], DImode)
2328 && !x86_64_immediate_operand (operands[1], DImode)"
2329 [(set (match_dup 0) (match_dup 1))
2330 (set (match_dup 2) (match_dup 3))]
2331 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2332 operands[1] = gen_lowpart (DImode, operands[2]);
2333 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2337 (define_insn "*pushdi2_prologue_rex64"
2338 [(set (match_operand:DI 0 "push_operand" "=<")
2339 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2340 (clobber (mem:BLK (scratch)))]
2343 [(set_attr "type" "push")
2344 (set_attr "mode" "DI")])
2346 (define_insn "*popdi1_epilogue_rex64"
2347 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2348 (mem:DI (reg:DI SP_REG)))
2349 (set (reg:DI SP_REG)
2350 (plus:DI (reg:DI SP_REG) (const_int 8)))
2351 (clobber (mem:BLK (scratch)))]
2354 [(set_attr "type" "pop")
2355 (set_attr "mode" "DI")])
2357 (define_insn "popdi1"
2358 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2359 (mem:DI (reg:DI SP_REG)))
2360 (set (reg:DI SP_REG)
2361 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2364 [(set_attr "type" "pop")
2365 (set_attr "mode" "DI")])
2367 (define_insn "*movdi_xor_rex64"
2368 [(set (match_operand:DI 0 "register_operand" "=r")
2369 (match_operand:DI 1 "const0_operand" ""))
2370 (clobber (reg:CC FLAGS_REG))]
2372 && reload_completed"
2374 [(set_attr "type" "alu1")
2375 (set_attr "mode" "SI")
2376 (set_attr "length_immediate" "0")])
2378 (define_insn "*movdi_or_rex64"
2379 [(set (match_operand:DI 0 "register_operand" "=r")
2380 (match_operand:DI 1 "const_int_operand" "i"))
2381 (clobber (reg:CC FLAGS_REG))]
2384 && operands[1] == constm1_rtx"
2386 operands[1] = constm1_rtx;
2387 return "or{q}\t{%1, %0|%0, %1}";
2389 [(set_attr "type" "alu1")
2390 (set_attr "mode" "DI")
2391 (set_attr "length_immediate" "1")])
2393 (define_insn "*movdi_2"
2394 [(set (match_operand:DI 0 "nonimmediate_operand"
2395 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2396 (match_operand:DI 1 "general_operand"
2397 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2398 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2403 movq\t{%1, %0|%0, %1}
2404 movq\t{%1, %0|%0, %1}
2406 %vmovq\t{%1, %0|%0, %1}
2407 %vmovdqa\t{%1, %0|%0, %1}
2408 %vmovq\t{%1, %0|%0, %1}
2410 movlps\t{%1, %0|%0, %1}
2411 movaps\t{%1, %0|%0, %1}
2412 movlps\t{%1, %0|%0, %1}"
2413 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2414 (set (attr "prefix")
2415 (if_then_else (eq_attr "alternative" "5,6,7,8")
2416 (const_string "vex")
2417 (const_string "orig")))
2418 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2421 [(set (match_operand:DI 0 "push_operand" "")
2422 (match_operand:DI 1 "general_operand" ""))]
2423 "!TARGET_64BIT && reload_completed
2424 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2426 "ix86_split_long_move (operands); DONE;")
2428 ;; %%% This multiword shite has got to go.
2430 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2431 (match_operand:DI 1 "general_operand" ""))]
2432 "!TARGET_64BIT && reload_completed
2433 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2434 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2436 "ix86_split_long_move (operands); DONE;")
2438 (define_insn "*movdi_1_rex64"
2439 [(set (match_operand:DI 0 "nonimmediate_operand"
2440 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2441 (match_operand:DI 1 "general_operand"
2442 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2443 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2445 switch (get_attr_type (insn))
2448 if (SSE_REG_P (operands[0]))
2449 return "movq2dq\t{%1, %0|%0, %1}";
2451 return "movdq2q\t{%1, %0|%0, %1}";
2456 if (get_attr_mode (insn) == MODE_TI)
2457 return "vmovdqa\t{%1, %0|%0, %1}";
2459 return "vmovq\t{%1, %0|%0, %1}";
2462 if (get_attr_mode (insn) == MODE_TI)
2463 return "movdqa\t{%1, %0|%0, %1}";
2467 /* Moves from and into integer register is done using movd
2468 opcode with REX prefix. */
2469 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2470 return "movd\t{%1, %0|%0, %1}";
2471 return "movq\t{%1, %0|%0, %1}";
2474 return "%vpxor\t%0, %d0";
2477 return "pxor\t%0, %0";
2483 return "lea{q}\t{%a1, %0|%0, %a1}";
2486 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2487 if (get_attr_mode (insn) == MODE_SI)
2488 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2489 else if (which_alternative == 2)
2490 return "movabs{q}\t{%1, %0|%0, %1}";
2492 return "mov{q}\t{%1, %0|%0, %1}";
2496 (cond [(eq_attr "alternative" "5")
2497 (const_string "mmx")
2498 (eq_attr "alternative" "6,7,8,9,10")
2499 (const_string "mmxmov")
2500 (eq_attr "alternative" "11")
2501 (const_string "sselog1")
2502 (eq_attr "alternative" "12,13,14,15,16")
2503 (const_string "ssemov")
2504 (eq_attr "alternative" "17,18")
2505 (const_string "ssecvt")
2506 (eq_attr "alternative" "4")
2507 (const_string "multi")
2508 (match_operand:DI 1 "pic_32bit_operand" "")
2509 (const_string "lea")
2511 (const_string "imov")))
2514 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2516 (const_string "*")))
2517 (set (attr "length_immediate")
2519 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2521 (const_string "*")))
2522 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2523 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2524 (set (attr "prefix")
2525 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2526 (const_string "maybe_vex")
2527 (const_string "orig")))
2528 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2530 ;; Stores and loads of ax to arbitrary constant address.
2531 ;; We fake an second form of instruction to force reload to load address
2532 ;; into register when rax is not available
2533 (define_insn "*movabsdi_1_rex64"
2534 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2535 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2536 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2538 movabs{q}\t{%1, %P0|%P0, %1}
2539 mov{q}\t{%1, %a0|%a0, %1}"
2540 [(set_attr "type" "imov")
2541 (set_attr "modrm" "0,*")
2542 (set_attr "length_address" "8,0")
2543 (set_attr "length_immediate" "0,*")
2544 (set_attr "memory" "store")
2545 (set_attr "mode" "DI")])
2547 (define_insn "*movabsdi_2_rex64"
2548 [(set (match_operand:DI 0 "register_operand" "=a,r")
2549 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2550 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2552 movabs{q}\t{%P1, %0|%0, %P1}
2553 mov{q}\t{%a1, %0|%0, %a1}"
2554 [(set_attr "type" "imov")
2555 (set_attr "modrm" "0,*")
2556 (set_attr "length_address" "8,0")
2557 (set_attr "length_immediate" "0")
2558 (set_attr "memory" "load")
2559 (set_attr "mode" "DI")])
2561 ;; Convert impossible stores of immediate to existing instructions.
2562 ;; First try to get scratch register and go through it. In case this
2563 ;; fails, move by 32bit parts.
2565 [(match_scratch:DI 2 "r")
2566 (set (match_operand:DI 0 "memory_operand" "")
2567 (match_operand:DI 1 "immediate_operand" ""))]
2568 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2569 && !x86_64_immediate_operand (operands[1], DImode)"
2570 [(set (match_dup 2) (match_dup 1))
2571 (set (match_dup 0) (match_dup 2))]
2574 ;; We need to define this as both peepholer and splitter for case
2575 ;; peephole2 pass is not run.
2576 ;; "&& 1" is needed to keep it from matching the previous pattern.
2578 [(set (match_operand:DI 0 "memory_operand" "")
2579 (match_operand:DI 1 "immediate_operand" ""))]
2580 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2581 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2582 [(set (match_dup 2) (match_dup 3))
2583 (set (match_dup 4) (match_dup 5))]
2584 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2587 [(set (match_operand:DI 0 "memory_operand" "")
2588 (match_operand:DI 1 "immediate_operand" ""))]
2589 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2590 ? epilogue_completed : reload_completed)
2591 && !symbolic_operand (operands[1], DImode)
2592 && !x86_64_immediate_operand (operands[1], DImode)"
2593 [(set (match_dup 2) (match_dup 3))
2594 (set (match_dup 4) (match_dup 5))]
2595 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2597 (define_insn "*swapdi_rex64"
2598 [(set (match_operand:DI 0 "register_operand" "+r")
2599 (match_operand:DI 1 "register_operand" "+r"))
2604 [(set_attr "type" "imov")
2605 (set_attr "mode" "DI")
2606 (set_attr "pent_pair" "np")
2607 (set_attr "athlon_decode" "vector")
2608 (set_attr "amdfam10_decode" "double")])
2610 (define_expand "movoi"
2611 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2612 (match_operand:OI 1 "general_operand" ""))]
2614 "ix86_expand_move (OImode, operands); DONE;")
2616 (define_insn "*movoi_internal"
2617 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2618 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2620 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2622 switch (which_alternative)
2625 return "vxorps\t%0, %0, %0";
2628 if (misaligned_operand (operands[0], OImode)
2629 || misaligned_operand (operands[1], OImode))
2630 return "vmovdqu\t{%1, %0|%0, %1}";
2632 return "vmovdqa\t{%1, %0|%0, %1}";
2637 [(set_attr "type" "sselog1,ssemov,ssemov")
2638 (set_attr "prefix" "vex")
2639 (set_attr "mode" "OI")])
2641 (define_expand "movti"
2642 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2643 (match_operand:TI 1 "nonimmediate_operand" ""))]
2644 "TARGET_SSE || TARGET_64BIT"
2647 ix86_expand_move (TImode, operands);
2648 else if (push_operand (operands[0], TImode))
2649 ix86_expand_push (TImode, operands[1]);
2651 ix86_expand_vector_move (TImode, operands);
2655 (define_insn "*movti_internal"
2656 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2657 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2658 "TARGET_SSE && !TARGET_64BIT
2659 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2661 switch (which_alternative)
2664 if (get_attr_mode (insn) == MODE_V4SF)
2665 return "%vxorps\t%0, %d0";
2667 return "%vpxor\t%0, %d0";
2670 /* TDmode values are passed as TImode on the stack. Moving them
2671 to stack may result in unaligned memory access. */
2672 if (misaligned_operand (operands[0], TImode)
2673 || misaligned_operand (operands[1], TImode))
2675 if (get_attr_mode (insn) == MODE_V4SF)
2676 return "%vmovups\t{%1, %0|%0, %1}";
2678 return "%vmovdqu\t{%1, %0|%0, %1}";
2682 if (get_attr_mode (insn) == MODE_V4SF)
2683 return "%vmovaps\t{%1, %0|%0, %1}";
2685 return "%vmovdqa\t{%1, %0|%0, %1}";
2691 [(set_attr "type" "sselog1,ssemov,ssemov")
2692 (set_attr "prefix" "maybe_vex")
2694 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2695 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2696 (const_string "V4SF")
2697 (and (eq_attr "alternative" "2")
2698 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2700 (const_string "V4SF")]
2701 (const_string "TI")))])
2703 (define_insn "*movti_rex64"
2704 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2705 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2707 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2709 switch (which_alternative)
2715 if (get_attr_mode (insn) == MODE_V4SF)
2716 return "%vxorps\t%0, %d0";
2718 return "%vpxor\t%0, %d0";
2721 /* TDmode values are passed as TImode on the stack. Moving them
2722 to stack may result in unaligned memory access. */
2723 if (misaligned_operand (operands[0], TImode)
2724 || misaligned_operand (operands[1], TImode))
2726 if (get_attr_mode (insn) == MODE_V4SF)
2727 return "%vmovups\t{%1, %0|%0, %1}";
2729 return "%vmovdqu\t{%1, %0|%0, %1}";
2733 if (get_attr_mode (insn) == MODE_V4SF)
2734 return "%vmovaps\t{%1, %0|%0, %1}";
2736 return "%vmovdqa\t{%1, %0|%0, %1}";
2742 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2743 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2745 (cond [(eq_attr "alternative" "2,3")
2747 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2749 (const_string "V4SF")
2750 (const_string "TI"))
2751 (eq_attr "alternative" "4")
2753 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2755 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2757 (const_string "V4SF")
2758 (const_string "TI"))]
2759 (const_string "DI")))])
2762 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2763 (match_operand:TI 1 "general_operand" ""))]
2764 "reload_completed && !SSE_REG_P (operands[0])
2765 && !SSE_REG_P (operands[1])"
2767 "ix86_split_long_move (operands); DONE;")
2769 ;; This expands to what emit_move_complex would generate if we didn't
2770 ;; have a movti pattern. Having this avoids problems with reload on
2771 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2772 ;; to have around all the time.
2773 (define_expand "movcdi"
2774 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2775 (match_operand:CDI 1 "general_operand" ""))]
2778 if (push_operand (operands[0], CDImode))
2779 emit_move_complex_push (CDImode, operands[0], operands[1]);
2781 emit_move_complex_parts (operands[0], operands[1]);
2785 (define_expand "movsf"
2786 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2787 (match_operand:SF 1 "general_operand" ""))]
2789 "ix86_expand_move (SFmode, operands); DONE;")
2791 (define_insn "*pushsf"
2792 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2793 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2796 /* Anything else should be already split before reg-stack. */
2797 gcc_assert (which_alternative == 1);
2798 return "push{l}\t%1";
2800 [(set_attr "type" "multi,push,multi")
2801 (set_attr "unit" "i387,*,*")
2802 (set_attr "mode" "SF,SI,SF")])
2804 (define_insn "*pushsf_rex64"
2805 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2806 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2809 /* Anything else should be already split before reg-stack. */
2810 gcc_assert (which_alternative == 1);
2811 return "push{q}\t%q1";
2813 [(set_attr "type" "multi,push,multi")
2814 (set_attr "unit" "i387,*,*")
2815 (set_attr "mode" "SF,DI,SF")])
2818 [(set (match_operand:SF 0 "push_operand" "")
2819 (match_operand:SF 1 "memory_operand" ""))]
2821 && MEM_P (operands[1])
2822 && (operands[2] = find_constant_src (insn))"
2826 ;; %%% Kill this when call knows how to work this out.
2828 [(set (match_operand:SF 0 "push_operand" "")
2829 (match_operand:SF 1 "any_fp_register_operand" ""))]
2831 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2832 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2835 [(set (match_operand:SF 0 "push_operand" "")
2836 (match_operand:SF 1 "any_fp_register_operand" ""))]
2838 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2839 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2841 (define_insn "*movsf_1"
2842 [(set (match_operand:SF 0 "nonimmediate_operand"
2843 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2844 (match_operand:SF 1 "general_operand"
2845 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2846 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2847 && (reload_in_progress || reload_completed
2848 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2849 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2850 && standard_80387_constant_p (operands[1]))
2851 || GET_CODE (operands[1]) != CONST_DOUBLE
2852 || memory_operand (operands[0], SFmode))"
2854 switch (which_alternative)
2858 return output_387_reg_move (insn, operands);
2861 return standard_80387_constant_opcode (operands[1]);
2865 return "mov{l}\t{%1, %0|%0, %1}";
2867 if (get_attr_mode (insn) == MODE_TI)
2868 return "%vpxor\t%0, %d0";
2870 return "%vxorps\t%0, %d0";
2872 if (get_attr_mode (insn) == MODE_V4SF)
2873 return "%vmovaps\t{%1, %0|%0, %1}";
2875 return "%vmovss\t{%1, %d0|%d0, %1}";
2878 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2879 : "vmovss\t{%1, %0|%0, %1}";
2881 return "movss\t{%1, %0|%0, %1}";
2883 return "%vmovss\t{%1, %0|%0, %1}";
2885 case 9: case 10: case 14: case 15:
2886 return "movd\t{%1, %0|%0, %1}";
2888 return "%vmovd\t{%1, %0|%0, %1}";
2891 return "movq\t{%1, %0|%0, %1}";
2897 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2898 (set (attr "prefix")
2899 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2900 (const_string "maybe_vex")
2901 (const_string "orig")))
2903 (cond [(eq_attr "alternative" "3,4,9,10")
2905 (eq_attr "alternative" "5")
2907 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2909 (ne (symbol_ref "TARGET_SSE2")
2911 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2914 (const_string "V4SF"))
2915 /* For architectures resolving dependencies on
2916 whole SSE registers use APS move to break dependency
2917 chains, otherwise use short move to avoid extra work.
2919 Do the same for architectures resolving dependencies on
2920 the parts. While in DF mode it is better to always handle
2921 just register parts, the SF mode is different due to lack
2922 of instructions to load just part of the register. It is
2923 better to maintain the whole registers in single format
2924 to avoid problems on using packed logical operations. */
2925 (eq_attr "alternative" "6")
2927 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2929 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2931 (const_string "V4SF")
2932 (const_string "SF"))
2933 (eq_attr "alternative" "11")
2934 (const_string "DI")]
2935 (const_string "SF")))])
2937 (define_insn "*swapsf"
2938 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2939 (match_operand:SF 1 "fp_register_operand" "+f"))
2942 "reload_completed || TARGET_80387"
2944 if (STACK_TOP_P (operands[0]))
2949 [(set_attr "type" "fxch")
2950 (set_attr "mode" "SF")])
2952 (define_expand "movdf"
2953 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2954 (match_operand:DF 1 "general_operand" ""))]
2956 "ix86_expand_move (DFmode, operands); DONE;")
2958 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2959 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2960 ;; On the average, pushdf using integers can be still shorter. Allow this
2961 ;; pattern for optimize_size too.
2963 (define_insn "*pushdf_nointeger"
2964 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2965 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2966 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2968 /* This insn should be already split before reg-stack. */
2971 [(set_attr "type" "multi")
2972 (set_attr "unit" "i387,*,*,*")
2973 (set_attr "mode" "DF,SI,SI,DF")])
2975 (define_insn "*pushdf_integer"
2976 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2977 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2978 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2980 /* This insn should be already split before reg-stack. */
2983 [(set_attr "type" "multi")
2984 (set_attr "unit" "i387,*,*")
2985 (set_attr "mode" "DF,SI,DF")])
2987 ;; %%% Kill this when call knows how to work this out.
2989 [(set (match_operand:DF 0 "push_operand" "")
2990 (match_operand:DF 1 "any_fp_register_operand" ""))]
2992 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2993 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2997 [(set (match_operand:DF 0 "push_operand" "")
2998 (match_operand:DF 1 "general_operand" ""))]
3001 "ix86_split_long_move (operands); DONE;")
3003 ;; Moving is usually shorter when only FP registers are used. This separate
3004 ;; movdf pattern avoids the use of integer registers for FP operations
3005 ;; when optimizing for size.
3007 (define_insn "*movdf_nointeger"
3008 [(set (match_operand:DF 0 "nonimmediate_operand"
3009 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3010 (match_operand:DF 1 "general_operand"
3011 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3012 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3013 && ((optimize_function_for_size_p (cfun)
3014 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3015 && (reload_in_progress || reload_completed
3016 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3017 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3018 && optimize_function_for_size_p (cfun)
3019 && !memory_operand (operands[0], DFmode)
3020 && standard_80387_constant_p (operands[1]))
3021 || GET_CODE (operands[1]) != CONST_DOUBLE
3022 || ((optimize_function_for_size_p (cfun)
3023 || !TARGET_MEMORY_MISMATCH_STALL
3024 || reload_in_progress || reload_completed)
3025 && memory_operand (operands[0], DFmode)))"
3027 switch (which_alternative)
3031 return output_387_reg_move (insn, operands);
3034 return standard_80387_constant_opcode (operands[1]);
3040 switch (get_attr_mode (insn))
3043 return "%vxorps\t%0, %d0";
3045 return "%vxorpd\t%0, %d0";
3047 return "%vpxor\t%0, %d0";
3054 switch (get_attr_mode (insn))
3057 return "%vmovaps\t{%1, %0|%0, %1}";
3059 return "%vmovapd\t{%1, %0|%0, %1}";
3061 return "%vmovdqa\t{%1, %0|%0, %1}";
3063 return "%vmovq\t{%1, %0|%0, %1}";
3067 if (REG_P (operands[0]) && REG_P (operands[1]))
3068 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3070 return "vmovsd\t{%1, %0|%0, %1}";
3073 return "movsd\t{%1, %0|%0, %1}";
3077 if (REG_P (operands[0]))
3078 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3080 return "vmovlpd\t{%1, %0|%0, %1}";
3083 return "movlpd\t{%1, %0|%0, %1}";
3087 if (REG_P (operands[0]))
3088 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3090 return "vmovlps\t{%1, %0|%0, %1}";
3093 return "movlps\t{%1, %0|%0, %1}";
3102 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3103 (set (attr "prefix")
3104 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3105 (const_string "orig")
3106 (const_string "maybe_vex")))
3107 (set (attr "prefix_data16")
3108 (if_then_else (eq_attr "mode" "V1DF")
3110 (const_string "*")))
3112 (cond [(eq_attr "alternative" "0,1,2")
3114 (eq_attr "alternative" "3,4")
3117 /* For SSE1, we have many fewer alternatives. */
3118 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3119 (cond [(eq_attr "alternative" "5,6")
3120 (const_string "V4SF")
3122 (const_string "V2SF"))
3124 /* xorps is one byte shorter. */
3125 (eq_attr "alternative" "5")
3126 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3128 (const_string "V4SF")
3129 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3133 (const_string "V2DF"))
3135 /* For architectures resolving dependencies on
3136 whole SSE registers use APD move to break dependency
3137 chains, otherwise use short move to avoid extra work.
3139 movaps encodes one byte shorter. */
3140 (eq_attr "alternative" "6")
3142 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3144 (const_string "V4SF")
3145 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3147 (const_string "V2DF")
3149 (const_string "DF"))
3150 /* For architectures resolving dependencies on register
3151 parts we may avoid extra work to zero out upper part
3153 (eq_attr "alternative" "7")
3155 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3157 (const_string "V1DF")
3158 (const_string "DF"))
3160 (const_string "DF")))])
3162 (define_insn "*movdf_integer_rex64"
3163 [(set (match_operand:DF 0 "nonimmediate_operand"
3164 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3165 (match_operand:DF 1 "general_operand"
3166 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3167 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3168 && (reload_in_progress || reload_completed
3169 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3170 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3171 && optimize_function_for_size_p (cfun)
3172 && standard_80387_constant_p (operands[1]))
3173 || GET_CODE (operands[1]) != CONST_DOUBLE
3174 || memory_operand (operands[0], DFmode))"
3176 switch (which_alternative)
3180 return output_387_reg_move (insn, operands);
3183 return standard_80387_constant_opcode (operands[1]);
3190 switch (get_attr_mode (insn))
3193 return "%vxorps\t%0, %d0";
3195 return "%vxorpd\t%0, %d0";
3197 return "%vpxor\t%0, %d0";
3204 switch (get_attr_mode (insn))
3207 return "%vmovaps\t{%1, %0|%0, %1}";
3209 return "%vmovapd\t{%1, %0|%0, %1}";
3211 return "%vmovdqa\t{%1, %0|%0, %1}";
3213 return "%vmovq\t{%1, %0|%0, %1}";
3217 if (REG_P (operands[0]) && REG_P (operands[1]))
3218 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3220 return "vmovsd\t{%1, %0|%0, %1}";
3223 return "movsd\t{%1, %0|%0, %1}";
3225 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3227 return "%vmovlps\t{%1, %d0|%d0, %1}";
3234 return "%vmovd\t{%1, %0|%0, %1}";
3240 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3241 (set (attr "prefix")
3242 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3243 (const_string "orig")
3244 (const_string "maybe_vex")))
3245 (set (attr "prefix_data16")
3246 (if_then_else (eq_attr "mode" "V1DF")
3248 (const_string "*")))
3250 (cond [(eq_attr "alternative" "0,1,2")
3252 (eq_attr "alternative" "3,4,9,10")
3255 /* For SSE1, we have many fewer alternatives. */
3256 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3257 (cond [(eq_attr "alternative" "5,6")
3258 (const_string "V4SF")
3260 (const_string "V2SF"))
3262 /* xorps is one byte shorter. */
3263 (eq_attr "alternative" "5")
3264 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3266 (const_string "V4SF")
3267 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3271 (const_string "V2DF"))
3273 /* For architectures resolving dependencies on
3274 whole SSE registers use APD move to break dependency
3275 chains, otherwise use short move to avoid extra work.
3277 movaps encodes one byte shorter. */
3278 (eq_attr "alternative" "6")
3280 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3282 (const_string "V4SF")
3283 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3285 (const_string "V2DF")
3287 (const_string "DF"))
3288 /* For architectures resolving dependencies on register
3289 parts we may avoid extra work to zero out upper part
3291 (eq_attr "alternative" "7")
3293 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3295 (const_string "V1DF")
3296 (const_string "DF"))
3298 (const_string "DF")))])
3300 (define_insn "*movdf_integer"
3301 [(set (match_operand:DF 0 "nonimmediate_operand"
3302 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3303 (match_operand:DF 1 "general_operand"
3304 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3305 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3306 && optimize_function_for_speed_p (cfun)
3307 && TARGET_INTEGER_DFMODE_MOVES
3308 && (reload_in_progress || reload_completed
3309 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3310 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3311 && optimize_function_for_size_p (cfun)
3312 && standard_80387_constant_p (operands[1]))
3313 || GET_CODE (operands[1]) != CONST_DOUBLE
3314 || memory_operand (operands[0], DFmode))"
3316 switch (which_alternative)
3320 return output_387_reg_move (insn, operands);
3323 return standard_80387_constant_opcode (operands[1]);
3330 switch (get_attr_mode (insn))
3333 return "xorps\t%0, %0";
3335 return "xorpd\t%0, %0";
3337 return "pxor\t%0, %0";
3344 switch (get_attr_mode (insn))
3347 return "movaps\t{%1, %0|%0, %1}";
3349 return "movapd\t{%1, %0|%0, %1}";
3351 return "movdqa\t{%1, %0|%0, %1}";
3353 return "movq\t{%1, %0|%0, %1}";
3355 return "movsd\t{%1, %0|%0, %1}";
3357 return "movlpd\t{%1, %0|%0, %1}";
3359 return "movlps\t{%1, %0|%0, %1}";
3368 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3369 (set (attr "prefix_data16")
3370 (if_then_else (eq_attr "mode" "V1DF")
3372 (const_string "*")))
3374 (cond [(eq_attr "alternative" "0,1,2")
3376 (eq_attr "alternative" "3,4")
3379 /* For SSE1, we have many fewer alternatives. */
3380 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3381 (cond [(eq_attr "alternative" "5,6")
3382 (const_string "V4SF")
3384 (const_string "V2SF"))
3386 /* xorps is one byte shorter. */
3387 (eq_attr "alternative" "5")
3388 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3390 (const_string "V4SF")
3391 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3395 (const_string "V2DF"))
3397 /* For architectures resolving dependencies on
3398 whole SSE registers use APD move to break dependency
3399 chains, otherwise use short move to avoid extra work.
3401 movaps encodes one byte shorter. */
3402 (eq_attr "alternative" "6")
3404 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3406 (const_string "V4SF")
3407 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3409 (const_string "V2DF")
3411 (const_string "DF"))
3412 /* For architectures resolving dependencies on register
3413 parts we may avoid extra work to zero out upper part
3415 (eq_attr "alternative" "7")
3417 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3419 (const_string "V1DF")
3420 (const_string "DF"))
3422 (const_string "DF")))])
3425 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3426 (match_operand:DF 1 "general_operand" ""))]
3428 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3429 && ! (ANY_FP_REG_P (operands[0]) ||
3430 (GET_CODE (operands[0]) == SUBREG
3431 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3432 && ! (ANY_FP_REG_P (operands[1]) ||
3433 (GET_CODE (operands[1]) == SUBREG
3434 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3436 "ix86_split_long_move (operands); DONE;")
3438 (define_insn "*swapdf"
3439 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3440 (match_operand:DF 1 "fp_register_operand" "+f"))
3443 "reload_completed || TARGET_80387"
3445 if (STACK_TOP_P (operands[0]))
3450 [(set_attr "type" "fxch")
3451 (set_attr "mode" "DF")])
3453 (define_expand "movxf"
3454 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3455 (match_operand:XF 1 "general_operand" ""))]
3457 "ix86_expand_move (XFmode, operands); DONE;")
3459 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3460 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3461 ;; Pushing using integer instructions is longer except for constants
3462 ;; and direct memory references.
3463 ;; (assuming that any given constant is pushed only once, but this ought to be
3464 ;; handled elsewhere).
3466 (define_insn "*pushxf_nointeger"
3467 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3468 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3469 "optimize_function_for_size_p (cfun)"
3471 /* This insn should be already split before reg-stack. */
3474 [(set_attr "type" "multi")
3475 (set_attr "unit" "i387,*,*")
3476 (set_attr "mode" "XF,SI,SI")])
3478 (define_insn "*pushxf_integer"
3479 [(set (match_operand:XF 0 "push_operand" "=<,<")
3480 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3481 "optimize_function_for_speed_p (cfun)"
3483 /* This insn should be already split before reg-stack. */
3486 [(set_attr "type" "multi")
3487 (set_attr "unit" "i387,*")
3488 (set_attr "mode" "XF,SI")])
3491 [(set (match_operand 0 "push_operand" "")
3492 (match_operand 1 "general_operand" ""))]
3494 && (GET_MODE (operands[0]) == XFmode
3495 || GET_MODE (operands[0]) == DFmode)
3496 && !ANY_FP_REG_P (operands[1])"
3498 "ix86_split_long_move (operands); DONE;")
3501 [(set (match_operand:XF 0 "push_operand" "")
3502 (match_operand:XF 1 "any_fp_register_operand" ""))]
3504 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3505 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3506 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3508 ;; Do not use integer registers when optimizing for size
3509 (define_insn "*movxf_nointeger"
3510 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3511 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3512 "optimize_function_for_size_p (cfun)
3513 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3514 && (reload_in_progress || reload_completed
3515 || standard_80387_constant_p (operands[1])
3516 || GET_CODE (operands[1]) != CONST_DOUBLE
3517 || memory_operand (operands[0], XFmode))"
3519 switch (which_alternative)
3523 return output_387_reg_move (insn, operands);
3526 return standard_80387_constant_opcode (operands[1]);
3534 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3535 (set_attr "mode" "XF,XF,XF,SI,SI")])
3537 (define_insn "*movxf_integer"
3538 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3539 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3540 "optimize_function_for_speed_p (cfun)
3541 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3542 && (reload_in_progress || reload_completed
3543 || GET_CODE (operands[1]) != CONST_DOUBLE
3544 || memory_operand (operands[0], XFmode))"
3546 switch (which_alternative)
3550 return output_387_reg_move (insn, operands);
3553 return standard_80387_constant_opcode (operands[1]);
3562 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3563 (set_attr "mode" "XF,XF,XF,SI,SI")])
3565 (define_expand "movtf"
3566 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3567 (match_operand:TF 1 "nonimmediate_operand" ""))]
3570 ix86_expand_move (TFmode, operands);
3574 (define_insn "*movtf_internal"
3575 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3576 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3578 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3580 switch (which_alternative)
3584 if (get_attr_mode (insn) == MODE_V4SF)
3585 return "%vmovaps\t{%1, %0|%0, %1}";
3587 return "%vmovdqa\t{%1, %0|%0, %1}";
3589 if (get_attr_mode (insn) == MODE_V4SF)
3590 return "%vxorps\t%0, %d0";
3592 return "%vpxor\t%0, %d0";
3600 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3601 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3603 (cond [(eq_attr "alternative" "0,2")
3605 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3607 (const_string "V4SF")
3608 (const_string "TI"))
3609 (eq_attr "alternative" "1")
3611 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3613 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3615 (const_string "V4SF")
3616 (const_string "TI"))]
3617 (const_string "DI")))])
3619 (define_insn "*pushtf_sse"
3620 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3621 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3624 /* This insn should be already split before reg-stack. */
3627 [(set_attr "type" "multi")
3628 (set_attr "unit" "sse,*,*")
3629 (set_attr "mode" "TF,SI,SI")])
3632 [(set (match_operand:TF 0 "push_operand" "")
3633 (match_operand:TF 1 "general_operand" ""))]
3634 "TARGET_SSE2 && reload_completed
3635 && !SSE_REG_P (operands[1])"
3637 "ix86_split_long_move (operands); DONE;")
3640 [(set (match_operand:TF 0 "push_operand" "")
3641 (match_operand:TF 1 "any_fp_register_operand" ""))]
3643 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3644 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3648 [(set (match_operand 0 "nonimmediate_operand" "")
3649 (match_operand 1 "general_operand" ""))]
3651 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3652 && GET_MODE (operands[0]) == XFmode
3653 && ! (ANY_FP_REG_P (operands[0]) ||
3654 (GET_CODE (operands[0]) == SUBREG
3655 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3656 && ! (ANY_FP_REG_P (operands[1]) ||
3657 (GET_CODE (operands[1]) == SUBREG
3658 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3660 "ix86_split_long_move (operands); DONE;")
3663 [(set (match_operand 0 "register_operand" "")
3664 (match_operand 1 "memory_operand" ""))]
3666 && MEM_P (operands[1])
3667 && (GET_MODE (operands[0]) == TFmode
3668 || GET_MODE (operands[0]) == XFmode
3669 || GET_MODE (operands[0]) == SFmode
3670 || GET_MODE (operands[0]) == DFmode)
3671 && (operands[2] = find_constant_src (insn))"
3672 [(set (match_dup 0) (match_dup 2))]
3674 rtx c = operands[2];
3675 rtx r = operands[0];
3677 if (GET_CODE (r) == SUBREG)
3682 if (!standard_sse_constant_p (c))
3685 else if (FP_REG_P (r))
3687 if (!standard_80387_constant_p (c))
3690 else if (MMX_REG_P (r))
3695 [(set (match_operand 0 "register_operand" "")
3696 (float_extend (match_operand 1 "memory_operand" "")))]
3698 && MEM_P (operands[1])
3699 && (GET_MODE (operands[0]) == TFmode
3700 || GET_MODE (operands[0]) == XFmode
3701 || GET_MODE (operands[0]) == SFmode
3702 || GET_MODE (operands[0]) == DFmode)
3703 && (operands[2] = find_constant_src (insn))"
3704 [(set (match_dup 0) (match_dup 2))]
3706 rtx c = operands[2];
3707 rtx r = operands[0];
3709 if (GET_CODE (r) == SUBREG)
3714 if (!standard_sse_constant_p (c))
3717 else if (FP_REG_P (r))
3719 if (!standard_80387_constant_p (c))
3722 else if (MMX_REG_P (r))
3726 (define_insn "swapxf"
3727 [(set (match_operand:XF 0 "register_operand" "+f")
3728 (match_operand:XF 1 "register_operand" "+f"))
3733 if (STACK_TOP_P (operands[0]))
3738 [(set_attr "type" "fxch")
3739 (set_attr "mode" "XF")])
3741 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3743 [(set (match_operand:X87MODEF 0 "register_operand" "")
3744 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3745 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3746 && (standard_80387_constant_p (operands[1]) == 8
3747 || standard_80387_constant_p (operands[1]) == 9)"
3748 [(set (match_dup 0)(match_dup 1))
3750 (neg:X87MODEF (match_dup 0)))]
3754 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3755 if (real_isnegzero (&r))
3756 operands[1] = CONST0_RTX (<MODE>mode);
3758 operands[1] = CONST1_RTX (<MODE>mode);
3762 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3763 (match_operand:TF 1 "general_operand" ""))]
3765 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3767 "ix86_split_long_move (operands); DONE;")
3769 ;; Zero extension instructions
3771 (define_expand "zero_extendhisi2"
3772 [(set (match_operand:SI 0 "register_operand" "")
3773 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3776 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3778 operands[1] = force_reg (HImode, operands[1]);
3779 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3784 (define_insn "zero_extendhisi2_and"
3785 [(set (match_operand:SI 0 "register_operand" "=r")
3786 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3787 (clobber (reg:CC FLAGS_REG))]
3788 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3790 [(set_attr "type" "alu1")
3791 (set_attr "mode" "SI")])
3794 [(set (match_operand:SI 0 "register_operand" "")
3795 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3796 (clobber (reg:CC FLAGS_REG))]
3797 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3798 && optimize_function_for_speed_p (cfun)"
3799 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3800 (clobber (reg:CC FLAGS_REG))])]
3803 (define_insn "*zero_extendhisi2_movzwl"
3804 [(set (match_operand:SI 0 "register_operand" "=r")
3805 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3806 "!TARGET_ZERO_EXTEND_WITH_AND
3807 || optimize_function_for_size_p (cfun)"
3808 "movz{wl|x}\t{%1, %0|%0, %1}"
3809 [(set_attr "type" "imovx")
3810 (set_attr "mode" "SI")])
3812 (define_expand "zero_extendqihi2"
3814 [(set (match_operand:HI 0 "register_operand" "")
3815 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3816 (clobber (reg:CC FLAGS_REG))])]
3820 (define_insn "*zero_extendqihi2_and"
3821 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3822 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3823 (clobber (reg:CC FLAGS_REG))]
3824 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3826 [(set_attr "type" "alu1")
3827 (set_attr "mode" "HI")])
3829 (define_insn "*zero_extendqihi2_movzbw_and"
3830 [(set (match_operand:HI 0 "register_operand" "=r,r")
3831 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3832 (clobber (reg:CC FLAGS_REG))]
3833 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3835 [(set_attr "type" "imovx,alu1")
3836 (set_attr "mode" "HI")])
3838 ; zero extend to SImode here to avoid partial register stalls
3839 (define_insn "*zero_extendqihi2_movzbl"
3840 [(set (match_operand:HI 0 "register_operand" "=r")
3841 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3842 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3843 && reload_completed"
3844 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3845 [(set_attr "type" "imovx")
3846 (set_attr "mode" "SI")])
3848 ;; For the movzbw case strip only the clobber
3850 [(set (match_operand:HI 0 "register_operand" "")
3851 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3852 (clobber (reg:CC FLAGS_REG))]
3854 && (!TARGET_ZERO_EXTEND_WITH_AND
3855 || optimize_function_for_size_p (cfun))
3856 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3857 [(set (match_operand:HI 0 "register_operand" "")
3858 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3860 ;; When source and destination does not overlap, clear destination
3861 ;; first and then do the movb
3863 [(set (match_operand:HI 0 "register_operand" "")
3864 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3865 (clobber (reg:CC FLAGS_REG))]
3867 && ANY_QI_REG_P (operands[0])
3868 && (TARGET_ZERO_EXTEND_WITH_AND
3869 && optimize_function_for_speed_p (cfun))
3870 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3871 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3873 operands[2] = gen_lowpart (QImode, operands[0]);
3874 ix86_expand_clear (operands[0]);
3877 ;; Rest is handled by single and.
3879 [(set (match_operand:HI 0 "register_operand" "")
3880 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3881 (clobber (reg:CC FLAGS_REG))]
3883 && true_regnum (operands[0]) == true_regnum (operands[1])"
3884 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3885 (clobber (reg:CC FLAGS_REG))])]
3888 (define_expand "zero_extendqisi2"
3890 [(set (match_operand:SI 0 "register_operand" "")
3891 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3892 (clobber (reg:CC FLAGS_REG))])]
3896 (define_insn "*zero_extendqisi2_and"
3897 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3898 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3899 (clobber (reg:CC FLAGS_REG))]
3900 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3902 [(set_attr "type" "alu1")
3903 (set_attr "mode" "SI")])
3905 (define_insn "*zero_extendqisi2_movzbl_and"
3906 [(set (match_operand:SI 0 "register_operand" "=r,r")
3907 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3908 (clobber (reg:CC FLAGS_REG))]
3909 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3911 [(set_attr "type" "imovx,alu1")
3912 (set_attr "mode" "SI")])
3914 (define_insn "*zero_extendqisi2_movzbl"
3915 [(set (match_operand:SI 0 "register_operand" "=r")
3916 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3917 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3918 && reload_completed"
3919 "movz{bl|x}\t{%1, %0|%0, %1}"
3920 [(set_attr "type" "imovx")
3921 (set_attr "mode" "SI")])
3923 ;; For the movzbl case strip only the clobber
3925 [(set (match_operand:SI 0 "register_operand" "")
3926 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3927 (clobber (reg:CC FLAGS_REG))]
3929 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3930 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3932 (zero_extend:SI (match_dup 1)))])
3934 ;; When source and destination does not overlap, clear destination
3935 ;; first and then do the movb
3937 [(set (match_operand:SI 0 "register_operand" "")
3938 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3939 (clobber (reg:CC FLAGS_REG))]
3941 && ANY_QI_REG_P (operands[0])
3942 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3943 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3944 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3945 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3947 operands[2] = gen_lowpart (QImode, operands[0]);
3948 ix86_expand_clear (operands[0]);
3951 ;; Rest is handled by single and.
3953 [(set (match_operand:SI 0 "register_operand" "")
3954 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3955 (clobber (reg:CC FLAGS_REG))]
3957 && true_regnum (operands[0]) == true_regnum (operands[1])"
3958 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3959 (clobber (reg:CC FLAGS_REG))])]
3962 ;; %%% Kill me once multi-word ops are sane.
3963 (define_expand "zero_extendsidi2"
3964 [(set (match_operand:DI 0 "register_operand" "")
3965 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3970 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3975 (define_insn "zero_extendsidi2_32"
3976 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3978 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3979 (clobber (reg:CC FLAGS_REG))]
3985 movd\t{%1, %0|%0, %1}
3986 movd\t{%1, %0|%0, %1}
3987 %vmovd\t{%1, %0|%0, %1}
3988 %vmovd\t{%1, %0|%0, %1}"
3989 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3990 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3991 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3993 (define_insn "zero_extendsidi2_rex64"
3994 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3996 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
3999 mov\t{%k1, %k0|%k0, %k1}
4001 movd\t{%1, %0|%0, %1}
4002 movd\t{%1, %0|%0, %1}
4003 %vmovd\t{%1, %0|%0, %1}
4004 %vmovd\t{%1, %0|%0, %1}"
4005 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4006 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4007 (set_attr "prefix_0f" "0,*,*,*,*,*")
4008 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4011 [(set (match_operand:DI 0 "memory_operand" "")
4012 (zero_extend:DI (match_dup 0)))]
4014 [(set (match_dup 4) (const_int 0))]
4015 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4018 [(set (match_operand:DI 0 "register_operand" "")
4019 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4020 (clobber (reg:CC FLAGS_REG))]
4021 "!TARGET_64BIT && reload_completed
4022 && true_regnum (operands[0]) == true_regnum (operands[1])"
4023 [(set (match_dup 4) (const_int 0))]
4024 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4027 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4028 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4029 (clobber (reg:CC FLAGS_REG))]
4030 "!TARGET_64BIT && reload_completed
4031 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4032 [(set (match_dup 3) (match_dup 1))
4033 (set (match_dup 4) (const_int 0))]
4034 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4036 (define_insn "zero_extendhidi2"
4037 [(set (match_operand:DI 0 "register_operand" "=r")
4038 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4040 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4041 [(set_attr "type" "imovx")
4042 (set_attr "mode" "SI")])
4044 (define_insn "zero_extendqidi2"
4045 [(set (match_operand:DI 0 "register_operand" "=r")
4046 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4048 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4049 [(set_attr "type" "imovx")
4050 (set_attr "mode" "SI")])
4052 ;; Sign extension instructions
4054 (define_expand "extendsidi2"
4055 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4056 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4057 (clobber (reg:CC FLAGS_REG))
4058 (clobber (match_scratch:SI 2 ""))])]
4063 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4068 (define_insn "*extendsidi2_1"
4069 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4070 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4071 (clobber (reg:CC FLAGS_REG))
4072 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4076 (define_insn "extendsidi2_rex64"
4077 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4078 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4082 movs{lq|x}\t{%1, %0|%0, %1}"
4083 [(set_attr "type" "imovx")
4084 (set_attr "mode" "DI")
4085 (set_attr "prefix_0f" "0")
4086 (set_attr "modrm" "0,1")])
4088 (define_insn "extendhidi2"
4089 [(set (match_operand:DI 0 "register_operand" "=r")
4090 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4092 "movs{wq|x}\t{%1, %0|%0, %1}"
4093 [(set_attr "type" "imovx")
4094 (set_attr "mode" "DI")])
4096 (define_insn "extendqidi2"
4097 [(set (match_operand:DI 0 "register_operand" "=r")
4098 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4100 "movs{bq|x}\t{%1, %0|%0, %1}"
4101 [(set_attr "type" "imovx")
4102 (set_attr "mode" "DI")])
4104 ;; Extend to memory case when source register does die.
4106 [(set (match_operand:DI 0 "memory_operand" "")
4107 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4108 (clobber (reg:CC FLAGS_REG))
4109 (clobber (match_operand:SI 2 "register_operand" ""))]
4111 && dead_or_set_p (insn, operands[1])
4112 && !reg_mentioned_p (operands[1], operands[0]))"
4113 [(set (match_dup 3) (match_dup 1))
4114 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4115 (clobber (reg:CC FLAGS_REG))])
4116 (set (match_dup 4) (match_dup 1))]
4117 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4119 ;; Extend to memory case when source register does not die.
4121 [(set (match_operand:DI 0 "memory_operand" "")
4122 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4123 (clobber (reg:CC FLAGS_REG))
4124 (clobber (match_operand:SI 2 "register_operand" ""))]
4128 split_di (&operands[0], 1, &operands[3], &operands[4]);
4130 emit_move_insn (operands[3], operands[1]);
4132 /* Generate a cltd if possible and doing so it profitable. */
4133 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4134 && true_regnum (operands[1]) == AX_REG
4135 && true_regnum (operands[2]) == DX_REG)
4137 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4141 emit_move_insn (operands[2], operands[1]);
4142 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4144 emit_move_insn (operands[4], operands[2]);
4148 ;; Extend to register case. Optimize case where source and destination
4149 ;; registers match and cases where we can use cltd.
4151 [(set (match_operand:DI 0 "register_operand" "")
4152 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4153 (clobber (reg:CC FLAGS_REG))
4154 (clobber (match_scratch:SI 2 ""))]
4158 split_di (&operands[0], 1, &operands[3], &operands[4]);
4160 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4161 emit_move_insn (operands[3], operands[1]);
4163 /* Generate a cltd if possible and doing so it profitable. */
4164 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4165 && true_regnum (operands[3]) == AX_REG)
4167 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4171 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4172 emit_move_insn (operands[4], operands[1]);
4174 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4178 (define_insn "extendhisi2"
4179 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4180 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4183 switch (get_attr_prefix_0f (insn))
4186 return "{cwtl|cwde}";
4188 return "movs{wl|x}\t{%1, %0|%0, %1}";
4191 [(set_attr "type" "imovx")
4192 (set_attr "mode" "SI")
4193 (set (attr "prefix_0f")
4194 ;; movsx is short decodable while cwtl is vector decoded.
4195 (if_then_else (and (eq_attr "cpu" "!k6")
4196 (eq_attr "alternative" "0"))
4198 (const_string "1")))
4200 (if_then_else (eq_attr "prefix_0f" "0")
4202 (const_string "1")))])
4204 (define_insn "*extendhisi2_zext"
4205 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4207 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4210 switch (get_attr_prefix_0f (insn))
4213 return "{cwtl|cwde}";
4215 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4218 [(set_attr "type" "imovx")
4219 (set_attr "mode" "SI")
4220 (set (attr "prefix_0f")
4221 ;; movsx is short decodable while cwtl is vector decoded.
4222 (if_then_else (and (eq_attr "cpu" "!k6")
4223 (eq_attr "alternative" "0"))
4225 (const_string "1")))
4227 (if_then_else (eq_attr "prefix_0f" "0")
4229 (const_string "1")))])
4231 (define_insn "extendqihi2"
4232 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4233 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4236 switch (get_attr_prefix_0f (insn))
4239 return "{cbtw|cbw}";
4241 return "movs{bw|x}\t{%1, %0|%0, %1}";
4244 [(set_attr "type" "imovx")
4245 (set_attr "mode" "HI")
4246 (set (attr "prefix_0f")
4247 ;; movsx is short decodable while cwtl is vector decoded.
4248 (if_then_else (and (eq_attr "cpu" "!k6")
4249 (eq_attr "alternative" "0"))
4251 (const_string "1")))
4253 (if_then_else (eq_attr "prefix_0f" "0")
4255 (const_string "1")))])
4257 (define_insn "extendqisi2"
4258 [(set (match_operand:SI 0 "register_operand" "=r")
4259 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4261 "movs{bl|x}\t{%1, %0|%0, %1}"
4262 [(set_attr "type" "imovx")
4263 (set_attr "mode" "SI")])
4265 (define_insn "*extendqisi2_zext"
4266 [(set (match_operand:DI 0 "register_operand" "=r")
4268 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4270 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4271 [(set_attr "type" "imovx")
4272 (set_attr "mode" "SI")])
4274 ;; Conversions between float and double.
4276 ;; These are all no-ops in the model used for the 80387. So just
4279 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4280 (define_insn "*dummy_extendsfdf2"
4281 [(set (match_operand:DF 0 "push_operand" "=<")
4282 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4287 [(set (match_operand:DF 0 "push_operand" "")
4288 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4290 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4291 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4293 (define_insn "*dummy_extendsfxf2"
4294 [(set (match_operand:XF 0 "push_operand" "=<")
4295 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4300 [(set (match_operand:XF 0 "push_operand" "")
4301 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4303 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4304 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4305 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4308 [(set (match_operand:XF 0 "push_operand" "")
4309 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4311 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4312 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4313 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4315 (define_expand "extendsfdf2"
4316 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4317 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4318 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4320 /* ??? Needed for compress_float_constant since all fp constants
4321 are LEGITIMATE_CONSTANT_P. */
4322 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4324 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4325 && standard_80387_constant_p (operands[1]) > 0)
4327 operands[1] = simplify_const_unary_operation
4328 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4329 emit_move_insn_1 (operands[0], operands[1]);
4332 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4336 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4338 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4340 We do the conversion post reload to avoid producing of 128bit spills
4341 that might lead to ICE on 32bit target. The sequence unlikely combine
4344 [(set (match_operand:DF 0 "register_operand" "")
4346 (match_operand:SF 1 "nonimmediate_operand" "")))]
4347 "TARGET_USE_VECTOR_FP_CONVERTS
4348 && optimize_insn_for_speed_p ()
4349 && reload_completed && SSE_REG_P (operands[0])"
4354 (parallel [(const_int 0) (const_int 1)]))))]
4356 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4357 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4358 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4359 Try to avoid move when unpacking can be done in source. */
4360 if (REG_P (operands[1]))
4362 /* If it is unsafe to overwrite upper half of source, we need
4363 to move to destination and unpack there. */
4364 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4365 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4366 && true_regnum (operands[0]) != true_regnum (operands[1]))
4368 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4369 emit_move_insn (tmp, operands[1]);
4372 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4373 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4376 emit_insn (gen_vec_setv4sf_0 (operands[3],
4377 CONST0_RTX (V4SFmode), operands[1]));
4380 (define_insn "*extendsfdf2_mixed"
4381 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4383 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4384 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4386 switch (which_alternative)
4390 return output_387_reg_move (insn, operands);
4393 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4399 [(set_attr "type" "fmov,fmov,ssecvt")
4400 (set_attr "prefix" "orig,orig,maybe_vex")
4401 (set_attr "mode" "SF,XF,DF")])
4403 (define_insn "*extendsfdf2_sse"
4404 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4405 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4406 "TARGET_SSE2 && TARGET_SSE_MATH"
4407 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4408 [(set_attr "type" "ssecvt")
4409 (set_attr "prefix" "maybe_vex")
4410 (set_attr "mode" "DF")])
4412 (define_insn "*extendsfdf2_i387"
4413 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4414 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4416 "* return output_387_reg_move (insn, operands);"
4417 [(set_attr "type" "fmov")
4418 (set_attr "mode" "SF,XF")])
4420 (define_expand "extend<mode>xf2"
4421 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4422 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4425 /* ??? Needed for compress_float_constant since all fp constants
4426 are LEGITIMATE_CONSTANT_P. */
4427 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4429 if (standard_80387_constant_p (operands[1]) > 0)
4431 operands[1] = simplify_const_unary_operation
4432 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4433 emit_move_insn_1 (operands[0], operands[1]);
4436 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4440 (define_insn "*extend<mode>xf2_i387"
4441 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4443 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4445 "* return output_387_reg_move (insn, operands);"
4446 [(set_attr "type" "fmov")
4447 (set_attr "mode" "<MODE>,XF")])
4449 ;; %%% This seems bad bad news.
4450 ;; This cannot output into an f-reg because there is no way to be sure
4451 ;; of truncating in that case. Otherwise this is just like a simple move
4452 ;; insn. So we pretend we can output to a reg in order to get better
4453 ;; register preferencing, but we really use a stack slot.
4455 ;; Conversion from DFmode to SFmode.
4457 (define_expand "truncdfsf2"
4458 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4460 (match_operand:DF 1 "nonimmediate_operand" "")))]
4461 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4463 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4465 else if (flag_unsafe_math_optimizations)
4469 enum ix86_stack_slot slot = (virtuals_instantiated
4472 rtx temp = assign_386_stack_local (SFmode, slot);
4473 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4478 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4480 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4482 We do the conversion post reload to avoid producing of 128bit spills
4483 that might lead to ICE on 32bit target. The sequence unlikely combine
4486 [(set (match_operand:SF 0 "register_operand" "")
4488 (match_operand:DF 1 "nonimmediate_operand" "")))]
4489 "TARGET_USE_VECTOR_FP_CONVERTS
4490 && optimize_insn_for_speed_p ()
4491 && reload_completed && SSE_REG_P (operands[0])"
4494 (float_truncate:V2SF
4498 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4499 operands[3] = CONST0_RTX (V2SFmode);
4500 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4501 /* Use movsd for loading from memory, unpcklpd for registers.
4502 Try to avoid move when unpacking can be done in source, or SSE3
4503 movddup is available. */
4504 if (REG_P (operands[1]))
4507 && true_regnum (operands[0]) != true_regnum (operands[1])
4508 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4509 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4511 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4512 emit_move_insn (tmp, operands[1]);
4515 else if (!TARGET_SSE3)
4516 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4517 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4520 emit_insn (gen_sse2_loadlpd (operands[4],
4521 CONST0_RTX (V2DFmode), operands[1]));
4524 (define_expand "truncdfsf2_with_temp"
4525 [(parallel [(set (match_operand:SF 0 "" "")
4526 (float_truncate:SF (match_operand:DF 1 "" "")))
4527 (clobber (match_operand:SF 2 "" ""))])]
4530 (define_insn "*truncdfsf_fast_mixed"
4531 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4533 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4534 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4536 switch (which_alternative)
4539 return output_387_reg_move (insn, operands);
4541 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4546 [(set_attr "type" "fmov,ssecvt")
4547 (set_attr "prefix" "orig,maybe_vex")
4548 (set_attr "mode" "SF")])
4550 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4551 ;; because nothing we do here is unsafe.
4552 (define_insn "*truncdfsf_fast_sse"
4553 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4555 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4556 "TARGET_SSE2 && TARGET_SSE_MATH"
4557 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4558 [(set_attr "type" "ssecvt")
4559 (set_attr "prefix" "maybe_vex")
4560 (set_attr "mode" "SF")])
4562 (define_insn "*truncdfsf_fast_i387"
4563 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4565 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4566 "TARGET_80387 && flag_unsafe_math_optimizations"
4567 "* return output_387_reg_move (insn, operands);"
4568 [(set_attr "type" "fmov")
4569 (set_attr "mode" "SF")])
4571 (define_insn "*truncdfsf_mixed"
4572 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4574 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4575 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4576 "TARGET_MIX_SSE_I387"
4578 switch (which_alternative)
4581 return output_387_reg_move (insn, operands);
4583 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4589 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4590 (set_attr "unit" "*,*,i387,i387,i387")
4591 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4592 (set_attr "mode" "SF")])
4594 (define_insn "*truncdfsf_i387"
4595 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4597 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4598 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4601 switch (which_alternative)
4604 return output_387_reg_move (insn, operands);
4610 [(set_attr "type" "fmov,multi,multi,multi")
4611 (set_attr "unit" "*,i387,i387,i387")
4612 (set_attr "mode" "SF")])
4614 (define_insn "*truncdfsf2_i387_1"
4615 [(set (match_operand:SF 0 "memory_operand" "=m")
4617 (match_operand:DF 1 "register_operand" "f")))]
4619 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4620 && !TARGET_MIX_SSE_I387"
4621 "* return output_387_reg_move (insn, operands);"
4622 [(set_attr "type" "fmov")
4623 (set_attr "mode" "SF")])
4626 [(set (match_operand:SF 0 "register_operand" "")
4628 (match_operand:DF 1 "fp_register_operand" "")))
4629 (clobber (match_operand 2 "" ""))]
4631 [(set (match_dup 2) (match_dup 1))
4632 (set (match_dup 0) (match_dup 2))]
4634 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4637 ;; Conversion from XFmode to {SF,DF}mode
4639 (define_expand "truncxf<mode>2"
4640 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4641 (float_truncate:MODEF
4642 (match_operand:XF 1 "register_operand" "")))
4643 (clobber (match_dup 2))])]
4646 if (flag_unsafe_math_optimizations)
4648 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4649 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4650 if (reg != operands[0])
4651 emit_move_insn (operands[0], reg);
4656 enum ix86_stack_slot slot = (virtuals_instantiated
4659 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4663 (define_insn "*truncxfsf2_mixed"
4664 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4666 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4667 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4670 gcc_assert (!which_alternative);
4671 return output_387_reg_move (insn, operands);
4673 [(set_attr "type" "fmov,multi,multi,multi")
4674 (set_attr "unit" "*,i387,i387,i387")
4675 (set_attr "mode" "SF")])
4677 (define_insn "*truncxfdf2_mixed"
4678 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4680 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4681 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4684 gcc_assert (!which_alternative);
4685 return output_387_reg_move (insn, operands);
4687 [(set_attr "type" "fmov,multi,multi,multi")
4688 (set_attr "unit" "*,i387,i387,i387")
4689 (set_attr "mode" "DF")])
4691 (define_insn "truncxf<mode>2_i387_noop"
4692 [(set (match_operand:MODEF 0 "register_operand" "=f")
4693 (float_truncate:MODEF
4694 (match_operand:XF 1 "register_operand" "f")))]
4695 "TARGET_80387 && flag_unsafe_math_optimizations"
4696 "* return output_387_reg_move (insn, operands);"
4697 [(set_attr "type" "fmov")
4698 (set_attr "mode" "<MODE>")])
4700 (define_insn "*truncxf<mode>2_i387"
4701 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4702 (float_truncate:MODEF
4703 (match_operand:XF 1 "register_operand" "f")))]
4705 "* return output_387_reg_move (insn, operands);"
4706 [(set_attr "type" "fmov")
4707 (set_attr "mode" "<MODE>")])
4710 [(set (match_operand:MODEF 0 "register_operand" "")
4711 (float_truncate:MODEF
4712 (match_operand:XF 1 "register_operand" "")))
4713 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4714 "TARGET_80387 && reload_completed"
4715 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4716 (set (match_dup 0) (match_dup 2))]
4720 [(set (match_operand:MODEF 0 "memory_operand" "")
4721 (float_truncate:MODEF
4722 (match_operand:XF 1 "register_operand" "")))
4723 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4725 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4728 ;; Signed conversion to DImode.
4730 (define_expand "fix_truncxfdi2"
4731 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4732 (fix:DI (match_operand:XF 1 "register_operand" "")))
4733 (clobber (reg:CC FLAGS_REG))])]
4738 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4743 (define_expand "fix_trunc<mode>di2"
4744 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4745 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4746 (clobber (reg:CC FLAGS_REG))])]
4747 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4750 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4752 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4755 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4757 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4758 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4759 if (out != operands[0])
4760 emit_move_insn (operands[0], out);
4765 ;; Signed conversion to SImode.
4767 (define_expand "fix_truncxfsi2"
4768 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4769 (fix:SI (match_operand:XF 1 "register_operand" "")))
4770 (clobber (reg:CC FLAGS_REG))])]
4775 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4780 (define_expand "fix_trunc<mode>si2"
4781 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4782 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4783 (clobber (reg:CC FLAGS_REG))])]
4784 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4787 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4789 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4792 if (SSE_FLOAT_MODE_P (<MODE>mode))
4794 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4795 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4796 if (out != operands[0])
4797 emit_move_insn (operands[0], out);
4802 ;; Signed conversion to HImode.
4804 (define_expand "fix_trunc<mode>hi2"
4805 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4806 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4807 (clobber (reg:CC FLAGS_REG))])]
4809 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4813 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4818 ;; Unsigned conversion to SImode.
4820 (define_expand "fixuns_trunc<mode>si2"
4822 [(set (match_operand:SI 0 "register_operand" "")
4824 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4826 (clobber (match_scratch:<ssevecmode> 3 ""))
4827 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4828 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4830 enum machine_mode mode = <MODE>mode;
4831 enum machine_mode vecmode = <ssevecmode>mode;
4832 REAL_VALUE_TYPE TWO31r;
4835 if (optimize_insn_for_size_p ())
4838 real_ldexp (&TWO31r, &dconst1, 31);
4839 two31 = const_double_from_real_value (TWO31r, mode);
4840 two31 = ix86_build_const_vector (mode, true, two31);
4841 operands[2] = force_reg (vecmode, two31);
4844 (define_insn_and_split "*fixuns_trunc<mode>_1"
4845 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4847 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4848 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4849 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4850 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4851 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4852 && optimize_function_for_speed_p (cfun)"
4854 "&& reload_completed"
4857 ix86_split_convert_uns_si_sse (operands);
4861 ;; Unsigned conversion to HImode.
4862 ;; Without these patterns, we'll try the unsigned SI conversion which
4863 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4865 (define_expand "fixuns_trunc<mode>hi2"
4867 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4868 (set (match_operand:HI 0 "nonimmediate_operand" "")
4869 (subreg:HI (match_dup 2) 0))]
4870 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4871 "operands[2] = gen_reg_rtx (SImode);")
4873 ;; When SSE is available, it is always faster to use it!
4874 (define_insn "fix_trunc<mode>di_sse"
4875 [(set (match_operand:DI 0 "register_operand" "=r,r")
4876 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4877 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4878 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4879 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4880 [(set_attr "type" "sseicvt")
4881 (set_attr "prefix" "maybe_vex")
4882 (set_attr "prefix_rex" "1")
4883 (set_attr "mode" "<MODE>")
4884 (set_attr "athlon_decode" "double,vector")
4885 (set_attr "amdfam10_decode" "double,double")])
4887 (define_insn "fix_trunc<mode>si_sse"
4888 [(set (match_operand:SI 0 "register_operand" "=r,r")
4889 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4890 "SSE_FLOAT_MODE_P (<MODE>mode)
4891 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4892 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4893 [(set_attr "type" "sseicvt")
4894 (set_attr "prefix" "maybe_vex")
4895 (set_attr "mode" "<MODE>")
4896 (set_attr "athlon_decode" "double,vector")
4897 (set_attr "amdfam10_decode" "double,double")])
4899 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4901 [(set (match_operand:MODEF 0 "register_operand" "")
4902 (match_operand:MODEF 1 "memory_operand" ""))
4903 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4904 (fix:SSEMODEI24 (match_dup 0)))]
4905 "TARGET_SHORTEN_X87_SSE
4906 && peep2_reg_dead_p (2, operands[0])"
4907 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4910 ;; Avoid vector decoded forms of the instruction.
4912 [(match_scratch:DF 2 "Y2")
4913 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4914 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4915 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4916 [(set (match_dup 2) (match_dup 1))
4917 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4921 [(match_scratch:SF 2 "x")
4922 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4923 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4924 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4925 [(set (match_dup 2) (match_dup 1))
4926 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4929 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4930 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4931 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4932 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4934 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4935 && (TARGET_64BIT || <MODE>mode != DImode))
4937 && can_create_pseudo_p ()"
4942 if (memory_operand (operands[0], VOIDmode))
4943 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4946 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4947 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4953 [(set_attr "type" "fisttp")
4954 (set_attr "mode" "<MODE>")])
4956 (define_insn "fix_trunc<mode>_i387_fisttp"
4957 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4958 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4959 (clobber (match_scratch:XF 2 "=&1f"))]
4960 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4962 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4963 && (TARGET_64BIT || <MODE>mode != DImode))
4964 && TARGET_SSE_MATH)"
4965 "* return output_fix_trunc (insn, operands, 1);"
4966 [(set_attr "type" "fisttp")
4967 (set_attr "mode" "<MODE>")])
4969 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4970 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4971 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4972 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4973 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4974 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4976 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4977 && (TARGET_64BIT || <MODE>mode != DImode))
4978 && TARGET_SSE_MATH)"
4980 [(set_attr "type" "fisttp")
4981 (set_attr "mode" "<MODE>")])
4984 [(set (match_operand:X87MODEI 0 "register_operand" "")
4985 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4986 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4987 (clobber (match_scratch 3 ""))]
4989 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4990 (clobber (match_dup 3))])
4991 (set (match_dup 0) (match_dup 2))]
4995 [(set (match_operand:X87MODEI 0 "memory_operand" "")
4996 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4997 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4998 (clobber (match_scratch 3 ""))]
5000 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5001 (clobber (match_dup 3))])]
5004 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5005 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5006 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5007 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5008 ;; function in i386.c.
5009 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5010 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5011 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5012 (clobber (reg:CC FLAGS_REG))]
5013 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5015 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5016 && (TARGET_64BIT || <MODE>mode != DImode))
5017 && can_create_pseudo_p ()"
5022 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5024 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5025 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5026 if (memory_operand (operands[0], VOIDmode))
5027 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5028 operands[2], operands[3]));
5031 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5032 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5033 operands[2], operands[3],
5038 [(set_attr "type" "fistp")
5039 (set_attr "i387_cw" "trunc")
5040 (set_attr "mode" "<MODE>")])
5042 (define_insn "fix_truncdi_i387"
5043 [(set (match_operand:DI 0 "memory_operand" "=m")
5044 (fix:DI (match_operand 1 "register_operand" "f")))
5045 (use (match_operand:HI 2 "memory_operand" "m"))
5046 (use (match_operand:HI 3 "memory_operand" "m"))
5047 (clobber (match_scratch:XF 4 "=&1f"))]
5048 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5050 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5051 "* return output_fix_trunc (insn, operands, 0);"
5052 [(set_attr "type" "fistp")
5053 (set_attr "i387_cw" "trunc")
5054 (set_attr "mode" "DI")])
5056 (define_insn "fix_truncdi_i387_with_temp"
5057 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5058 (fix:DI (match_operand 1 "register_operand" "f,f")))
5059 (use (match_operand:HI 2 "memory_operand" "m,m"))
5060 (use (match_operand:HI 3 "memory_operand" "m,m"))
5061 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5062 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5063 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5065 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5067 [(set_attr "type" "fistp")
5068 (set_attr "i387_cw" "trunc")
5069 (set_attr "mode" "DI")])
5072 [(set (match_operand:DI 0 "register_operand" "")
5073 (fix:DI (match_operand 1 "register_operand" "")))
5074 (use (match_operand:HI 2 "memory_operand" ""))
5075 (use (match_operand:HI 3 "memory_operand" ""))
5076 (clobber (match_operand:DI 4 "memory_operand" ""))
5077 (clobber (match_scratch 5 ""))]
5079 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5082 (clobber (match_dup 5))])
5083 (set (match_dup 0) (match_dup 4))]
5087 [(set (match_operand:DI 0 "memory_operand" "")
5088 (fix:DI (match_operand 1 "register_operand" "")))
5089 (use (match_operand:HI 2 "memory_operand" ""))
5090 (use (match_operand:HI 3 "memory_operand" ""))
5091 (clobber (match_operand:DI 4 "memory_operand" ""))
5092 (clobber (match_scratch 5 ""))]
5094 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5097 (clobber (match_dup 5))])]
5100 (define_insn "fix_trunc<mode>_i387"
5101 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5102 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5103 (use (match_operand:HI 2 "memory_operand" "m"))
5104 (use (match_operand:HI 3 "memory_operand" "m"))]
5105 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5107 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5108 "* return output_fix_trunc (insn, operands, 0);"
5109 [(set_attr "type" "fistp")
5110 (set_attr "i387_cw" "trunc")
5111 (set_attr "mode" "<MODE>")])
5113 (define_insn "fix_trunc<mode>_i387_with_temp"
5114 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5115 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5116 (use (match_operand:HI 2 "memory_operand" "m,m"))
5117 (use (match_operand:HI 3 "memory_operand" "m,m"))
5118 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5119 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5121 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5123 [(set_attr "type" "fistp")
5124 (set_attr "i387_cw" "trunc")
5125 (set_attr "mode" "<MODE>")])
5128 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5129 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5130 (use (match_operand:HI 2 "memory_operand" ""))
5131 (use (match_operand:HI 3 "memory_operand" ""))
5132 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5134 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5136 (use (match_dup 3))])
5137 (set (match_dup 0) (match_dup 4))]
5141 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5142 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5143 (use (match_operand:HI 2 "memory_operand" ""))
5144 (use (match_operand:HI 3 "memory_operand" ""))
5145 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5147 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5149 (use (match_dup 3))])]
5152 (define_insn "x86_fnstcw_1"
5153 [(set (match_operand:HI 0 "memory_operand" "=m")
5154 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5157 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5158 (set_attr "mode" "HI")
5159 (set_attr "unit" "i387")])
5161 (define_insn "x86_fldcw_1"
5162 [(set (reg:HI FPCR_REG)
5163 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5166 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5167 (set_attr "mode" "HI")
5168 (set_attr "unit" "i387")
5169 (set_attr "athlon_decode" "vector")
5170 (set_attr "amdfam10_decode" "vector")])
5172 ;; Conversion between fixed point and floating point.
5174 ;; Even though we only accept memory inputs, the backend _really_
5175 ;; wants to be able to do this between registers.
5177 (define_expand "floathi<mode>2"
5178 [(set (match_operand:X87MODEF 0 "register_operand" "")
5179 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5182 || TARGET_MIX_SSE_I387)"
5185 ;; Pre-reload splitter to add memory clobber to the pattern.
5186 (define_insn_and_split "*floathi<mode>2_1"
5187 [(set (match_operand:X87MODEF 0 "register_operand" "")
5188 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5190 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5191 || TARGET_MIX_SSE_I387)
5192 && can_create_pseudo_p ()"
5195 [(parallel [(set (match_dup 0)
5196 (float:X87MODEF (match_dup 1)))
5197 (clobber (match_dup 2))])]
5198 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5200 (define_insn "*floathi<mode>2_i387_with_temp"
5201 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5202 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5203 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5205 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5206 || TARGET_MIX_SSE_I387)"
5208 [(set_attr "type" "fmov,multi")
5209 (set_attr "mode" "<MODE>")
5210 (set_attr "unit" "*,i387")
5211 (set_attr "fp_int_src" "true")])
5213 (define_insn "*floathi<mode>2_i387"
5214 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5215 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5217 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5218 || TARGET_MIX_SSE_I387)"
5220 [(set_attr "type" "fmov")
5221 (set_attr "mode" "<MODE>")
5222 (set_attr "fp_int_src" "true")])
5225 [(set (match_operand:X87MODEF 0 "register_operand" "")
5226 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5227 (clobber (match_operand:HI 2 "memory_operand" ""))]
5229 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5230 || TARGET_MIX_SSE_I387)
5231 && reload_completed"
5232 [(set (match_dup 2) (match_dup 1))
5233 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5237 [(set (match_operand:X87MODEF 0 "register_operand" "")
5238 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5239 (clobber (match_operand:HI 2 "memory_operand" ""))]
5241 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5242 || TARGET_MIX_SSE_I387)
5243 && reload_completed"
5244 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5247 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5248 [(set (match_operand:X87MODEF 0 "register_operand" "")
5250 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5252 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5253 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5256 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5257 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5258 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5260 rtx reg = gen_reg_rtx (XFmode);
5263 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5265 if (<X87MODEF:MODE>mode == SFmode)
5266 insn = gen_truncxfsf2 (operands[0], reg);
5267 else if (<X87MODEF:MODE>mode == DFmode)
5268 insn = gen_truncxfdf2 (operands[0], reg);
5277 ;; Pre-reload splitter to add memory clobber to the pattern.
5278 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5279 [(set (match_operand:X87MODEF 0 "register_operand" "")
5280 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5282 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5283 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5284 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5285 || TARGET_MIX_SSE_I387))
5286 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5287 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5288 && ((<SSEMODEI24:MODE>mode == SImode
5289 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5290 && optimize_function_for_speed_p (cfun)
5291 && flag_trapping_math)
5292 || !(TARGET_INTER_UNIT_CONVERSIONS
5293 || optimize_function_for_size_p (cfun)))))
5294 && can_create_pseudo_p ()"
5297 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5298 (clobber (match_dup 2))])]
5300 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5302 /* Avoid store forwarding (partial memory) stall penalty
5303 by passing DImode value through XMM registers. */
5304 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5305 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5306 && optimize_function_for_speed_p (cfun))
5308 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5315 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5316 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5318 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5319 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5320 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5321 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5323 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5324 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5325 (set_attr "unit" "*,i387,*,*,*")
5326 (set_attr "athlon_decode" "*,*,double,direct,double")
5327 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5328 (set_attr "fp_int_src" "true")])
5330 (define_insn "*floatsi<mode>2_vector_mixed"
5331 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5332 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5333 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5334 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5338 [(set_attr "type" "fmov,sseicvt")
5339 (set_attr "mode" "<MODE>,<ssevecmode>")
5340 (set_attr "unit" "i387,*")
5341 (set_attr "athlon_decode" "*,direct")
5342 (set_attr "amdfam10_decode" "*,double")
5343 (set_attr "fp_int_src" "true")])
5345 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5346 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5348 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5349 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5350 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5351 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5353 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5354 (set_attr "mode" "<MODEF:MODE>")
5355 (set_attr "unit" "*,i387,*,*")
5356 (set_attr "athlon_decode" "*,*,double,direct")
5357 (set_attr "amdfam10_decode" "*,*,vector,double")
5358 (set_attr "fp_int_src" "true")])
5361 [(set (match_operand:MODEF 0 "register_operand" "")
5362 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5363 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5364 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5365 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5366 && TARGET_INTER_UNIT_CONVERSIONS
5368 && (SSE_REG_P (operands[0])
5369 || (GET_CODE (operands[0]) == SUBREG
5370 && SSE_REG_P (operands[0])))"
5371 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5375 [(set (match_operand:MODEF 0 "register_operand" "")
5376 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5377 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5378 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5379 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5380 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5382 && (SSE_REG_P (operands[0])
5383 || (GET_CODE (operands[0]) == SUBREG
5384 && SSE_REG_P (operands[0])))"
5385 [(set (match_dup 2) (match_dup 1))
5386 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5389 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5390 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5392 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5393 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5394 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5395 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5398 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5399 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5400 [(set_attr "type" "fmov,sseicvt,sseicvt")
5401 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5402 (set_attr "mode" "<MODEF:MODE>")
5403 (set (attr "prefix_rex")
5405 (and (eq_attr "prefix" "maybe_vex")
5406 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5408 (const_string "*")))
5409 (set_attr "unit" "i387,*,*")
5410 (set_attr "athlon_decode" "*,double,direct")
5411 (set_attr "amdfam10_decode" "*,vector,double")
5412 (set_attr "fp_int_src" "true")])
5414 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5415 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5417 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5418 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5419 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5420 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5423 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5424 [(set_attr "type" "fmov,sseicvt")
5425 (set_attr "prefix" "orig,maybe_vex")
5426 (set_attr "mode" "<MODEF:MODE>")
5427 (set (attr "prefix_rex")
5429 (and (eq_attr "prefix" "maybe_vex")
5430 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5432 (const_string "*")))
5433 (set_attr "athlon_decode" "*,direct")
5434 (set_attr "amdfam10_decode" "*,double")
5435 (set_attr "fp_int_src" "true")])
5437 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5438 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5440 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5441 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5442 "TARGET_SSE2 && TARGET_SSE_MATH
5443 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5445 [(set_attr "type" "sseicvt")
5446 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5447 (set_attr "athlon_decode" "double,direct,double")
5448 (set_attr "amdfam10_decode" "vector,double,double")
5449 (set_attr "fp_int_src" "true")])
5451 (define_insn "*floatsi<mode>2_vector_sse"
5452 [(set (match_operand:MODEF 0 "register_operand" "=x")
5453 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5454 "TARGET_SSE2 && TARGET_SSE_MATH
5455 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5457 [(set_attr "type" "sseicvt")
5458 (set_attr "mode" "<MODE>")
5459 (set_attr "athlon_decode" "direct")
5460 (set_attr "amdfam10_decode" "double")
5461 (set_attr "fp_int_src" "true")])
5464 [(set (match_operand:MODEF 0 "register_operand" "")
5465 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5466 (clobber (match_operand:SI 2 "memory_operand" ""))]
5467 "TARGET_SSE2 && TARGET_SSE_MATH
5468 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5470 && (SSE_REG_P (operands[0])
5471 || (GET_CODE (operands[0]) == SUBREG
5472 && SSE_REG_P (operands[0])))"
5475 rtx op1 = operands[1];
5477 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5479 if (GET_CODE (op1) == SUBREG)
5480 op1 = SUBREG_REG (op1);
5482 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5484 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5485 emit_insn (gen_sse2_loadld (operands[4],
5486 CONST0_RTX (V4SImode), operands[1]));
5488 /* We can ignore possible trapping value in the
5489 high part of SSE register for non-trapping math. */
5490 else if (SSE_REG_P (op1) && !flag_trapping_math)
5491 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5494 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5495 emit_move_insn (operands[2], operands[1]);
5496 emit_insn (gen_sse2_loadld (operands[4],
5497 CONST0_RTX (V4SImode), operands[2]));
5500 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5505 [(set (match_operand:MODEF 0 "register_operand" "")
5506 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5507 (clobber (match_operand:SI 2 "memory_operand" ""))]
5508 "TARGET_SSE2 && TARGET_SSE_MATH
5509 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5511 && (SSE_REG_P (operands[0])
5512 || (GET_CODE (operands[0]) == SUBREG
5513 && SSE_REG_P (operands[0])))"
5516 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5518 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5520 emit_insn (gen_sse2_loadld (operands[4],
5521 CONST0_RTX (V4SImode), operands[1]));
5523 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5528 [(set (match_operand:MODEF 0 "register_operand" "")
5529 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5530 "TARGET_SSE2 && TARGET_SSE_MATH
5531 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5533 && (SSE_REG_P (operands[0])
5534 || (GET_CODE (operands[0]) == SUBREG
5535 && SSE_REG_P (operands[0])))"
5538 rtx op1 = operands[1];
5540 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5542 if (GET_CODE (op1) == SUBREG)
5543 op1 = SUBREG_REG (op1);
5545 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5547 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5548 emit_insn (gen_sse2_loadld (operands[4],
5549 CONST0_RTX (V4SImode), operands[1]));
5551 /* We can ignore possible trapping value in the
5552 high part of SSE register for non-trapping math. */
5553 else if (SSE_REG_P (op1) && !flag_trapping_math)
5554 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5558 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5563 [(set (match_operand:MODEF 0 "register_operand" "")
5564 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5565 "TARGET_SSE2 && TARGET_SSE_MATH
5566 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5568 && (SSE_REG_P (operands[0])
5569 || (GET_CODE (operands[0]) == SUBREG
5570 && SSE_REG_P (operands[0])))"
5573 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5575 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5577 emit_insn (gen_sse2_loadld (operands[4],
5578 CONST0_RTX (V4SImode), operands[1]));
5580 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5584 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5585 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5587 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5588 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5589 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5590 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5592 [(set_attr "type" "sseicvt")
5593 (set_attr "mode" "<MODEF:MODE>")
5594 (set_attr "athlon_decode" "double,direct")
5595 (set_attr "amdfam10_decode" "vector,double")
5596 (set_attr "fp_int_src" "true")])
5598 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5599 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5601 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5602 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5603 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5604 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5605 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5606 [(set_attr "type" "sseicvt")
5607 (set_attr "prefix" "maybe_vex")
5608 (set_attr "mode" "<MODEF:MODE>")
5609 (set (attr "prefix_rex")
5611 (and (eq_attr "prefix" "maybe_vex")
5612 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5614 (const_string "*")))
5615 (set_attr "athlon_decode" "double,direct")
5616 (set_attr "amdfam10_decode" "vector,double")
5617 (set_attr "fp_int_src" "true")])
5620 [(set (match_operand:MODEF 0 "register_operand" "")
5621 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5622 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5623 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5624 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5625 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5627 && (SSE_REG_P (operands[0])
5628 || (GET_CODE (operands[0]) == SUBREG
5629 && SSE_REG_P (operands[0])))"
5630 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5633 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5634 [(set (match_operand:MODEF 0 "register_operand" "=x")
5636 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5637 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5638 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5639 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5640 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5641 [(set_attr "type" "sseicvt")
5642 (set_attr "prefix" "maybe_vex")
5643 (set_attr "mode" "<MODEF:MODE>")
5644 (set (attr "prefix_rex")
5646 (and (eq_attr "prefix" "maybe_vex")
5647 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5649 (const_string "*")))
5650 (set_attr "athlon_decode" "direct")
5651 (set_attr "amdfam10_decode" "double")
5652 (set_attr "fp_int_src" "true")])
5655 [(set (match_operand:MODEF 0 "register_operand" "")
5656 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5657 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5658 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5659 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5660 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5662 && (SSE_REG_P (operands[0])
5663 || (GET_CODE (operands[0]) == SUBREG
5664 && SSE_REG_P (operands[0])))"
5665 [(set (match_dup 2) (match_dup 1))
5666 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5670 [(set (match_operand:MODEF 0 "register_operand" "")
5671 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5672 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5673 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5674 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5676 && (SSE_REG_P (operands[0])
5677 || (GET_CODE (operands[0]) == SUBREG
5678 && SSE_REG_P (operands[0])))"
5679 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5682 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5683 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5685 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5686 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5688 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5692 [(set_attr "type" "fmov,multi")
5693 (set_attr "mode" "<X87MODEF:MODE>")
5694 (set_attr "unit" "*,i387")
5695 (set_attr "fp_int_src" "true")])
5697 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5698 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5700 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5702 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5704 [(set_attr "type" "fmov")
5705 (set_attr "mode" "<X87MODEF:MODE>")
5706 (set_attr "fp_int_src" "true")])
5709 [(set (match_operand:X87MODEF 0 "register_operand" "")
5710 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5711 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5713 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5715 && FP_REG_P (operands[0])"
5716 [(set (match_dup 2) (match_dup 1))
5717 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5721 [(set (match_operand:X87MODEF 0 "register_operand" "")
5722 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5723 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5725 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5727 && FP_REG_P (operands[0])"
5728 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5731 ;; Avoid store forwarding (partial memory) stall penalty
5732 ;; by passing DImode value through XMM registers. */
5734 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5735 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5737 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5738 (clobber (match_scratch:V4SI 3 "=X,x"))
5739 (clobber (match_scratch:V4SI 4 "=X,x"))
5740 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5741 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5742 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5743 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5745 [(set_attr "type" "multi")
5746 (set_attr "mode" "<X87MODEF:MODE>")
5747 (set_attr "unit" "i387")
5748 (set_attr "fp_int_src" "true")])
5751 [(set (match_operand:X87MODEF 0 "register_operand" "")
5752 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5753 (clobber (match_scratch:V4SI 3 ""))
5754 (clobber (match_scratch:V4SI 4 ""))
5755 (clobber (match_operand:DI 2 "memory_operand" ""))]
5756 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5757 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5758 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5760 && FP_REG_P (operands[0])"
5761 [(set (match_dup 2) (match_dup 3))
5762 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5764 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5765 Assemble the 64-bit DImode value in an xmm register. */
5766 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5767 gen_rtx_SUBREG (SImode, operands[1], 0)));
5768 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5769 gen_rtx_SUBREG (SImode, operands[1], 4)));
5770 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5772 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5776 [(set (match_operand:X87MODEF 0 "register_operand" "")
5777 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5778 (clobber (match_scratch:V4SI 3 ""))
5779 (clobber (match_scratch:V4SI 4 ""))
5780 (clobber (match_operand:DI 2 "memory_operand" ""))]
5781 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5782 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5783 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5785 && FP_REG_P (operands[0])"
5786 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5789 ;; Avoid store forwarding (partial memory) stall penalty by extending
5790 ;; SImode value to DImode through XMM register instead of pushing two
5791 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5792 ;; targets benefit from this optimization. Also note that fild
5793 ;; loads from memory only.
5795 (define_insn "*floatunssi<mode>2_1"
5796 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5797 (unsigned_float:X87MODEF
5798 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5799 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5800 (clobber (match_scratch:SI 3 "=X,x"))]
5802 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5805 [(set_attr "type" "multi")
5806 (set_attr "mode" "<MODE>")])
5809 [(set (match_operand:X87MODEF 0 "register_operand" "")
5810 (unsigned_float:X87MODEF
5811 (match_operand:SI 1 "register_operand" "")))
5812 (clobber (match_operand:DI 2 "memory_operand" ""))
5813 (clobber (match_scratch:SI 3 ""))]
5815 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5817 && reload_completed"
5818 [(set (match_dup 2) (match_dup 1))
5820 (float:X87MODEF (match_dup 2)))]
5821 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5824 [(set (match_operand:X87MODEF 0 "register_operand" "")
5825 (unsigned_float:X87MODEF
5826 (match_operand:SI 1 "memory_operand" "")))
5827 (clobber (match_operand:DI 2 "memory_operand" ""))
5828 (clobber (match_scratch:SI 3 ""))]
5830 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5832 && reload_completed"
5833 [(set (match_dup 2) (match_dup 3))
5835 (float:X87MODEF (match_dup 2)))]
5837 emit_move_insn (operands[3], operands[1]);
5838 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5841 (define_expand "floatunssi<mode>2"
5843 [(set (match_operand:X87MODEF 0 "register_operand" "")
5844 (unsigned_float:X87MODEF
5845 (match_operand:SI 1 "nonimmediate_operand" "")))
5846 (clobber (match_dup 2))
5847 (clobber (match_scratch:SI 3 ""))])]
5849 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5851 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5853 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5855 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5860 enum ix86_stack_slot slot = (virtuals_instantiated
5863 operands[2] = assign_386_stack_local (DImode, slot);
5867 (define_expand "floatunsdisf2"
5868 [(use (match_operand:SF 0 "register_operand" ""))
5869 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5870 "TARGET_64BIT && TARGET_SSE_MATH"
5871 "x86_emit_floatuns (operands); DONE;")
5873 (define_expand "floatunsdidf2"
5874 [(use (match_operand:DF 0 "register_operand" ""))
5875 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5876 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5877 && TARGET_SSE2 && TARGET_SSE_MATH"
5880 x86_emit_floatuns (operands);
5882 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5888 (define_expand "add<mode>3"
5889 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5890 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5891 (match_operand:SDWIM 2 "<general_operand>" "")))]
5893 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5895 (define_insn_and_split "*add<dwi>3_doubleword"
5896 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5898 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5899 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5900 (clobber (reg:CC FLAGS_REG))]
5901 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5904 [(parallel [(set (reg:CC FLAGS_REG)
5905 (unspec:CC [(match_dup 1) (match_dup 2)]
5908 (plus:DWIH (match_dup 1) (match_dup 2)))])
5909 (parallel [(set (match_dup 3)
5912 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5915 (clobber (reg:CC FLAGS_REG))])]
5916 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5918 (define_insn "add<mode>3_carry"
5919 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
5921 (plus:SWI (match_operand:SWI 3 "ix86_carry_flag_operator" "")
5922 (match_operand:SWI 1 "nonimmediate_operand" "%0,0"))
5923 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
5924 (clobber (reg:CC FLAGS_REG))]
5925 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5926 "adc{<imodesuffix>}\t{%2, %0|%0, %2}"
5927 [(set_attr "type" "alu")
5928 (set_attr "use_carry" "1")
5929 (set_attr "pent_pair" "pu")
5930 (set_attr "mode" "<MODE>")])
5932 (define_insn "*addsi3_carry_zext"
5933 [(set (match_operand:DI 0 "register_operand" "=r")
5936 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
5937 (match_operand:SI 1 "nonimmediate_operand" "%0"))
5938 (match_operand:SI 2 "general_operand" "g"))))
5939 (clobber (reg:CC FLAGS_REG))]
5940 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
5941 "adc{l}\t{%2, %k0|%k0, %2}"
5942 [(set_attr "type" "alu")
5943 (set_attr "use_carry" "1")
5944 (set_attr "pent_pair" "pu")
5945 (set_attr "mode" "SI")])
5947 (define_insn "*add<mode>3_cc"
5948 [(set (reg:CC FLAGS_REG)
5950 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5951 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5953 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5954 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5955 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5956 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5957 [(set_attr "type" "alu")
5958 (set_attr "mode" "<MODE>")])
5960 (define_insn "addqi3_cc"
5961 [(set (reg:CC FLAGS_REG)
5963 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5964 (match_operand:QI 2 "general_operand" "qn,qm")]
5966 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5967 (plus:QI (match_dup 1) (match_dup 2)))]
5968 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5969 "add{b}\t{%2, %0|%0, %2}"
5970 [(set_attr "type" "alu")
5971 (set_attr "mode" "QI")])
5973 (define_insn "*add<mode>3_cconly_overflow"
5974 [(set (reg:CCC FLAGS_REG)
5977 (match_operand:SWI 1 "nonimmediate_operand" "%0")
5978 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
5980 (clobber (match_scratch:SWI 0 "=<r>"))]
5981 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5982 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5983 [(set_attr "type" "alu")
5984 (set_attr "mode" "<MODE>")])
5986 (define_insn "*lea_1"
5987 [(set (match_operand:DWIH 0 "register_operand" "=r")
5988 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5990 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5991 [(set_attr "type" "lea")
5992 (set_attr "mode" "<MODE>")])
5994 (define_insn "*lea_2"
5995 [(set (match_operand:SI 0 "register_operand" "=r")
5996 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5998 "lea{l}\t{%a1, %0|%0, %a1}"
5999 [(set_attr "type" "lea")
6000 (set_attr "mode" "SI")])
6002 (define_insn "*lea_2_zext"
6003 [(set (match_operand:DI 0 "register_operand" "=r")
6005 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6007 "lea{l}\t{%a1, %k0|%k0, %a1}"
6008 [(set_attr "type" "lea")
6009 (set_attr "mode" "SI")])
6011 (define_insn "*add<mode>_1"
6012 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
6014 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
6015 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
6016 (clobber (reg:CC FLAGS_REG))]
6017 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6019 switch (get_attr_type (insn))
6022 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6023 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
6026 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6027 if (operands[2] == const1_rtx)
6028 return "inc{<imodesuffix>}\t%0";
6031 gcc_assert (operands[2] == constm1_rtx);
6032 return "dec{<imodesuffix>}\t%0";
6036 /* Use add as much as possible to replace lea for AGU optimization. */
6037 if (which_alternative == 2 && TARGET_OPT_AGU)
6038 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6040 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6042 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6043 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6044 if (CONST_INT_P (operands[2])
6045 /* Avoid overflows. */
6046 && (<MODE>mode != DImode
6047 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6048 && (INTVAL (operands[2]) == 128
6049 || (INTVAL (operands[2]) < 0
6050 && INTVAL (operands[2]) != -128)))
6052 operands[2] = GEN_INT (-INTVAL (operands[2]));
6053 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6055 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6059 (cond [(and (eq_attr "alternative" "2")
6060 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6061 (const_string "lea")
6062 (eq_attr "alternative" "3")
6063 (const_string "lea")
6064 ; Current assemblers are broken and do not allow @GOTOFF in
6065 ; ought but a memory context.
6066 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6067 (const_string "lea")
6068 (match_operand:SWI48 2 "incdec_operand" "")
6069 (const_string "incdec")
6071 (const_string "alu")))
6072 (set (attr "length_immediate")
6074 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6076 (const_string "*")))
6077 (set_attr "mode" "<MODE>")])
6079 ;; It may seem that nonimmediate operand is proper one for operand 1.
6080 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6081 ;; we take care in ix86_binary_operator_ok to not allow two memory
6082 ;; operands so proper swapping will be done in reload. This allow
6083 ;; patterns constructed from addsi_1 to match.
6085 (define_insn "*addsi_1_zext"
6086 [(set (match_operand:DI 0 "register_operand" "=r,r")
6088 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6089 (match_operand:SI 2 "general_operand" "g,li"))))
6090 (clobber (reg:CC FLAGS_REG))]
6091 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6093 switch (get_attr_type (insn))
6096 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6097 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6100 if (operands[2] == const1_rtx)
6101 return "inc{l}\t%k0";
6104 gcc_assert (operands[2] == constm1_rtx);
6105 return "dec{l}\t%k0";
6109 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6110 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6111 if (CONST_INT_P (operands[2])
6112 && (INTVAL (operands[2]) == 128
6113 || (INTVAL (operands[2]) < 0
6114 && INTVAL (operands[2]) != -128)))
6116 operands[2] = GEN_INT (-INTVAL (operands[2]));
6117 return "sub{l}\t{%2, %k0|%k0, %2}";
6119 return "add{l}\t{%2, %k0|%k0, %2}";
6123 (cond [(eq_attr "alternative" "1")
6124 (const_string "lea")
6125 ; Current assemblers are broken and do not allow @GOTOFF in
6126 ; ought but a memory context.
6127 (match_operand:SI 2 "pic_symbolic_operand" "")
6128 (const_string "lea")
6129 (match_operand:SI 2 "incdec_operand" "")
6130 (const_string "incdec")
6132 (const_string "alu")))
6133 (set (attr "length_immediate")
6135 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6137 (const_string "*")))
6138 (set_attr "mode" "SI")])
6140 (define_insn "*addhi_1"
6141 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6142 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6143 (match_operand:HI 2 "general_operand" "rn,rm")))
6144 (clobber (reg:CC FLAGS_REG))]
6145 "TARGET_PARTIAL_REG_STALL
6146 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6148 switch (get_attr_type (insn))
6151 if (operands[2] == const1_rtx)
6152 return "inc{w}\t%0";
6155 gcc_assert (operands[2] == constm1_rtx);
6156 return "dec{w}\t%0";
6160 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6161 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6162 if (CONST_INT_P (operands[2])
6163 && (INTVAL (operands[2]) == 128
6164 || (INTVAL (operands[2]) < 0
6165 && INTVAL (operands[2]) != -128)))
6167 operands[2] = GEN_INT (-INTVAL (operands[2]));
6168 return "sub{w}\t{%2, %0|%0, %2}";
6170 return "add{w}\t{%2, %0|%0, %2}";
6174 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6175 (const_string "incdec")
6176 (const_string "alu")))
6177 (set (attr "length_immediate")
6179 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6181 (const_string "*")))
6182 (set_attr "mode" "HI")])
6184 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6185 ;; type optimizations enabled by define-splits. This is not important
6186 ;; for PII, and in fact harmful because of partial register stalls.
6188 (define_insn "*addhi_1_lea"
6189 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6190 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6191 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6192 (clobber (reg:CC FLAGS_REG))]
6193 "!TARGET_PARTIAL_REG_STALL
6194 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6196 switch (get_attr_type (insn))
6201 if (operands[2] == const1_rtx)
6202 return "inc{w}\t%0";
6205 gcc_assert (operands[2] == constm1_rtx);
6206 return "dec{w}\t%0";
6210 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6211 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6212 if (CONST_INT_P (operands[2])
6213 && (INTVAL (operands[2]) == 128
6214 || (INTVAL (operands[2]) < 0
6215 && INTVAL (operands[2]) != -128)))
6217 operands[2] = GEN_INT (-INTVAL (operands[2]));
6218 return "sub{w}\t{%2, %0|%0, %2}";
6220 return "add{w}\t{%2, %0|%0, %2}";
6224 (if_then_else (eq_attr "alternative" "2")
6225 (const_string "lea")
6226 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6227 (const_string "incdec")
6228 (const_string "alu"))))
6229 (set (attr "length_immediate")
6231 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6233 (const_string "*")))
6234 (set_attr "mode" "HI,HI,SI")])
6236 (define_insn "*addqi_1"
6237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6238 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6239 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6240 (clobber (reg:CC FLAGS_REG))]
6241 "TARGET_PARTIAL_REG_STALL
6242 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6244 int widen = (which_alternative == 2);
6245 switch (get_attr_type (insn))
6248 if (operands[2] == const1_rtx)
6249 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6252 gcc_assert (operands[2] == constm1_rtx);
6253 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6257 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6258 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6259 if (CONST_INT_P (operands[2])
6260 && (INTVAL (operands[2]) == 128
6261 || (INTVAL (operands[2]) < 0
6262 && INTVAL (operands[2]) != -128)))
6264 operands[2] = GEN_INT (-INTVAL (operands[2]));
6266 return "sub{l}\t{%2, %k0|%k0, %2}";
6268 return "sub{b}\t{%2, %0|%0, %2}";
6271 return "add{l}\t{%k2, %k0|%k0, %k2}";
6273 return "add{b}\t{%2, %0|%0, %2}";
6277 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6278 (const_string "incdec")
6279 (const_string "alu")))
6280 (set (attr "length_immediate")
6282 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6284 (const_string "*")))
6285 (set_attr "mode" "QI,QI,SI")])
6287 ;; %%% Potential partial reg stall on alternative 2. What to do?
6288 (define_insn "*addqi_1_lea"
6289 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6290 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6291 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6292 (clobber (reg:CC FLAGS_REG))]
6293 "!TARGET_PARTIAL_REG_STALL
6294 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6296 int widen = (which_alternative == 2);
6297 switch (get_attr_type (insn))
6302 if (operands[2] == const1_rtx)
6303 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6306 gcc_assert (operands[2] == constm1_rtx);
6307 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6311 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6312 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6313 if (CONST_INT_P (operands[2])
6314 && (INTVAL (operands[2]) == 128
6315 || (INTVAL (operands[2]) < 0
6316 && INTVAL (operands[2]) != -128)))
6318 operands[2] = GEN_INT (-INTVAL (operands[2]));
6320 return "sub{l}\t{%2, %k0|%k0, %2}";
6322 return "sub{b}\t{%2, %0|%0, %2}";
6325 return "add{l}\t{%k2, %k0|%k0, %k2}";
6327 return "add{b}\t{%2, %0|%0, %2}";
6331 (if_then_else (eq_attr "alternative" "3")
6332 (const_string "lea")
6333 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6334 (const_string "incdec")
6335 (const_string "alu"))))
6336 (set (attr "length_immediate")
6338 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6340 (const_string "*")))
6341 (set_attr "mode" "QI,QI,SI,SI")])
6343 (define_insn "*addqi_1_slp"
6344 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6345 (plus:QI (match_dup 0)
6346 (match_operand:QI 1 "general_operand" "qn,qnm")))
6347 (clobber (reg:CC FLAGS_REG))]
6348 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6349 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6351 switch (get_attr_type (insn))
6354 if (operands[1] == const1_rtx)
6355 return "inc{b}\t%0";
6358 gcc_assert (operands[1] == constm1_rtx);
6359 return "dec{b}\t%0";
6363 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6364 if (CONST_INT_P (operands[1])
6365 && INTVAL (operands[1]) < 0)
6367 operands[1] = GEN_INT (-INTVAL (operands[1]));
6368 return "sub{b}\t{%1, %0|%0, %1}";
6370 return "add{b}\t{%1, %0|%0, %1}";
6374 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6375 (const_string "incdec")
6376 (const_string "alu1")))
6377 (set (attr "memory")
6378 (if_then_else (match_operand 1 "memory_operand" "")
6379 (const_string "load")
6380 (const_string "none")))
6381 (set_attr "mode" "QI")])
6383 (define_insn "*add<mode>_2"
6384 [(set (reg FLAGS_REG)
6387 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6388 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6390 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6391 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6392 "ix86_match_ccmode (insn, CCGOCmode)
6393 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6394 /* Current assemblers are broken and do not allow @GOTOFF in
6395 ought but a memory context. */
6396 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6398 switch (get_attr_type (insn))
6401 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6402 if (operands[2] == const1_rtx)
6403 return "inc{<imodesuffix>}\t%0";
6406 gcc_assert (operands[2] == constm1_rtx);
6407 return "dec{<imodesuffix>}\t%0";
6411 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6412 /* ???? In DImode, we ought to handle there the 32bit case too
6413 - do we need new constraint? */
6414 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6415 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6416 if (CONST_INT_P (operands[2])
6417 /* Avoid overflows. */
6418 && (<MODE>mode != DImode
6419 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6420 && (INTVAL (operands[2]) == 128
6421 || (INTVAL (operands[2]) < 0
6422 && INTVAL (operands[2]) != -128)))
6424 operands[2] = GEN_INT (-INTVAL (operands[2]));
6425 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6427 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6431 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6432 (const_string "incdec")
6433 (const_string "alu")))
6434 (set (attr "length_immediate")
6436 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6438 (const_string "*")))
6439 (set_attr "mode" "<MODE>")])
6441 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6442 (define_insn "*addsi_2_zext"
6443 [(set (reg FLAGS_REG)
6445 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6446 (match_operand:SI 2 "general_operand" "g"))
6448 (set (match_operand:DI 0 "register_operand" "=r")
6449 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6450 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6451 && ix86_binary_operator_ok (PLUS, SImode, operands)
6452 /* Current assemblers are broken and do not allow @GOTOFF in
6453 ought but a memory context. */
6454 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6456 switch (get_attr_type (insn))
6459 if (operands[2] == const1_rtx)
6460 return "inc{l}\t%k0";
6463 gcc_assert (operands[2] == constm1_rtx);
6464 return "dec{l}\t%k0";
6468 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6469 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6470 if (CONST_INT_P (operands[2])
6471 && (INTVAL (operands[2]) == 128
6472 || (INTVAL (operands[2]) < 0
6473 && INTVAL (operands[2]) != -128)))
6475 operands[2] = GEN_INT (-INTVAL (operands[2]));
6476 return "sub{l}\t{%2, %k0|%k0, %2}";
6478 return "add{l}\t{%2, %k0|%k0, %2}";
6482 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6483 (const_string "incdec")
6484 (const_string "alu")))
6485 (set (attr "length_immediate")
6487 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6489 (const_string "*")))
6490 (set_attr "mode" "SI")])
6492 (define_insn "*addhi_2"
6493 [(set (reg FLAGS_REG)
6495 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6496 (match_operand:HI 2 "general_operand" "rmn,rn"))
6498 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6499 (plus:HI (match_dup 1) (match_dup 2)))]
6500 "ix86_match_ccmode (insn, CCGOCmode)
6501 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6503 switch (get_attr_type (insn))
6506 if (operands[2] == const1_rtx)
6507 return "inc{w}\t%0";
6510 gcc_assert (operands[2] == constm1_rtx);
6511 return "dec{w}\t%0";
6515 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6516 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6517 if (CONST_INT_P (operands[2])
6518 && (INTVAL (operands[2]) == 128
6519 || (INTVAL (operands[2]) < 0
6520 && INTVAL (operands[2]) != -128)))
6522 operands[2] = GEN_INT (-INTVAL (operands[2]));
6523 return "sub{w}\t{%2, %0|%0, %2}";
6525 return "add{w}\t{%2, %0|%0, %2}";
6529 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6530 (const_string "incdec")
6531 (const_string "alu")))
6532 (set (attr "length_immediate")
6534 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6536 (const_string "*")))
6537 (set_attr "mode" "HI")])
6539 (define_insn "*addqi_2"
6540 [(set (reg FLAGS_REG)
6542 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6543 (match_operand:QI 2 "general_operand" "qmn,qn"))
6545 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6546 (plus:QI (match_dup 1) (match_dup 2)))]
6547 "ix86_match_ccmode (insn, CCGOCmode)
6548 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6550 switch (get_attr_type (insn))
6553 if (operands[2] == const1_rtx)
6554 return "inc{b}\t%0";
6557 gcc_assert (operands[2] == constm1_rtx
6558 || (CONST_INT_P (operands[2])
6559 && INTVAL (operands[2]) == 255));
6560 return "dec{b}\t%0";
6564 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6565 if (CONST_INT_P (operands[2])
6566 && INTVAL (operands[2]) < 0)
6568 operands[2] = GEN_INT (-INTVAL (operands[2]));
6569 return "sub{b}\t{%2, %0|%0, %2}";
6571 return "add{b}\t{%2, %0|%0, %2}";
6575 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6576 (const_string "incdec")
6577 (const_string "alu")))
6578 (set_attr "mode" "QI")])
6580 (define_insn "*add<mode>_3"
6581 [(set (reg FLAGS_REG)
6583 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6584 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6585 (clobber (match_scratch:SWI48 0 "=r"))]
6586 "ix86_match_ccmode (insn, CCZmode)
6587 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6588 /* Current assemblers are broken and do not allow @GOTOFF in
6589 ought but a memory context. */
6590 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6592 switch (get_attr_type (insn))
6595 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6596 if (operands[2] == const1_rtx)
6597 return "inc{<imodesuffix>}\t%0";
6600 gcc_assert (operands[2] == constm1_rtx);
6601 return "dec{<imodesuffix>}\t%0";
6605 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6606 /* ???? In DImode, we ought to handle there the 32bit case too
6607 - do we need new constraint? */
6608 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6609 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6610 if (CONST_INT_P (operands[2])
6611 /* Avoid overflows. */
6612 && (<MODE>mode != DImode
6613 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6614 && (INTVAL (operands[2]) == 128
6615 || (INTVAL (operands[2]) < 0
6616 && INTVAL (operands[2]) != -128)))
6618 operands[2] = GEN_INT (-INTVAL (operands[2]));
6619 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6621 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6625 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6626 (const_string "incdec")
6627 (const_string "alu")))
6628 (set (attr "length_immediate")
6630 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6632 (const_string "*")))
6633 (set_attr "mode" "<MODE>")])
6635 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6636 (define_insn "*addsi_3_zext"
6637 [(set (reg FLAGS_REG)
6639 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6640 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6641 (set (match_operand:DI 0 "register_operand" "=r")
6642 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6643 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6644 && ix86_binary_operator_ok (PLUS, SImode, operands)
6645 /* Current assemblers are broken and do not allow @GOTOFF in
6646 ought but a memory context. */
6647 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6649 switch (get_attr_type (insn))
6652 if (operands[2] == const1_rtx)
6653 return "inc{l}\t%k0";
6656 gcc_assert (operands[2] == constm1_rtx);
6657 return "dec{l}\t%k0";
6661 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6662 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6663 if (CONST_INT_P (operands[2])
6664 && (INTVAL (operands[2]) == 128
6665 || (INTVAL (operands[2]) < 0
6666 && INTVAL (operands[2]) != -128)))
6668 operands[2] = GEN_INT (-INTVAL (operands[2]));
6669 return "sub{l}\t{%2, %k0|%k0, %2}";
6671 return "add{l}\t{%2, %k0|%k0, %2}";
6675 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6676 (const_string "incdec")
6677 (const_string "alu")))
6678 (set (attr "length_immediate")
6680 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6682 (const_string "*")))
6683 (set_attr "mode" "SI")])
6685 (define_insn "*addhi_3"
6686 [(set (reg FLAGS_REG)
6688 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6689 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6690 (clobber (match_scratch:HI 0 "=r"))]
6691 "ix86_match_ccmode (insn, CCZmode)
6692 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6694 switch (get_attr_type (insn))
6697 if (operands[2] == const1_rtx)
6698 return "inc{w}\t%0";
6701 gcc_assert (operands[2] == constm1_rtx);
6702 return "dec{w}\t%0";
6706 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6707 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6708 if (CONST_INT_P (operands[2])
6709 && (INTVAL (operands[2]) == 128
6710 || (INTVAL (operands[2]) < 0
6711 && INTVAL (operands[2]) != -128)))
6713 operands[2] = GEN_INT (-INTVAL (operands[2]));
6714 return "sub{w}\t{%2, %0|%0, %2}";
6716 return "add{w}\t{%2, %0|%0, %2}";
6720 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6721 (const_string "incdec")
6722 (const_string "alu")))
6723 (set (attr "length_immediate")
6725 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6727 (const_string "*")))
6728 (set_attr "mode" "HI")])
6730 (define_insn "*addqi_3"
6731 [(set (reg FLAGS_REG)
6733 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6734 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6735 (clobber (match_scratch:QI 0 "=q"))]
6736 "ix86_match_ccmode (insn, CCZmode)
6737 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6739 switch (get_attr_type (insn))
6742 if (operands[2] == const1_rtx)
6743 return "inc{b}\t%0";
6746 gcc_assert (operands[2] == constm1_rtx
6747 || (CONST_INT_P (operands[2])
6748 && INTVAL (operands[2]) == 255));
6749 return "dec{b}\t%0";
6753 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6754 if (CONST_INT_P (operands[2])
6755 && INTVAL (operands[2]) < 0)
6757 operands[2] = GEN_INT (-INTVAL (operands[2]));
6758 return "sub{b}\t{%2, %0|%0, %2}";
6760 return "add{b}\t{%2, %0|%0, %2}";
6764 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6765 (const_string "incdec")
6766 (const_string "alu")))
6767 (set_attr "mode" "QI")])
6769 ; For comparisons against 1, -1 and 128, we may generate better code
6770 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6771 ; is matched then. We can't accept general immediate, because for
6772 ; case of overflows, the result is messed up.
6773 ; This pattern also don't hold of 0x8000000000000000, since the value
6774 ; overflows when negated.
6775 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6776 ; only for comparisons not depending on it.
6778 (define_insn "*adddi_4"
6779 [(set (reg FLAGS_REG)
6781 (match_operand:DI 1 "nonimmediate_operand" "0")
6782 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6783 (clobber (match_scratch:DI 0 "=rm"))]
6785 && ix86_match_ccmode (insn, CCGCmode)"
6787 switch (get_attr_type (insn))
6790 if (operands[2] == constm1_rtx)
6791 return "inc{q}\t%0";
6794 gcc_assert (operands[2] == const1_rtx);
6795 return "dec{q}\t%0";
6799 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6800 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6801 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6802 if ((INTVAL (operands[2]) == -128
6803 || (INTVAL (operands[2]) > 0
6804 && INTVAL (operands[2]) != 128))
6805 /* Avoid overflows. */
6806 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6807 return "sub{q}\t{%2, %0|%0, %2}";
6808 operands[2] = GEN_INT (-INTVAL (operands[2]));
6809 return "add{q}\t{%2, %0|%0, %2}";
6813 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6814 (const_string "incdec")
6815 (const_string "alu")))
6816 (set (attr "length_immediate")
6818 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6820 (const_string "*")))
6821 (set_attr "mode" "DI")])
6823 ; For comparisons against 1, -1 and 128, we may generate better code
6824 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6825 ; is matched then. We can't accept general immediate, because for
6826 ; case of overflows, the result is messed up.
6827 ; This pattern also don't hold of 0x80000000, since the value overflows
6829 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6830 ; only for comparisons not depending on it.
6832 (define_insn "*addsi_4"
6833 [(set (reg FLAGS_REG)
6835 (match_operand:SI 1 "nonimmediate_operand" "0")
6836 (match_operand:SI 2 "const_int_operand" "n")))
6837 (clobber (match_scratch:SI 0 "=rm"))]
6838 "ix86_match_ccmode (insn, CCGCmode)
6839 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6841 switch (get_attr_type (insn))
6844 if (operands[2] == constm1_rtx)
6845 return "inc{l}\t%0";
6848 gcc_assert (operands[2] == const1_rtx);
6849 return "dec{l}\t%0";
6853 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6854 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6855 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6856 if ((INTVAL (operands[2]) == -128
6857 || (INTVAL (operands[2]) > 0
6858 && INTVAL (operands[2]) != 128)))
6859 return "sub{l}\t{%2, %0|%0, %2}";
6860 operands[2] = GEN_INT (-INTVAL (operands[2]));
6861 return "add{l}\t{%2, %0|%0, %2}";
6865 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6866 (const_string "incdec")
6867 (const_string "alu")))
6868 (set (attr "length_immediate")
6870 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6872 (const_string "*")))
6873 (set_attr "mode" "SI")])
6875 ; See comments above addsi_4 for details.
6877 (define_insn "*addhi_4"
6878 [(set (reg FLAGS_REG)
6880 (match_operand:HI 1 "nonimmediate_operand" "0")
6881 (match_operand:HI 2 "const_int_operand" "n")))
6882 (clobber (match_scratch:HI 0 "=rm"))]
6883 "ix86_match_ccmode (insn, CCGCmode)
6884 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6886 switch (get_attr_type (insn))
6889 if (operands[2] == constm1_rtx)
6890 return "inc{w}\t%0";
6893 gcc_assert (operands[2] == const1_rtx);
6894 return "dec{w}\t%0";
6898 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6899 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6900 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6901 if ((INTVAL (operands[2]) == -128
6902 || (INTVAL (operands[2]) > 0
6903 && INTVAL (operands[2]) != 128)))
6904 return "sub{w}\t{%2, %0|%0, %2}";
6905 operands[2] = GEN_INT (-INTVAL (operands[2]));
6906 return "add{w}\t{%2, %0|%0, %2}";
6910 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6911 (const_string "incdec")
6912 (const_string "alu")))
6913 (set (attr "length_immediate")
6915 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6917 (const_string "*")))
6918 (set_attr "mode" "HI")])
6920 ; See comments above addsi_4 for details.
6922 (define_insn "*addqi_4"
6923 [(set (reg FLAGS_REG)
6925 (match_operand:QI 1 "nonimmediate_operand" "0")
6926 (match_operand:QI 2 "const_int_operand" "n")))
6927 (clobber (match_scratch:QI 0 "=qm"))]
6928 "ix86_match_ccmode (insn, CCGCmode)
6929 && (INTVAL (operands[2]) & 0xff) != 0x80"
6931 switch (get_attr_type (insn))
6934 if (operands[2] == constm1_rtx
6935 || (CONST_INT_P (operands[2])
6936 && INTVAL (operands[2]) == 255))
6937 return "inc{b}\t%0";
6940 gcc_assert (operands[2] == const1_rtx);
6941 return "dec{b}\t%0";
6945 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6946 if (INTVAL (operands[2]) < 0)
6948 operands[2] = GEN_INT (-INTVAL (operands[2]));
6949 return "add{b}\t{%2, %0|%0, %2}";
6951 return "sub{b}\t{%2, %0|%0, %2}";
6955 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6956 (const_string "incdec")
6957 (const_string "alu")))
6958 (set_attr "mode" "QI")])
6960 (define_insn "*add<mode>_5"
6961 [(set (reg FLAGS_REG)
6964 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6965 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6967 (clobber (match_scratch:SWI48 0 "=r"))]
6968 "ix86_match_ccmode (insn, CCGOCmode)
6969 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6970 /* Current assemblers are broken and do not allow @GOTOFF in
6971 ought but a memory context. */
6972 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6974 switch (get_attr_type (insn))
6977 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6978 if (operands[2] == const1_rtx)
6979 return "inc{<imodesuffix>}\t%0";
6982 gcc_assert (operands[2] == constm1_rtx);
6983 return "dec{<imodesuffix>}\t%0";
6987 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6988 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6989 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6990 if (CONST_INT_P (operands[2])
6991 /* Avoid overflows. */
6992 && (<MODE>mode != DImode
6993 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6994 && (INTVAL (operands[2]) == 128
6995 || (INTVAL (operands[2]) < 0
6996 && INTVAL (operands[2]) != -128)))
6998 operands[2] = GEN_INT (-INTVAL (operands[2]));
6999 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
7001 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
7005 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
7006 (const_string "incdec")
7007 (const_string "alu")))
7008 (set (attr "length_immediate")
7010 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7012 (const_string "*")))
7013 (set_attr "mode" "<MODE>")])
7015 (define_insn "*addhi_5"
7016 [(set (reg FLAGS_REG)
7018 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7019 (match_operand:HI 2 "general_operand" "rmn"))
7021 (clobber (match_scratch:HI 0 "=r"))]
7022 "ix86_match_ccmode (insn, CCGOCmode)
7023 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7025 switch (get_attr_type (insn))
7028 if (operands[2] == const1_rtx)
7029 return "inc{w}\t%0";
7032 gcc_assert (operands[2] == constm1_rtx);
7033 return "dec{w}\t%0";
7037 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7038 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7039 if (CONST_INT_P (operands[2])
7040 && (INTVAL (operands[2]) == 128
7041 || (INTVAL (operands[2]) < 0
7042 && INTVAL (operands[2]) != -128)))
7044 operands[2] = GEN_INT (-INTVAL (operands[2]));
7045 return "sub{w}\t{%2, %0|%0, %2}";
7047 return "add{w}\t{%2, %0|%0, %2}";
7051 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7052 (const_string "incdec")
7053 (const_string "alu")))
7054 (set (attr "length_immediate")
7056 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7058 (const_string "*")))
7059 (set_attr "mode" "HI")])
7061 (define_insn "*addqi_5"
7062 [(set (reg FLAGS_REG)
7064 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7065 (match_operand:QI 2 "general_operand" "qmn"))
7067 (clobber (match_scratch:QI 0 "=q"))]
7068 "ix86_match_ccmode (insn, CCGOCmode)
7069 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7071 switch (get_attr_type (insn))
7074 if (operands[2] == const1_rtx)
7075 return "inc{b}\t%0";
7078 gcc_assert (operands[2] == constm1_rtx
7079 || (CONST_INT_P (operands[2])
7080 && INTVAL (operands[2]) == 255));
7081 return "dec{b}\t%0";
7085 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
7086 if (CONST_INT_P (operands[2])
7087 && INTVAL (operands[2]) < 0)
7089 operands[2] = GEN_INT (-INTVAL (operands[2]));
7090 return "sub{b}\t{%2, %0|%0, %2}";
7092 return "add{b}\t{%2, %0|%0, %2}";
7096 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7097 (const_string "incdec")
7098 (const_string "alu")))
7099 (set_attr "mode" "QI")])
7101 (define_insn "*addqi_ext_1_rex64"
7102 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7107 (match_operand 1 "ext_register_operand" "0")
7110 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7111 (clobber (reg:CC FLAGS_REG))]
7114 switch (get_attr_type (insn))
7117 if (operands[2] == const1_rtx)
7118 return "inc{b}\t%h0";
7121 gcc_assert (operands[2] == constm1_rtx
7122 || (CONST_INT_P (operands[2])
7123 && INTVAL (operands[2]) == 255));
7124 return "dec{b}\t%h0";
7128 return "add{b}\t{%2, %h0|%h0, %2}";
7132 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7133 (const_string "incdec")
7134 (const_string "alu")))
7135 (set_attr "modrm" "1")
7136 (set_attr "mode" "QI")])
7138 (define_insn "addqi_ext_1"
7139 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7144 (match_operand 1 "ext_register_operand" "0")
7147 (match_operand:QI 2 "general_operand" "Qmn")))
7148 (clobber (reg:CC FLAGS_REG))]
7151 switch (get_attr_type (insn))
7154 if (operands[2] == const1_rtx)
7155 return "inc{b}\t%h0";
7158 gcc_assert (operands[2] == constm1_rtx
7159 || (CONST_INT_P (operands[2])
7160 && INTVAL (operands[2]) == 255));
7161 return "dec{b}\t%h0";
7165 return "add{b}\t{%2, %h0|%h0, %2}";
7169 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7170 (const_string "incdec")
7171 (const_string "alu")))
7172 (set_attr "modrm" "1")
7173 (set_attr "mode" "QI")])
7175 (define_insn "*addqi_ext_2"
7176 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7181 (match_operand 1 "ext_register_operand" "%0")
7185 (match_operand 2 "ext_register_operand" "Q")
7188 (clobber (reg:CC FLAGS_REG))]
7190 "add{b}\t{%h2, %h0|%h0, %h2}"
7191 [(set_attr "type" "alu")
7192 (set_attr "mode" "QI")])
7194 ;; The lea patterns for non-Pmodes needs to be matched by
7195 ;; several insns converted to real lea by splitters.
7197 (define_insn_and_split "*lea_general_1"
7198 [(set (match_operand 0 "register_operand" "=r")
7199 (plus (plus (match_operand 1 "index_register_operand" "l")
7200 (match_operand 2 "register_operand" "r"))
7201 (match_operand 3 "immediate_operand" "i")))]
7202 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7203 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7204 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7205 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7206 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7207 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7208 || GET_MODE (operands[3]) == VOIDmode)"
7210 "&& reload_completed"
7214 operands[0] = gen_lowpart (SImode, operands[0]);
7215 operands[1] = gen_lowpart (Pmode, operands[1]);
7216 operands[2] = gen_lowpart (Pmode, operands[2]);
7217 operands[3] = gen_lowpart (Pmode, operands[3]);
7218 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7220 if (Pmode != SImode)
7221 pat = gen_rtx_SUBREG (SImode, pat, 0);
7222 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7225 [(set_attr "type" "lea")
7226 (set_attr "mode" "SI")])
7228 (define_insn_and_split "*lea_general_1_zext"
7229 [(set (match_operand:DI 0 "register_operand" "=r")
7232 (match_operand:SI 1 "index_register_operand" "l")
7233 (match_operand:SI 2 "register_operand" "r"))
7234 (match_operand:SI 3 "immediate_operand" "i"))))]
7237 "&& reload_completed"
7239 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7241 (match_dup 3)) 0)))]
7243 operands[1] = gen_lowpart (Pmode, operands[1]);
7244 operands[2] = gen_lowpart (Pmode, operands[2]);
7245 operands[3] = gen_lowpart (Pmode, operands[3]);
7247 [(set_attr "type" "lea")
7248 (set_attr "mode" "SI")])
7250 (define_insn_and_split "*lea_general_2"
7251 [(set (match_operand 0 "register_operand" "=r")
7252 (plus (mult (match_operand 1 "index_register_operand" "l")
7253 (match_operand 2 "const248_operand" "i"))
7254 (match_operand 3 "nonmemory_operand" "ri")))]
7255 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7256 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7257 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7258 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7259 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7260 || GET_MODE (operands[3]) == VOIDmode)"
7262 "&& reload_completed"
7266 operands[0] = gen_lowpart (SImode, operands[0]);
7267 operands[1] = gen_lowpart (Pmode, operands[1]);
7268 operands[3] = gen_lowpart (Pmode, operands[3]);
7269 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7271 if (Pmode != SImode)
7272 pat = gen_rtx_SUBREG (SImode, pat, 0);
7273 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7276 [(set_attr "type" "lea")
7277 (set_attr "mode" "SI")])
7279 (define_insn_and_split "*lea_general_2_zext"
7280 [(set (match_operand:DI 0 "register_operand" "=r")
7283 (match_operand:SI 1 "index_register_operand" "l")
7284 (match_operand:SI 2 "const248_operand" "n"))
7285 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7288 "&& reload_completed"
7290 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7292 (match_dup 3)) 0)))]
7294 operands[1] = gen_lowpart (Pmode, operands[1]);
7295 operands[3] = gen_lowpart (Pmode, operands[3]);
7297 [(set_attr "type" "lea")
7298 (set_attr "mode" "SI")])
7300 (define_insn_and_split "*lea_general_3"
7301 [(set (match_operand 0 "register_operand" "=r")
7302 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7303 (match_operand 2 "const248_operand" "i"))
7304 (match_operand 3 "register_operand" "r"))
7305 (match_operand 4 "immediate_operand" "i")))]
7306 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7307 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7308 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7309 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7310 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7312 "&& reload_completed"
7316 operands[0] = gen_lowpart (SImode, operands[0]);
7317 operands[1] = gen_lowpart (Pmode, operands[1]);
7318 operands[3] = gen_lowpart (Pmode, operands[3]);
7319 operands[4] = gen_lowpart (Pmode, operands[4]);
7320 pat = gen_rtx_PLUS (Pmode,
7321 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7325 if (Pmode != SImode)
7326 pat = gen_rtx_SUBREG (SImode, pat, 0);
7327 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7330 [(set_attr "type" "lea")
7331 (set_attr "mode" "SI")])
7333 (define_insn_and_split "*lea_general_3_zext"
7334 [(set (match_operand:DI 0 "register_operand" "=r")
7338 (match_operand:SI 1 "index_register_operand" "l")
7339 (match_operand:SI 2 "const248_operand" "n"))
7340 (match_operand:SI 3 "register_operand" "r"))
7341 (match_operand:SI 4 "immediate_operand" "i"))))]
7344 "&& reload_completed"
7346 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7349 (match_dup 4)) 0)))]
7351 operands[1] = gen_lowpart (Pmode, operands[1]);
7352 operands[3] = gen_lowpart (Pmode, operands[3]);
7353 operands[4] = gen_lowpart (Pmode, operands[4]);
7355 [(set_attr "type" "lea")
7356 (set_attr "mode" "SI")])
7358 ;; Convert lea to the lea pattern to avoid flags dependency.
7360 [(set (match_operand:DI 0 "register_operand" "")
7361 (plus:DI (match_operand:DI 1 "register_operand" "")
7362 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7363 (clobber (reg:CC FLAGS_REG))]
7364 "TARGET_64BIT && reload_completed
7365 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7367 (plus:DI (match_dup 1)
7371 ;; Convert lea to the lea pattern to avoid flags dependency.
7373 [(set (match_operand 0 "register_operand" "")
7374 (plus (match_operand 1 "register_operand" "")
7375 (match_operand 2 "nonmemory_operand" "")))
7376 (clobber (reg:CC FLAGS_REG))]
7377 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7381 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7382 may confuse gen_lowpart. */
7383 if (GET_MODE (operands[0]) != Pmode)
7385 operands[1] = gen_lowpart (Pmode, operands[1]);
7386 operands[2] = gen_lowpart (Pmode, operands[2]);
7388 operands[0] = gen_lowpart (SImode, operands[0]);
7389 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7390 if (Pmode != SImode)
7391 pat = gen_rtx_SUBREG (SImode, pat, 0);
7392 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7396 ;; Convert lea to the lea pattern to avoid flags dependency.
7398 [(set (match_operand:DI 0 "register_operand" "")
7400 (plus:SI (match_operand:SI 1 "register_operand" "")
7401 (match_operand:SI 2 "nonmemory_operand" ""))))
7402 (clobber (reg:CC FLAGS_REG))]
7403 "TARGET_64BIT && reload_completed
7404 && true_regnum (operands[0]) != true_regnum (operands[1])"
7406 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7408 operands[1] = gen_lowpart (Pmode, operands[1]);
7409 operands[2] = gen_lowpart (Pmode, operands[2]);
7412 ;; Subtract instructions
7414 (define_expand "sub<mode>3"
7415 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7416 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7417 (match_operand:SDWIM 2 "<general_operand>" "")))]
7419 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7421 (define_insn_and_split "*sub<dwi>3_doubleword"
7422 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7424 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7425 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7426 (clobber (reg:CC FLAGS_REG))]
7427 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7430 [(parallel [(set (reg:CC FLAGS_REG)
7431 (compare:CC (match_dup 1) (match_dup 2)))
7433 (minus:DWIH (match_dup 1) (match_dup 2)))])
7434 (parallel [(set (match_dup 3)
7438 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7440 (clobber (reg:CC FLAGS_REG))])]
7441 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7443 (define_insn "sub<mode>3_carry"
7444 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7446 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7448 (match_operand:SWI 3 "ix86_carry_flag_operator" "")
7449 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7450 (clobber (reg:CC FLAGS_REG))]
7451 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7452 "sbb{<imodesuffix>}\t{%2, %0|%0, %2}"
7453 [(set_attr "type" "alu")
7454 (set_attr "use_carry" "1")
7455 (set_attr "pent_pair" "pu")
7456 (set_attr "mode" "<MODE>")])
7458 (define_insn "*subsi3_carry_zext"
7459 [(set (match_operand:DI 0 "register_operand" "=r")
7461 (minus:SI (match_operand:SI 1 "register_operand" "0")
7462 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
7463 (match_operand:SI 2 "general_operand" "g")))))
7464 (clobber (reg:CC FLAGS_REG))]
7465 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7466 "sbb{l}\t{%2, %k0|%k0, %2}"
7467 [(set_attr "type" "alu")
7468 (set_attr "pent_pair" "pu")
7469 (set_attr "mode" "SI")])
7471 (define_insn "*sub<mode>3_cconly_overflow"
7472 [(set (reg:CCC FLAGS_REG)
7475 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7476 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7479 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7480 [(set_attr "type" "icmp")
7481 (set_attr "mode" "<MODE>")])
7483 (define_insn "*sub<mode>_1"
7484 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7486 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7487 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7488 (clobber (reg:CC FLAGS_REG))]
7489 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7490 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7491 [(set_attr "type" "alu")
7492 (set_attr "mode" "<MODE>")])
7494 (define_insn "*subsi_1_zext"
7495 [(set (match_operand:DI 0 "register_operand" "=r")
7497 (minus:SI (match_operand:SI 1 "register_operand" "0")
7498 (match_operand:SI 2 "general_operand" "g"))))
7499 (clobber (reg:CC FLAGS_REG))]
7500 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7501 "sub{l}\t{%2, %k0|%k0, %2}"
7502 [(set_attr "type" "alu")
7503 (set_attr "mode" "SI")])
7505 (define_insn "*subqi_1_slp"
7506 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7507 (minus:QI (match_dup 0)
7508 (match_operand:QI 1 "general_operand" "qn,qm")))
7509 (clobber (reg:CC FLAGS_REG))]
7510 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7511 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7512 "sub{b}\t{%1, %0|%0, %1}"
7513 [(set_attr "type" "alu1")
7514 (set_attr "mode" "QI")])
7516 (define_insn "*sub<mode>_2"
7517 [(set (reg FLAGS_REG)
7520 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7521 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7523 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7524 (minus:SWI (match_dup 1) (match_dup 2)))]
7525 "ix86_match_ccmode (insn, CCGOCmode)
7526 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7527 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7528 [(set_attr "type" "alu")
7529 (set_attr "mode" "<MODE>")])
7531 (define_insn "*subsi_2_zext"
7532 [(set (reg FLAGS_REG)
7534 (minus:SI (match_operand:SI 1 "register_operand" "0")
7535 (match_operand:SI 2 "general_operand" "g"))
7537 (set (match_operand:DI 0 "register_operand" "=r")
7539 (minus:SI (match_dup 1)
7541 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7542 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7543 "sub{l}\t{%2, %k0|%k0, %2}"
7544 [(set_attr "type" "alu")
7545 (set_attr "mode" "SI")])
7547 (define_insn "*sub<mode>_3"
7548 [(set (reg FLAGS_REG)
7549 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7550 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7551 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7552 (minus:SWI (match_dup 1) (match_dup 2)))]
7553 "ix86_match_ccmode (insn, CCmode)
7554 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7555 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7556 [(set_attr "type" "alu")
7557 (set_attr "mode" "<MODE>")])
7559 (define_insn "*subsi_3_zext"
7560 [(set (reg FLAGS_REG)
7561 (compare (match_operand:SI 1 "register_operand" "0")
7562 (match_operand:SI 2 "general_operand" "g")))
7563 (set (match_operand:DI 0 "register_operand" "=r")
7565 (minus:SI (match_dup 1)
7567 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7568 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7569 "sub{l}\t{%2, %1|%1, %2}"
7570 [(set_attr "type" "alu")
7571 (set_attr "mode" "SI")])
7574 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7575 [(set (reg:CCC FLAGS_REG)
7578 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7579 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7581 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7582 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7583 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7584 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7585 [(set_attr "type" "alu")
7586 (set_attr "mode" "<MODE>")])
7588 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7589 [(set (reg:CCC FLAGS_REG)
7592 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7593 (match_operand:SI 2 "general_operand" "g"))
7595 (set (match_operand:DI 0 "register_operand" "=r")
7596 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7597 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7598 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7599 [(set_attr "type" "alu")
7600 (set_attr "mode" "SI")])
7602 ;; The patterns that match these are at the end of this file.
7604 (define_expand "<plusminus_insn>xf3"
7605 [(set (match_operand:XF 0 "register_operand" "")
7607 (match_operand:XF 1 "register_operand" "")
7608 (match_operand:XF 2 "register_operand" "")))]
7612 (define_expand "<plusminus_insn><mode>3"
7613 [(set (match_operand:MODEF 0 "register_operand" "")
7615 (match_operand:MODEF 1 "register_operand" "")
7616 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7617 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7618 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7621 ;; Multiply instructions
7623 (define_expand "mul<mode>3"
7624 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7626 (match_operand:SWIM248 1 "register_operand" "")
7627 (match_operand:SWIM248 2 "<general_operand>" "")))
7628 (clobber (reg:CC FLAGS_REG))])]
7632 (define_expand "mulqi3"
7633 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7635 (match_operand:QI 1 "register_operand" "")
7636 (match_operand:QI 2 "nonimmediate_operand" "")))
7637 (clobber (reg:CC FLAGS_REG))])]
7638 "TARGET_QIMODE_MATH"
7642 ;; IMUL reg32/64, reg32/64, imm8 Direct
7643 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7644 ;; IMUL reg32/64, reg32/64, imm32 Direct
7645 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7646 ;; IMUL reg32/64, reg32/64 Direct
7647 ;; IMUL reg32/64, mem32/64 Direct
7649 (define_insn "*mul<mode>3_1"
7650 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7652 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7653 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7654 (clobber (reg:CC FLAGS_REG))]
7655 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7657 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7658 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7659 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7660 [(set_attr "type" "imul")
7661 (set_attr "prefix_0f" "0,0,1")
7662 (set (attr "athlon_decode")
7663 (cond [(eq_attr "cpu" "athlon")
7664 (const_string "vector")
7665 (eq_attr "alternative" "1")
7666 (const_string "vector")
7667 (and (eq_attr "alternative" "2")
7668 (match_operand 1 "memory_operand" ""))
7669 (const_string "vector")]
7670 (const_string "direct")))
7671 (set (attr "amdfam10_decode")
7672 (cond [(and (eq_attr "alternative" "0,1")
7673 (match_operand 1 "memory_operand" ""))
7674 (const_string "vector")]
7675 (const_string "direct")))
7676 (set_attr "mode" "<MODE>")])
7678 (define_insn "*mulsi3_1_zext"
7679 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7681 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7682 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7683 (clobber (reg:CC FLAGS_REG))]
7685 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7687 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7688 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7689 imul{l}\t{%2, %k0|%k0, %2}"
7690 [(set_attr "type" "imul")
7691 (set_attr "prefix_0f" "0,0,1")
7692 (set (attr "athlon_decode")
7693 (cond [(eq_attr "cpu" "athlon")
7694 (const_string "vector")
7695 (eq_attr "alternative" "1")
7696 (const_string "vector")
7697 (and (eq_attr "alternative" "2")
7698 (match_operand 1 "memory_operand" ""))
7699 (const_string "vector")]
7700 (const_string "direct")))
7701 (set (attr "amdfam10_decode")
7702 (cond [(and (eq_attr "alternative" "0,1")
7703 (match_operand 1 "memory_operand" ""))
7704 (const_string "vector")]
7705 (const_string "direct")))
7706 (set_attr "mode" "SI")])
7709 ;; IMUL reg16, reg16, imm8 VectorPath
7710 ;; IMUL reg16, mem16, imm8 VectorPath
7711 ;; IMUL reg16, reg16, imm16 VectorPath
7712 ;; IMUL reg16, mem16, imm16 VectorPath
7713 ;; IMUL reg16, reg16 Direct
7714 ;; IMUL reg16, mem16 Direct
7716 (define_insn "*mulhi3_1"
7717 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7718 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7719 (match_operand:HI 2 "general_operand" "K,n,mr")))
7720 (clobber (reg:CC FLAGS_REG))]
7722 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7724 imul{w}\t{%2, %1, %0|%0, %1, %2}
7725 imul{w}\t{%2, %1, %0|%0, %1, %2}
7726 imul{w}\t{%2, %0|%0, %2}"
7727 [(set_attr "type" "imul")
7728 (set_attr "prefix_0f" "0,0,1")
7729 (set (attr "athlon_decode")
7730 (cond [(eq_attr "cpu" "athlon")
7731 (const_string "vector")
7732 (eq_attr "alternative" "1,2")
7733 (const_string "vector")]
7734 (const_string "direct")))
7735 (set (attr "amdfam10_decode")
7736 (cond [(eq_attr "alternative" "0,1")
7737 (const_string "vector")]
7738 (const_string "direct")))
7739 (set_attr "mode" "HI")])
7745 (define_insn "*mulqi3_1"
7746 [(set (match_operand:QI 0 "register_operand" "=a")
7747 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7748 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7749 (clobber (reg:CC FLAGS_REG))]
7751 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7753 [(set_attr "type" "imul")
7754 (set_attr "length_immediate" "0")
7755 (set (attr "athlon_decode")
7756 (if_then_else (eq_attr "cpu" "athlon")
7757 (const_string "vector")
7758 (const_string "direct")))
7759 (set_attr "amdfam10_decode" "direct")
7760 (set_attr "mode" "QI")])
7762 (define_expand "<u>mul<mode><dwi>3"
7763 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7766 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7768 (match_operand:DWIH 2 "register_operand" ""))))
7769 (clobber (reg:CC FLAGS_REG))])]
7773 (define_expand "<u>mulqihi3"
7774 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7777 (match_operand:QI 1 "nonimmediate_operand" ""))
7779 (match_operand:QI 2 "register_operand" ""))))
7780 (clobber (reg:CC FLAGS_REG))])]
7781 "TARGET_QIMODE_MATH"
7784 (define_insn "*<u>mul<mode><dwi>3_1"
7785 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7788 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7790 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7791 (clobber (reg:CC FLAGS_REG))]
7792 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7793 "<sgnprefix>mul{<imodesuffix>}\t%2"
7794 [(set_attr "type" "imul")
7795 (set_attr "length_immediate" "0")
7796 (set (attr "athlon_decode")
7797 (if_then_else (eq_attr "cpu" "athlon")
7798 (const_string "vector")
7799 (const_string "double")))
7800 (set_attr "amdfam10_decode" "double")
7801 (set_attr "mode" "<MODE>")])
7803 (define_insn "*<u>mulqihi3_1"
7804 [(set (match_operand:HI 0 "register_operand" "=a")
7807 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7809 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7810 (clobber (reg:CC FLAGS_REG))]
7812 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7813 "<sgnprefix>mul{b}\t%2"
7814 [(set_attr "type" "imul")
7815 (set_attr "length_immediate" "0")
7816 (set (attr "athlon_decode")
7817 (if_then_else (eq_attr "cpu" "athlon")
7818 (const_string "vector")
7819 (const_string "direct")))
7820 (set_attr "amdfam10_decode" "direct")
7821 (set_attr "mode" "QI")])
7823 (define_expand "<s>mul<mode>3_highpart"
7824 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7829 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7831 (match_operand:SWI48 2 "register_operand" "")))
7833 (clobber (match_scratch:SWI48 3 ""))
7834 (clobber (reg:CC FLAGS_REG))])]
7836 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7838 (define_insn "*<s>muldi3_highpart_1"
7839 [(set (match_operand:DI 0 "register_operand" "=d")
7844 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7846 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7848 (clobber (match_scratch:DI 3 "=1"))
7849 (clobber (reg:CC FLAGS_REG))]
7851 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7852 "<sgnprefix>mul{q}\t%2"
7853 [(set_attr "type" "imul")
7854 (set_attr "length_immediate" "0")
7855 (set (attr "athlon_decode")
7856 (if_then_else (eq_attr "cpu" "athlon")
7857 (const_string "vector")
7858 (const_string "double")))
7859 (set_attr "amdfam10_decode" "double")
7860 (set_attr "mode" "DI")])
7862 (define_insn "*<s>mulsi3_highpart_1"
7863 [(set (match_operand:SI 0 "register_operand" "=d")
7868 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7870 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7872 (clobber (match_scratch:SI 3 "=1"))
7873 (clobber (reg:CC FLAGS_REG))]
7874 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7875 "<sgnprefix>mul{l}\t%2"
7876 [(set_attr "type" "imul")
7877 (set_attr "length_immediate" "0")
7878 (set (attr "athlon_decode")
7879 (if_then_else (eq_attr "cpu" "athlon")
7880 (const_string "vector")
7881 (const_string "double")))
7882 (set_attr "amdfam10_decode" "double")
7883 (set_attr "mode" "SI")])
7885 (define_insn "*<s>mulsi3_highpart_zext"
7886 [(set (match_operand:DI 0 "register_operand" "=d")
7887 (zero_extend:DI (truncate:SI
7889 (mult:DI (any_extend:DI
7890 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7892 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7894 (clobber (match_scratch:SI 3 "=1"))
7895 (clobber (reg:CC FLAGS_REG))]
7897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7898 "<sgnprefix>mul{l}\t%2"
7899 [(set_attr "type" "imul")
7900 (set_attr "length_immediate" "0")
7901 (set (attr "athlon_decode")
7902 (if_then_else (eq_attr "cpu" "athlon")
7903 (const_string "vector")
7904 (const_string "double")))
7905 (set_attr "amdfam10_decode" "double")
7906 (set_attr "mode" "SI")])
7908 ;; The patterns that match these are at the end of this file.
7910 (define_expand "mulxf3"
7911 [(set (match_operand:XF 0 "register_operand" "")
7912 (mult:XF (match_operand:XF 1 "register_operand" "")
7913 (match_operand:XF 2 "register_operand" "")))]
7917 (define_expand "mul<mode>3"
7918 [(set (match_operand:MODEF 0 "register_operand" "")
7919 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7920 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7921 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7922 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7925 ;; Divide instructions
7927 (define_insn "<u>divqi3"
7928 [(set (match_operand:QI 0 "register_operand" "=a")
7930 (match_operand:HI 1 "register_operand" "0")
7931 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7932 (clobber (reg:CC FLAGS_REG))]
7933 "TARGET_QIMODE_MATH"
7934 "<sgnprefix>div{b}\t%2"
7935 [(set_attr "type" "idiv")
7936 (set_attr "mode" "QI")])
7938 ;; The patterns that match these are at the end of this file.
7940 (define_expand "divxf3"
7941 [(set (match_operand:XF 0 "register_operand" "")
7942 (div:XF (match_operand:XF 1 "register_operand" "")
7943 (match_operand:XF 2 "register_operand" "")))]
7947 (define_expand "divdf3"
7948 [(set (match_operand:DF 0 "register_operand" "")
7949 (div:DF (match_operand:DF 1 "register_operand" "")
7950 (match_operand:DF 2 "nonimmediate_operand" "")))]
7951 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7952 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7955 (define_expand "divsf3"
7956 [(set (match_operand:SF 0 "register_operand" "")
7957 (div:SF (match_operand:SF 1 "register_operand" "")
7958 (match_operand:SF 2 "nonimmediate_operand" "")))]
7959 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7962 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7963 && flag_finite_math_only && !flag_trapping_math
7964 && flag_unsafe_math_optimizations)
7966 ix86_emit_swdivsf (operands[0], operands[1],
7967 operands[2], SFmode);
7972 ;; Divmod instructions.
7974 (define_expand "divmod<mode>4"
7975 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7977 (match_operand:SWIM248 1 "register_operand" "")
7978 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7979 (set (match_operand:SWIM248 3 "register_operand" "")
7980 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7981 (clobber (reg:CC FLAGS_REG))])]
7985 (define_insn_and_split "*divmod<mode>4"
7986 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7987 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7988 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7989 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7990 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7991 (clobber (reg:CC FLAGS_REG))]
7994 "&& reload_completed"
7995 [(parallel [(set (match_dup 1)
7996 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7997 (clobber (reg:CC FLAGS_REG))])
7998 (parallel [(set (match_dup 0)
7999 (div:SWIM248 (match_dup 2) (match_dup 3)))
8001 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8003 (clobber (reg:CC FLAGS_REG))])]
8005 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8007 if (<MODE>mode != HImode
8008 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8009 operands[4] = operands[2];
8012 /* Avoid use of cltd in favor of a mov+shift. */
8013 emit_move_insn (operands[1], operands[2]);
8014 operands[4] = operands[1];
8017 [(set_attr "type" "multi")
8018 (set_attr "mode" "<MODE>")])
8020 (define_insn "*divmod<mode>4_noext"
8021 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8022 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8023 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8024 (set (match_operand:SWIM248 1 "register_operand" "=d")
8025 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8026 (use (match_operand:SWIM248 4 "register_operand" "1"))
8027 (clobber (reg:CC FLAGS_REG))]
8029 "idiv{<imodesuffix>}\t%3"
8030 [(set_attr "type" "idiv")
8031 (set_attr "mode" "<MODE>")])
8033 (define_expand "udivmod<mode>4"
8034 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8036 (match_operand:SWIM248 1 "register_operand" "")
8037 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8038 (set (match_operand:SWIM248 3 "register_operand" "")
8039 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8040 (clobber (reg:CC FLAGS_REG))])]
8044 (define_insn_and_split "*udivmod<mode>4"
8045 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8046 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8047 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8048 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8049 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8050 (clobber (reg:CC FLAGS_REG))]
8053 "&& reload_completed"
8054 [(set (match_dup 1) (const_int 0))
8055 (parallel [(set (match_dup 0)
8056 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8058 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8060 (clobber (reg:CC FLAGS_REG))])]
8062 [(set_attr "type" "multi")
8063 (set_attr "mode" "<MODE>")])
8065 (define_insn "*udivmod<mode>4_noext"
8066 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8067 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8068 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8069 (set (match_operand:SWIM248 1 "register_operand" "=d")
8070 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8071 (use (match_operand:SWIM248 4 "register_operand" "1"))
8072 (clobber (reg:CC FLAGS_REG))]
8074 "div{<imodesuffix>}\t%3"
8075 [(set_attr "type" "idiv")
8076 (set_attr "mode" "<MODE>")])
8078 ;; We cannot use div/idiv for double division, because it causes
8079 ;; "division by zero" on the overflow and that's not what we expect
8080 ;; from truncate. Because true (non truncating) double division is
8081 ;; never generated, we can't create this insn anyway.
8084 ; [(set (match_operand:SI 0 "register_operand" "=a")
8086 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8088 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8089 ; (set (match_operand:SI 3 "register_operand" "=d")
8091 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8092 ; (clobber (reg:CC FLAGS_REG))]
8094 ; "div{l}\t{%2, %0|%0, %2}"
8095 ; [(set_attr "type" "idiv")])
8097 ;;- Logical AND instructions
8099 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8100 ;; Note that this excludes ah.
8102 (define_insn "*testdi_1_rex64"
8103 [(set (reg FLAGS_REG)
8105 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8106 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8108 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8109 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8111 test{l}\t{%k1, %k0|%k0, %k1}
8112 test{l}\t{%k1, %k0|%k0, %k1}
8113 test{q}\t{%1, %0|%0, %1}
8114 test{q}\t{%1, %0|%0, %1}
8115 test{q}\t{%1, %0|%0, %1}"
8116 [(set_attr "type" "test")
8117 (set_attr "modrm" "0,1,0,1,1")
8118 (set_attr "mode" "SI,SI,DI,DI,DI")
8119 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8121 (define_insn "testsi_1"
8122 [(set (reg FLAGS_REG)
8124 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8125 (match_operand:SI 1 "general_operand" "i,i,ri"))
8127 "ix86_match_ccmode (insn, CCNOmode)
8128 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8129 "test{l}\t{%1, %0|%0, %1}"
8130 [(set_attr "type" "test")
8131 (set_attr "modrm" "0,1,1")
8132 (set_attr "mode" "SI")
8133 (set_attr "pent_pair" "uv,np,uv")])
8135 (define_expand "testsi_ccno_1"
8136 [(set (reg:CCNO FLAGS_REG)
8138 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8139 (match_operand:SI 1 "nonmemory_operand" ""))
8144 (define_insn "*testhi_1"
8145 [(set (reg FLAGS_REG)
8146 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8147 (match_operand:HI 1 "general_operand" "n,n,rn"))
8149 "ix86_match_ccmode (insn, CCNOmode)
8150 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8151 "test{w}\t{%1, %0|%0, %1}"
8152 [(set_attr "type" "test")
8153 (set_attr "modrm" "0,1,1")
8154 (set_attr "mode" "HI")
8155 (set_attr "pent_pair" "uv,np,uv")])
8157 (define_expand "testqi_ccz_1"
8158 [(set (reg:CCZ FLAGS_REG)
8159 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8160 (match_operand:QI 1 "nonmemory_operand" ""))
8165 (define_insn "*testqi_1_maybe_si"
8166 [(set (reg FLAGS_REG)
8169 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8170 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8172 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8173 && ix86_match_ccmode (insn,
8174 CONST_INT_P (operands[1])
8175 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8177 if (which_alternative == 3)
8179 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8180 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8181 return "test{l}\t{%1, %k0|%k0, %1}";
8183 return "test{b}\t{%1, %0|%0, %1}";
8185 [(set_attr "type" "test")
8186 (set_attr "modrm" "0,1,1,1")
8187 (set_attr "mode" "QI,QI,QI,SI")
8188 (set_attr "pent_pair" "uv,np,uv,np")])
8190 (define_insn "*testqi_1"
8191 [(set (reg FLAGS_REG)
8194 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8195 (match_operand:QI 1 "general_operand" "n,n,qn"))
8197 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8198 && ix86_match_ccmode (insn, CCNOmode)"
8199 "test{b}\t{%1, %0|%0, %1}"
8200 [(set_attr "type" "test")
8201 (set_attr "modrm" "0,1,1")
8202 (set_attr "mode" "QI")
8203 (set_attr "pent_pair" "uv,np,uv")])
8205 (define_expand "testqi_ext_ccno_0"
8206 [(set (reg:CCNO FLAGS_REG)
8210 (match_operand 0 "ext_register_operand" "")
8213 (match_operand 1 "const_int_operand" ""))
8218 (define_insn "*testqi_ext_0"
8219 [(set (reg FLAGS_REG)
8223 (match_operand 0 "ext_register_operand" "Q")
8226 (match_operand 1 "const_int_operand" "n"))
8228 "ix86_match_ccmode (insn, CCNOmode)"
8229 "test{b}\t{%1, %h0|%h0, %1}"
8230 [(set_attr "type" "test")
8231 (set_attr "mode" "QI")
8232 (set_attr "length_immediate" "1")
8233 (set_attr "modrm" "1")
8234 (set_attr "pent_pair" "np")])
8236 (define_insn "*testqi_ext_1"
8237 [(set (reg FLAGS_REG)
8241 (match_operand 0 "ext_register_operand" "Q")
8245 (match_operand:QI 1 "general_operand" "Qm")))
8247 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8248 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8249 "test{b}\t{%1, %h0|%h0, %1}"
8250 [(set_attr "type" "test")
8251 (set_attr "mode" "QI")])
8253 (define_insn "*testqi_ext_1_rex64"
8254 [(set (reg FLAGS_REG)
8258 (match_operand 0 "ext_register_operand" "Q")
8262 (match_operand:QI 1 "register_operand" "Q")))
8264 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8265 "test{b}\t{%1, %h0|%h0, %1}"
8266 [(set_attr "type" "test")
8267 (set_attr "mode" "QI")])
8269 (define_insn "*testqi_ext_2"
8270 [(set (reg FLAGS_REG)
8274 (match_operand 0 "ext_register_operand" "Q")
8278 (match_operand 1 "ext_register_operand" "Q")
8282 "ix86_match_ccmode (insn, CCNOmode)"
8283 "test{b}\t{%h1, %h0|%h0, %h1}"
8284 [(set_attr "type" "test")
8285 (set_attr "mode" "QI")])
8287 ;; Combine likes to form bit extractions for some tests. Humor it.
8288 (define_insn "*testqi_ext_3"
8289 [(set (reg FLAGS_REG)
8290 (compare (zero_extract:SI
8291 (match_operand 0 "nonimmediate_operand" "rm")
8292 (match_operand:SI 1 "const_int_operand" "")
8293 (match_operand:SI 2 "const_int_operand" ""))
8295 "ix86_match_ccmode (insn, CCNOmode)
8296 && INTVAL (operands[1]) > 0
8297 && INTVAL (operands[2]) >= 0
8298 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8299 && (GET_MODE (operands[0]) == SImode
8300 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8301 || GET_MODE (operands[0]) == HImode
8302 || GET_MODE (operands[0]) == QImode)"
8305 (define_insn "*testqi_ext_3_rex64"
8306 [(set (reg FLAGS_REG)
8307 (compare (zero_extract:DI
8308 (match_operand 0 "nonimmediate_operand" "rm")
8309 (match_operand:DI 1 "const_int_operand" "")
8310 (match_operand:DI 2 "const_int_operand" ""))
8313 && ix86_match_ccmode (insn, CCNOmode)
8314 && INTVAL (operands[1]) > 0
8315 && INTVAL (operands[2]) >= 0
8316 /* Ensure that resulting mask is zero or sign extended operand. */
8317 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8318 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8319 && INTVAL (operands[1]) > 32))
8320 && (GET_MODE (operands[0]) == SImode
8321 || GET_MODE (operands[0]) == DImode
8322 || GET_MODE (operands[0]) == HImode
8323 || GET_MODE (operands[0]) == QImode)"
8327 [(set (match_operand 0 "flags_reg_operand" "")
8328 (match_operator 1 "compare_operator"
8330 (match_operand 2 "nonimmediate_operand" "")
8331 (match_operand 3 "const_int_operand" "")
8332 (match_operand 4 "const_int_operand" ""))
8334 "ix86_match_ccmode (insn, CCNOmode)"
8335 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8337 rtx val = operands[2];
8338 HOST_WIDE_INT len = INTVAL (operands[3]);
8339 HOST_WIDE_INT pos = INTVAL (operands[4]);
8341 enum machine_mode mode, submode;
8343 mode = GET_MODE (val);
8346 /* ??? Combine likes to put non-volatile mem extractions in QImode
8347 no matter the size of the test. So find a mode that works. */
8348 if (! MEM_VOLATILE_P (val))
8350 mode = smallest_mode_for_size (pos + len, MODE_INT);
8351 val = adjust_address (val, mode, 0);
8354 else if (GET_CODE (val) == SUBREG
8355 && (submode = GET_MODE (SUBREG_REG (val)),
8356 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8357 && pos + len <= GET_MODE_BITSIZE (submode)
8358 && GET_MODE_CLASS (submode) == MODE_INT)
8360 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8362 val = SUBREG_REG (val);
8364 else if (mode == HImode && pos + len <= 8)
8366 /* Small HImode tests can be converted to QImode. */
8368 val = gen_lowpart (QImode, val);
8371 if (len == HOST_BITS_PER_WIDE_INT)
8374 mask = ((HOST_WIDE_INT)1 << len) - 1;
8377 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8380 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8381 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8382 ;; this is relatively important trick.
8383 ;; Do the conversion only post-reload to avoid limiting of the register class
8386 [(set (match_operand 0 "flags_reg_operand" "")
8387 (match_operator 1 "compare_operator"
8388 [(and (match_operand 2 "register_operand" "")
8389 (match_operand 3 "const_int_operand" ""))
8392 && QI_REG_P (operands[2])
8393 && GET_MODE (operands[2]) != QImode
8394 && ((ix86_match_ccmode (insn, CCZmode)
8395 && !(INTVAL (operands[3]) & ~(255 << 8)))
8396 || (ix86_match_ccmode (insn, CCNOmode)
8397 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8400 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8403 "operands[2] = gen_lowpart (SImode, operands[2]);
8404 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8407 [(set (match_operand 0 "flags_reg_operand" "")
8408 (match_operator 1 "compare_operator"
8409 [(and (match_operand 2 "nonimmediate_operand" "")
8410 (match_operand 3 "const_int_operand" ""))
8413 && GET_MODE (operands[2]) != QImode
8414 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8415 && ((ix86_match_ccmode (insn, CCZmode)
8416 && !(INTVAL (operands[3]) & ~255))
8417 || (ix86_match_ccmode (insn, CCNOmode)
8418 && !(INTVAL (operands[3]) & ~127)))"
8420 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8422 "operands[2] = gen_lowpart (QImode, operands[2]);
8423 operands[3] = gen_lowpart (QImode, operands[3]);")
8426 ;; %%% This used to optimize known byte-wide and operations to memory,
8427 ;; and sometimes to QImode registers. If this is considered useful,
8428 ;; it should be done with splitters.
8430 (define_expand "anddi3"
8431 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8432 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8433 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8435 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8437 (define_insn "*anddi_1_rex64"
8438 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8439 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8440 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8441 (clobber (reg:CC FLAGS_REG))]
8442 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8444 switch (get_attr_type (insn))
8448 enum machine_mode mode;
8450 gcc_assert (CONST_INT_P (operands[2]));
8451 if (INTVAL (operands[2]) == 0xff)
8455 gcc_assert (INTVAL (operands[2]) == 0xffff);
8459 operands[1] = gen_lowpart (mode, operands[1]);
8461 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8463 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8467 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8468 if (get_attr_mode (insn) == MODE_SI)
8469 return "and{l}\t{%k2, %k0|%k0, %k2}";
8471 return "and{q}\t{%2, %0|%0, %2}";
8474 [(set_attr "type" "alu,alu,alu,imovx")
8475 (set_attr "length_immediate" "*,*,*,0")
8476 (set (attr "prefix_rex")
8478 (and (eq_attr "type" "imovx")
8479 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8480 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8482 (const_string "*")))
8483 (set_attr "mode" "SI,DI,DI,SI")])
8485 (define_insn "*anddi_2"
8486 [(set (reg FLAGS_REG)
8487 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8488 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8490 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8491 (and:DI (match_dup 1) (match_dup 2)))]
8492 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8493 && ix86_binary_operator_ok (AND, DImode, operands)"
8495 and{l}\t{%k2, %k0|%k0, %k2}
8496 and{q}\t{%2, %0|%0, %2}
8497 and{q}\t{%2, %0|%0, %2}"
8498 [(set_attr "type" "alu")
8499 (set_attr "mode" "SI,DI,DI")])
8501 (define_expand "andsi3"
8502 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8503 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8504 (match_operand:SI 2 "general_operand" "")))]
8506 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8508 (define_insn "*andsi_1"
8509 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8510 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8511 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8512 (clobber (reg:CC FLAGS_REG))]
8513 "ix86_binary_operator_ok (AND, SImode, operands)"
8515 switch (get_attr_type (insn))
8519 enum machine_mode mode;
8521 gcc_assert (CONST_INT_P (operands[2]));
8522 if (INTVAL (operands[2]) == 0xff)
8526 gcc_assert (INTVAL (operands[2]) == 0xffff);
8530 operands[1] = gen_lowpart (mode, operands[1]);
8532 return "movz{bl|x}\t{%1, %0|%0, %1}";
8534 return "movz{wl|x}\t{%1, %0|%0, %1}";
8538 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8539 return "and{l}\t{%2, %0|%0, %2}";
8542 [(set_attr "type" "alu,alu,imovx")
8543 (set (attr "prefix_rex")
8545 (and (eq_attr "type" "imovx")
8546 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8547 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8549 (const_string "*")))
8550 (set_attr "length_immediate" "*,*,0")
8551 (set_attr "mode" "SI")])
8554 [(set (match_operand 0 "register_operand" "")
8556 (const_int -65536)))
8557 (clobber (reg:CC FLAGS_REG))]
8558 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8559 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8560 "operands[1] = gen_lowpart (HImode, operands[0]);")
8563 [(set (match_operand 0 "ext_register_operand" "")
8566 (clobber (reg:CC FLAGS_REG))]
8567 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8568 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8569 "operands[1] = gen_lowpart (QImode, operands[0]);")
8572 [(set (match_operand 0 "ext_register_operand" "")
8574 (const_int -65281)))
8575 (clobber (reg:CC FLAGS_REG))]
8576 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8577 [(parallel [(set (zero_extract:SI (match_dup 0)
8581 (zero_extract:SI (match_dup 0)
8584 (zero_extract:SI (match_dup 0)
8587 (clobber (reg:CC FLAGS_REG))])]
8588 "operands[0] = gen_lowpart (SImode, operands[0]);")
8590 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8591 (define_insn "*andsi_1_zext"
8592 [(set (match_operand:DI 0 "register_operand" "=r")
8594 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8595 (match_operand:SI 2 "general_operand" "g"))))
8596 (clobber (reg:CC FLAGS_REG))]
8597 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8598 "and{l}\t{%2, %k0|%k0, %2}"
8599 [(set_attr "type" "alu")
8600 (set_attr "mode" "SI")])
8602 (define_insn "*andsi_2"
8603 [(set (reg FLAGS_REG)
8604 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8605 (match_operand:SI 2 "general_operand" "g,ri"))
8607 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8608 (and:SI (match_dup 1) (match_dup 2)))]
8609 "ix86_match_ccmode (insn, CCNOmode)
8610 && ix86_binary_operator_ok (AND, SImode, operands)"
8611 "and{l}\t{%2, %0|%0, %2}"
8612 [(set_attr "type" "alu")
8613 (set_attr "mode" "SI")])
8615 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8616 (define_insn "*andsi_2_zext"
8617 [(set (reg FLAGS_REG)
8618 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8619 (match_operand:SI 2 "general_operand" "g"))
8621 (set (match_operand:DI 0 "register_operand" "=r")
8622 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8623 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8624 && ix86_binary_operator_ok (AND, SImode, operands)"
8625 "and{l}\t{%2, %k0|%k0, %2}"
8626 [(set_attr "type" "alu")
8627 (set_attr "mode" "SI")])
8629 (define_expand "andhi3"
8630 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8631 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8632 (match_operand:HI 2 "general_operand" "")))]
8633 "TARGET_HIMODE_MATH"
8634 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8636 (define_insn "*andhi_1"
8637 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8638 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8639 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8640 (clobber (reg:CC FLAGS_REG))]
8641 "ix86_binary_operator_ok (AND, HImode, operands)"
8643 switch (get_attr_type (insn))
8646 gcc_assert (CONST_INT_P (operands[2]));
8647 gcc_assert (INTVAL (operands[2]) == 0xff);
8648 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8651 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8653 return "and{w}\t{%2, %0|%0, %2}";
8656 [(set_attr "type" "alu,alu,imovx")
8657 (set_attr "length_immediate" "*,*,0")
8658 (set (attr "prefix_rex")
8660 (and (eq_attr "type" "imovx")
8661 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8663 (const_string "*")))
8664 (set_attr "mode" "HI,HI,SI")])
8666 (define_insn "*andhi_2"
8667 [(set (reg FLAGS_REG)
8668 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8669 (match_operand:HI 2 "general_operand" "rmn,rn"))
8671 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8672 (and:HI (match_dup 1) (match_dup 2)))]
8673 "ix86_match_ccmode (insn, CCNOmode)
8674 && ix86_binary_operator_ok (AND, HImode, operands)"
8675 "and{w}\t{%2, %0|%0, %2}"
8676 [(set_attr "type" "alu")
8677 (set_attr "mode" "HI")])
8679 (define_expand "andqi3"
8680 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8681 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8682 (match_operand:QI 2 "general_operand" "")))]
8683 "TARGET_QIMODE_MATH"
8684 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8686 ;; %%% Potential partial reg stall on alternative 2. What to do?
8687 (define_insn "*andqi_1"
8688 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8689 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8690 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8691 (clobber (reg:CC FLAGS_REG))]
8692 "ix86_binary_operator_ok (AND, QImode, operands)"
8694 and{b}\t{%2, %0|%0, %2}
8695 and{b}\t{%2, %0|%0, %2}
8696 and{l}\t{%k2, %k0|%k0, %k2}"
8697 [(set_attr "type" "alu")
8698 (set_attr "mode" "QI,QI,SI")])
8700 (define_insn "*andqi_1_slp"
8701 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8702 (and:QI (match_dup 0)
8703 (match_operand:QI 1 "general_operand" "qn,qmn")))
8704 (clobber (reg:CC FLAGS_REG))]
8705 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8706 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8707 "and{b}\t{%1, %0|%0, %1}"
8708 [(set_attr "type" "alu1")
8709 (set_attr "mode" "QI")])
8711 (define_insn "*andqi_2_maybe_si"
8712 [(set (reg FLAGS_REG)
8714 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8715 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8717 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8718 (and:QI (match_dup 1) (match_dup 2)))]
8719 "ix86_binary_operator_ok (AND, QImode, operands)
8720 && ix86_match_ccmode (insn,
8721 CONST_INT_P (operands[2])
8722 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8724 if (which_alternative == 2)
8726 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8727 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8728 return "and{l}\t{%2, %k0|%k0, %2}";
8730 return "and{b}\t{%2, %0|%0, %2}";
8732 [(set_attr "type" "alu")
8733 (set_attr "mode" "QI,QI,SI")])
8735 (define_insn "*andqi_2"
8736 [(set (reg FLAGS_REG)
8738 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8739 (match_operand:QI 2 "general_operand" "qmn,qn"))
8741 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8742 (and:QI (match_dup 1) (match_dup 2)))]
8743 "ix86_match_ccmode (insn, CCNOmode)
8744 && ix86_binary_operator_ok (AND, QImode, operands)"
8745 "and{b}\t{%2, %0|%0, %2}"
8746 [(set_attr "type" "alu")
8747 (set_attr "mode" "QI")])
8749 (define_insn "*andqi_2_slp"
8750 [(set (reg FLAGS_REG)
8752 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8753 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8755 (set (strict_low_part (match_dup 0))
8756 (and:QI (match_dup 0) (match_dup 1)))]
8757 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8758 && ix86_match_ccmode (insn, CCNOmode)
8759 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8760 "and{b}\t{%1, %0|%0, %1}"
8761 [(set_attr "type" "alu1")
8762 (set_attr "mode" "QI")])
8764 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8765 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8766 ;; for a QImode operand, which of course failed.
8768 (define_insn "andqi_ext_0"
8769 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8774 (match_operand 1 "ext_register_operand" "0")
8777 (match_operand 2 "const_int_operand" "n")))
8778 (clobber (reg:CC FLAGS_REG))]
8780 "and{b}\t{%2, %h0|%h0, %2}"
8781 [(set_attr "type" "alu")
8782 (set_attr "length_immediate" "1")
8783 (set_attr "modrm" "1")
8784 (set_attr "mode" "QI")])
8786 ;; Generated by peephole translating test to and. This shows up
8787 ;; often in fp comparisons.
8789 (define_insn "*andqi_ext_0_cc"
8790 [(set (reg FLAGS_REG)
8794 (match_operand 1 "ext_register_operand" "0")
8797 (match_operand 2 "const_int_operand" "n"))
8799 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8808 "ix86_match_ccmode (insn, CCNOmode)"
8809 "and{b}\t{%2, %h0|%h0, %2}"
8810 [(set_attr "type" "alu")
8811 (set_attr "length_immediate" "1")
8812 (set_attr "modrm" "1")
8813 (set_attr "mode" "QI")])
8815 (define_insn "*andqi_ext_1"
8816 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8821 (match_operand 1 "ext_register_operand" "0")
8825 (match_operand:QI 2 "general_operand" "Qm"))))
8826 (clobber (reg:CC FLAGS_REG))]
8828 "and{b}\t{%2, %h0|%h0, %2}"
8829 [(set_attr "type" "alu")
8830 (set_attr "length_immediate" "0")
8831 (set_attr "mode" "QI")])
8833 (define_insn "*andqi_ext_1_rex64"
8834 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8839 (match_operand 1 "ext_register_operand" "0")
8843 (match_operand 2 "ext_register_operand" "Q"))))
8844 (clobber (reg:CC FLAGS_REG))]
8846 "and{b}\t{%2, %h0|%h0, %2}"
8847 [(set_attr "type" "alu")
8848 (set_attr "length_immediate" "0")
8849 (set_attr "mode" "QI")])
8851 (define_insn "*andqi_ext_2"
8852 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8857 (match_operand 1 "ext_register_operand" "%0")
8861 (match_operand 2 "ext_register_operand" "Q")
8864 (clobber (reg:CC FLAGS_REG))]
8866 "and{b}\t{%h2, %h0|%h0, %h2}"
8867 [(set_attr "type" "alu")
8868 (set_attr "length_immediate" "0")
8869 (set_attr "mode" "QI")])
8871 ;; Convert wide AND instructions with immediate operand to shorter QImode
8872 ;; equivalents when possible.
8873 ;; Don't do the splitting with memory operands, since it introduces risk
8874 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8875 ;; for size, but that can (should?) be handled by generic code instead.
8877 [(set (match_operand 0 "register_operand" "")
8878 (and (match_operand 1 "register_operand" "")
8879 (match_operand 2 "const_int_operand" "")))
8880 (clobber (reg:CC FLAGS_REG))]
8882 && QI_REG_P (operands[0])
8883 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8884 && !(~INTVAL (operands[2]) & ~(255 << 8))
8885 && GET_MODE (operands[0]) != QImode"
8886 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8887 (and:SI (zero_extract:SI (match_dup 1)
8888 (const_int 8) (const_int 8))
8890 (clobber (reg:CC FLAGS_REG))])]
8891 "operands[0] = gen_lowpart (SImode, operands[0]);
8892 operands[1] = gen_lowpart (SImode, operands[1]);
8893 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8895 ;; Since AND can be encoded with sign extended immediate, this is only
8896 ;; profitable when 7th bit is not set.
8898 [(set (match_operand 0 "register_operand" "")
8899 (and (match_operand 1 "general_operand" "")
8900 (match_operand 2 "const_int_operand" "")))
8901 (clobber (reg:CC FLAGS_REG))]
8903 && ANY_QI_REG_P (operands[0])
8904 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8905 && !(~INTVAL (operands[2]) & ~255)
8906 && !(INTVAL (operands[2]) & 128)
8907 && GET_MODE (operands[0]) != QImode"
8908 [(parallel [(set (strict_low_part (match_dup 0))
8909 (and:QI (match_dup 1)
8911 (clobber (reg:CC FLAGS_REG))])]
8912 "operands[0] = gen_lowpart (QImode, operands[0]);
8913 operands[1] = gen_lowpart (QImode, operands[1]);
8914 operands[2] = gen_lowpart (QImode, operands[2]);")
8916 ;; Logical inclusive OR instructions
8918 ;; %%% This used to optimize known byte-wide and operations to memory.
8919 ;; If this is considered useful, it should be done with splitters.
8921 (define_expand "iordi3"
8922 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8923 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8924 (match_operand:DI 2 "x86_64_general_operand" "")))]
8926 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8928 (define_insn "*iordi_1_rex64"
8929 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8930 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8931 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8932 (clobber (reg:CC FLAGS_REG))]
8934 && ix86_binary_operator_ok (IOR, DImode, operands)"
8935 "or{q}\t{%2, %0|%0, %2}"
8936 [(set_attr "type" "alu")
8937 (set_attr "mode" "DI")])
8939 (define_insn "*iordi_2_rex64"
8940 [(set (reg FLAGS_REG)
8941 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8942 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8944 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8945 (ior:DI (match_dup 1) (match_dup 2)))]
8947 && ix86_match_ccmode (insn, CCNOmode)
8948 && ix86_binary_operator_ok (IOR, DImode, operands)"
8949 "or{q}\t{%2, %0|%0, %2}"
8950 [(set_attr "type" "alu")
8951 (set_attr "mode" "DI")])
8953 (define_insn "*iordi_3_rex64"
8954 [(set (reg FLAGS_REG)
8955 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8956 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8958 (clobber (match_scratch:DI 0 "=r"))]
8960 && ix86_match_ccmode (insn, CCNOmode)
8961 && ix86_binary_operator_ok (IOR, DImode, operands)"
8962 "or{q}\t{%2, %0|%0, %2}"
8963 [(set_attr "type" "alu")
8964 (set_attr "mode" "DI")])
8967 (define_expand "iorsi3"
8968 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8969 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8970 (match_operand:SI 2 "general_operand" "")))]
8972 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8974 (define_insn "*iorsi_1"
8975 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8976 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8977 (match_operand:SI 2 "general_operand" "ri,g")))
8978 (clobber (reg:CC FLAGS_REG))]
8979 "ix86_binary_operator_ok (IOR, SImode, operands)"
8980 "or{l}\t{%2, %0|%0, %2}"
8981 [(set_attr "type" "alu")
8982 (set_attr "mode" "SI")])
8984 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8985 (define_insn "*iorsi_1_zext"
8986 [(set (match_operand:DI 0 "register_operand" "=r")
8988 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8989 (match_operand:SI 2 "general_operand" "g"))))
8990 (clobber (reg:CC FLAGS_REG))]
8991 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8992 "or{l}\t{%2, %k0|%k0, %2}"
8993 [(set_attr "type" "alu")
8994 (set_attr "mode" "SI")])
8996 (define_insn "*iorsi_1_zext_imm"
8997 [(set (match_operand:DI 0 "register_operand" "=r")
8998 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8999 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9000 (clobber (reg:CC FLAGS_REG))]
9002 "or{l}\t{%2, %k0|%k0, %2}"
9003 [(set_attr "type" "alu")
9004 (set_attr "mode" "SI")])
9006 (define_insn "*iorsi_2"
9007 [(set (reg FLAGS_REG)
9008 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9009 (match_operand:SI 2 "general_operand" "g,ri"))
9011 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9012 (ior:SI (match_dup 1) (match_dup 2)))]
9013 "ix86_match_ccmode (insn, CCNOmode)
9014 && ix86_binary_operator_ok (IOR, SImode, operands)"
9015 "or{l}\t{%2, %0|%0, %2}"
9016 [(set_attr "type" "alu")
9017 (set_attr "mode" "SI")])
9019 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9020 ;; ??? Special case for immediate operand is missing - it is tricky.
9021 (define_insn "*iorsi_2_zext"
9022 [(set (reg FLAGS_REG)
9023 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9024 (match_operand:SI 2 "general_operand" "g"))
9026 (set (match_operand:DI 0 "register_operand" "=r")
9027 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9028 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9029 && ix86_binary_operator_ok (IOR, SImode, operands)"
9030 "or{l}\t{%2, %k0|%k0, %2}"
9031 [(set_attr "type" "alu")
9032 (set_attr "mode" "SI")])
9034 (define_insn "*iorsi_2_zext_imm"
9035 [(set (reg FLAGS_REG)
9036 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9037 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9039 (set (match_operand:DI 0 "register_operand" "=r")
9040 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9041 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9042 && ix86_binary_operator_ok (IOR, SImode, operands)"
9043 "or{l}\t{%2, %k0|%k0, %2}"
9044 [(set_attr "type" "alu")
9045 (set_attr "mode" "SI")])
9047 (define_insn "*iorsi_3"
9048 [(set (reg FLAGS_REG)
9049 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9050 (match_operand:SI 2 "general_operand" "g"))
9052 (clobber (match_scratch:SI 0 "=r"))]
9053 "ix86_match_ccmode (insn, CCNOmode)
9054 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9055 "or{l}\t{%2, %0|%0, %2}"
9056 [(set_attr "type" "alu")
9057 (set_attr "mode" "SI")])
9059 (define_expand "iorhi3"
9060 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9061 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9062 (match_operand:HI 2 "general_operand" "")))]
9063 "TARGET_HIMODE_MATH"
9064 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9066 (define_insn "*iorhi_1"
9067 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9068 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9069 (match_operand:HI 2 "general_operand" "rmn,rn")))
9070 (clobber (reg:CC FLAGS_REG))]
9071 "ix86_binary_operator_ok (IOR, HImode, operands)"
9072 "or{w}\t{%2, %0|%0, %2}"
9073 [(set_attr "type" "alu")
9074 (set_attr "mode" "HI")])
9076 (define_insn "*iorhi_2"
9077 [(set (reg FLAGS_REG)
9078 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9079 (match_operand:HI 2 "general_operand" "rmn,rn"))
9081 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9082 (ior:HI (match_dup 1) (match_dup 2)))]
9083 "ix86_match_ccmode (insn, CCNOmode)
9084 && ix86_binary_operator_ok (IOR, HImode, operands)"
9085 "or{w}\t{%2, %0|%0, %2}"
9086 [(set_attr "type" "alu")
9087 (set_attr "mode" "HI")])
9089 (define_insn "*iorhi_3"
9090 [(set (reg FLAGS_REG)
9091 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9092 (match_operand:HI 2 "general_operand" "rmn"))
9094 (clobber (match_scratch:HI 0 "=r"))]
9095 "ix86_match_ccmode (insn, CCNOmode)
9096 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9097 "or{w}\t{%2, %0|%0, %2}"
9098 [(set_attr "type" "alu")
9099 (set_attr "mode" "HI")])
9101 (define_expand "iorqi3"
9102 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9103 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9104 (match_operand:QI 2 "general_operand" "")))]
9105 "TARGET_QIMODE_MATH"
9106 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9108 ;; %%% Potential partial reg stall on alternative 2. What to do?
9109 (define_insn "*iorqi_1"
9110 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9111 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9112 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9113 (clobber (reg:CC FLAGS_REG))]
9114 "ix86_binary_operator_ok (IOR, QImode, operands)"
9116 or{b}\t{%2, %0|%0, %2}
9117 or{b}\t{%2, %0|%0, %2}
9118 or{l}\t{%k2, %k0|%k0, %k2}"
9119 [(set_attr "type" "alu")
9120 (set_attr "mode" "QI,QI,SI")])
9122 (define_insn "*iorqi_1_slp"
9123 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9124 (ior:QI (match_dup 0)
9125 (match_operand:QI 1 "general_operand" "qmn,qn")))
9126 (clobber (reg:CC FLAGS_REG))]
9127 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9128 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9129 "or{b}\t{%1, %0|%0, %1}"
9130 [(set_attr "type" "alu1")
9131 (set_attr "mode" "QI")])
9133 (define_insn "*iorqi_2"
9134 [(set (reg FLAGS_REG)
9135 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9136 (match_operand:QI 2 "general_operand" "qmn,qn"))
9138 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9139 (ior:QI (match_dup 1) (match_dup 2)))]
9140 "ix86_match_ccmode (insn, CCNOmode)
9141 && ix86_binary_operator_ok (IOR, QImode, operands)"
9142 "or{b}\t{%2, %0|%0, %2}"
9143 [(set_attr "type" "alu")
9144 (set_attr "mode" "QI")])
9146 (define_insn "*iorqi_2_slp"
9147 [(set (reg FLAGS_REG)
9148 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9149 (match_operand:QI 1 "general_operand" "qmn,qn"))
9151 (set (strict_low_part (match_dup 0))
9152 (ior:QI (match_dup 0) (match_dup 1)))]
9153 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9154 && ix86_match_ccmode (insn, CCNOmode)
9155 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9156 "or{b}\t{%1, %0|%0, %1}"
9157 [(set_attr "type" "alu1")
9158 (set_attr "mode" "QI")])
9160 (define_insn "*iorqi_3"
9161 [(set (reg FLAGS_REG)
9162 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9163 (match_operand:QI 2 "general_operand" "qmn"))
9165 (clobber (match_scratch:QI 0 "=q"))]
9166 "ix86_match_ccmode (insn, CCNOmode)
9167 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9168 "or{b}\t{%2, %0|%0, %2}"
9169 [(set_attr "type" "alu")
9170 (set_attr "mode" "QI")])
9172 (define_insn "*iorqi_ext_0"
9173 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9178 (match_operand 1 "ext_register_operand" "0")
9181 (match_operand 2 "const_int_operand" "n")))
9182 (clobber (reg:CC FLAGS_REG))]
9183 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9184 "or{b}\t{%2, %h0|%h0, %2}"
9185 [(set_attr "type" "alu")
9186 (set_attr "length_immediate" "1")
9187 (set_attr "modrm" "1")
9188 (set_attr "mode" "QI")])
9190 (define_insn "*iorqi_ext_1"
9191 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9196 (match_operand 1 "ext_register_operand" "0")
9200 (match_operand:QI 2 "general_operand" "Qm"))))
9201 (clobber (reg:CC FLAGS_REG))]
9203 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9204 "or{b}\t{%2, %h0|%h0, %2}"
9205 [(set_attr "type" "alu")
9206 (set_attr "length_immediate" "0")
9207 (set_attr "mode" "QI")])
9209 (define_insn "*iorqi_ext_1_rex64"
9210 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9215 (match_operand 1 "ext_register_operand" "0")
9219 (match_operand 2 "ext_register_operand" "Q"))))
9220 (clobber (reg:CC FLAGS_REG))]
9222 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9223 "or{b}\t{%2, %h0|%h0, %2}"
9224 [(set_attr "type" "alu")
9225 (set_attr "length_immediate" "0")
9226 (set_attr "mode" "QI")])
9228 (define_insn "*iorqi_ext_2"
9229 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9233 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9236 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9239 (clobber (reg:CC FLAGS_REG))]
9240 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9241 "ior{b}\t{%h2, %h0|%h0, %h2}"
9242 [(set_attr "type" "alu")
9243 (set_attr "length_immediate" "0")
9244 (set_attr "mode" "QI")])
9247 [(set (match_operand 0 "register_operand" "")
9248 (ior (match_operand 1 "register_operand" "")
9249 (match_operand 2 "const_int_operand" "")))
9250 (clobber (reg:CC FLAGS_REG))]
9252 && QI_REG_P (operands[0])
9253 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9254 && !(INTVAL (operands[2]) & ~(255 << 8))
9255 && GET_MODE (operands[0]) != QImode"
9256 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9257 (ior:SI (zero_extract:SI (match_dup 1)
9258 (const_int 8) (const_int 8))
9260 (clobber (reg:CC FLAGS_REG))])]
9261 "operands[0] = gen_lowpart (SImode, operands[0]);
9262 operands[1] = gen_lowpart (SImode, operands[1]);
9263 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9265 ;; Since OR can be encoded with sign extended immediate, this is only
9266 ;; profitable when 7th bit is set.
9268 [(set (match_operand 0 "register_operand" "")
9269 (ior (match_operand 1 "general_operand" "")
9270 (match_operand 2 "const_int_operand" "")))
9271 (clobber (reg:CC FLAGS_REG))]
9273 && ANY_QI_REG_P (operands[0])
9274 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9275 && !(INTVAL (operands[2]) & ~255)
9276 && (INTVAL (operands[2]) & 128)
9277 && GET_MODE (operands[0]) != QImode"
9278 [(parallel [(set (strict_low_part (match_dup 0))
9279 (ior:QI (match_dup 1)
9281 (clobber (reg:CC FLAGS_REG))])]
9282 "operands[0] = gen_lowpart (QImode, operands[0]);
9283 operands[1] = gen_lowpart (QImode, operands[1]);
9284 operands[2] = gen_lowpart (QImode, operands[2]);")
9286 ;; Logical XOR instructions
9288 ;; %%% This used to optimize known byte-wide and operations to memory.
9289 ;; If this is considered useful, it should be done with splitters.
9291 (define_expand "xordi3"
9292 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9293 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9294 (match_operand:DI 2 "x86_64_general_operand" "")))]
9296 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9298 (define_insn "*xordi_1_rex64"
9299 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9300 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9301 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9302 (clobber (reg:CC FLAGS_REG))]
9304 && ix86_binary_operator_ok (XOR, DImode, operands)"
9305 "xor{q}\t{%2, %0|%0, %2}"
9306 [(set_attr "type" "alu")
9307 (set_attr "mode" "DI")])
9309 (define_insn "*xordi_2_rex64"
9310 [(set (reg FLAGS_REG)
9311 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9312 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9314 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9315 (xor:DI (match_dup 1) (match_dup 2)))]
9317 && ix86_match_ccmode (insn, CCNOmode)
9318 && ix86_binary_operator_ok (XOR, DImode, operands)"
9319 "xor{q}\t{%2, %0|%0, %2}"
9320 [(set_attr "type" "alu")
9321 (set_attr "mode" "DI")])
9323 (define_insn "*xordi_3_rex64"
9324 [(set (reg FLAGS_REG)
9325 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9326 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9328 (clobber (match_scratch:DI 0 "=r"))]
9330 && ix86_match_ccmode (insn, CCNOmode)
9331 && ix86_binary_operator_ok (XOR, DImode, operands)"
9332 "xor{q}\t{%2, %0|%0, %2}"
9333 [(set_attr "type" "alu")
9334 (set_attr "mode" "DI")])
9336 (define_expand "xorsi3"
9337 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9338 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9339 (match_operand:SI 2 "general_operand" "")))]
9341 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9343 (define_insn "*xorsi_1"
9344 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9345 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9346 (match_operand:SI 2 "general_operand" "ri,rm")))
9347 (clobber (reg:CC FLAGS_REG))]
9348 "ix86_binary_operator_ok (XOR, SImode, operands)"
9349 "xor{l}\t{%2, %0|%0, %2}"
9350 [(set_attr "type" "alu")
9351 (set_attr "mode" "SI")])
9353 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9354 ;; Add speccase for immediates
9355 (define_insn "*xorsi_1_zext"
9356 [(set (match_operand:DI 0 "register_operand" "=r")
9358 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9359 (match_operand:SI 2 "general_operand" "g"))))
9360 (clobber (reg:CC FLAGS_REG))]
9361 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9362 "xor{l}\t{%2, %k0|%k0, %2}"
9363 [(set_attr "type" "alu")
9364 (set_attr "mode" "SI")])
9366 (define_insn "*xorsi_1_zext_imm"
9367 [(set (match_operand:DI 0 "register_operand" "=r")
9368 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9369 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9370 (clobber (reg:CC FLAGS_REG))]
9371 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9372 "xor{l}\t{%2, %k0|%k0, %2}"
9373 [(set_attr "type" "alu")
9374 (set_attr "mode" "SI")])
9376 (define_insn "*xorsi_2"
9377 [(set (reg FLAGS_REG)
9378 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9379 (match_operand:SI 2 "general_operand" "g,ri"))
9381 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9382 (xor:SI (match_dup 1) (match_dup 2)))]
9383 "ix86_match_ccmode (insn, CCNOmode)
9384 && ix86_binary_operator_ok (XOR, SImode, operands)"
9385 "xor{l}\t{%2, %0|%0, %2}"
9386 [(set_attr "type" "alu")
9387 (set_attr "mode" "SI")])
9389 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9390 ;; ??? Special case for immediate operand is missing - it is tricky.
9391 (define_insn "*xorsi_2_zext"
9392 [(set (reg FLAGS_REG)
9393 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9394 (match_operand:SI 2 "general_operand" "g"))
9396 (set (match_operand:DI 0 "register_operand" "=r")
9397 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9398 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9399 && ix86_binary_operator_ok (XOR, SImode, operands)"
9400 "xor{l}\t{%2, %k0|%k0, %2}"
9401 [(set_attr "type" "alu")
9402 (set_attr "mode" "SI")])
9404 (define_insn "*xorsi_2_zext_imm"
9405 [(set (reg FLAGS_REG)
9406 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9407 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9409 (set (match_operand:DI 0 "register_operand" "=r")
9410 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9411 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9412 && ix86_binary_operator_ok (XOR, SImode, operands)"
9413 "xor{l}\t{%2, %k0|%k0, %2}"
9414 [(set_attr "type" "alu")
9415 (set_attr "mode" "SI")])
9417 (define_insn "*xorsi_3"
9418 [(set (reg FLAGS_REG)
9419 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9420 (match_operand:SI 2 "general_operand" "g"))
9422 (clobber (match_scratch:SI 0 "=r"))]
9423 "ix86_match_ccmode (insn, CCNOmode)
9424 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9425 "xor{l}\t{%2, %0|%0, %2}"
9426 [(set_attr "type" "alu")
9427 (set_attr "mode" "SI")])
9429 (define_expand "xorhi3"
9430 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9431 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9432 (match_operand:HI 2 "general_operand" "")))]
9433 "TARGET_HIMODE_MATH"
9434 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9436 (define_insn "*xorhi_1"
9437 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9438 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9439 (match_operand:HI 2 "general_operand" "rmn,rn")))
9440 (clobber (reg:CC FLAGS_REG))]
9441 "ix86_binary_operator_ok (XOR, HImode, operands)"
9442 "xor{w}\t{%2, %0|%0, %2}"
9443 [(set_attr "type" "alu")
9444 (set_attr "mode" "HI")])
9446 (define_insn "*xorhi_2"
9447 [(set (reg FLAGS_REG)
9448 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9449 (match_operand:HI 2 "general_operand" "rmn,rn"))
9451 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9452 (xor:HI (match_dup 1) (match_dup 2)))]
9453 "ix86_match_ccmode (insn, CCNOmode)
9454 && ix86_binary_operator_ok (XOR, HImode, operands)"
9455 "xor{w}\t{%2, %0|%0, %2}"
9456 [(set_attr "type" "alu")
9457 (set_attr "mode" "HI")])
9459 (define_insn "*xorhi_3"
9460 [(set (reg FLAGS_REG)
9461 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9462 (match_operand:HI 2 "general_operand" "rmn"))
9464 (clobber (match_scratch:HI 0 "=r"))]
9465 "ix86_match_ccmode (insn, CCNOmode)
9466 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9467 "xor{w}\t{%2, %0|%0, %2}"
9468 [(set_attr "type" "alu")
9469 (set_attr "mode" "HI")])
9471 (define_expand "xorqi3"
9472 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9473 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9474 (match_operand:QI 2 "general_operand" "")))]
9475 "TARGET_QIMODE_MATH"
9476 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9478 ;; %%% Potential partial reg stall on alternative 2. What to do?
9479 (define_insn "*xorqi_1"
9480 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9481 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9482 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9483 (clobber (reg:CC FLAGS_REG))]
9484 "ix86_binary_operator_ok (XOR, QImode, operands)"
9486 xor{b}\t{%2, %0|%0, %2}
9487 xor{b}\t{%2, %0|%0, %2}
9488 xor{l}\t{%k2, %k0|%k0, %k2}"
9489 [(set_attr "type" "alu")
9490 (set_attr "mode" "QI,QI,SI")])
9492 (define_insn "*xorqi_1_slp"
9493 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9494 (xor:QI (match_dup 0)
9495 (match_operand:QI 1 "general_operand" "qn,qmn")))
9496 (clobber (reg:CC FLAGS_REG))]
9497 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9498 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9499 "xor{b}\t{%1, %0|%0, %1}"
9500 [(set_attr "type" "alu1")
9501 (set_attr "mode" "QI")])
9503 (define_insn "*xorqi_ext_0"
9504 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9509 (match_operand 1 "ext_register_operand" "0")
9512 (match_operand 2 "const_int_operand" "n")))
9513 (clobber (reg:CC FLAGS_REG))]
9514 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9515 "xor{b}\t{%2, %h0|%h0, %2}"
9516 [(set_attr "type" "alu")
9517 (set_attr "length_immediate" "1")
9518 (set_attr "modrm" "1")
9519 (set_attr "mode" "QI")])
9521 (define_insn "*xorqi_ext_1"
9522 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9527 (match_operand 1 "ext_register_operand" "0")
9531 (match_operand:QI 2 "general_operand" "Qm"))))
9532 (clobber (reg:CC FLAGS_REG))]
9534 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9535 "xor{b}\t{%2, %h0|%h0, %2}"
9536 [(set_attr "type" "alu")
9537 (set_attr "length_immediate" "0")
9538 (set_attr "mode" "QI")])
9540 (define_insn "*xorqi_ext_1_rex64"
9541 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9546 (match_operand 1 "ext_register_operand" "0")
9550 (match_operand 2 "ext_register_operand" "Q"))))
9551 (clobber (reg:CC FLAGS_REG))]
9553 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9554 "xor{b}\t{%2, %h0|%h0, %2}"
9555 [(set_attr "type" "alu")
9556 (set_attr "length_immediate" "0")
9557 (set_attr "mode" "QI")])
9559 (define_insn "*xorqi_ext_2"
9560 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9564 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9567 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9570 (clobber (reg:CC FLAGS_REG))]
9571 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9572 "xor{b}\t{%h2, %h0|%h0, %h2}"
9573 [(set_attr "type" "alu")
9574 (set_attr "length_immediate" "0")
9575 (set_attr "mode" "QI")])
9577 (define_insn "*xorqi_cc_1"
9578 [(set (reg FLAGS_REG)
9580 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9581 (match_operand:QI 2 "general_operand" "qmn,qn"))
9583 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9584 (xor:QI (match_dup 1) (match_dup 2)))]
9585 "ix86_match_ccmode (insn, CCNOmode)
9586 && ix86_binary_operator_ok (XOR, QImode, operands)"
9587 "xor{b}\t{%2, %0|%0, %2}"
9588 [(set_attr "type" "alu")
9589 (set_attr "mode" "QI")])
9591 (define_insn "*xorqi_2_slp"
9592 [(set (reg FLAGS_REG)
9593 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9594 (match_operand:QI 1 "general_operand" "qmn,qn"))
9596 (set (strict_low_part (match_dup 0))
9597 (xor:QI (match_dup 0) (match_dup 1)))]
9598 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9599 && ix86_match_ccmode (insn, CCNOmode)
9600 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9601 "xor{b}\t{%1, %0|%0, %1}"
9602 [(set_attr "type" "alu1")
9603 (set_attr "mode" "QI")])
9605 (define_insn "*xorqi_cc_2"
9606 [(set (reg FLAGS_REG)
9608 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9609 (match_operand:QI 2 "general_operand" "qmn"))
9611 (clobber (match_scratch:QI 0 "=q"))]
9612 "ix86_match_ccmode (insn, CCNOmode)
9613 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9614 "xor{b}\t{%2, %0|%0, %2}"
9615 [(set_attr "type" "alu")
9616 (set_attr "mode" "QI")])
9618 (define_insn "*xorqi_cc_ext_1"
9619 [(set (reg FLAGS_REG)
9623 (match_operand 1 "ext_register_operand" "0")
9626 (match_operand:QI 2 "general_operand" "qmn"))
9628 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9632 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9634 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9635 "xor{b}\t{%2, %h0|%h0, %2}"
9636 [(set_attr "type" "alu")
9637 (set_attr "modrm" "1")
9638 (set_attr "mode" "QI")])
9640 (define_insn "*xorqi_cc_ext_1_rex64"
9641 [(set (reg FLAGS_REG)
9645 (match_operand 1 "ext_register_operand" "0")
9648 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9650 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9654 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9656 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9657 "xor{b}\t{%2, %h0|%h0, %2}"
9658 [(set_attr "type" "alu")
9659 (set_attr "modrm" "1")
9660 (set_attr "mode" "QI")])
9662 (define_expand "xorqi_cc_ext_1"
9664 (set (reg:CCNO FLAGS_REG)
9668 (match_operand 1 "ext_register_operand" "")
9671 (match_operand:QI 2 "general_operand" ""))
9673 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9677 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9683 [(set (match_operand 0 "register_operand" "")
9684 (xor (match_operand 1 "register_operand" "")
9685 (match_operand 2 "const_int_operand" "")))
9686 (clobber (reg:CC FLAGS_REG))]
9688 && QI_REG_P (operands[0])
9689 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9690 && !(INTVAL (operands[2]) & ~(255 << 8))
9691 && GET_MODE (operands[0]) != QImode"
9692 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9693 (xor:SI (zero_extract:SI (match_dup 1)
9694 (const_int 8) (const_int 8))
9696 (clobber (reg:CC FLAGS_REG))])]
9697 "operands[0] = gen_lowpart (SImode, operands[0]);
9698 operands[1] = gen_lowpart (SImode, operands[1]);
9699 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9701 ;; Since XOR can be encoded with sign extended immediate, this is only
9702 ;; profitable when 7th bit is set.
9704 [(set (match_operand 0 "register_operand" "")
9705 (xor (match_operand 1 "general_operand" "")
9706 (match_operand 2 "const_int_operand" "")))
9707 (clobber (reg:CC FLAGS_REG))]
9709 && ANY_QI_REG_P (operands[0])
9710 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9711 && !(INTVAL (operands[2]) & ~255)
9712 && (INTVAL (operands[2]) & 128)
9713 && GET_MODE (operands[0]) != QImode"
9714 [(parallel [(set (strict_low_part (match_dup 0))
9715 (xor:QI (match_dup 1)
9717 (clobber (reg:CC FLAGS_REG))])]
9718 "operands[0] = gen_lowpart (QImode, operands[0]);
9719 operands[1] = gen_lowpart (QImode, operands[1]);
9720 operands[2] = gen_lowpart (QImode, operands[2]);")
9722 ;; Negation instructions
9724 (define_expand "negti2"
9725 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9726 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
9728 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
9730 (define_insn "*negti2_1"
9731 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
9732 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
9733 (clobber (reg:CC FLAGS_REG))]
9735 && ix86_unary_operator_ok (NEG, TImode, operands)"
9739 [(set (match_operand:TI 0 "nonimmediate_operand" "")
9740 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
9741 (clobber (reg:CC FLAGS_REG))]
9742 "TARGET_64BIT && reload_completed"
9744 [(set (reg:CCZ FLAGS_REG)
9745 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
9746 (set (match_dup 0) (neg:DI (match_dup 1)))])
9749 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
9752 (clobber (reg:CC FLAGS_REG))])
9755 (neg:DI (match_dup 2)))
9756 (clobber (reg:CC FLAGS_REG))])]
9757 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
9759 (define_expand "negdi2"
9760 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9761 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
9763 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
9765 (define_insn "*negdi2_1"
9766 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
9767 (neg:DI (match_operand:DI 1 "general_operand" "0")))
9768 (clobber (reg:CC FLAGS_REG))]
9770 && ix86_unary_operator_ok (NEG, DImode, operands)"
9774 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9775 (neg:DI (match_operand:DI 1 "general_operand" "")))
9776 (clobber (reg:CC FLAGS_REG))]
9777 "!TARGET_64BIT && reload_completed"
9779 [(set (reg:CCZ FLAGS_REG)
9780 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
9781 (set (match_dup 0) (neg:SI (match_dup 1)))])
9784 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
9787 (clobber (reg:CC FLAGS_REG))])
9790 (neg:SI (match_dup 2)))
9791 (clobber (reg:CC FLAGS_REG))])]
9792 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
9794 (define_insn "*negdi2_1_rex64"
9795 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9796 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
9797 (clobber (reg:CC FLAGS_REG))]
9798 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9800 [(set_attr "type" "negnot")
9801 (set_attr "mode" "DI")])
9803 ;; The problem with neg is that it does not perform (compare x 0),
9804 ;; it really performs (compare 0 x), which leaves us with the zero
9805 ;; flag being the only useful item.
9807 (define_insn "*negdi2_cmpz_rex64"
9808 [(set (reg:CCZ FLAGS_REG)
9809 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
9811 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9812 (neg:DI (match_dup 1)))]
9813 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
9815 [(set_attr "type" "negnot")
9816 (set_attr "mode" "DI")])
9819 (define_expand "negsi2"
9820 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9821 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
9823 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
9825 (define_insn "*negsi2_1"
9826 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9827 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
9828 (clobber (reg:CC FLAGS_REG))]
9829 "ix86_unary_operator_ok (NEG, SImode, operands)"
9831 [(set_attr "type" "negnot")
9832 (set_attr "mode" "SI")])
9834 ;; Combine is quite creative about this pattern.
9835 (define_insn "*negsi2_1_zext"
9836 [(set (match_operand:DI 0 "register_operand" "=r")
9837 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9840 (clobber (reg:CC FLAGS_REG))]
9841 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9843 [(set_attr "type" "negnot")
9844 (set_attr "mode" "SI")])
9846 ;; The problem with neg is that it does not perform (compare x 0),
9847 ;; it really performs (compare 0 x), which leaves us with the zero
9848 ;; flag being the only useful item.
9850 (define_insn "*negsi2_cmpz"
9851 [(set (reg:CCZ FLAGS_REG)
9852 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
9854 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
9855 (neg:SI (match_dup 1)))]
9856 "ix86_unary_operator_ok (NEG, SImode, operands)"
9858 [(set_attr "type" "negnot")
9859 (set_attr "mode" "SI")])
9861 (define_insn "*negsi2_cmpz_zext"
9862 [(set (reg:CCZ FLAGS_REG)
9863 (compare:CCZ (lshiftrt:DI
9865 (match_operand:DI 1 "register_operand" "0")
9869 (set (match_operand:DI 0 "register_operand" "=r")
9870 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9873 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9875 [(set_attr "type" "negnot")
9876 (set_attr "mode" "SI")])
9878 (define_expand "neghi2"
9879 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9880 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
9881 "TARGET_HIMODE_MATH"
9882 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
9884 (define_insn "*neghi2_1"
9885 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9886 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
9887 (clobber (reg:CC FLAGS_REG))]
9888 "ix86_unary_operator_ok (NEG, HImode, operands)"
9890 [(set_attr "type" "negnot")
9891 (set_attr "mode" "HI")])
9893 (define_insn "*neghi2_cmpz"
9894 [(set (reg:CCZ FLAGS_REG)
9895 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
9897 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
9898 (neg:HI (match_dup 1)))]
9899 "ix86_unary_operator_ok (NEG, HImode, operands)"
9901 [(set_attr "type" "negnot")
9902 (set_attr "mode" "HI")])
9904 (define_expand "negqi2"
9905 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9906 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
9907 "TARGET_QIMODE_MATH"
9908 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
9910 (define_insn "*negqi2_1"
9911 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9912 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
9913 (clobber (reg:CC FLAGS_REG))]
9914 "ix86_unary_operator_ok (NEG, QImode, operands)"
9916 [(set_attr "type" "negnot")
9917 (set_attr "mode" "QI")])
9919 (define_insn "*negqi2_cmpz"
9920 [(set (reg:CCZ FLAGS_REG)
9921 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
9923 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
9924 (neg:QI (match_dup 1)))]
9925 "ix86_unary_operator_ok (NEG, QImode, operands)"
9927 [(set_attr "type" "negnot")
9928 (set_attr "mode" "QI")])
9930 ;; Changing of sign for FP values is doable using integer unit too.
9932 (define_expand "<code><mode>2"
9933 [(set (match_operand:X87MODEF 0 "register_operand" "")
9934 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9935 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9936 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9938 (define_insn "*absneg<mode>2_mixed"
9939 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9940 (match_operator:MODEF 3 "absneg_operator"
9941 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9942 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9943 (clobber (reg:CC FLAGS_REG))]
9944 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9947 (define_insn "*absneg<mode>2_sse"
9948 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9949 (match_operator:MODEF 3 "absneg_operator"
9950 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9951 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9952 (clobber (reg:CC FLAGS_REG))]
9953 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9956 (define_insn "*absneg<mode>2_i387"
9957 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9958 (match_operator:X87MODEF 3 "absneg_operator"
9959 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9960 (use (match_operand 2 "" ""))
9961 (clobber (reg:CC FLAGS_REG))]
9962 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9965 (define_expand "<code>tf2"
9966 [(set (match_operand:TF 0 "register_operand" "")
9967 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9969 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9971 (define_insn "*absnegtf2_sse"
9972 [(set (match_operand:TF 0 "register_operand" "=x,x")
9973 (match_operator:TF 3 "absneg_operator"
9974 [(match_operand:TF 1 "register_operand" "0,x")]))
9975 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9976 (clobber (reg:CC FLAGS_REG))]
9980 ;; Splitters for fp abs and neg.
9983 [(set (match_operand 0 "fp_register_operand" "")
9984 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9985 (use (match_operand 2 "" ""))
9986 (clobber (reg:CC FLAGS_REG))]
9988 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9991 [(set (match_operand 0 "register_operand" "")
9992 (match_operator 3 "absneg_operator"
9993 [(match_operand 1 "register_operand" "")]))
9994 (use (match_operand 2 "nonimmediate_operand" ""))
9995 (clobber (reg:CC FLAGS_REG))]
9996 "reload_completed && SSE_REG_P (operands[0])"
9997 [(set (match_dup 0) (match_dup 3))]
9999 enum machine_mode mode = GET_MODE (operands[0]);
10000 enum machine_mode vmode = GET_MODE (operands[2]);
10003 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
10004 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
10005 if (operands_match_p (operands[0], operands[2]))
10008 operands[1] = operands[2];
10011 if (GET_CODE (operands[3]) == ABS)
10012 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
10014 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
10019 [(set (match_operand:SF 0 "register_operand" "")
10020 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
10021 (use (match_operand:V4SF 2 "" ""))
10022 (clobber (reg:CC FLAGS_REG))]
10024 [(parallel [(set (match_dup 0) (match_dup 1))
10025 (clobber (reg:CC FLAGS_REG))])]
10028 operands[0] = gen_lowpart (SImode, operands[0]);
10029 if (GET_CODE (operands[1]) == ABS)
10031 tmp = gen_int_mode (0x7fffffff, SImode);
10032 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10036 tmp = gen_int_mode (0x80000000, SImode);
10037 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10043 [(set (match_operand:DF 0 "register_operand" "")
10044 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
10045 (use (match_operand 2 "" ""))
10046 (clobber (reg:CC FLAGS_REG))]
10048 [(parallel [(set (match_dup 0) (match_dup 1))
10049 (clobber (reg:CC FLAGS_REG))])]
10054 tmp = gen_lowpart (DImode, operands[0]);
10055 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
10058 if (GET_CODE (operands[1]) == ABS)
10061 tmp = gen_rtx_NOT (DImode, tmp);
10065 operands[0] = gen_highpart (SImode, operands[0]);
10066 if (GET_CODE (operands[1]) == ABS)
10068 tmp = gen_int_mode (0x7fffffff, SImode);
10069 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10073 tmp = gen_int_mode (0x80000000, SImode);
10074 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10081 [(set (match_operand:XF 0 "register_operand" "")
10082 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
10083 (use (match_operand 2 "" ""))
10084 (clobber (reg:CC FLAGS_REG))]
10086 [(parallel [(set (match_dup 0) (match_dup 1))
10087 (clobber (reg:CC FLAGS_REG))])]
10090 operands[0] = gen_rtx_REG (SImode,
10091 true_regnum (operands[0])
10092 + (TARGET_64BIT ? 1 : 2));
10093 if (GET_CODE (operands[1]) == ABS)
10095 tmp = GEN_INT (0x7fff);
10096 tmp = gen_rtx_AND (SImode, operands[0], tmp);
10100 tmp = GEN_INT (0x8000);
10101 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
10106 ;; Conditionalize these after reload. If they match before reload, we
10107 ;; lose the clobber and ability to use integer instructions.
10109 (define_insn "*<code><mode>2_1"
10110 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
10111 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
10113 && (reload_completed
10114 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10116 [(set_attr "type" "fsgn")
10117 (set_attr "mode" "<MODE>")])
10119 (define_insn "*<code>extendsfdf2"
10120 [(set (match_operand:DF 0 "register_operand" "=f")
10121 (absneg:DF (float_extend:DF
10122 (match_operand:SF 1 "register_operand" "0"))))]
10123 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10125 [(set_attr "type" "fsgn")
10126 (set_attr "mode" "DF")])
10128 (define_insn "*<code>extendsfxf2"
10129 [(set (match_operand:XF 0 "register_operand" "=f")
10130 (absneg:XF (float_extend:XF
10131 (match_operand:SF 1 "register_operand" "0"))))]
10134 [(set_attr "type" "fsgn")
10135 (set_attr "mode" "XF")])
10137 (define_insn "*<code>extenddfxf2"
10138 [(set (match_operand:XF 0 "register_operand" "=f")
10139 (absneg:XF (float_extend:XF
10140 (match_operand:DF 1 "register_operand" "0"))))]
10143 [(set_attr "type" "fsgn")
10144 (set_attr "mode" "XF")])
10146 ;; Copysign instructions
10148 (define_mode_iterator CSGNMODE [SF DF TF])
10149 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10151 (define_expand "copysign<mode>3"
10152 [(match_operand:CSGNMODE 0 "register_operand" "")
10153 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10154 (match_operand:CSGNMODE 2 "register_operand" "")]
10155 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10156 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10158 ix86_expand_copysign (operands);
10162 (define_insn_and_split "copysign<mode>3_const"
10163 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10165 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10166 (match_operand:CSGNMODE 2 "register_operand" "0")
10167 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10169 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10170 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10172 "&& reload_completed"
10175 ix86_split_copysign_const (operands);
10179 (define_insn "copysign<mode>3_var"
10180 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10182 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10183 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10184 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10185 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10187 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10188 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10189 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10193 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10195 [(match_operand:CSGNMODE 2 "register_operand" "")
10196 (match_operand:CSGNMODE 3 "register_operand" "")
10197 (match_operand:<CSGNVMODE> 4 "" "")
10198 (match_operand:<CSGNVMODE> 5 "" "")]
10200 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10201 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10202 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10203 && reload_completed"
10206 ix86_split_copysign_var (operands);
10210 ;; One complement instructions
10212 (define_expand "one_cmpldi2"
10213 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10214 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10216 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
10218 (define_insn "*one_cmpldi2_1_rex64"
10219 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10220 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
10221 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
10223 [(set_attr "type" "negnot")
10224 (set_attr "mode" "DI")])
10226 (define_insn "*one_cmpldi2_2_rex64"
10227 [(set (reg FLAGS_REG)
10228 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10230 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10231 (not:DI (match_dup 1)))]
10232 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10233 && ix86_unary_operator_ok (NOT, DImode, operands)"
10235 [(set_attr "type" "alu1")
10236 (set_attr "mode" "DI")])
10239 [(set (match_operand 0 "flags_reg_operand" "")
10240 (match_operator 2 "compare_operator"
10241 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
10243 (set (match_operand:DI 1 "nonimmediate_operand" "")
10244 (not:DI (match_dup 3)))]
10245 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10246 [(parallel [(set (match_dup 0)
10248 [(xor:DI (match_dup 3) (const_int -1))
10251 (xor:DI (match_dup 3) (const_int -1)))])]
10254 (define_expand "one_cmplsi2"
10255 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10256 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10258 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
10260 (define_insn "*one_cmplsi2_1"
10261 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10262 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
10263 "ix86_unary_operator_ok (NOT, SImode, operands)"
10265 [(set_attr "type" "negnot")
10266 (set_attr "mode" "SI")])
10268 ;; ??? Currently never generated - xor is used instead.
10269 (define_insn "*one_cmplsi2_1_zext"
10270 [(set (match_operand:DI 0 "register_operand" "=r")
10271 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10272 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10274 [(set_attr "type" "negnot")
10275 (set_attr "mode" "SI")])
10277 (define_insn "*one_cmplsi2_2"
10278 [(set (reg FLAGS_REG)
10279 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
10281 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10282 (not:SI (match_dup 1)))]
10283 "ix86_match_ccmode (insn, CCNOmode)
10284 && ix86_unary_operator_ok (NOT, SImode, operands)"
10286 [(set_attr "type" "alu1")
10287 (set_attr "mode" "SI")])
10290 [(set (match_operand 0 "flags_reg_operand" "")
10291 (match_operator 2 "compare_operator"
10292 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
10294 (set (match_operand:SI 1 "nonimmediate_operand" "")
10295 (not:SI (match_dup 3)))]
10296 "ix86_match_ccmode (insn, CCNOmode)"
10297 [(parallel [(set (match_dup 0)
10298 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10301 (xor:SI (match_dup 3) (const_int -1)))])]
10304 ;; ??? Currently never generated - xor is used instead.
10305 (define_insn "*one_cmplsi2_2_zext"
10306 [(set (reg FLAGS_REG)
10307 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10309 (set (match_operand:DI 0 "register_operand" "=r")
10310 (zero_extend:DI (not:SI (match_dup 1))))]
10311 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10312 && ix86_unary_operator_ok (NOT, SImode, operands)"
10314 [(set_attr "type" "alu1")
10315 (set_attr "mode" "SI")])
10318 [(set (match_operand 0 "flags_reg_operand" "")
10319 (match_operator 2 "compare_operator"
10320 [(not:SI (match_operand:SI 3 "register_operand" ""))
10322 (set (match_operand:DI 1 "register_operand" "")
10323 (zero_extend:DI (not:SI (match_dup 3))))]
10324 "ix86_match_ccmode (insn, CCNOmode)"
10325 [(parallel [(set (match_dup 0)
10326 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10329 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10332 (define_expand "one_cmplhi2"
10333 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10334 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
10335 "TARGET_HIMODE_MATH"
10336 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
10338 (define_insn "*one_cmplhi2_1"
10339 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10340 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
10341 "ix86_unary_operator_ok (NOT, HImode, operands)"
10343 [(set_attr "type" "negnot")
10344 (set_attr "mode" "HI")])
10346 (define_insn "*one_cmplhi2_2"
10347 [(set (reg FLAGS_REG)
10348 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
10350 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10351 (not:HI (match_dup 1)))]
10352 "ix86_match_ccmode (insn, CCNOmode)
10353 && ix86_unary_operator_ok (NEG, HImode, operands)"
10355 [(set_attr "type" "alu1")
10356 (set_attr "mode" "HI")])
10359 [(set (match_operand 0 "flags_reg_operand" "")
10360 (match_operator 2 "compare_operator"
10361 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
10363 (set (match_operand:HI 1 "nonimmediate_operand" "")
10364 (not:HI (match_dup 3)))]
10365 "ix86_match_ccmode (insn, CCNOmode)"
10366 [(parallel [(set (match_dup 0)
10367 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
10370 (xor:HI (match_dup 3) (const_int -1)))])]
10373 ;; %%% Potential partial reg stall on alternative 1. What to do?
10374 (define_expand "one_cmplqi2"
10375 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10376 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
10377 "TARGET_QIMODE_MATH"
10378 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
10380 (define_insn "*one_cmplqi2_1"
10381 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10382 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10383 "ix86_unary_operator_ok (NOT, QImode, operands)"
10387 [(set_attr "type" "negnot")
10388 (set_attr "mode" "QI,SI")])
10390 (define_insn "*one_cmplqi2_2"
10391 [(set (reg FLAGS_REG)
10392 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
10394 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10395 (not:QI (match_dup 1)))]
10396 "ix86_match_ccmode (insn, CCNOmode)
10397 && ix86_unary_operator_ok (NOT, QImode, operands)"
10399 [(set_attr "type" "alu1")
10400 (set_attr "mode" "QI")])
10403 [(set (match_operand 0 "flags_reg_operand" "")
10404 (match_operator 2 "compare_operator"
10405 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
10407 (set (match_operand:QI 1 "nonimmediate_operand" "")
10408 (not:QI (match_dup 3)))]
10409 "ix86_match_ccmode (insn, CCNOmode)"
10410 [(parallel [(set (match_dup 0)
10411 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
10414 (xor:QI (match_dup 3) (const_int -1)))])]
10417 ;; Arithmetic shift instructions
10419 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10420 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10421 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10422 ;; from the assembler input.
10424 ;; This instruction shifts the target reg/mem as usual, but instead of
10425 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10426 ;; is a left shift double, bits are taken from the high order bits of
10427 ;; reg, else if the insn is a shift right double, bits are taken from the
10428 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10429 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10431 ;; Since sh[lr]d does not change the `reg' operand, that is done
10432 ;; separately, making all shifts emit pairs of shift double and normal
10433 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10434 ;; support a 63 bit shift, each shift where the count is in a reg expands
10435 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10437 ;; If the shift count is a constant, we need never emit more than one
10438 ;; shift pair, instead using moves and sign extension for counts greater
10441 (define_expand "ashlti3"
10442 [(set (match_operand:TI 0 "register_operand" "")
10443 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10444 (match_operand:QI 2 "nonmemory_operand" "")))]
10446 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10448 ;; This pattern must be defined before *ashlti3_1 to prevent
10449 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10451 (define_insn "*avx_ashlti3"
10452 [(set (match_operand:TI 0 "register_operand" "=x")
10453 (ashift:TI (match_operand:TI 1 "register_operand" "x")
10454 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10457 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10458 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
10460 [(set_attr "type" "sseishft")
10461 (set_attr "prefix" "vex")
10462 (set_attr "length_immediate" "1")
10463 (set_attr "mode" "TI")])
10465 (define_insn "sse2_ashlti3"
10466 [(set (match_operand:TI 0 "register_operand" "=x")
10467 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10468 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10471 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10472 return "pslldq\t{%2, %0|%0, %2}";
10474 [(set_attr "type" "sseishft")
10475 (set_attr "prefix_data16" "1")
10476 (set_attr "length_immediate" "1")
10477 (set_attr "mode" "TI")])
10479 (define_insn "*ashlti3_1"
10480 [(set (match_operand:TI 0 "register_operand" "=&r,r")
10481 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10482 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10483 (clobber (reg:CC FLAGS_REG))]
10486 [(set_attr "type" "multi")])
10489 [(match_scratch:DI 3 "r")
10490 (parallel [(set (match_operand:TI 0 "register_operand" "")
10491 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10492 (match_operand:QI 2 "nonmemory_operand" "")))
10493 (clobber (reg:CC FLAGS_REG))])
10497 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10500 [(set (match_operand:TI 0 "register_operand" "")
10501 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10502 (match_operand:QI 2 "nonmemory_operand" "")))
10503 (clobber (reg:CC FLAGS_REG))]
10504 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10505 ? epilogue_completed : reload_completed)"
10507 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10509 (define_insn "x86_64_shld"
10510 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10511 (ior:DI (ashift:DI (match_dup 0)
10512 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10513 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10514 (minus:QI (const_int 64) (match_dup 2)))))
10515 (clobber (reg:CC FLAGS_REG))]
10517 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10518 [(set_attr "type" "ishift")
10519 (set_attr "prefix_0f" "1")
10520 (set_attr "mode" "DI")
10521 (set_attr "athlon_decode" "vector")
10522 (set_attr "amdfam10_decode" "vector")])
10524 (define_expand "x86_64_shift_adj_1"
10525 [(set (reg:CCZ FLAGS_REG)
10526 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10529 (set (match_operand:DI 0 "register_operand" "")
10530 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10531 (match_operand:DI 1 "register_operand" "")
10534 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10535 (match_operand:DI 3 "register_operand" "r")
10540 (define_expand "x86_64_shift_adj_2"
10541 [(use (match_operand:DI 0 "register_operand" ""))
10542 (use (match_operand:DI 1 "register_operand" ""))
10543 (use (match_operand:QI 2 "register_operand" ""))]
10546 rtx label = gen_label_rtx ();
10549 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10551 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10552 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10553 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10554 gen_rtx_LABEL_REF (VOIDmode, label),
10556 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10557 JUMP_LABEL (tmp) = label;
10559 emit_move_insn (operands[0], operands[1]);
10560 ix86_expand_clear (operands[1]);
10562 emit_label (label);
10563 LABEL_NUSES (label) = 1;
10568 (define_expand "ashldi3"
10569 [(set (match_operand:DI 0 "shiftdi_operand" "")
10570 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10571 (match_operand:QI 2 "nonmemory_operand" "")))]
10573 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10575 (define_insn "*ashldi3_1_rex64"
10576 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10577 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10578 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10579 (clobber (reg:CC FLAGS_REG))]
10580 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10582 switch (get_attr_type (insn))
10585 gcc_assert (operands[2] == const1_rtx);
10586 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10587 return "add{q}\t%0, %0";
10590 gcc_assert (CONST_INT_P (operands[2]));
10591 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10592 operands[1] = gen_rtx_MULT (DImode, operands[1],
10593 GEN_INT (1 << INTVAL (operands[2])));
10594 return "lea{q}\t{%a1, %0|%0, %a1}";
10597 if (REG_P (operands[2]))
10598 return "sal{q}\t{%b2, %0|%0, %b2}";
10599 else if (operands[2] == const1_rtx
10600 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10601 return "sal{q}\t%0";
10603 return "sal{q}\t{%2, %0|%0, %2}";
10606 [(set (attr "type")
10607 (cond [(eq_attr "alternative" "1")
10608 (const_string "lea")
10609 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10611 (match_operand 0 "register_operand" ""))
10612 (match_operand 2 "const1_operand" ""))
10613 (const_string "alu")
10615 (const_string "ishift")))
10616 (set (attr "length_immediate")
10618 (ior (eq_attr "type" "alu")
10619 (and (eq_attr "type" "ishift")
10620 (and (match_operand 2 "const1_operand" "")
10621 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10624 (const_string "*")))
10625 (set_attr "mode" "DI")])
10627 ;; Convert lea to the lea pattern to avoid flags dependency.
10629 [(set (match_operand:DI 0 "register_operand" "")
10630 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10631 (match_operand:QI 2 "immediate_operand" "")))
10632 (clobber (reg:CC FLAGS_REG))]
10633 "TARGET_64BIT && reload_completed
10634 && true_regnum (operands[0]) != true_regnum (operands[1])"
10635 [(set (match_dup 0)
10636 (mult:DI (match_dup 1)
10638 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10640 ;; This pattern can't accept a variable shift count, since shifts by
10641 ;; zero don't affect the flags. We assume that shifts by constant
10642 ;; zero are optimized away.
10643 (define_insn "*ashldi3_cmp_rex64"
10644 [(set (reg FLAGS_REG)
10646 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10647 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10649 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10650 (ashift:DI (match_dup 1) (match_dup 2)))]
10652 && (optimize_function_for_size_p (cfun)
10653 || !TARGET_PARTIAL_FLAG_REG_STALL
10654 || (operands[2] == const1_rtx
10656 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10657 && ix86_match_ccmode (insn, CCGOCmode)
10658 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10660 switch (get_attr_type (insn))
10663 gcc_assert (operands[2] == const1_rtx);
10664 return "add{q}\t%0, %0";
10667 if (REG_P (operands[2]))
10668 return "sal{q}\t{%b2, %0|%0, %b2}";
10669 else if (operands[2] == const1_rtx
10670 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10671 return "sal{q}\t%0";
10673 return "sal{q}\t{%2, %0|%0, %2}";
10676 [(set (attr "type")
10677 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10679 (match_operand 0 "register_operand" ""))
10680 (match_operand 2 "const1_operand" ""))
10681 (const_string "alu")
10683 (const_string "ishift")))
10684 (set (attr "length_immediate")
10686 (ior (eq_attr "type" "alu")
10687 (and (eq_attr "type" "ishift")
10688 (and (match_operand 2 "const1_operand" "")
10689 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10692 (const_string "*")))
10693 (set_attr "mode" "DI")])
10695 (define_insn "*ashldi3_cconly_rex64"
10696 [(set (reg FLAGS_REG)
10698 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10699 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10701 (clobber (match_scratch:DI 0 "=r"))]
10703 && (optimize_function_for_size_p (cfun)
10704 || !TARGET_PARTIAL_FLAG_REG_STALL
10705 || (operands[2] == const1_rtx
10707 || TARGET_DOUBLE_WITH_ADD)))
10708 && ix86_match_ccmode (insn, CCGOCmode)
10709 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10711 switch (get_attr_type (insn))
10714 gcc_assert (operands[2] == const1_rtx);
10715 return "add{q}\t%0, %0";
10718 if (REG_P (operands[2]))
10719 return "sal{q}\t{%b2, %0|%0, %b2}";
10720 else if (operands[2] == const1_rtx
10721 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10722 return "sal{q}\t%0";
10724 return "sal{q}\t{%2, %0|%0, %2}";
10727 [(set (attr "type")
10728 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10730 (match_operand 0 "register_operand" ""))
10731 (match_operand 2 "const1_operand" ""))
10732 (const_string "alu")
10734 (const_string "ishift")))
10735 (set (attr "length_immediate")
10737 (ior (eq_attr "type" "alu")
10738 (and (eq_attr "type" "ishift")
10739 (and (match_operand 2 "const1_operand" "")
10740 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10743 (const_string "*")))
10744 (set_attr "mode" "DI")])
10746 (define_insn "*ashldi3_1"
10747 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10748 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10749 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10750 (clobber (reg:CC FLAGS_REG))]
10753 [(set_attr "type" "multi")])
10755 ;; By default we don't ask for a scratch register, because when DImode
10756 ;; values are manipulated, registers are already at a premium. But if
10757 ;; we have one handy, we won't turn it away.
10759 [(match_scratch:SI 3 "r")
10760 (parallel [(set (match_operand:DI 0 "register_operand" "")
10761 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10762 (match_operand:QI 2 "nonmemory_operand" "")))
10763 (clobber (reg:CC FLAGS_REG))])
10765 "!TARGET_64BIT && TARGET_CMOVE"
10767 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10770 [(set (match_operand:DI 0 "register_operand" "")
10771 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10772 (match_operand:QI 2 "nonmemory_operand" "")))
10773 (clobber (reg:CC FLAGS_REG))]
10774 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10775 ? epilogue_completed : reload_completed)"
10777 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10779 (define_insn "x86_shld"
10780 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10781 (ior:SI (ashift:SI (match_dup 0)
10782 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10783 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10784 (minus:QI (const_int 32) (match_dup 2)))))
10785 (clobber (reg:CC FLAGS_REG))]
10787 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10788 [(set_attr "type" "ishift")
10789 (set_attr "prefix_0f" "1")
10790 (set_attr "mode" "SI")
10791 (set_attr "pent_pair" "np")
10792 (set_attr "athlon_decode" "vector")
10793 (set_attr "amdfam10_decode" "vector")])
10795 (define_expand "x86_shift_adj_1"
10796 [(set (reg:CCZ FLAGS_REG)
10797 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10800 (set (match_operand:SI 0 "register_operand" "")
10801 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10802 (match_operand:SI 1 "register_operand" "")
10805 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10806 (match_operand:SI 3 "register_operand" "r")
10811 (define_expand "x86_shift_adj_2"
10812 [(use (match_operand:SI 0 "register_operand" ""))
10813 (use (match_operand:SI 1 "register_operand" ""))
10814 (use (match_operand:QI 2 "register_operand" ""))]
10817 rtx label = gen_label_rtx ();
10820 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10822 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10823 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10824 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10825 gen_rtx_LABEL_REF (VOIDmode, label),
10827 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10828 JUMP_LABEL (tmp) = label;
10830 emit_move_insn (operands[0], operands[1]);
10831 ix86_expand_clear (operands[1]);
10833 emit_label (label);
10834 LABEL_NUSES (label) = 1;
10839 (define_expand "ashlsi3"
10840 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10841 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10842 (match_operand:QI 2 "nonmemory_operand" "")))]
10844 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10846 (define_insn "*ashlsi3_1"
10847 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10848 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10849 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10850 (clobber (reg:CC FLAGS_REG))]
10851 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10853 switch (get_attr_type (insn))
10856 gcc_assert (operands[2] == const1_rtx);
10857 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10858 return "add{l}\t%0, %0";
10864 if (REG_P (operands[2]))
10865 return "sal{l}\t{%b2, %0|%0, %b2}";
10866 else if (operands[2] == const1_rtx
10867 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10868 return "sal{l}\t%0";
10870 return "sal{l}\t{%2, %0|%0, %2}";
10873 [(set (attr "type")
10874 (cond [(eq_attr "alternative" "1")
10875 (const_string "lea")
10876 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10878 (match_operand 0 "register_operand" ""))
10879 (match_operand 2 "const1_operand" ""))
10880 (const_string "alu")
10882 (const_string "ishift")))
10883 (set (attr "length_immediate")
10885 (ior (eq_attr "type" "alu")
10886 (and (eq_attr "type" "ishift")
10887 (and (match_operand 2 "const1_operand" "")
10888 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10891 (const_string "*")))
10892 (set_attr "mode" "SI")])
10894 ;; Convert lea to the lea pattern to avoid flags dependency.
10896 [(set (match_operand 0 "register_operand" "")
10897 (ashift (match_operand 1 "index_register_operand" "")
10898 (match_operand:QI 2 "const_int_operand" "")))
10899 (clobber (reg:CC FLAGS_REG))]
10901 && true_regnum (operands[0]) != true_regnum (operands[1])
10902 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10906 enum machine_mode mode = GET_MODE (operands[0]);
10908 if (GET_MODE_SIZE (mode) < 4)
10909 operands[0] = gen_lowpart (SImode, operands[0]);
10911 operands[1] = gen_lowpart (Pmode, operands[1]);
10912 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10914 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10915 if (Pmode != SImode)
10916 pat = gen_rtx_SUBREG (SImode, pat, 0);
10917 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10921 ;; Rare case of shifting RSP is handled by generating move and shift
10923 [(set (match_operand 0 "register_operand" "")
10924 (ashift (match_operand 1 "register_operand" "")
10925 (match_operand:QI 2 "const_int_operand" "")))
10926 (clobber (reg:CC FLAGS_REG))]
10928 && true_regnum (operands[0]) != true_regnum (operands[1])"
10932 emit_move_insn (operands[0], operands[1]);
10933 pat = gen_rtx_SET (VOIDmode, operands[0],
10934 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10935 operands[0], operands[2]));
10936 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10937 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10941 (define_insn "*ashlsi3_1_zext"
10942 [(set (match_operand:DI 0 "register_operand" "=r,r")
10943 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10944 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10945 (clobber (reg:CC FLAGS_REG))]
10946 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10948 switch (get_attr_type (insn))
10951 gcc_assert (operands[2] == const1_rtx);
10952 return "add{l}\t%k0, %k0";
10958 if (REG_P (operands[2]))
10959 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10960 else if (operands[2] == const1_rtx
10961 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10962 return "sal{l}\t%k0";
10964 return "sal{l}\t{%2, %k0|%k0, %2}";
10967 [(set (attr "type")
10968 (cond [(eq_attr "alternative" "1")
10969 (const_string "lea")
10970 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
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" "SI")])
10987 ;; Convert lea to the lea pattern to avoid flags dependency.
10989 [(set (match_operand:DI 0 "register_operand" "")
10990 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10991 (match_operand:QI 2 "const_int_operand" ""))))
10992 (clobber (reg:CC FLAGS_REG))]
10993 "TARGET_64BIT && reload_completed
10994 && true_regnum (operands[0]) != true_regnum (operands[1])"
10995 [(set (match_dup 0) (zero_extend:DI
10996 (subreg:SI (mult:SI (match_dup 1)
10997 (match_dup 2)) 0)))]
10999 operands[1] = gen_lowpart (Pmode, operands[1]);
11000 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
11003 ;; This pattern can't accept a variable shift count, since shifts by
11004 ;; zero don't affect the flags. We assume that shifts by constant
11005 ;; zero are optimized away.
11006 (define_insn "*ashlsi3_cmp"
11007 [(set (reg FLAGS_REG)
11009 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11010 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11012 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11013 (ashift:SI (match_dup 1) (match_dup 2)))]
11014 "(optimize_function_for_size_p (cfun)
11015 || !TARGET_PARTIAL_FLAG_REG_STALL
11016 || (operands[2] == const1_rtx
11018 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11019 && ix86_match_ccmode (insn, CCGOCmode)
11020 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11022 switch (get_attr_type (insn))
11025 gcc_assert (operands[2] == const1_rtx);
11026 return "add{l}\t%0, %0";
11029 if (REG_P (operands[2]))
11030 return "sal{l}\t{%b2, %0|%0, %b2}";
11031 else if (operands[2] == const1_rtx
11032 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11033 return "sal{l}\t%0";
11035 return "sal{l}\t{%2, %0|%0, %2}";
11038 [(set (attr "type")
11039 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11041 (match_operand 0 "register_operand" ""))
11042 (match_operand 2 "const1_operand" ""))
11043 (const_string "alu")
11045 (const_string "ishift")))
11046 (set (attr "length_immediate")
11048 (ior (eq_attr "type" "alu")
11049 (and (eq_attr "type" "ishift")
11050 (and (match_operand 2 "const1_operand" "")
11051 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11054 (const_string "*")))
11055 (set_attr "mode" "SI")])
11057 (define_insn "*ashlsi3_cconly"
11058 [(set (reg FLAGS_REG)
11060 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11061 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11063 (clobber (match_scratch:SI 0 "=r"))]
11064 "(optimize_function_for_size_p (cfun)
11065 || !TARGET_PARTIAL_FLAG_REG_STALL
11066 || (operands[2] == const1_rtx
11068 || TARGET_DOUBLE_WITH_ADD)))
11069 && ix86_match_ccmode (insn, CCGOCmode)
11070 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11072 switch (get_attr_type (insn))
11075 gcc_assert (operands[2] == const1_rtx);
11076 return "add{l}\t%0, %0";
11079 if (REG_P (operands[2]))
11080 return "sal{l}\t{%b2, %0|%0, %b2}";
11081 else if (operands[2] == const1_rtx
11082 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11083 return "sal{l}\t%0";
11085 return "sal{l}\t{%2, %0|%0, %2}";
11088 [(set (attr "type")
11089 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11091 (match_operand 0 "register_operand" ""))
11092 (match_operand 2 "const1_operand" ""))
11093 (const_string "alu")
11095 (const_string "ishift")))
11096 (set (attr "length_immediate")
11098 (ior (eq_attr "type" "alu")
11099 (and (eq_attr "type" "ishift")
11100 (and (match_operand 2 "const1_operand" "")
11101 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11104 (const_string "*")))
11105 (set_attr "mode" "SI")])
11107 (define_insn "*ashlsi3_cmp_zext"
11108 [(set (reg FLAGS_REG)
11110 (ashift:SI (match_operand:SI 1 "register_operand" "0")
11111 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11113 (set (match_operand:DI 0 "register_operand" "=r")
11114 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
11116 && (optimize_function_for_size_p (cfun)
11117 || !TARGET_PARTIAL_FLAG_REG_STALL
11118 || (operands[2] == const1_rtx
11120 || TARGET_DOUBLE_WITH_ADD)))
11121 && ix86_match_ccmode (insn, CCGOCmode)
11122 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
11124 switch (get_attr_type (insn))
11127 gcc_assert (operands[2] == const1_rtx);
11128 return "add{l}\t%k0, %k0";
11131 if (REG_P (operands[2]))
11132 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11133 else if (operands[2] == const1_rtx
11134 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11135 return "sal{l}\t%k0";
11137 return "sal{l}\t{%2, %k0|%k0, %2}";
11140 [(set (attr "type")
11141 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11143 (match_operand 2 "const1_operand" ""))
11144 (const_string "alu")
11146 (const_string "ishift")))
11147 (set (attr "length_immediate")
11149 (ior (eq_attr "type" "alu")
11150 (and (eq_attr "type" "ishift")
11151 (and (match_operand 2 "const1_operand" "")
11152 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11155 (const_string "*")))
11156 (set_attr "mode" "SI")])
11158 (define_expand "ashlhi3"
11159 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11160 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
11161 (match_operand:QI 2 "nonmemory_operand" "")))]
11162 "TARGET_HIMODE_MATH"
11163 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
11165 (define_insn "*ashlhi3_1_lea"
11166 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
11167 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
11168 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
11169 (clobber (reg:CC FLAGS_REG))]
11170 "!TARGET_PARTIAL_REG_STALL
11171 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11173 switch (get_attr_type (insn))
11178 gcc_assert (operands[2] == const1_rtx);
11179 return "add{w}\t%0, %0";
11182 if (REG_P (operands[2]))
11183 return "sal{w}\t{%b2, %0|%0, %b2}";
11184 else if (operands[2] == const1_rtx
11185 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11186 return "sal{w}\t%0";
11188 return "sal{w}\t{%2, %0|%0, %2}";
11191 [(set (attr "type")
11192 (cond [(eq_attr "alternative" "1")
11193 (const_string "lea")
11194 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11196 (match_operand 0 "register_operand" ""))
11197 (match_operand 2 "const1_operand" ""))
11198 (const_string "alu")
11200 (const_string "ishift")))
11201 (set (attr "length_immediate")
11203 (ior (eq_attr "type" "alu")
11204 (and (eq_attr "type" "ishift")
11205 (and (match_operand 2 "const1_operand" "")
11206 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11209 (const_string "*")))
11210 (set_attr "mode" "HI,SI")])
11212 (define_insn "*ashlhi3_1"
11213 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11214 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11215 (match_operand:QI 2 "nonmemory_operand" "cI")))
11216 (clobber (reg:CC FLAGS_REG))]
11217 "TARGET_PARTIAL_REG_STALL
11218 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11220 switch (get_attr_type (insn))
11223 gcc_assert (operands[2] == const1_rtx);
11224 return "add{w}\t%0, %0";
11227 if (REG_P (operands[2]))
11228 return "sal{w}\t{%b2, %0|%0, %b2}";
11229 else if (operands[2] == const1_rtx
11230 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11231 return "sal{w}\t%0";
11233 return "sal{w}\t{%2, %0|%0, %2}";
11236 [(set (attr "type")
11237 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11239 (match_operand 0 "register_operand" ""))
11240 (match_operand 2 "const1_operand" ""))
11241 (const_string "alu")
11243 (const_string "ishift")))
11244 (set (attr "length_immediate")
11246 (ior (eq_attr "type" "alu")
11247 (and (eq_attr "type" "ishift")
11248 (and (match_operand 2 "const1_operand" "")
11249 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11252 (const_string "*")))
11253 (set_attr "mode" "HI")])
11255 ;; This pattern can't accept a variable shift count, since shifts by
11256 ;; zero don't affect the flags. We assume that shifts by constant
11257 ;; zero are optimized away.
11258 (define_insn "*ashlhi3_cmp"
11259 [(set (reg FLAGS_REG)
11261 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11262 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11264 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11265 (ashift:HI (match_dup 1) (match_dup 2)))]
11266 "(optimize_function_for_size_p (cfun)
11267 || !TARGET_PARTIAL_FLAG_REG_STALL
11268 || (operands[2] == const1_rtx
11270 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11271 && ix86_match_ccmode (insn, CCGOCmode)
11272 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11274 switch (get_attr_type (insn))
11277 gcc_assert (operands[2] == const1_rtx);
11278 return "add{w}\t%0, %0";
11281 if (REG_P (operands[2]))
11282 return "sal{w}\t{%b2, %0|%0, %b2}";
11283 else if (operands[2] == const1_rtx
11284 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11285 return "sal{w}\t%0";
11287 return "sal{w}\t{%2, %0|%0, %2}";
11290 [(set (attr "type")
11291 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11293 (match_operand 0 "register_operand" ""))
11294 (match_operand 2 "const1_operand" ""))
11295 (const_string "alu")
11297 (const_string "ishift")))
11298 (set (attr "length_immediate")
11300 (ior (eq_attr "type" "alu")
11301 (and (eq_attr "type" "ishift")
11302 (and (match_operand 2 "const1_operand" "")
11303 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11306 (const_string "*")))
11307 (set_attr "mode" "HI")])
11309 (define_insn "*ashlhi3_cconly"
11310 [(set (reg FLAGS_REG)
11312 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11313 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11315 (clobber (match_scratch:HI 0 "=r"))]
11316 "(optimize_function_for_size_p (cfun)
11317 || !TARGET_PARTIAL_FLAG_REG_STALL
11318 || (operands[2] == const1_rtx
11320 || TARGET_DOUBLE_WITH_ADD)))
11321 && ix86_match_ccmode (insn, CCGOCmode)
11322 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11324 switch (get_attr_type (insn))
11327 gcc_assert (operands[2] == const1_rtx);
11328 return "add{w}\t%0, %0";
11331 if (REG_P (operands[2]))
11332 return "sal{w}\t{%b2, %0|%0, %b2}";
11333 else if (operands[2] == const1_rtx
11334 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11335 return "sal{w}\t%0";
11337 return "sal{w}\t{%2, %0|%0, %2}";
11340 [(set (attr "type")
11341 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11343 (match_operand 0 "register_operand" ""))
11344 (match_operand 2 "const1_operand" ""))
11345 (const_string "alu")
11347 (const_string "ishift")))
11348 (set (attr "length_immediate")
11350 (ior (eq_attr "type" "alu")
11351 (and (eq_attr "type" "ishift")
11352 (and (match_operand 2 "const1_operand" "")
11353 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11356 (const_string "*")))
11357 (set_attr "mode" "HI")])
11359 (define_expand "ashlqi3"
11360 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11361 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11362 (match_operand:QI 2 "nonmemory_operand" "")))]
11363 "TARGET_QIMODE_MATH"
11364 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11366 ;; %%% Potential partial reg stall on alternative 2. What to do?
11368 (define_insn "*ashlqi3_1_lea"
11369 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11370 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11371 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11372 (clobber (reg:CC FLAGS_REG))]
11373 "!TARGET_PARTIAL_REG_STALL
11374 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11376 switch (get_attr_type (insn))
11381 gcc_assert (operands[2] == const1_rtx);
11382 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11383 return "add{l}\t%k0, %k0";
11385 return "add{b}\t%0, %0";
11388 if (REG_P (operands[2]))
11390 if (get_attr_mode (insn) == MODE_SI)
11391 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11393 return "sal{b}\t{%b2, %0|%0, %b2}";
11395 else if (operands[2] == const1_rtx
11396 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11398 if (get_attr_mode (insn) == MODE_SI)
11399 return "sal{l}\t%0";
11401 return "sal{b}\t%0";
11405 if (get_attr_mode (insn) == MODE_SI)
11406 return "sal{l}\t{%2, %k0|%k0, %2}";
11408 return "sal{b}\t{%2, %0|%0, %2}";
11412 [(set (attr "type")
11413 (cond [(eq_attr "alternative" "2")
11414 (const_string "lea")
11415 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11417 (match_operand 0 "register_operand" ""))
11418 (match_operand 2 "const1_operand" ""))
11419 (const_string "alu")
11421 (const_string "ishift")))
11422 (set (attr "length_immediate")
11424 (ior (eq_attr "type" "alu")
11425 (and (eq_attr "type" "ishift")
11426 (and (match_operand 2 "const1_operand" "")
11427 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11430 (const_string "*")))
11431 (set_attr "mode" "QI,SI,SI")])
11433 (define_insn "*ashlqi3_1"
11434 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11435 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11436 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11437 (clobber (reg:CC FLAGS_REG))]
11438 "TARGET_PARTIAL_REG_STALL
11439 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11441 switch (get_attr_type (insn))
11444 gcc_assert (operands[2] == const1_rtx);
11445 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11446 return "add{l}\t%k0, %k0";
11448 return "add{b}\t%0, %0";
11451 if (REG_P (operands[2]))
11453 if (get_attr_mode (insn) == MODE_SI)
11454 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11456 return "sal{b}\t{%b2, %0|%0, %b2}";
11458 else if (operands[2] == const1_rtx
11459 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11461 if (get_attr_mode (insn) == MODE_SI)
11462 return "sal{l}\t%0";
11464 return "sal{b}\t%0";
11468 if (get_attr_mode (insn) == MODE_SI)
11469 return "sal{l}\t{%2, %k0|%k0, %2}";
11471 return "sal{b}\t{%2, %0|%0, %2}";
11475 [(set (attr "type")
11476 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11478 (match_operand 0 "register_operand" ""))
11479 (match_operand 2 "const1_operand" ""))
11480 (const_string "alu")
11482 (const_string "ishift")))
11483 (set (attr "length_immediate")
11485 (ior (eq_attr "type" "alu")
11486 (and (eq_attr "type" "ishift")
11487 (and (match_operand 2 "const1_operand" "")
11488 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11491 (const_string "*")))
11492 (set_attr "mode" "QI,SI")])
11494 ;; This pattern can't accept a variable shift count, since shifts by
11495 ;; zero don't affect the flags. We assume that shifts by constant
11496 ;; zero are optimized away.
11497 (define_insn "*ashlqi3_cmp"
11498 [(set (reg FLAGS_REG)
11500 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11501 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11503 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11504 (ashift:QI (match_dup 1) (match_dup 2)))]
11505 "(optimize_function_for_size_p (cfun)
11506 || !TARGET_PARTIAL_FLAG_REG_STALL
11507 || (operands[2] == const1_rtx
11509 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11510 && ix86_match_ccmode (insn, CCGOCmode)
11511 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11513 switch (get_attr_type (insn))
11516 gcc_assert (operands[2] == const1_rtx);
11517 return "add{b}\t%0, %0";
11520 if (REG_P (operands[2]))
11521 return "sal{b}\t{%b2, %0|%0, %b2}";
11522 else if (operands[2] == const1_rtx
11523 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11524 return "sal{b}\t%0";
11526 return "sal{b}\t{%2, %0|%0, %2}";
11529 [(set (attr "type")
11530 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11532 (match_operand 0 "register_operand" ""))
11533 (match_operand 2 "const1_operand" ""))
11534 (const_string "alu")
11536 (const_string "ishift")))
11537 (set (attr "length_immediate")
11539 (ior (eq_attr "type" "alu")
11540 (and (eq_attr "type" "ishift")
11541 (and (match_operand 2 "const1_operand" "")
11542 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11545 (const_string "*")))
11546 (set_attr "mode" "QI")])
11548 (define_insn "*ashlqi3_cconly"
11549 [(set (reg FLAGS_REG)
11551 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11552 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11554 (clobber (match_scratch:QI 0 "=q"))]
11555 "(optimize_function_for_size_p (cfun)
11556 || !TARGET_PARTIAL_FLAG_REG_STALL
11557 || (operands[2] == const1_rtx
11559 || TARGET_DOUBLE_WITH_ADD)))
11560 && ix86_match_ccmode (insn, CCGOCmode)
11561 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11563 switch (get_attr_type (insn))
11566 gcc_assert (operands[2] == const1_rtx);
11567 return "add{b}\t%0, %0";
11570 if (REG_P (operands[2]))
11571 return "sal{b}\t{%b2, %0|%0, %b2}";
11572 else if (operands[2] == const1_rtx
11573 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11574 return "sal{b}\t%0";
11576 return "sal{b}\t{%2, %0|%0, %2}";
11579 [(set (attr "type")
11580 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11582 (match_operand 0 "register_operand" ""))
11583 (match_operand 2 "const1_operand" ""))
11584 (const_string "alu")
11586 (const_string "ishift")))
11587 (set (attr "length_immediate")
11589 (ior (eq_attr "type" "alu")
11590 (and (eq_attr "type" "ishift")
11591 (and (match_operand 2 "const1_operand" "")
11592 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11595 (const_string "*")))
11596 (set_attr "mode" "QI")])
11598 ;; See comment above `ashldi3' about how this works.
11600 (define_expand "ashrti3"
11601 [(set (match_operand:TI 0 "register_operand" "")
11602 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11603 (match_operand:QI 2 "nonmemory_operand" "")))]
11605 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11607 (define_insn "*ashrti3_1"
11608 [(set (match_operand:TI 0 "register_operand" "=r")
11609 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11610 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11611 (clobber (reg:CC FLAGS_REG))]
11614 [(set_attr "type" "multi")])
11617 [(match_scratch:DI 3 "r")
11618 (parallel [(set (match_operand:TI 0 "register_operand" "")
11619 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11620 (match_operand:QI 2 "nonmemory_operand" "")))
11621 (clobber (reg:CC FLAGS_REG))])
11625 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11628 [(set (match_operand:TI 0 "register_operand" "")
11629 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11630 (match_operand:QI 2 "nonmemory_operand" "")))
11631 (clobber (reg:CC FLAGS_REG))]
11632 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11633 ? epilogue_completed : reload_completed)"
11635 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11637 (define_insn "x86_64_shrd"
11638 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11639 (ior:DI (ashiftrt:DI (match_dup 0)
11640 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11641 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11642 (minus:QI (const_int 64) (match_dup 2)))))
11643 (clobber (reg:CC FLAGS_REG))]
11645 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11646 [(set_attr "type" "ishift")
11647 (set_attr "prefix_0f" "1")
11648 (set_attr "mode" "DI")
11649 (set_attr "athlon_decode" "vector")
11650 (set_attr "amdfam10_decode" "vector")])
11652 (define_expand "ashrdi3"
11653 [(set (match_operand:DI 0 "shiftdi_operand" "")
11654 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11655 (match_operand:QI 2 "nonmemory_operand" "")))]
11657 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11659 (define_expand "x86_64_shift_adj_3"
11660 [(use (match_operand:DI 0 "register_operand" ""))
11661 (use (match_operand:DI 1 "register_operand" ""))
11662 (use (match_operand:QI 2 "register_operand" ""))]
11665 rtx label = gen_label_rtx ();
11668 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11670 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11671 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11672 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11673 gen_rtx_LABEL_REF (VOIDmode, label),
11675 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11676 JUMP_LABEL (tmp) = label;
11678 emit_move_insn (operands[0], operands[1]);
11679 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11681 emit_label (label);
11682 LABEL_NUSES (label) = 1;
11687 (define_insn "ashrdi3_63_rex64"
11688 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11689 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11690 (match_operand:DI 2 "const_int_operand" "i,i")))
11691 (clobber (reg:CC FLAGS_REG))]
11692 "TARGET_64BIT && INTVAL (operands[2]) == 63
11693 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11694 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11697 sar{q}\t{%2, %0|%0, %2}"
11698 [(set_attr "type" "imovx,ishift")
11699 (set_attr "prefix_0f" "0,*")
11700 (set_attr "length_immediate" "0,*")
11701 (set_attr "modrm" "0,1")
11702 (set_attr "mode" "DI")])
11704 (define_insn "*ashrdi3_1_one_bit_rex64"
11705 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11706 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11707 (match_operand:QI 2 "const1_operand" "")))
11708 (clobber (reg:CC FLAGS_REG))]
11710 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11711 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11713 [(set_attr "type" "ishift")
11714 (set_attr "length_immediate" "0")
11715 (set_attr "mode" "DI")])
11717 (define_insn "*ashrdi3_1_rex64"
11718 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11719 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11720 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11721 (clobber (reg:CC FLAGS_REG))]
11722 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11724 sar{q}\t{%2, %0|%0, %2}
11725 sar{q}\t{%b2, %0|%0, %b2}"
11726 [(set_attr "type" "ishift")
11727 (set_attr "mode" "DI")])
11729 ;; This pattern can't accept a variable shift count, since shifts by
11730 ;; zero don't affect the flags. We assume that shifts by constant
11731 ;; zero are optimized away.
11732 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11733 [(set (reg FLAGS_REG)
11735 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11736 (match_operand:QI 2 "const1_operand" ""))
11738 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11739 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11741 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11742 && ix86_match_ccmode (insn, CCGOCmode)
11743 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11745 [(set_attr "type" "ishift")
11746 (set_attr "length_immediate" "0")
11747 (set_attr "mode" "DI")])
11749 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11750 [(set (reg FLAGS_REG)
11752 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11753 (match_operand:QI 2 "const1_operand" ""))
11755 (clobber (match_scratch:DI 0 "=r"))]
11757 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11758 && ix86_match_ccmode (insn, CCGOCmode)
11759 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11761 [(set_attr "type" "ishift")
11762 (set_attr "length_immediate" "0")
11763 (set_attr "mode" "DI")])
11765 ;; This pattern can't accept a variable shift count, since shifts by
11766 ;; zero don't affect the flags. We assume that shifts by constant
11767 ;; zero are optimized away.
11768 (define_insn "*ashrdi3_cmp_rex64"
11769 [(set (reg FLAGS_REG)
11771 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11772 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11774 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11775 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11777 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11778 && ix86_match_ccmode (insn, CCGOCmode)
11779 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11780 "sar{q}\t{%2, %0|%0, %2}"
11781 [(set_attr "type" "ishift")
11782 (set_attr "mode" "DI")])
11784 (define_insn "*ashrdi3_cconly_rex64"
11785 [(set (reg FLAGS_REG)
11787 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11788 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11790 (clobber (match_scratch:DI 0 "=r"))]
11792 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11793 && ix86_match_ccmode (insn, CCGOCmode)
11794 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11795 "sar{q}\t{%2, %0|%0, %2}"
11796 [(set_attr "type" "ishift")
11797 (set_attr "mode" "DI")])
11799 (define_insn "*ashrdi3_1"
11800 [(set (match_operand:DI 0 "register_operand" "=r")
11801 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11802 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11803 (clobber (reg:CC FLAGS_REG))]
11806 [(set_attr "type" "multi")])
11808 ;; By default we don't ask for a scratch register, because when DImode
11809 ;; values are manipulated, registers are already at a premium. But if
11810 ;; we have one handy, we won't turn it away.
11812 [(match_scratch:SI 3 "r")
11813 (parallel [(set (match_operand:DI 0 "register_operand" "")
11814 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11815 (match_operand:QI 2 "nonmemory_operand" "")))
11816 (clobber (reg:CC FLAGS_REG))])
11818 "!TARGET_64BIT && TARGET_CMOVE"
11820 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11823 [(set (match_operand:DI 0 "register_operand" "")
11824 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11825 (match_operand:QI 2 "nonmemory_operand" "")))
11826 (clobber (reg:CC FLAGS_REG))]
11827 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11828 ? epilogue_completed : reload_completed)"
11830 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11832 (define_insn "x86_shrd"
11833 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11834 (ior:SI (ashiftrt:SI (match_dup 0)
11835 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11836 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11837 (minus:QI (const_int 32) (match_dup 2)))))
11838 (clobber (reg:CC FLAGS_REG))]
11840 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11841 [(set_attr "type" "ishift")
11842 (set_attr "prefix_0f" "1")
11843 (set_attr "pent_pair" "np")
11844 (set_attr "mode" "SI")])
11846 (define_expand "x86_shift_adj_3"
11847 [(use (match_operand:SI 0 "register_operand" ""))
11848 (use (match_operand:SI 1 "register_operand" ""))
11849 (use (match_operand:QI 2 "register_operand" ""))]
11852 rtx label = gen_label_rtx ();
11855 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11857 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11858 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11859 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11860 gen_rtx_LABEL_REF (VOIDmode, label),
11862 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11863 JUMP_LABEL (tmp) = label;
11865 emit_move_insn (operands[0], operands[1]);
11866 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11868 emit_label (label);
11869 LABEL_NUSES (label) = 1;
11874 (define_expand "ashrsi3_31"
11875 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11876 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11877 (match_operand:SI 2 "const_int_operand" "i,i")))
11878 (clobber (reg:CC FLAGS_REG))])]
11881 (define_insn "*ashrsi3_31"
11882 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11883 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11884 (match_operand:SI 2 "const_int_operand" "i,i")))
11885 (clobber (reg:CC FLAGS_REG))]
11886 "INTVAL (operands[2]) == 31
11887 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11888 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11891 sar{l}\t{%2, %0|%0, %2}"
11892 [(set_attr "type" "imovx,ishift")
11893 (set_attr "prefix_0f" "0,*")
11894 (set_attr "length_immediate" "0,*")
11895 (set_attr "modrm" "0,1")
11896 (set_attr "mode" "SI")])
11898 (define_insn "*ashrsi3_31_zext"
11899 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11900 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11901 (match_operand:SI 2 "const_int_operand" "i,i"))))
11902 (clobber (reg:CC FLAGS_REG))]
11903 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11904 && INTVAL (operands[2]) == 31
11905 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11908 sar{l}\t{%2, %k0|%k0, %2}"
11909 [(set_attr "type" "imovx,ishift")
11910 (set_attr "prefix_0f" "0,*")
11911 (set_attr "length_immediate" "0,*")
11912 (set_attr "modrm" "0,1")
11913 (set_attr "mode" "SI")])
11915 (define_expand "ashrsi3"
11916 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11917 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11918 (match_operand:QI 2 "nonmemory_operand" "")))]
11920 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11922 (define_insn "*ashrsi3_1_one_bit"
11923 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11924 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11925 (match_operand:QI 2 "const1_operand" "")))
11926 (clobber (reg:CC FLAGS_REG))]
11927 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11928 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11930 [(set_attr "type" "ishift")
11931 (set_attr "length_immediate" "0")
11932 (set_attr "mode" "SI")])
11934 (define_insn "*ashrsi3_1_one_bit_zext"
11935 [(set (match_operand:DI 0 "register_operand" "=r")
11936 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11937 (match_operand:QI 2 "const1_operand" ""))))
11938 (clobber (reg:CC FLAGS_REG))]
11940 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11941 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11943 [(set_attr "type" "ishift")
11944 (set_attr "length_immediate" "0")
11945 (set_attr "mode" "SI")])
11947 (define_insn "*ashrsi3_1"
11948 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11949 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11950 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11951 (clobber (reg:CC FLAGS_REG))]
11952 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11954 sar{l}\t{%2, %0|%0, %2}
11955 sar{l}\t{%b2, %0|%0, %b2}"
11956 [(set_attr "type" "ishift")
11957 (set_attr "mode" "SI")])
11959 (define_insn "*ashrsi3_1_zext"
11960 [(set (match_operand:DI 0 "register_operand" "=r,r")
11961 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11962 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11963 (clobber (reg:CC FLAGS_REG))]
11964 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11966 sar{l}\t{%2, %k0|%k0, %2}
11967 sar{l}\t{%b2, %k0|%k0, %b2}"
11968 [(set_attr "type" "ishift")
11969 (set_attr "mode" "SI")])
11971 ;; This pattern can't accept a variable shift count, since shifts by
11972 ;; zero don't affect the flags. We assume that shifts by constant
11973 ;; zero are optimized away.
11974 (define_insn "*ashrsi3_one_bit_cmp"
11975 [(set (reg FLAGS_REG)
11977 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11978 (match_operand:QI 2 "const1_operand" ""))
11980 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11981 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11982 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11983 && ix86_match_ccmode (insn, CCGOCmode)
11984 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11986 [(set_attr "type" "ishift")
11987 (set_attr "length_immediate" "0")
11988 (set_attr "mode" "SI")])
11990 (define_insn "*ashrsi3_one_bit_cconly"
11991 [(set (reg FLAGS_REG)
11993 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11994 (match_operand:QI 2 "const1_operand" ""))
11996 (clobber (match_scratch:SI 0 "=r"))]
11997 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11998 && ix86_match_ccmode (insn, CCGOCmode)
11999 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12001 [(set_attr "type" "ishift")
12002 (set_attr "length_immediate" "0")
12003 (set_attr "mode" "SI")])
12005 (define_insn "*ashrsi3_one_bit_cmp_zext"
12006 [(set (reg FLAGS_REG)
12008 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12009 (match_operand:QI 2 "const1_operand" ""))
12011 (set (match_operand:DI 0 "register_operand" "=r")
12012 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12014 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12015 && ix86_match_ccmode (insn, CCmode)
12016 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12018 [(set_attr "type" "ishift")
12019 (set_attr "length_immediate" "0")
12020 (set_attr "mode" "SI")])
12022 ;; This pattern can't accept a variable shift count, since shifts by
12023 ;; zero don't affect the flags. We assume that shifts by constant
12024 ;; zero are optimized away.
12025 (define_insn "*ashrsi3_cmp"
12026 [(set (reg FLAGS_REG)
12028 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12029 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12031 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12032 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
12033 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12034 && ix86_match_ccmode (insn, CCGOCmode)
12035 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12036 "sar{l}\t{%2, %0|%0, %2}"
12037 [(set_attr "type" "ishift")
12038 (set_attr "mode" "SI")])
12040 (define_insn "*ashrsi3_cconly"
12041 [(set (reg FLAGS_REG)
12043 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12044 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12046 (clobber (match_scratch:SI 0 "=r"))]
12047 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12048 && ix86_match_ccmode (insn, CCGOCmode)
12049 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12050 "sar{l}\t{%2, %0|%0, %2}"
12051 [(set_attr "type" "ishift")
12052 (set_attr "mode" "SI")])
12054 (define_insn "*ashrsi3_cmp_zext"
12055 [(set (reg FLAGS_REG)
12057 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
12058 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12060 (set (match_operand:DI 0 "register_operand" "=r")
12061 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
12063 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12064 && ix86_match_ccmode (insn, CCGOCmode)
12065 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
12066 "sar{l}\t{%2, %k0|%k0, %2}"
12067 [(set_attr "type" "ishift")
12068 (set_attr "mode" "SI")])
12070 (define_expand "ashrhi3"
12071 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12072 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12073 (match_operand:QI 2 "nonmemory_operand" "")))]
12074 "TARGET_HIMODE_MATH"
12075 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
12077 (define_insn "*ashrhi3_1_one_bit"
12078 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12079 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12080 (match_operand:QI 2 "const1_operand" "")))
12081 (clobber (reg:CC FLAGS_REG))]
12082 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12083 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12085 [(set_attr "type" "ishift")
12086 (set_attr "length_immediate" "0")
12087 (set_attr "mode" "HI")])
12089 (define_insn "*ashrhi3_1"
12090 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12091 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12092 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12093 (clobber (reg:CC FLAGS_REG))]
12094 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12096 sar{w}\t{%2, %0|%0, %2}
12097 sar{w}\t{%b2, %0|%0, %b2}"
12098 [(set_attr "type" "ishift")
12099 (set_attr "mode" "HI")])
12101 ;; This pattern can't accept a variable shift count, since shifts by
12102 ;; zero don't affect the flags. We assume that shifts by constant
12103 ;; zero are optimized away.
12104 (define_insn "*ashrhi3_one_bit_cmp"
12105 [(set (reg FLAGS_REG)
12107 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12108 (match_operand:QI 2 "const1_operand" ""))
12110 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12111 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12112 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12113 && ix86_match_ccmode (insn, CCGOCmode)
12114 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12116 [(set_attr "type" "ishift")
12117 (set_attr "length_immediate" "0")
12118 (set_attr "mode" "HI")])
12120 (define_insn "*ashrhi3_one_bit_cconly"
12121 [(set (reg FLAGS_REG)
12123 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12124 (match_operand:QI 2 "const1_operand" ""))
12126 (clobber (match_scratch:HI 0 "=r"))]
12127 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12128 && ix86_match_ccmode (insn, CCGOCmode)
12129 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12131 [(set_attr "type" "ishift")
12132 (set_attr "length_immediate" "0")
12133 (set_attr "mode" "HI")])
12135 ;; This pattern can't accept a variable shift count, since shifts by
12136 ;; zero don't affect the flags. We assume that shifts by constant
12137 ;; zero are optimized away.
12138 (define_insn "*ashrhi3_cmp"
12139 [(set (reg FLAGS_REG)
12141 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12142 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12144 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12145 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
12146 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12147 && ix86_match_ccmode (insn, CCGOCmode)
12148 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12149 "sar{w}\t{%2, %0|%0, %2}"
12150 [(set_attr "type" "ishift")
12151 (set_attr "mode" "HI")])
12153 (define_insn "*ashrhi3_cconly"
12154 [(set (reg FLAGS_REG)
12156 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12157 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12159 (clobber (match_scratch:HI 0 "=r"))]
12160 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12161 && ix86_match_ccmode (insn, CCGOCmode)
12162 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
12163 "sar{w}\t{%2, %0|%0, %2}"
12164 [(set_attr "type" "ishift")
12165 (set_attr "mode" "HI")])
12167 (define_expand "ashrqi3"
12168 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12169 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12170 (match_operand:QI 2 "nonmemory_operand" "")))]
12171 "TARGET_QIMODE_MATH"
12172 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
12174 (define_insn "*ashrqi3_1_one_bit"
12175 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12176 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12177 (match_operand:QI 2 "const1_operand" "")))
12178 (clobber (reg:CC FLAGS_REG))]
12179 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12180 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12182 [(set_attr "type" "ishift")
12183 (set_attr "length_immediate" "0")
12184 (set_attr "mode" "QI")])
12186 (define_insn "*ashrqi3_1_one_bit_slp"
12187 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12188 (ashiftrt:QI (match_dup 0)
12189 (match_operand:QI 1 "const1_operand" "")))
12190 (clobber (reg:CC FLAGS_REG))]
12191 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12192 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12193 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12195 [(set_attr "type" "ishift1")
12196 (set_attr "length_immediate" "0")
12197 (set_attr "mode" "QI")])
12199 (define_insn "*ashrqi3_1"
12200 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12201 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12202 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12203 (clobber (reg:CC FLAGS_REG))]
12204 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12206 sar{b}\t{%2, %0|%0, %2}
12207 sar{b}\t{%b2, %0|%0, %b2}"
12208 [(set_attr "type" "ishift")
12209 (set_attr "mode" "QI")])
12211 (define_insn "*ashrqi3_1_slp"
12212 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12213 (ashiftrt:QI (match_dup 0)
12214 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12215 (clobber (reg:CC FLAGS_REG))]
12216 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12217 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12219 sar{b}\t{%1, %0|%0, %1}
12220 sar{b}\t{%b1, %0|%0, %b1}"
12221 [(set_attr "type" "ishift1")
12222 (set_attr "mode" "QI")])
12224 ;; This pattern can't accept a variable shift count, since shifts by
12225 ;; zero don't affect the flags. We assume that shifts by constant
12226 ;; zero are optimized away.
12227 (define_insn "*ashrqi3_one_bit_cmp"
12228 [(set (reg FLAGS_REG)
12230 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12231 (match_operand:QI 2 "const1_operand" "I"))
12233 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12234 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12235 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12236 && ix86_match_ccmode (insn, CCGOCmode)
12237 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12239 [(set_attr "type" "ishift")
12240 (set_attr "length_immediate" "0")
12241 (set_attr "mode" "QI")])
12243 (define_insn "*ashrqi3_one_bit_cconly"
12244 [(set (reg FLAGS_REG)
12246 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12247 (match_operand:QI 2 "const1_operand" ""))
12249 (clobber (match_scratch:QI 0 "=q"))]
12250 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12251 && ix86_match_ccmode (insn, CCGOCmode)
12252 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12254 [(set_attr "type" "ishift")
12255 (set_attr "length_immediate" "0")
12256 (set_attr "mode" "QI")])
12258 ;; This pattern can't accept a variable shift count, since shifts by
12259 ;; zero don't affect the flags. We assume that shifts by constant
12260 ;; zero are optimized away.
12261 (define_insn "*ashrqi3_cmp"
12262 [(set (reg FLAGS_REG)
12264 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12265 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12267 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12268 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12269 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12270 && ix86_match_ccmode (insn, CCGOCmode)
12271 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12272 "sar{b}\t{%2, %0|%0, %2}"
12273 [(set_attr "type" "ishift")
12274 (set_attr "mode" "QI")])
12276 (define_insn "*ashrqi3_cconly"
12277 [(set (reg FLAGS_REG)
12279 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12280 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12282 (clobber (match_scratch:QI 0 "=q"))]
12283 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12284 && ix86_match_ccmode (insn, CCGOCmode)
12285 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12286 "sar{b}\t{%2, %0|%0, %2}"
12287 [(set_attr "type" "ishift")
12288 (set_attr "mode" "QI")])
12291 ;; Logical shift instructions
12293 ;; See comment above `ashldi3' about how this works.
12295 (define_expand "lshrti3"
12296 [(set (match_operand:TI 0 "register_operand" "")
12297 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12298 (match_operand:QI 2 "nonmemory_operand" "")))]
12300 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12302 ;; This pattern must be defined before *lshrti3_1 to prevent
12303 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12305 (define_insn "*avx_lshrti3"
12306 [(set (match_operand:TI 0 "register_operand" "=x")
12307 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12308 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12311 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12312 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12314 [(set_attr "type" "sseishft")
12315 (set_attr "prefix" "vex")
12316 (set_attr "length_immediate" "1")
12317 (set_attr "mode" "TI")])
12319 (define_insn "sse2_lshrti3"
12320 [(set (match_operand:TI 0 "register_operand" "=x")
12321 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12322 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12325 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12326 return "psrldq\t{%2, %0|%0, %2}";
12328 [(set_attr "type" "sseishft")
12329 (set_attr "prefix_data16" "1")
12330 (set_attr "length_immediate" "1")
12331 (set_attr "mode" "TI")])
12333 (define_insn "*lshrti3_1"
12334 [(set (match_operand:TI 0 "register_operand" "=r")
12335 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12336 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12337 (clobber (reg:CC FLAGS_REG))]
12340 [(set_attr "type" "multi")])
12343 [(match_scratch:DI 3 "r")
12344 (parallel [(set (match_operand:TI 0 "register_operand" "")
12345 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12346 (match_operand:QI 2 "nonmemory_operand" "")))
12347 (clobber (reg:CC FLAGS_REG))])
12351 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12354 [(set (match_operand:TI 0 "register_operand" "")
12355 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12356 (match_operand:QI 2 "nonmemory_operand" "")))
12357 (clobber (reg:CC FLAGS_REG))]
12358 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12359 ? epilogue_completed : reload_completed)"
12361 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12363 (define_expand "lshrdi3"
12364 [(set (match_operand:DI 0 "shiftdi_operand" "")
12365 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12366 (match_operand:QI 2 "nonmemory_operand" "")))]
12368 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12370 (define_insn "*lshrdi3_1_one_bit_rex64"
12371 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12372 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12373 (match_operand:QI 2 "const1_operand" "")))
12374 (clobber (reg:CC FLAGS_REG))]
12376 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12377 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12379 [(set_attr "type" "ishift")
12380 (set_attr "length_immediate" "0")
12381 (set_attr "mode" "DI")])
12383 (define_insn "*lshrdi3_1_rex64"
12384 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12385 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12386 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12387 (clobber (reg:CC FLAGS_REG))]
12388 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12390 shr{q}\t{%2, %0|%0, %2}
12391 shr{q}\t{%b2, %0|%0, %b2}"
12392 [(set_attr "type" "ishift")
12393 (set_attr "mode" "DI")])
12395 ;; This pattern can't accept a variable shift count, since shifts by
12396 ;; zero don't affect the flags. We assume that shifts by constant
12397 ;; zero are optimized away.
12398 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12399 [(set (reg FLAGS_REG)
12401 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12402 (match_operand:QI 2 "const1_operand" ""))
12404 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12405 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12407 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408 && ix86_match_ccmode (insn, CCGOCmode)
12409 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12411 [(set_attr "type" "ishift")
12412 (set_attr "length_immediate" "0")
12413 (set_attr "mode" "DI")])
12415 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12416 [(set (reg FLAGS_REG)
12418 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12419 (match_operand:QI 2 "const1_operand" ""))
12421 (clobber (match_scratch:DI 0 "=r"))]
12423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12424 && ix86_match_ccmode (insn, CCGOCmode)
12425 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12427 [(set_attr "type" "ishift")
12428 (set_attr "length_immediate" "0")
12429 (set_attr "mode" "DI")])
12431 ;; This pattern can't accept a variable shift count, since shifts by
12432 ;; zero don't affect the flags. We assume that shifts by constant
12433 ;; zero are optimized away.
12434 (define_insn "*lshrdi3_cmp_rex64"
12435 [(set (reg FLAGS_REG)
12437 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12438 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12440 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12441 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12443 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12444 && ix86_match_ccmode (insn, CCGOCmode)
12445 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12446 "shr{q}\t{%2, %0|%0, %2}"
12447 [(set_attr "type" "ishift")
12448 (set_attr "mode" "DI")])
12450 (define_insn "*lshrdi3_cconly_rex64"
12451 [(set (reg FLAGS_REG)
12453 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12454 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12456 (clobber (match_scratch:DI 0 "=r"))]
12458 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12459 && ix86_match_ccmode (insn, CCGOCmode)
12460 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12461 "shr{q}\t{%2, %0|%0, %2}"
12462 [(set_attr "type" "ishift")
12463 (set_attr "mode" "DI")])
12465 (define_insn "*lshrdi3_1"
12466 [(set (match_operand:DI 0 "register_operand" "=r")
12467 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12468 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12469 (clobber (reg:CC FLAGS_REG))]
12472 [(set_attr "type" "multi")])
12474 ;; By default we don't ask for a scratch register, because when DImode
12475 ;; values are manipulated, registers are already at a premium. But if
12476 ;; we have one handy, we won't turn it away.
12478 [(match_scratch:SI 3 "r")
12479 (parallel [(set (match_operand:DI 0 "register_operand" "")
12480 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12481 (match_operand:QI 2 "nonmemory_operand" "")))
12482 (clobber (reg:CC FLAGS_REG))])
12484 "!TARGET_64BIT && TARGET_CMOVE"
12486 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12489 [(set (match_operand:DI 0 "register_operand" "")
12490 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12491 (match_operand:QI 2 "nonmemory_operand" "")))
12492 (clobber (reg:CC FLAGS_REG))]
12493 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12494 ? epilogue_completed : reload_completed)"
12496 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12498 (define_expand "lshrsi3"
12499 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12500 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12501 (match_operand:QI 2 "nonmemory_operand" "")))]
12503 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12505 (define_insn "*lshrsi3_1_one_bit"
12506 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12507 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12508 (match_operand:QI 2 "const1_operand" "")))
12509 (clobber (reg:CC FLAGS_REG))]
12510 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12511 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12513 [(set_attr "type" "ishift")
12514 (set_attr "length_immediate" "0")
12515 (set_attr "mode" "SI")])
12517 (define_insn "*lshrsi3_1_one_bit_zext"
12518 [(set (match_operand:DI 0 "register_operand" "=r")
12519 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12520 (match_operand:QI 2 "const1_operand" "")))
12521 (clobber (reg:CC FLAGS_REG))]
12523 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12524 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12526 [(set_attr "type" "ishift")
12527 (set_attr "length_immediate" "0")
12528 (set_attr "mode" "SI")])
12530 (define_insn "*lshrsi3_1"
12531 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12532 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12533 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12534 (clobber (reg:CC FLAGS_REG))]
12535 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12537 shr{l}\t{%2, %0|%0, %2}
12538 shr{l}\t{%b2, %0|%0, %b2}"
12539 [(set_attr "type" "ishift")
12540 (set_attr "mode" "SI")])
12542 (define_insn "*lshrsi3_1_zext"
12543 [(set (match_operand:DI 0 "register_operand" "=r,r")
12545 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12546 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12547 (clobber (reg:CC FLAGS_REG))]
12548 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12550 shr{l}\t{%2, %k0|%k0, %2}
12551 shr{l}\t{%b2, %k0|%k0, %b2}"
12552 [(set_attr "type" "ishift")
12553 (set_attr "mode" "SI")])
12555 ;; This pattern can't accept a variable shift count, since shifts by
12556 ;; zero don't affect the flags. We assume that shifts by constant
12557 ;; zero are optimized away.
12558 (define_insn "*lshrsi3_one_bit_cmp"
12559 [(set (reg FLAGS_REG)
12561 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12562 (match_operand:QI 2 "const1_operand" ""))
12564 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12565 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12566 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12567 && ix86_match_ccmode (insn, CCGOCmode)
12568 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12570 [(set_attr "type" "ishift")
12571 (set_attr "length_immediate" "0")
12572 (set_attr "mode" "SI")])
12574 (define_insn "*lshrsi3_one_bit_cconly"
12575 [(set (reg FLAGS_REG)
12577 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12578 (match_operand:QI 2 "const1_operand" ""))
12580 (clobber (match_scratch:SI 0 "=r"))]
12581 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12582 && ix86_match_ccmode (insn, CCGOCmode)
12583 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12585 [(set_attr "type" "ishift")
12586 (set_attr "length_immediate" "0")
12587 (set_attr "mode" "SI")])
12589 (define_insn "*lshrsi3_cmp_one_bit_zext"
12590 [(set (reg FLAGS_REG)
12592 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12593 (match_operand:QI 2 "const1_operand" ""))
12595 (set (match_operand:DI 0 "register_operand" "=r")
12596 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12598 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12599 && ix86_match_ccmode (insn, CCGOCmode)
12600 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12602 [(set_attr "type" "ishift")
12603 (set_attr "length_immediate" "0")
12604 (set_attr "mode" "SI")])
12606 ;; This pattern can't accept a variable shift count, since shifts by
12607 ;; zero don't affect the flags. We assume that shifts by constant
12608 ;; zero are optimized away.
12609 (define_insn "*lshrsi3_cmp"
12610 [(set (reg FLAGS_REG)
12612 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12613 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12615 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12616 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12617 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12618 && ix86_match_ccmode (insn, CCGOCmode)
12619 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12620 "shr{l}\t{%2, %0|%0, %2}"
12621 [(set_attr "type" "ishift")
12622 (set_attr "mode" "SI")])
12624 (define_insn "*lshrsi3_cconly"
12625 [(set (reg FLAGS_REG)
12627 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12628 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12630 (clobber (match_scratch:SI 0 "=r"))]
12631 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12632 && ix86_match_ccmode (insn, CCGOCmode)
12633 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12634 "shr{l}\t{%2, %0|%0, %2}"
12635 [(set_attr "type" "ishift")
12636 (set_attr "mode" "SI")])
12638 (define_insn "*lshrsi3_cmp_zext"
12639 [(set (reg FLAGS_REG)
12641 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12642 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12644 (set (match_operand:DI 0 "register_operand" "=r")
12645 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12647 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12648 && ix86_match_ccmode (insn, CCGOCmode)
12649 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12650 "shr{l}\t{%2, %k0|%k0, %2}"
12651 [(set_attr "type" "ishift")
12652 (set_attr "mode" "SI")])
12654 (define_expand "lshrhi3"
12655 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12656 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12657 (match_operand:QI 2 "nonmemory_operand" "")))]
12658 "TARGET_HIMODE_MATH"
12659 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12661 (define_insn "*lshrhi3_1_one_bit"
12662 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12663 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12664 (match_operand:QI 2 "const1_operand" "")))
12665 (clobber (reg:CC FLAGS_REG))]
12666 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12667 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12669 [(set_attr "type" "ishift")
12670 (set_attr "length_immediate" "0")
12671 (set_attr "mode" "HI")])
12673 (define_insn "*lshrhi3_1"
12674 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12675 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12676 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12677 (clobber (reg:CC FLAGS_REG))]
12678 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12680 shr{w}\t{%2, %0|%0, %2}
12681 shr{w}\t{%b2, %0|%0, %b2}"
12682 [(set_attr "type" "ishift")
12683 (set_attr "mode" "HI")])
12685 ;; This pattern can't accept a variable shift count, since shifts by
12686 ;; zero don't affect the flags. We assume that shifts by constant
12687 ;; zero are optimized away.
12688 (define_insn "*lshrhi3_one_bit_cmp"
12689 [(set (reg FLAGS_REG)
12691 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12692 (match_operand:QI 2 "const1_operand" ""))
12694 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12695 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12696 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12697 && ix86_match_ccmode (insn, CCGOCmode)
12698 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12700 [(set_attr "type" "ishift")
12701 (set_attr "length_immediate" "0")
12702 (set_attr "mode" "HI")])
12704 (define_insn "*lshrhi3_one_bit_cconly"
12705 [(set (reg FLAGS_REG)
12707 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12708 (match_operand:QI 2 "const1_operand" ""))
12710 (clobber (match_scratch:HI 0 "=r"))]
12711 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12712 && ix86_match_ccmode (insn, CCGOCmode)
12713 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12715 [(set_attr "type" "ishift")
12716 (set_attr "length_immediate" "0")
12717 (set_attr "mode" "HI")])
12719 ;; This pattern can't accept a variable shift count, since shifts by
12720 ;; zero don't affect the flags. We assume that shifts by constant
12721 ;; zero are optimized away.
12722 (define_insn "*lshrhi3_cmp"
12723 [(set (reg FLAGS_REG)
12725 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12726 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12728 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12729 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12730 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12731 && ix86_match_ccmode (insn, CCGOCmode)
12732 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12733 "shr{w}\t{%2, %0|%0, %2}"
12734 [(set_attr "type" "ishift")
12735 (set_attr "mode" "HI")])
12737 (define_insn "*lshrhi3_cconly"
12738 [(set (reg FLAGS_REG)
12740 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12741 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12743 (clobber (match_scratch:HI 0 "=r"))]
12744 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12745 && ix86_match_ccmode (insn, CCGOCmode)
12746 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12747 "shr{w}\t{%2, %0|%0, %2}"
12748 [(set_attr "type" "ishift")
12749 (set_attr "mode" "HI")])
12751 (define_expand "lshrqi3"
12752 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12753 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12754 (match_operand:QI 2 "nonmemory_operand" "")))]
12755 "TARGET_QIMODE_MATH"
12756 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12758 (define_insn "*lshrqi3_1_one_bit"
12759 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12760 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12761 (match_operand:QI 2 "const1_operand" "")))
12762 (clobber (reg:CC FLAGS_REG))]
12763 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12764 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12766 [(set_attr "type" "ishift")
12767 (set_attr "length_immediate" "0")
12768 (set_attr "mode" "QI")])
12770 (define_insn "*lshrqi3_1_one_bit_slp"
12771 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12772 (lshiftrt:QI (match_dup 0)
12773 (match_operand:QI 1 "const1_operand" "")))
12774 (clobber (reg:CC FLAGS_REG))]
12775 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12776 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12778 [(set_attr "type" "ishift1")
12779 (set_attr "length_immediate" "0")
12780 (set_attr "mode" "QI")])
12782 (define_insn "*lshrqi3_1"
12783 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12784 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12785 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12786 (clobber (reg:CC FLAGS_REG))]
12787 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12789 shr{b}\t{%2, %0|%0, %2}
12790 shr{b}\t{%b2, %0|%0, %b2}"
12791 [(set_attr "type" "ishift")
12792 (set_attr "mode" "QI")])
12794 (define_insn "*lshrqi3_1_slp"
12795 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12796 (lshiftrt:QI (match_dup 0)
12797 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12798 (clobber (reg:CC FLAGS_REG))]
12799 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12800 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12802 shr{b}\t{%1, %0|%0, %1}
12803 shr{b}\t{%b1, %0|%0, %b1}"
12804 [(set_attr "type" "ishift1")
12805 (set_attr "mode" "QI")])
12807 ;; This pattern can't accept a variable shift count, since shifts by
12808 ;; zero don't affect the flags. We assume that shifts by constant
12809 ;; zero are optimized away.
12810 (define_insn "*lshrqi2_one_bit_cmp"
12811 [(set (reg FLAGS_REG)
12813 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12814 (match_operand:QI 2 "const1_operand" ""))
12816 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12817 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12818 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12819 && ix86_match_ccmode (insn, CCGOCmode)
12820 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12822 [(set_attr "type" "ishift")
12823 (set_attr "length_immediate" "0")
12824 (set_attr "mode" "QI")])
12826 (define_insn "*lshrqi2_one_bit_cconly"
12827 [(set (reg FLAGS_REG)
12829 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12830 (match_operand:QI 2 "const1_operand" ""))
12832 (clobber (match_scratch:QI 0 "=q"))]
12833 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12834 && ix86_match_ccmode (insn, CCGOCmode)
12835 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12837 [(set_attr "type" "ishift")
12838 (set_attr "length_immediate" "0")
12839 (set_attr "mode" "QI")])
12841 ;; This pattern can't accept a variable shift count, since shifts by
12842 ;; zero don't affect the flags. We assume that shifts by constant
12843 ;; zero are optimized away.
12844 (define_insn "*lshrqi2_cmp"
12845 [(set (reg FLAGS_REG)
12847 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12848 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12850 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12851 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12852 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12853 && ix86_match_ccmode (insn, CCGOCmode)
12854 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12855 "shr{b}\t{%2, %0|%0, %2}"
12856 [(set_attr "type" "ishift")
12857 (set_attr "mode" "QI")])
12859 (define_insn "*lshrqi2_cconly"
12860 [(set (reg FLAGS_REG)
12862 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12863 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12865 (clobber (match_scratch:QI 0 "=q"))]
12866 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12867 && ix86_match_ccmode (insn, CCGOCmode)
12868 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12869 "shr{b}\t{%2, %0|%0, %2}"
12870 [(set_attr "type" "ishift")
12871 (set_attr "mode" "QI")])
12873 ;; Rotate instructions
12875 (define_expand "rotldi3"
12876 [(set (match_operand:DI 0 "shiftdi_operand" "")
12877 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12878 (match_operand:QI 2 "nonmemory_operand" "")))]
12883 ix86_expand_binary_operator (ROTATE, DImode, operands);
12886 if (!const_1_to_31_operand (operands[2], VOIDmode))
12888 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12892 ;; Implement rotation using two double-precision shift instructions
12893 ;; and a scratch register.
12894 (define_insn_and_split "ix86_rotldi3"
12895 [(set (match_operand:DI 0 "register_operand" "=r")
12896 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12897 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12898 (clobber (reg:CC FLAGS_REG))
12899 (clobber (match_scratch:SI 3 "=&r"))]
12902 "&& reload_completed"
12903 [(set (match_dup 3) (match_dup 4))
12905 [(set (match_dup 4)
12906 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12907 (lshiftrt:SI (match_dup 5)
12908 (minus:QI (const_int 32) (match_dup 2)))))
12909 (clobber (reg:CC FLAGS_REG))])
12911 [(set (match_dup 5)
12912 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12913 (lshiftrt:SI (match_dup 3)
12914 (minus:QI (const_int 32) (match_dup 2)))))
12915 (clobber (reg:CC FLAGS_REG))])]
12916 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12918 (define_insn "*rotlsi3_1_one_bit_rex64"
12919 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12920 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12921 (match_operand:QI 2 "const1_operand" "")))
12922 (clobber (reg:CC FLAGS_REG))]
12924 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12925 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12927 [(set_attr "type" "rotate")
12928 (set_attr "length_immediate" "0")
12929 (set_attr "mode" "DI")])
12931 (define_insn "*rotldi3_1_rex64"
12932 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12933 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12934 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12935 (clobber (reg:CC FLAGS_REG))]
12936 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12938 rol{q}\t{%2, %0|%0, %2}
12939 rol{q}\t{%b2, %0|%0, %b2}"
12940 [(set_attr "type" "rotate")
12941 (set_attr "mode" "DI")])
12943 (define_expand "rotlsi3"
12944 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12945 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12946 (match_operand:QI 2 "nonmemory_operand" "")))]
12948 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12950 (define_insn "*rotlsi3_1_one_bit"
12951 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12952 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12953 (match_operand:QI 2 "const1_operand" "")))
12954 (clobber (reg:CC FLAGS_REG))]
12955 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12956 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12958 [(set_attr "type" "rotate")
12959 (set_attr "length_immediate" "0")
12960 (set_attr "mode" "SI")])
12962 (define_insn "*rotlsi3_1_one_bit_zext"
12963 [(set (match_operand:DI 0 "register_operand" "=r")
12965 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12966 (match_operand:QI 2 "const1_operand" ""))))
12967 (clobber (reg:CC FLAGS_REG))]
12969 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12970 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12972 [(set_attr "type" "rotate")
12973 (set_attr "length_immediate" "0")
12974 (set_attr "mode" "SI")])
12976 (define_insn "*rotlsi3_1"
12977 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12978 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12979 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12980 (clobber (reg:CC FLAGS_REG))]
12981 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12983 rol{l}\t{%2, %0|%0, %2}
12984 rol{l}\t{%b2, %0|%0, %b2}"
12985 [(set_attr "type" "rotate")
12986 (set_attr "mode" "SI")])
12988 (define_insn "*rotlsi3_1_zext"
12989 [(set (match_operand:DI 0 "register_operand" "=r,r")
12991 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12992 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12993 (clobber (reg:CC FLAGS_REG))]
12994 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12996 rol{l}\t{%2, %k0|%k0, %2}
12997 rol{l}\t{%b2, %k0|%k0, %b2}"
12998 [(set_attr "type" "rotate")
12999 (set_attr "mode" "SI")])
13001 (define_expand "rotlhi3"
13002 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13003 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
13004 (match_operand:QI 2 "nonmemory_operand" "")))]
13005 "TARGET_HIMODE_MATH"
13006 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
13008 (define_insn "*rotlhi3_1_one_bit"
13009 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13010 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13011 (match_operand:QI 2 "const1_operand" "")))
13012 (clobber (reg:CC FLAGS_REG))]
13013 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13014 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
13016 [(set_attr "type" "rotate")
13017 (set_attr "length_immediate" "0")
13018 (set_attr "mode" "HI")])
13020 (define_insn "*rotlhi3_1"
13021 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13022 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13023 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13024 (clobber (reg:CC FLAGS_REG))]
13025 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
13027 rol{w}\t{%2, %0|%0, %2}
13028 rol{w}\t{%b2, %0|%0, %b2}"
13029 [(set_attr "type" "rotate")
13030 (set_attr "mode" "HI")])
13033 [(set (match_operand:HI 0 "register_operand" "")
13034 (rotate:HI (match_dup 0) (const_int 8)))
13035 (clobber (reg:CC FLAGS_REG))]
13037 [(parallel [(set (strict_low_part (match_dup 0))
13038 (bswap:HI (match_dup 0)))
13039 (clobber (reg:CC FLAGS_REG))])]
13042 (define_expand "rotlqi3"
13043 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13044 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
13045 (match_operand:QI 2 "nonmemory_operand" "")))]
13046 "TARGET_QIMODE_MATH"
13047 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
13049 (define_insn "*rotlqi3_1_one_bit_slp"
13050 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13051 (rotate:QI (match_dup 0)
13052 (match_operand:QI 1 "const1_operand" "")))
13053 (clobber (reg:CC FLAGS_REG))]
13054 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13055 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13057 [(set_attr "type" "rotate1")
13058 (set_attr "length_immediate" "0")
13059 (set_attr "mode" "QI")])
13061 (define_insn "*rotlqi3_1_one_bit"
13062 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13063 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13064 (match_operand:QI 2 "const1_operand" "")))
13065 (clobber (reg:CC FLAGS_REG))]
13066 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13067 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
13069 [(set_attr "type" "rotate")
13070 (set_attr "length_immediate" "0")
13071 (set_attr "mode" "QI")])
13073 (define_insn "*rotlqi3_1_slp"
13074 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13075 (rotate:QI (match_dup 0)
13076 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13077 (clobber (reg:CC FLAGS_REG))]
13078 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13079 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13081 rol{b}\t{%1, %0|%0, %1}
13082 rol{b}\t{%b1, %0|%0, %b1}"
13083 [(set_attr "type" "rotate1")
13084 (set_attr "mode" "QI")])
13086 (define_insn "*rotlqi3_1"
13087 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13088 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13089 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13090 (clobber (reg:CC FLAGS_REG))]
13091 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
13093 rol{b}\t{%2, %0|%0, %2}
13094 rol{b}\t{%b2, %0|%0, %b2}"
13095 [(set_attr "type" "rotate")
13096 (set_attr "mode" "QI")])
13098 (define_expand "rotrdi3"
13099 [(set (match_operand:DI 0 "shiftdi_operand" "")
13100 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
13101 (match_operand:QI 2 "nonmemory_operand" "")))]
13106 ix86_expand_binary_operator (ROTATERT, DImode, operands);
13109 if (!const_1_to_31_operand (operands[2], VOIDmode))
13111 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
13115 ;; Implement rotation using two double-precision shift instructions
13116 ;; and a scratch register.
13117 (define_insn_and_split "ix86_rotrdi3"
13118 [(set (match_operand:DI 0 "register_operand" "=r")
13119 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
13120 (match_operand:QI 2 "const_1_to_31_operand" "I")))
13121 (clobber (reg:CC FLAGS_REG))
13122 (clobber (match_scratch:SI 3 "=&r"))]
13125 "&& reload_completed"
13126 [(set (match_dup 3) (match_dup 4))
13128 [(set (match_dup 4)
13129 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
13130 (ashift:SI (match_dup 5)
13131 (minus:QI (const_int 32) (match_dup 2)))))
13132 (clobber (reg:CC FLAGS_REG))])
13134 [(set (match_dup 5)
13135 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
13136 (ashift:SI (match_dup 3)
13137 (minus:QI (const_int 32) (match_dup 2)))))
13138 (clobber (reg:CC FLAGS_REG))])]
13139 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
13141 (define_insn "*rotrdi3_1_one_bit_rex64"
13142 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13143 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13144 (match_operand:QI 2 "const1_operand" "")))
13145 (clobber (reg:CC FLAGS_REG))]
13147 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13148 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13150 [(set_attr "type" "rotate")
13151 (set_attr "length_immediate" "0")
13152 (set_attr "mode" "DI")])
13154 (define_insn "*rotrdi3_1_rex64"
13155 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13156 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13157 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13158 (clobber (reg:CC FLAGS_REG))]
13159 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
13161 ror{q}\t{%2, %0|%0, %2}
13162 ror{q}\t{%b2, %0|%0, %b2}"
13163 [(set_attr "type" "rotate")
13164 (set_attr "mode" "DI")])
13166 (define_expand "rotrsi3"
13167 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13168 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
13169 (match_operand:QI 2 "nonmemory_operand" "")))]
13171 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
13173 (define_insn "*rotrsi3_1_one_bit"
13174 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13175 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13176 (match_operand:QI 2 "const1_operand" "")))
13177 (clobber (reg:CC FLAGS_REG))]
13178 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13179 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13181 [(set_attr "type" "rotate")
13182 (set_attr "length_immediate" "0")
13183 (set_attr "mode" "SI")])
13185 (define_insn "*rotrsi3_1_one_bit_zext"
13186 [(set (match_operand:DI 0 "register_operand" "=r")
13188 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
13189 (match_operand:QI 2 "const1_operand" ""))))
13190 (clobber (reg:CC FLAGS_REG))]
13192 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13193 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13195 [(set_attr "type" "rotate")
13196 (set_attr "length_immediate" "0")
13197 (set_attr "mode" "SI")])
13199 (define_insn "*rotrsi3_1"
13200 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13201 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13202 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13203 (clobber (reg:CC FLAGS_REG))]
13204 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13206 ror{l}\t{%2, %0|%0, %2}
13207 ror{l}\t{%b2, %0|%0, %b2}"
13208 [(set_attr "type" "rotate")
13209 (set_attr "mode" "SI")])
13211 (define_insn "*rotrsi3_1_zext"
13212 [(set (match_operand:DI 0 "register_operand" "=r,r")
13214 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
13215 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13216 (clobber (reg:CC FLAGS_REG))]
13217 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
13219 ror{l}\t{%2, %k0|%k0, %2}
13220 ror{l}\t{%b2, %k0|%k0, %b2}"
13221 [(set_attr "type" "rotate")
13222 (set_attr "mode" "SI")])
13224 (define_expand "rotrhi3"
13225 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13226 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
13227 (match_operand:QI 2 "nonmemory_operand" "")))]
13228 "TARGET_HIMODE_MATH"
13229 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13231 (define_insn "*rotrhi3_one_bit"
13232 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13233 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13234 (match_operand:QI 2 "const1_operand" "")))
13235 (clobber (reg:CC FLAGS_REG))]
13236 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13237 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13239 [(set_attr "type" "rotate")
13240 (set_attr "length_immediate" "0")
13241 (set_attr "mode" "HI")])
13243 (define_insn "*rotrhi3_1"
13244 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13245 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13246 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13247 (clobber (reg:CC FLAGS_REG))]
13248 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13250 ror{w}\t{%2, %0|%0, %2}
13251 ror{w}\t{%b2, %0|%0, %b2}"
13252 [(set_attr "type" "rotate")
13253 (set_attr "mode" "HI")])
13256 [(set (match_operand:HI 0 "register_operand" "")
13257 (rotatert:HI (match_dup 0) (const_int 8)))
13258 (clobber (reg:CC FLAGS_REG))]
13260 [(parallel [(set (strict_low_part (match_dup 0))
13261 (bswap:HI (match_dup 0)))
13262 (clobber (reg:CC FLAGS_REG))])]
13265 (define_expand "rotrqi3"
13266 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13267 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13268 (match_operand:QI 2 "nonmemory_operand" "")))]
13269 "TARGET_QIMODE_MATH"
13270 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13272 (define_insn "*rotrqi3_1_one_bit"
13273 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13274 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13275 (match_operand:QI 2 "const1_operand" "")))
13276 (clobber (reg:CC FLAGS_REG))]
13277 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13278 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13280 [(set_attr "type" "rotate")
13281 (set_attr "length_immediate" "0")
13282 (set_attr "mode" "QI")])
13284 (define_insn "*rotrqi3_1_one_bit_slp"
13285 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13286 (rotatert:QI (match_dup 0)
13287 (match_operand:QI 1 "const1_operand" "")))
13288 (clobber (reg:CC FLAGS_REG))]
13289 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13290 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13292 [(set_attr "type" "rotate1")
13293 (set_attr "length_immediate" "0")
13294 (set_attr "mode" "QI")])
13296 (define_insn "*rotrqi3_1"
13297 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13298 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13299 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13300 (clobber (reg:CC FLAGS_REG))]
13301 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13303 ror{b}\t{%2, %0|%0, %2}
13304 ror{b}\t{%b2, %0|%0, %b2}"
13305 [(set_attr "type" "rotate")
13306 (set_attr "mode" "QI")])
13308 (define_insn "*rotrqi3_1_slp"
13309 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13310 (rotatert:QI (match_dup 0)
13311 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13312 (clobber (reg:CC FLAGS_REG))]
13313 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13314 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13316 ror{b}\t{%1, %0|%0, %1}
13317 ror{b}\t{%b1, %0|%0, %b1}"
13318 [(set_attr "type" "rotate1")
13319 (set_attr "mode" "QI")])
13321 ;; Bit set / bit test instructions
13323 (define_expand "extv"
13324 [(set (match_operand:SI 0 "register_operand" "")
13325 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13326 (match_operand:SI 2 "const8_operand" "")
13327 (match_operand:SI 3 "const8_operand" "")))]
13330 /* Handle extractions from %ah et al. */
13331 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13334 /* From mips.md: extract_bit_field doesn't verify that our source
13335 matches the predicate, so check it again here. */
13336 if (! ext_register_operand (operands[1], VOIDmode))
13340 (define_expand "extzv"
13341 [(set (match_operand:SI 0 "register_operand" "")
13342 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13343 (match_operand:SI 2 "const8_operand" "")
13344 (match_operand:SI 3 "const8_operand" "")))]
13347 /* Handle extractions from %ah et al. */
13348 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13351 /* From mips.md: extract_bit_field doesn't verify that our source
13352 matches the predicate, so check it again here. */
13353 if (! ext_register_operand (operands[1], VOIDmode))
13357 (define_expand "insv"
13358 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13359 (match_operand 1 "const8_operand" "")
13360 (match_operand 2 "const8_operand" ""))
13361 (match_operand 3 "register_operand" ""))]
13364 /* Handle insertions to %ah et al. */
13365 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13368 /* From mips.md: insert_bit_field doesn't verify that our source
13369 matches the predicate, so check it again here. */
13370 if (! ext_register_operand (operands[0], VOIDmode))
13374 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13376 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13381 ;; %%% bts, btr, btc, bt.
13382 ;; In general these instructions are *slow* when applied to memory,
13383 ;; since they enforce atomic operation. When applied to registers,
13384 ;; it depends on the cpu implementation. They're never faster than
13385 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13386 ;; no point. But in 64-bit, we can't hold the relevant immediates
13387 ;; within the instruction itself, so operating on bits in the high
13388 ;; 32-bits of a register becomes easier.
13390 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13391 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13392 ;; negdf respectively, so they can never be disabled entirely.
13394 (define_insn "*btsq"
13395 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13397 (match_operand:DI 1 "const_0_to_63_operand" ""))
13399 (clobber (reg:CC FLAGS_REG))]
13400 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13401 "bts{q}\t{%1, %0|%0, %1}"
13402 [(set_attr "type" "alu1")
13403 (set_attr "prefix_0f" "1")
13404 (set_attr "mode" "DI")])
13406 (define_insn "*btrq"
13407 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13409 (match_operand:DI 1 "const_0_to_63_operand" ""))
13411 (clobber (reg:CC FLAGS_REG))]
13412 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13413 "btr{q}\t{%1, %0|%0, %1}"
13414 [(set_attr "type" "alu1")
13415 (set_attr "prefix_0f" "1")
13416 (set_attr "mode" "DI")])
13418 (define_insn "*btcq"
13419 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13421 (match_operand:DI 1 "const_0_to_63_operand" ""))
13422 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13423 (clobber (reg:CC FLAGS_REG))]
13424 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13425 "btc{q}\t{%1, %0|%0, %1}"
13426 [(set_attr "type" "alu1")
13427 (set_attr "prefix_0f" "1")
13428 (set_attr "mode" "DI")])
13430 ;; Allow Nocona to avoid these instructions if a register is available.
13433 [(match_scratch:DI 2 "r")
13434 (parallel [(set (zero_extract:DI
13435 (match_operand:DI 0 "register_operand" "")
13437 (match_operand:DI 1 "const_0_to_63_operand" ""))
13439 (clobber (reg:CC FLAGS_REG))])]
13440 "TARGET_64BIT && !TARGET_USE_BT"
13443 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13446 if (HOST_BITS_PER_WIDE_INT >= 64)
13447 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13448 else if (i < HOST_BITS_PER_WIDE_INT)
13449 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13451 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13453 op1 = immed_double_const (lo, hi, DImode);
13456 emit_move_insn (operands[2], op1);
13460 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13465 [(match_scratch:DI 2 "r")
13466 (parallel [(set (zero_extract:DI
13467 (match_operand:DI 0 "register_operand" "")
13469 (match_operand:DI 1 "const_0_to_63_operand" ""))
13471 (clobber (reg:CC FLAGS_REG))])]
13472 "TARGET_64BIT && !TARGET_USE_BT"
13475 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13478 if (HOST_BITS_PER_WIDE_INT >= 64)
13479 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13480 else if (i < HOST_BITS_PER_WIDE_INT)
13481 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13483 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13485 op1 = immed_double_const (~lo, ~hi, DImode);
13488 emit_move_insn (operands[2], op1);
13492 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13497 [(match_scratch:DI 2 "r")
13498 (parallel [(set (zero_extract:DI
13499 (match_operand:DI 0 "register_operand" "")
13501 (match_operand:DI 1 "const_0_to_63_operand" ""))
13502 (not:DI (zero_extract:DI
13503 (match_dup 0) (const_int 1) (match_dup 1))))
13504 (clobber (reg:CC FLAGS_REG))])]
13505 "TARGET_64BIT && !TARGET_USE_BT"
13508 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13511 if (HOST_BITS_PER_WIDE_INT >= 64)
13512 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13513 else if (i < HOST_BITS_PER_WIDE_INT)
13514 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13516 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13518 op1 = immed_double_const (lo, hi, DImode);
13521 emit_move_insn (operands[2], op1);
13525 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13529 (define_insn "*btdi_rex64"
13530 [(set (reg:CCC FLAGS_REG)
13533 (match_operand:DI 0 "register_operand" "r")
13535 (match_operand:DI 1 "nonmemory_operand" "rN"))
13537 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13538 "bt{q}\t{%1, %0|%0, %1}"
13539 [(set_attr "type" "alu1")
13540 (set_attr "prefix_0f" "1")
13541 (set_attr "mode" "DI")])
13543 (define_insn "*btsi"
13544 [(set (reg:CCC FLAGS_REG)
13547 (match_operand:SI 0 "register_operand" "r")
13549 (match_operand:SI 1 "nonmemory_operand" "rN"))
13551 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13552 "bt{l}\t{%1, %0|%0, %1}"
13553 [(set_attr "type" "alu1")
13554 (set_attr "prefix_0f" "1")
13555 (set_attr "mode" "SI")])
13557 ;; Store-flag instructions.
13559 ;; For all sCOND expanders, also expand the compare or test insn that
13560 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13562 (define_insn_and_split "*setcc_di_1"
13563 [(set (match_operand:DI 0 "register_operand" "=q")
13564 (match_operator:DI 1 "ix86_comparison_operator"
13565 [(reg FLAGS_REG) (const_int 0)]))]
13566 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
13568 "&& reload_completed"
13569 [(set (match_dup 2) (match_dup 1))
13570 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
13572 PUT_MODE (operands[1], QImode);
13573 operands[2] = gen_lowpart (QImode, operands[0]);
13576 (define_insn_and_split "*setcc_si_1_and"
13577 [(set (match_operand:SI 0 "register_operand" "=q")
13578 (match_operator:SI 1 "ix86_comparison_operator"
13579 [(reg FLAGS_REG) (const_int 0)]))
13580 (clobber (reg:CC FLAGS_REG))]
13581 "!TARGET_PARTIAL_REG_STALL
13582 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
13584 "&& reload_completed"
13585 [(set (match_dup 2) (match_dup 1))
13586 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
13587 (clobber (reg:CC FLAGS_REG))])]
13589 PUT_MODE (operands[1], QImode);
13590 operands[2] = gen_lowpart (QImode, operands[0]);
13593 (define_insn_and_split "*setcc_si_1_movzbl"
13594 [(set (match_operand:SI 0 "register_operand" "=q")
13595 (match_operator:SI 1 "ix86_comparison_operator"
13596 [(reg FLAGS_REG) (const_int 0)]))]
13597 "!TARGET_PARTIAL_REG_STALL
13598 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
13600 "&& reload_completed"
13601 [(set (match_dup 2) (match_dup 1))
13602 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
13604 PUT_MODE (operands[1], QImode);
13605 operands[2] = gen_lowpart (QImode, operands[0]);
13608 (define_insn "*setcc_qi"
13609 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13610 (match_operator:QI 1 "ix86_comparison_operator"
13611 [(reg FLAGS_REG) (const_int 0)]))]
13614 [(set_attr "type" "setcc")
13615 (set_attr "mode" "QI")])
13617 (define_insn "*setcc_qi_slp"
13618 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13619 (match_operator:QI 1 "ix86_comparison_operator"
13620 [(reg FLAGS_REG) (const_int 0)]))]
13623 [(set_attr "type" "setcc")
13624 (set_attr "mode" "QI")])
13626 ;; In general it is not safe to assume too much about CCmode registers,
13627 ;; so simplify-rtx stops when it sees a second one. Under certain
13628 ;; conditions this is safe on x86, so help combine not create
13635 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13636 (ne:QI (match_operator 1 "ix86_comparison_operator"
13637 [(reg FLAGS_REG) (const_int 0)])
13640 [(set (match_dup 0) (match_dup 1))]
13642 PUT_MODE (operands[1], QImode);
13646 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13647 (ne:QI (match_operator 1 "ix86_comparison_operator"
13648 [(reg FLAGS_REG) (const_int 0)])
13651 [(set (match_dup 0) (match_dup 1))]
13653 PUT_MODE (operands[1], QImode);
13657 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13658 (eq:QI (match_operator 1 "ix86_comparison_operator"
13659 [(reg FLAGS_REG) (const_int 0)])
13662 [(set (match_dup 0) (match_dup 1))]
13664 rtx new_op1 = copy_rtx (operands[1]);
13665 operands[1] = new_op1;
13666 PUT_MODE (new_op1, QImode);
13667 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13668 GET_MODE (XEXP (new_op1, 0))));
13670 /* Make sure that (a) the CCmode we have for the flags is strong
13671 enough for the reversed compare or (b) we have a valid FP compare. */
13672 if (! ix86_comparison_operator (new_op1, VOIDmode))
13677 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13678 (eq:QI (match_operator 1 "ix86_comparison_operator"
13679 [(reg FLAGS_REG) (const_int 0)])
13682 [(set (match_dup 0) (match_dup 1))]
13684 rtx new_op1 = copy_rtx (operands[1]);
13685 operands[1] = new_op1;
13686 PUT_MODE (new_op1, QImode);
13687 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13688 GET_MODE (XEXP (new_op1, 0))));
13690 /* Make sure that (a) the CCmode we have for the flags is strong
13691 enough for the reversed compare or (b) we have a valid FP compare. */
13692 if (! ix86_comparison_operator (new_op1, VOIDmode))
13696 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13697 ;; subsequent logical operations are used to imitate conditional moves.
13698 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13701 (define_insn "*avx_setcc<mode>"
13702 [(set (match_operand:MODEF 0 "register_operand" "=x")
13703 (match_operator:MODEF 1 "avx_comparison_float_operator"
13704 [(match_operand:MODEF 2 "register_operand" "x")
13705 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13707 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13708 [(set_attr "type" "ssecmp")
13709 (set_attr "prefix" "vex")
13710 (set_attr "length_immediate" "1")
13711 (set_attr "mode" "<MODE>")])
13713 (define_insn "*sse_setcc<mode>"
13714 [(set (match_operand:MODEF 0 "register_operand" "=x")
13715 (match_operator:MODEF 1 "sse_comparison_operator"
13716 [(match_operand:MODEF 2 "register_operand" "0")
13717 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13718 "SSE_FLOAT_MODE_P (<MODE>mode)"
13719 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13720 [(set_attr "type" "ssecmp")
13721 (set_attr "length_immediate" "1")
13722 (set_attr "mode" "<MODE>")])
13724 ;; Basic conditional jump instructions.
13725 ;; We ignore the overflow flag for signed branch instructions.
13727 (define_insn "*jcc_1"
13729 (if_then_else (match_operator 1 "ix86_comparison_operator"
13730 [(reg FLAGS_REG) (const_int 0)])
13731 (label_ref (match_operand 0 "" ""))
13735 [(set_attr "type" "ibr")
13736 (set_attr "modrm" "0")
13737 (set (attr "length")
13738 (if_then_else (and (ge (minus (match_dup 0) (pc))
13740 (lt (minus (match_dup 0) (pc))
13745 (define_insn "*jcc_2"
13747 (if_then_else (match_operator 1 "ix86_comparison_operator"
13748 [(reg FLAGS_REG) (const_int 0)])
13750 (label_ref (match_operand 0 "" ""))))]
13753 [(set_attr "type" "ibr")
13754 (set_attr "modrm" "0")
13755 (set (attr "length")
13756 (if_then_else (and (ge (minus (match_dup 0) (pc))
13758 (lt (minus (match_dup 0) (pc))
13763 ;; In general it is not safe to assume too much about CCmode registers,
13764 ;; so simplify-rtx stops when it sees a second one. Under certain
13765 ;; conditions this is safe on x86, so help combine not create
13773 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13774 [(reg FLAGS_REG) (const_int 0)])
13776 (label_ref (match_operand 1 "" ""))
13780 (if_then_else (match_dup 0)
13781 (label_ref (match_dup 1))
13784 PUT_MODE (operands[0], VOIDmode);
13789 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13790 [(reg FLAGS_REG) (const_int 0)])
13792 (label_ref (match_operand 1 "" ""))
13796 (if_then_else (match_dup 0)
13797 (label_ref (match_dup 1))
13800 rtx new_op0 = copy_rtx (operands[0]);
13801 operands[0] = new_op0;
13802 PUT_MODE (new_op0, VOIDmode);
13803 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13804 GET_MODE (XEXP (new_op0, 0))));
13806 /* Make sure that (a) the CCmode we have for the flags is strong
13807 enough for the reversed compare or (b) we have a valid FP compare. */
13808 if (! ix86_comparison_operator (new_op0, VOIDmode))
13812 ;; zero_extend in SImode is correct, since this is what combine pass
13813 ;; generates from shift insn with QImode operand. Actually, the mode of
13814 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
13815 ;; appropriate modulo of the bit offset value.
13817 (define_insn_and_split "*jcc_btdi_rex64"
13819 (if_then_else (match_operator 0 "bt_comparison_operator"
13821 (match_operand:DI 1 "register_operand" "r")
13824 (match_operand:QI 2 "register_operand" "r")))
13826 (label_ref (match_operand 3 "" ""))
13828 (clobber (reg:CC FLAGS_REG))]
13829 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13832 [(set (reg:CCC FLAGS_REG)
13840 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13841 (label_ref (match_dup 3))
13844 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13846 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13849 ;; avoid useless masking of bit offset operand
13850 (define_insn_and_split "*jcc_btdi_mask_rex64"
13852 (if_then_else (match_operator 0 "bt_comparison_operator"
13854 (match_operand:DI 1 "register_operand" "r")
13857 (match_operand:SI 2 "register_operand" "r")
13858 (match_operand:SI 3 "const_int_operand" "n")))])
13859 (label_ref (match_operand 4 "" ""))
13861 (clobber (reg:CC FLAGS_REG))]
13862 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13863 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13866 [(set (reg:CCC FLAGS_REG)
13874 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13875 (label_ref (match_dup 4))
13878 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13880 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13883 (define_insn_and_split "*jcc_btsi"
13885 (if_then_else (match_operator 0 "bt_comparison_operator"
13887 (match_operand:SI 1 "register_operand" "r")
13890 (match_operand:QI 2 "register_operand" "r")))
13892 (label_ref (match_operand 3 "" ""))
13894 (clobber (reg:CC FLAGS_REG))]
13895 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13898 [(set (reg:CCC FLAGS_REG)
13906 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13907 (label_ref (match_dup 3))
13910 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13912 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13915 ;; avoid useless masking of bit offset operand
13916 (define_insn_and_split "*jcc_btsi_mask"
13918 (if_then_else (match_operator 0 "bt_comparison_operator"
13920 (match_operand:SI 1 "register_operand" "r")
13923 (match_operand:SI 2 "register_operand" "r")
13924 (match_operand:SI 3 "const_int_operand" "n")))])
13925 (label_ref (match_operand 4 "" ""))
13927 (clobber (reg:CC FLAGS_REG))]
13928 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13929 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13932 [(set (reg:CCC FLAGS_REG)
13940 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13941 (label_ref (match_dup 4))
13943 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13945 (define_insn_and_split "*jcc_btsi_1"
13947 (if_then_else (match_operator 0 "bt_comparison_operator"
13950 (match_operand:SI 1 "register_operand" "r")
13951 (match_operand:QI 2 "register_operand" "r"))
13954 (label_ref (match_operand 3 "" ""))
13956 (clobber (reg:CC FLAGS_REG))]
13957 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13960 [(set (reg:CCC FLAGS_REG)
13968 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13969 (label_ref (match_dup 3))
13972 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13974 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13977 ;; avoid useless masking of bit offset operand
13978 (define_insn_and_split "*jcc_btsi_mask_1"
13981 (match_operator 0 "bt_comparison_operator"
13984 (match_operand:SI 1 "register_operand" "r")
13987 (match_operand:SI 2 "register_operand" "r")
13988 (match_operand:SI 3 "const_int_operand" "n")) 0))
13991 (label_ref (match_operand 4 "" ""))
13993 (clobber (reg:CC FLAGS_REG))]
13994 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13995 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13998 [(set (reg:CCC FLAGS_REG)
14006 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14007 (label_ref (match_dup 4))
14009 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
14011 ;; Define combination compare-and-branch fp compare instructions to help
14014 (define_insn "*fp_jcc_3_387"
14016 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14017 [(match_operand 1 "register_operand" "f")
14018 (match_operand 2 "nonimmediate_operand" "fm")])
14019 (label_ref (match_operand 3 "" ""))
14021 (clobber (reg:CCFP FPSR_REG))
14022 (clobber (reg:CCFP FLAGS_REG))
14023 (clobber (match_scratch:HI 4 "=a"))]
14025 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14026 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14027 && SELECT_CC_MODE (GET_CODE (operands[0]),
14028 operands[1], operands[2]) == CCFPmode
14032 (define_insn "*fp_jcc_4_387"
14034 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14035 [(match_operand 1 "register_operand" "f")
14036 (match_operand 2 "nonimmediate_operand" "fm")])
14038 (label_ref (match_operand 3 "" ""))))
14039 (clobber (reg:CCFP FPSR_REG))
14040 (clobber (reg:CCFP FLAGS_REG))
14041 (clobber (match_scratch:HI 4 "=a"))]
14043 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
14044 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14045 && SELECT_CC_MODE (GET_CODE (operands[0]),
14046 operands[1], operands[2]) == CCFPmode
14050 (define_insn "*fp_jcc_5_387"
14052 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14053 [(match_operand 1 "register_operand" "f")
14054 (match_operand 2 "register_operand" "f")])
14055 (label_ref (match_operand 3 "" ""))
14057 (clobber (reg:CCFP FPSR_REG))
14058 (clobber (reg:CCFP FLAGS_REG))
14059 (clobber (match_scratch:HI 4 "=a"))]
14060 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14061 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14065 (define_insn "*fp_jcc_6_387"
14067 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14068 [(match_operand 1 "register_operand" "f")
14069 (match_operand 2 "register_operand" "f")])
14071 (label_ref (match_operand 3 "" ""))))
14072 (clobber (reg:CCFP FPSR_REG))
14073 (clobber (reg:CCFP FLAGS_REG))
14074 (clobber (match_scratch:HI 4 "=a"))]
14075 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14076 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14080 (define_insn "*fp_jcc_7_387"
14082 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14083 [(match_operand 1 "register_operand" "f")
14084 (match_operand 2 "const0_operand" "")])
14085 (label_ref (match_operand 3 "" ""))
14087 (clobber (reg:CCFP FPSR_REG))
14088 (clobber (reg:CCFP FLAGS_REG))
14089 (clobber (match_scratch:HI 4 "=a"))]
14090 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
14091 && GET_MODE (operands[1]) == GET_MODE (operands[2])
14092 && SELECT_CC_MODE (GET_CODE (operands[0]),
14093 operands[1], operands[2]) == CCFPmode
14097 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
14098 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
14099 ;; with a precedence over other operators and is always put in the first
14100 ;; place. Swap condition and operands to match ficom instruction.
14102 (define_insn "*fp_jcc_8<mode>_387"
14104 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14105 [(match_operator 1 "float_operator"
14106 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
14107 (match_operand 3 "register_operand" "f,f")])
14108 (label_ref (match_operand 4 "" ""))
14110 (clobber (reg:CCFP FPSR_REG))
14111 (clobber (reg:CCFP FLAGS_REG))
14112 (clobber (match_scratch:HI 5 "=a,a"))]
14113 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
14114 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
14115 && GET_MODE (operands[1]) == GET_MODE (operands[3])
14116 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
14122 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14123 [(match_operand 1 "register_operand" "")
14124 (match_operand 2 "nonimmediate_operand" "")])
14125 (match_operand 3 "" "")
14126 (match_operand 4 "" "")))
14127 (clobber (reg:CCFP FPSR_REG))
14128 (clobber (reg:CCFP FLAGS_REG))]
14132 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14133 operands[3], operands[4], NULL_RTX, NULL_RTX);
14139 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14140 [(match_operand 1 "register_operand" "")
14141 (match_operand 2 "general_operand" "")])
14142 (match_operand 3 "" "")
14143 (match_operand 4 "" "")))
14144 (clobber (reg:CCFP FPSR_REG))
14145 (clobber (reg:CCFP FLAGS_REG))
14146 (clobber (match_scratch:HI 5 "=a"))]
14150 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
14151 operands[3], operands[4], operands[5], NULL_RTX);
14157 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14158 [(match_operator 1 "float_operator"
14159 [(match_operand:X87MODEI12 2 "memory_operand" "")])
14160 (match_operand 3 "register_operand" "")])
14161 (match_operand 4 "" "")
14162 (match_operand 5 "" "")))
14163 (clobber (reg:CCFP FPSR_REG))
14164 (clobber (reg:CCFP FLAGS_REG))
14165 (clobber (match_scratch:HI 6 "=a"))]
14169 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
14170 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14171 operands[3], operands[7],
14172 operands[4], operands[5], operands[6], NULL_RTX);
14176 ;; %%% Kill this when reload knows how to do it.
14179 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
14180 [(match_operator 1 "float_operator"
14181 [(match_operand:X87MODEI12 2 "register_operand" "")])
14182 (match_operand 3 "register_operand" "")])
14183 (match_operand 4 "" "")
14184 (match_operand 5 "" "")))
14185 (clobber (reg:CCFP FPSR_REG))
14186 (clobber (reg:CCFP FLAGS_REG))
14187 (clobber (match_scratch:HI 6 "=a"))]
14191 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
14192 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
14193 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
14194 operands[3], operands[7],
14195 operands[4], operands[5], operands[6], operands[2]);
14199 ;; Unconditional and other jump instructions
14201 (define_insn "jump"
14203 (label_ref (match_operand 0 "" "")))]
14206 [(set_attr "type" "ibr")
14207 (set (attr "length")
14208 (if_then_else (and (ge (minus (match_dup 0) (pc))
14210 (lt (minus (match_dup 0) (pc))
14214 (set_attr "modrm" "0")])
14216 (define_expand "indirect_jump"
14217 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
14221 (define_insn "*indirect_jump"
14222 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
14225 [(set_attr "type" "ibr")
14226 (set_attr "length_immediate" "0")])
14228 (define_expand "tablejump"
14229 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14230 (use (label_ref (match_operand 1 "" "")))])]
14233 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14234 relative. Convert the relative address to an absolute address. */
14238 enum rtx_code code;
14240 /* We can't use @GOTOFF for text labels on VxWorks;
14241 see gotoff_operand. */
14242 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14246 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14248 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14252 op1 = pic_offset_table_rtx;
14257 op0 = pic_offset_table_rtx;
14261 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14266 (define_insn "*tablejump_1"
14267 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14268 (use (label_ref (match_operand 1 "" "")))]
14271 [(set_attr "type" "ibr")
14272 (set_attr "length_immediate" "0")])
14274 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14277 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14278 (set (match_operand:QI 1 "register_operand" "")
14279 (match_operator:QI 2 "ix86_comparison_operator"
14280 [(reg FLAGS_REG) (const_int 0)]))
14281 (set (match_operand 3 "q_regs_operand" "")
14282 (zero_extend (match_dup 1)))]
14283 "(peep2_reg_dead_p (3, operands[1])
14284 || operands_match_p (operands[1], operands[3]))
14285 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14286 [(set (match_dup 4) (match_dup 0))
14287 (set (strict_low_part (match_dup 5))
14290 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14291 operands[5] = gen_lowpart (QImode, operands[3]);
14292 ix86_expand_clear (operands[3]);
14295 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14298 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14299 (set (match_operand:QI 1 "register_operand" "")
14300 (match_operator:QI 2 "ix86_comparison_operator"
14301 [(reg FLAGS_REG) (const_int 0)]))
14302 (parallel [(set (match_operand 3 "q_regs_operand" "")
14303 (zero_extend (match_dup 1)))
14304 (clobber (reg:CC FLAGS_REG))])]
14305 "(peep2_reg_dead_p (3, operands[1])
14306 || operands_match_p (operands[1], operands[3]))
14307 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14308 [(set (match_dup 4) (match_dup 0))
14309 (set (strict_low_part (match_dup 5))
14312 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14313 operands[5] = gen_lowpart (QImode, operands[3]);
14314 ix86_expand_clear (operands[3]);
14317 ;; Call instructions.
14319 ;; The predicates normally associated with named expanders are not properly
14320 ;; checked for calls. This is a bug in the generic code, but it isn't that
14321 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14323 ;; P6 processors will jump to the address after the decrement when %esp
14324 ;; is used as a call operand, so they will execute return address as a code.
14325 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
14327 ;; Call subroutine returning no value.
14329 (define_expand "call_pop"
14330 [(parallel [(call (match_operand:QI 0 "" "")
14331 (match_operand:SI 1 "" ""))
14332 (set (reg:SI SP_REG)
14333 (plus:SI (reg:SI SP_REG)
14334 (match_operand:SI 3 "" "")))])]
14337 ix86_expand_call (NULL, operands[0], operands[1],
14338 operands[2], operands[3], 0);
14342 (define_insn "*call_pop_0"
14343 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14344 (match_operand:SI 1 "" ""))
14345 (set (reg:SI SP_REG)
14346 (plus:SI (reg:SI SP_REG)
14347 (match_operand:SI 2 "immediate_operand" "")))]
14350 if (SIBLING_CALL_P (insn))
14353 return "call\t%P0";
14355 [(set_attr "type" "call")])
14357 (define_insn "*call_pop_1"
14358 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14359 (match_operand:SI 1 "" ""))
14360 (set (reg:SI SP_REG)
14361 (plus:SI (reg:SI SP_REG)
14362 (match_operand:SI 2 "immediate_operand" "i")))]
14363 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14365 if (constant_call_address_operand (operands[0], Pmode))
14366 return "call\t%P0";
14367 return "call\t%A0";
14369 [(set_attr "type" "call")])
14371 (define_insn "*sibcall_pop_1"
14372 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14373 (match_operand:SI 1 "" ""))
14374 (set (reg:SI SP_REG)
14375 (plus:SI (reg:SI SP_REG)
14376 (match_operand:SI 2 "immediate_operand" "i,i")))]
14377 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14381 [(set_attr "type" "call")])
14383 (define_expand "call"
14384 [(call (match_operand:QI 0 "" "")
14385 (match_operand 1 "" ""))
14386 (use (match_operand 2 "" ""))]
14389 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14393 (define_expand "sibcall"
14394 [(call (match_operand:QI 0 "" "")
14395 (match_operand 1 "" ""))
14396 (use (match_operand 2 "" ""))]
14399 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14403 (define_insn "*call_0"
14404 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14405 (match_operand 1 "" ""))]
14408 if (SIBLING_CALL_P (insn))
14411 return "call\t%P0";
14413 [(set_attr "type" "call")])
14415 (define_insn "*call_1"
14416 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14417 (match_operand 1 "" ""))]
14418 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14420 if (constant_call_address_operand (operands[0], Pmode))
14421 return "call\t%P0";
14422 return "call\t%A0";
14424 [(set_attr "type" "call")])
14426 (define_insn "*sibcall_1"
14427 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14428 (match_operand 1 "" ""))]
14429 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14433 [(set_attr "type" "call")])
14435 (define_insn "*call_1_rex64"
14436 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14437 (match_operand 1 "" ""))]
14438 "TARGET_64BIT && !SIBLING_CALL_P (insn)
14439 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14441 if (constant_call_address_operand (operands[0], Pmode))
14442 return "call\t%P0";
14443 return "call\t%A0";
14445 [(set_attr "type" "call")])
14447 (define_insn "*call_1_rex64_ms_sysv"
14448 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14449 (match_operand 1 "" ""))
14450 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
14451 (clobber (reg:TI XMM6_REG))
14452 (clobber (reg:TI XMM7_REG))
14453 (clobber (reg:TI XMM8_REG))
14454 (clobber (reg:TI XMM9_REG))
14455 (clobber (reg:TI XMM10_REG))
14456 (clobber (reg:TI XMM11_REG))
14457 (clobber (reg:TI XMM12_REG))
14458 (clobber (reg:TI XMM13_REG))
14459 (clobber (reg:TI XMM14_REG))
14460 (clobber (reg:TI XMM15_REG))
14461 (clobber (reg:DI SI_REG))
14462 (clobber (reg:DI DI_REG))]
14463 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14465 if (constant_call_address_operand (operands[0], Pmode))
14466 return "call\t%P0";
14467 return "call\t%A0";
14469 [(set_attr "type" "call")])
14471 (define_insn "*call_1_rex64_large"
14472 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14473 (match_operand 1 "" ""))]
14474 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14476 [(set_attr "type" "call")])
14478 (define_insn "*sibcall_1_rex64"
14479 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
14480 (match_operand 1 "" ""))]
14481 "TARGET_64BIT && SIBLING_CALL_P (insn)"
14485 [(set_attr "type" "call")])
14487 ;; Call subroutine, returning value in operand 0
14488 (define_expand "call_value_pop"
14489 [(parallel [(set (match_operand 0 "" "")
14490 (call (match_operand:QI 1 "" "")
14491 (match_operand:SI 2 "" "")))
14492 (set (reg:SI SP_REG)
14493 (plus:SI (reg:SI SP_REG)
14494 (match_operand:SI 4 "" "")))])]
14497 ix86_expand_call (operands[0], operands[1], operands[2],
14498 operands[3], operands[4], 0);
14502 (define_expand "call_value"
14503 [(set (match_operand 0 "" "")
14504 (call (match_operand:QI 1 "" "")
14505 (match_operand:SI 2 "" "")))
14506 (use (match_operand:SI 3 "" ""))]
14507 ;; Operand 3 is not used on the i386.
14510 ix86_expand_call (operands[0], operands[1], operands[2],
14511 operands[3], NULL, 0);
14515 (define_expand "sibcall_value"
14516 [(set (match_operand 0 "" "")
14517 (call (match_operand:QI 1 "" "")
14518 (match_operand:SI 2 "" "")))
14519 (use (match_operand:SI 3 "" ""))]
14520 ;; Operand 3 is not used on the i386.
14523 ix86_expand_call (operands[0], operands[1], operands[2],
14524 operands[3], NULL, 1);
14528 ;; Call subroutine returning any type.
14530 (define_expand "untyped_call"
14531 [(parallel [(call (match_operand 0 "" "")
14533 (match_operand 1 "" "")
14534 (match_operand 2 "" "")])]
14539 /* In order to give reg-stack an easier job in validating two
14540 coprocessor registers as containing a possible return value,
14541 simply pretend the untyped call returns a complex long double
14544 We can't use SSE_REGPARM_MAX here since callee is unprototyped
14545 and should have the default ABI. */
14547 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14548 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14549 operands[0], const0_rtx,
14550 GEN_INT ((TARGET_64BIT
14551 ? (ix86_abi == SYSV_ABI
14552 ? X86_64_SSE_REGPARM_MAX
14553 : X86_64_MS_SSE_REGPARM_MAX)
14554 : X86_32_SSE_REGPARM_MAX)
14558 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14560 rtx set = XVECEXP (operands[2], 0, i);
14561 emit_move_insn (SET_DEST (set), SET_SRC (set));
14564 /* The optimizer does not know that the call sets the function value
14565 registers we stored in the result block. We avoid problems by
14566 claiming that all hard registers are used and clobbered at this
14568 emit_insn (gen_blockage ());
14573 ;; Prologue and epilogue instructions
14575 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14576 ;; all of memory. This blocks insns from being moved across this point.
14578 (define_insn "blockage"
14579 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14582 [(set_attr "length" "0")])
14584 ;; Do not schedule instructions accessing memory across this point.
14586 (define_expand "memory_blockage"
14587 [(set (match_dup 0)
14588 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14591 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14592 MEM_VOLATILE_P (operands[0]) = 1;
14595 (define_insn "*memory_blockage"
14596 [(set (match_operand:BLK 0 "" "")
14597 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14600 [(set_attr "length" "0")])
14602 ;; As USE insns aren't meaningful after reload, this is used instead
14603 ;; to prevent deleting instructions setting registers for PIC code
14604 (define_insn "prologue_use"
14605 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14608 [(set_attr "length" "0")])
14610 ;; Insn emitted into the body of a function to return from a function.
14611 ;; This is only done if the function's epilogue is known to be simple.
14612 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14614 (define_expand "return"
14616 "ix86_can_use_return_insn_p ()"
14618 if (crtl->args.pops_args)
14620 rtx popc = GEN_INT (crtl->args.pops_args);
14621 emit_jump_insn (gen_return_pop_internal (popc));
14626 (define_insn "return_internal"
14630 [(set_attr "length" "1")
14631 (set_attr "atom_unit" "jeu")
14632 (set_attr "length_immediate" "0")
14633 (set_attr "modrm" "0")])
14635 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14636 ;; instruction Athlon and K8 have.
14638 (define_insn "return_internal_long"
14640 (unspec [(const_int 0)] UNSPEC_REP)]
14643 [(set_attr "length" "2")
14644 (set_attr "atom_unit" "jeu")
14645 (set_attr "length_immediate" "0")
14646 (set_attr "prefix_rep" "1")
14647 (set_attr "modrm" "0")])
14649 (define_insn "return_pop_internal"
14651 (use (match_operand:SI 0 "const_int_operand" ""))]
14654 [(set_attr "length" "3")
14655 (set_attr "atom_unit" "jeu")
14656 (set_attr "length_immediate" "2")
14657 (set_attr "modrm" "0")])
14659 (define_insn "return_indirect_internal"
14661 (use (match_operand:SI 0 "register_operand" "r"))]
14664 [(set_attr "type" "ibr")
14665 (set_attr "length_immediate" "0")])
14671 [(set_attr "length" "1")
14672 (set_attr "length_immediate" "0")
14673 (set_attr "modrm" "0")])
14675 (define_insn "vswapmov"
14676 [(set (match_operand:SI 0 "register_operand" "=r")
14677 (match_operand:SI 1 "register_operand" "r"))
14678 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
14680 "movl.s\t{%1, %0|%0, %1}"
14681 [(set_attr "length" "2")
14682 (set_attr "length_immediate" "0")
14683 (set_attr "modrm" "0")])
14685 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
14686 ;; branch prediction penalty for the third jump in a 16-byte
14690 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14693 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
14694 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
14696 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14697 The align insn is used to avoid 3 jump instructions in the row to improve
14698 branch prediction and the benefits hardly outweigh the cost of extra 8
14699 nops on the average inserted by full alignment pseudo operation. */
14703 [(set_attr "length" "16")])
14705 (define_expand "prologue"
14708 "ix86_expand_prologue (); DONE;")
14710 (define_insn "set_got"
14711 [(set (match_operand:SI 0 "register_operand" "=r")
14712 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14713 (clobber (reg:CC FLAGS_REG))]
14715 { return output_set_got (operands[0], NULL_RTX); }
14716 [(set_attr "type" "multi")
14717 (set_attr "length" "12")])
14719 (define_insn "set_got_labelled"
14720 [(set (match_operand:SI 0 "register_operand" "=r")
14721 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14723 (clobber (reg:CC FLAGS_REG))]
14725 { return output_set_got (operands[0], operands[1]); }
14726 [(set_attr "type" "multi")
14727 (set_attr "length" "12")])
14729 (define_insn "set_got_rex64"
14730 [(set (match_operand:DI 0 "register_operand" "=r")
14731 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14733 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14734 [(set_attr "type" "lea")
14735 (set_attr "length_address" "4")
14736 (set_attr "mode" "DI")])
14738 (define_insn "set_rip_rex64"
14739 [(set (match_operand:DI 0 "register_operand" "=r")
14740 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
14742 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14743 [(set_attr "type" "lea")
14744 (set_attr "length_address" "4")
14745 (set_attr "mode" "DI")])
14747 (define_insn "set_got_offset_rex64"
14748 [(set (match_operand:DI 0 "register_operand" "=r")
14750 [(label_ref (match_operand 1 "" ""))]
14751 UNSPEC_SET_GOT_OFFSET))]
14753 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14754 [(set_attr "type" "imov")
14755 (set_attr "length_immediate" "0")
14756 (set_attr "length_address" "8")
14757 (set_attr "mode" "DI")])
14759 (define_expand "epilogue"
14762 "ix86_expand_epilogue (1); DONE;")
14764 (define_expand "sibcall_epilogue"
14767 "ix86_expand_epilogue (0); DONE;")
14769 (define_expand "eh_return"
14770 [(use (match_operand 0 "register_operand" ""))]
14773 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14775 /* Tricky bit: we write the address of the handler to which we will
14776 be returning into someone else's stack frame, one word below the
14777 stack address we wish to restore. */
14778 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14779 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14780 tmp = gen_rtx_MEM (Pmode, tmp);
14781 emit_move_insn (tmp, ra);
14783 emit_jump_insn (gen_eh_return_internal ());
14788 (define_insn_and_split "eh_return_internal"
14792 "epilogue_completed"
14794 "ix86_expand_epilogue (2); DONE;")
14796 (define_insn "leave"
14797 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14798 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14799 (clobber (mem:BLK (scratch)))]
14802 [(set_attr "type" "leave")])
14804 (define_insn "leave_rex64"
14805 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14806 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14807 (clobber (mem:BLK (scratch)))]
14810 [(set_attr "type" "leave")])
14812 (define_expand "ffssi2"
14814 [(set (match_operand:SI 0 "register_operand" "")
14815 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14816 (clobber (match_scratch:SI 2 ""))
14817 (clobber (reg:CC FLAGS_REG))])]
14822 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14827 (define_expand "ffs_cmove"
14828 [(set (match_dup 2) (const_int -1))
14829 (parallel [(set (reg:CCZ FLAGS_REG)
14830 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14832 (set (match_operand:SI 0 "register_operand" "")
14833 (ctz:SI (match_dup 1)))])
14834 (set (match_dup 0) (if_then_else:SI
14835 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14838 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14839 (clobber (reg:CC FLAGS_REG))])]
14841 "operands[2] = gen_reg_rtx (SImode);")
14843 (define_insn_and_split "*ffs_no_cmove"
14844 [(set (match_operand:SI 0 "register_operand" "=r")
14845 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14846 (clobber (match_scratch:SI 2 "=&q"))
14847 (clobber (reg:CC FLAGS_REG))]
14850 "&& reload_completed"
14851 [(parallel [(set (reg:CCZ FLAGS_REG)
14852 (compare:CCZ (match_dup 1) (const_int 0)))
14853 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14854 (set (strict_low_part (match_dup 3))
14855 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14856 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14857 (clobber (reg:CC FLAGS_REG))])
14858 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14859 (clobber (reg:CC FLAGS_REG))])
14860 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14861 (clobber (reg:CC FLAGS_REG))])]
14863 operands[3] = gen_lowpart (QImode, operands[2]);
14864 ix86_expand_clear (operands[2]);
14867 (define_insn "*ffssi_1"
14868 [(set (reg:CCZ FLAGS_REG)
14869 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14871 (set (match_operand:SI 0 "register_operand" "=r")
14872 (ctz:SI (match_dup 1)))]
14874 "bsf{l}\t{%1, %0|%0, %1}"
14875 [(set_attr "type" "alu1")
14876 (set_attr "prefix_0f" "1")
14877 (set_attr "mode" "SI")])
14879 (define_expand "ffsdi2"
14880 [(set (match_dup 2) (const_int -1))
14881 (parallel [(set (reg:CCZ FLAGS_REG)
14882 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14884 (set (match_operand:DI 0 "register_operand" "")
14885 (ctz:DI (match_dup 1)))])
14886 (set (match_dup 0) (if_then_else:DI
14887 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14890 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14891 (clobber (reg:CC FLAGS_REG))])]
14893 "operands[2] = gen_reg_rtx (DImode);")
14895 (define_insn "*ffsdi_1"
14896 [(set (reg:CCZ FLAGS_REG)
14897 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14899 (set (match_operand:DI 0 "register_operand" "=r")
14900 (ctz:DI (match_dup 1)))]
14902 "bsf{q}\t{%1, %0|%0, %1}"
14903 [(set_attr "type" "alu1")
14904 (set_attr "prefix_0f" "1")
14905 (set_attr "mode" "DI")])
14907 (define_insn "ctzsi2"
14908 [(set (match_operand:SI 0 "register_operand" "=r")
14909 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14910 (clobber (reg:CC FLAGS_REG))]
14912 "bsf{l}\t{%1, %0|%0, %1}"
14913 [(set_attr "type" "alu1")
14914 (set_attr "prefix_0f" "1")
14915 (set_attr "mode" "SI")])
14917 (define_insn "ctzdi2"
14918 [(set (match_operand:DI 0 "register_operand" "=r")
14919 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14920 (clobber (reg:CC FLAGS_REG))]
14922 "bsf{q}\t{%1, %0|%0, %1}"
14923 [(set_attr "type" "alu1")
14924 (set_attr "prefix_0f" "1")
14925 (set_attr "mode" "DI")])
14927 (define_expand "clzsi2"
14929 [(set (match_operand:SI 0 "register_operand" "")
14930 (minus:SI (const_int 31)
14931 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14932 (clobber (reg:CC FLAGS_REG))])
14934 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14935 (clobber (reg:CC FLAGS_REG))])]
14940 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14945 (define_insn "clzsi2_abm"
14946 [(set (match_operand:SI 0 "register_operand" "=r")
14947 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14948 (clobber (reg:CC FLAGS_REG))]
14950 "lzcnt{l}\t{%1, %0|%0, %1}"
14951 [(set_attr "prefix_rep" "1")
14952 (set_attr "type" "bitmanip")
14953 (set_attr "mode" "SI")])
14956 [(set (match_operand:SI 0 "register_operand" "=r")
14957 (minus:SI (const_int 31)
14958 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14959 (clobber (reg:CC FLAGS_REG))]
14961 "bsr{l}\t{%1, %0|%0, %1}"
14962 [(set_attr "type" "alu1")
14963 (set_attr "prefix_0f" "1")
14964 (set_attr "mode" "SI")])
14966 (define_insn "popcount<mode>2"
14967 [(set (match_operand:SWI248 0 "register_operand" "=r")
14969 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14970 (clobber (reg:CC FLAGS_REG))]
14974 return "popcnt\t{%1, %0|%0, %1}";
14976 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14979 [(set_attr "prefix_rep" "1")
14980 (set_attr "type" "bitmanip")
14981 (set_attr "mode" "<MODE>")])
14983 (define_insn "*popcount<mode>2_cmp"
14984 [(set (reg FLAGS_REG)
14987 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14989 (set (match_operand:SWI248 0 "register_operand" "=r")
14990 (popcount:SWI248 (match_dup 1)))]
14991 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14994 return "popcnt\t{%1, %0|%0, %1}";
14996 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14999 [(set_attr "prefix_rep" "1")
15000 (set_attr "type" "bitmanip")
15001 (set_attr "mode" "<MODE>")])
15003 (define_insn "*popcountsi2_cmp_zext"
15004 [(set (reg FLAGS_REG)
15006 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
15008 (set (match_operand:DI 0 "register_operand" "=r")
15009 (zero_extend:DI(popcount:SI (match_dup 1))))]
15010 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
15013 return "popcnt\t{%1, %0|%0, %1}";
15015 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
15018 [(set_attr "prefix_rep" "1")
15019 (set_attr "type" "bitmanip")
15020 (set_attr "mode" "SI")])
15022 (define_expand "bswapsi2"
15023 [(set (match_operand:SI 0 "register_operand" "")
15024 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
15027 if (!(TARGET_BSWAP || TARGET_MOVBE))
15029 rtx x = operands[0];
15031 emit_move_insn (x, operands[1]);
15032 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15033 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
15034 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
15039 (define_insn "*bswapsi_movbe"
15040 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
15041 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
15042 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15045 movbe\t{%1, %0|%0, %1}
15046 movbe\t{%1, %0|%0, %1}"
15047 [(set_attr "type" "*,imov,imov")
15048 (set_attr "modrm" "*,1,1")
15049 (set_attr "prefix_0f" "1")
15050 (set_attr "prefix_extra" "*,1,1")
15051 (set_attr "length" "2,*,*")
15052 (set_attr "mode" "SI")])
15054 (define_insn "*bswapsi_1"
15055 [(set (match_operand:SI 0 "register_operand" "=r")
15056 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
15059 [(set_attr "prefix_0f" "1")
15060 (set_attr "length" "2")])
15062 (define_insn "*bswaphi_lowpart_1"
15063 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
15064 (bswap:HI (match_dup 0)))
15065 (clobber (reg:CC FLAGS_REG))]
15066 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
15068 xchg{b}\t{%h0, %b0|%b0, %h0}
15069 rol{w}\t{$8, %0|%0, 8}"
15070 [(set_attr "length" "2,4")
15071 (set_attr "mode" "QI,HI")])
15073 (define_insn "bswaphi_lowpart"
15074 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
15075 (bswap:HI (match_dup 0)))
15076 (clobber (reg:CC FLAGS_REG))]
15078 "rol{w}\t{$8, %0|%0, 8}"
15079 [(set_attr "length" "4")
15080 (set_attr "mode" "HI")])
15082 (define_expand "bswapdi2"
15083 [(set (match_operand:DI 0 "register_operand" "")
15084 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
15088 (define_insn "*bswapdi_movbe"
15089 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
15090 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
15091 "TARGET_64BIT && TARGET_MOVBE
15092 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
15095 movbe\t{%1, %0|%0, %1}
15096 movbe\t{%1, %0|%0, %1}"
15097 [(set_attr "type" "*,imov,imov")
15098 (set_attr "modrm" "*,1,1")
15099 (set_attr "prefix_0f" "1")
15100 (set_attr "prefix_extra" "*,1,1")
15101 (set_attr "length" "3,*,*")
15102 (set_attr "mode" "DI")])
15104 (define_insn "*bswapdi_1"
15105 [(set (match_operand:DI 0 "register_operand" "=r")
15106 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
15109 [(set_attr "prefix_0f" "1")
15110 (set_attr "length" "3")])
15112 (define_expand "clzdi2"
15114 [(set (match_operand:DI 0 "register_operand" "")
15115 (minus:DI (const_int 63)
15116 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
15117 (clobber (reg:CC FLAGS_REG))])
15119 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
15120 (clobber (reg:CC FLAGS_REG))])]
15125 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
15130 (define_insn "clzdi2_abm"
15131 [(set (match_operand:DI 0 "register_operand" "=r")
15132 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
15133 (clobber (reg:CC FLAGS_REG))]
15134 "TARGET_64BIT && TARGET_ABM"
15135 "lzcnt{q}\t{%1, %0|%0, %1}"
15136 [(set_attr "prefix_rep" "1")
15137 (set_attr "type" "bitmanip")
15138 (set_attr "mode" "DI")])
15140 (define_insn "bsr_rex64"
15141 [(set (match_operand:DI 0 "register_operand" "=r")
15142 (minus:DI (const_int 63)
15143 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
15144 (clobber (reg:CC FLAGS_REG))]
15146 "bsr{q}\t{%1, %0|%0, %1}"
15147 [(set_attr "type" "alu1")
15148 (set_attr "prefix_0f" "1")
15149 (set_attr "mode" "DI")])
15151 (define_expand "clzhi2"
15153 [(set (match_operand:HI 0 "register_operand" "")
15154 (minus:HI (const_int 15)
15155 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
15156 (clobber (reg:CC FLAGS_REG))])
15158 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
15159 (clobber (reg:CC FLAGS_REG))])]
15164 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
15169 (define_insn "clzhi2_abm"
15170 [(set (match_operand:HI 0 "register_operand" "=r")
15171 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
15172 (clobber (reg:CC FLAGS_REG))]
15174 "lzcnt{w}\t{%1, %0|%0, %1}"
15175 [(set_attr "prefix_rep" "1")
15176 (set_attr "type" "bitmanip")
15177 (set_attr "mode" "HI")])
15179 (define_insn "*bsrhi"
15180 [(set (match_operand:HI 0 "register_operand" "=r")
15181 (minus:HI (const_int 15)
15182 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
15183 (clobber (reg:CC FLAGS_REG))]
15185 "bsr{w}\t{%1, %0|%0, %1}"
15186 [(set_attr "type" "alu1")
15187 (set_attr "prefix_0f" "1")
15188 (set_attr "mode" "HI")])
15190 (define_expand "paritydi2"
15191 [(set (match_operand:DI 0 "register_operand" "")
15192 (parity:DI (match_operand:DI 1 "register_operand" "")))]
15195 rtx scratch = gen_reg_rtx (QImode);
15198 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
15199 NULL_RTX, operands[1]));
15201 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15202 gen_rtx_REG (CCmode, FLAGS_REG),
15204 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15207 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
15210 rtx tmp = gen_reg_rtx (SImode);
15212 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
15213 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
15218 (define_insn_and_split "paritydi2_cmp"
15219 [(set (reg:CC FLAGS_REG)
15220 (parity:CC (match_operand:DI 3 "register_operand" "0")))
15221 (clobber (match_scratch:DI 0 "=r"))
15222 (clobber (match_scratch:SI 1 "=&r"))
15223 (clobber (match_scratch:HI 2 "=Q"))]
15226 "&& reload_completed"
15228 [(set (match_dup 1)
15229 (xor:SI (match_dup 1) (match_dup 4)))
15230 (clobber (reg:CC FLAGS_REG))])
15232 [(set (reg:CC FLAGS_REG)
15233 (parity:CC (match_dup 1)))
15234 (clobber (match_dup 1))
15235 (clobber (match_dup 2))])]
15237 operands[4] = gen_lowpart (SImode, operands[3]);
15241 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15242 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15245 operands[1] = gen_highpart (SImode, operands[3]);
15248 (define_expand "paritysi2"
15249 [(set (match_operand:SI 0 "register_operand" "")
15250 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15253 rtx scratch = gen_reg_rtx (QImode);
15256 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15258 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15259 gen_rtx_REG (CCmode, FLAGS_REG),
15261 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15263 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15267 (define_insn_and_split "paritysi2_cmp"
15268 [(set (reg:CC FLAGS_REG)
15269 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15270 (clobber (match_scratch:SI 0 "=r"))
15271 (clobber (match_scratch:HI 1 "=&Q"))]
15274 "&& reload_completed"
15276 [(set (match_dup 1)
15277 (xor:HI (match_dup 1) (match_dup 3)))
15278 (clobber (reg:CC FLAGS_REG))])
15280 [(set (reg:CC FLAGS_REG)
15281 (parity:CC (match_dup 1)))
15282 (clobber (match_dup 1))])]
15284 operands[3] = gen_lowpart (HImode, operands[2]);
15286 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15287 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15290 (define_insn "*parityhi2_cmp"
15291 [(set (reg:CC FLAGS_REG)
15292 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15293 (clobber (match_scratch:HI 0 "=Q"))]
15295 "xor{b}\t{%h0, %b0|%b0, %h0}"
15296 [(set_attr "length" "2")
15297 (set_attr "mode" "HI")])
15299 (define_insn "*parityqi2_cmp"
15300 [(set (reg:CC FLAGS_REG)
15301 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15304 [(set_attr "length" "2")
15305 (set_attr "mode" "QI")])
15307 ;; Thread-local storage patterns for ELF.
15309 ;; Note that these code sequences must appear exactly as shown
15310 ;; in order to allow linker relaxation.
15312 (define_insn "*tls_global_dynamic_32_gnu"
15313 [(set (match_operand:SI 0 "register_operand" "=a")
15314 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15315 (match_operand:SI 2 "tls_symbolic_operand" "")
15316 (match_operand:SI 3 "call_insn_operand" "")]
15318 (clobber (match_scratch:SI 4 "=d"))
15319 (clobber (match_scratch:SI 5 "=c"))
15320 (clobber (reg:CC FLAGS_REG))]
15321 "!TARGET_64BIT && TARGET_GNU_TLS"
15322 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15323 [(set_attr "type" "multi")
15324 (set_attr "length" "12")])
15326 (define_insn "*tls_global_dynamic_32_sun"
15327 [(set (match_operand:SI 0 "register_operand" "=a")
15328 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15329 (match_operand:SI 2 "tls_symbolic_operand" "")
15330 (match_operand:SI 3 "call_insn_operand" "")]
15332 (clobber (match_scratch:SI 4 "=d"))
15333 (clobber (match_scratch:SI 5 "=c"))
15334 (clobber (reg:CC FLAGS_REG))]
15335 "!TARGET_64BIT && TARGET_SUN_TLS"
15336 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15337 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15338 [(set_attr "type" "multi")
15339 (set_attr "length" "14")])
15341 (define_expand "tls_global_dynamic_32"
15342 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15345 (match_operand:SI 1 "tls_symbolic_operand" "")
15348 (clobber (match_scratch:SI 4 ""))
15349 (clobber (match_scratch:SI 5 ""))
15350 (clobber (reg:CC FLAGS_REG))])]
15354 operands[2] = pic_offset_table_rtx;
15357 operands[2] = gen_reg_rtx (Pmode);
15358 emit_insn (gen_set_got (operands[2]));
15360 if (TARGET_GNU2_TLS)
15362 emit_insn (gen_tls_dynamic_gnu2_32
15363 (operands[0], operands[1], operands[2]));
15366 operands[3] = ix86_tls_get_addr ();
15369 (define_insn "*tls_global_dynamic_64"
15370 [(set (match_operand:DI 0 "register_operand" "=a")
15371 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15372 (match_operand:DI 3 "" "")))
15373 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15376 { 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"; }
15377 [(set_attr "type" "multi")
15378 (set_attr "length" "16")])
15380 (define_expand "tls_global_dynamic_64"
15381 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15382 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15383 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15387 if (TARGET_GNU2_TLS)
15389 emit_insn (gen_tls_dynamic_gnu2_64
15390 (operands[0], operands[1]));
15393 operands[2] = ix86_tls_get_addr ();
15396 (define_insn "*tls_local_dynamic_base_32_gnu"
15397 [(set (match_operand:SI 0 "register_operand" "=a")
15398 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15399 (match_operand:SI 2 "call_insn_operand" "")]
15400 UNSPEC_TLS_LD_BASE))
15401 (clobber (match_scratch:SI 3 "=d"))
15402 (clobber (match_scratch:SI 4 "=c"))
15403 (clobber (reg:CC FLAGS_REG))]
15404 "!TARGET_64BIT && TARGET_GNU_TLS"
15405 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15406 [(set_attr "type" "multi")
15407 (set_attr "length" "11")])
15409 (define_insn "*tls_local_dynamic_base_32_sun"
15410 [(set (match_operand:SI 0 "register_operand" "=a")
15411 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15412 (match_operand:SI 2 "call_insn_operand" "")]
15413 UNSPEC_TLS_LD_BASE))
15414 (clobber (match_scratch:SI 3 "=d"))
15415 (clobber (match_scratch:SI 4 "=c"))
15416 (clobber (reg:CC FLAGS_REG))]
15417 "!TARGET_64BIT && TARGET_SUN_TLS"
15418 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15419 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15420 [(set_attr "type" "multi")
15421 (set_attr "length" "13")])
15423 (define_expand "tls_local_dynamic_base_32"
15424 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15425 (unspec:SI [(match_dup 1) (match_dup 2)]
15426 UNSPEC_TLS_LD_BASE))
15427 (clobber (match_scratch:SI 3 ""))
15428 (clobber (match_scratch:SI 4 ""))
15429 (clobber (reg:CC FLAGS_REG))])]
15433 operands[1] = pic_offset_table_rtx;
15436 operands[1] = gen_reg_rtx (Pmode);
15437 emit_insn (gen_set_got (operands[1]));
15439 if (TARGET_GNU2_TLS)
15441 emit_insn (gen_tls_dynamic_gnu2_32
15442 (operands[0], ix86_tls_module_base (), operands[1]));
15445 operands[2] = ix86_tls_get_addr ();
15448 (define_insn "*tls_local_dynamic_base_64"
15449 [(set (match_operand:DI 0 "register_operand" "=a")
15450 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15451 (match_operand:DI 2 "" "")))
15452 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15454 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15455 [(set_attr "type" "multi")
15456 (set_attr "length" "12")])
15458 (define_expand "tls_local_dynamic_base_64"
15459 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15460 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15461 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15464 if (TARGET_GNU2_TLS)
15466 emit_insn (gen_tls_dynamic_gnu2_64
15467 (operands[0], ix86_tls_module_base ()));
15470 operands[1] = ix86_tls_get_addr ();
15473 ;; Local dynamic of a single variable is a lose. Show combine how
15474 ;; to convert that back to global dynamic.
15476 (define_insn_and_split "*tls_local_dynamic_32_once"
15477 [(set (match_operand:SI 0 "register_operand" "=a")
15478 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15479 (match_operand:SI 2 "call_insn_operand" "")]
15480 UNSPEC_TLS_LD_BASE)
15481 (const:SI (unspec:SI
15482 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15484 (clobber (match_scratch:SI 4 "=d"))
15485 (clobber (match_scratch:SI 5 "=c"))
15486 (clobber (reg:CC FLAGS_REG))]
15490 [(parallel [(set (match_dup 0)
15491 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15493 (clobber (match_dup 4))
15494 (clobber (match_dup 5))
15495 (clobber (reg:CC FLAGS_REG))])]
15498 ;; Load and add the thread base pointer from %gs:0.
15500 (define_insn "*load_tp_si"
15501 [(set (match_operand:SI 0 "register_operand" "=r")
15502 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15504 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15505 [(set_attr "type" "imov")
15506 (set_attr "modrm" "0")
15507 (set_attr "length" "7")
15508 (set_attr "memory" "load")
15509 (set_attr "imm_disp" "false")])
15511 (define_insn "*add_tp_si"
15512 [(set (match_operand:SI 0 "register_operand" "=r")
15513 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15514 (match_operand:SI 1 "register_operand" "0")))
15515 (clobber (reg:CC FLAGS_REG))]
15517 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15518 [(set_attr "type" "alu")
15519 (set_attr "modrm" "0")
15520 (set_attr "length" "7")
15521 (set_attr "memory" "load")
15522 (set_attr "imm_disp" "false")])
15524 (define_insn "*load_tp_di"
15525 [(set (match_operand:DI 0 "register_operand" "=r")
15526 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15528 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15529 [(set_attr "type" "imov")
15530 (set_attr "modrm" "0")
15531 (set_attr "length" "7")
15532 (set_attr "memory" "load")
15533 (set_attr "imm_disp" "false")])
15535 (define_insn "*add_tp_di"
15536 [(set (match_operand:DI 0 "register_operand" "=r")
15537 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15538 (match_operand:DI 1 "register_operand" "0")))
15539 (clobber (reg:CC FLAGS_REG))]
15541 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15542 [(set_attr "type" "alu")
15543 (set_attr "modrm" "0")
15544 (set_attr "length" "7")
15545 (set_attr "memory" "load")
15546 (set_attr "imm_disp" "false")])
15548 ;; GNU2 TLS patterns can be split.
15550 (define_expand "tls_dynamic_gnu2_32"
15551 [(set (match_dup 3)
15552 (plus:SI (match_operand:SI 2 "register_operand" "")
15554 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15557 [(set (match_operand:SI 0 "register_operand" "")
15558 (unspec:SI [(match_dup 1) (match_dup 3)
15559 (match_dup 2) (reg:SI SP_REG)]
15561 (clobber (reg:CC FLAGS_REG))])]
15562 "!TARGET_64BIT && TARGET_GNU2_TLS"
15564 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15565 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15568 (define_insn "*tls_dynamic_lea_32"
15569 [(set (match_operand:SI 0 "register_operand" "=r")
15570 (plus:SI (match_operand:SI 1 "register_operand" "b")
15572 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15573 UNSPEC_TLSDESC))))]
15574 "!TARGET_64BIT && TARGET_GNU2_TLS"
15575 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15576 [(set_attr "type" "lea")
15577 (set_attr "mode" "SI")
15578 (set_attr "length" "6")
15579 (set_attr "length_address" "4")])
15581 (define_insn "*tls_dynamic_call_32"
15582 [(set (match_operand:SI 0 "register_operand" "=a")
15583 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15584 (match_operand:SI 2 "register_operand" "0")
15585 ;; we have to make sure %ebx still points to the GOT
15586 (match_operand:SI 3 "register_operand" "b")
15589 (clobber (reg:CC FLAGS_REG))]
15590 "!TARGET_64BIT && TARGET_GNU2_TLS"
15591 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15592 [(set_attr "type" "call")
15593 (set_attr "length" "2")
15594 (set_attr "length_address" "0")])
15596 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15597 [(set (match_operand:SI 0 "register_operand" "=&a")
15599 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15600 (match_operand:SI 4 "" "")
15601 (match_operand:SI 2 "register_operand" "b")
15604 (const:SI (unspec:SI
15605 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15607 (clobber (reg:CC FLAGS_REG))]
15608 "!TARGET_64BIT && TARGET_GNU2_TLS"
15611 [(set (match_dup 0) (match_dup 5))]
15613 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15614 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15617 (define_expand "tls_dynamic_gnu2_64"
15618 [(set (match_dup 2)
15619 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15622 [(set (match_operand:DI 0 "register_operand" "")
15623 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15625 (clobber (reg:CC FLAGS_REG))])]
15626 "TARGET_64BIT && TARGET_GNU2_TLS"
15628 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15629 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15632 (define_insn "*tls_dynamic_lea_64"
15633 [(set (match_operand:DI 0 "register_operand" "=r")
15634 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15636 "TARGET_64BIT && TARGET_GNU2_TLS"
15637 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15638 [(set_attr "type" "lea")
15639 (set_attr "mode" "DI")
15640 (set_attr "length" "7")
15641 (set_attr "length_address" "4")])
15643 (define_insn "*tls_dynamic_call_64"
15644 [(set (match_operand:DI 0 "register_operand" "=a")
15645 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15646 (match_operand:DI 2 "register_operand" "0")
15649 (clobber (reg:CC FLAGS_REG))]
15650 "TARGET_64BIT && TARGET_GNU2_TLS"
15651 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15652 [(set_attr "type" "call")
15653 (set_attr "length" "2")
15654 (set_attr "length_address" "0")])
15656 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15657 [(set (match_operand:DI 0 "register_operand" "=&a")
15659 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15660 (match_operand:DI 3 "" "")
15663 (const:DI (unspec:DI
15664 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15666 (clobber (reg:CC FLAGS_REG))]
15667 "TARGET_64BIT && TARGET_GNU2_TLS"
15670 [(set (match_dup 0) (match_dup 4))]
15672 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15673 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15678 ;; These patterns match the binary 387 instructions for addM3, subM3,
15679 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15680 ;; SFmode. The first is the normal insn, the second the same insn but
15681 ;; with one operand a conversion, and the third the same insn but with
15682 ;; the other operand a conversion. The conversion may be SFmode or
15683 ;; SImode if the target mode DFmode, but only SImode if the target mode
15686 ;; Gcc is slightly more smart about handling normal two address instructions
15687 ;; so use special patterns for add and mull.
15689 (define_insn "*fop_<mode>_comm_mixed_avx"
15690 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15691 (match_operator:MODEF 3 "binary_fp_operator"
15692 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15693 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15694 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15695 && COMMUTATIVE_ARITH_P (operands[3])
15696 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15697 "* return output_387_binary_op (insn, operands);"
15698 [(set (attr "type")
15699 (if_then_else (eq_attr "alternative" "1")
15700 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15701 (const_string "ssemul")
15702 (const_string "sseadd"))
15703 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15704 (const_string "fmul")
15705 (const_string "fop"))))
15706 (set_attr "prefix" "orig,maybe_vex")
15707 (set_attr "mode" "<MODE>")])
15709 (define_insn "*fop_<mode>_comm_mixed"
15710 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15711 (match_operator:MODEF 3 "binary_fp_operator"
15712 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15713 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15714 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15715 && COMMUTATIVE_ARITH_P (operands[3])
15716 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15717 "* return output_387_binary_op (insn, operands);"
15718 [(set (attr "type")
15719 (if_then_else (eq_attr "alternative" "1")
15720 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15721 (const_string "ssemul")
15722 (const_string "sseadd"))
15723 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15724 (const_string "fmul")
15725 (const_string "fop"))))
15726 (set_attr "mode" "<MODE>")])
15728 (define_insn "*fop_<mode>_comm_avx"
15729 [(set (match_operand:MODEF 0 "register_operand" "=x")
15730 (match_operator:MODEF 3 "binary_fp_operator"
15731 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
15732 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15733 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15734 && COMMUTATIVE_ARITH_P (operands[3])
15735 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15736 "* return output_387_binary_op (insn, operands);"
15737 [(set (attr "type")
15738 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15739 (const_string "ssemul")
15740 (const_string "sseadd")))
15741 (set_attr "prefix" "vex")
15742 (set_attr "mode" "<MODE>")])
15744 (define_insn "*fop_<mode>_comm_sse"
15745 [(set (match_operand:MODEF 0 "register_operand" "=x")
15746 (match_operator:MODEF 3 "binary_fp_operator"
15747 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15748 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15749 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15750 && COMMUTATIVE_ARITH_P (operands[3])
15751 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15752 "* return output_387_binary_op (insn, operands);"
15753 [(set (attr "type")
15754 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15755 (const_string "ssemul")
15756 (const_string "sseadd")))
15757 (set_attr "mode" "<MODE>")])
15759 (define_insn "*fop_<mode>_comm_i387"
15760 [(set (match_operand:MODEF 0 "register_operand" "=f")
15761 (match_operator:MODEF 3 "binary_fp_operator"
15762 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15763 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15764 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15765 && COMMUTATIVE_ARITH_P (operands[3])
15766 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15767 "* return output_387_binary_op (insn, operands);"
15768 [(set (attr "type")
15769 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15770 (const_string "fmul")
15771 (const_string "fop")))
15772 (set_attr "mode" "<MODE>")])
15774 (define_insn "*fop_<mode>_1_mixed_avx"
15775 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15776 (match_operator:MODEF 3 "binary_fp_operator"
15777 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
15778 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15779 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15780 && !COMMUTATIVE_ARITH_P (operands[3])
15781 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15782 "* return output_387_binary_op (insn, operands);"
15783 [(set (attr "type")
15784 (cond [(and (eq_attr "alternative" "2")
15785 (match_operand:MODEF 3 "mult_operator" ""))
15786 (const_string "ssemul")
15787 (and (eq_attr "alternative" "2")
15788 (match_operand:MODEF 3 "div_operator" ""))
15789 (const_string "ssediv")
15790 (eq_attr "alternative" "2")
15791 (const_string "sseadd")
15792 (match_operand:MODEF 3 "mult_operator" "")
15793 (const_string "fmul")
15794 (match_operand:MODEF 3 "div_operator" "")
15795 (const_string "fdiv")
15797 (const_string "fop")))
15798 (set_attr "prefix" "orig,orig,maybe_vex")
15799 (set_attr "mode" "<MODE>")])
15801 (define_insn "*fop_<mode>_1_mixed"
15802 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15803 (match_operator:MODEF 3 "binary_fp_operator"
15804 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15805 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15806 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15807 && !COMMUTATIVE_ARITH_P (operands[3])
15808 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15809 "* return output_387_binary_op (insn, operands);"
15810 [(set (attr "type")
15811 (cond [(and (eq_attr "alternative" "2")
15812 (match_operand:MODEF 3 "mult_operator" ""))
15813 (const_string "ssemul")
15814 (and (eq_attr "alternative" "2")
15815 (match_operand:MODEF 3 "div_operator" ""))
15816 (const_string "ssediv")
15817 (eq_attr "alternative" "2")
15818 (const_string "sseadd")
15819 (match_operand:MODEF 3 "mult_operator" "")
15820 (const_string "fmul")
15821 (match_operand:MODEF 3 "div_operator" "")
15822 (const_string "fdiv")
15824 (const_string "fop")))
15825 (set_attr "mode" "<MODE>")])
15827 (define_insn "*rcpsf2_sse"
15828 [(set (match_operand:SF 0 "register_operand" "=x")
15829 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15832 "%vrcpss\t{%1, %d0|%d0, %1}"
15833 [(set_attr "type" "sse")
15834 (set_attr "atom_sse_attr" "rcp")
15835 (set_attr "prefix" "maybe_vex")
15836 (set_attr "mode" "SF")])
15838 (define_insn "*fop_<mode>_1_avx"
15839 [(set (match_operand:MODEF 0 "register_operand" "=x")
15840 (match_operator:MODEF 3 "binary_fp_operator"
15841 [(match_operand:MODEF 1 "register_operand" "x")
15842 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15843 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15844 && !COMMUTATIVE_ARITH_P (operands[3])"
15845 "* return output_387_binary_op (insn, operands);"
15846 [(set (attr "type")
15847 (cond [(match_operand:MODEF 3 "mult_operator" "")
15848 (const_string "ssemul")
15849 (match_operand:MODEF 3 "div_operator" "")
15850 (const_string "ssediv")
15852 (const_string "sseadd")))
15853 (set_attr "prefix" "vex")
15854 (set_attr "mode" "<MODE>")])
15856 (define_insn "*fop_<mode>_1_sse"
15857 [(set (match_operand:MODEF 0 "register_operand" "=x")
15858 (match_operator:MODEF 3 "binary_fp_operator"
15859 [(match_operand:MODEF 1 "register_operand" "0")
15860 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15861 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15862 && !COMMUTATIVE_ARITH_P (operands[3])"
15863 "* return output_387_binary_op (insn, operands);"
15864 [(set (attr "type")
15865 (cond [(match_operand:MODEF 3 "mult_operator" "")
15866 (const_string "ssemul")
15867 (match_operand:MODEF 3 "div_operator" "")
15868 (const_string "ssediv")
15870 (const_string "sseadd")))
15871 (set_attr "mode" "<MODE>")])
15873 ;; This pattern is not fully shadowed by the pattern above.
15874 (define_insn "*fop_<mode>_1_i387"
15875 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15876 (match_operator:MODEF 3 "binary_fp_operator"
15877 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15878 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15879 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15880 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15881 && !COMMUTATIVE_ARITH_P (operands[3])
15882 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15883 "* return output_387_binary_op (insn, operands);"
15884 [(set (attr "type")
15885 (cond [(match_operand:MODEF 3 "mult_operator" "")
15886 (const_string "fmul")
15887 (match_operand:MODEF 3 "div_operator" "")
15888 (const_string "fdiv")
15890 (const_string "fop")))
15891 (set_attr "mode" "<MODE>")])
15893 ;; ??? Add SSE splitters for these!
15894 (define_insn "*fop_<MODEF:mode>_2_i387"
15895 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15896 (match_operator:MODEF 3 "binary_fp_operator"
15898 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15899 (match_operand:MODEF 2 "register_operand" "0,0")]))]
15900 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15901 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15902 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15903 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15904 [(set (attr "type")
15905 (cond [(match_operand:MODEF 3 "mult_operator" "")
15906 (const_string "fmul")
15907 (match_operand:MODEF 3 "div_operator" "")
15908 (const_string "fdiv")
15910 (const_string "fop")))
15911 (set_attr "fp_int_src" "true")
15912 (set_attr "mode" "<X87MODEI12:MODE>")])
15914 (define_insn "*fop_<MODEF:mode>_3_i387"
15915 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15916 (match_operator:MODEF 3 "binary_fp_operator"
15917 [(match_operand:MODEF 1 "register_operand" "0,0")
15919 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15920 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15921 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15922 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15923 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15924 [(set (attr "type")
15925 (cond [(match_operand:MODEF 3 "mult_operator" "")
15926 (const_string "fmul")
15927 (match_operand:MODEF 3 "div_operator" "")
15928 (const_string "fdiv")
15930 (const_string "fop")))
15931 (set_attr "fp_int_src" "true")
15932 (set_attr "mode" "<MODE>")])
15934 (define_insn "*fop_df_4_i387"
15935 [(set (match_operand:DF 0 "register_operand" "=f,f")
15936 (match_operator:DF 3 "binary_fp_operator"
15938 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15939 (match_operand:DF 2 "register_operand" "0,f")]))]
15940 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15941 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15942 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15943 "* return output_387_binary_op (insn, operands);"
15944 [(set (attr "type")
15945 (cond [(match_operand:DF 3 "mult_operator" "")
15946 (const_string "fmul")
15947 (match_operand:DF 3 "div_operator" "")
15948 (const_string "fdiv")
15950 (const_string "fop")))
15951 (set_attr "mode" "SF")])
15953 (define_insn "*fop_df_5_i387"
15954 [(set (match_operand:DF 0 "register_operand" "=f,f")
15955 (match_operator:DF 3 "binary_fp_operator"
15956 [(match_operand:DF 1 "register_operand" "0,f")
15958 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15959 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15960 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15961 "* return output_387_binary_op (insn, operands);"
15962 [(set (attr "type")
15963 (cond [(match_operand:DF 3 "mult_operator" "")
15964 (const_string "fmul")
15965 (match_operand:DF 3 "div_operator" "")
15966 (const_string "fdiv")
15968 (const_string "fop")))
15969 (set_attr "mode" "SF")])
15971 (define_insn "*fop_df_6_i387"
15972 [(set (match_operand:DF 0 "register_operand" "=f,f")
15973 (match_operator:DF 3 "binary_fp_operator"
15975 (match_operand:SF 1 "register_operand" "0,f"))
15977 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15978 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15979 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15980 "* return output_387_binary_op (insn, operands);"
15981 [(set (attr "type")
15982 (cond [(match_operand:DF 3 "mult_operator" "")
15983 (const_string "fmul")
15984 (match_operand:DF 3 "div_operator" "")
15985 (const_string "fdiv")
15987 (const_string "fop")))
15988 (set_attr "mode" "SF")])
15990 (define_insn "*fop_xf_comm_i387"
15991 [(set (match_operand:XF 0 "register_operand" "=f")
15992 (match_operator:XF 3 "binary_fp_operator"
15993 [(match_operand:XF 1 "register_operand" "%0")
15994 (match_operand:XF 2 "register_operand" "f")]))]
15996 && COMMUTATIVE_ARITH_P (operands[3])"
15997 "* return output_387_binary_op (insn, operands);"
15998 [(set (attr "type")
15999 (if_then_else (match_operand:XF 3 "mult_operator" "")
16000 (const_string "fmul")
16001 (const_string "fop")))
16002 (set_attr "mode" "XF")])
16004 (define_insn "*fop_xf_1_i387"
16005 [(set (match_operand:XF 0 "register_operand" "=f,f")
16006 (match_operator:XF 3 "binary_fp_operator"
16007 [(match_operand:XF 1 "register_operand" "0,f")
16008 (match_operand:XF 2 "register_operand" "f,0")]))]
16010 && !COMMUTATIVE_ARITH_P (operands[3])"
16011 "* return output_387_binary_op (insn, operands);"
16012 [(set (attr "type")
16013 (cond [(match_operand:XF 3 "mult_operator" "")
16014 (const_string "fmul")
16015 (match_operand:XF 3 "div_operator" "")
16016 (const_string "fdiv")
16018 (const_string "fop")))
16019 (set_attr "mode" "XF")])
16021 (define_insn "*fop_xf_2_i387"
16022 [(set (match_operand:XF 0 "register_operand" "=f,f")
16023 (match_operator:XF 3 "binary_fp_operator"
16025 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
16026 (match_operand:XF 2 "register_operand" "0,0")]))]
16027 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16028 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16029 [(set (attr "type")
16030 (cond [(match_operand:XF 3 "mult_operator" "")
16031 (const_string "fmul")
16032 (match_operand:XF 3 "div_operator" "")
16033 (const_string "fdiv")
16035 (const_string "fop")))
16036 (set_attr "fp_int_src" "true")
16037 (set_attr "mode" "<MODE>")])
16039 (define_insn "*fop_xf_3_i387"
16040 [(set (match_operand:XF 0 "register_operand" "=f,f")
16041 (match_operator:XF 3 "binary_fp_operator"
16042 [(match_operand:XF 1 "register_operand" "0,0")
16044 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
16045 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
16046 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
16047 [(set (attr "type")
16048 (cond [(match_operand:XF 3 "mult_operator" "")
16049 (const_string "fmul")
16050 (match_operand:XF 3 "div_operator" "")
16051 (const_string "fdiv")
16053 (const_string "fop")))
16054 (set_attr "fp_int_src" "true")
16055 (set_attr "mode" "<MODE>")])
16057 (define_insn "*fop_xf_4_i387"
16058 [(set (match_operand:XF 0 "register_operand" "=f,f")
16059 (match_operator:XF 3 "binary_fp_operator"
16061 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
16062 (match_operand:XF 2 "register_operand" "0,f")]))]
16064 "* return output_387_binary_op (insn, operands);"
16065 [(set (attr "type")
16066 (cond [(match_operand:XF 3 "mult_operator" "")
16067 (const_string "fmul")
16068 (match_operand:XF 3 "div_operator" "")
16069 (const_string "fdiv")
16071 (const_string "fop")))
16072 (set_attr "mode" "<MODE>")])
16074 (define_insn "*fop_xf_5_i387"
16075 [(set (match_operand:XF 0 "register_operand" "=f,f")
16076 (match_operator:XF 3 "binary_fp_operator"
16077 [(match_operand:XF 1 "register_operand" "0,f")
16079 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16081 "* return output_387_binary_op (insn, operands);"
16082 [(set (attr "type")
16083 (cond [(match_operand:XF 3 "mult_operator" "")
16084 (const_string "fmul")
16085 (match_operand:XF 3 "div_operator" "")
16086 (const_string "fdiv")
16088 (const_string "fop")))
16089 (set_attr "mode" "<MODE>")])
16091 (define_insn "*fop_xf_6_i387"
16092 [(set (match_operand:XF 0 "register_operand" "=f,f")
16093 (match_operator:XF 3 "binary_fp_operator"
16095 (match_operand:MODEF 1 "register_operand" "0,f"))
16097 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
16099 "* return output_387_binary_op (insn, operands);"
16100 [(set (attr "type")
16101 (cond [(match_operand:XF 3 "mult_operator" "")
16102 (const_string "fmul")
16103 (match_operand:XF 3 "div_operator" "")
16104 (const_string "fdiv")
16106 (const_string "fop")))
16107 (set_attr "mode" "<MODE>")])
16110 [(set (match_operand 0 "register_operand" "")
16111 (match_operator 3 "binary_fp_operator"
16112 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
16113 (match_operand 2 "register_operand" "")]))]
16115 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16116 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
16119 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
16120 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16121 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16122 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16123 GET_MODE (operands[3]),
16126 ix86_free_from_memory (GET_MODE (operands[1]));
16131 [(set (match_operand 0 "register_operand" "")
16132 (match_operator 3 "binary_fp_operator"
16133 [(match_operand 1 "register_operand" "")
16134 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
16136 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
16137 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
16140 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
16141 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
16142 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
16143 gen_rtx_fmt_ee (GET_CODE (operands[3]),
16144 GET_MODE (operands[3]),
16147 ix86_free_from_memory (GET_MODE (operands[2]));
16151 ;; FPU special functions.
16153 ;; This pattern implements a no-op XFmode truncation for
16154 ;; all fancy i386 XFmode math functions.
16156 (define_insn "truncxf<mode>2_i387_noop_unspec"
16157 [(set (match_operand:MODEF 0 "register_operand" "=f")
16158 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
16159 UNSPEC_TRUNC_NOOP))]
16160 "TARGET_USE_FANCY_MATH_387"
16161 "* return output_387_reg_move (insn, operands);"
16162 [(set_attr "type" "fmov")
16163 (set_attr "mode" "<MODE>")])
16165 (define_insn "sqrtxf2"
16166 [(set (match_operand:XF 0 "register_operand" "=f")
16167 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
16168 "TARGET_USE_FANCY_MATH_387"
16170 [(set_attr "type" "fpspc")
16171 (set_attr "mode" "XF")
16172 (set_attr "athlon_decode" "direct")
16173 (set_attr "amdfam10_decode" "direct")])
16175 (define_insn "sqrt_extend<mode>xf2_i387"
16176 [(set (match_operand:XF 0 "register_operand" "=f")
16179 (match_operand:MODEF 1 "register_operand" "0"))))]
16180 "TARGET_USE_FANCY_MATH_387"
16182 [(set_attr "type" "fpspc")
16183 (set_attr "mode" "XF")
16184 (set_attr "athlon_decode" "direct")
16185 (set_attr "amdfam10_decode" "direct")])
16187 (define_insn "*rsqrtsf2_sse"
16188 [(set (match_operand:SF 0 "register_operand" "=x")
16189 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
16192 "%vrsqrtss\t{%1, %d0|%d0, %1}"
16193 [(set_attr "type" "sse")
16194 (set_attr "atom_sse_attr" "rcp")
16195 (set_attr "prefix" "maybe_vex")
16196 (set_attr "mode" "SF")])
16198 (define_expand "rsqrtsf2"
16199 [(set (match_operand:SF 0 "register_operand" "")
16200 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
16204 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
16208 (define_insn "*sqrt<mode>2_sse"
16209 [(set (match_operand:MODEF 0 "register_operand" "=x")
16211 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
16212 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
16213 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
16214 [(set_attr "type" "sse")
16215 (set_attr "atom_sse_attr" "sqrt")
16216 (set_attr "prefix" "maybe_vex")
16217 (set_attr "mode" "<MODE>")
16218 (set_attr "athlon_decode" "*")
16219 (set_attr "amdfam10_decode" "*")])
16221 (define_expand "sqrt<mode>2"
16222 [(set (match_operand:MODEF 0 "register_operand" "")
16224 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
16225 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
16226 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
16228 if (<MODE>mode == SFmode
16229 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16230 && flag_finite_math_only && !flag_trapping_math
16231 && flag_unsafe_math_optimizations)
16233 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16237 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16239 rtx op0 = gen_reg_rtx (XFmode);
16240 rtx op1 = force_reg (<MODE>mode, operands[1]);
16242 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16243 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16248 (define_insn "fpremxf4_i387"
16249 [(set (match_operand:XF 0 "register_operand" "=f")
16250 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16251 (match_operand:XF 3 "register_operand" "1")]
16253 (set (match_operand:XF 1 "register_operand" "=u")
16254 (unspec:XF [(match_dup 2) (match_dup 3)]
16256 (set (reg:CCFP FPSR_REG)
16257 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16259 "TARGET_USE_FANCY_MATH_387"
16261 [(set_attr "type" "fpspc")
16262 (set_attr "mode" "XF")])
16264 (define_expand "fmodxf3"
16265 [(use (match_operand:XF 0 "register_operand" ""))
16266 (use (match_operand:XF 1 "general_operand" ""))
16267 (use (match_operand:XF 2 "general_operand" ""))]
16268 "TARGET_USE_FANCY_MATH_387"
16270 rtx label = gen_label_rtx ();
16272 rtx op1 = gen_reg_rtx (XFmode);
16273 rtx op2 = gen_reg_rtx (XFmode);
16275 emit_move_insn (op2, operands[2]);
16276 emit_move_insn (op1, operands[1]);
16278 emit_label (label);
16279 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16280 ix86_emit_fp_unordered_jump (label);
16281 LABEL_NUSES (label) = 1;
16283 emit_move_insn (operands[0], op1);
16287 (define_expand "fmod<mode>3"
16288 [(use (match_operand:MODEF 0 "register_operand" ""))
16289 (use (match_operand:MODEF 1 "general_operand" ""))
16290 (use (match_operand:MODEF 2 "general_operand" ""))]
16291 "TARGET_USE_FANCY_MATH_387"
16293 rtx label = gen_label_rtx ();
16295 rtx op1 = gen_reg_rtx (XFmode);
16296 rtx op2 = gen_reg_rtx (XFmode);
16298 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16299 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16301 emit_label (label);
16302 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16303 ix86_emit_fp_unordered_jump (label);
16304 LABEL_NUSES (label) = 1;
16306 /* Truncate the result properly for strict SSE math. */
16307 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16308 && !TARGET_MIX_SSE_I387)
16309 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16311 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16316 (define_insn "fprem1xf4_i387"
16317 [(set (match_operand:XF 0 "register_operand" "=f")
16318 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16319 (match_operand:XF 3 "register_operand" "1")]
16321 (set (match_operand:XF 1 "register_operand" "=u")
16322 (unspec:XF [(match_dup 2) (match_dup 3)]
16324 (set (reg:CCFP FPSR_REG)
16325 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16327 "TARGET_USE_FANCY_MATH_387"
16329 [(set_attr "type" "fpspc")
16330 (set_attr "mode" "XF")])
16332 (define_expand "remainderxf3"
16333 [(use (match_operand:XF 0 "register_operand" ""))
16334 (use (match_operand:XF 1 "general_operand" ""))
16335 (use (match_operand:XF 2 "general_operand" ""))]
16336 "TARGET_USE_FANCY_MATH_387"
16338 rtx label = gen_label_rtx ();
16340 rtx op1 = gen_reg_rtx (XFmode);
16341 rtx op2 = gen_reg_rtx (XFmode);
16343 emit_move_insn (op2, operands[2]);
16344 emit_move_insn (op1, operands[1]);
16346 emit_label (label);
16347 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16348 ix86_emit_fp_unordered_jump (label);
16349 LABEL_NUSES (label) = 1;
16351 emit_move_insn (operands[0], op1);
16355 (define_expand "remainder<mode>3"
16356 [(use (match_operand:MODEF 0 "register_operand" ""))
16357 (use (match_operand:MODEF 1 "general_operand" ""))
16358 (use (match_operand:MODEF 2 "general_operand" ""))]
16359 "TARGET_USE_FANCY_MATH_387"
16361 rtx label = gen_label_rtx ();
16363 rtx op1 = gen_reg_rtx (XFmode);
16364 rtx op2 = gen_reg_rtx (XFmode);
16366 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16367 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16369 emit_label (label);
16371 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16372 ix86_emit_fp_unordered_jump (label);
16373 LABEL_NUSES (label) = 1;
16375 /* Truncate the result properly for strict SSE math. */
16376 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16377 && !TARGET_MIX_SSE_I387)
16378 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16380 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16385 (define_insn "*sinxf2_i387"
16386 [(set (match_operand:XF 0 "register_operand" "=f")
16387 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16388 "TARGET_USE_FANCY_MATH_387
16389 && flag_unsafe_math_optimizations"
16391 [(set_attr "type" "fpspc")
16392 (set_attr "mode" "XF")])
16394 (define_insn "*sin_extend<mode>xf2_i387"
16395 [(set (match_operand:XF 0 "register_operand" "=f")
16396 (unspec:XF [(float_extend:XF
16397 (match_operand:MODEF 1 "register_operand" "0"))]
16399 "TARGET_USE_FANCY_MATH_387
16400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16401 || TARGET_MIX_SSE_I387)
16402 && flag_unsafe_math_optimizations"
16404 [(set_attr "type" "fpspc")
16405 (set_attr "mode" "XF")])
16407 (define_insn "*cosxf2_i387"
16408 [(set (match_operand:XF 0 "register_operand" "=f")
16409 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16410 "TARGET_USE_FANCY_MATH_387
16411 && flag_unsafe_math_optimizations"
16413 [(set_attr "type" "fpspc")
16414 (set_attr "mode" "XF")])
16416 (define_insn "*cos_extend<mode>xf2_i387"
16417 [(set (match_operand:XF 0 "register_operand" "=f")
16418 (unspec:XF [(float_extend:XF
16419 (match_operand:MODEF 1 "register_operand" "0"))]
16421 "TARGET_USE_FANCY_MATH_387
16422 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16423 || TARGET_MIX_SSE_I387)
16424 && flag_unsafe_math_optimizations"
16426 [(set_attr "type" "fpspc")
16427 (set_attr "mode" "XF")])
16429 ;; When sincos pattern is defined, sin and cos builtin functions will be
16430 ;; expanded to sincos pattern with one of its outputs left unused.
16431 ;; CSE pass will figure out if two sincos patterns can be combined,
16432 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16433 ;; depending on the unused output.
16435 (define_insn "sincosxf3"
16436 [(set (match_operand:XF 0 "register_operand" "=f")
16437 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16438 UNSPEC_SINCOS_COS))
16439 (set (match_operand:XF 1 "register_operand" "=u")
16440 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16441 "TARGET_USE_FANCY_MATH_387
16442 && flag_unsafe_math_optimizations"
16444 [(set_attr "type" "fpspc")
16445 (set_attr "mode" "XF")])
16448 [(set (match_operand:XF 0 "register_operand" "")
16449 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16450 UNSPEC_SINCOS_COS))
16451 (set (match_operand:XF 1 "register_operand" "")
16452 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16453 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16454 && !(reload_completed || reload_in_progress)"
16455 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16459 [(set (match_operand:XF 0 "register_operand" "")
16460 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16461 UNSPEC_SINCOS_COS))
16462 (set (match_operand:XF 1 "register_operand" "")
16463 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16464 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16465 && !(reload_completed || reload_in_progress)"
16466 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16469 (define_insn "sincos_extend<mode>xf3_i387"
16470 [(set (match_operand:XF 0 "register_operand" "=f")
16471 (unspec:XF [(float_extend:XF
16472 (match_operand:MODEF 2 "register_operand" "0"))]
16473 UNSPEC_SINCOS_COS))
16474 (set (match_operand:XF 1 "register_operand" "=u")
16475 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16476 "TARGET_USE_FANCY_MATH_387
16477 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16478 || TARGET_MIX_SSE_I387)
16479 && flag_unsafe_math_optimizations"
16481 [(set_attr "type" "fpspc")
16482 (set_attr "mode" "XF")])
16485 [(set (match_operand:XF 0 "register_operand" "")
16486 (unspec:XF [(float_extend:XF
16487 (match_operand:MODEF 2 "register_operand" ""))]
16488 UNSPEC_SINCOS_COS))
16489 (set (match_operand:XF 1 "register_operand" "")
16490 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16491 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16492 && !(reload_completed || reload_in_progress)"
16493 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16497 [(set (match_operand:XF 0 "register_operand" "")
16498 (unspec:XF [(float_extend:XF
16499 (match_operand:MODEF 2 "register_operand" ""))]
16500 UNSPEC_SINCOS_COS))
16501 (set (match_operand:XF 1 "register_operand" "")
16502 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16503 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16504 && !(reload_completed || reload_in_progress)"
16505 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16508 (define_expand "sincos<mode>3"
16509 [(use (match_operand:MODEF 0 "register_operand" ""))
16510 (use (match_operand:MODEF 1 "register_operand" ""))
16511 (use (match_operand:MODEF 2 "register_operand" ""))]
16512 "TARGET_USE_FANCY_MATH_387
16513 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16514 || TARGET_MIX_SSE_I387)
16515 && flag_unsafe_math_optimizations"
16517 rtx op0 = gen_reg_rtx (XFmode);
16518 rtx op1 = gen_reg_rtx (XFmode);
16520 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16521 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16522 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16526 (define_insn "fptanxf4_i387"
16527 [(set (match_operand:XF 0 "register_operand" "=f")
16528 (match_operand:XF 3 "const_double_operand" "F"))
16529 (set (match_operand:XF 1 "register_operand" "=u")
16530 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16532 "TARGET_USE_FANCY_MATH_387
16533 && flag_unsafe_math_optimizations
16534 && standard_80387_constant_p (operands[3]) == 2"
16536 [(set_attr "type" "fpspc")
16537 (set_attr "mode" "XF")])
16539 (define_insn "fptan_extend<mode>xf4_i387"
16540 [(set (match_operand:MODEF 0 "register_operand" "=f")
16541 (match_operand:MODEF 3 "const_double_operand" "F"))
16542 (set (match_operand:XF 1 "register_operand" "=u")
16543 (unspec:XF [(float_extend:XF
16544 (match_operand:MODEF 2 "register_operand" "0"))]
16546 "TARGET_USE_FANCY_MATH_387
16547 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16548 || TARGET_MIX_SSE_I387)
16549 && flag_unsafe_math_optimizations
16550 && standard_80387_constant_p (operands[3]) == 2"
16552 [(set_attr "type" "fpspc")
16553 (set_attr "mode" "XF")])
16555 (define_expand "tanxf2"
16556 [(use (match_operand:XF 0 "register_operand" ""))
16557 (use (match_operand:XF 1 "register_operand" ""))]
16558 "TARGET_USE_FANCY_MATH_387
16559 && flag_unsafe_math_optimizations"
16561 rtx one = gen_reg_rtx (XFmode);
16562 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16564 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16568 (define_expand "tan<mode>2"
16569 [(use (match_operand:MODEF 0 "register_operand" ""))
16570 (use (match_operand:MODEF 1 "register_operand" ""))]
16571 "TARGET_USE_FANCY_MATH_387
16572 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16573 || TARGET_MIX_SSE_I387)
16574 && flag_unsafe_math_optimizations"
16576 rtx op0 = gen_reg_rtx (XFmode);
16578 rtx one = gen_reg_rtx (<MODE>mode);
16579 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16581 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16582 operands[1], op2));
16583 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16587 (define_insn "*fpatanxf3_i387"
16588 [(set (match_operand:XF 0 "register_operand" "=f")
16589 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16590 (match_operand:XF 2 "register_operand" "u")]
16592 (clobber (match_scratch:XF 3 "=2"))]
16593 "TARGET_USE_FANCY_MATH_387
16594 && flag_unsafe_math_optimizations"
16596 [(set_attr "type" "fpspc")
16597 (set_attr "mode" "XF")])
16599 (define_insn "fpatan_extend<mode>xf3_i387"
16600 [(set (match_operand:XF 0 "register_operand" "=f")
16601 (unspec:XF [(float_extend:XF
16602 (match_operand:MODEF 1 "register_operand" "0"))
16604 (match_operand:MODEF 2 "register_operand" "u"))]
16606 (clobber (match_scratch:XF 3 "=2"))]
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 [(set_attr "type" "fpspc")
16613 (set_attr "mode" "XF")])
16615 (define_expand "atan2xf3"
16616 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16617 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16618 (match_operand:XF 1 "register_operand" "")]
16620 (clobber (match_scratch:XF 3 ""))])]
16621 "TARGET_USE_FANCY_MATH_387
16622 && flag_unsafe_math_optimizations"
16625 (define_expand "atan2<mode>3"
16626 [(use (match_operand:MODEF 0 "register_operand" ""))
16627 (use (match_operand:MODEF 1 "register_operand" ""))
16628 (use (match_operand:MODEF 2 "register_operand" ""))]
16629 "TARGET_USE_FANCY_MATH_387
16630 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16631 || TARGET_MIX_SSE_I387)
16632 && flag_unsafe_math_optimizations"
16634 rtx op0 = gen_reg_rtx (XFmode);
16636 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16637 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16641 (define_expand "atanxf2"
16642 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16643 (unspec:XF [(match_dup 2)
16644 (match_operand:XF 1 "register_operand" "")]
16646 (clobber (match_scratch:XF 3 ""))])]
16647 "TARGET_USE_FANCY_MATH_387
16648 && flag_unsafe_math_optimizations"
16650 operands[2] = gen_reg_rtx (XFmode);
16651 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16654 (define_expand "atan<mode>2"
16655 [(use (match_operand:MODEF 0 "register_operand" ""))
16656 (use (match_operand:MODEF 1 "register_operand" ""))]
16657 "TARGET_USE_FANCY_MATH_387
16658 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16659 || TARGET_MIX_SSE_I387)
16660 && flag_unsafe_math_optimizations"
16662 rtx op0 = gen_reg_rtx (XFmode);
16664 rtx op2 = gen_reg_rtx (<MODE>mode);
16665 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16667 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16668 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16672 (define_expand "asinxf2"
16673 [(set (match_dup 2)
16674 (mult:XF (match_operand:XF 1 "register_operand" "")
16676 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16677 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16678 (parallel [(set (match_operand:XF 0 "register_operand" "")
16679 (unspec:XF [(match_dup 5) (match_dup 1)]
16681 (clobber (match_scratch:XF 6 ""))])]
16682 "TARGET_USE_FANCY_MATH_387
16683 && flag_unsafe_math_optimizations"
16687 if (optimize_insn_for_size_p ())
16690 for (i = 2; i < 6; i++)
16691 operands[i] = gen_reg_rtx (XFmode);
16693 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16696 (define_expand "asin<mode>2"
16697 [(use (match_operand:MODEF 0 "register_operand" ""))
16698 (use (match_operand:MODEF 1 "general_operand" ""))]
16699 "TARGET_USE_FANCY_MATH_387
16700 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16701 || TARGET_MIX_SSE_I387)
16702 && flag_unsafe_math_optimizations"
16704 rtx op0 = gen_reg_rtx (XFmode);
16705 rtx op1 = gen_reg_rtx (XFmode);
16707 if (optimize_insn_for_size_p ())
16710 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16711 emit_insn (gen_asinxf2 (op0, op1));
16712 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16716 (define_expand "acosxf2"
16717 [(set (match_dup 2)
16718 (mult:XF (match_operand:XF 1 "register_operand" "")
16720 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16721 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16722 (parallel [(set (match_operand:XF 0 "register_operand" "")
16723 (unspec:XF [(match_dup 1) (match_dup 5)]
16725 (clobber (match_scratch:XF 6 ""))])]
16726 "TARGET_USE_FANCY_MATH_387
16727 && flag_unsafe_math_optimizations"
16731 if (optimize_insn_for_size_p ())
16734 for (i = 2; i < 6; i++)
16735 operands[i] = gen_reg_rtx (XFmode);
16737 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16740 (define_expand "acos<mode>2"
16741 [(use (match_operand:MODEF 0 "register_operand" ""))
16742 (use (match_operand:MODEF 1 "general_operand" ""))]
16743 "TARGET_USE_FANCY_MATH_387
16744 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16745 || TARGET_MIX_SSE_I387)
16746 && flag_unsafe_math_optimizations"
16748 rtx op0 = gen_reg_rtx (XFmode);
16749 rtx op1 = gen_reg_rtx (XFmode);
16751 if (optimize_insn_for_size_p ())
16754 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16755 emit_insn (gen_acosxf2 (op0, op1));
16756 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16760 (define_insn "fyl2xxf3_i387"
16761 [(set (match_operand:XF 0 "register_operand" "=f")
16762 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16763 (match_operand:XF 2 "register_operand" "u")]
16765 (clobber (match_scratch:XF 3 "=2"))]
16766 "TARGET_USE_FANCY_MATH_387
16767 && flag_unsafe_math_optimizations"
16769 [(set_attr "type" "fpspc")
16770 (set_attr "mode" "XF")])
16772 (define_insn "fyl2x_extend<mode>xf3_i387"
16773 [(set (match_operand:XF 0 "register_operand" "=f")
16774 (unspec:XF [(float_extend:XF
16775 (match_operand:MODEF 1 "register_operand" "0"))
16776 (match_operand:XF 2 "register_operand" "u")]
16778 (clobber (match_scratch:XF 3 "=2"))]
16779 "TARGET_USE_FANCY_MATH_387
16780 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16781 || TARGET_MIX_SSE_I387)
16782 && flag_unsafe_math_optimizations"
16784 [(set_attr "type" "fpspc")
16785 (set_attr "mode" "XF")])
16787 (define_expand "logxf2"
16788 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16789 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16790 (match_dup 2)] UNSPEC_FYL2X))
16791 (clobber (match_scratch:XF 3 ""))])]
16792 "TARGET_USE_FANCY_MATH_387
16793 && flag_unsafe_math_optimizations"
16795 operands[2] = gen_reg_rtx (XFmode);
16796 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16799 (define_expand "log<mode>2"
16800 [(use (match_operand:MODEF 0 "register_operand" ""))
16801 (use (match_operand:MODEF 1 "register_operand" ""))]
16802 "TARGET_USE_FANCY_MATH_387
16803 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16804 || TARGET_MIX_SSE_I387)
16805 && flag_unsafe_math_optimizations"
16807 rtx op0 = gen_reg_rtx (XFmode);
16809 rtx op2 = gen_reg_rtx (XFmode);
16810 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16812 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16813 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16817 (define_expand "log10xf2"
16818 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16819 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16820 (match_dup 2)] UNSPEC_FYL2X))
16821 (clobber (match_scratch:XF 3 ""))])]
16822 "TARGET_USE_FANCY_MATH_387
16823 && flag_unsafe_math_optimizations"
16825 operands[2] = gen_reg_rtx (XFmode);
16826 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16829 (define_expand "log10<mode>2"
16830 [(use (match_operand:MODEF 0 "register_operand" ""))
16831 (use (match_operand:MODEF 1 "register_operand" ""))]
16832 "TARGET_USE_FANCY_MATH_387
16833 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16834 || TARGET_MIX_SSE_I387)
16835 && flag_unsafe_math_optimizations"
16837 rtx op0 = gen_reg_rtx (XFmode);
16839 rtx op2 = gen_reg_rtx (XFmode);
16840 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16842 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16843 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16847 (define_expand "log2xf2"
16848 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16849 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16850 (match_dup 2)] UNSPEC_FYL2X))
16851 (clobber (match_scratch:XF 3 ""))])]
16852 "TARGET_USE_FANCY_MATH_387
16853 && flag_unsafe_math_optimizations"
16855 operands[2] = gen_reg_rtx (XFmode);
16856 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16859 (define_expand "log2<mode>2"
16860 [(use (match_operand:MODEF 0 "register_operand" ""))
16861 (use (match_operand:MODEF 1 "register_operand" ""))]
16862 "TARGET_USE_FANCY_MATH_387
16863 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16864 || TARGET_MIX_SSE_I387)
16865 && flag_unsafe_math_optimizations"
16867 rtx op0 = gen_reg_rtx (XFmode);
16869 rtx op2 = gen_reg_rtx (XFmode);
16870 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16872 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16873 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16877 (define_insn "fyl2xp1xf3_i387"
16878 [(set (match_operand:XF 0 "register_operand" "=f")
16879 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16880 (match_operand:XF 2 "register_operand" "u")]
16882 (clobber (match_scratch:XF 3 "=2"))]
16883 "TARGET_USE_FANCY_MATH_387
16884 && flag_unsafe_math_optimizations"
16886 [(set_attr "type" "fpspc")
16887 (set_attr "mode" "XF")])
16889 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16890 [(set (match_operand:XF 0 "register_operand" "=f")
16891 (unspec:XF [(float_extend:XF
16892 (match_operand:MODEF 1 "register_operand" "0"))
16893 (match_operand:XF 2 "register_operand" "u")]
16895 (clobber (match_scratch:XF 3 "=2"))]
16896 "TARGET_USE_FANCY_MATH_387
16897 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16898 || TARGET_MIX_SSE_I387)
16899 && flag_unsafe_math_optimizations"
16901 [(set_attr "type" "fpspc")
16902 (set_attr "mode" "XF")])
16904 (define_expand "log1pxf2"
16905 [(use (match_operand:XF 0 "register_operand" ""))
16906 (use (match_operand:XF 1 "register_operand" ""))]
16907 "TARGET_USE_FANCY_MATH_387
16908 && flag_unsafe_math_optimizations"
16910 if (optimize_insn_for_size_p ())
16913 ix86_emit_i387_log1p (operands[0], operands[1]);
16917 (define_expand "log1p<mode>2"
16918 [(use (match_operand:MODEF 0 "register_operand" ""))
16919 (use (match_operand:MODEF 1 "register_operand" ""))]
16920 "TARGET_USE_FANCY_MATH_387
16921 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16922 || TARGET_MIX_SSE_I387)
16923 && flag_unsafe_math_optimizations"
16927 if (optimize_insn_for_size_p ())
16930 op0 = gen_reg_rtx (XFmode);
16932 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16934 ix86_emit_i387_log1p (op0, operands[1]);
16935 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16939 (define_insn "fxtractxf3_i387"
16940 [(set (match_operand:XF 0 "register_operand" "=f")
16941 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16942 UNSPEC_XTRACT_FRACT))
16943 (set (match_operand:XF 1 "register_operand" "=u")
16944 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16945 "TARGET_USE_FANCY_MATH_387
16946 && flag_unsafe_math_optimizations"
16948 [(set_attr "type" "fpspc")
16949 (set_attr "mode" "XF")])
16951 (define_insn "fxtract_extend<mode>xf3_i387"
16952 [(set (match_operand:XF 0 "register_operand" "=f")
16953 (unspec:XF [(float_extend:XF
16954 (match_operand:MODEF 2 "register_operand" "0"))]
16955 UNSPEC_XTRACT_FRACT))
16956 (set (match_operand:XF 1 "register_operand" "=u")
16957 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16958 "TARGET_USE_FANCY_MATH_387
16959 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16960 || TARGET_MIX_SSE_I387)
16961 && flag_unsafe_math_optimizations"
16963 [(set_attr "type" "fpspc")
16964 (set_attr "mode" "XF")])
16966 (define_expand "logbxf2"
16967 [(parallel [(set (match_dup 2)
16968 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16969 UNSPEC_XTRACT_FRACT))
16970 (set (match_operand:XF 0 "register_operand" "")
16971 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16972 "TARGET_USE_FANCY_MATH_387
16973 && flag_unsafe_math_optimizations"
16975 operands[2] = gen_reg_rtx (XFmode);
16978 (define_expand "logb<mode>2"
16979 [(use (match_operand:MODEF 0 "register_operand" ""))
16980 (use (match_operand:MODEF 1 "register_operand" ""))]
16981 "TARGET_USE_FANCY_MATH_387
16982 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16983 || TARGET_MIX_SSE_I387)
16984 && flag_unsafe_math_optimizations"
16986 rtx op0 = gen_reg_rtx (XFmode);
16987 rtx op1 = gen_reg_rtx (XFmode);
16989 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16990 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16994 (define_expand "ilogbxf2"
16995 [(use (match_operand:SI 0 "register_operand" ""))
16996 (use (match_operand:XF 1 "register_operand" ""))]
16997 "TARGET_USE_FANCY_MATH_387
16998 && flag_unsafe_math_optimizations"
17002 if (optimize_insn_for_size_p ())
17005 op0 = gen_reg_rtx (XFmode);
17006 op1 = gen_reg_rtx (XFmode);
17008 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
17009 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17013 (define_expand "ilogb<mode>2"
17014 [(use (match_operand:SI 0 "register_operand" ""))
17015 (use (match_operand:MODEF 1 "register_operand" ""))]
17016 "TARGET_USE_FANCY_MATH_387
17017 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17018 || TARGET_MIX_SSE_I387)
17019 && flag_unsafe_math_optimizations"
17023 if (optimize_insn_for_size_p ())
17026 op0 = gen_reg_rtx (XFmode);
17027 op1 = gen_reg_rtx (XFmode);
17029 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17030 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
17034 (define_insn "*f2xm1xf2_i387"
17035 [(set (match_operand:XF 0 "register_operand" "=f")
17036 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17038 "TARGET_USE_FANCY_MATH_387
17039 && flag_unsafe_math_optimizations"
17041 [(set_attr "type" "fpspc")
17042 (set_attr "mode" "XF")])
17044 (define_insn "*fscalexf4_i387"
17045 [(set (match_operand:XF 0 "register_operand" "=f")
17046 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17047 (match_operand:XF 3 "register_operand" "1")]
17048 UNSPEC_FSCALE_FRACT))
17049 (set (match_operand:XF 1 "register_operand" "=u")
17050 (unspec:XF [(match_dup 2) (match_dup 3)]
17051 UNSPEC_FSCALE_EXP))]
17052 "TARGET_USE_FANCY_MATH_387
17053 && flag_unsafe_math_optimizations"
17055 [(set_attr "type" "fpspc")
17056 (set_attr "mode" "XF")])
17058 (define_expand "expNcorexf3"
17059 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17060 (match_operand:XF 2 "register_operand" "")))
17061 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17062 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17063 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17064 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
17065 (parallel [(set (match_operand:XF 0 "register_operand" "")
17066 (unspec:XF [(match_dup 8) (match_dup 4)]
17067 UNSPEC_FSCALE_FRACT))
17069 (unspec:XF [(match_dup 8) (match_dup 4)]
17070 UNSPEC_FSCALE_EXP))])]
17071 "TARGET_USE_FANCY_MATH_387
17072 && flag_unsafe_math_optimizations"
17076 if (optimize_insn_for_size_p ())
17079 for (i = 3; i < 10; i++)
17080 operands[i] = gen_reg_rtx (XFmode);
17082 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
17085 (define_expand "expxf2"
17086 [(use (match_operand:XF 0 "register_operand" ""))
17087 (use (match_operand:XF 1 "register_operand" ""))]
17088 "TARGET_USE_FANCY_MATH_387
17089 && flag_unsafe_math_optimizations"
17093 if (optimize_insn_for_size_p ())
17096 op2 = gen_reg_rtx (XFmode);
17097 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
17099 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17103 (define_expand "exp<mode>2"
17104 [(use (match_operand:MODEF 0 "register_operand" ""))
17105 (use (match_operand:MODEF 1 "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);
17119 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17120 emit_insn (gen_expxf2 (op0, op1));
17121 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17125 (define_expand "exp10xf2"
17126 [(use (match_operand:XF 0 "register_operand" ""))
17127 (use (match_operand:XF 1 "register_operand" ""))]
17128 "TARGET_USE_FANCY_MATH_387
17129 && flag_unsafe_math_optimizations"
17133 if (optimize_insn_for_size_p ())
17136 op2 = gen_reg_rtx (XFmode);
17137 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
17139 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17143 (define_expand "exp10<mode>2"
17144 [(use (match_operand:MODEF 0 "register_operand" ""))
17145 (use (match_operand:MODEF 1 "general_operand" ""))]
17146 "TARGET_USE_FANCY_MATH_387
17147 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17148 || TARGET_MIX_SSE_I387)
17149 && flag_unsafe_math_optimizations"
17153 if (optimize_insn_for_size_p ())
17156 op0 = gen_reg_rtx (XFmode);
17157 op1 = gen_reg_rtx (XFmode);
17159 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17160 emit_insn (gen_exp10xf2 (op0, op1));
17161 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17165 (define_expand "exp2xf2"
17166 [(use (match_operand:XF 0 "register_operand" ""))
17167 (use (match_operand:XF 1 "register_operand" ""))]
17168 "TARGET_USE_FANCY_MATH_387
17169 && flag_unsafe_math_optimizations"
17173 if (optimize_insn_for_size_p ())
17176 op2 = gen_reg_rtx (XFmode);
17177 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
17179 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
17183 (define_expand "exp2<mode>2"
17184 [(use (match_operand:MODEF 0 "register_operand" ""))
17185 (use (match_operand:MODEF 1 "general_operand" ""))]
17186 "TARGET_USE_FANCY_MATH_387
17187 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17188 || TARGET_MIX_SSE_I387)
17189 && flag_unsafe_math_optimizations"
17193 if (optimize_insn_for_size_p ())
17196 op0 = gen_reg_rtx (XFmode);
17197 op1 = gen_reg_rtx (XFmode);
17199 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17200 emit_insn (gen_exp2xf2 (op0, op1));
17201 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17205 (define_expand "expm1xf2"
17206 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
17208 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
17209 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
17210 (set (match_dup 9) (float_extend:XF (match_dup 13)))
17211 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
17212 (parallel [(set (match_dup 7)
17213 (unspec:XF [(match_dup 6) (match_dup 4)]
17214 UNSPEC_FSCALE_FRACT))
17216 (unspec:XF [(match_dup 6) (match_dup 4)]
17217 UNSPEC_FSCALE_EXP))])
17218 (parallel [(set (match_dup 10)
17219 (unspec:XF [(match_dup 9) (match_dup 8)]
17220 UNSPEC_FSCALE_FRACT))
17221 (set (match_dup 11)
17222 (unspec:XF [(match_dup 9) (match_dup 8)]
17223 UNSPEC_FSCALE_EXP))])
17224 (set (match_dup 12) (minus:XF (match_dup 10)
17225 (float_extend:XF (match_dup 13))))
17226 (set (match_operand:XF 0 "register_operand" "")
17227 (plus:XF (match_dup 12) (match_dup 7)))]
17228 "TARGET_USE_FANCY_MATH_387
17229 && flag_unsafe_math_optimizations"
17233 if (optimize_insn_for_size_p ())
17236 for (i = 2; i < 13; i++)
17237 operands[i] = gen_reg_rtx (XFmode);
17240 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17242 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17245 (define_expand "expm1<mode>2"
17246 [(use (match_operand:MODEF 0 "register_operand" ""))
17247 (use (match_operand:MODEF 1 "general_operand" ""))]
17248 "TARGET_USE_FANCY_MATH_387
17249 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17250 || TARGET_MIX_SSE_I387)
17251 && flag_unsafe_math_optimizations"
17255 if (optimize_insn_for_size_p ())
17258 op0 = gen_reg_rtx (XFmode);
17259 op1 = gen_reg_rtx (XFmode);
17261 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17262 emit_insn (gen_expm1xf2 (op0, op1));
17263 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17267 (define_expand "ldexpxf3"
17268 [(set (match_dup 3)
17269 (float:XF (match_operand:SI 2 "register_operand" "")))
17270 (parallel [(set (match_operand:XF 0 " register_operand" "")
17271 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17273 UNSPEC_FSCALE_FRACT))
17275 (unspec:XF [(match_dup 1) (match_dup 3)]
17276 UNSPEC_FSCALE_EXP))])]
17277 "TARGET_USE_FANCY_MATH_387
17278 && flag_unsafe_math_optimizations"
17280 if (optimize_insn_for_size_p ())
17283 operands[3] = gen_reg_rtx (XFmode);
17284 operands[4] = gen_reg_rtx (XFmode);
17287 (define_expand "ldexp<mode>3"
17288 [(use (match_operand:MODEF 0 "register_operand" ""))
17289 (use (match_operand:MODEF 1 "general_operand" ""))
17290 (use (match_operand:SI 2 "register_operand" ""))]
17291 "TARGET_USE_FANCY_MATH_387
17292 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17293 || TARGET_MIX_SSE_I387)
17294 && flag_unsafe_math_optimizations"
17298 if (optimize_insn_for_size_p ())
17301 op0 = gen_reg_rtx (XFmode);
17302 op1 = gen_reg_rtx (XFmode);
17304 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17305 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17306 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17310 (define_expand "scalbxf3"
17311 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17312 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17313 (match_operand:XF 2 "register_operand" "")]
17314 UNSPEC_FSCALE_FRACT))
17316 (unspec:XF [(match_dup 1) (match_dup 2)]
17317 UNSPEC_FSCALE_EXP))])]
17318 "TARGET_USE_FANCY_MATH_387
17319 && flag_unsafe_math_optimizations"
17321 if (optimize_insn_for_size_p ())
17324 operands[3] = gen_reg_rtx (XFmode);
17327 (define_expand "scalb<mode>3"
17328 [(use (match_operand:MODEF 0 "register_operand" ""))
17329 (use (match_operand:MODEF 1 "general_operand" ""))
17330 (use (match_operand:MODEF 2 "general_operand" ""))]
17331 "TARGET_USE_FANCY_MATH_387
17332 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17333 || TARGET_MIX_SSE_I387)
17334 && flag_unsafe_math_optimizations"
17338 if (optimize_insn_for_size_p ())
17341 op0 = gen_reg_rtx (XFmode);
17342 op1 = gen_reg_rtx (XFmode);
17343 op2 = gen_reg_rtx (XFmode);
17345 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17346 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17347 emit_insn (gen_scalbxf3 (op0, op1, op2));
17348 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17352 (define_expand "significandxf2"
17353 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17354 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17355 UNSPEC_XTRACT_FRACT))
17357 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17358 "TARGET_USE_FANCY_MATH_387
17359 && flag_unsafe_math_optimizations"
17361 operands[2] = gen_reg_rtx (XFmode);
17364 (define_expand "significand<mode>2"
17365 [(use (match_operand:MODEF 0 "register_operand" ""))
17366 (use (match_operand:MODEF 1 "register_operand" ""))]
17367 "TARGET_USE_FANCY_MATH_387
17368 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17369 || TARGET_MIX_SSE_I387)
17370 && flag_unsafe_math_optimizations"
17372 rtx op0 = gen_reg_rtx (XFmode);
17373 rtx op1 = gen_reg_rtx (XFmode);
17375 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17376 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17381 (define_insn "sse4_1_round<mode>2"
17382 [(set (match_operand:MODEF 0 "register_operand" "=x")
17383 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17384 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17387 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17388 [(set_attr "type" "ssecvt")
17389 (set_attr "prefix_extra" "1")
17390 (set_attr "prefix" "maybe_vex")
17391 (set_attr "mode" "<MODE>")])
17393 (define_insn "rintxf2"
17394 [(set (match_operand:XF 0 "register_operand" "=f")
17395 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17397 "TARGET_USE_FANCY_MATH_387
17398 && flag_unsafe_math_optimizations"
17400 [(set_attr "type" "fpspc")
17401 (set_attr "mode" "XF")])
17403 (define_expand "rint<mode>2"
17404 [(use (match_operand:MODEF 0 "register_operand" ""))
17405 (use (match_operand:MODEF 1 "register_operand" ""))]
17406 "(TARGET_USE_FANCY_MATH_387
17407 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17408 || TARGET_MIX_SSE_I387)
17409 && flag_unsafe_math_optimizations)
17410 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17411 && !flag_trapping_math)"
17413 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17414 && !flag_trapping_math)
17416 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17419 emit_insn (gen_sse4_1_round<mode>2
17420 (operands[0], operands[1], GEN_INT (0x04)));
17422 ix86_expand_rint (operand0, operand1);
17426 rtx op0 = gen_reg_rtx (XFmode);
17427 rtx op1 = gen_reg_rtx (XFmode);
17429 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17430 emit_insn (gen_rintxf2 (op0, op1));
17432 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17437 (define_expand "round<mode>2"
17438 [(match_operand:MODEF 0 "register_operand" "")
17439 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17440 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17441 && !flag_trapping_math && !flag_rounding_math"
17443 if (optimize_insn_for_size_p ())
17445 if (TARGET_64BIT || (<MODE>mode != DFmode))
17446 ix86_expand_round (operand0, operand1);
17448 ix86_expand_rounddf_32 (operand0, operand1);
17452 (define_insn_and_split "*fistdi2_1"
17453 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17454 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17456 "TARGET_USE_FANCY_MATH_387
17457 && can_create_pseudo_p ()"
17462 if (memory_operand (operands[0], VOIDmode))
17463 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17466 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17467 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17472 [(set_attr "type" "fpspc")
17473 (set_attr "mode" "DI")])
17475 (define_insn "fistdi2"
17476 [(set (match_operand:DI 0 "memory_operand" "=m")
17477 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17479 (clobber (match_scratch:XF 2 "=&1f"))]
17480 "TARGET_USE_FANCY_MATH_387"
17481 "* return output_fix_trunc (insn, operands, 0);"
17482 [(set_attr "type" "fpspc")
17483 (set_attr "mode" "DI")])
17485 (define_insn "fistdi2_with_temp"
17486 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17487 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17489 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17490 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17491 "TARGET_USE_FANCY_MATH_387"
17493 [(set_attr "type" "fpspc")
17494 (set_attr "mode" "DI")])
17497 [(set (match_operand:DI 0 "register_operand" "")
17498 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17500 (clobber (match_operand:DI 2 "memory_operand" ""))
17501 (clobber (match_scratch 3 ""))]
17503 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17504 (clobber (match_dup 3))])
17505 (set (match_dup 0) (match_dup 2))]
17509 [(set (match_operand:DI 0 "memory_operand" "")
17510 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17512 (clobber (match_operand:DI 2 "memory_operand" ""))
17513 (clobber (match_scratch 3 ""))]
17515 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17516 (clobber (match_dup 3))])]
17519 (define_insn_and_split "*fist<mode>2_1"
17520 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17521 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17523 "TARGET_USE_FANCY_MATH_387
17524 && can_create_pseudo_p ()"
17529 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17530 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17534 [(set_attr "type" "fpspc")
17535 (set_attr "mode" "<MODE>")])
17537 (define_insn "fist<mode>2"
17538 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17539 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17541 "TARGET_USE_FANCY_MATH_387"
17542 "* return output_fix_trunc (insn, operands, 0);"
17543 [(set_attr "type" "fpspc")
17544 (set_attr "mode" "<MODE>")])
17546 (define_insn "fist<mode>2_with_temp"
17547 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17548 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17550 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17551 "TARGET_USE_FANCY_MATH_387"
17553 [(set_attr "type" "fpspc")
17554 (set_attr "mode" "<MODE>")])
17557 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17558 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17560 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17562 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17563 (set (match_dup 0) (match_dup 2))]
17567 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17568 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17570 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17572 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17575 (define_expand "lrintxf<mode>2"
17576 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17577 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17579 "TARGET_USE_FANCY_MATH_387"
17582 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17583 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17584 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17585 UNSPEC_FIX_NOTRUNC))]
17586 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17587 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17590 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17591 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17592 (match_operand:MODEF 1 "register_operand" "")]
17593 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17594 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17595 && !flag_trapping_math && !flag_rounding_math"
17597 if (optimize_insn_for_size_p ())
17599 ix86_expand_lround (operand0, operand1);
17603 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17604 (define_insn_and_split "frndintxf2_floor"
17605 [(set (match_operand:XF 0 "register_operand" "")
17606 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17607 UNSPEC_FRNDINT_FLOOR))
17608 (clobber (reg:CC FLAGS_REG))]
17609 "TARGET_USE_FANCY_MATH_387
17610 && flag_unsafe_math_optimizations
17611 && can_create_pseudo_p ()"
17616 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17618 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17619 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17621 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17622 operands[2], operands[3]));
17625 [(set_attr "type" "frndint")
17626 (set_attr "i387_cw" "floor")
17627 (set_attr "mode" "XF")])
17629 (define_insn "frndintxf2_floor_i387"
17630 [(set (match_operand:XF 0 "register_operand" "=f")
17631 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17632 UNSPEC_FRNDINT_FLOOR))
17633 (use (match_operand:HI 2 "memory_operand" "m"))
17634 (use (match_operand:HI 3 "memory_operand" "m"))]
17635 "TARGET_USE_FANCY_MATH_387
17636 && flag_unsafe_math_optimizations"
17637 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17638 [(set_attr "type" "frndint")
17639 (set_attr "i387_cw" "floor")
17640 (set_attr "mode" "XF")])
17642 (define_expand "floorxf2"
17643 [(use (match_operand:XF 0 "register_operand" ""))
17644 (use (match_operand:XF 1 "register_operand" ""))]
17645 "TARGET_USE_FANCY_MATH_387
17646 && flag_unsafe_math_optimizations"
17648 if (optimize_insn_for_size_p ())
17650 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17654 (define_expand "floor<mode>2"
17655 [(use (match_operand:MODEF 0 "register_operand" ""))
17656 (use (match_operand:MODEF 1 "register_operand" ""))]
17657 "(TARGET_USE_FANCY_MATH_387
17658 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17659 || TARGET_MIX_SSE_I387)
17660 && flag_unsafe_math_optimizations)
17661 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17662 && !flag_trapping_math)"
17664 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17665 && !flag_trapping_math
17666 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17668 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17671 emit_insn (gen_sse4_1_round<mode>2
17672 (operands[0], operands[1], GEN_INT (0x01)));
17673 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17674 ix86_expand_floorceil (operand0, operand1, true);
17676 ix86_expand_floorceildf_32 (operand0, operand1, true);
17682 if (optimize_insn_for_size_p ())
17685 op0 = gen_reg_rtx (XFmode);
17686 op1 = gen_reg_rtx (XFmode);
17687 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17688 emit_insn (gen_frndintxf2_floor (op0, op1));
17690 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17695 (define_insn_and_split "*fist<mode>2_floor_1"
17696 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17697 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17698 UNSPEC_FIST_FLOOR))
17699 (clobber (reg:CC FLAGS_REG))]
17700 "TARGET_USE_FANCY_MATH_387
17701 && flag_unsafe_math_optimizations
17702 && can_create_pseudo_p ()"
17707 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17709 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17710 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17711 if (memory_operand (operands[0], VOIDmode))
17712 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17713 operands[2], operands[3]));
17716 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17717 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17718 operands[2], operands[3],
17723 [(set_attr "type" "fistp")
17724 (set_attr "i387_cw" "floor")
17725 (set_attr "mode" "<MODE>")])
17727 (define_insn "fistdi2_floor"
17728 [(set (match_operand:DI 0 "memory_operand" "=m")
17729 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17730 UNSPEC_FIST_FLOOR))
17731 (use (match_operand:HI 2 "memory_operand" "m"))
17732 (use (match_operand:HI 3 "memory_operand" "m"))
17733 (clobber (match_scratch:XF 4 "=&1f"))]
17734 "TARGET_USE_FANCY_MATH_387
17735 && flag_unsafe_math_optimizations"
17736 "* return output_fix_trunc (insn, operands, 0);"
17737 [(set_attr "type" "fistp")
17738 (set_attr "i387_cw" "floor")
17739 (set_attr "mode" "DI")])
17741 (define_insn "fistdi2_floor_with_temp"
17742 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17743 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17744 UNSPEC_FIST_FLOOR))
17745 (use (match_operand:HI 2 "memory_operand" "m,m"))
17746 (use (match_operand:HI 3 "memory_operand" "m,m"))
17747 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17748 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17749 "TARGET_USE_FANCY_MATH_387
17750 && flag_unsafe_math_optimizations"
17752 [(set_attr "type" "fistp")
17753 (set_attr "i387_cw" "floor")
17754 (set_attr "mode" "DI")])
17757 [(set (match_operand:DI 0 "register_operand" "")
17758 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17759 UNSPEC_FIST_FLOOR))
17760 (use (match_operand:HI 2 "memory_operand" ""))
17761 (use (match_operand:HI 3 "memory_operand" ""))
17762 (clobber (match_operand:DI 4 "memory_operand" ""))
17763 (clobber (match_scratch 5 ""))]
17765 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17766 (use (match_dup 2))
17767 (use (match_dup 3))
17768 (clobber (match_dup 5))])
17769 (set (match_dup 0) (match_dup 4))]
17773 [(set (match_operand:DI 0 "memory_operand" "")
17774 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17775 UNSPEC_FIST_FLOOR))
17776 (use (match_operand:HI 2 "memory_operand" ""))
17777 (use (match_operand:HI 3 "memory_operand" ""))
17778 (clobber (match_operand:DI 4 "memory_operand" ""))
17779 (clobber (match_scratch 5 ""))]
17781 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17782 (use (match_dup 2))
17783 (use (match_dup 3))
17784 (clobber (match_dup 5))])]
17787 (define_insn "fist<mode>2_floor"
17788 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17789 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17790 UNSPEC_FIST_FLOOR))
17791 (use (match_operand:HI 2 "memory_operand" "m"))
17792 (use (match_operand:HI 3 "memory_operand" "m"))]
17793 "TARGET_USE_FANCY_MATH_387
17794 && flag_unsafe_math_optimizations"
17795 "* return output_fix_trunc (insn, operands, 0);"
17796 [(set_attr "type" "fistp")
17797 (set_attr "i387_cw" "floor")
17798 (set_attr "mode" "<MODE>")])
17800 (define_insn "fist<mode>2_floor_with_temp"
17801 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17802 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17803 UNSPEC_FIST_FLOOR))
17804 (use (match_operand:HI 2 "memory_operand" "m,m"))
17805 (use (match_operand:HI 3 "memory_operand" "m,m"))
17806 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17807 "TARGET_USE_FANCY_MATH_387
17808 && flag_unsafe_math_optimizations"
17810 [(set_attr "type" "fistp")
17811 (set_attr "i387_cw" "floor")
17812 (set_attr "mode" "<MODE>")])
17815 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17816 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17817 UNSPEC_FIST_FLOOR))
17818 (use (match_operand:HI 2 "memory_operand" ""))
17819 (use (match_operand:HI 3 "memory_operand" ""))
17820 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17822 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17823 UNSPEC_FIST_FLOOR))
17824 (use (match_dup 2))
17825 (use (match_dup 3))])
17826 (set (match_dup 0) (match_dup 4))]
17830 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17831 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17832 UNSPEC_FIST_FLOOR))
17833 (use (match_operand:HI 2 "memory_operand" ""))
17834 (use (match_operand:HI 3 "memory_operand" ""))
17835 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17837 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17838 UNSPEC_FIST_FLOOR))
17839 (use (match_dup 2))
17840 (use (match_dup 3))])]
17843 (define_expand "lfloorxf<mode>2"
17844 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17845 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17846 UNSPEC_FIST_FLOOR))
17847 (clobber (reg:CC FLAGS_REG))])]
17848 "TARGET_USE_FANCY_MATH_387
17849 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17850 && flag_unsafe_math_optimizations"
17853 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17854 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17855 (match_operand:MODEF 1 "register_operand" "")]
17856 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17857 && !flag_trapping_math"
17859 if (TARGET_64BIT && optimize_insn_for_size_p ())
17861 ix86_expand_lfloorceil (operand0, operand1, true);
17865 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17866 (define_insn_and_split "frndintxf2_ceil"
17867 [(set (match_operand:XF 0 "register_operand" "")
17868 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17869 UNSPEC_FRNDINT_CEIL))
17870 (clobber (reg:CC FLAGS_REG))]
17871 "TARGET_USE_FANCY_MATH_387
17872 && flag_unsafe_math_optimizations
17873 && can_create_pseudo_p ()"
17878 ix86_optimize_mode_switching[I387_CEIL] = 1;
17880 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17881 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17883 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17884 operands[2], operands[3]));
17887 [(set_attr "type" "frndint")
17888 (set_attr "i387_cw" "ceil")
17889 (set_attr "mode" "XF")])
17891 (define_insn "frndintxf2_ceil_i387"
17892 [(set (match_operand:XF 0 "register_operand" "=f")
17893 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17894 UNSPEC_FRNDINT_CEIL))
17895 (use (match_operand:HI 2 "memory_operand" "m"))
17896 (use (match_operand:HI 3 "memory_operand" "m"))]
17897 "TARGET_USE_FANCY_MATH_387
17898 && flag_unsafe_math_optimizations"
17899 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17900 [(set_attr "type" "frndint")
17901 (set_attr "i387_cw" "ceil")
17902 (set_attr "mode" "XF")])
17904 (define_expand "ceilxf2"
17905 [(use (match_operand:XF 0 "register_operand" ""))
17906 (use (match_operand:XF 1 "register_operand" ""))]
17907 "TARGET_USE_FANCY_MATH_387
17908 && flag_unsafe_math_optimizations"
17910 if (optimize_insn_for_size_p ())
17912 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17916 (define_expand "ceil<mode>2"
17917 [(use (match_operand:MODEF 0 "register_operand" ""))
17918 (use (match_operand:MODEF 1 "register_operand" ""))]
17919 "(TARGET_USE_FANCY_MATH_387
17920 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17921 || TARGET_MIX_SSE_I387)
17922 && flag_unsafe_math_optimizations)
17923 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17924 && !flag_trapping_math)"
17926 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17927 && !flag_trapping_math
17928 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17931 emit_insn (gen_sse4_1_round<mode>2
17932 (operands[0], operands[1], GEN_INT (0x02)));
17933 else if (optimize_insn_for_size_p ())
17935 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17936 ix86_expand_floorceil (operand0, operand1, false);
17938 ix86_expand_floorceildf_32 (operand0, operand1, false);
17944 if (optimize_insn_for_size_p ())
17947 op0 = gen_reg_rtx (XFmode);
17948 op1 = gen_reg_rtx (XFmode);
17949 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17950 emit_insn (gen_frndintxf2_ceil (op0, op1));
17952 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17957 (define_insn_and_split "*fist<mode>2_ceil_1"
17958 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17959 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17961 (clobber (reg:CC FLAGS_REG))]
17962 "TARGET_USE_FANCY_MATH_387
17963 && flag_unsafe_math_optimizations
17964 && can_create_pseudo_p ()"
17969 ix86_optimize_mode_switching[I387_CEIL] = 1;
17971 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17972 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17973 if (memory_operand (operands[0], VOIDmode))
17974 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17975 operands[2], operands[3]));
17978 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17979 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17980 operands[2], operands[3],
17985 [(set_attr "type" "fistp")
17986 (set_attr "i387_cw" "ceil")
17987 (set_attr "mode" "<MODE>")])
17989 (define_insn "fistdi2_ceil"
17990 [(set (match_operand:DI 0 "memory_operand" "=m")
17991 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17993 (use (match_operand:HI 2 "memory_operand" "m"))
17994 (use (match_operand:HI 3 "memory_operand" "m"))
17995 (clobber (match_scratch:XF 4 "=&1f"))]
17996 "TARGET_USE_FANCY_MATH_387
17997 && flag_unsafe_math_optimizations"
17998 "* return output_fix_trunc (insn, operands, 0);"
17999 [(set_attr "type" "fistp")
18000 (set_attr "i387_cw" "ceil")
18001 (set_attr "mode" "DI")])
18003 (define_insn "fistdi2_ceil_with_temp"
18004 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18005 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18007 (use (match_operand:HI 2 "memory_operand" "m,m"))
18008 (use (match_operand:HI 3 "memory_operand" "m,m"))
18009 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18010 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18011 "TARGET_USE_FANCY_MATH_387
18012 && flag_unsafe_math_optimizations"
18014 [(set_attr "type" "fistp")
18015 (set_attr "i387_cw" "ceil")
18016 (set_attr "mode" "DI")])
18019 [(set (match_operand:DI 0 "register_operand" "")
18020 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18022 (use (match_operand:HI 2 "memory_operand" ""))
18023 (use (match_operand:HI 3 "memory_operand" ""))
18024 (clobber (match_operand:DI 4 "memory_operand" ""))
18025 (clobber (match_scratch 5 ""))]
18027 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18028 (use (match_dup 2))
18029 (use (match_dup 3))
18030 (clobber (match_dup 5))])
18031 (set (match_dup 0) (match_dup 4))]
18035 [(set (match_operand:DI 0 "memory_operand" "")
18036 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18038 (use (match_operand:HI 2 "memory_operand" ""))
18039 (use (match_operand:HI 3 "memory_operand" ""))
18040 (clobber (match_operand:DI 4 "memory_operand" ""))
18041 (clobber (match_scratch 5 ""))]
18043 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
18044 (use (match_dup 2))
18045 (use (match_dup 3))
18046 (clobber (match_dup 5))])]
18049 (define_insn "fist<mode>2_ceil"
18050 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18051 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18053 (use (match_operand:HI 2 "memory_operand" "m"))
18054 (use (match_operand:HI 3 "memory_operand" "m"))]
18055 "TARGET_USE_FANCY_MATH_387
18056 && flag_unsafe_math_optimizations"
18057 "* return output_fix_trunc (insn, operands, 0);"
18058 [(set_attr "type" "fistp")
18059 (set_attr "i387_cw" "ceil")
18060 (set_attr "mode" "<MODE>")])
18062 (define_insn "fist<mode>2_ceil_with_temp"
18063 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18064 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18066 (use (match_operand:HI 2 "memory_operand" "m,m"))
18067 (use (match_operand:HI 3 "memory_operand" "m,m"))
18068 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18069 "TARGET_USE_FANCY_MATH_387
18070 && flag_unsafe_math_optimizations"
18072 [(set_attr "type" "fistp")
18073 (set_attr "i387_cw" "ceil")
18074 (set_attr "mode" "<MODE>")])
18077 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18078 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18080 (use (match_operand:HI 2 "memory_operand" ""))
18081 (use (match_operand:HI 3 "memory_operand" ""))
18082 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18084 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18086 (use (match_dup 2))
18087 (use (match_dup 3))])
18088 (set (match_dup 0) (match_dup 4))]
18092 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18093 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18095 (use (match_operand:HI 2 "memory_operand" ""))
18096 (use (match_operand:HI 3 "memory_operand" ""))
18097 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18099 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
18101 (use (match_dup 2))
18102 (use (match_dup 3))])]
18105 (define_expand "lceilxf<mode>2"
18106 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18107 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18109 (clobber (reg:CC FLAGS_REG))])]
18110 "TARGET_USE_FANCY_MATH_387
18111 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
18112 && flag_unsafe_math_optimizations"
18115 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
18116 [(match_operand:SWI48 0 "nonimmediate_operand" "")
18117 (match_operand:MODEF 1 "register_operand" "")]
18118 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18119 && !flag_trapping_math"
18121 ix86_expand_lfloorceil (operand0, operand1, false);
18125 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18126 (define_insn_and_split "frndintxf2_trunc"
18127 [(set (match_operand:XF 0 "register_operand" "")
18128 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18129 UNSPEC_FRNDINT_TRUNC))
18130 (clobber (reg:CC FLAGS_REG))]
18131 "TARGET_USE_FANCY_MATH_387
18132 && flag_unsafe_math_optimizations
18133 && can_create_pseudo_p ()"
18138 ix86_optimize_mode_switching[I387_TRUNC] = 1;
18140 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18141 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
18143 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
18144 operands[2], operands[3]));
18147 [(set_attr "type" "frndint")
18148 (set_attr "i387_cw" "trunc")
18149 (set_attr "mode" "XF")])
18151 (define_insn "frndintxf2_trunc_i387"
18152 [(set (match_operand:XF 0 "register_operand" "=f")
18153 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18154 UNSPEC_FRNDINT_TRUNC))
18155 (use (match_operand:HI 2 "memory_operand" "m"))
18156 (use (match_operand:HI 3 "memory_operand" "m"))]
18157 "TARGET_USE_FANCY_MATH_387
18158 && flag_unsafe_math_optimizations"
18159 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18160 [(set_attr "type" "frndint")
18161 (set_attr "i387_cw" "trunc")
18162 (set_attr "mode" "XF")])
18164 (define_expand "btruncxf2"
18165 [(use (match_operand:XF 0 "register_operand" ""))
18166 (use (match_operand:XF 1 "register_operand" ""))]
18167 "TARGET_USE_FANCY_MATH_387
18168 && flag_unsafe_math_optimizations"
18170 if (optimize_insn_for_size_p ())
18172 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
18176 (define_expand "btrunc<mode>2"
18177 [(use (match_operand:MODEF 0 "register_operand" ""))
18178 (use (match_operand:MODEF 1 "register_operand" ""))]
18179 "(TARGET_USE_FANCY_MATH_387
18180 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18181 || TARGET_MIX_SSE_I387)
18182 && flag_unsafe_math_optimizations)
18183 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18184 && !flag_trapping_math)"
18186 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18187 && !flag_trapping_math
18188 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18191 emit_insn (gen_sse4_1_round<mode>2
18192 (operands[0], operands[1], GEN_INT (0x03)));
18193 else if (optimize_insn_for_size_p ())
18195 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18196 ix86_expand_trunc (operand0, operand1);
18198 ix86_expand_truncdf_32 (operand0, operand1);
18204 if (optimize_insn_for_size_p ())
18207 op0 = gen_reg_rtx (XFmode);
18208 op1 = gen_reg_rtx (XFmode);
18209 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18210 emit_insn (gen_frndintxf2_trunc (op0, op1));
18212 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18217 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18218 (define_insn_and_split "frndintxf2_mask_pm"
18219 [(set (match_operand:XF 0 "register_operand" "")
18220 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18221 UNSPEC_FRNDINT_MASK_PM))
18222 (clobber (reg:CC FLAGS_REG))]
18223 "TARGET_USE_FANCY_MATH_387
18224 && flag_unsafe_math_optimizations
18225 && can_create_pseudo_p ()"
18230 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18232 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18233 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18235 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18236 operands[2], operands[3]));
18239 [(set_attr "type" "frndint")
18240 (set_attr "i387_cw" "mask_pm")
18241 (set_attr "mode" "XF")])
18243 (define_insn "frndintxf2_mask_pm_i387"
18244 [(set (match_operand:XF 0 "register_operand" "=f")
18245 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18246 UNSPEC_FRNDINT_MASK_PM))
18247 (use (match_operand:HI 2 "memory_operand" "m"))
18248 (use (match_operand:HI 3 "memory_operand" "m"))]
18249 "TARGET_USE_FANCY_MATH_387
18250 && flag_unsafe_math_optimizations"
18251 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18252 [(set_attr "type" "frndint")
18253 (set_attr "i387_cw" "mask_pm")
18254 (set_attr "mode" "XF")])
18256 (define_expand "nearbyintxf2"
18257 [(use (match_operand:XF 0 "register_operand" ""))
18258 (use (match_operand:XF 1 "register_operand" ""))]
18259 "TARGET_USE_FANCY_MATH_387
18260 && flag_unsafe_math_optimizations"
18262 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18267 (define_expand "nearbyint<mode>2"
18268 [(use (match_operand:MODEF 0 "register_operand" ""))
18269 (use (match_operand:MODEF 1 "register_operand" ""))]
18270 "TARGET_USE_FANCY_MATH_387
18271 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18272 || TARGET_MIX_SSE_I387)
18273 && flag_unsafe_math_optimizations"
18275 rtx op0 = gen_reg_rtx (XFmode);
18276 rtx op1 = gen_reg_rtx (XFmode);
18278 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18279 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18281 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18285 (define_insn "fxam<mode>2_i387"
18286 [(set (match_operand:HI 0 "register_operand" "=a")
18288 [(match_operand:X87MODEF 1 "register_operand" "f")]
18290 "TARGET_USE_FANCY_MATH_387"
18291 "fxam\n\tfnstsw\t%0"
18292 [(set_attr "type" "multi")
18293 (set_attr "length" "4")
18294 (set_attr "unit" "i387")
18295 (set_attr "mode" "<MODE>")])
18297 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18298 [(set (match_operand:HI 0 "register_operand" "")
18300 [(match_operand:MODEF 1 "memory_operand" "")]
18302 "TARGET_USE_FANCY_MATH_387
18303 && can_create_pseudo_p ()"
18306 [(set (match_dup 2)(match_dup 1))
18308 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18310 operands[2] = gen_reg_rtx (<MODE>mode);
18312 MEM_VOLATILE_P (operands[1]) = 1;
18314 [(set_attr "type" "multi")
18315 (set_attr "unit" "i387")
18316 (set_attr "mode" "<MODE>")])
18318 (define_expand "isinfxf2"
18319 [(use (match_operand:SI 0 "register_operand" ""))
18320 (use (match_operand:XF 1 "register_operand" ""))]
18321 "TARGET_USE_FANCY_MATH_387
18322 && TARGET_C99_FUNCTIONS"
18324 rtx mask = GEN_INT (0x45);
18325 rtx val = GEN_INT (0x05);
18329 rtx scratch = gen_reg_rtx (HImode);
18330 rtx res = gen_reg_rtx (QImode);
18332 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18334 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18335 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18336 cond = gen_rtx_fmt_ee (EQ, QImode,
18337 gen_rtx_REG (CCmode, FLAGS_REG),
18339 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18340 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18344 (define_expand "isinf<mode>2"
18345 [(use (match_operand:SI 0 "register_operand" ""))
18346 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18347 "TARGET_USE_FANCY_MATH_387
18348 && TARGET_C99_FUNCTIONS
18349 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18351 rtx mask = GEN_INT (0x45);
18352 rtx val = GEN_INT (0x05);
18356 rtx scratch = gen_reg_rtx (HImode);
18357 rtx res = gen_reg_rtx (QImode);
18359 /* Remove excess precision by forcing value through memory. */
18360 if (memory_operand (operands[1], VOIDmode))
18361 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18364 enum ix86_stack_slot slot = (virtuals_instantiated
18367 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18369 emit_move_insn (temp, operands[1]);
18370 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18373 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18374 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18375 cond = gen_rtx_fmt_ee (EQ, QImode,
18376 gen_rtx_REG (CCmode, FLAGS_REG),
18378 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18379 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18383 (define_expand "signbit<mode>2"
18384 [(use (match_operand:SI 0 "register_operand" ""))
18385 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18386 "TARGET_USE_FANCY_MATH_387
18387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18389 rtx mask = GEN_INT (0x0200);
18391 rtx scratch = gen_reg_rtx (HImode);
18393 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18394 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18398 ;; Block operation instructions
18401 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18404 [(set_attr "length" "1")
18405 (set_attr "length_immediate" "0")
18406 (set_attr "modrm" "0")])
18408 (define_expand "movmemsi"
18409 [(use (match_operand:BLK 0 "memory_operand" ""))
18410 (use (match_operand:BLK 1 "memory_operand" ""))
18411 (use (match_operand:SI 2 "nonmemory_operand" ""))
18412 (use (match_operand:SI 3 "const_int_operand" ""))
18413 (use (match_operand:SI 4 "const_int_operand" ""))
18414 (use (match_operand:SI 5 "const_int_operand" ""))]
18417 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18418 operands[4], operands[5]))
18424 (define_expand "movmemdi"
18425 [(use (match_operand:BLK 0 "memory_operand" ""))
18426 (use (match_operand:BLK 1 "memory_operand" ""))
18427 (use (match_operand:DI 2 "nonmemory_operand" ""))
18428 (use (match_operand:DI 3 "const_int_operand" ""))
18429 (use (match_operand:SI 4 "const_int_operand" ""))
18430 (use (match_operand:SI 5 "const_int_operand" ""))]
18433 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18434 operands[4], operands[5]))
18440 ;; Most CPUs don't like single string operations
18441 ;; Handle this case here to simplify previous expander.
18443 (define_expand "strmov"
18444 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18445 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18446 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18447 (clobber (reg:CC FLAGS_REG))])
18448 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18449 (clobber (reg:CC FLAGS_REG))])]
18452 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18454 /* If .md ever supports :P for Pmode, these can be directly
18455 in the pattern above. */
18456 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18457 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18459 /* Can't use this if the user has appropriated esi or edi. */
18460 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18461 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18463 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18464 operands[2], operands[3],
18465 operands[5], operands[6]));
18469 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18472 (define_expand "strmov_singleop"
18473 [(parallel [(set (match_operand 1 "memory_operand" "")
18474 (match_operand 3 "memory_operand" ""))
18475 (set (match_operand 0 "register_operand" "")
18476 (match_operand 4 "" ""))
18477 (set (match_operand 2 "register_operand" "")
18478 (match_operand 5 "" ""))])]
18480 "ix86_current_function_needs_cld = 1;")
18482 (define_insn "*strmovdi_rex_1"
18483 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18484 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18485 (set (match_operand:DI 0 "register_operand" "=D")
18486 (plus:DI (match_dup 2)
18488 (set (match_operand:DI 1 "register_operand" "=S")
18489 (plus:DI (match_dup 3)
18493 [(set_attr "type" "str")
18494 (set_attr "mode" "DI")
18495 (set_attr "memory" "both")])
18497 (define_insn "*strmovsi_1"
18498 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18499 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18500 (set (match_operand:SI 0 "register_operand" "=D")
18501 (plus:SI (match_dup 2)
18503 (set (match_operand:SI 1 "register_operand" "=S")
18504 (plus:SI (match_dup 3)
18508 [(set_attr "type" "str")
18509 (set_attr "mode" "SI")
18510 (set_attr "memory" "both")])
18512 (define_insn "*strmovsi_rex_1"
18513 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18514 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18515 (set (match_operand:DI 0 "register_operand" "=D")
18516 (plus:DI (match_dup 2)
18518 (set (match_operand:DI 1 "register_operand" "=S")
18519 (plus:DI (match_dup 3)
18523 [(set_attr "type" "str")
18524 (set_attr "mode" "SI")
18525 (set_attr "memory" "both")])
18527 (define_insn "*strmovhi_1"
18528 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18529 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18530 (set (match_operand:SI 0 "register_operand" "=D")
18531 (plus:SI (match_dup 2)
18533 (set (match_operand:SI 1 "register_operand" "=S")
18534 (plus:SI (match_dup 3)
18538 [(set_attr "type" "str")
18539 (set_attr "memory" "both")
18540 (set_attr "mode" "HI")])
18542 (define_insn "*strmovhi_rex_1"
18543 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18544 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18545 (set (match_operand:DI 0 "register_operand" "=D")
18546 (plus:DI (match_dup 2)
18548 (set (match_operand:DI 1 "register_operand" "=S")
18549 (plus:DI (match_dup 3)
18553 [(set_attr "type" "str")
18554 (set_attr "memory" "both")
18555 (set_attr "mode" "HI")])
18557 (define_insn "*strmovqi_1"
18558 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18559 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18560 (set (match_operand:SI 0 "register_operand" "=D")
18561 (plus:SI (match_dup 2)
18563 (set (match_operand:SI 1 "register_operand" "=S")
18564 (plus:SI (match_dup 3)
18568 [(set_attr "type" "str")
18569 (set_attr "memory" "both")
18570 (set_attr "mode" "QI")])
18572 (define_insn "*strmovqi_rex_1"
18573 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18574 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18575 (set (match_operand:DI 0 "register_operand" "=D")
18576 (plus:DI (match_dup 2)
18578 (set (match_operand:DI 1 "register_operand" "=S")
18579 (plus:DI (match_dup 3)
18583 [(set_attr "type" "str")
18584 (set_attr "memory" "both")
18585 (set_attr "prefix_rex" "0")
18586 (set_attr "mode" "QI")])
18588 (define_expand "rep_mov"
18589 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18590 (set (match_operand 0 "register_operand" "")
18591 (match_operand 5 "" ""))
18592 (set (match_operand 2 "register_operand" "")
18593 (match_operand 6 "" ""))
18594 (set (match_operand 1 "memory_operand" "")
18595 (match_operand 3 "memory_operand" ""))
18596 (use (match_dup 4))])]
18598 "ix86_current_function_needs_cld = 1;")
18600 (define_insn "*rep_movdi_rex64"
18601 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18602 (set (match_operand:DI 0 "register_operand" "=D")
18603 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18605 (match_operand:DI 3 "register_operand" "0")))
18606 (set (match_operand:DI 1 "register_operand" "=S")
18607 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18608 (match_operand:DI 4 "register_operand" "1")))
18609 (set (mem:BLK (match_dup 3))
18610 (mem:BLK (match_dup 4)))
18611 (use (match_dup 5))]
18614 [(set_attr "type" "str")
18615 (set_attr "prefix_rep" "1")
18616 (set_attr "memory" "both")
18617 (set_attr "mode" "DI")])
18619 (define_insn "*rep_movsi"
18620 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18621 (set (match_operand:SI 0 "register_operand" "=D")
18622 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18624 (match_operand:SI 3 "register_operand" "0")))
18625 (set (match_operand:SI 1 "register_operand" "=S")
18626 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18627 (match_operand:SI 4 "register_operand" "1")))
18628 (set (mem:BLK (match_dup 3))
18629 (mem:BLK (match_dup 4)))
18630 (use (match_dup 5))]
18633 [(set_attr "type" "str")
18634 (set_attr "prefix_rep" "1")
18635 (set_attr "memory" "both")
18636 (set_attr "mode" "SI")])
18638 (define_insn "*rep_movsi_rex64"
18639 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18640 (set (match_operand:DI 0 "register_operand" "=D")
18641 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18643 (match_operand:DI 3 "register_operand" "0")))
18644 (set (match_operand:DI 1 "register_operand" "=S")
18645 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18646 (match_operand:DI 4 "register_operand" "1")))
18647 (set (mem:BLK (match_dup 3))
18648 (mem:BLK (match_dup 4)))
18649 (use (match_dup 5))]
18652 [(set_attr "type" "str")
18653 (set_attr "prefix_rep" "1")
18654 (set_attr "memory" "both")
18655 (set_attr "mode" "SI")])
18657 (define_insn "*rep_movqi"
18658 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18659 (set (match_operand:SI 0 "register_operand" "=D")
18660 (plus:SI (match_operand:SI 3 "register_operand" "0")
18661 (match_operand:SI 5 "register_operand" "2")))
18662 (set (match_operand:SI 1 "register_operand" "=S")
18663 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18664 (set (mem:BLK (match_dup 3))
18665 (mem:BLK (match_dup 4)))
18666 (use (match_dup 5))]
18669 [(set_attr "type" "str")
18670 (set_attr "prefix_rep" "1")
18671 (set_attr "memory" "both")
18672 (set_attr "mode" "SI")])
18674 (define_insn "*rep_movqi_rex64"
18675 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18676 (set (match_operand:DI 0 "register_operand" "=D")
18677 (plus:DI (match_operand:DI 3 "register_operand" "0")
18678 (match_operand:DI 5 "register_operand" "2")))
18679 (set (match_operand:DI 1 "register_operand" "=S")
18680 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18681 (set (mem:BLK (match_dup 3))
18682 (mem:BLK (match_dup 4)))
18683 (use (match_dup 5))]
18686 [(set_attr "type" "str")
18687 (set_attr "prefix_rep" "1")
18688 (set_attr "memory" "both")
18689 (set_attr "mode" "SI")])
18691 (define_expand "setmemsi"
18692 [(use (match_operand:BLK 0 "memory_operand" ""))
18693 (use (match_operand:SI 1 "nonmemory_operand" ""))
18694 (use (match_operand 2 "const_int_operand" ""))
18695 (use (match_operand 3 "const_int_operand" ""))
18696 (use (match_operand:SI 4 "const_int_operand" ""))
18697 (use (match_operand:SI 5 "const_int_operand" ""))]
18700 if (ix86_expand_setmem (operands[0], operands[1],
18701 operands[2], operands[3],
18702 operands[4], operands[5]))
18708 (define_expand "setmemdi"
18709 [(use (match_operand:BLK 0 "memory_operand" ""))
18710 (use (match_operand:DI 1 "nonmemory_operand" ""))
18711 (use (match_operand 2 "const_int_operand" ""))
18712 (use (match_operand 3 "const_int_operand" ""))
18713 (use (match_operand 4 "const_int_operand" ""))
18714 (use (match_operand 5 "const_int_operand" ""))]
18717 if (ix86_expand_setmem (operands[0], operands[1],
18718 operands[2], operands[3],
18719 operands[4], operands[5]))
18725 ;; Most CPUs don't like single string operations
18726 ;; Handle this case here to simplify previous expander.
18728 (define_expand "strset"
18729 [(set (match_operand 1 "memory_operand" "")
18730 (match_operand 2 "register_operand" ""))
18731 (parallel [(set (match_operand 0 "register_operand" "")
18733 (clobber (reg:CC FLAGS_REG))])]
18736 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18737 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18739 /* If .md ever supports :P for Pmode, this can be directly
18740 in the pattern above. */
18741 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18742 GEN_INT (GET_MODE_SIZE (GET_MODE
18744 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18746 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18752 (define_expand "strset_singleop"
18753 [(parallel [(set (match_operand 1 "memory_operand" "")
18754 (match_operand 2 "register_operand" ""))
18755 (set (match_operand 0 "register_operand" "")
18756 (match_operand 3 "" ""))])]
18758 "ix86_current_function_needs_cld = 1;")
18760 (define_insn "*strsetdi_rex_1"
18761 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18762 (match_operand:DI 2 "register_operand" "a"))
18763 (set (match_operand:DI 0 "register_operand" "=D")
18764 (plus:DI (match_dup 1)
18768 [(set_attr "type" "str")
18769 (set_attr "memory" "store")
18770 (set_attr "mode" "DI")])
18772 (define_insn "*strsetsi_1"
18773 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18774 (match_operand:SI 2 "register_operand" "a"))
18775 (set (match_operand:SI 0 "register_operand" "=D")
18776 (plus:SI (match_dup 1)
18780 [(set_attr "type" "str")
18781 (set_attr "memory" "store")
18782 (set_attr "mode" "SI")])
18784 (define_insn "*strsetsi_rex_1"
18785 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18786 (match_operand:SI 2 "register_operand" "a"))
18787 (set (match_operand:DI 0 "register_operand" "=D")
18788 (plus:DI (match_dup 1)
18792 [(set_attr "type" "str")
18793 (set_attr "memory" "store")
18794 (set_attr "mode" "SI")])
18796 (define_insn "*strsethi_1"
18797 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18798 (match_operand:HI 2 "register_operand" "a"))
18799 (set (match_operand:SI 0 "register_operand" "=D")
18800 (plus:SI (match_dup 1)
18804 [(set_attr "type" "str")
18805 (set_attr "memory" "store")
18806 (set_attr "mode" "HI")])
18808 (define_insn "*strsethi_rex_1"
18809 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18810 (match_operand:HI 2 "register_operand" "a"))
18811 (set (match_operand:DI 0 "register_operand" "=D")
18812 (plus:DI (match_dup 1)
18816 [(set_attr "type" "str")
18817 (set_attr "memory" "store")
18818 (set_attr "mode" "HI")])
18820 (define_insn "*strsetqi_1"
18821 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18822 (match_operand:QI 2 "register_operand" "a"))
18823 (set (match_operand:SI 0 "register_operand" "=D")
18824 (plus:SI (match_dup 1)
18828 [(set_attr "type" "str")
18829 (set_attr "memory" "store")
18830 (set_attr "mode" "QI")])
18832 (define_insn "*strsetqi_rex_1"
18833 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18834 (match_operand:QI 2 "register_operand" "a"))
18835 (set (match_operand:DI 0 "register_operand" "=D")
18836 (plus:DI (match_dup 1)
18840 [(set_attr "type" "str")
18841 (set_attr "memory" "store")
18842 (set_attr "prefix_rex" "0")
18843 (set_attr "mode" "QI")])
18845 (define_expand "rep_stos"
18846 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18847 (set (match_operand 0 "register_operand" "")
18848 (match_operand 4 "" ""))
18849 (set (match_operand 2 "memory_operand" "") (const_int 0))
18850 (use (match_operand 3 "register_operand" ""))
18851 (use (match_dup 1))])]
18853 "ix86_current_function_needs_cld = 1;")
18855 (define_insn "*rep_stosdi_rex64"
18856 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18857 (set (match_operand:DI 0 "register_operand" "=D")
18858 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18860 (match_operand:DI 3 "register_operand" "0")))
18861 (set (mem:BLK (match_dup 3))
18863 (use (match_operand:DI 2 "register_operand" "a"))
18864 (use (match_dup 4))]
18867 [(set_attr "type" "str")
18868 (set_attr "prefix_rep" "1")
18869 (set_attr "memory" "store")
18870 (set_attr "mode" "DI")])
18872 (define_insn "*rep_stossi"
18873 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18874 (set (match_operand:SI 0 "register_operand" "=D")
18875 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18877 (match_operand:SI 3 "register_operand" "0")))
18878 (set (mem:BLK (match_dup 3))
18880 (use (match_operand:SI 2 "register_operand" "a"))
18881 (use (match_dup 4))]
18884 [(set_attr "type" "str")
18885 (set_attr "prefix_rep" "1")
18886 (set_attr "memory" "store")
18887 (set_attr "mode" "SI")])
18889 (define_insn "*rep_stossi_rex64"
18890 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18891 (set (match_operand:DI 0 "register_operand" "=D")
18892 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18894 (match_operand:DI 3 "register_operand" "0")))
18895 (set (mem:BLK (match_dup 3))
18897 (use (match_operand:SI 2 "register_operand" "a"))
18898 (use (match_dup 4))]
18901 [(set_attr "type" "str")
18902 (set_attr "prefix_rep" "1")
18903 (set_attr "memory" "store")
18904 (set_attr "mode" "SI")])
18906 (define_insn "*rep_stosqi"
18907 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18908 (set (match_operand:SI 0 "register_operand" "=D")
18909 (plus:SI (match_operand:SI 3 "register_operand" "0")
18910 (match_operand:SI 4 "register_operand" "1")))
18911 (set (mem:BLK (match_dup 3))
18913 (use (match_operand:QI 2 "register_operand" "a"))
18914 (use (match_dup 4))]
18917 [(set_attr "type" "str")
18918 (set_attr "prefix_rep" "1")
18919 (set_attr "memory" "store")
18920 (set_attr "mode" "QI")])
18922 (define_insn "*rep_stosqi_rex64"
18923 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18924 (set (match_operand:DI 0 "register_operand" "=D")
18925 (plus:DI (match_operand:DI 3 "register_operand" "0")
18926 (match_operand:DI 4 "register_operand" "1")))
18927 (set (mem:BLK (match_dup 3))
18929 (use (match_operand:QI 2 "register_operand" "a"))
18930 (use (match_dup 4))]
18933 [(set_attr "type" "str")
18934 (set_attr "prefix_rep" "1")
18935 (set_attr "memory" "store")
18936 (set_attr "prefix_rex" "0")
18937 (set_attr "mode" "QI")])
18939 (define_expand "cmpstrnsi"
18940 [(set (match_operand:SI 0 "register_operand" "")
18941 (compare:SI (match_operand:BLK 1 "general_operand" "")
18942 (match_operand:BLK 2 "general_operand" "")))
18943 (use (match_operand 3 "general_operand" ""))
18944 (use (match_operand 4 "immediate_operand" ""))]
18947 rtx addr1, addr2, out, outlow, count, countreg, align;
18949 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18952 /* Can't use this if the user has appropriated esi or edi. */
18953 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18958 out = gen_reg_rtx (SImode);
18960 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18961 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18962 if (addr1 != XEXP (operands[1], 0))
18963 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18964 if (addr2 != XEXP (operands[2], 0))
18965 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18967 count = operands[3];
18968 countreg = ix86_zero_extend_to_Pmode (count);
18970 /* %%% Iff we are testing strict equality, we can use known alignment
18971 to good advantage. This may be possible with combine, particularly
18972 once cc0 is dead. */
18973 align = operands[4];
18975 if (CONST_INT_P (count))
18977 if (INTVAL (count) == 0)
18979 emit_move_insn (operands[0], const0_rtx);
18982 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18983 operands[1], operands[2]));
18987 rtx (*cmp_insn)(rtx, rtx);
18990 cmp_insn = gen_cmpdi_1;
18992 cmp_insn = gen_cmpsi_1;
18993 emit_insn (cmp_insn (countreg, countreg));
18994 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18995 operands[1], operands[2]));
18998 outlow = gen_lowpart (QImode, out);
18999 emit_insn (gen_cmpintqi (outlow));
19000 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
19002 if (operands[0] != out)
19003 emit_move_insn (operands[0], out);
19008 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
19010 (define_expand "cmpintqi"
19011 [(set (match_dup 1)
19012 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19014 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19015 (parallel [(set (match_operand:QI 0 "register_operand" "")
19016 (minus:QI (match_dup 1)
19018 (clobber (reg:CC FLAGS_REG))])]
19020 "operands[1] = gen_reg_rtx (QImode);
19021 operands[2] = gen_reg_rtx (QImode);")
19023 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
19024 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
19026 (define_expand "cmpstrnqi_nz_1"
19027 [(parallel [(set (reg:CC FLAGS_REG)
19028 (compare:CC (match_operand 4 "memory_operand" "")
19029 (match_operand 5 "memory_operand" "")))
19030 (use (match_operand 2 "register_operand" ""))
19031 (use (match_operand:SI 3 "immediate_operand" ""))
19032 (clobber (match_operand 0 "register_operand" ""))
19033 (clobber (match_operand 1 "register_operand" ""))
19034 (clobber (match_dup 2))])]
19036 "ix86_current_function_needs_cld = 1;")
19038 (define_insn "*cmpstrnqi_nz_1"
19039 [(set (reg:CC FLAGS_REG)
19040 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19041 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
19042 (use (match_operand:SI 6 "register_operand" "2"))
19043 (use (match_operand:SI 3 "immediate_operand" "i"))
19044 (clobber (match_operand:SI 0 "register_operand" "=S"))
19045 (clobber (match_operand:SI 1 "register_operand" "=D"))
19046 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19049 [(set_attr "type" "str")
19050 (set_attr "mode" "QI")
19051 (set_attr "prefix_rep" "1")])
19053 (define_insn "*cmpstrnqi_nz_rex_1"
19054 [(set (reg:CC FLAGS_REG)
19055 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19056 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
19057 (use (match_operand:DI 6 "register_operand" "2"))
19058 (use (match_operand:SI 3 "immediate_operand" "i"))
19059 (clobber (match_operand:DI 0 "register_operand" "=S"))
19060 (clobber (match_operand:DI 1 "register_operand" "=D"))
19061 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19064 [(set_attr "type" "str")
19065 (set_attr "mode" "QI")
19066 (set_attr "prefix_rex" "0")
19067 (set_attr "prefix_rep" "1")])
19069 ;; The same, but the count is not known to not be zero.
19071 (define_expand "cmpstrnqi_1"
19072 [(parallel [(set (reg:CC FLAGS_REG)
19073 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
19075 (compare:CC (match_operand 4 "memory_operand" "")
19076 (match_operand 5 "memory_operand" ""))
19078 (use (match_operand:SI 3 "immediate_operand" ""))
19079 (use (reg:CC FLAGS_REG))
19080 (clobber (match_operand 0 "register_operand" ""))
19081 (clobber (match_operand 1 "register_operand" ""))
19082 (clobber (match_dup 2))])]
19084 "ix86_current_function_needs_cld = 1;")
19086 (define_insn "*cmpstrnqi_1"
19087 [(set (reg:CC FLAGS_REG)
19088 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
19090 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
19091 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
19093 (use (match_operand:SI 3 "immediate_operand" "i"))
19094 (use (reg:CC FLAGS_REG))
19095 (clobber (match_operand:SI 0 "register_operand" "=S"))
19096 (clobber (match_operand:SI 1 "register_operand" "=D"))
19097 (clobber (match_operand:SI 2 "register_operand" "=c"))]
19100 [(set_attr "type" "str")
19101 (set_attr "mode" "QI")
19102 (set_attr "prefix_rep" "1")])
19104 (define_insn "*cmpstrnqi_rex_1"
19105 [(set (reg:CC FLAGS_REG)
19106 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
19108 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
19109 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
19111 (use (match_operand:SI 3 "immediate_operand" "i"))
19112 (use (reg:CC FLAGS_REG))
19113 (clobber (match_operand:DI 0 "register_operand" "=S"))
19114 (clobber (match_operand:DI 1 "register_operand" "=D"))
19115 (clobber (match_operand:DI 2 "register_operand" "=c"))]
19118 [(set_attr "type" "str")
19119 (set_attr "mode" "QI")
19120 (set_attr "prefix_rex" "0")
19121 (set_attr "prefix_rep" "1")])
19123 (define_expand "strlensi"
19124 [(set (match_operand:SI 0 "register_operand" "")
19125 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
19126 (match_operand:QI 2 "immediate_operand" "")
19127 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19130 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19136 (define_expand "strlendi"
19137 [(set (match_operand:DI 0 "register_operand" "")
19138 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
19139 (match_operand:QI 2 "immediate_operand" "")
19140 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
19143 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
19149 (define_expand "strlenqi_1"
19150 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
19151 (clobber (match_operand 1 "register_operand" ""))
19152 (clobber (reg:CC FLAGS_REG))])]
19154 "ix86_current_function_needs_cld = 1;")
19156 (define_insn "*strlenqi_1"
19157 [(set (match_operand:SI 0 "register_operand" "=&c")
19158 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
19159 (match_operand:QI 2 "register_operand" "a")
19160 (match_operand:SI 3 "immediate_operand" "i")
19161 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
19162 (clobber (match_operand:SI 1 "register_operand" "=D"))
19163 (clobber (reg:CC FLAGS_REG))]
19166 [(set_attr "type" "str")
19167 (set_attr "mode" "QI")
19168 (set_attr "prefix_rep" "1")])
19170 (define_insn "*strlenqi_rex_1"
19171 [(set (match_operand:DI 0 "register_operand" "=&c")
19172 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
19173 (match_operand:QI 2 "register_operand" "a")
19174 (match_operand:DI 3 "immediate_operand" "i")
19175 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
19176 (clobber (match_operand:DI 1 "register_operand" "=D"))
19177 (clobber (reg:CC FLAGS_REG))]
19180 [(set_attr "type" "str")
19181 (set_attr "mode" "QI")
19182 (set_attr "prefix_rex" "0")
19183 (set_attr "prefix_rep" "1")])
19185 ;; Peephole optimizations to clean up after cmpstrn*. This should be
19186 ;; handled in combine, but it is not currently up to the task.
19187 ;; When used for their truth value, the cmpstrn* expanders generate
19196 ;; The intermediate three instructions are unnecessary.
19198 ;; This one handles cmpstrn*_nz_1...
19201 (set (reg:CC FLAGS_REG)
19202 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19203 (mem:BLK (match_operand 5 "register_operand" ""))))
19204 (use (match_operand 6 "register_operand" ""))
19205 (use (match_operand:SI 3 "immediate_operand" ""))
19206 (clobber (match_operand 0 "register_operand" ""))
19207 (clobber (match_operand 1 "register_operand" ""))
19208 (clobber (match_operand 2 "register_operand" ""))])
19209 (set (match_operand:QI 7 "register_operand" "")
19210 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19211 (set (match_operand:QI 8 "register_operand" "")
19212 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19213 (set (reg FLAGS_REG)
19214 (compare (match_dup 7) (match_dup 8)))
19216 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19218 (set (reg:CC FLAGS_REG)
19219 (compare:CC (mem:BLK (match_dup 4))
19220 (mem:BLK (match_dup 5))))
19221 (use (match_dup 6))
19222 (use (match_dup 3))
19223 (clobber (match_dup 0))
19224 (clobber (match_dup 1))
19225 (clobber (match_dup 2))])]
19228 ;; ...and this one handles cmpstrn*_1.
19231 (set (reg:CC FLAGS_REG)
19232 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19234 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19235 (mem:BLK (match_operand 5 "register_operand" "")))
19237 (use (match_operand:SI 3 "immediate_operand" ""))
19238 (use (reg:CC FLAGS_REG))
19239 (clobber (match_operand 0 "register_operand" ""))
19240 (clobber (match_operand 1 "register_operand" ""))
19241 (clobber (match_operand 2 "register_operand" ""))])
19242 (set (match_operand:QI 7 "register_operand" "")
19243 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19244 (set (match_operand:QI 8 "register_operand" "")
19245 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19246 (set (reg FLAGS_REG)
19247 (compare (match_dup 7) (match_dup 8)))
19249 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19251 (set (reg:CC FLAGS_REG)
19252 (if_then_else:CC (ne (match_dup 6)
19254 (compare:CC (mem:BLK (match_dup 4))
19255 (mem:BLK (match_dup 5)))
19257 (use (match_dup 3))
19258 (use (reg:CC FLAGS_REG))
19259 (clobber (match_dup 0))
19260 (clobber (match_dup 1))
19261 (clobber (match_dup 2))])]
19266 ;; Conditional move instructions.
19268 (define_expand "mov<mode>cc"
19269 [(set (match_operand:SWIM 0 "register_operand" "")
19270 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
19271 (match_operand:SWIM 2 "general_operand" "")
19272 (match_operand:SWIM 3 "general_operand" "")))]
19274 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19276 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19277 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19278 ;; So just document what we're doing explicitly.
19280 (define_insn "x86_mov<mode>cc_0_m1"
19281 [(set (match_operand:SWI48 0 "register_operand" "=r")
19282 (if_then_else:SWI48 (match_operand 1 "ix86_carry_flag_operator" "")
19285 (clobber (reg:CC FLAGS_REG))]
19287 "sbb{<imodesuffix>}\t%0, %0"
19288 ; Since we don't have the proper number of operands for an alu insn,
19289 ; fill in all the blanks.
19290 [(set_attr "type" "alu")
19291 (set_attr "use_carry" "1")
19292 (set_attr "pent_pair" "pu")
19293 (set_attr "memory" "none")
19294 (set_attr "imm_disp" "false")
19295 (set_attr "mode" "<MODE>")
19296 (set_attr "length_immediate" "0")])
19298 (define_insn "*x86_mov<mode>cc_0_m1_se"
19299 [(set (match_operand:SWI48 0 "register_operand" "=r")
19300 (sign_extract:SWI48 (match_operand 1 "ix86_carry_flag_operator" "")
19303 (clobber (reg:CC FLAGS_REG))]
19305 "sbb{<imodesuffix>}\t%0, %0"
19306 [(set_attr "type" "alu")
19307 (set_attr "use_carry" "1")
19308 (set_attr "pent_pair" "pu")
19309 (set_attr "memory" "none")
19310 (set_attr "imm_disp" "false")
19311 (set_attr "mode" "<MODE>")
19312 (set_attr "length_immediate" "0")])
19314 (define_insn "*x86_mov<mode>cc_0_m1_neg"
19315 [(set (match_operand:SWI48 0 "register_operand" "=r")
19316 (neg:SWI48 (match_operand 1 "ix86_carry_flag_operator" "")))]
19318 "sbb{<imodesuffix>}\t%0, %0"
19319 [(set_attr "type" "alu")
19320 (set_attr "use_carry" "1")
19321 (set_attr "pent_pair" "pu")
19322 (set_attr "memory" "none")
19323 (set_attr "imm_disp" "false")
19324 (set_attr "mode" "<MODE>")
19325 (set_attr "length_immediate" "0")])
19327 (define_insn "*mov<mode>cc_noc"
19328 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
19329 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
19330 [(reg FLAGS_REG) (const_int 0)])
19331 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
19332 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
19333 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19335 cmov%O2%C1\t{%2, %0|%0, %2}
19336 cmov%O2%c1\t{%3, %0|%0, %3}"
19337 [(set_attr "type" "icmov")
19338 (set_attr "mode" "<MODE>")])
19340 (define_insn_and_split "*movqicc_noc"
19341 [(set (match_operand:QI 0 "register_operand" "=r,r")
19342 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19343 [(match_operand 4 "flags_reg_operand" "")
19345 (match_operand:QI 2 "register_operand" "r,0")
19346 (match_operand:QI 3 "register_operand" "0,r")))]
19347 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19349 "&& reload_completed"
19350 [(set (match_dup 0)
19351 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19354 "operands[0] = gen_lowpart (SImode, operands[0]);
19355 operands[2] = gen_lowpart (SImode, operands[2]);
19356 operands[3] = gen_lowpart (SImode, operands[3]);"
19357 [(set_attr "type" "icmov")
19358 (set_attr "mode" "SI")])
19360 (define_expand "mov<mode>cc"
19361 [(set (match_operand:X87MODEF 0 "register_operand" "")
19362 (if_then_else:X87MODEF
19363 (match_operand 1 "ix86_fp_comparison_operator" "")
19364 (match_operand:X87MODEF 2 "register_operand" "")
19365 (match_operand:X87MODEF 3 "register_operand" "")))]
19366 "(TARGET_80387 && TARGET_CMOVE)
19367 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19368 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19370 (define_insn "*movsfcc_1_387"
19371 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19372 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19373 [(reg FLAGS_REG) (const_int 0)])
19374 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19375 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19376 "TARGET_80387 && TARGET_CMOVE
19377 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19379 fcmov%F1\t{%2, %0|%0, %2}
19380 fcmov%f1\t{%3, %0|%0, %3}
19381 cmov%O2%C1\t{%2, %0|%0, %2}
19382 cmov%O2%c1\t{%3, %0|%0, %3}"
19383 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19384 (set_attr "mode" "SF,SF,SI,SI")])
19386 (define_insn "*movdfcc_1"
19387 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19388 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19389 [(reg FLAGS_REG) (const_int 0)])
19390 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19391 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19392 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19393 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19395 fcmov%F1\t{%2, %0|%0, %2}
19396 fcmov%f1\t{%3, %0|%0, %3}
19399 [(set_attr "type" "fcmov,fcmov,multi,multi")
19400 (set_attr "mode" "DF")])
19402 (define_insn "*movdfcc_1_rex64"
19403 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19404 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19405 [(reg FLAGS_REG) (const_int 0)])
19406 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19407 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19408 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19409 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19411 fcmov%F1\t{%2, %0|%0, %2}
19412 fcmov%f1\t{%3, %0|%0, %3}
19413 cmov%O2%C1\t{%2, %0|%0, %2}
19414 cmov%O2%c1\t{%3, %0|%0, %3}"
19415 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19416 (set_attr "mode" "DF")])
19419 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19420 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19421 [(match_operand 4 "flags_reg_operand" "")
19423 (match_operand:DF 2 "nonimmediate_operand" "")
19424 (match_operand:DF 3 "nonimmediate_operand" "")))]
19425 "!TARGET_64BIT && reload_completed"
19426 [(set (match_dup 2)
19427 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19431 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19434 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19435 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19437 (define_insn "*movxfcc_1"
19438 [(set (match_operand:XF 0 "register_operand" "=f,f")
19439 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19440 [(reg FLAGS_REG) (const_int 0)])
19441 (match_operand:XF 2 "register_operand" "f,0")
19442 (match_operand:XF 3 "register_operand" "0,f")))]
19443 "TARGET_80387 && TARGET_CMOVE"
19445 fcmov%F1\t{%2, %0|%0, %2}
19446 fcmov%f1\t{%3, %0|%0, %3}"
19447 [(set_attr "type" "fcmov")
19448 (set_attr "mode" "XF")])
19450 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
19451 ;; the scalar versions to have only XMM registers as operands.
19453 ;; XOP conditional move
19454 (define_insn "*xop_pcmov_<mode>"
19455 [(set (match_operand:MODEF 0 "register_operand" "=x")
19456 (if_then_else:MODEF
19457 (match_operand:MODEF 1 "register_operand" "x")
19458 (match_operand:MODEF 2 "register_operand" "x")
19459 (match_operand:MODEF 3 "register_operand" "x")))]
19460 "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)"
19461 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19462 [(set_attr "type" "sse4arg")])
19464 ;; These versions of the min/max patterns are intentionally ignorant of
19465 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19466 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19467 ;; are undefined in this condition, we're certain this is correct.
19469 (define_insn "*avx_<code><mode>3"
19470 [(set (match_operand:MODEF 0 "register_operand" "=x")
19472 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19473 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19474 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19475 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19476 [(set_attr "type" "sseadd")
19477 (set_attr "prefix" "vex")
19478 (set_attr "mode" "<MODE>")])
19480 (define_insn "<code><mode>3"
19481 [(set (match_operand:MODEF 0 "register_operand" "=x")
19483 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19484 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19485 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19486 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19487 [(set_attr "type" "sseadd")
19488 (set_attr "mode" "<MODE>")])
19490 ;; These versions of the min/max patterns implement exactly the operations
19491 ;; min = (op1 < op2 ? op1 : op2)
19492 ;; max = (!(op1 < op2) ? op1 : op2)
19493 ;; Their operands are not commutative, and thus they may be used in the
19494 ;; presence of -0.0 and NaN.
19496 (define_insn "*avx_ieee_smin<mode>3"
19497 [(set (match_operand:MODEF 0 "register_operand" "=x")
19499 [(match_operand:MODEF 1 "register_operand" "x")
19500 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19502 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19503 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19504 [(set_attr "type" "sseadd")
19505 (set_attr "prefix" "vex")
19506 (set_attr "mode" "<MODE>")])
19508 (define_insn "*ieee_smin<mode>3"
19509 [(set (match_operand:MODEF 0 "register_operand" "=x")
19511 [(match_operand:MODEF 1 "register_operand" "0")
19512 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19514 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19515 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19516 [(set_attr "type" "sseadd")
19517 (set_attr "mode" "<MODE>")])
19519 (define_insn "*avx_ieee_smax<mode>3"
19520 [(set (match_operand:MODEF 0 "register_operand" "=x")
19522 [(match_operand:MODEF 1 "register_operand" "0")
19523 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19525 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19526 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19527 [(set_attr "type" "sseadd")
19528 (set_attr "prefix" "vex")
19529 (set_attr "mode" "<MODE>")])
19531 (define_insn "*ieee_smax<mode>3"
19532 [(set (match_operand:MODEF 0 "register_operand" "=x")
19534 [(match_operand:MODEF 1 "register_operand" "0")
19535 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19537 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19538 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19539 [(set_attr "type" "sseadd")
19540 (set_attr "mode" "<MODE>")])
19542 ;; Make two stack loads independent:
19544 ;; fld %st(0) -> fld bb
19545 ;; fmul bb fmul %st(1), %st
19547 ;; Actually we only match the last two instructions for simplicity.
19549 [(set (match_operand 0 "fp_register_operand" "")
19550 (match_operand 1 "fp_register_operand" ""))
19552 (match_operator 2 "binary_fp_operator"
19554 (match_operand 3 "memory_operand" "")]))]
19555 "REGNO (operands[0]) != REGNO (operands[1])"
19556 [(set (match_dup 0) (match_dup 3))
19557 (set (match_dup 0) (match_dup 4))]
19559 ;; The % modifier is not operational anymore in peephole2's, so we have to
19560 ;; swap the operands manually in the case of addition and multiplication.
19561 "if (COMMUTATIVE_ARITH_P (operands[2]))
19562 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19563 operands[0], operands[1]);
19565 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19566 operands[1], operands[0]);")
19568 ;; Conditional addition patterns
19569 (define_expand "add<mode>cc"
19570 [(match_operand:SWI 0 "register_operand" "")
19571 (match_operand 1 "comparison_operator" "")
19572 (match_operand:SWI 2 "register_operand" "")
19573 (match_operand:SWI 3 "const_int_operand" "")]
19575 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19578 ;; Misc patterns (?)
19580 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19581 ;; Otherwise there will be nothing to keep
19583 ;; [(set (reg ebp) (reg esp))]
19584 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19585 ;; (clobber (eflags)]
19586 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19588 ;; in proper program order.
19589 (define_insn "pro_epilogue_adjust_stack_1"
19590 [(set (match_operand:SI 0 "register_operand" "=r,r")
19591 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19592 (match_operand:SI 2 "immediate_operand" "i,i")))
19593 (clobber (reg:CC FLAGS_REG))
19594 (clobber (mem:BLK (scratch)))]
19597 switch (get_attr_type (insn))
19600 return "mov{l}\t{%1, %0|%0, %1}";
19603 if (CONST_INT_P (operands[2])
19604 && (INTVAL (operands[2]) == 128
19605 || (INTVAL (operands[2]) < 0
19606 && INTVAL (operands[2]) != -128)))
19608 operands[2] = GEN_INT (-INTVAL (operands[2]));
19609 return "sub{l}\t{%2, %0|%0, %2}";
19611 return "add{l}\t{%2, %0|%0, %2}";
19614 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19615 return "lea{l}\t{%a2, %0|%0, %a2}";
19618 gcc_unreachable ();
19621 [(set (attr "type")
19622 (cond [(and (eq_attr "alternative" "0")
19623 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19624 (const_string "alu")
19625 (match_operand:SI 2 "const0_operand" "")
19626 (const_string "imov")
19628 (const_string "lea")))
19629 (set (attr "length_immediate")
19630 (cond [(eq_attr "type" "imov")
19632 (and (eq_attr "type" "alu")
19633 (match_operand 2 "const128_operand" ""))
19636 (const_string "*")))
19637 (set_attr "mode" "SI")])
19639 (define_insn "pro_epilogue_adjust_stack_rex64"
19640 [(set (match_operand:DI 0 "register_operand" "=r,r")
19641 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19642 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19643 (clobber (reg:CC FLAGS_REG))
19644 (clobber (mem:BLK (scratch)))]
19647 switch (get_attr_type (insn))
19650 return "mov{q}\t{%1, %0|%0, %1}";
19653 if (CONST_INT_P (operands[2])
19654 /* Avoid overflows. */
19655 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19656 && (INTVAL (operands[2]) == 128
19657 || (INTVAL (operands[2]) < 0
19658 && INTVAL (operands[2]) != -128)))
19660 operands[2] = GEN_INT (-INTVAL (operands[2]));
19661 return "sub{q}\t{%2, %0|%0, %2}";
19663 return "add{q}\t{%2, %0|%0, %2}";
19666 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19667 return "lea{q}\t{%a2, %0|%0, %a2}";
19670 gcc_unreachable ();
19673 [(set (attr "type")
19674 (cond [(and (eq_attr "alternative" "0")
19675 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19676 (const_string "alu")
19677 (match_operand:DI 2 "const0_operand" "")
19678 (const_string "imov")
19680 (const_string "lea")))
19681 (set (attr "length_immediate")
19682 (cond [(eq_attr "type" "imov")
19684 (and (eq_attr "type" "alu")
19685 (match_operand 2 "const128_operand" ""))
19688 (const_string "*")))
19689 (set_attr "mode" "DI")])
19691 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19692 [(set (match_operand:DI 0 "register_operand" "=r,r")
19693 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19694 (match_operand:DI 3 "immediate_operand" "i,i")))
19695 (use (match_operand:DI 2 "register_operand" "r,r"))
19696 (clobber (reg:CC FLAGS_REG))
19697 (clobber (mem:BLK (scratch)))]
19700 switch (get_attr_type (insn))
19703 return "add{q}\t{%2, %0|%0, %2}";
19706 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19707 return "lea{q}\t{%a2, %0|%0, %a2}";
19710 gcc_unreachable ();
19713 [(set_attr "type" "alu,lea")
19714 (set_attr "mode" "DI")])
19716 (define_insn "allocate_stack_worker_32"
19717 [(set (match_operand:SI 0 "register_operand" "=a")
19718 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
19719 UNSPECV_STACK_PROBE))
19720 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
19721 (clobber (reg:CC FLAGS_REG))]
19722 "!TARGET_64BIT && TARGET_STACK_PROBE"
19724 [(set_attr "type" "multi")
19725 (set_attr "length" "5")])
19727 (define_insn "allocate_stack_worker_64"
19728 [(set (match_operand:DI 0 "register_operand" "=a")
19729 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
19730 UNSPECV_STACK_PROBE))
19731 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
19732 (clobber (reg:DI R10_REG))
19733 (clobber (reg:DI R11_REG))
19734 (clobber (reg:CC FLAGS_REG))]
19735 "TARGET_64BIT && TARGET_STACK_PROBE"
19737 [(set_attr "type" "multi")
19738 (set_attr "length" "5")])
19740 (define_expand "allocate_stack"
19741 [(match_operand 0 "register_operand" "")
19742 (match_operand 1 "general_operand" "")]
19743 "TARGET_STACK_PROBE"
19747 #ifndef CHECK_STACK_LIMIT
19748 #define CHECK_STACK_LIMIT 0
19751 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19752 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19754 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19755 stack_pointer_rtx, 0, OPTAB_DIRECT);
19756 if (x != stack_pointer_rtx)
19757 emit_move_insn (stack_pointer_rtx, x);
19761 x = copy_to_mode_reg (Pmode, operands[1]);
19763 x = gen_allocate_stack_worker_64 (x, x);
19765 x = gen_allocate_stack_worker_32 (x, x);
19769 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19773 ;; Use IOR for stack probes, this is shorter.
19774 (define_expand "probe_stack"
19775 [(match_operand 0 "memory_operand" "")]
19778 if (GET_MODE (operands[0]) == DImode)
19779 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
19781 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
19785 (define_expand "builtin_setjmp_receiver"
19786 [(label_ref (match_operand 0 "" ""))]
19787 "!TARGET_64BIT && flag_pic"
19793 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19794 rtx label_rtx = gen_label_rtx ();
19795 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19796 xops[0] = xops[1] = picreg;
19797 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19798 ix86_expand_binary_operator (MINUS, SImode, xops);
19802 emit_insn (gen_set_got (pic_offset_table_rtx));
19806 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19809 [(set (match_operand 0 "register_operand" "")
19810 (match_operator 3 "promotable_binary_operator"
19811 [(match_operand 1 "register_operand" "")
19812 (match_operand 2 "aligned_operand" "")]))
19813 (clobber (reg:CC FLAGS_REG))]
19814 "! TARGET_PARTIAL_REG_STALL && reload_completed
19815 && ((GET_MODE (operands[0]) == HImode
19816 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19817 /* ??? next two lines just !satisfies_constraint_K (...) */
19818 || !CONST_INT_P (operands[2])
19819 || satisfies_constraint_K (operands[2])))
19820 || (GET_MODE (operands[0]) == QImode
19821 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19822 [(parallel [(set (match_dup 0)
19823 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19824 (clobber (reg:CC FLAGS_REG))])]
19825 "operands[0] = gen_lowpart (SImode, operands[0]);
19826 operands[1] = gen_lowpart (SImode, operands[1]);
19827 if (GET_CODE (operands[3]) != ASHIFT)
19828 operands[2] = gen_lowpart (SImode, operands[2]);
19829 PUT_MODE (operands[3], SImode);")
19831 ; Promote the QImode tests, as i386 has encoding of the AND
19832 ; instruction with 32-bit sign-extended immediate and thus the
19833 ; instruction size is unchanged, except in the %eax case for
19834 ; which it is increased by one byte, hence the ! optimize_size.
19836 [(set (match_operand 0 "flags_reg_operand" "")
19837 (match_operator 2 "compare_operator"
19838 [(and (match_operand 3 "aligned_operand" "")
19839 (match_operand 4 "const_int_operand" ""))
19841 (set (match_operand 1 "register_operand" "")
19842 (and (match_dup 3) (match_dup 4)))]
19843 "! TARGET_PARTIAL_REG_STALL && reload_completed
19844 && optimize_insn_for_speed_p ()
19845 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19846 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19847 /* Ensure that the operand will remain sign-extended immediate. */
19848 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19849 [(parallel [(set (match_dup 0)
19850 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19853 (and:SI (match_dup 3) (match_dup 4)))])]
19856 = gen_int_mode (INTVAL (operands[4])
19857 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19858 operands[1] = gen_lowpart (SImode, operands[1]);
19859 operands[3] = gen_lowpart (SImode, operands[3]);
19862 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19863 ; the TEST instruction with 32-bit sign-extended immediate and thus
19864 ; the instruction size would at least double, which is not what we
19865 ; want even with ! optimize_size.
19867 [(set (match_operand 0 "flags_reg_operand" "")
19868 (match_operator 1 "compare_operator"
19869 [(and (match_operand:HI 2 "aligned_operand" "")
19870 (match_operand:HI 3 "const_int_operand" ""))
19872 "! TARGET_PARTIAL_REG_STALL && reload_completed
19873 && ! TARGET_FAST_PREFIX
19874 && optimize_insn_for_speed_p ()
19875 /* Ensure that the operand will remain sign-extended immediate. */
19876 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19877 [(set (match_dup 0)
19878 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19882 = gen_int_mode (INTVAL (operands[3])
19883 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19884 operands[2] = gen_lowpart (SImode, operands[2]);
19888 [(set (match_operand 0 "register_operand" "")
19889 (neg (match_operand 1 "register_operand" "")))
19890 (clobber (reg:CC FLAGS_REG))]
19891 "! TARGET_PARTIAL_REG_STALL && reload_completed
19892 && (GET_MODE (operands[0]) == HImode
19893 || (GET_MODE (operands[0]) == QImode
19894 && (TARGET_PROMOTE_QImode
19895 || optimize_insn_for_size_p ())))"
19896 [(parallel [(set (match_dup 0)
19897 (neg:SI (match_dup 1)))
19898 (clobber (reg:CC FLAGS_REG))])]
19899 "operands[0] = gen_lowpart (SImode, operands[0]);
19900 operands[1] = gen_lowpart (SImode, operands[1]);")
19903 [(set (match_operand 0 "register_operand" "")
19904 (not (match_operand 1 "register_operand" "")))]
19905 "! TARGET_PARTIAL_REG_STALL && reload_completed
19906 && (GET_MODE (operands[0]) == HImode
19907 || (GET_MODE (operands[0]) == QImode
19908 && (TARGET_PROMOTE_QImode
19909 || optimize_insn_for_size_p ())))"
19910 [(set (match_dup 0)
19911 (not:SI (match_dup 1)))]
19912 "operands[0] = gen_lowpart (SImode, operands[0]);
19913 operands[1] = gen_lowpart (SImode, operands[1]);")
19916 [(set (match_operand 0 "register_operand" "")
19917 (if_then_else (match_operator 1 "comparison_operator"
19918 [(reg FLAGS_REG) (const_int 0)])
19919 (match_operand 2 "register_operand" "")
19920 (match_operand 3 "register_operand" "")))]
19921 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19922 && (GET_MODE (operands[0]) == HImode
19923 || (GET_MODE (operands[0]) == QImode
19924 && (TARGET_PROMOTE_QImode
19925 || optimize_insn_for_size_p ())))"
19926 [(set (match_dup 0)
19927 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19928 "operands[0] = gen_lowpart (SImode, operands[0]);
19929 operands[2] = gen_lowpart (SImode, operands[2]);
19930 operands[3] = gen_lowpart (SImode, operands[3]);")
19933 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19934 ;; transform a complex memory operation into two memory to register operations.
19936 ;; Don't push memory operands
19938 [(set (match_operand:SI 0 "push_operand" "")
19939 (match_operand:SI 1 "memory_operand" ""))
19940 (match_scratch:SI 2 "r")]
19941 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19942 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19943 [(set (match_dup 2) (match_dup 1))
19944 (set (match_dup 0) (match_dup 2))]
19948 [(set (match_operand:DI 0 "push_operand" "")
19949 (match_operand:DI 1 "memory_operand" ""))
19950 (match_scratch:DI 2 "r")]
19951 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19952 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19953 [(set (match_dup 2) (match_dup 1))
19954 (set (match_dup 0) (match_dup 2))]
19957 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19960 [(set (match_operand:SF 0 "push_operand" "")
19961 (match_operand:SF 1 "memory_operand" ""))
19962 (match_scratch:SF 2 "r")]
19963 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19964 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19965 [(set (match_dup 2) (match_dup 1))
19966 (set (match_dup 0) (match_dup 2))]
19970 [(set (match_operand:HI 0 "push_operand" "")
19971 (match_operand:HI 1 "memory_operand" ""))
19972 (match_scratch:HI 2 "r")]
19973 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19974 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19975 [(set (match_dup 2) (match_dup 1))
19976 (set (match_dup 0) (match_dup 2))]
19980 [(set (match_operand:QI 0 "push_operand" "")
19981 (match_operand:QI 1 "memory_operand" ""))
19982 (match_scratch:QI 2 "q")]
19983 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19984 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19985 [(set (match_dup 2) (match_dup 1))
19986 (set (match_dup 0) (match_dup 2))]
19989 ;; Don't move an immediate directly to memory when the instruction
19992 [(match_scratch:SI 1 "r")
19993 (set (match_operand:SI 0 "memory_operand" "")
19995 "optimize_insn_for_speed_p ()
19996 && ! TARGET_USE_MOV0
19997 && TARGET_SPLIT_LONG_MOVES
19998 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19999 && peep2_regno_dead_p (0, FLAGS_REG)"
20000 [(parallel [(set (match_dup 1) (const_int 0))
20001 (clobber (reg:CC FLAGS_REG))])
20002 (set (match_dup 0) (match_dup 1))]
20006 [(match_scratch:HI 1 "r")
20007 (set (match_operand:HI 0 "memory_operand" "")
20009 "optimize_insn_for_speed_p ()
20010 && ! TARGET_USE_MOV0
20011 && TARGET_SPLIT_LONG_MOVES
20012 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20013 && peep2_regno_dead_p (0, FLAGS_REG)"
20014 [(parallel [(set (match_dup 2) (const_int 0))
20015 (clobber (reg:CC FLAGS_REG))])
20016 (set (match_dup 0) (match_dup 1))]
20017 "operands[2] = gen_lowpart (SImode, operands[1]);")
20020 [(match_scratch:QI 1 "q")
20021 (set (match_operand:QI 0 "memory_operand" "")
20023 "optimize_insn_for_speed_p ()
20024 && ! TARGET_USE_MOV0
20025 && TARGET_SPLIT_LONG_MOVES
20026 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
20027 && peep2_regno_dead_p (0, FLAGS_REG)"
20028 [(parallel [(set (match_dup 2) (const_int 0))
20029 (clobber (reg:CC FLAGS_REG))])
20030 (set (match_dup 0) (match_dup 1))]
20031 "operands[2] = gen_lowpart (SImode, operands[1]);")
20034 [(match_scratch:SI 2 "r")
20035 (set (match_operand:SI 0 "memory_operand" "")
20036 (match_operand:SI 1 "immediate_operand" ""))]
20037 "optimize_insn_for_speed_p ()
20038 && TARGET_SPLIT_LONG_MOVES
20039 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20040 [(set (match_dup 2) (match_dup 1))
20041 (set (match_dup 0) (match_dup 2))]
20045 [(match_scratch:HI 2 "r")
20046 (set (match_operand:HI 0 "memory_operand" "")
20047 (match_operand:HI 1 "immediate_operand" ""))]
20048 "optimize_insn_for_speed_p ()
20049 && TARGET_SPLIT_LONG_MOVES
20050 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20051 [(set (match_dup 2) (match_dup 1))
20052 (set (match_dup 0) (match_dup 2))]
20056 [(match_scratch:QI 2 "q")
20057 (set (match_operand:QI 0 "memory_operand" "")
20058 (match_operand:QI 1 "immediate_operand" ""))]
20059 "optimize_insn_for_speed_p ()
20060 && TARGET_SPLIT_LONG_MOVES
20061 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
20062 [(set (match_dup 2) (match_dup 1))
20063 (set (match_dup 0) (match_dup 2))]
20066 ;; Don't compare memory with zero, load and use a test instead.
20068 [(set (match_operand 0 "flags_reg_operand" "")
20069 (match_operator 1 "compare_operator"
20070 [(match_operand:SI 2 "memory_operand" "")
20072 (match_scratch:SI 3 "r")]
20073 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
20074 [(set (match_dup 3) (match_dup 2))
20075 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
20078 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
20079 ;; Don't split NOTs with a displacement operand, because resulting XOR
20080 ;; will not be pairable anyway.
20082 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
20083 ;; represented using a modRM byte. The XOR replacement is long decoded,
20084 ;; so this split helps here as well.
20086 ;; Note: Can't do this as a regular split because we can't get proper
20087 ;; lifetime information then.
20090 [(set (match_operand:SI 0 "nonimmediate_operand" "")
20091 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
20092 "optimize_insn_for_speed_p ()
20093 && ((TARGET_NOT_UNPAIRABLE
20094 && (!MEM_P (operands[0])
20095 || !memory_displacement_operand (operands[0], SImode)))
20096 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
20097 && peep2_regno_dead_p (0, FLAGS_REG)"
20098 [(parallel [(set (match_dup 0)
20099 (xor:SI (match_dup 1) (const_int -1)))
20100 (clobber (reg:CC FLAGS_REG))])]
20104 [(set (match_operand:HI 0 "nonimmediate_operand" "")
20105 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
20106 "optimize_insn_for_speed_p ()
20107 && ((TARGET_NOT_UNPAIRABLE
20108 && (!MEM_P (operands[0])
20109 || !memory_displacement_operand (operands[0], HImode)))
20110 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
20111 && peep2_regno_dead_p (0, FLAGS_REG)"
20112 [(parallel [(set (match_dup 0)
20113 (xor:HI (match_dup 1) (const_int -1)))
20114 (clobber (reg:CC FLAGS_REG))])]
20118 [(set (match_operand:QI 0 "nonimmediate_operand" "")
20119 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
20120 "optimize_insn_for_speed_p ()
20121 && ((TARGET_NOT_UNPAIRABLE
20122 && (!MEM_P (operands[0])
20123 || !memory_displacement_operand (operands[0], QImode)))
20124 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
20125 && peep2_regno_dead_p (0, FLAGS_REG)"
20126 [(parallel [(set (match_dup 0)
20127 (xor:QI (match_dup 1) (const_int -1)))
20128 (clobber (reg:CC FLAGS_REG))])]
20131 ;; Non pairable "test imm, reg" instructions can be translated to
20132 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
20133 ;; byte opcode instead of two, have a short form for byte operands),
20134 ;; so do it for other CPUs as well. Given that the value was dead,
20135 ;; this should not create any new dependencies. Pass on the sub-word
20136 ;; versions if we're concerned about partial register stalls.
20139 [(set (match_operand 0 "flags_reg_operand" "")
20140 (match_operator 1 "compare_operator"
20141 [(and:SI (match_operand:SI 2 "register_operand" "")
20142 (match_operand:SI 3 "immediate_operand" ""))
20144 "ix86_match_ccmode (insn, CCNOmode)
20145 && (true_regnum (operands[2]) != AX_REG
20146 || satisfies_constraint_K (operands[3]))
20147 && peep2_reg_dead_p (1, operands[2])"
20149 [(set (match_dup 0)
20150 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
20153 (and:SI (match_dup 2) (match_dup 3)))])]
20156 ;; We don't need to handle HImode case, because it will be promoted to SImode
20157 ;; on ! TARGET_PARTIAL_REG_STALL
20160 [(set (match_operand 0 "flags_reg_operand" "")
20161 (match_operator 1 "compare_operator"
20162 [(and:QI (match_operand:QI 2 "register_operand" "")
20163 (match_operand:QI 3 "immediate_operand" ""))
20165 "! TARGET_PARTIAL_REG_STALL
20166 && ix86_match_ccmode (insn, CCNOmode)
20167 && true_regnum (operands[2]) != AX_REG
20168 && peep2_reg_dead_p (1, operands[2])"
20170 [(set (match_dup 0)
20171 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
20174 (and:QI (match_dup 2) (match_dup 3)))])]
20178 [(set (match_operand 0 "flags_reg_operand" "")
20179 (match_operator 1 "compare_operator"
20182 (match_operand 2 "ext_register_operand" "")
20185 (match_operand 3 "const_int_operand" ""))
20187 "! TARGET_PARTIAL_REG_STALL
20188 && ix86_match_ccmode (insn, CCNOmode)
20189 && true_regnum (operands[2]) != AX_REG
20190 && peep2_reg_dead_p (1, operands[2])"
20191 [(parallel [(set (match_dup 0)
20200 (set (zero_extract:SI (match_dup 2)
20211 ;; Don't do logical operations with memory inputs.
20213 [(match_scratch:SI 2 "r")
20214 (parallel [(set (match_operand:SI 0 "register_operand" "")
20215 (match_operator:SI 3 "arith_or_logical_operator"
20217 (match_operand:SI 1 "memory_operand" "")]))
20218 (clobber (reg:CC FLAGS_REG))])]
20219 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20220 [(set (match_dup 2) (match_dup 1))
20221 (parallel [(set (match_dup 0)
20222 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20223 (clobber (reg:CC FLAGS_REG))])]
20227 [(match_scratch:SI 2 "r")
20228 (parallel [(set (match_operand:SI 0 "register_operand" "")
20229 (match_operator:SI 3 "arith_or_logical_operator"
20230 [(match_operand:SI 1 "memory_operand" "")
20232 (clobber (reg:CC FLAGS_REG))])]
20233 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20234 [(set (match_dup 2) (match_dup 1))
20235 (parallel [(set (match_dup 0)
20236 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20237 (clobber (reg:CC FLAGS_REG))])]
20240 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20241 ;; refers to the destination of the load!
20244 [(set (match_operand:SI 0 "register_operand" "")
20245 (match_operand:SI 1 "register_operand" ""))
20246 (parallel [(set (match_dup 0)
20247 (match_operator:SI 3 "commutative_operator"
20249 (match_operand:SI 2 "memory_operand" "")]))
20250 (clobber (reg:CC FLAGS_REG))])]
20251 "REGNO (operands[0]) != REGNO (operands[1])
20252 && GENERAL_REGNO_P (REGNO (operands[0]))
20253 && GENERAL_REGNO_P (REGNO (operands[1]))"
20254 [(set (match_dup 0) (match_dup 4))
20255 (parallel [(set (match_dup 0)
20256 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20257 (clobber (reg:CC FLAGS_REG))])]
20258 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20261 [(set (match_operand 0 "register_operand" "")
20262 (match_operand 1 "register_operand" ""))
20264 (match_operator 3 "commutative_operator"
20266 (match_operand 2 "memory_operand" "")]))]
20267 "REGNO (operands[0]) != REGNO (operands[1])
20268 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20269 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20270 [(set (match_dup 0) (match_dup 2))
20272 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20275 ; Don't do logical operations with memory outputs
20277 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20278 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20279 ; the same decoder scheduling characteristics as the original.
20282 [(match_scratch:SI 2 "r")
20283 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20284 (match_operator:SI 3 "arith_or_logical_operator"
20286 (match_operand:SI 1 "nonmemory_operand" "")]))
20287 (clobber (reg:CC FLAGS_REG))])]
20288 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20289 /* Do not split stack checking probes. */
20290 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20291 [(set (match_dup 2) (match_dup 0))
20292 (parallel [(set (match_dup 2)
20293 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20294 (clobber (reg:CC FLAGS_REG))])
20295 (set (match_dup 0) (match_dup 2))]
20299 [(match_scratch:SI 2 "r")
20300 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20301 (match_operator:SI 3 "arith_or_logical_operator"
20302 [(match_operand:SI 1 "nonmemory_operand" "")
20304 (clobber (reg:CC FLAGS_REG))])]
20305 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20306 /* Do not split stack checking probes. */
20307 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20308 [(set (match_dup 2) (match_dup 0))
20309 (parallel [(set (match_dup 2)
20310 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20311 (clobber (reg:CC FLAGS_REG))])
20312 (set (match_dup 0) (match_dup 2))]
20315 ;; Attempt to always use XOR for zeroing registers.
20317 [(set (match_operand 0 "register_operand" "")
20318 (match_operand 1 "const0_operand" ""))]
20319 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20320 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20321 && GENERAL_REG_P (operands[0])
20322 && peep2_regno_dead_p (0, FLAGS_REG)"
20323 [(parallel [(set (match_dup 0) (const_int 0))
20324 (clobber (reg:CC FLAGS_REG))])]
20326 operands[0] = gen_lowpart (word_mode, operands[0]);
20330 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20332 "(GET_MODE (operands[0]) == QImode
20333 || GET_MODE (operands[0]) == HImode)
20334 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20335 && peep2_regno_dead_p (0, FLAGS_REG)"
20336 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20337 (clobber (reg:CC FLAGS_REG))])])
20339 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20341 [(set (match_operand 0 "register_operand" "")
20343 "(GET_MODE (operands[0]) == HImode
20344 || GET_MODE (operands[0]) == SImode
20345 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20346 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20347 && peep2_regno_dead_p (0, FLAGS_REG)"
20348 [(parallel [(set (match_dup 0) (const_int -1))
20349 (clobber (reg:CC FLAGS_REG))])]
20350 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20353 ;; Attempt to convert simple leas to adds. These can be created by
20356 [(set (match_operand:SI 0 "register_operand" "")
20357 (plus:SI (match_dup 0)
20358 (match_operand:SI 1 "nonmemory_operand" "")))]
20359 "peep2_regno_dead_p (0, FLAGS_REG)"
20360 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20361 (clobber (reg:CC FLAGS_REG))])]
20365 [(set (match_operand:SI 0 "register_operand" "")
20366 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20367 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20368 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20369 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20370 (clobber (reg:CC FLAGS_REG))])]
20371 "operands[2] = gen_lowpart (SImode, operands[2]);")
20374 [(set (match_operand:DI 0 "register_operand" "")
20375 (plus:DI (match_dup 0)
20376 (match_operand:DI 1 "x86_64_general_operand" "")))]
20377 "peep2_regno_dead_p (0, FLAGS_REG)"
20378 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20379 (clobber (reg:CC FLAGS_REG))])]
20383 [(set (match_operand:SI 0 "register_operand" "")
20384 (mult:SI (match_dup 0)
20385 (match_operand:SI 1 "const_int_operand" "")))]
20386 "exact_log2 (INTVAL (operands[1])) >= 0
20387 && peep2_regno_dead_p (0, FLAGS_REG)"
20388 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20389 (clobber (reg:CC FLAGS_REG))])]
20390 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20393 [(set (match_operand:DI 0 "register_operand" "")
20394 (mult:DI (match_dup 0)
20395 (match_operand:DI 1 "const_int_operand" "")))]
20396 "exact_log2 (INTVAL (operands[1])) >= 0
20397 && peep2_regno_dead_p (0, FLAGS_REG)"
20398 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20399 (clobber (reg:CC FLAGS_REG))])]
20400 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20403 [(set (match_operand:SI 0 "register_operand" "")
20404 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20405 (match_operand:DI 2 "const_int_operand" "")) 0))]
20406 "exact_log2 (INTVAL (operands[2])) >= 0
20407 && REGNO (operands[0]) == REGNO (operands[1])
20408 && peep2_regno_dead_p (0, FLAGS_REG)"
20409 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20410 (clobber (reg:CC FLAGS_REG))])]
20411 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20413 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20414 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20415 ;; many CPUs it is also faster, since special hardware to avoid esp
20416 ;; dependencies is present.
20418 ;; While some of these conversions may be done using splitters, we use peepholes
20419 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20421 ;; Convert prologue esp subtractions to push.
20422 ;; We need register to push. In order to keep verify_flow_info happy we have
20424 ;; - use scratch and clobber it in order to avoid dependencies
20425 ;; - use already live register
20426 ;; We can't use the second way right now, since there is no reliable way how to
20427 ;; verify that given register is live. First choice will also most likely in
20428 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20429 ;; call clobbered registers are dead. We may want to use base pointer as an
20430 ;; alternative when no register is available later.
20433 [(match_scratch:SI 0 "r")
20434 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20435 (clobber (reg:CC FLAGS_REG))
20436 (clobber (mem:BLK (scratch)))])]
20437 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20438 [(clobber (match_dup 0))
20439 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20440 (clobber (mem:BLK (scratch)))])])
20443 [(match_scratch:SI 0 "r")
20444 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20445 (clobber (reg:CC FLAGS_REG))
20446 (clobber (mem:BLK (scratch)))])]
20447 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20448 [(clobber (match_dup 0))
20449 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20450 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20451 (clobber (mem:BLK (scratch)))])])
20453 ;; Convert esp subtractions to push.
20455 [(match_scratch:SI 0 "r")
20456 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20457 (clobber (reg:CC FLAGS_REG))])]
20458 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20459 [(clobber (match_dup 0))
20460 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20463 [(match_scratch:SI 0 "r")
20464 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20465 (clobber (reg:CC FLAGS_REG))])]
20466 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20467 [(clobber (match_dup 0))
20468 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20469 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20471 ;; Convert epilogue deallocator to pop.
20473 [(match_scratch:SI 0 "r")
20474 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20475 (clobber (reg:CC FLAGS_REG))
20476 (clobber (mem:BLK (scratch)))])]
20477 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20478 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20479 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20480 (clobber (mem:BLK (scratch)))])]
20483 ;; Two pops case is tricky, since pop causes dependency on destination register.
20484 ;; We use two registers if available.
20486 [(match_scratch:SI 0 "r")
20487 (match_scratch:SI 1 "r")
20488 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20489 (clobber (reg:CC FLAGS_REG))
20490 (clobber (mem:BLK (scratch)))])]
20491 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20492 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20493 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20494 (clobber (mem:BLK (scratch)))])
20495 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20496 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20500 [(match_scratch:SI 0 "r")
20501 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20502 (clobber (reg:CC FLAGS_REG))
20503 (clobber (mem:BLK (scratch)))])]
20504 "optimize_insn_for_size_p ()"
20505 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20506 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20507 (clobber (mem:BLK (scratch)))])
20508 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20509 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20512 ;; Convert esp additions to pop.
20514 [(match_scratch:SI 0 "r")
20515 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20516 (clobber (reg:CC FLAGS_REG))])]
20518 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20519 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20522 ;; Two pops case is tricky, since pop causes dependency on destination register.
20523 ;; We use two registers if available.
20525 [(match_scratch:SI 0 "r")
20526 (match_scratch:SI 1 "r")
20527 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20528 (clobber (reg:CC FLAGS_REG))])]
20530 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20531 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20532 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20533 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20537 [(match_scratch:SI 0 "r")
20538 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20539 (clobber (reg:CC FLAGS_REG))])]
20540 "optimize_insn_for_size_p ()"
20541 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20542 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20543 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20544 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20547 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20548 ;; required and register dies. Similarly for 128 to -128.
20550 [(set (match_operand 0 "flags_reg_operand" "")
20551 (match_operator 1 "compare_operator"
20552 [(match_operand 2 "register_operand" "")
20553 (match_operand 3 "const_int_operand" "")]))]
20554 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20555 && incdec_operand (operands[3], GET_MODE (operands[3])))
20556 || (!TARGET_FUSE_CMP_AND_BRANCH
20557 && INTVAL (operands[3]) == 128))
20558 && ix86_match_ccmode (insn, CCGCmode)
20559 && peep2_reg_dead_p (1, operands[2])"
20560 [(parallel [(set (match_dup 0)
20561 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20562 (clobber (match_dup 2))])]
20566 [(match_scratch:DI 0 "r")
20567 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20568 (clobber (reg:CC FLAGS_REG))
20569 (clobber (mem:BLK (scratch)))])]
20570 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20571 [(clobber (match_dup 0))
20572 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20573 (clobber (mem:BLK (scratch)))])])
20576 [(match_scratch:DI 0 "r")
20577 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20578 (clobber (reg:CC FLAGS_REG))
20579 (clobber (mem:BLK (scratch)))])]
20580 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20581 [(clobber (match_dup 0))
20582 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20583 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20584 (clobber (mem:BLK (scratch)))])])
20586 ;; Convert esp subtractions to push.
20588 [(match_scratch:DI 0 "r")
20589 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20590 (clobber (reg:CC FLAGS_REG))])]
20591 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20592 [(clobber (match_dup 0))
20593 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20596 [(match_scratch:DI 0 "r")
20597 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20598 (clobber (reg:CC FLAGS_REG))])]
20599 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20600 [(clobber (match_dup 0))
20601 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20602 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20604 ;; Convert epilogue deallocator to pop.
20606 [(match_scratch:DI 0 "r")
20607 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20608 (clobber (reg:CC FLAGS_REG))
20609 (clobber (mem:BLK (scratch)))])]
20610 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20611 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20612 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20613 (clobber (mem:BLK (scratch)))])]
20616 ;; Two pops case is tricky, since pop causes dependency on destination register.
20617 ;; We use two registers if available.
20619 [(match_scratch:DI 0 "r")
20620 (match_scratch:DI 1 "r")
20621 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20622 (clobber (reg:CC FLAGS_REG))
20623 (clobber (mem:BLK (scratch)))])]
20624 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20625 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20626 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20627 (clobber (mem:BLK (scratch)))])
20628 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20629 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20633 [(match_scratch:DI 0 "r")
20634 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20635 (clobber (reg:CC FLAGS_REG))
20636 (clobber (mem:BLK (scratch)))])]
20637 "optimize_insn_for_size_p ()"
20638 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20639 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20640 (clobber (mem:BLK (scratch)))])
20641 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20642 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20645 ;; Convert esp additions to pop.
20647 [(match_scratch:DI 0 "r")
20648 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20649 (clobber (reg:CC FLAGS_REG))])]
20651 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20652 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20655 ;; Two pops case is tricky, since pop causes dependency on destination register.
20656 ;; We use two registers if available.
20658 [(match_scratch:DI 0 "r")
20659 (match_scratch:DI 1 "r")
20660 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20661 (clobber (reg:CC FLAGS_REG))])]
20663 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20664 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20665 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20666 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20670 [(match_scratch:DI 0 "r")
20671 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20672 (clobber (reg:CC FLAGS_REG))])]
20673 "optimize_insn_for_size_p ()"
20674 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20675 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20676 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20677 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20680 ;; Convert imul by three, five and nine into lea
20683 [(set (match_operand:SI 0 "register_operand" "")
20684 (mult:SI (match_operand:SI 1 "register_operand" "")
20685 (match_operand:SI 2 "const_int_operand" "")))
20686 (clobber (reg:CC FLAGS_REG))])]
20687 "INTVAL (operands[2]) == 3
20688 || INTVAL (operands[2]) == 5
20689 || INTVAL (operands[2]) == 9"
20690 [(set (match_dup 0)
20691 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20693 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20697 [(set (match_operand:SI 0 "register_operand" "")
20698 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20699 (match_operand:SI 2 "const_int_operand" "")))
20700 (clobber (reg:CC FLAGS_REG))])]
20701 "optimize_insn_for_speed_p ()
20702 && (INTVAL (operands[2]) == 3
20703 || INTVAL (operands[2]) == 5
20704 || INTVAL (operands[2]) == 9)"
20705 [(set (match_dup 0) (match_dup 1))
20707 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20709 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20713 [(set (match_operand:DI 0 "register_operand" "")
20714 (mult:DI (match_operand:DI 1 "register_operand" "")
20715 (match_operand:DI 2 "const_int_operand" "")))
20716 (clobber (reg:CC FLAGS_REG))])]
20718 && (INTVAL (operands[2]) == 3
20719 || INTVAL (operands[2]) == 5
20720 || INTVAL (operands[2]) == 9)"
20721 [(set (match_dup 0)
20722 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20724 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20728 [(set (match_operand:DI 0 "register_operand" "")
20729 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20730 (match_operand:DI 2 "const_int_operand" "")))
20731 (clobber (reg:CC FLAGS_REG))])]
20733 && optimize_insn_for_speed_p ()
20734 && (INTVAL (operands[2]) == 3
20735 || INTVAL (operands[2]) == 5
20736 || INTVAL (operands[2]) == 9)"
20737 [(set (match_dup 0) (match_dup 1))
20739 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20741 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20743 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20744 ;; imul $32bit_imm, reg, reg is direct decoded.
20746 [(match_scratch:DI 3 "r")
20747 (parallel [(set (match_operand:DI 0 "register_operand" "")
20748 (mult:DI (match_operand:DI 1 "memory_operand" "")
20749 (match_operand:DI 2 "immediate_operand" "")))
20750 (clobber (reg:CC FLAGS_REG))])]
20751 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20752 && !satisfies_constraint_K (operands[2])"
20753 [(set (match_dup 3) (match_dup 1))
20754 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20755 (clobber (reg:CC FLAGS_REG))])]
20759 [(match_scratch:SI 3 "r")
20760 (parallel [(set (match_operand:SI 0 "register_operand" "")
20761 (mult:SI (match_operand:SI 1 "memory_operand" "")
20762 (match_operand:SI 2 "immediate_operand" "")))
20763 (clobber (reg:CC FLAGS_REG))])]
20764 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20765 && !satisfies_constraint_K (operands[2])"
20766 [(set (match_dup 3) (match_dup 1))
20767 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20768 (clobber (reg:CC FLAGS_REG))])]
20772 [(match_scratch:SI 3 "r")
20773 (parallel [(set (match_operand:DI 0 "register_operand" "")
20775 (mult:SI (match_operand:SI 1 "memory_operand" "")
20776 (match_operand:SI 2 "immediate_operand" ""))))
20777 (clobber (reg:CC FLAGS_REG))])]
20778 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20779 && !satisfies_constraint_K (operands[2])"
20780 [(set (match_dup 3) (match_dup 1))
20781 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20782 (clobber (reg:CC FLAGS_REG))])]
20785 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20786 ;; Convert it into imul reg, reg
20787 ;; It would be better to force assembler to encode instruction using long
20788 ;; immediate, but there is apparently no way to do so.
20790 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20791 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20792 (match_operand:DI 2 "const_int_operand" "")))
20793 (clobber (reg:CC FLAGS_REG))])
20794 (match_scratch:DI 3 "r")]
20795 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20796 && satisfies_constraint_K (operands[2])"
20797 [(set (match_dup 3) (match_dup 2))
20798 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20799 (clobber (reg:CC FLAGS_REG))])]
20801 if (!rtx_equal_p (operands[0], operands[1]))
20802 emit_move_insn (operands[0], operands[1]);
20806 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20807 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20808 (match_operand:SI 2 "const_int_operand" "")))
20809 (clobber (reg:CC FLAGS_REG))])
20810 (match_scratch:SI 3 "r")]
20811 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20812 && satisfies_constraint_K (operands[2])"
20813 [(set (match_dup 3) (match_dup 2))
20814 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20815 (clobber (reg:CC FLAGS_REG))])]
20817 if (!rtx_equal_p (operands[0], operands[1]))
20818 emit_move_insn (operands[0], operands[1]);
20822 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20823 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20824 (match_operand:HI 2 "immediate_operand" "")))
20825 (clobber (reg:CC FLAGS_REG))])
20826 (match_scratch:HI 3 "r")]
20827 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20828 [(set (match_dup 3) (match_dup 2))
20829 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20830 (clobber (reg:CC FLAGS_REG))])]
20832 if (!rtx_equal_p (operands[0], operands[1]))
20833 emit_move_insn (operands[0], operands[1]);
20836 ;; After splitting up read-modify operations, array accesses with memory
20837 ;; operands might end up in form:
20839 ;; movl 4(%esp), %edx
20841 ;; instead of pre-splitting:
20843 ;; addl 4(%esp), %eax
20845 ;; movl 4(%esp), %edx
20846 ;; leal (%edx,%eax,4), %eax
20849 [(parallel [(set (match_operand 0 "register_operand" "")
20850 (ashift (match_operand 1 "register_operand" "")
20851 (match_operand 2 "const_int_operand" "")))
20852 (clobber (reg:CC FLAGS_REG))])
20853 (set (match_operand 3 "register_operand")
20854 (match_operand 4 "x86_64_general_operand" ""))
20855 (parallel [(set (match_operand 5 "register_operand" "")
20856 (plus (match_operand 6 "register_operand" "")
20857 (match_operand 7 "register_operand" "")))
20858 (clobber (reg:CC FLAGS_REG))])]
20859 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20860 /* Validate MODE for lea. */
20861 && ((!TARGET_PARTIAL_REG_STALL
20862 && (GET_MODE (operands[0]) == QImode
20863 || GET_MODE (operands[0]) == HImode))
20864 || GET_MODE (operands[0]) == SImode
20865 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20866 /* We reorder load and the shift. */
20867 && !rtx_equal_p (operands[1], operands[3])
20868 && !reg_overlap_mentioned_p (operands[0], operands[4])
20869 /* Last PLUS must consist of operand 0 and 3. */
20870 && !rtx_equal_p (operands[0], operands[3])
20871 && (rtx_equal_p (operands[3], operands[6])
20872 || rtx_equal_p (operands[3], operands[7]))
20873 && (rtx_equal_p (operands[0], operands[6])
20874 || rtx_equal_p (operands[0], operands[7]))
20875 /* The intermediate operand 0 must die or be same as output. */
20876 && (rtx_equal_p (operands[0], operands[5])
20877 || peep2_reg_dead_p (3, operands[0]))"
20878 [(set (match_dup 3) (match_dup 4))
20879 (set (match_dup 0) (match_dup 1))]
20881 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20882 int scale = 1 << INTVAL (operands[2]);
20883 rtx index = gen_lowpart (Pmode, operands[1]);
20884 rtx base = gen_lowpart (Pmode, operands[3]);
20885 rtx dest = gen_lowpart (mode, operands[5]);
20887 operands[1] = gen_rtx_PLUS (Pmode, base,
20888 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20890 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20891 operands[0] = dest;
20894 ;; Call-value patterns last so that the wildcard operand does not
20895 ;; disrupt insn-recog's switch tables.
20897 (define_insn "*call_value_pop_0"
20898 [(set (match_operand 0 "" "")
20899 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20900 (match_operand:SI 2 "" "")))
20901 (set (reg:SI SP_REG)
20902 (plus:SI (reg:SI SP_REG)
20903 (match_operand:SI 3 "immediate_operand" "")))]
20906 if (SIBLING_CALL_P (insn))
20909 return "call\t%P1";
20911 [(set_attr "type" "callv")])
20913 (define_insn "*call_value_pop_1"
20914 [(set (match_operand 0 "" "")
20915 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20916 (match_operand:SI 2 "" "")))
20917 (set (reg:SI SP_REG)
20918 (plus:SI (reg:SI SP_REG)
20919 (match_operand:SI 3 "immediate_operand" "i")))]
20920 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20922 if (constant_call_address_operand (operands[1], Pmode))
20923 return "call\t%P1";
20924 return "call\t%A1";
20926 [(set_attr "type" "callv")])
20928 (define_insn "*sibcall_value_pop_1"
20929 [(set (match_operand 0 "" "")
20930 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20931 (match_operand:SI 2 "" "")))
20932 (set (reg:SI SP_REG)
20933 (plus:SI (reg:SI SP_REG)
20934 (match_operand:SI 3 "immediate_operand" "i,i")))]
20935 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20939 [(set_attr "type" "callv")])
20941 (define_insn "*call_value_0"
20942 [(set (match_operand 0 "" "")
20943 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20944 (match_operand:SI 2 "" "")))]
20947 if (SIBLING_CALL_P (insn))
20950 return "call\t%P1";
20952 [(set_attr "type" "callv")])
20954 (define_insn "*call_value_0_rex64"
20955 [(set (match_operand 0 "" "")
20956 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20957 (match_operand:DI 2 "const_int_operand" "")))]
20960 if (SIBLING_CALL_P (insn))
20963 return "call\t%P1";
20965 [(set_attr "type" "callv")])
20967 (define_insn "*call_value_0_rex64_ms_sysv"
20968 [(set (match_operand 0 "" "")
20969 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20970 (match_operand:DI 2 "const_int_operand" "")))
20971 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20972 (clobber (reg:TI XMM6_REG))
20973 (clobber (reg:TI XMM7_REG))
20974 (clobber (reg:TI XMM8_REG))
20975 (clobber (reg:TI XMM9_REG))
20976 (clobber (reg:TI XMM10_REG))
20977 (clobber (reg:TI XMM11_REG))
20978 (clobber (reg:TI XMM12_REG))
20979 (clobber (reg:TI XMM13_REG))
20980 (clobber (reg:TI XMM14_REG))
20981 (clobber (reg:TI XMM15_REG))
20982 (clobber (reg:DI SI_REG))
20983 (clobber (reg:DI DI_REG))]
20984 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20986 if (SIBLING_CALL_P (insn))
20989 return "call\t%P1";
20991 [(set_attr "type" "callv")])
20993 (define_insn "*call_value_1"
20994 [(set (match_operand 0 "" "")
20995 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20996 (match_operand:SI 2 "" "")))]
20997 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20999 if (constant_call_address_operand (operands[1], Pmode))
21000 return "call\t%P1";
21001 return "call\t%A1";
21003 [(set_attr "type" "callv")])
21005 (define_insn "*sibcall_value_1"
21006 [(set (match_operand 0 "" "")
21007 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
21008 (match_operand:SI 2 "" "")))]
21009 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
21013 [(set_attr "type" "callv")])
21015 (define_insn "*call_value_1_rex64"
21016 [(set (match_operand 0 "" "")
21017 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21018 (match_operand:DI 2 "" "")))]
21019 "TARGET_64BIT && !SIBLING_CALL_P (insn)
21020 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
21022 if (constant_call_address_operand (operands[1], Pmode))
21023 return "call\t%P1";
21024 return "call\t%A1";
21026 [(set_attr "type" "callv")])
21028 (define_insn "*call_value_1_rex64_ms_sysv"
21029 [(set (match_operand 0 "" "")
21030 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
21031 (match_operand:DI 2 "" "")))
21032 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
21033 (clobber (reg:TI XMM6_REG))
21034 (clobber (reg:TI XMM7_REG))
21035 (clobber (reg:TI XMM8_REG))
21036 (clobber (reg:TI XMM9_REG))
21037 (clobber (reg:TI XMM10_REG))
21038 (clobber (reg:TI XMM11_REG))
21039 (clobber (reg:TI XMM12_REG))
21040 (clobber (reg:TI XMM13_REG))
21041 (clobber (reg:TI XMM14_REG))
21042 (clobber (reg:TI XMM15_REG))
21043 (clobber (reg:DI SI_REG))
21044 (clobber (reg:DI DI_REG))]
21045 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
21047 if (constant_call_address_operand (operands[1], Pmode))
21048 return "call\t%P1";
21049 return "call\t%A1";
21051 [(set_attr "type" "callv")])
21053 (define_insn "*call_value_1_rex64_large"
21054 [(set (match_operand 0 "" "")
21055 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
21056 (match_operand:DI 2 "" "")))]
21057 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
21059 [(set_attr "type" "callv")])
21061 (define_insn "*sibcall_value_1_rex64"
21062 [(set (match_operand 0 "" "")
21063 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
21064 (match_operand:DI 2 "" "")))]
21065 "TARGET_64BIT && SIBLING_CALL_P (insn)"
21069 [(set_attr "type" "callv")])
21071 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
21072 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
21073 ;; caught for use by garbage collectors and the like. Using an insn that
21074 ;; maps to SIGILL makes it more likely the program will rightfully die.
21075 ;; Keeping with tradition, "6" is in honor of #UD.
21076 (define_insn "trap"
21077 [(trap_if (const_int 1) (const_int 6))]
21079 { return ASM_SHORT "0x0b0f"; }
21080 [(set_attr "length" "2")])
21082 (define_expand "sse_prologue_save"
21083 [(parallel [(set (match_operand:BLK 0 "" "")
21084 (unspec:BLK [(reg:DI XMM0_REG)
21091 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
21092 (use (match_operand:DI 1 "register_operand" ""))
21093 (use (match_operand:DI 2 "immediate_operand" ""))
21094 (use (label_ref:DI (match_operand 3 "" "")))])]
21098 (define_insn "*sse_prologue_save_insn"
21099 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
21100 (match_operand:DI 4 "const_int_operand" "n")))
21101 (unspec:BLK [(reg:DI XMM0_REG)
21108 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
21109 (use (match_operand:DI 1 "register_operand" "r"))
21110 (use (match_operand:DI 2 "const_int_operand" "i"))
21111 (use (label_ref:DI (match_operand 3 "" "X")))]
21113 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
21114 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
21117 operands[0] = gen_rtx_MEM (Pmode,
21118 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
21119 /* VEX instruction with a REX prefix will #UD. */
21120 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
21121 gcc_unreachable ();
21123 output_asm_insn ("jmp\t%A1", operands);
21124 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
21126 operands[4] = adjust_address (operands[0], DImode, i*16);
21127 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
21128 PUT_MODE (operands[4], TImode);
21129 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
21130 output_asm_insn ("rex", operands);
21131 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
21133 (*targetm.asm_out.internal_label) (asm_out_file, "L",
21134 CODE_LABEL_NUMBER (operands[3]));
21137 [(set_attr "type" "other")
21138 (set_attr "length_immediate" "0")
21139 (set_attr "length_address" "0")
21140 (set (attr "length")
21142 (eq (symbol_ref "TARGET_AVX") (const_int 0))
21143 (const_string "34")
21144 (const_string "42")))
21145 (set_attr "memory" "store")
21146 (set_attr "modrm" "0")
21147 (set_attr "prefix" "maybe_vex")
21148 (set_attr "mode" "DI")])
21150 (define_expand "prefetch"
21151 [(prefetch (match_operand 0 "address_operand" "")
21152 (match_operand:SI 1 "const_int_operand" "")
21153 (match_operand:SI 2 "const_int_operand" ""))]
21154 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
21156 int rw = INTVAL (operands[1]);
21157 int locality = INTVAL (operands[2]);
21159 gcc_assert (rw == 0 || rw == 1);
21160 gcc_assert (locality >= 0 && locality <= 3);
21161 gcc_assert (GET_MODE (operands[0]) == Pmode
21162 || GET_MODE (operands[0]) == VOIDmode);
21164 /* Use 3dNOW prefetch in case we are asking for write prefetch not
21165 supported by SSE counterpart or the SSE prefetch is not available
21166 (K6 machines). Otherwise use SSE prefetch as it allows specifying
21168 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
21169 operands[2] = GEN_INT (3);
21171 operands[1] = const0_rtx;
21174 (define_insn "*prefetch_sse"
21175 [(prefetch (match_operand:SI 0 "address_operand" "p")
21177 (match_operand:SI 1 "const_int_operand" ""))]
21178 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
21180 static const char * const patterns[4] = {
21181 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21184 int locality = INTVAL (operands[1]);
21185 gcc_assert (locality >= 0 && locality <= 3);
21187 return patterns[locality];
21189 [(set_attr "type" "sse")
21190 (set_attr "atom_sse_attr" "prefetch")
21191 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21192 (set_attr "memory" "none")])
21194 (define_insn "*prefetch_sse_rex"
21195 [(prefetch (match_operand:DI 0 "address_operand" "p")
21197 (match_operand:SI 1 "const_int_operand" ""))]
21198 "TARGET_PREFETCH_SSE && TARGET_64BIT"
21200 static const char * const patterns[4] = {
21201 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
21204 int locality = INTVAL (operands[1]);
21205 gcc_assert (locality >= 0 && locality <= 3);
21207 return patterns[locality];
21209 [(set_attr "type" "sse")
21210 (set_attr "atom_sse_attr" "prefetch")
21211 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21212 (set_attr "memory" "none")])
21214 (define_insn "*prefetch_3dnow"
21215 [(prefetch (match_operand:SI 0 "address_operand" "p")
21216 (match_operand:SI 1 "const_int_operand" "n")
21218 "TARGET_3DNOW && !TARGET_64BIT"
21220 if (INTVAL (operands[1]) == 0)
21221 return "prefetch\t%a0";
21223 return "prefetchw\t%a0";
21225 [(set_attr "type" "mmx")
21226 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21227 (set_attr "memory" "none")])
21229 (define_insn "*prefetch_3dnow_rex"
21230 [(prefetch (match_operand:DI 0 "address_operand" "p")
21231 (match_operand:SI 1 "const_int_operand" "n")
21233 "TARGET_3DNOW && TARGET_64BIT"
21235 if (INTVAL (operands[1]) == 0)
21236 return "prefetch\t%a0";
21238 return "prefetchw\t%a0";
21240 [(set_attr "type" "mmx")
21241 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21242 (set_attr "memory" "none")])
21244 (define_expand "stack_protect_set"
21245 [(match_operand 0 "memory_operand" "")
21246 (match_operand 1 "memory_operand" "")]
21249 #ifdef TARGET_THREAD_SSP_OFFSET
21251 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21252 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21254 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21255 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21258 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21260 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21265 (define_insn "stack_protect_set_si"
21266 [(set (match_operand:SI 0 "memory_operand" "=m")
21267 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21268 (set (match_scratch:SI 2 "=&r") (const_int 0))
21269 (clobber (reg:CC FLAGS_REG))]
21271 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21272 [(set_attr "type" "multi")])
21274 (define_insn "stack_protect_set_di"
21275 [(set (match_operand:DI 0 "memory_operand" "=m")
21276 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21277 (set (match_scratch:DI 2 "=&r") (const_int 0))
21278 (clobber (reg:CC FLAGS_REG))]
21280 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21281 [(set_attr "type" "multi")])
21283 (define_insn "stack_tls_protect_set_si"
21284 [(set (match_operand:SI 0 "memory_operand" "=m")
21285 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21286 (set (match_scratch:SI 2 "=&r") (const_int 0))
21287 (clobber (reg:CC FLAGS_REG))]
21289 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21290 [(set_attr "type" "multi")])
21292 (define_insn "stack_tls_protect_set_di"
21293 [(set (match_operand:DI 0 "memory_operand" "=m")
21294 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21295 (set (match_scratch:DI 2 "=&r") (const_int 0))
21296 (clobber (reg:CC FLAGS_REG))]
21299 /* The kernel uses a different segment register for performance reasons; a
21300 system call would not have to trash the userspace segment register,
21301 which would be expensive */
21302 if (ix86_cmodel != CM_KERNEL)
21303 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21305 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21307 [(set_attr "type" "multi")])
21309 (define_expand "stack_protect_test"
21310 [(match_operand 0 "memory_operand" "")
21311 (match_operand 1 "memory_operand" "")
21312 (match_operand 2 "" "")]
21315 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21317 #ifdef TARGET_THREAD_SSP_OFFSET
21319 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21320 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21322 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21323 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21326 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21328 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21331 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
21332 flags, const0_rtx, operands[2]));
21336 (define_insn "stack_protect_test_si"
21337 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21338 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21339 (match_operand:SI 2 "memory_operand" "m")]
21341 (clobber (match_scratch:SI 3 "=&r"))]
21343 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21344 [(set_attr "type" "multi")])
21346 (define_insn "stack_protect_test_di"
21347 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21348 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21349 (match_operand:DI 2 "memory_operand" "m")]
21351 (clobber (match_scratch:DI 3 "=&r"))]
21353 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21354 [(set_attr "type" "multi")])
21356 (define_insn "stack_tls_protect_test_si"
21357 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21358 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21359 (match_operand:SI 2 "const_int_operand" "i")]
21360 UNSPEC_SP_TLS_TEST))
21361 (clobber (match_scratch:SI 3 "=r"))]
21363 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21364 [(set_attr "type" "multi")])
21366 (define_insn "stack_tls_protect_test_di"
21367 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21368 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21369 (match_operand:DI 2 "const_int_operand" "i")]
21370 UNSPEC_SP_TLS_TEST))
21371 (clobber (match_scratch:DI 3 "=r"))]
21374 /* The kernel uses a different segment register for performance reasons; a
21375 system call would not have to trash the userspace segment register,
21376 which would be expensive */
21377 if (ix86_cmodel != CM_KERNEL)
21378 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21380 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21382 [(set_attr "type" "multi")])
21384 (define_mode_iterator CRC32MODE [QI HI SI])
21385 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21386 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21388 (define_insn "sse4_2_crc32<mode>"
21389 [(set (match_operand:SI 0 "register_operand" "=r")
21391 [(match_operand:SI 1 "register_operand" "0")
21392 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21394 "TARGET_SSE4_2 || TARGET_CRC32"
21395 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21396 [(set_attr "type" "sselog1")
21397 (set_attr "prefix_rep" "1")
21398 (set_attr "prefix_extra" "1")
21399 (set (attr "prefix_data16")
21400 (if_then_else (match_operand:HI 2 "" "")
21402 (const_string "*")))
21403 (set (attr "prefix_rex")
21404 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
21406 (const_string "*")))
21407 (set_attr "mode" "SI")])
21409 (define_insn "sse4_2_crc32di"
21410 [(set (match_operand:DI 0 "register_operand" "=r")
21412 [(match_operand:DI 1 "register_operand" "0")
21413 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21415 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21416 "crc32q\t{%2, %0|%0, %2}"
21417 [(set_attr "type" "sselog1")
21418 (set_attr "prefix_rep" "1")
21419 (set_attr "prefix_extra" "1")
21420 (set_attr "mode" "DI")])
21422 (define_expand "rdpmc"
21423 [(match_operand:DI 0 "register_operand" "")
21424 (match_operand:SI 1 "register_operand" "")]
21427 rtx reg = gen_reg_rtx (DImode);
21430 /* Force operand 1 into ECX. */
21431 rtx ecx = gen_rtx_REG (SImode, CX_REG);
21432 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
21433 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
21438 rtvec vec = rtvec_alloc (2);
21439 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21440 rtx upper = gen_reg_rtx (DImode);
21441 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21442 gen_rtvec (1, const0_rtx),
21444 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
21445 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21447 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21448 NULL, 1, OPTAB_DIRECT);
21449 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21453 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
21454 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21458 (define_insn "*rdpmc"
21459 [(set (match_operand:DI 0 "register_operand" "=A")
21460 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21464 [(set_attr "type" "other")
21465 (set_attr "length" "2")])
21467 (define_insn "*rdpmc_rex64"
21468 [(set (match_operand:DI 0 "register_operand" "=a")
21469 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21471 (set (match_operand:DI 1 "register_operand" "=d")
21472 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
21475 [(set_attr "type" "other")
21476 (set_attr "length" "2")])
21478 (define_expand "rdtsc"
21479 [(set (match_operand:DI 0 "register_operand" "")
21480 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21485 rtvec vec = rtvec_alloc (2);
21486 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21487 rtx upper = gen_reg_rtx (DImode);
21488 rtx lower = gen_reg_rtx (DImode);
21489 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
21490 gen_rtvec (1, const0_rtx),
21492 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
21493 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
21495 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21496 NULL, 1, OPTAB_DIRECT);
21497 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
21499 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
21504 (define_insn "*rdtsc"
21505 [(set (match_operand:DI 0 "register_operand" "=A")
21506 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21509 [(set_attr "type" "other")
21510 (set_attr "length" "2")])
21512 (define_insn "*rdtsc_rex64"
21513 [(set (match_operand:DI 0 "register_operand" "=a")
21514 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21515 (set (match_operand:DI 1 "register_operand" "=d")
21516 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21519 [(set_attr "type" "other")
21520 (set_attr "length" "2")])
21522 (define_expand "rdtscp"
21523 [(match_operand:DI 0 "register_operand" "")
21524 (match_operand:SI 1 "memory_operand" "")]
21527 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21528 gen_rtvec (1, const0_rtx),
21530 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21531 gen_rtvec (1, const0_rtx),
21533 rtx reg = gen_reg_rtx (DImode);
21534 rtx tmp = gen_reg_rtx (SImode);
21538 rtvec vec = rtvec_alloc (3);
21539 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21540 rtx upper = gen_reg_rtx (DImode);
21541 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21542 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21543 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
21545 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21546 NULL, 1, OPTAB_DIRECT);
21547 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21552 rtvec vec = rtvec_alloc (2);
21553 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21554 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21555 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
21558 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21559 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
21563 (define_insn "*rdtscp"
21564 [(set (match_operand:DI 0 "register_operand" "=A")
21565 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21566 (set (match_operand:SI 1 "register_operand" "=c")
21567 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21570 [(set_attr "type" "other")
21571 (set_attr "length" "3")])
21573 (define_insn "*rdtscp_rex64"
21574 [(set (match_operand:DI 0 "register_operand" "=a")
21575 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21576 (set (match_operand:DI 1 "register_operand" "=d")
21577 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21578 (set (match_operand:SI 2 "register_operand" "=c")
21579 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21582 [(set_attr "type" "other")
21583 (set_attr "length" "3")])
21585 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21587 ;; LWP instructions
21589 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21591 (define_insn "lwp_llwpcbhi1"
21592 [(unspec [(match_operand:HI 0 "register_operand" "r")]
21593 UNSPEC_LLWP_INTRINSIC)]
21596 [(set_attr "type" "lwp")
21597 (set_attr "mode" "HI")])
21599 (define_insn "lwp_llwpcbsi1"
21600 [(unspec [(match_operand:SI 0 "register_operand" "r")]
21601 UNSPEC_LLWP_INTRINSIC)]
21604 [(set_attr "type" "lwp")
21605 (set_attr "mode" "SI")])
21607 (define_insn "lwp_llwpcbdi1"
21608 [(unspec [(match_operand:DI 0 "register_operand" "r")]
21609 UNSPEC_LLWP_INTRINSIC)]
21612 [(set_attr "type" "lwp")
21613 (set_attr "mode" "DI")])
21615 (define_insn "lwp_slwpcbhi1"
21616 [(unspec [(match_operand:HI 0 "register_operand" "r")]
21617 UNSPEC_SLWP_INTRINSIC)]
21620 [(set_attr "type" "lwp")
21621 (set_attr "mode" "HI")])
21623 (define_insn "lwp_slwpcbsi1"
21624 [(unspec [(match_operand:SI 0 "register_operand" "r")]
21625 UNSPEC_SLWP_INTRINSIC)]
21628 [(set_attr "type" "lwp")
21629 (set_attr "mode" "SI")])
21631 (define_insn "lwp_slwpcbdi1"
21632 [(unspec [(match_operand:DI 0 "register_operand" "r")]
21633 UNSPEC_SLWP_INTRINSIC)]
21636 [(set_attr "type" "lwp")
21637 (set_attr "mode" "DI")])
21639 (define_insn "lwp_lwpvalhi3"
21640 [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21641 (match_operand:SI 1 "nonimmediate_operand" "rm")
21642 (match_operand:HI 2 "const_int_operand" "")]
21643 UNSPECV_LWPVAL_INTRINSIC)]
21645 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21646 [(set_attr "type" "lwp")
21647 (set_attr "mode" "HI")])
21649 (define_insn "lwp_lwpvalsi3"
21650 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21651 (match_operand:SI 1 "nonimmediate_operand" "rm")
21652 (match_operand:SI 2 "const_int_operand" "")]
21653 UNSPECV_LWPVAL_INTRINSIC)]
21655 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21656 [(set_attr "type" "lwp")
21657 (set_attr "mode" "SI")])
21659 (define_insn "lwp_lwpvaldi3"
21660 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21661 (match_operand:SI 1 "nonimmediate_operand" "rm")
21662 (match_operand:SI 2 "const_int_operand" "")]
21663 UNSPECV_LWPVAL_INTRINSIC)]
21665 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21666 [(set_attr "type" "lwp")
21667 (set_attr "mode" "DI")])
21669 (define_insn "lwp_lwpinshi3"
21670 [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21671 (match_operand:SI 1 "nonimmediate_operand" "rm")
21672 (match_operand:HI 2 "const_int_operand" "")]
21673 UNSPECV_LWPINS_INTRINSIC)]
21675 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21676 [(set_attr "type" "lwp")
21677 (set_attr "mode" "HI")])
21679 (define_insn "lwp_lwpinssi3"
21680 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21681 (match_operand:SI 1 "nonimmediate_operand" "rm")
21682 (match_operand:SI 2 "const_int_operand" "")]
21683 UNSPECV_LWPINS_INTRINSIC)]
21685 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21686 [(set_attr "type" "lwp")
21687 (set_attr "mode" "SI")])
21689 (define_insn "lwp_lwpinsdi3"
21690 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21691 (match_operand:SI 1 "nonimmediate_operand" "rm")
21692 (match_operand:SI 2 "const_int_operand" "")]
21693 UNSPECV_LWPINS_INTRINSIC)]
21695 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21696 [(set_attr "type" "lwp")
21697 (set_attr "mode" "DI")])
21701 (include "sync.md")