1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for XOP pcom* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
67 [; Relocation specifiers
78 (UNSPEC_MACHOPIC_OFFSET 10)
81 (UNSPEC_STACK_ALLOC 11)
83 (UNSPEC_SSE_PROLOGUE_SAVE 13)
87 (UNSPEC_SET_GOT_OFFSET 17)
88 (UNSPEC_MEMORY_BLOCKAGE 18)
93 (UNSPEC_TLS_LD_BASE 22)
96 ; Other random patterns
101 (UNSPEC_ADD_CARRY 34)
104 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
105 (UNSPEC_TRUNC_NOOP 39)
107 ; For SSE/MMX support:
108 (UNSPEC_FIX_NOTRUNC 40)
125 (UNSPEC_MS_TO_SYSV_CALL 48)
127 ; Generic math support
129 (UNSPEC_IEEE_MIN 51) ; not commutative
130 (UNSPEC_IEEE_MAX 52) ; not commutative
145 (UNSPEC_FRNDINT_FLOOR 70)
146 (UNSPEC_FRNDINT_CEIL 71)
147 (UNSPEC_FRNDINT_TRUNC 72)
148 (UNSPEC_FRNDINT_MASK_PM 73)
149 (UNSPEC_FIST_FLOOR 74)
150 (UNSPEC_FIST_CEIL 75)
152 ; x87 Double output FP
153 (UNSPEC_SINCOS_COS 80)
154 (UNSPEC_SINCOS_SIN 81)
155 (UNSPEC_XTRACT_FRACT 84)
156 (UNSPEC_XTRACT_EXP 85)
157 (UNSPEC_FSCALE_FRACT 86)
158 (UNSPEC_FSCALE_EXP 87)
170 (UNSPEC_SP_TLS_SET 102)
171 (UNSPEC_SP_TLS_TEST 103)
181 (UNSPEC_INSERTQI 132)
186 (UNSPEC_INSERTPS 135)
188 (UNSPEC_MOVNTDQA 137)
190 (UNSPEC_PHMINPOSUW 139)
196 (UNSPEC_PCMPESTR 144)
197 (UNSPEC_PCMPISTR 145)
200 (UNSPEC_FMA4_INTRINSIC 150)
201 (UNSPEC_FMA4_FMADDSUB 151)
202 (UNSPEC_FMA4_FMSUBADD 152)
203 (UNSPEC_XOP_UNSIGNED_CMP 151)
204 (UNSPEC_XOP_TRUEFALSE 152)
205 (UNSPEC_XOP_PERMUTE 153)
207 (UNSPEC_LLWP_INTRINSIC 155)
208 (UNSPEC_SLWP_INTRINSIC 156)
209 (UNSPECV_LWPVAL_INTRINSIC 157)
210 (UNSPECV_LWPINS_INTRINSIC 158)
214 (UNSPEC_AESENCLAST 160)
216 (UNSPEC_AESDECLAST 162)
218 (UNSPEC_AESKEYGENASSIST 164)
226 (UNSPEC_VPERMIL2F128 168)
227 (UNSPEC_MASKLOAD 169)
228 (UNSPEC_MASKSTORE 170)
234 [(UNSPECV_BLOCKAGE 0)
235 (UNSPECV_STACK_PROBE 1)
247 (UNSPECV_PROLOGUE_USE 14)
249 (UNSPECV_VZEROALL 16)
250 (UNSPECV_VZEROUPPER 17)
254 (UNSPECV_VSWAPMOV 21)
257 ;; Constants to represent pcomtrue/pcomfalse variants
267 ;; Constants used in the XOP pperm instruction
269 [(PPERM_SRC 0x00) /* copy source */
270 (PPERM_INVERT 0x20) /* invert source */
271 (PPERM_REVERSE 0x40) /* bit reverse source */
272 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
273 (PPERM_ZERO 0x80) /* all 0's */
274 (PPERM_ONES 0xa0) /* all 1's */
275 (PPERM_SIGN 0xc0) /* propagate sign bit */
276 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
277 (PPERM_SRC1 0x00) /* use first source byte */
278 (PPERM_SRC2 0x10) /* use second source byte */
281 ;; Registers by name.
334 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
337 ;; In C guard expressions, put expressions which may be compile-time
338 ;; constants first. This allows for better optimization. For
339 ;; example, write "TARGET_64BIT && reload_completed", not
340 ;; "reload_completed && TARGET_64BIT".
344 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
346 (const (symbol_ref "ix86_schedule")))
348 ;; A basic instruction type. Refinements due to arguments to be
349 ;; provided in other attributes.
352 alu,alu1,negnot,imov,imovx,lea,
353 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
354 icmp,test,ibr,setcc,icmov,
355 push,pop,call,callv,leave,
357 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
358 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
359 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
360 ssemuladd,sse4arg,lwp,
361 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
362 (const_string "other"))
364 ;; Main data type used by the insn
366 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
367 (const_string "unknown"))
369 ;; The CPU unit operations uses.
370 (define_attr "unit" "integer,i387,sse,mmx,unknown"
371 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
372 (const_string "i387")
373 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
374 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
375 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
377 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
379 (eq_attr "type" "other")
380 (const_string "unknown")]
381 (const_string "integer")))
383 ;; The (bounding maximum) length of an instruction immediate.
384 (define_attr "length_immediate" ""
385 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
388 (eq_attr "unit" "i387,sse,mmx")
390 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
392 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
393 (eq_attr "type" "imov,test")
394 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
395 (eq_attr "type" "call")
396 (if_then_else (match_operand 0 "constant_call_address_operand" "")
399 (eq_attr "type" "callv")
400 (if_then_else (match_operand 1 "constant_call_address_operand" "")
403 ;; We don't know the size before shorten_branches. Expect
404 ;; the instruction to fit for better scheduling.
405 (eq_attr "type" "ibr")
408 (symbol_ref "/* Update immediate_length and other attributes! */
409 gcc_unreachable (),1")))
411 ;; The (bounding maximum) length of an instruction address.
412 (define_attr "length_address" ""
413 (cond [(eq_attr "type" "str,other,multi,fxch")
415 (and (eq_attr "type" "call")
416 (match_operand 0 "constant_call_address_operand" ""))
418 (and (eq_attr "type" "callv")
419 (match_operand 1 "constant_call_address_operand" ""))
422 (symbol_ref "ix86_attr_length_address_default (insn)")))
424 ;; Set when length prefix is used.
425 (define_attr "prefix_data16" ""
426 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
428 (eq_attr "mode" "HI")
430 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
435 ;; Set when string REP prefix is used.
436 (define_attr "prefix_rep" ""
437 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
439 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
444 ;; Set when 0f opcode prefix is used.
445 (define_attr "prefix_0f" ""
447 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
448 (eq_attr "unit" "sse,mmx"))
452 ;; Set when REX opcode prefix is used.
453 (define_attr "prefix_rex" ""
454 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
456 (and (eq_attr "mode" "DI")
457 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
458 (eq_attr "unit" "!mmx")))
460 (and (eq_attr "mode" "QI")
461 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
464 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
467 (and (eq_attr "type" "imovx")
468 (match_operand:QI 1 "ext_QIreg_operand" ""))
473 ;; There are also additional prefixes in 3DNOW, SSSE3.
474 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
475 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
476 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
477 (define_attr "prefix_extra" ""
478 (cond [(eq_attr "type" "ssemuladd,sse4arg")
480 (eq_attr "type" "sseiadd1,ssecvt1")
485 ;; Prefix used: original, VEX or maybe VEX.
486 (define_attr "prefix" "orig,vex,maybe_vex"
487 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
489 (const_string "orig")))
491 ;; VEX W bit is used.
492 (define_attr "prefix_vex_w" "" (const_int 0))
494 ;; The length of VEX prefix
495 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
496 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
497 ;; still prefix_0f 1, with prefix_extra 1.
498 (define_attr "length_vex" ""
499 (if_then_else (and (eq_attr "prefix_0f" "1")
500 (eq_attr "prefix_extra" "0"))
501 (if_then_else (eq_attr "prefix_vex_w" "1")
502 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
503 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
504 (if_then_else (eq_attr "prefix_vex_w" "1")
505 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
506 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
508 ;; Set when modrm byte is used.
509 (define_attr "modrm" ""
510 (cond [(eq_attr "type" "str,leave")
512 (eq_attr "unit" "i387")
514 (and (eq_attr "type" "incdec")
515 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
516 (ior (match_operand:SI 1 "register_operand" "")
517 (match_operand:HI 1 "register_operand" ""))))
519 (and (eq_attr "type" "push")
520 (not (match_operand 1 "memory_operand" "")))
522 (and (eq_attr "type" "pop")
523 (not (match_operand 0 "memory_operand" "")))
525 (and (eq_attr "type" "imov")
526 (and (not (eq_attr "mode" "DI"))
527 (ior (and (match_operand 0 "register_operand" "")
528 (match_operand 1 "immediate_operand" ""))
529 (ior (and (match_operand 0 "ax_reg_operand" "")
530 (match_operand 1 "memory_displacement_only_operand" ""))
531 (and (match_operand 0 "memory_displacement_only_operand" "")
532 (match_operand 1 "ax_reg_operand" ""))))))
534 (and (eq_attr "type" "call")
535 (match_operand 0 "constant_call_address_operand" ""))
537 (and (eq_attr "type" "callv")
538 (match_operand 1 "constant_call_address_operand" ""))
540 (and (eq_attr "type" "alu,alu1,icmp,test")
541 (match_operand 0 "ax_reg_operand" ""))
542 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
546 ;; The (bounding maximum) length of an instruction in bytes.
547 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
548 ;; Later we may want to split them and compute proper length as for
550 (define_attr "length" ""
551 (cond [(eq_attr "type" "other,multi,fistp,frndint")
553 (eq_attr "type" "fcmp")
555 (eq_attr "unit" "i387")
557 (plus (attr "prefix_data16")
558 (attr "length_address")))
559 (ior (eq_attr "prefix" "vex")
560 (and (eq_attr "prefix" "maybe_vex")
561 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
562 (plus (attr "length_vex")
563 (plus (attr "length_immediate")
565 (attr "length_address"))))]
566 (plus (plus (attr "modrm")
567 (plus (attr "prefix_0f")
568 (plus (attr "prefix_rex")
569 (plus (attr "prefix_extra")
571 (plus (attr "prefix_rep")
572 (plus (attr "prefix_data16")
573 (plus (attr "length_immediate")
574 (attr "length_address")))))))
576 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
577 ;; `store' if there is a simple memory reference therein, or `unknown'
578 ;; if the instruction is complex.
580 (define_attr "memory" "none,load,store,both,unknown"
581 (cond [(eq_attr "type" "other,multi,str")
582 (const_string "unknown")
583 (eq_attr "type" "lea,fcmov,fpspc")
584 (const_string "none")
585 (eq_attr "type" "fistp,leave")
586 (const_string "both")
587 (eq_attr "type" "frndint")
588 (const_string "load")
589 (eq_attr "type" "push")
590 (if_then_else (match_operand 1 "memory_operand" "")
591 (const_string "both")
592 (const_string "store"))
593 (eq_attr "type" "pop")
594 (if_then_else (match_operand 0 "memory_operand" "")
595 (const_string "both")
596 (const_string "load"))
597 (eq_attr "type" "setcc")
598 (if_then_else (match_operand 0 "memory_operand" "")
599 (const_string "store")
600 (const_string "none"))
601 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
602 (if_then_else (ior (match_operand 0 "memory_operand" "")
603 (match_operand 1 "memory_operand" ""))
604 (const_string "load")
605 (const_string "none"))
606 (eq_attr "type" "ibr")
607 (if_then_else (match_operand 0 "memory_operand" "")
608 (const_string "load")
609 (const_string "none"))
610 (eq_attr "type" "call")
611 (if_then_else (match_operand 0 "constant_call_address_operand" "")
612 (const_string "none")
613 (const_string "load"))
614 (eq_attr "type" "callv")
615 (if_then_else (match_operand 1 "constant_call_address_operand" "")
616 (const_string "none")
617 (const_string "load"))
618 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
619 (match_operand 1 "memory_operand" ""))
620 (const_string "both")
621 (and (match_operand 0 "memory_operand" "")
622 (match_operand 1 "memory_operand" ""))
623 (const_string "both")
624 (match_operand 0 "memory_operand" "")
625 (const_string "store")
626 (match_operand 1 "memory_operand" "")
627 (const_string "load")
629 "!alu1,negnot,ishift1,
630 imov,imovx,icmp,test,bitmanip,
632 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
633 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
634 (match_operand 2 "memory_operand" ""))
635 (const_string "load")
636 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
637 (match_operand 3 "memory_operand" ""))
638 (const_string "load")
640 (const_string "none")))
642 ;; Indicates if an instruction has both an immediate and a displacement.
644 (define_attr "imm_disp" "false,true,unknown"
645 (cond [(eq_attr "type" "other,multi")
646 (const_string "unknown")
647 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
648 (and (match_operand 0 "memory_displacement_operand" "")
649 (match_operand 1 "immediate_operand" "")))
650 (const_string "true")
651 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
652 (and (match_operand 0 "memory_displacement_operand" "")
653 (match_operand 2 "immediate_operand" "")))
654 (const_string "true")
656 (const_string "false")))
658 ;; Indicates if an FP operation has an integer source.
660 (define_attr "fp_int_src" "false,true"
661 (const_string "false"))
663 ;; Defines rounding mode of an FP operation.
665 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
666 (const_string "any"))
668 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
669 (define_attr "use_carry" "0,1" (const_string "0"))
671 ;; Define attribute to indicate unaligned ssemov insns
672 (define_attr "movu" "0,1" (const_string "0"))
674 ;; Describe a user's asm statement.
675 (define_asm_attributes
676 [(set_attr "length" "128")
677 (set_attr "type" "multi")])
679 ;; All integer comparison codes.
680 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
682 ;; All floating-point comparison codes.
683 (define_code_iterator fp_cond [unordered ordered
684 uneq unge ungt unle unlt ltgt ])
686 (define_code_iterator plusminus [plus minus])
688 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
690 ;; Base name for define_insn
691 (define_code_attr plusminus_insn
692 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
693 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
695 ;; Base name for insn mnemonic.
696 (define_code_attr plusminus_mnemonic
697 [(plus "add") (ss_plus "adds") (us_plus "addus")
698 (minus "sub") (ss_minus "subs") (us_minus "subus")])
699 (define_code_attr plusminus_carry_mnemonic
700 [(plus "adc") (minus "sbb")])
702 ;; Mark commutative operators as such in constraints.
703 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
704 (minus "") (ss_minus "") (us_minus "")])
706 ;; Mapping of signed max and min
707 (define_code_iterator smaxmin [smax smin])
709 ;; Mapping of unsigned max and min
710 (define_code_iterator umaxmin [umax umin])
712 ;; Mapping of signed/unsigned max and min
713 (define_code_iterator maxmin [smax smin umax umin])
715 ;; Base name for integer and FP insn mnemonic
716 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
717 (umax "maxu") (umin "minu")])
718 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
720 ;; Mapping of parallel logic operators
721 (define_code_iterator plogic [and ior xor])
723 ;; Base name for insn mnemonic.
724 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
726 ;; Mapping of abs neg operators
727 (define_code_iterator absneg [abs neg])
729 ;; Base name for x87 insn mnemonic.
730 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
732 ;; Used in signed and unsigned widening multiplications.
733 (define_code_iterator any_extend [sign_extend zero_extend])
735 ;; Used in signed and unsigned divisions.
736 (define_code_iterator any_div [div udiv])
738 ;; Various insn prefixes for signed and unsigned operations.
739 (define_code_attr u [(sign_extend "") (zero_extend "u")
740 (div "") (udiv "u")])
741 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
743 ;; Instruction prefix for signed and unsigned operations.
744 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
745 (div "i") (udiv "")])
747 ;; All single word integer modes.
748 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
750 ;; Single word integer modes without DImode.
751 (define_mode_iterator SWI124 [QI HI SI])
753 ;; Single word integer modes without QImode.
754 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
756 ;; Single word integer modes without QImode and HImode.
757 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
759 ;; All math-dependant single and double word integer modes.
760 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
761 (HI "TARGET_HIMODE_MATH")
762 SI DI (TI "TARGET_64BIT")])
764 ;; Math-dependant single word integer modes.
765 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
766 (HI "TARGET_HIMODE_MATH")
767 SI (DI "TARGET_64BIT")])
769 ;; Math-dependant single word integer modes without QImode.
770 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
771 SI (DI "TARGET_64BIT")])
773 ;; Half mode for double word integer modes.
774 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
775 (DI "TARGET_64BIT")])
777 ;; Double word integer modes.
778 (define_mode_attr DWI [(SI "DI") (DI "TI")])
779 (define_mode_attr dwi [(SI "di") (DI "ti")])
781 ;; Instruction suffix for integer modes.
782 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
784 ;; Register class for integer modes.
785 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
787 ;; Immediate operand constraint for integer modes.
788 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
790 ;; General operand constraint for word modes.
791 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
793 ;; Immediate operand constraint for double integer modes.
794 (define_mode_attr di [(SI "iF") (DI "e")])
796 ;; General operand predicate for integer modes.
797 (define_mode_attr general_operand
798 [(QI "general_operand")
799 (HI "general_operand")
800 (SI "general_operand")
801 (DI "x86_64_general_operand")
802 (TI "x86_64_general_operand")])
804 ;; General sign/zero extend operand predicate for integer modes.
805 (define_mode_attr general_szext_operand
806 [(QI "general_operand")
807 (HI "general_operand")
808 (SI "general_operand")
809 (DI "x86_64_szext_general_operand")])
811 ;; SSE and x87 SFmode and DFmode floating point modes
812 (define_mode_iterator MODEF [SF DF])
814 ;; All x87 floating point modes
815 (define_mode_iterator X87MODEF [SF DF XF])
817 ;; All integer modes handled by x87 fisttp operator.
818 (define_mode_iterator X87MODEI [HI SI DI])
820 ;; All integer modes handled by integer x87 operators.
821 (define_mode_iterator X87MODEI12 [HI SI])
823 ;; All integer modes handled by SSE cvtts?2si* operators.
824 (define_mode_iterator SSEMODEI24 [SI DI])
826 ;; SSE asm suffix for floating point modes
827 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
829 ;; SSE vector mode corresponding to a scalar mode
830 (define_mode_attr ssevecmode
831 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
833 ;; Instruction suffix for REX 64bit operators.
834 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
836 ;; This mode iterator allows :P to be used for patterns that operate on
837 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
838 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
840 ;; Scheduling descriptions
842 (include "pentium.md")
845 (include "athlon.md")
850 ;; Operand and operator predicates and constraints
852 (include "predicates.md")
853 (include "constraints.md")
856 ;; Compare and branch/compare and store instructions.
858 (define_expand "cbranch<mode>4"
859 [(set (reg:CC FLAGS_REG)
860 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
861 (match_operand:SDWIM 2 "<general_operand>" "")))
862 (set (pc) (if_then_else
863 (match_operator 0 "comparison_operator"
864 [(reg:CC FLAGS_REG) (const_int 0)])
865 (label_ref (match_operand 3 "" ""))
869 if (MEM_P (operands[1]) && MEM_P (operands[2]))
870 operands[1] = force_reg (<MODE>mode, operands[1]);
871 ix86_compare_op0 = operands[1];
872 ix86_compare_op1 = operands[2];
873 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
877 (define_expand "cstore<mode>4"
878 [(set (reg:CC FLAGS_REG)
879 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
880 (match_operand:SWIM 3 "<general_operand>" "")))
881 (set (match_operand:QI 0 "register_operand" "")
882 (match_operator 1 "comparison_operator"
883 [(reg:CC FLAGS_REG) (const_int 0)]))]
886 if (MEM_P (operands[2]) && MEM_P (operands[3]))
887 operands[2] = force_reg (<MODE>mode, operands[2]);
888 ix86_compare_op0 = operands[2];
889 ix86_compare_op1 = operands[3];
890 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
894 (define_expand "cmp<mode>_1"
895 [(set (reg:CC FLAGS_REG)
896 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
897 (match_operand:SWI48 1 "<general_operand>" "")))]
901 (define_insn "*cmp<mode>_ccno_1"
902 [(set (reg FLAGS_REG)
903 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
904 (match_operand:SWI 1 "const0_operand" "")))]
905 "ix86_match_ccmode (insn, CCNOmode)"
907 test{<imodesuffix>}\t%0, %0
908 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
909 [(set_attr "type" "test,icmp")
910 (set_attr "length_immediate" "0,1")
911 (set_attr "mode" "<MODE>")])
913 (define_insn "*cmp<mode>_1"
914 [(set (reg FLAGS_REG)
915 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
916 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
917 "ix86_match_ccmode (insn, CCmode)"
918 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
919 [(set_attr "type" "icmp")
920 (set_attr "mode" "<MODE>")])
922 (define_insn "*cmp<mode>_minus_1"
923 [(set (reg FLAGS_REG)
925 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
926 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
928 "ix86_match_ccmode (insn, CCGOCmode)"
929 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
930 [(set_attr "type" "icmp")
931 (set_attr "mode" "<MODE>")])
933 (define_insn "*cmpqi_ext_1"
934 [(set (reg FLAGS_REG)
936 (match_operand:QI 0 "general_operand" "Qm")
939 (match_operand 1 "ext_register_operand" "Q")
942 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
943 "cmp{b}\t{%h1, %0|%0, %h1}"
944 [(set_attr "type" "icmp")
945 (set_attr "mode" "QI")])
947 (define_insn "*cmpqi_ext_1_rex64"
948 [(set (reg FLAGS_REG)
950 (match_operand:QI 0 "register_operand" "Q")
953 (match_operand 1 "ext_register_operand" "Q")
956 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
957 "cmp{b}\t{%h1, %0|%0, %h1}"
958 [(set_attr "type" "icmp")
959 (set_attr "mode" "QI")])
961 (define_insn "*cmpqi_ext_2"
962 [(set (reg FLAGS_REG)
966 (match_operand 0 "ext_register_operand" "Q")
969 (match_operand:QI 1 "const0_operand" "")))]
970 "ix86_match_ccmode (insn, CCNOmode)"
972 [(set_attr "type" "test")
973 (set_attr "length_immediate" "0")
974 (set_attr "mode" "QI")])
976 (define_expand "cmpqi_ext_3"
977 [(set (reg:CC FLAGS_REG)
981 (match_operand 0 "ext_register_operand" "")
984 (match_operand:QI 1 "immediate_operand" "")))]
988 (define_insn "*cmpqi_ext_3_insn"
989 [(set (reg FLAGS_REG)
993 (match_operand 0 "ext_register_operand" "Q")
996 (match_operand:QI 1 "general_operand" "Qmn")))]
997 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
998 "cmp{b}\t{%1, %h0|%h0, %1}"
999 [(set_attr "type" "icmp")
1000 (set_attr "modrm" "1")
1001 (set_attr "mode" "QI")])
1003 (define_insn "*cmpqi_ext_3_insn_rex64"
1004 [(set (reg FLAGS_REG)
1008 (match_operand 0 "ext_register_operand" "Q")
1011 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1012 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1013 "cmp{b}\t{%1, %h0|%h0, %1}"
1014 [(set_attr "type" "icmp")
1015 (set_attr "modrm" "1")
1016 (set_attr "mode" "QI")])
1018 (define_insn "*cmpqi_ext_4"
1019 [(set (reg FLAGS_REG)
1023 (match_operand 0 "ext_register_operand" "Q")
1028 (match_operand 1 "ext_register_operand" "Q")
1030 (const_int 8)) 0)))]
1031 "ix86_match_ccmode (insn, CCmode)"
1032 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1033 [(set_attr "type" "icmp")
1034 (set_attr "mode" "QI")])
1036 ;; These implement float point compares.
1037 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1038 ;; which would allow mix and match FP modes on the compares. Which is what
1039 ;; the old patterns did, but with many more of them.
1041 (define_expand "cbranchxf4"
1042 [(set (reg:CC FLAGS_REG)
1043 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1044 (match_operand:XF 2 "nonmemory_operand" "")))
1045 (set (pc) (if_then_else
1046 (match_operator 0 "ix86_fp_comparison_operator"
1049 (label_ref (match_operand 3 "" ""))
1053 ix86_compare_op0 = operands[1];
1054 ix86_compare_op1 = operands[2];
1055 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1059 (define_expand "cstorexf4"
1060 [(set (reg:CC FLAGS_REG)
1061 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1062 (match_operand:XF 3 "nonmemory_operand" "")))
1063 (set (match_operand:QI 0 "register_operand" "")
1064 (match_operator 1 "ix86_fp_comparison_operator"
1069 ix86_compare_op0 = operands[2];
1070 ix86_compare_op1 = operands[3];
1071 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1075 (define_expand "cbranch<mode>4"
1076 [(set (reg:CC FLAGS_REG)
1077 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1078 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1079 (set (pc) (if_then_else
1080 (match_operator 0 "ix86_fp_comparison_operator"
1083 (label_ref (match_operand 3 "" ""))
1085 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1087 ix86_compare_op0 = operands[1];
1088 ix86_compare_op1 = operands[2];
1089 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1093 (define_expand "cstore<mode>4"
1094 [(set (reg:CC FLAGS_REG)
1095 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1096 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1097 (set (match_operand:QI 0 "register_operand" "")
1098 (match_operator 1 "ix86_fp_comparison_operator"
1101 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1103 ix86_compare_op0 = operands[2];
1104 ix86_compare_op1 = operands[3];
1105 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1109 (define_expand "cbranchcc4"
1110 [(set (pc) (if_then_else
1111 (match_operator 0 "comparison_operator"
1112 [(match_operand 1 "flags_reg_operand" "")
1113 (match_operand 2 "const0_operand" "")])
1114 (label_ref (match_operand 3 "" ""))
1118 ix86_compare_op0 = operands[1];
1119 ix86_compare_op1 = operands[2];
1120 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1124 (define_expand "cstorecc4"
1125 [(set (match_operand:QI 0 "register_operand" "")
1126 (match_operator 1 "comparison_operator"
1127 [(match_operand 2 "flags_reg_operand" "")
1128 (match_operand 3 "const0_operand" "")]))]
1131 ix86_compare_op0 = operands[2];
1132 ix86_compare_op1 = operands[3];
1133 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1138 ;; FP compares, step 1:
1139 ;; Set the FP condition codes.
1141 ;; CCFPmode compare with exceptions
1142 ;; CCFPUmode compare with no exceptions
1144 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1145 ;; used to manage the reg stack popping would not be preserved.
1147 (define_insn "*cmpfp_0"
1148 [(set (match_operand:HI 0 "register_operand" "=a")
1151 (match_operand 1 "register_operand" "f")
1152 (match_operand 2 "const0_operand" ""))]
1154 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1155 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1156 "* return output_fp_compare (insn, operands, 0, 0);"
1157 [(set_attr "type" "multi")
1158 (set_attr "unit" "i387")
1160 (cond [(match_operand:SF 1 "" "")
1162 (match_operand:DF 1 "" "")
1165 (const_string "XF")))])
1167 (define_insn_and_split "*cmpfp_0_cc"
1168 [(set (reg:CCFP FLAGS_REG)
1170 (match_operand 1 "register_operand" "f")
1171 (match_operand 2 "const0_operand" "")))
1172 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1173 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1174 && TARGET_SAHF && !TARGET_CMOVE
1175 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1177 "&& reload_completed"
1180 [(compare:CCFP (match_dup 1)(match_dup 2))]
1182 (set (reg:CC FLAGS_REG)
1183 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1185 [(set_attr "type" "multi")
1186 (set_attr "unit" "i387")
1188 (cond [(match_operand:SF 1 "" "")
1190 (match_operand:DF 1 "" "")
1193 (const_string "XF")))])
1195 (define_insn "*cmpfp_xf"
1196 [(set (match_operand:HI 0 "register_operand" "=a")
1199 (match_operand:XF 1 "register_operand" "f")
1200 (match_operand:XF 2 "register_operand" "f"))]
1203 "* return output_fp_compare (insn, operands, 0, 0);"
1204 [(set_attr "type" "multi")
1205 (set_attr "unit" "i387")
1206 (set_attr "mode" "XF")])
1208 (define_insn_and_split "*cmpfp_xf_cc"
1209 [(set (reg:CCFP FLAGS_REG)
1211 (match_operand:XF 1 "register_operand" "f")
1212 (match_operand:XF 2 "register_operand" "f")))
1213 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1215 && TARGET_SAHF && !TARGET_CMOVE"
1217 "&& reload_completed"
1220 [(compare:CCFP (match_dup 1)(match_dup 2))]
1222 (set (reg:CC FLAGS_REG)
1223 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1225 [(set_attr "type" "multi")
1226 (set_attr "unit" "i387")
1227 (set_attr "mode" "XF")])
1229 (define_insn "*cmpfp_<mode>"
1230 [(set (match_operand:HI 0 "register_operand" "=a")
1233 (match_operand:MODEF 1 "register_operand" "f")
1234 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1237 "* return output_fp_compare (insn, operands, 0, 0);"
1238 [(set_attr "type" "multi")
1239 (set_attr "unit" "i387")
1240 (set_attr "mode" "<MODE>")])
1242 (define_insn_and_split "*cmpfp_<mode>_cc"
1243 [(set (reg:CCFP FLAGS_REG)
1245 (match_operand:MODEF 1 "register_operand" "f")
1246 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1247 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1249 && TARGET_SAHF && !TARGET_CMOVE"
1251 "&& reload_completed"
1254 [(compare:CCFP (match_dup 1)(match_dup 2))]
1256 (set (reg:CC FLAGS_REG)
1257 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1259 [(set_attr "type" "multi")
1260 (set_attr "unit" "i387")
1261 (set_attr "mode" "<MODE>")])
1263 (define_insn "*cmpfp_u"
1264 [(set (match_operand:HI 0 "register_operand" "=a")
1267 (match_operand 1 "register_operand" "f")
1268 (match_operand 2 "register_operand" "f"))]
1270 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1271 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1272 "* return output_fp_compare (insn, operands, 0, 1);"
1273 [(set_attr "type" "multi")
1274 (set_attr "unit" "i387")
1276 (cond [(match_operand:SF 1 "" "")
1278 (match_operand:DF 1 "" "")
1281 (const_string "XF")))])
1283 (define_insn_and_split "*cmpfp_u_cc"
1284 [(set (reg:CCFPU FLAGS_REG)
1286 (match_operand 1 "register_operand" "f")
1287 (match_operand 2 "register_operand" "f")))
1288 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1289 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1290 && TARGET_SAHF && !TARGET_CMOVE
1291 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1293 "&& reload_completed"
1296 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1298 (set (reg:CC FLAGS_REG)
1299 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1301 [(set_attr "type" "multi")
1302 (set_attr "unit" "i387")
1304 (cond [(match_operand:SF 1 "" "")
1306 (match_operand:DF 1 "" "")
1309 (const_string "XF")))])
1311 (define_insn "*cmpfp_<mode>"
1312 [(set (match_operand:HI 0 "register_operand" "=a")
1315 (match_operand 1 "register_operand" "f")
1316 (match_operator 3 "float_operator"
1317 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1319 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1320 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1321 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1322 "* return output_fp_compare (insn, operands, 0, 0);"
1323 [(set_attr "type" "multi")
1324 (set_attr "unit" "i387")
1325 (set_attr "fp_int_src" "true")
1326 (set_attr "mode" "<MODE>")])
1328 (define_insn_and_split "*cmpfp_<mode>_cc"
1329 [(set (reg:CCFP FLAGS_REG)
1331 (match_operand 1 "register_operand" "f")
1332 (match_operator 3 "float_operator"
1333 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1334 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1335 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1336 && TARGET_SAHF && !TARGET_CMOVE
1337 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1338 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1340 "&& reload_completed"
1345 (match_op_dup 3 [(match_dup 2)]))]
1347 (set (reg:CC FLAGS_REG)
1348 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1350 [(set_attr "type" "multi")
1351 (set_attr "unit" "i387")
1352 (set_attr "fp_int_src" "true")
1353 (set_attr "mode" "<MODE>")])
1355 ;; FP compares, step 2
1356 ;; Move the fpsw to ax.
1358 (define_insn "x86_fnstsw_1"
1359 [(set (match_operand:HI 0 "register_operand" "=a")
1360 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1363 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1364 (set_attr "mode" "SI")
1365 (set_attr "unit" "i387")])
1367 ;; FP compares, step 3
1368 ;; Get ax into flags, general case.
1370 (define_insn "x86_sahf_1"
1371 [(set (reg:CC FLAGS_REG)
1372 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1376 #ifdef HAVE_AS_IX86_SAHF
1379 return ASM_BYTE "0x9e";
1382 [(set_attr "length" "1")
1383 (set_attr "athlon_decode" "vector")
1384 (set_attr "amdfam10_decode" "direct")
1385 (set_attr "mode" "SI")])
1387 ;; Pentium Pro can do steps 1 through 3 in one go.
1388 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1389 (define_insn "*cmpfp_i_mixed"
1390 [(set (reg:CCFP FLAGS_REG)
1391 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1392 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1393 "TARGET_MIX_SSE_I387
1394 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1395 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1396 "* return output_fp_compare (insn, operands, 1, 0);"
1397 [(set_attr "type" "fcmp,ssecomi")
1398 (set_attr "prefix" "orig,maybe_vex")
1400 (if_then_else (match_operand:SF 1 "" "")
1402 (const_string "DF")))
1403 (set (attr "prefix_rep")
1404 (if_then_else (eq_attr "type" "ssecomi")
1406 (const_string "*")))
1407 (set (attr "prefix_data16")
1408 (cond [(eq_attr "type" "fcmp")
1410 (eq_attr "mode" "DF")
1413 (const_string "0")))
1414 (set_attr "athlon_decode" "vector")
1415 (set_attr "amdfam10_decode" "direct")])
1417 (define_insn "*cmpfp_i_sse"
1418 [(set (reg:CCFP FLAGS_REG)
1419 (compare:CCFP (match_operand 0 "register_operand" "x")
1420 (match_operand 1 "nonimmediate_operand" "xm")))]
1422 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1423 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1424 "* return output_fp_compare (insn, operands, 1, 0);"
1425 [(set_attr "type" "ssecomi")
1426 (set_attr "prefix" "maybe_vex")
1428 (if_then_else (match_operand:SF 1 "" "")
1430 (const_string "DF")))
1431 (set_attr "prefix_rep" "0")
1432 (set (attr "prefix_data16")
1433 (if_then_else (eq_attr "mode" "DF")
1435 (const_string "0")))
1436 (set_attr "athlon_decode" "vector")
1437 (set_attr "amdfam10_decode" "direct")])
1439 (define_insn "*cmpfp_i_i387"
1440 [(set (reg:CCFP FLAGS_REG)
1441 (compare:CCFP (match_operand 0 "register_operand" "f")
1442 (match_operand 1 "register_operand" "f")))]
1443 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1445 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1446 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1447 "* return output_fp_compare (insn, operands, 1, 0);"
1448 [(set_attr "type" "fcmp")
1450 (cond [(match_operand:SF 1 "" "")
1452 (match_operand:DF 1 "" "")
1455 (const_string "XF")))
1456 (set_attr "athlon_decode" "vector")
1457 (set_attr "amdfam10_decode" "direct")])
1459 (define_insn "*cmpfp_iu_mixed"
1460 [(set (reg:CCFPU FLAGS_REG)
1461 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1462 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1463 "TARGET_MIX_SSE_I387
1464 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1465 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1466 "* return output_fp_compare (insn, operands, 1, 1);"
1467 [(set_attr "type" "fcmp,ssecomi")
1468 (set_attr "prefix" "orig,maybe_vex")
1470 (if_then_else (match_operand:SF 1 "" "")
1472 (const_string "DF")))
1473 (set (attr "prefix_rep")
1474 (if_then_else (eq_attr "type" "ssecomi")
1476 (const_string "*")))
1477 (set (attr "prefix_data16")
1478 (cond [(eq_attr "type" "fcmp")
1480 (eq_attr "mode" "DF")
1483 (const_string "0")))
1484 (set_attr "athlon_decode" "vector")
1485 (set_attr "amdfam10_decode" "direct")])
1487 (define_insn "*cmpfp_iu_sse"
1488 [(set (reg:CCFPU FLAGS_REG)
1489 (compare:CCFPU (match_operand 0 "register_operand" "x")
1490 (match_operand 1 "nonimmediate_operand" "xm")))]
1492 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1493 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1494 "* return output_fp_compare (insn, operands, 1, 1);"
1495 [(set_attr "type" "ssecomi")
1496 (set_attr "prefix" "maybe_vex")
1498 (if_then_else (match_operand:SF 1 "" "")
1500 (const_string "DF")))
1501 (set_attr "prefix_rep" "0")
1502 (set (attr "prefix_data16")
1503 (if_then_else (eq_attr "mode" "DF")
1505 (const_string "0")))
1506 (set_attr "athlon_decode" "vector")
1507 (set_attr "amdfam10_decode" "direct")])
1509 (define_insn "*cmpfp_iu_387"
1510 [(set (reg:CCFPU FLAGS_REG)
1511 (compare:CCFPU (match_operand 0 "register_operand" "f")
1512 (match_operand 1 "register_operand" "f")))]
1513 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1515 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1516 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1517 "* return output_fp_compare (insn, operands, 1, 1);"
1518 [(set_attr "type" "fcmp")
1520 (cond [(match_operand:SF 1 "" "")
1522 (match_operand:DF 1 "" "")
1525 (const_string "XF")))
1526 (set_attr "athlon_decode" "vector")
1527 (set_attr "amdfam10_decode" "direct")])
1529 ;; Move instructions.
1531 ;; General case of fullword move.
1533 (define_expand "movsi"
1534 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1535 (match_operand:SI 1 "general_operand" ""))]
1537 "ix86_expand_move (SImode, operands); DONE;")
1539 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1542 ;; %%% We don't use a post-inc memory reference because x86 is not a
1543 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1544 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1545 ;; targets without our curiosities, and it is just as easy to represent
1546 ;; this differently.
1548 (define_insn "*pushsi2"
1549 [(set (match_operand:SI 0 "push_operand" "=<")
1550 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1553 [(set_attr "type" "push")
1554 (set_attr "mode" "SI")])
1556 ;; For 64BIT abi we always round up to 8 bytes.
1557 (define_insn "*pushsi2_rex64"
1558 [(set (match_operand:SI 0 "push_operand" "=X")
1559 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1562 [(set_attr "type" "push")
1563 (set_attr "mode" "SI")])
1565 (define_insn "*pushsi2_prologue"
1566 [(set (match_operand:SI 0 "push_operand" "=<")
1567 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1568 (clobber (mem:BLK (scratch)))]
1571 [(set_attr "type" "push")
1572 (set_attr "mode" "SI")])
1574 (define_insn "*popsi1_epilogue"
1575 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1576 (mem:SI (reg:SI SP_REG)))
1577 (set (reg:SI SP_REG)
1578 (plus:SI (reg:SI SP_REG) (const_int 4)))
1579 (clobber (mem:BLK (scratch)))]
1582 [(set_attr "type" "pop")
1583 (set_attr "mode" "SI")])
1585 (define_insn "popsi1"
1586 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1587 (mem:SI (reg:SI SP_REG)))
1588 (set (reg:SI SP_REG)
1589 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1592 [(set_attr "type" "pop")
1593 (set_attr "mode" "SI")])
1595 (define_insn "*movsi_xor"
1596 [(set (match_operand:SI 0 "register_operand" "=r")
1597 (match_operand:SI 1 "const0_operand" ""))
1598 (clobber (reg:CC FLAGS_REG))]
1601 [(set_attr "type" "alu1")
1602 (set_attr "mode" "SI")
1603 (set_attr "length_immediate" "0")])
1605 (define_insn "*movsi_or"
1606 [(set (match_operand:SI 0 "register_operand" "=r")
1607 (match_operand:SI 1 "immediate_operand" "i"))
1608 (clobber (reg:CC FLAGS_REG))]
1610 && operands[1] == constm1_rtx"
1612 operands[1] = constm1_rtx;
1613 return "or{l}\t{%1, %0|%0, %1}";
1615 [(set_attr "type" "alu1")
1616 (set_attr "mode" "SI")
1617 (set_attr "length_immediate" "1")])
1619 (define_insn "*movsi_1"
1620 [(set (match_operand:SI 0 "nonimmediate_operand"
1621 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1622 (match_operand:SI 1 "general_operand"
1623 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1624 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1626 switch (get_attr_type (insn))
1629 if (get_attr_mode (insn) == MODE_TI)
1630 return "%vpxor\t%0, %d0";
1631 return "%vxorps\t%0, %d0";
1634 switch (get_attr_mode (insn))
1637 return "%vmovdqa\t{%1, %0|%0, %1}";
1639 return "%vmovaps\t{%1, %0|%0, %1}";
1641 return "%vmovd\t{%1, %0|%0, %1}";
1643 return "%vmovss\t{%1, %0|%0, %1}";
1649 return "pxor\t%0, %0";
1652 if (get_attr_mode (insn) == MODE_DI)
1653 return "movq\t{%1, %0|%0, %1}";
1654 return "movd\t{%1, %0|%0, %1}";
1657 return "lea{l}\t{%1, %0|%0, %1}";
1660 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1661 return "mov{l}\t{%1, %0|%0, %1}";
1665 (cond [(eq_attr "alternative" "2")
1666 (const_string "mmx")
1667 (eq_attr "alternative" "3,4,5")
1668 (const_string "mmxmov")
1669 (eq_attr "alternative" "6")
1670 (const_string "sselog1")
1671 (eq_attr "alternative" "7,8,9,10,11")
1672 (const_string "ssemov")
1673 (match_operand:DI 1 "pic_32bit_operand" "")
1674 (const_string "lea")
1676 (const_string "imov")))
1677 (set (attr "prefix")
1678 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1679 (const_string "orig")
1680 (const_string "maybe_vex")))
1681 (set (attr "prefix_data16")
1682 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1684 (const_string "*")))
1686 (cond [(eq_attr "alternative" "2,3")
1688 (eq_attr "alternative" "6,7")
1690 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1691 (const_string "V4SF")
1692 (const_string "TI"))
1693 (and (eq_attr "alternative" "8,9,10,11")
1694 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1697 (const_string "SI")))])
1699 ;; Stores and loads of ax to arbitrary constant address.
1700 ;; We fake an second form of instruction to force reload to load address
1701 ;; into register when rax is not available
1702 (define_insn "*movabssi_1_rex64"
1703 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1704 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1705 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1707 movabs{l}\t{%1, %P0|%P0, %1}
1708 mov{l}\t{%1, %a0|%a0, %1}"
1709 [(set_attr "type" "imov")
1710 (set_attr "modrm" "0,*")
1711 (set_attr "length_address" "8,0")
1712 (set_attr "length_immediate" "0,*")
1713 (set_attr "memory" "store")
1714 (set_attr "mode" "SI")])
1716 (define_insn "*movabssi_2_rex64"
1717 [(set (match_operand:SI 0 "register_operand" "=a,r")
1718 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1719 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1721 movabs{l}\t{%P1, %0|%0, %P1}
1722 mov{l}\t{%a1, %0|%0, %a1}"
1723 [(set_attr "type" "imov")
1724 (set_attr "modrm" "0,*")
1725 (set_attr "length_address" "8,0")
1726 (set_attr "length_immediate" "0")
1727 (set_attr "memory" "load")
1728 (set_attr "mode" "SI")])
1730 (define_insn "*swapsi"
1731 [(set (match_operand:SI 0 "register_operand" "+r")
1732 (match_operand:SI 1 "register_operand" "+r"))
1737 [(set_attr "type" "imov")
1738 (set_attr "mode" "SI")
1739 (set_attr "pent_pair" "np")
1740 (set_attr "athlon_decode" "vector")
1741 (set_attr "amdfam10_decode" "double")])
1743 (define_expand "movhi"
1744 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1745 (match_operand:HI 1 "general_operand" ""))]
1747 "ix86_expand_move (HImode, operands); DONE;")
1749 (define_insn "*pushhi2"
1750 [(set (match_operand:HI 0 "push_operand" "=X")
1751 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1754 [(set_attr "type" "push")
1755 (set_attr "mode" "SI")])
1757 ;; For 64BIT abi we always round up to 8 bytes.
1758 (define_insn "*pushhi2_rex64"
1759 [(set (match_operand:HI 0 "push_operand" "=X")
1760 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1763 [(set_attr "type" "push")
1764 (set_attr "mode" "DI")])
1766 (define_insn "*movhi_1"
1767 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1768 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1769 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1771 switch (get_attr_type (insn))
1774 /* movzwl is faster than movw on p2 due to partial word stalls,
1775 though not as fast as an aligned movl. */
1776 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1778 if (get_attr_mode (insn) == MODE_SI)
1779 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1781 return "mov{w}\t{%1, %0|%0, %1}";
1785 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1786 (const_string "imov")
1787 (and (eq_attr "alternative" "0")
1788 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1790 (eq (symbol_ref "TARGET_HIMODE_MATH")
1792 (const_string "imov")
1793 (and (eq_attr "alternative" "1,2")
1794 (match_operand:HI 1 "aligned_operand" ""))
1795 (const_string "imov")
1796 (and (ne (symbol_ref "TARGET_MOVX")
1798 (eq_attr "alternative" "0,2"))
1799 (const_string "imovx")
1801 (const_string "imov")))
1803 (cond [(eq_attr "type" "imovx")
1805 (and (eq_attr "alternative" "1,2")
1806 (match_operand:HI 1 "aligned_operand" ""))
1808 (and (eq_attr "alternative" "0")
1809 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1811 (eq (symbol_ref "TARGET_HIMODE_MATH")
1815 (const_string "HI")))])
1817 ;; Stores and loads of ax to arbitrary constant address.
1818 ;; We fake an second form of instruction to force reload to load address
1819 ;; into register when rax is not available
1820 (define_insn "*movabshi_1_rex64"
1821 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1822 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1823 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1825 movabs{w}\t{%1, %P0|%P0, %1}
1826 mov{w}\t{%1, %a0|%a0, %1}"
1827 [(set_attr "type" "imov")
1828 (set_attr "modrm" "0,*")
1829 (set_attr "length_address" "8,0")
1830 (set_attr "length_immediate" "0,*")
1831 (set_attr "memory" "store")
1832 (set_attr "mode" "HI")])
1834 (define_insn "*movabshi_2_rex64"
1835 [(set (match_operand:HI 0 "register_operand" "=a,r")
1836 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1837 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1839 movabs{w}\t{%P1, %0|%0, %P1}
1840 mov{w}\t{%a1, %0|%0, %a1}"
1841 [(set_attr "type" "imov")
1842 (set_attr "modrm" "0,*")
1843 (set_attr "length_address" "8,0")
1844 (set_attr "length_immediate" "0")
1845 (set_attr "memory" "load")
1846 (set_attr "mode" "HI")])
1848 (define_insn "*swaphi_1"
1849 [(set (match_operand:HI 0 "register_operand" "+r")
1850 (match_operand:HI 1 "register_operand" "+r"))
1853 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1855 [(set_attr "type" "imov")
1856 (set_attr "mode" "SI")
1857 (set_attr "pent_pair" "np")
1858 (set_attr "athlon_decode" "vector")
1859 (set_attr "amdfam10_decode" "double")])
1861 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1862 (define_insn "*swaphi_2"
1863 [(set (match_operand:HI 0 "register_operand" "+r")
1864 (match_operand:HI 1 "register_operand" "+r"))
1867 "TARGET_PARTIAL_REG_STALL"
1869 [(set_attr "type" "imov")
1870 (set_attr "mode" "HI")
1871 (set_attr "pent_pair" "np")
1872 (set_attr "athlon_decode" "vector")])
1874 (define_expand "movstricthi"
1875 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1876 (match_operand:HI 1 "general_operand" ""))]
1879 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1881 /* Don't generate memory->memory moves, go through a register */
1882 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1883 operands[1] = force_reg (HImode, operands[1]);
1886 (define_insn "*movstricthi_1"
1887 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1888 (match_operand:HI 1 "general_operand" "rn,m"))]
1889 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1890 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1891 "mov{w}\t{%1, %0|%0, %1}"
1892 [(set_attr "type" "imov")
1893 (set_attr "mode" "HI")])
1895 (define_insn "*movstricthi_xor"
1896 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1897 (match_operand:HI 1 "const0_operand" ""))
1898 (clobber (reg:CC FLAGS_REG))]
1901 [(set_attr "type" "alu1")
1902 (set_attr "mode" "HI")
1903 (set_attr "length_immediate" "0")])
1905 (define_expand "movqi"
1906 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1907 (match_operand:QI 1 "general_operand" ""))]
1909 "ix86_expand_move (QImode, operands); DONE;")
1911 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1912 ;; "push a byte". But actually we use pushl, which has the effect
1913 ;; of rounding the amount pushed up to a word.
1915 (define_insn "*pushqi2"
1916 [(set (match_operand:QI 0 "push_operand" "=X")
1917 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1920 [(set_attr "type" "push")
1921 (set_attr "mode" "SI")])
1923 ;; For 64BIT abi we always round up to 8 bytes.
1924 (define_insn "*pushqi2_rex64"
1925 [(set (match_operand:QI 0 "push_operand" "=X")
1926 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1929 [(set_attr "type" "push")
1930 (set_attr "mode" "DI")])
1932 ;; Situation is quite tricky about when to choose full sized (SImode) move
1933 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1934 ;; partial register dependency machines (such as AMD Athlon), where QImode
1935 ;; moves issue extra dependency and for partial register stalls machines
1936 ;; that don't use QImode patterns (and QImode move cause stall on the next
1939 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1940 ;; register stall machines with, where we use QImode instructions, since
1941 ;; partial register stall can be caused there. Then we use movzx.
1942 (define_insn "*movqi_1"
1943 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1944 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1945 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1947 switch (get_attr_type (insn))
1950 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1951 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1953 if (get_attr_mode (insn) == MODE_SI)
1954 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1956 return "mov{b}\t{%1, %0|%0, %1}";
1960 (cond [(and (eq_attr "alternative" "5")
1961 (not (match_operand:QI 1 "aligned_operand" "")))
1962 (const_string "imovx")
1963 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1964 (const_string "imov")
1965 (and (eq_attr "alternative" "3")
1966 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1968 (eq (symbol_ref "TARGET_QIMODE_MATH")
1970 (const_string "imov")
1971 (eq_attr "alternative" "3,5")
1972 (const_string "imovx")
1973 (and (ne (symbol_ref "TARGET_MOVX")
1975 (eq_attr "alternative" "2"))
1976 (const_string "imovx")
1978 (const_string "imov")))
1980 (cond [(eq_attr "alternative" "3,4,5")
1982 (eq_attr "alternative" "6")
1984 (eq_attr "type" "imovx")
1986 (and (eq_attr "type" "imov")
1987 (and (eq_attr "alternative" "0,1")
1988 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1990 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1992 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1995 ;; Avoid partial register stalls when not using QImode arithmetic
1996 (and (eq_attr "type" "imov")
1997 (and (eq_attr "alternative" "0,1")
1998 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2000 (eq (symbol_ref "TARGET_QIMODE_MATH")
2004 (const_string "QI")))])
2006 (define_insn "*swapqi_1"
2007 [(set (match_operand:QI 0 "register_operand" "+r")
2008 (match_operand:QI 1 "register_operand" "+r"))
2011 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2013 [(set_attr "type" "imov")
2014 (set_attr "mode" "SI")
2015 (set_attr "pent_pair" "np")
2016 (set_attr "athlon_decode" "vector")
2017 (set_attr "amdfam10_decode" "vector")])
2019 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2020 (define_insn "*swapqi_2"
2021 [(set (match_operand:QI 0 "register_operand" "+q")
2022 (match_operand:QI 1 "register_operand" "+q"))
2025 "TARGET_PARTIAL_REG_STALL"
2027 [(set_attr "type" "imov")
2028 (set_attr "mode" "QI")
2029 (set_attr "pent_pair" "np")
2030 (set_attr "athlon_decode" "vector")])
2032 (define_expand "movstrictqi"
2033 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2034 (match_operand:QI 1 "general_operand" ""))]
2037 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2039 /* Don't generate memory->memory moves, go through a register. */
2040 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2041 operands[1] = force_reg (QImode, operands[1]);
2044 (define_insn "*movstrictqi_1"
2045 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2046 (match_operand:QI 1 "general_operand" "*qn,m"))]
2047 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2048 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2049 "mov{b}\t{%1, %0|%0, %1}"
2050 [(set_attr "type" "imov")
2051 (set_attr "mode" "QI")])
2053 (define_insn "*movstrictqi_xor"
2054 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2055 (match_operand:QI 1 "const0_operand" ""))
2056 (clobber (reg:CC FLAGS_REG))]
2059 [(set_attr "type" "alu1")
2060 (set_attr "mode" "QI")
2061 (set_attr "length_immediate" "0")])
2063 (define_insn "*movsi_extv_1"
2064 [(set (match_operand:SI 0 "register_operand" "=R")
2065 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2069 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2070 [(set_attr "type" "imovx")
2071 (set_attr "mode" "SI")])
2073 (define_insn "*movhi_extv_1"
2074 [(set (match_operand:HI 0 "register_operand" "=R")
2075 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2079 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2080 [(set_attr "type" "imovx")
2081 (set_attr "mode" "SI")])
2083 (define_insn "*movqi_extv_1"
2084 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2085 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2090 switch (get_attr_type (insn))
2093 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2095 return "mov{b}\t{%h1, %0|%0, %h1}";
2099 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2100 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2101 (ne (symbol_ref "TARGET_MOVX")
2103 (const_string "imovx")
2104 (const_string "imov")))
2106 (if_then_else (eq_attr "type" "imovx")
2108 (const_string "QI")))])
2110 (define_insn "*movqi_extv_1_rex64"
2111 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2112 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2117 switch (get_attr_type (insn))
2120 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2122 return "mov{b}\t{%h1, %0|%0, %h1}";
2126 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2127 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2128 (ne (symbol_ref "TARGET_MOVX")
2130 (const_string "imovx")
2131 (const_string "imov")))
2133 (if_then_else (eq_attr "type" "imovx")
2135 (const_string "QI")))])
2137 ;; Stores and loads of ax to arbitrary constant address.
2138 ;; We fake an second form of instruction to force reload to load address
2139 ;; into register when rax is not available
2140 (define_insn "*movabsqi_1_rex64"
2141 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2142 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2143 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2145 movabs{b}\t{%1, %P0|%P0, %1}
2146 mov{b}\t{%1, %a0|%a0, %1}"
2147 [(set_attr "type" "imov")
2148 (set_attr "modrm" "0,*")
2149 (set_attr "length_address" "8,0")
2150 (set_attr "length_immediate" "0,*")
2151 (set_attr "memory" "store")
2152 (set_attr "mode" "QI")])
2154 (define_insn "*movabsqi_2_rex64"
2155 [(set (match_operand:QI 0 "register_operand" "=a,r")
2156 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2157 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2159 movabs{b}\t{%P1, %0|%0, %P1}
2160 mov{b}\t{%a1, %0|%0, %a1}"
2161 [(set_attr "type" "imov")
2162 (set_attr "modrm" "0,*")
2163 (set_attr "length_address" "8,0")
2164 (set_attr "length_immediate" "0")
2165 (set_attr "memory" "load")
2166 (set_attr "mode" "QI")])
2168 (define_insn "*movdi_extzv_1"
2169 [(set (match_operand:DI 0 "register_operand" "=R")
2170 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2174 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2175 [(set_attr "type" "imovx")
2176 (set_attr "mode" "SI")])
2178 (define_insn "*movsi_extzv_1"
2179 [(set (match_operand:SI 0 "register_operand" "=R")
2180 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2184 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2185 [(set_attr "type" "imovx")
2186 (set_attr "mode" "SI")])
2188 (define_insn "*movqi_extzv_2"
2189 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2190 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2195 switch (get_attr_type (insn))
2198 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2200 return "mov{b}\t{%h1, %0|%0, %h1}";
2204 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2205 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2206 (ne (symbol_ref "TARGET_MOVX")
2208 (const_string "imovx")
2209 (const_string "imov")))
2211 (if_then_else (eq_attr "type" "imovx")
2213 (const_string "QI")))])
2215 (define_insn "*movqi_extzv_2_rex64"
2216 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2217 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2222 switch (get_attr_type (insn))
2225 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2227 return "mov{b}\t{%h1, %0|%0, %h1}";
2231 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2232 (ne (symbol_ref "TARGET_MOVX")
2234 (const_string "imovx")
2235 (const_string "imov")))
2237 (if_then_else (eq_attr "type" "imovx")
2239 (const_string "QI")))])
2241 (define_insn "movsi_insv_1"
2242 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2245 (match_operand:SI 1 "general_operand" "Qmn"))]
2247 "mov{b}\t{%b1, %h0|%h0, %b1}"
2248 [(set_attr "type" "imov")
2249 (set_attr "mode" "QI")])
2251 (define_insn "*movsi_insv_1_rex64"
2252 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2255 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2257 "mov{b}\t{%b1, %h0|%h0, %b1}"
2258 [(set_attr "type" "imov")
2259 (set_attr "mode" "QI")])
2261 (define_insn "movdi_insv_1_rex64"
2262 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2265 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2267 "mov{b}\t{%b1, %h0|%h0, %b1}"
2268 [(set_attr "type" "imov")
2269 (set_attr "mode" "QI")])
2271 (define_insn "*movqi_insv_2"
2272 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2275 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2278 "mov{b}\t{%h1, %h0|%h0, %h1}"
2279 [(set_attr "type" "imov")
2280 (set_attr "mode" "QI")])
2282 (define_expand "movdi"
2283 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2284 (match_operand:DI 1 "general_operand" ""))]
2286 "ix86_expand_move (DImode, operands); DONE;")
2288 (define_insn "*pushdi"
2289 [(set (match_operand:DI 0 "push_operand" "=<")
2290 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2294 (define_insn "*pushdi2_rex64"
2295 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2296 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2301 [(set_attr "type" "push,multi")
2302 (set_attr "mode" "DI")])
2304 ;; Convert impossible pushes of immediate to existing instructions.
2305 ;; First try to get scratch register and go through it. In case this
2306 ;; fails, push sign extended lower part first and then overwrite
2307 ;; upper part by 32bit move.
2309 [(match_scratch:DI 2 "r")
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)"
2314 [(set (match_dup 2) (match_dup 1))
2315 (set (match_dup 0) (match_dup 2))]
2318 ;; We need to define this as both peepholer and splitter for case
2319 ;; peephole2 pass is not run.
2320 ;; "&& 1" is needed to keep it from matching the previous pattern.
2322 [(set (match_operand:DI 0 "push_operand" "")
2323 (match_operand:DI 1 "immediate_operand" ""))]
2324 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2325 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2326 [(set (match_dup 0) (match_dup 1))
2327 (set (match_dup 2) (match_dup 3))]
2328 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2329 operands[1] = gen_lowpart (DImode, operands[2]);
2330 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2335 [(set (match_operand:DI 0 "push_operand" "")
2336 (match_operand:DI 1 "immediate_operand" ""))]
2337 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2338 ? epilogue_completed : reload_completed)
2339 && !symbolic_operand (operands[1], DImode)
2340 && !x86_64_immediate_operand (operands[1], DImode)"
2341 [(set (match_dup 0) (match_dup 1))
2342 (set (match_dup 2) (match_dup 3))]
2343 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2344 operands[1] = gen_lowpart (DImode, operands[2]);
2345 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2349 (define_insn "*pushdi2_prologue_rex64"
2350 [(set (match_operand:DI 0 "push_operand" "=<")
2351 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2352 (clobber (mem:BLK (scratch)))]
2355 [(set_attr "type" "push")
2356 (set_attr "mode" "DI")])
2358 (define_insn "*popdi1_epilogue_rex64"
2359 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2360 (mem:DI (reg:DI SP_REG)))
2361 (set (reg:DI SP_REG)
2362 (plus:DI (reg:DI SP_REG) (const_int 8)))
2363 (clobber (mem:BLK (scratch)))]
2366 [(set_attr "type" "pop")
2367 (set_attr "mode" "DI")])
2369 (define_insn "popdi1"
2370 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2371 (mem:DI (reg:DI SP_REG)))
2372 (set (reg:DI SP_REG)
2373 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2376 [(set_attr "type" "pop")
2377 (set_attr "mode" "DI")])
2379 (define_insn "*movdi_xor_rex64"
2380 [(set (match_operand:DI 0 "register_operand" "=r")
2381 (match_operand:DI 1 "const0_operand" ""))
2382 (clobber (reg:CC FLAGS_REG))]
2384 && reload_completed"
2386 [(set_attr "type" "alu1")
2387 (set_attr "mode" "SI")
2388 (set_attr "length_immediate" "0")])
2390 (define_insn "*movdi_or_rex64"
2391 [(set (match_operand:DI 0 "register_operand" "=r")
2392 (match_operand:DI 1 "const_int_operand" "i"))
2393 (clobber (reg:CC FLAGS_REG))]
2396 && operands[1] == constm1_rtx"
2398 operands[1] = constm1_rtx;
2399 return "or{q}\t{%1, %0|%0, %1}";
2401 [(set_attr "type" "alu1")
2402 (set_attr "mode" "DI")
2403 (set_attr "length_immediate" "1")])
2405 (define_insn "*movdi_2"
2406 [(set (match_operand:DI 0 "nonimmediate_operand"
2407 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2408 (match_operand:DI 1 "general_operand"
2409 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2410 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2415 movq\t{%1, %0|%0, %1}
2416 movq\t{%1, %0|%0, %1}
2418 %vmovq\t{%1, %0|%0, %1}
2419 %vmovdqa\t{%1, %0|%0, %1}
2420 %vmovq\t{%1, %0|%0, %1}
2422 movlps\t{%1, %0|%0, %1}
2423 movaps\t{%1, %0|%0, %1}
2424 movlps\t{%1, %0|%0, %1}"
2425 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2426 (set (attr "prefix")
2427 (if_then_else (eq_attr "alternative" "5,6,7,8")
2428 (const_string "vex")
2429 (const_string "orig")))
2430 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2433 [(set (match_operand:DI 0 "push_operand" "")
2434 (match_operand:DI 1 "general_operand" ""))]
2435 "!TARGET_64BIT && reload_completed
2436 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2438 "ix86_split_long_move (operands); DONE;")
2440 ;; %%% This multiword shite has got to go.
2442 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2443 (match_operand:DI 1 "general_operand" ""))]
2444 "!TARGET_64BIT && reload_completed
2445 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2446 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2448 "ix86_split_long_move (operands); DONE;")
2450 (define_insn "*movdi_1_rex64"
2451 [(set (match_operand:DI 0 "nonimmediate_operand"
2452 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2453 (match_operand:DI 1 "general_operand"
2454 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2455 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2457 switch (get_attr_type (insn))
2460 if (SSE_REG_P (operands[0]))
2461 return "movq2dq\t{%1, %0|%0, %1}";
2463 return "movdq2q\t{%1, %0|%0, %1}";
2468 if (get_attr_mode (insn) == MODE_TI)
2469 return "vmovdqa\t{%1, %0|%0, %1}";
2471 return "vmovq\t{%1, %0|%0, %1}";
2474 if (get_attr_mode (insn) == MODE_TI)
2475 return "movdqa\t{%1, %0|%0, %1}";
2479 /* Moves from and into integer register is done using movd
2480 opcode with REX prefix. */
2481 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2482 return "movd\t{%1, %0|%0, %1}";
2483 return "movq\t{%1, %0|%0, %1}";
2486 return "%vpxor\t%0, %d0";
2489 return "pxor\t%0, %0";
2495 return "lea{q}\t{%a1, %0|%0, %a1}";
2498 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2499 if (get_attr_mode (insn) == MODE_SI)
2500 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2501 else if (which_alternative == 2)
2502 return "movabs{q}\t{%1, %0|%0, %1}";
2504 return "mov{q}\t{%1, %0|%0, %1}";
2508 (cond [(eq_attr "alternative" "5")
2509 (const_string "mmx")
2510 (eq_attr "alternative" "6,7,8,9,10")
2511 (const_string "mmxmov")
2512 (eq_attr "alternative" "11")
2513 (const_string "sselog1")
2514 (eq_attr "alternative" "12,13,14,15,16")
2515 (const_string "ssemov")
2516 (eq_attr "alternative" "17,18")
2517 (const_string "ssecvt")
2518 (eq_attr "alternative" "4")
2519 (const_string "multi")
2520 (match_operand:DI 1 "pic_32bit_operand" "")
2521 (const_string "lea")
2523 (const_string "imov")))
2526 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2528 (const_string "*")))
2529 (set (attr "length_immediate")
2531 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2533 (const_string "*")))
2534 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2535 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2536 (set (attr "prefix")
2537 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2538 (const_string "maybe_vex")
2539 (const_string "orig")))
2540 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2542 ;; Stores and loads of ax to arbitrary constant address.
2543 ;; We fake an second form of instruction to force reload to load address
2544 ;; into register when rax is not available
2545 (define_insn "*movabsdi_1_rex64"
2546 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2547 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2548 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2550 movabs{q}\t{%1, %P0|%P0, %1}
2551 mov{q}\t{%1, %a0|%a0, %1}"
2552 [(set_attr "type" "imov")
2553 (set_attr "modrm" "0,*")
2554 (set_attr "length_address" "8,0")
2555 (set_attr "length_immediate" "0,*")
2556 (set_attr "memory" "store")
2557 (set_attr "mode" "DI")])
2559 (define_insn "*movabsdi_2_rex64"
2560 [(set (match_operand:DI 0 "register_operand" "=a,r")
2561 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2562 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2564 movabs{q}\t{%P1, %0|%0, %P1}
2565 mov{q}\t{%a1, %0|%0, %a1}"
2566 [(set_attr "type" "imov")
2567 (set_attr "modrm" "0,*")
2568 (set_attr "length_address" "8,0")
2569 (set_attr "length_immediate" "0")
2570 (set_attr "memory" "load")
2571 (set_attr "mode" "DI")])
2573 ;; Convert impossible stores of immediate to existing instructions.
2574 ;; First try to get scratch register and go through it. In case this
2575 ;; fails, move by 32bit parts.
2577 [(match_scratch:DI 2 "r")
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)"
2582 [(set (match_dup 2) (match_dup 1))
2583 (set (match_dup 0) (match_dup 2))]
2586 ;; We need to define this as both peepholer and splitter for case
2587 ;; peephole2 pass is not run.
2588 ;; "&& 1" is needed to keep it from matching the previous pattern.
2590 [(set (match_operand:DI 0 "memory_operand" "")
2591 (match_operand:DI 1 "immediate_operand" ""))]
2592 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2593 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2594 [(set (match_dup 2) (match_dup 3))
2595 (set (match_dup 4) (match_dup 5))]
2596 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2599 [(set (match_operand:DI 0 "memory_operand" "")
2600 (match_operand:DI 1 "immediate_operand" ""))]
2601 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2602 ? epilogue_completed : reload_completed)
2603 && !symbolic_operand (operands[1], DImode)
2604 && !x86_64_immediate_operand (operands[1], DImode)"
2605 [(set (match_dup 2) (match_dup 3))
2606 (set (match_dup 4) (match_dup 5))]
2607 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2609 (define_insn "*swapdi_rex64"
2610 [(set (match_operand:DI 0 "register_operand" "+r")
2611 (match_operand:DI 1 "register_operand" "+r"))
2616 [(set_attr "type" "imov")
2617 (set_attr "mode" "DI")
2618 (set_attr "pent_pair" "np")
2619 (set_attr "athlon_decode" "vector")
2620 (set_attr "amdfam10_decode" "double")])
2622 (define_expand "movoi"
2623 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2624 (match_operand:OI 1 "general_operand" ""))]
2626 "ix86_expand_move (OImode, operands); DONE;")
2628 (define_insn "*movoi_internal"
2629 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2630 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2632 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2634 switch (which_alternative)
2637 return "vxorps\t%0, %0, %0";
2640 if (misaligned_operand (operands[0], OImode)
2641 || misaligned_operand (operands[1], OImode))
2642 return "vmovdqu\t{%1, %0|%0, %1}";
2644 return "vmovdqa\t{%1, %0|%0, %1}";
2649 [(set_attr "type" "sselog1,ssemov,ssemov")
2650 (set_attr "prefix" "vex")
2651 (set_attr "mode" "OI")])
2653 (define_expand "movti"
2654 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2655 (match_operand:TI 1 "nonimmediate_operand" ""))]
2656 "TARGET_SSE || TARGET_64BIT"
2659 ix86_expand_move (TImode, operands);
2660 else if (push_operand (operands[0], TImode))
2661 ix86_expand_push (TImode, operands[1]);
2663 ix86_expand_vector_move (TImode, operands);
2667 (define_insn "*movti_internal"
2668 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2669 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2670 "TARGET_SSE && !TARGET_64BIT
2671 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2673 switch (which_alternative)
2676 if (get_attr_mode (insn) == MODE_V4SF)
2677 return "%vxorps\t%0, %d0";
2679 return "%vpxor\t%0, %d0";
2682 /* TDmode values are passed as TImode on the stack. Moving them
2683 to stack may result in unaligned memory access. */
2684 if (misaligned_operand (operands[0], TImode)
2685 || misaligned_operand (operands[1], TImode))
2687 if (get_attr_mode (insn) == MODE_V4SF)
2688 return "%vmovups\t{%1, %0|%0, %1}";
2690 return "%vmovdqu\t{%1, %0|%0, %1}";
2694 if (get_attr_mode (insn) == MODE_V4SF)
2695 return "%vmovaps\t{%1, %0|%0, %1}";
2697 return "%vmovdqa\t{%1, %0|%0, %1}";
2703 [(set_attr "type" "sselog1,ssemov,ssemov")
2704 (set_attr "prefix" "maybe_vex")
2706 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2707 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2708 (const_string "V4SF")
2709 (and (eq_attr "alternative" "2")
2710 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2712 (const_string "V4SF")]
2713 (const_string "TI")))])
2715 (define_insn "*movti_rex64"
2716 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2717 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2719 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2721 switch (which_alternative)
2727 if (get_attr_mode (insn) == MODE_V4SF)
2728 return "%vxorps\t%0, %d0";
2730 return "%vpxor\t%0, %d0";
2733 /* TDmode values are passed as TImode on the stack. Moving them
2734 to stack may result in unaligned memory access. */
2735 if (misaligned_operand (operands[0], TImode)
2736 || misaligned_operand (operands[1], TImode))
2738 if (get_attr_mode (insn) == MODE_V4SF)
2739 return "%vmovups\t{%1, %0|%0, %1}";
2741 return "%vmovdqu\t{%1, %0|%0, %1}";
2745 if (get_attr_mode (insn) == MODE_V4SF)
2746 return "%vmovaps\t{%1, %0|%0, %1}";
2748 return "%vmovdqa\t{%1, %0|%0, %1}";
2754 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2755 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2757 (cond [(eq_attr "alternative" "2,3")
2759 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2761 (const_string "V4SF")
2762 (const_string "TI"))
2763 (eq_attr "alternative" "4")
2765 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2767 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2769 (const_string "V4SF")
2770 (const_string "TI"))]
2771 (const_string "DI")))])
2774 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2775 (match_operand:TI 1 "general_operand" ""))]
2776 "reload_completed && !SSE_REG_P (operands[0])
2777 && !SSE_REG_P (operands[1])"
2779 "ix86_split_long_move (operands); DONE;")
2781 ;; This expands to what emit_move_complex would generate if we didn't
2782 ;; have a movti pattern. Having this avoids problems with reload on
2783 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2784 ;; to have around all the time.
2785 (define_expand "movcdi"
2786 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2787 (match_operand:CDI 1 "general_operand" ""))]
2790 if (push_operand (operands[0], CDImode))
2791 emit_move_complex_push (CDImode, operands[0], operands[1]);
2793 emit_move_complex_parts (operands[0], operands[1]);
2797 (define_expand "movsf"
2798 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2799 (match_operand:SF 1 "general_operand" ""))]
2801 "ix86_expand_move (SFmode, operands); DONE;")
2803 (define_insn "*pushsf"
2804 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2805 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2808 /* Anything else should be already split before reg-stack. */
2809 gcc_assert (which_alternative == 1);
2810 return "push{l}\t%1";
2812 [(set_attr "type" "multi,push,multi")
2813 (set_attr "unit" "i387,*,*")
2814 (set_attr "mode" "SF,SI,SF")])
2816 (define_insn "*pushsf_rex64"
2817 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2818 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2821 /* Anything else should be already split before reg-stack. */
2822 gcc_assert (which_alternative == 1);
2823 return "push{q}\t%q1";
2825 [(set_attr "type" "multi,push,multi")
2826 (set_attr "unit" "i387,*,*")
2827 (set_attr "mode" "SF,DI,SF")])
2830 [(set (match_operand:SF 0 "push_operand" "")
2831 (match_operand:SF 1 "memory_operand" ""))]
2833 && MEM_P (operands[1])
2834 && (operands[2] = find_constant_src (insn))"
2838 ;; %%% Kill this when call knows how to work this out.
2840 [(set (match_operand:SF 0 "push_operand" "")
2841 (match_operand:SF 1 "any_fp_register_operand" ""))]
2843 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2844 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2847 [(set (match_operand:SF 0 "push_operand" "")
2848 (match_operand:SF 1 "any_fp_register_operand" ""))]
2850 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2851 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2853 (define_insn "*movsf_1"
2854 [(set (match_operand:SF 0 "nonimmediate_operand"
2855 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2856 (match_operand:SF 1 "general_operand"
2857 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2858 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2859 && (reload_in_progress || reload_completed
2860 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2861 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2862 && standard_80387_constant_p (operands[1]))
2863 || GET_CODE (operands[1]) != CONST_DOUBLE
2864 || memory_operand (operands[0], SFmode))"
2866 switch (which_alternative)
2870 return output_387_reg_move (insn, operands);
2873 return standard_80387_constant_opcode (operands[1]);
2877 return "mov{l}\t{%1, %0|%0, %1}";
2879 if (get_attr_mode (insn) == MODE_TI)
2880 return "%vpxor\t%0, %d0";
2882 return "%vxorps\t%0, %d0";
2884 if (get_attr_mode (insn) == MODE_V4SF)
2885 return "%vmovaps\t{%1, %0|%0, %1}";
2887 return "%vmovss\t{%1, %d0|%d0, %1}";
2890 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2891 : "vmovss\t{%1, %0|%0, %1}";
2893 return "movss\t{%1, %0|%0, %1}";
2895 return "%vmovss\t{%1, %0|%0, %1}";
2897 case 9: case 10: case 14: case 15:
2898 return "movd\t{%1, %0|%0, %1}";
2900 return "%vmovd\t{%1, %0|%0, %1}";
2903 return "movq\t{%1, %0|%0, %1}";
2909 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2910 (set (attr "prefix")
2911 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2912 (const_string "maybe_vex")
2913 (const_string "orig")))
2915 (cond [(eq_attr "alternative" "3,4,9,10")
2917 (eq_attr "alternative" "5")
2919 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2921 (ne (symbol_ref "TARGET_SSE2")
2923 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2926 (const_string "V4SF"))
2927 /* For architectures resolving dependencies on
2928 whole SSE registers use APS move to break dependency
2929 chains, otherwise use short move to avoid extra work.
2931 Do the same for architectures resolving dependencies on
2932 the parts. While in DF mode it is better to always handle
2933 just register parts, the SF mode is different due to lack
2934 of instructions to load just part of the register. It is
2935 better to maintain the whole registers in single format
2936 to avoid problems on using packed logical operations. */
2937 (eq_attr "alternative" "6")
2939 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2941 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2943 (const_string "V4SF")
2944 (const_string "SF"))
2945 (eq_attr "alternative" "11")
2946 (const_string "DI")]
2947 (const_string "SF")))])
2949 (define_insn "*swapsf"
2950 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2951 (match_operand:SF 1 "fp_register_operand" "+f"))
2954 "reload_completed || TARGET_80387"
2956 if (STACK_TOP_P (operands[0]))
2961 [(set_attr "type" "fxch")
2962 (set_attr "mode" "SF")])
2964 (define_expand "movdf"
2965 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2966 (match_operand:DF 1 "general_operand" ""))]
2968 "ix86_expand_move (DFmode, operands); DONE;")
2970 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2971 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2972 ;; On the average, pushdf using integers can be still shorter. Allow this
2973 ;; pattern for optimize_size too.
2975 (define_insn "*pushdf_nointeger"
2976 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2977 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,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,SI,DF")])
2987 (define_insn "*pushdf_integer"
2988 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2989 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2990 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2992 /* This insn should be already split before reg-stack. */
2995 [(set_attr "type" "multi")
2996 (set_attr "unit" "i387,*,*")
2997 (set_attr "mode" "DF,SI,DF")])
2999 ;; %%% Kill this when call knows how to work this out.
3001 [(set (match_operand:DF 0 "push_operand" "")
3002 (match_operand:DF 1 "any_fp_register_operand" ""))]
3004 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3005 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3009 [(set (match_operand:DF 0 "push_operand" "")
3010 (match_operand:DF 1 "general_operand" ""))]
3013 "ix86_split_long_move (operands); DONE;")
3015 ;; Moving is usually shorter when only FP registers are used. This separate
3016 ;; movdf pattern avoids the use of integer registers for FP operations
3017 ;; when optimizing for size.
3019 (define_insn "*movdf_nointeger"
3020 [(set (match_operand:DF 0 "nonimmediate_operand"
3021 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3022 (match_operand:DF 1 "general_operand"
3023 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3024 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3025 && ((optimize_function_for_size_p (cfun)
3026 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3027 && (reload_in_progress || reload_completed
3028 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3029 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3030 && optimize_function_for_size_p (cfun)
3031 && !memory_operand (operands[0], DFmode)
3032 && standard_80387_constant_p (operands[1]))
3033 || GET_CODE (operands[1]) != CONST_DOUBLE
3034 || ((optimize_function_for_size_p (cfun)
3035 || !TARGET_MEMORY_MISMATCH_STALL
3036 || reload_in_progress || reload_completed)
3037 && memory_operand (operands[0], DFmode)))"
3039 switch (which_alternative)
3043 return output_387_reg_move (insn, operands);
3046 return standard_80387_constant_opcode (operands[1]);
3052 switch (get_attr_mode (insn))
3055 return "%vxorps\t%0, %d0";
3057 return "%vxorpd\t%0, %d0";
3059 return "%vpxor\t%0, %d0";
3066 switch (get_attr_mode (insn))
3069 return "%vmovaps\t{%1, %0|%0, %1}";
3071 return "%vmovapd\t{%1, %0|%0, %1}";
3073 return "%vmovdqa\t{%1, %0|%0, %1}";
3075 return "%vmovq\t{%1, %0|%0, %1}";
3079 if (REG_P (operands[0]) && REG_P (operands[1]))
3080 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3082 return "vmovsd\t{%1, %0|%0, %1}";
3085 return "movsd\t{%1, %0|%0, %1}";
3089 if (REG_P (operands[0]))
3090 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3092 return "vmovlpd\t{%1, %0|%0, %1}";
3095 return "movlpd\t{%1, %0|%0, %1}";
3099 if (REG_P (operands[0]))
3100 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3102 return "vmovlps\t{%1, %0|%0, %1}";
3105 return "movlps\t{%1, %0|%0, %1}";
3114 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3115 (set (attr "prefix")
3116 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3117 (const_string "orig")
3118 (const_string "maybe_vex")))
3119 (set (attr "prefix_data16")
3120 (if_then_else (eq_attr "mode" "V1DF")
3122 (const_string "*")))
3124 (cond [(eq_attr "alternative" "0,1,2")
3126 (eq_attr "alternative" "3,4")
3129 /* For SSE1, we have many fewer alternatives. */
3130 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3131 (cond [(eq_attr "alternative" "5,6")
3132 (const_string "V4SF")
3134 (const_string "V2SF"))
3136 /* xorps is one byte shorter. */
3137 (eq_attr "alternative" "5")
3138 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3140 (const_string "V4SF")
3141 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3145 (const_string "V2DF"))
3147 /* For architectures resolving dependencies on
3148 whole SSE registers use APD move to break dependency
3149 chains, otherwise use short move to avoid extra work.
3151 movaps encodes one byte shorter. */
3152 (eq_attr "alternative" "6")
3154 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3156 (const_string "V4SF")
3157 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3159 (const_string "V2DF")
3161 (const_string "DF"))
3162 /* For architectures resolving dependencies on register
3163 parts we may avoid extra work to zero out upper part
3165 (eq_attr "alternative" "7")
3167 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3169 (const_string "V1DF")
3170 (const_string "DF"))
3172 (const_string "DF")))])
3174 (define_insn "*movdf_integer_rex64"
3175 [(set (match_operand:DF 0 "nonimmediate_operand"
3176 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3177 (match_operand:DF 1 "general_operand"
3178 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3179 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3180 && (reload_in_progress || reload_completed
3181 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3182 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3183 && optimize_function_for_size_p (cfun)
3184 && standard_80387_constant_p (operands[1]))
3185 || GET_CODE (operands[1]) != CONST_DOUBLE
3186 || memory_operand (operands[0], DFmode))"
3188 switch (which_alternative)
3192 return output_387_reg_move (insn, operands);
3195 return standard_80387_constant_opcode (operands[1]);
3202 switch (get_attr_mode (insn))
3205 return "%vxorps\t%0, %d0";
3207 return "%vxorpd\t%0, %d0";
3209 return "%vpxor\t%0, %d0";
3216 switch (get_attr_mode (insn))
3219 return "%vmovaps\t{%1, %0|%0, %1}";
3221 return "%vmovapd\t{%1, %0|%0, %1}";
3223 return "%vmovdqa\t{%1, %0|%0, %1}";
3225 return "%vmovq\t{%1, %0|%0, %1}";
3229 if (REG_P (operands[0]) && REG_P (operands[1]))
3230 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3232 return "vmovsd\t{%1, %0|%0, %1}";
3235 return "movsd\t{%1, %0|%0, %1}";
3237 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3239 return "%vmovlps\t{%1, %d0|%d0, %1}";
3246 return "%vmovd\t{%1, %0|%0, %1}";
3252 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3253 (set (attr "prefix")
3254 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3255 (const_string "orig")
3256 (const_string "maybe_vex")))
3257 (set (attr "prefix_data16")
3258 (if_then_else (eq_attr "mode" "V1DF")
3260 (const_string "*")))
3262 (cond [(eq_attr "alternative" "0,1,2")
3264 (eq_attr "alternative" "3,4,9,10")
3267 /* For SSE1, we have many fewer alternatives. */
3268 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3269 (cond [(eq_attr "alternative" "5,6")
3270 (const_string "V4SF")
3272 (const_string "V2SF"))
3274 /* xorps is one byte shorter. */
3275 (eq_attr "alternative" "5")
3276 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3278 (const_string "V4SF")
3279 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3283 (const_string "V2DF"))
3285 /* For architectures resolving dependencies on
3286 whole SSE registers use APD move to break dependency
3287 chains, otherwise use short move to avoid extra work.
3289 movaps encodes one byte shorter. */
3290 (eq_attr "alternative" "6")
3292 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3294 (const_string "V4SF")
3295 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3297 (const_string "V2DF")
3299 (const_string "DF"))
3300 /* For architectures resolving dependencies on register
3301 parts we may avoid extra work to zero out upper part
3303 (eq_attr "alternative" "7")
3305 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3307 (const_string "V1DF")
3308 (const_string "DF"))
3310 (const_string "DF")))])
3312 (define_insn "*movdf_integer"
3313 [(set (match_operand:DF 0 "nonimmediate_operand"
3314 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3315 (match_operand:DF 1 "general_operand"
3316 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3317 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3318 && optimize_function_for_speed_p (cfun)
3319 && TARGET_INTEGER_DFMODE_MOVES
3320 && (reload_in_progress || reload_completed
3321 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3322 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3323 && optimize_function_for_size_p (cfun)
3324 && standard_80387_constant_p (operands[1]))
3325 || GET_CODE (operands[1]) != CONST_DOUBLE
3326 || memory_operand (operands[0], DFmode))"
3328 switch (which_alternative)
3332 return output_387_reg_move (insn, operands);
3335 return standard_80387_constant_opcode (operands[1]);
3342 switch (get_attr_mode (insn))
3345 return "xorps\t%0, %0";
3347 return "xorpd\t%0, %0";
3349 return "pxor\t%0, %0";
3356 switch (get_attr_mode (insn))
3359 return "movaps\t{%1, %0|%0, %1}";
3361 return "movapd\t{%1, %0|%0, %1}";
3363 return "movdqa\t{%1, %0|%0, %1}";
3365 return "movq\t{%1, %0|%0, %1}";
3367 return "movsd\t{%1, %0|%0, %1}";
3369 return "movlpd\t{%1, %0|%0, %1}";
3371 return "movlps\t{%1, %0|%0, %1}";
3380 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3381 (set (attr "prefix_data16")
3382 (if_then_else (eq_attr "mode" "V1DF")
3384 (const_string "*")))
3386 (cond [(eq_attr "alternative" "0,1,2")
3388 (eq_attr "alternative" "3,4")
3391 /* For SSE1, we have many fewer alternatives. */
3392 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3393 (cond [(eq_attr "alternative" "5,6")
3394 (const_string "V4SF")
3396 (const_string "V2SF"))
3398 /* xorps is one byte shorter. */
3399 (eq_attr "alternative" "5")
3400 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3402 (const_string "V4SF")
3403 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3407 (const_string "V2DF"))
3409 /* For architectures resolving dependencies on
3410 whole SSE registers use APD move to break dependency
3411 chains, otherwise use short move to avoid extra work.
3413 movaps encodes one byte shorter. */
3414 (eq_attr "alternative" "6")
3416 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3418 (const_string "V4SF")
3419 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3421 (const_string "V2DF")
3423 (const_string "DF"))
3424 /* For architectures resolving dependencies on register
3425 parts we may avoid extra work to zero out upper part
3427 (eq_attr "alternative" "7")
3429 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3431 (const_string "V1DF")
3432 (const_string "DF"))
3434 (const_string "DF")))])
3437 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3438 (match_operand:DF 1 "general_operand" ""))]
3440 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3441 && ! (ANY_FP_REG_P (operands[0]) ||
3442 (GET_CODE (operands[0]) == SUBREG
3443 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3444 && ! (ANY_FP_REG_P (operands[1]) ||
3445 (GET_CODE (operands[1]) == SUBREG
3446 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3448 "ix86_split_long_move (operands); DONE;")
3450 (define_insn "*swapdf"
3451 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3452 (match_operand:DF 1 "fp_register_operand" "+f"))
3455 "reload_completed || TARGET_80387"
3457 if (STACK_TOP_P (operands[0]))
3462 [(set_attr "type" "fxch")
3463 (set_attr "mode" "DF")])
3465 (define_expand "movxf"
3466 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3467 (match_operand:XF 1 "general_operand" ""))]
3469 "ix86_expand_move (XFmode, operands); DONE;")
3471 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3472 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3473 ;; Pushing using integer instructions is longer except for constants
3474 ;; and direct memory references.
3475 ;; (assuming that any given constant is pushed only once, but this ought to be
3476 ;; handled elsewhere).
3478 (define_insn "*pushxf_nointeger"
3479 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3480 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3481 "optimize_function_for_size_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,SI")])
3490 (define_insn "*pushxf_integer"
3491 [(set (match_operand:XF 0 "push_operand" "=<,<")
3492 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3493 "optimize_function_for_speed_p (cfun)"
3495 /* This insn should be already split before reg-stack. */
3498 [(set_attr "type" "multi")
3499 (set_attr "unit" "i387,*")
3500 (set_attr "mode" "XF,SI")])
3503 [(set (match_operand 0 "push_operand" "")
3504 (match_operand 1 "general_operand" ""))]
3506 && (GET_MODE (operands[0]) == XFmode
3507 || GET_MODE (operands[0]) == DFmode)
3508 && !ANY_FP_REG_P (operands[1])"
3510 "ix86_split_long_move (operands); DONE;")
3513 [(set (match_operand:XF 0 "push_operand" "")
3514 (match_operand:XF 1 "any_fp_register_operand" ""))]
3516 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3517 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3518 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3520 ;; Do not use integer registers when optimizing for size
3521 (define_insn "*movxf_nointeger"
3522 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3523 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3524 "optimize_function_for_size_p (cfun)
3525 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3526 && (reload_in_progress || reload_completed
3527 || standard_80387_constant_p (operands[1])
3528 || GET_CODE (operands[1]) != CONST_DOUBLE
3529 || memory_operand (operands[0], XFmode))"
3531 switch (which_alternative)
3535 return output_387_reg_move (insn, operands);
3538 return standard_80387_constant_opcode (operands[1]);
3546 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3547 (set_attr "mode" "XF,XF,XF,SI,SI")])
3549 (define_insn "*movxf_integer"
3550 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3551 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3552 "optimize_function_for_speed_p (cfun)
3553 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3554 && (reload_in_progress || reload_completed
3555 || GET_CODE (operands[1]) != CONST_DOUBLE
3556 || memory_operand (operands[0], XFmode))"
3558 switch (which_alternative)
3562 return output_387_reg_move (insn, operands);
3565 return standard_80387_constant_opcode (operands[1]);
3574 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3575 (set_attr "mode" "XF,XF,XF,SI,SI")])
3577 (define_expand "movtf"
3578 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3579 (match_operand:TF 1 "nonimmediate_operand" ""))]
3582 ix86_expand_move (TFmode, operands);
3586 (define_insn "*movtf_internal"
3587 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3588 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3590 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3592 switch (which_alternative)
3596 if (get_attr_mode (insn) == MODE_V4SF)
3597 return "%vmovaps\t{%1, %0|%0, %1}";
3599 return "%vmovdqa\t{%1, %0|%0, %1}";
3601 if (get_attr_mode (insn) == MODE_V4SF)
3602 return "%vxorps\t%0, %d0";
3604 return "%vpxor\t%0, %d0";
3612 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3613 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3615 (cond [(eq_attr "alternative" "0,2")
3617 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3619 (const_string "V4SF")
3620 (const_string "TI"))
3621 (eq_attr "alternative" "1")
3623 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3625 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3627 (const_string "V4SF")
3628 (const_string "TI"))]
3629 (const_string "DI")))])
3631 (define_insn "*pushtf_sse"
3632 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3633 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3636 /* This insn should be already split before reg-stack. */
3639 [(set_attr "type" "multi")
3640 (set_attr "unit" "sse,*,*")
3641 (set_attr "mode" "TF,SI,SI")])
3644 [(set (match_operand:TF 0 "push_operand" "")
3645 (match_operand:TF 1 "general_operand" ""))]
3646 "TARGET_SSE2 && reload_completed
3647 && !SSE_REG_P (operands[1])"
3649 "ix86_split_long_move (operands); DONE;")
3652 [(set (match_operand:TF 0 "push_operand" "")
3653 (match_operand:TF 1 "any_fp_register_operand" ""))]
3655 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3656 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3660 [(set (match_operand 0 "nonimmediate_operand" "")
3661 (match_operand 1 "general_operand" ""))]
3663 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3664 && GET_MODE (operands[0]) == XFmode
3665 && ! (ANY_FP_REG_P (operands[0]) ||
3666 (GET_CODE (operands[0]) == SUBREG
3667 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3668 && ! (ANY_FP_REG_P (operands[1]) ||
3669 (GET_CODE (operands[1]) == SUBREG
3670 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3672 "ix86_split_long_move (operands); DONE;")
3675 [(set (match_operand 0 "register_operand" "")
3676 (match_operand 1 "memory_operand" ""))]
3678 && MEM_P (operands[1])
3679 && (GET_MODE (operands[0]) == TFmode
3680 || GET_MODE (operands[0]) == XFmode
3681 || GET_MODE (operands[0]) == SFmode
3682 || GET_MODE (operands[0]) == DFmode)
3683 && (operands[2] = find_constant_src (insn))"
3684 [(set (match_dup 0) (match_dup 2))]
3686 rtx c = operands[2];
3687 rtx r = operands[0];
3689 if (GET_CODE (r) == SUBREG)
3694 if (!standard_sse_constant_p (c))
3697 else if (FP_REG_P (r))
3699 if (!standard_80387_constant_p (c))
3702 else if (MMX_REG_P (r))
3707 [(set (match_operand 0 "register_operand" "")
3708 (float_extend (match_operand 1 "memory_operand" "")))]
3710 && MEM_P (operands[1])
3711 && (GET_MODE (operands[0]) == TFmode
3712 || GET_MODE (operands[0]) == XFmode
3713 || GET_MODE (operands[0]) == SFmode
3714 || GET_MODE (operands[0]) == DFmode)
3715 && (operands[2] = find_constant_src (insn))"
3716 [(set (match_dup 0) (match_dup 2))]
3718 rtx c = operands[2];
3719 rtx r = operands[0];
3721 if (GET_CODE (r) == SUBREG)
3726 if (!standard_sse_constant_p (c))
3729 else if (FP_REG_P (r))
3731 if (!standard_80387_constant_p (c))
3734 else if (MMX_REG_P (r))
3738 (define_insn "swapxf"
3739 [(set (match_operand:XF 0 "register_operand" "+f")
3740 (match_operand:XF 1 "register_operand" "+f"))
3745 if (STACK_TOP_P (operands[0]))
3750 [(set_attr "type" "fxch")
3751 (set_attr "mode" "XF")])
3753 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3755 [(set (match_operand:X87MODEF 0 "register_operand" "")
3756 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3757 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3758 && (standard_80387_constant_p (operands[1]) == 8
3759 || standard_80387_constant_p (operands[1]) == 9)"
3760 [(set (match_dup 0)(match_dup 1))
3762 (neg:X87MODEF (match_dup 0)))]
3766 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3767 if (real_isnegzero (&r))
3768 operands[1] = CONST0_RTX (<MODE>mode);
3770 operands[1] = CONST1_RTX (<MODE>mode);
3774 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3775 (match_operand:TF 1 "general_operand" ""))]
3777 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3779 "ix86_split_long_move (operands); DONE;")
3781 ;; Zero extension instructions
3783 (define_expand "zero_extendhisi2"
3784 [(set (match_operand:SI 0 "register_operand" "")
3785 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3788 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3790 operands[1] = force_reg (HImode, operands[1]);
3791 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3796 (define_insn "zero_extendhisi2_and"
3797 [(set (match_operand:SI 0 "register_operand" "=r")
3798 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3799 (clobber (reg:CC FLAGS_REG))]
3800 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3802 [(set_attr "type" "alu1")
3803 (set_attr "mode" "SI")])
3806 [(set (match_operand:SI 0 "register_operand" "")
3807 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3808 (clobber (reg:CC FLAGS_REG))]
3809 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3810 && optimize_function_for_speed_p (cfun)"
3811 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3812 (clobber (reg:CC FLAGS_REG))])]
3815 (define_insn "*zero_extendhisi2_movzwl"
3816 [(set (match_operand:SI 0 "register_operand" "=r")
3817 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3818 "!TARGET_ZERO_EXTEND_WITH_AND
3819 || optimize_function_for_size_p (cfun)"
3820 "movz{wl|x}\t{%1, %0|%0, %1}"
3821 [(set_attr "type" "imovx")
3822 (set_attr "mode" "SI")])
3824 (define_expand "zero_extendqihi2"
3826 [(set (match_operand:HI 0 "register_operand" "")
3827 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3828 (clobber (reg:CC FLAGS_REG))])]
3832 (define_insn "*zero_extendqihi2_and"
3833 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3834 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3835 (clobber (reg:CC FLAGS_REG))]
3836 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3838 [(set_attr "type" "alu1")
3839 (set_attr "mode" "HI")])
3841 (define_insn "*zero_extendqihi2_movzbw_and"
3842 [(set (match_operand:HI 0 "register_operand" "=r,r")
3843 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3844 (clobber (reg:CC FLAGS_REG))]
3845 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3847 [(set_attr "type" "imovx,alu1")
3848 (set_attr "mode" "HI")])
3850 ; zero extend to SImode here to avoid partial register stalls
3851 (define_insn "*zero_extendqihi2_movzbl"
3852 [(set (match_operand:HI 0 "register_operand" "=r")
3853 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3854 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3855 && reload_completed"
3856 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3857 [(set_attr "type" "imovx")
3858 (set_attr "mode" "SI")])
3860 ;; For the movzbw case strip only the clobber
3862 [(set (match_operand:HI 0 "register_operand" "")
3863 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3864 (clobber (reg:CC FLAGS_REG))]
3866 && (!TARGET_ZERO_EXTEND_WITH_AND
3867 || optimize_function_for_size_p (cfun))
3868 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3869 [(set (match_operand:HI 0 "register_operand" "")
3870 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3872 ;; When source and destination does not overlap, clear destination
3873 ;; first and then do the movb
3875 [(set (match_operand:HI 0 "register_operand" "")
3876 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3877 (clobber (reg:CC FLAGS_REG))]
3879 && ANY_QI_REG_P (operands[0])
3880 && (TARGET_ZERO_EXTEND_WITH_AND
3881 && optimize_function_for_speed_p (cfun))
3882 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3883 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3885 operands[2] = gen_lowpart (QImode, operands[0]);
3886 ix86_expand_clear (operands[0]);
3889 ;; Rest is handled by single and.
3891 [(set (match_operand:HI 0 "register_operand" "")
3892 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3893 (clobber (reg:CC FLAGS_REG))]
3895 && true_regnum (operands[0]) == true_regnum (operands[1])"
3896 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3897 (clobber (reg:CC FLAGS_REG))])]
3900 (define_expand "zero_extendqisi2"
3902 [(set (match_operand:SI 0 "register_operand" "")
3903 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3904 (clobber (reg:CC FLAGS_REG))])]
3908 (define_insn "*zero_extendqisi2_and"
3909 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3910 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3911 (clobber (reg:CC FLAGS_REG))]
3912 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3914 [(set_attr "type" "alu1")
3915 (set_attr "mode" "SI")])
3917 (define_insn "*zero_extendqisi2_movzbl_and"
3918 [(set (match_operand:SI 0 "register_operand" "=r,r")
3919 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3920 (clobber (reg:CC FLAGS_REG))]
3921 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3923 [(set_attr "type" "imovx,alu1")
3924 (set_attr "mode" "SI")])
3926 (define_insn "*zero_extendqisi2_movzbl"
3927 [(set (match_operand:SI 0 "register_operand" "=r")
3928 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3929 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3930 && reload_completed"
3931 "movz{bl|x}\t{%1, %0|%0, %1}"
3932 [(set_attr "type" "imovx")
3933 (set_attr "mode" "SI")])
3935 ;; For the movzbl case strip only the clobber
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 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3942 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3944 (zero_extend:SI (match_dup 1)))])
3946 ;; When source and destination does not overlap, clear destination
3947 ;; first and then do the movb
3949 [(set (match_operand:SI 0 "register_operand" "")
3950 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3951 (clobber (reg:CC FLAGS_REG))]
3953 && ANY_QI_REG_P (operands[0])
3954 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3955 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3956 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3957 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3959 operands[2] = gen_lowpart (QImode, operands[0]);
3960 ix86_expand_clear (operands[0]);
3963 ;; Rest is handled by single and.
3965 [(set (match_operand:SI 0 "register_operand" "")
3966 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3967 (clobber (reg:CC FLAGS_REG))]
3969 && true_regnum (operands[0]) == true_regnum (operands[1])"
3970 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3971 (clobber (reg:CC FLAGS_REG))])]
3974 ;; %%% Kill me once multi-word ops are sane.
3975 (define_expand "zero_extendsidi2"
3976 [(set (match_operand:DI 0 "register_operand" "")
3977 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3982 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3987 (define_insn "zero_extendsidi2_32"
3988 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3990 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3991 (clobber (reg:CC FLAGS_REG))]
3997 movd\t{%1, %0|%0, %1}
3998 movd\t{%1, %0|%0, %1}
3999 %vmovd\t{%1, %0|%0, %1}
4000 %vmovd\t{%1, %0|%0, %1}"
4001 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4002 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4003 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4005 (define_insn "zero_extendsidi2_rex64"
4006 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4008 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4011 mov\t{%k1, %k0|%k0, %k1}
4013 movd\t{%1, %0|%0, %1}
4014 movd\t{%1, %0|%0, %1}
4015 %vmovd\t{%1, %0|%0, %1}
4016 %vmovd\t{%1, %0|%0, %1}"
4017 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4018 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4019 (set_attr "prefix_0f" "0,*,*,*,*,*")
4020 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4023 [(set (match_operand:DI 0 "memory_operand" "")
4024 (zero_extend:DI (match_dup 0)))]
4026 [(set (match_dup 4) (const_int 0))]
4027 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4030 [(set (match_operand:DI 0 "register_operand" "")
4031 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4032 (clobber (reg:CC FLAGS_REG))]
4033 "!TARGET_64BIT && reload_completed
4034 && true_regnum (operands[0]) == true_regnum (operands[1])"
4035 [(set (match_dup 4) (const_int 0))]
4036 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4039 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4040 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4041 (clobber (reg:CC FLAGS_REG))]
4042 "!TARGET_64BIT && reload_completed
4043 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4044 [(set (match_dup 3) (match_dup 1))
4045 (set (match_dup 4) (const_int 0))]
4046 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4048 (define_insn "zero_extendhidi2"
4049 [(set (match_operand:DI 0 "register_operand" "=r")
4050 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4052 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4053 [(set_attr "type" "imovx")
4054 (set_attr "mode" "SI")])
4056 (define_insn "zero_extendqidi2"
4057 [(set (match_operand:DI 0 "register_operand" "=r")
4058 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4060 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4061 [(set_attr "type" "imovx")
4062 (set_attr "mode" "SI")])
4064 ;; Sign extension instructions
4066 (define_expand "extendsidi2"
4067 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4068 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4069 (clobber (reg:CC FLAGS_REG))
4070 (clobber (match_scratch:SI 2 ""))])]
4075 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4080 (define_insn "*extendsidi2_1"
4081 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4082 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4083 (clobber (reg:CC FLAGS_REG))
4084 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4088 (define_insn "extendsidi2_rex64"
4089 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4090 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4094 movs{lq|x}\t{%1, %0|%0, %1}"
4095 [(set_attr "type" "imovx")
4096 (set_attr "mode" "DI")
4097 (set_attr "prefix_0f" "0")
4098 (set_attr "modrm" "0,1")])
4100 (define_insn "extendhidi2"
4101 [(set (match_operand:DI 0 "register_operand" "=r")
4102 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4104 "movs{wq|x}\t{%1, %0|%0, %1}"
4105 [(set_attr "type" "imovx")
4106 (set_attr "mode" "DI")])
4108 (define_insn "extendqidi2"
4109 [(set (match_operand:DI 0 "register_operand" "=r")
4110 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4112 "movs{bq|x}\t{%1, %0|%0, %1}"
4113 [(set_attr "type" "imovx")
4114 (set_attr "mode" "DI")])
4116 ;; Extend to memory case when source register does die.
4118 [(set (match_operand:DI 0 "memory_operand" "")
4119 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4120 (clobber (reg:CC FLAGS_REG))
4121 (clobber (match_operand:SI 2 "register_operand" ""))]
4123 && dead_or_set_p (insn, operands[1])
4124 && !reg_mentioned_p (operands[1], operands[0]))"
4125 [(set (match_dup 3) (match_dup 1))
4126 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4127 (clobber (reg:CC FLAGS_REG))])
4128 (set (match_dup 4) (match_dup 1))]
4129 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4131 ;; Extend to memory case when source register does not die.
4133 [(set (match_operand:DI 0 "memory_operand" "")
4134 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4135 (clobber (reg:CC FLAGS_REG))
4136 (clobber (match_operand:SI 2 "register_operand" ""))]
4140 split_di (&operands[0], 1, &operands[3], &operands[4]);
4142 emit_move_insn (operands[3], operands[1]);
4144 /* Generate a cltd if possible and doing so it profitable. */
4145 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4146 && true_regnum (operands[1]) == AX_REG
4147 && true_regnum (operands[2]) == DX_REG)
4149 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4153 emit_move_insn (operands[2], operands[1]);
4154 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4156 emit_move_insn (operands[4], operands[2]);
4160 ;; Extend to register case. Optimize case where source and destination
4161 ;; registers match and cases where we can use cltd.
4163 [(set (match_operand:DI 0 "register_operand" "")
4164 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4165 (clobber (reg:CC FLAGS_REG))
4166 (clobber (match_scratch:SI 2 ""))]
4170 split_di (&operands[0], 1, &operands[3], &operands[4]);
4172 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4173 emit_move_insn (operands[3], operands[1]);
4175 /* Generate a cltd if possible and doing so it profitable. */
4176 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4177 && true_regnum (operands[3]) == AX_REG)
4179 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4183 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4184 emit_move_insn (operands[4], operands[1]);
4186 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4190 (define_insn "extendhisi2"
4191 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4192 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4195 switch (get_attr_prefix_0f (insn))
4198 return "{cwtl|cwde}";
4200 return "movs{wl|x}\t{%1, %0|%0, %1}";
4203 [(set_attr "type" "imovx")
4204 (set_attr "mode" "SI")
4205 (set (attr "prefix_0f")
4206 ;; movsx is short decodable while cwtl is vector decoded.
4207 (if_then_else (and (eq_attr "cpu" "!k6")
4208 (eq_attr "alternative" "0"))
4210 (const_string "1")))
4212 (if_then_else (eq_attr "prefix_0f" "0")
4214 (const_string "1")))])
4216 (define_insn "*extendhisi2_zext"
4217 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4219 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4222 switch (get_attr_prefix_0f (insn))
4225 return "{cwtl|cwde}";
4227 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4230 [(set_attr "type" "imovx")
4231 (set_attr "mode" "SI")
4232 (set (attr "prefix_0f")
4233 ;; movsx is short decodable while cwtl is vector decoded.
4234 (if_then_else (and (eq_attr "cpu" "!k6")
4235 (eq_attr "alternative" "0"))
4237 (const_string "1")))
4239 (if_then_else (eq_attr "prefix_0f" "0")
4241 (const_string "1")))])
4243 (define_insn "extendqihi2"
4244 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4245 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4248 switch (get_attr_prefix_0f (insn))
4251 return "{cbtw|cbw}";
4253 return "movs{bw|x}\t{%1, %0|%0, %1}";
4256 [(set_attr "type" "imovx")
4257 (set_attr "mode" "HI")
4258 (set (attr "prefix_0f")
4259 ;; movsx is short decodable while cwtl is vector decoded.
4260 (if_then_else (and (eq_attr "cpu" "!k6")
4261 (eq_attr "alternative" "0"))
4263 (const_string "1")))
4265 (if_then_else (eq_attr "prefix_0f" "0")
4267 (const_string "1")))])
4269 (define_insn "extendqisi2"
4270 [(set (match_operand:SI 0 "register_operand" "=r")
4271 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4273 "movs{bl|x}\t{%1, %0|%0, %1}"
4274 [(set_attr "type" "imovx")
4275 (set_attr "mode" "SI")])
4277 (define_insn "*extendqisi2_zext"
4278 [(set (match_operand:DI 0 "register_operand" "=r")
4280 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4282 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4283 [(set_attr "type" "imovx")
4284 (set_attr "mode" "SI")])
4286 ;; Conversions between float and double.
4288 ;; These are all no-ops in the model used for the 80387. So just
4291 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4292 (define_insn "*dummy_extendsfdf2"
4293 [(set (match_operand:DF 0 "push_operand" "=<")
4294 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4299 [(set (match_operand:DF 0 "push_operand" "")
4300 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4302 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4303 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4305 (define_insn "*dummy_extendsfxf2"
4306 [(set (match_operand:XF 0 "push_operand" "=<")
4307 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4312 [(set (match_operand:XF 0 "push_operand" "")
4313 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4315 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4316 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4317 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4320 [(set (match_operand:XF 0 "push_operand" "")
4321 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4323 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4324 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4325 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4327 (define_expand "extendsfdf2"
4328 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4329 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4330 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4332 /* ??? Needed for compress_float_constant since all fp constants
4333 are LEGITIMATE_CONSTANT_P. */
4334 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4336 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4337 && standard_80387_constant_p (operands[1]) > 0)
4339 operands[1] = simplify_const_unary_operation
4340 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4341 emit_move_insn_1 (operands[0], operands[1]);
4344 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4348 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4350 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4352 We do the conversion post reload to avoid producing of 128bit spills
4353 that might lead to ICE on 32bit target. The sequence unlikely combine
4356 [(set (match_operand:DF 0 "register_operand" "")
4358 (match_operand:SF 1 "nonimmediate_operand" "")))]
4359 "TARGET_USE_VECTOR_FP_CONVERTS
4360 && optimize_insn_for_speed_p ()
4361 && reload_completed && SSE_REG_P (operands[0])"
4366 (parallel [(const_int 0) (const_int 1)]))))]
4368 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4369 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4370 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4371 Try to avoid move when unpacking can be done in source. */
4372 if (REG_P (operands[1]))
4374 /* If it is unsafe to overwrite upper half of source, we need
4375 to move to destination and unpack there. */
4376 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4377 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4378 && true_regnum (operands[0]) != true_regnum (operands[1]))
4380 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4381 emit_move_insn (tmp, operands[1]);
4384 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4385 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4389 emit_insn (gen_vec_setv4sf_0 (operands[3],
4390 CONST0_RTX (V4SFmode), operands[1]));
4393 (define_insn "*extendsfdf2_mixed"
4394 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4396 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4397 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4399 switch (which_alternative)
4403 return output_387_reg_move (insn, operands);
4406 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4412 [(set_attr "type" "fmov,fmov,ssecvt")
4413 (set_attr "prefix" "orig,orig,maybe_vex")
4414 (set_attr "mode" "SF,XF,DF")])
4416 (define_insn "*extendsfdf2_sse"
4417 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4418 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4419 "TARGET_SSE2 && TARGET_SSE_MATH"
4420 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4421 [(set_attr "type" "ssecvt")
4422 (set_attr "prefix" "maybe_vex")
4423 (set_attr "mode" "DF")])
4425 (define_insn "*extendsfdf2_i387"
4426 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4427 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4429 "* return output_387_reg_move (insn, operands);"
4430 [(set_attr "type" "fmov")
4431 (set_attr "mode" "SF,XF")])
4433 (define_expand "extend<mode>xf2"
4434 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4435 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4438 /* ??? Needed for compress_float_constant since all fp constants
4439 are LEGITIMATE_CONSTANT_P. */
4440 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4442 if (standard_80387_constant_p (operands[1]) > 0)
4444 operands[1] = simplify_const_unary_operation
4445 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4446 emit_move_insn_1 (operands[0], operands[1]);
4449 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4453 (define_insn "*extend<mode>xf2_i387"
4454 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4456 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4458 "* return output_387_reg_move (insn, operands);"
4459 [(set_attr "type" "fmov")
4460 (set_attr "mode" "<MODE>,XF")])
4462 ;; %%% This seems bad bad news.
4463 ;; This cannot output into an f-reg because there is no way to be sure
4464 ;; of truncating in that case. Otherwise this is just like a simple move
4465 ;; insn. So we pretend we can output to a reg in order to get better
4466 ;; register preferencing, but we really use a stack slot.
4468 ;; Conversion from DFmode to SFmode.
4470 (define_expand "truncdfsf2"
4471 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4473 (match_operand:DF 1 "nonimmediate_operand" "")))]
4474 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4476 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4478 else if (flag_unsafe_math_optimizations)
4482 enum ix86_stack_slot slot = (virtuals_instantiated
4485 rtx temp = assign_386_stack_local (SFmode, slot);
4486 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4491 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4493 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4495 We do the conversion post reload to avoid producing of 128bit spills
4496 that might lead to ICE on 32bit target. The sequence unlikely combine
4499 [(set (match_operand:SF 0 "register_operand" "")
4501 (match_operand:DF 1 "nonimmediate_operand" "")))]
4502 "TARGET_USE_VECTOR_FP_CONVERTS
4503 && optimize_insn_for_speed_p ()
4504 && reload_completed && SSE_REG_P (operands[0])"
4507 (float_truncate:V2SF
4511 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4512 operands[3] = CONST0_RTX (V2SFmode);
4513 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4514 /* Use movsd for loading from memory, unpcklpd for registers.
4515 Try to avoid move when unpacking can be done in source, or SSE3
4516 movddup is available. */
4517 if (REG_P (operands[1]))
4520 && true_regnum (operands[0]) != true_regnum (operands[1])
4521 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4522 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4524 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4525 emit_move_insn (tmp, operands[1]);
4528 else if (!TARGET_SSE3)
4529 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4530 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4533 emit_insn (gen_sse2_loadlpd (operands[4],
4534 CONST0_RTX (V2DFmode), operands[1]));
4537 (define_expand "truncdfsf2_with_temp"
4538 [(parallel [(set (match_operand:SF 0 "" "")
4539 (float_truncate:SF (match_operand:DF 1 "" "")))
4540 (clobber (match_operand:SF 2 "" ""))])]
4543 (define_insn "*truncdfsf_fast_mixed"
4544 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4546 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4547 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4549 switch (which_alternative)
4552 return output_387_reg_move (insn, operands);
4554 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4559 [(set_attr "type" "fmov,ssecvt")
4560 (set_attr "prefix" "orig,maybe_vex")
4561 (set_attr "mode" "SF")])
4563 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4564 ;; because nothing we do here is unsafe.
4565 (define_insn "*truncdfsf_fast_sse"
4566 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4568 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4569 "TARGET_SSE2 && TARGET_SSE_MATH"
4570 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4571 [(set_attr "type" "ssecvt")
4572 (set_attr "prefix" "maybe_vex")
4573 (set_attr "mode" "SF")])
4575 (define_insn "*truncdfsf_fast_i387"
4576 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4578 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4579 "TARGET_80387 && flag_unsafe_math_optimizations"
4580 "* return output_387_reg_move (insn, operands);"
4581 [(set_attr "type" "fmov")
4582 (set_attr "mode" "SF")])
4584 (define_insn "*truncdfsf_mixed"
4585 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4587 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4588 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4589 "TARGET_MIX_SSE_I387"
4591 switch (which_alternative)
4594 return output_387_reg_move (insn, operands);
4596 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4602 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4603 (set_attr "unit" "*,*,i387,i387,i387")
4604 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4605 (set_attr "mode" "SF")])
4607 (define_insn "*truncdfsf_i387"
4608 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4610 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4611 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4614 switch (which_alternative)
4617 return output_387_reg_move (insn, operands);
4623 [(set_attr "type" "fmov,multi,multi,multi")
4624 (set_attr "unit" "*,i387,i387,i387")
4625 (set_attr "mode" "SF")])
4627 (define_insn "*truncdfsf2_i387_1"
4628 [(set (match_operand:SF 0 "memory_operand" "=m")
4630 (match_operand:DF 1 "register_operand" "f")))]
4632 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4633 && !TARGET_MIX_SSE_I387"
4634 "* return output_387_reg_move (insn, operands);"
4635 [(set_attr "type" "fmov")
4636 (set_attr "mode" "SF")])
4639 [(set (match_operand:SF 0 "register_operand" "")
4641 (match_operand:DF 1 "fp_register_operand" "")))
4642 (clobber (match_operand 2 "" ""))]
4644 [(set (match_dup 2) (match_dup 1))
4645 (set (match_dup 0) (match_dup 2))]
4647 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4650 ;; Conversion from XFmode to {SF,DF}mode
4652 (define_expand "truncxf<mode>2"
4653 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4654 (float_truncate:MODEF
4655 (match_operand:XF 1 "register_operand" "")))
4656 (clobber (match_dup 2))])]
4659 if (flag_unsafe_math_optimizations)
4661 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4662 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4663 if (reg != operands[0])
4664 emit_move_insn (operands[0], reg);
4669 enum ix86_stack_slot slot = (virtuals_instantiated
4672 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4676 (define_insn "*truncxfsf2_mixed"
4677 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4679 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4680 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4683 gcc_assert (!which_alternative);
4684 return output_387_reg_move (insn, operands);
4686 [(set_attr "type" "fmov,multi,multi,multi")
4687 (set_attr "unit" "*,i387,i387,i387")
4688 (set_attr "mode" "SF")])
4690 (define_insn "*truncxfdf2_mixed"
4691 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4693 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4694 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4697 gcc_assert (!which_alternative);
4698 return output_387_reg_move (insn, operands);
4700 [(set_attr "type" "fmov,multi,multi,multi")
4701 (set_attr "unit" "*,i387,i387,i387")
4702 (set_attr "mode" "DF")])
4704 (define_insn "truncxf<mode>2_i387_noop"
4705 [(set (match_operand:MODEF 0 "register_operand" "=f")
4706 (float_truncate:MODEF
4707 (match_operand:XF 1 "register_operand" "f")))]
4708 "TARGET_80387 && flag_unsafe_math_optimizations"
4709 "* return output_387_reg_move (insn, operands);"
4710 [(set_attr "type" "fmov")
4711 (set_attr "mode" "<MODE>")])
4713 (define_insn "*truncxf<mode>2_i387"
4714 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4715 (float_truncate:MODEF
4716 (match_operand:XF 1 "register_operand" "f")))]
4718 "* return output_387_reg_move (insn, operands);"
4719 [(set_attr "type" "fmov")
4720 (set_attr "mode" "<MODE>")])
4723 [(set (match_operand:MODEF 0 "register_operand" "")
4724 (float_truncate:MODEF
4725 (match_operand:XF 1 "register_operand" "")))
4726 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4727 "TARGET_80387 && reload_completed"
4728 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4729 (set (match_dup 0) (match_dup 2))]
4733 [(set (match_operand:MODEF 0 "memory_operand" "")
4734 (float_truncate:MODEF
4735 (match_operand:XF 1 "register_operand" "")))
4736 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4738 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4741 ;; Signed conversion to DImode.
4743 (define_expand "fix_truncxfdi2"
4744 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4745 (fix:DI (match_operand:XF 1 "register_operand" "")))
4746 (clobber (reg:CC FLAGS_REG))])]
4751 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4756 (define_expand "fix_trunc<mode>di2"
4757 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4758 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4759 (clobber (reg:CC FLAGS_REG))])]
4760 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4763 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4765 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4768 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4770 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4771 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4772 if (out != operands[0])
4773 emit_move_insn (operands[0], out);
4778 ;; Signed conversion to SImode.
4780 (define_expand "fix_truncxfsi2"
4781 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4782 (fix:SI (match_operand:XF 1 "register_operand" "")))
4783 (clobber (reg:CC FLAGS_REG))])]
4788 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4793 (define_expand "fix_trunc<mode>si2"
4794 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4795 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4796 (clobber (reg:CC FLAGS_REG))])]
4797 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4800 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4802 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4805 if (SSE_FLOAT_MODE_P (<MODE>mode))
4807 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4808 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4809 if (out != operands[0])
4810 emit_move_insn (operands[0], out);
4815 ;; Signed conversion to HImode.
4817 (define_expand "fix_trunc<mode>hi2"
4818 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4819 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4820 (clobber (reg:CC FLAGS_REG))])]
4822 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4826 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4831 ;; Unsigned conversion to SImode.
4833 (define_expand "fixuns_trunc<mode>si2"
4835 [(set (match_operand:SI 0 "register_operand" "")
4837 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4839 (clobber (match_scratch:<ssevecmode> 3 ""))
4840 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4841 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4843 enum machine_mode mode = <MODE>mode;
4844 enum machine_mode vecmode = <ssevecmode>mode;
4845 REAL_VALUE_TYPE TWO31r;
4848 if (optimize_insn_for_size_p ())
4851 real_ldexp (&TWO31r, &dconst1, 31);
4852 two31 = const_double_from_real_value (TWO31r, mode);
4853 two31 = ix86_build_const_vector (mode, true, two31);
4854 operands[2] = force_reg (vecmode, two31);
4857 (define_insn_and_split "*fixuns_trunc<mode>_1"
4858 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4860 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4861 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4862 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4863 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4864 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4865 && optimize_function_for_speed_p (cfun)"
4867 "&& reload_completed"
4870 ix86_split_convert_uns_si_sse (operands);
4874 ;; Unsigned conversion to HImode.
4875 ;; Without these patterns, we'll try the unsigned SI conversion which
4876 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4878 (define_expand "fixuns_trunc<mode>hi2"
4880 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4881 (set (match_operand:HI 0 "nonimmediate_operand" "")
4882 (subreg:HI (match_dup 2) 0))]
4883 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4884 "operands[2] = gen_reg_rtx (SImode);")
4886 ;; When SSE is available, it is always faster to use it!
4887 (define_insn "fix_trunc<mode>di_sse"
4888 [(set (match_operand:DI 0 "register_operand" "=r,r")
4889 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4890 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4891 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4892 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4893 [(set_attr "type" "sseicvt")
4894 (set_attr "prefix" "maybe_vex")
4895 (set_attr "prefix_rex" "1")
4896 (set_attr "mode" "<MODE>")
4897 (set_attr "athlon_decode" "double,vector")
4898 (set_attr "amdfam10_decode" "double,double")])
4900 (define_insn "fix_trunc<mode>si_sse"
4901 [(set (match_operand:SI 0 "register_operand" "=r,r")
4902 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4903 "SSE_FLOAT_MODE_P (<MODE>mode)
4904 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4905 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4906 [(set_attr "type" "sseicvt")
4907 (set_attr "prefix" "maybe_vex")
4908 (set_attr "mode" "<MODE>")
4909 (set_attr "athlon_decode" "double,vector")
4910 (set_attr "amdfam10_decode" "double,double")])
4912 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4914 [(set (match_operand:MODEF 0 "register_operand" "")
4915 (match_operand:MODEF 1 "memory_operand" ""))
4916 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4917 (fix:SSEMODEI24 (match_dup 0)))]
4918 "TARGET_SHORTEN_X87_SSE
4919 && peep2_reg_dead_p (2, operands[0])"
4920 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4923 ;; Avoid vector decoded forms of the instruction.
4925 [(match_scratch:DF 2 "Y2")
4926 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4927 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4928 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4929 [(set (match_dup 2) (match_dup 1))
4930 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4934 [(match_scratch:SF 2 "x")
4935 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4936 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4937 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4938 [(set (match_dup 2) (match_dup 1))
4939 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4942 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4943 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4944 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4945 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4947 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4948 && (TARGET_64BIT || <MODE>mode != DImode))
4950 && can_create_pseudo_p ()"
4955 if (memory_operand (operands[0], VOIDmode))
4956 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4959 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4960 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4966 [(set_attr "type" "fisttp")
4967 (set_attr "mode" "<MODE>")])
4969 (define_insn "fix_trunc<mode>_i387_fisttp"
4970 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4971 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4972 (clobber (match_scratch:XF 2 "=&1f"))]
4973 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4975 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4976 && (TARGET_64BIT || <MODE>mode != DImode))
4977 && TARGET_SSE_MATH)"
4978 "* return output_fix_trunc (insn, operands, 1);"
4979 [(set_attr "type" "fisttp")
4980 (set_attr "mode" "<MODE>")])
4982 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4983 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4984 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4985 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4986 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4987 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4989 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4990 && (TARGET_64BIT || <MODE>mode != DImode))
4991 && TARGET_SSE_MATH)"
4993 [(set_attr "type" "fisttp")
4994 (set_attr "mode" "<MODE>")])
4997 [(set (match_operand:X87MODEI 0 "register_operand" "")
4998 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4999 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5000 (clobber (match_scratch 3 ""))]
5002 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5003 (clobber (match_dup 3))])
5004 (set (match_dup 0) (match_dup 2))]
5008 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5009 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5010 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5011 (clobber (match_scratch 3 ""))]
5013 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5014 (clobber (match_dup 3))])]
5017 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5018 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5019 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5020 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5021 ;; function in i386.c.
5022 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5023 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5024 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5025 (clobber (reg:CC FLAGS_REG))]
5026 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5028 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5029 && (TARGET_64BIT || <MODE>mode != DImode))
5030 && can_create_pseudo_p ()"
5035 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5037 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5038 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5039 if (memory_operand (operands[0], VOIDmode))
5040 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5041 operands[2], operands[3]));
5044 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5045 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5046 operands[2], operands[3],
5051 [(set_attr "type" "fistp")
5052 (set_attr "i387_cw" "trunc")
5053 (set_attr "mode" "<MODE>")])
5055 (define_insn "fix_truncdi_i387"
5056 [(set (match_operand:DI 0 "memory_operand" "=m")
5057 (fix:DI (match_operand 1 "register_operand" "f")))
5058 (use (match_operand:HI 2 "memory_operand" "m"))
5059 (use (match_operand:HI 3 "memory_operand" "m"))
5060 (clobber (match_scratch:XF 4 "=&1f"))]
5061 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5063 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5064 "* return output_fix_trunc (insn, operands, 0);"
5065 [(set_attr "type" "fistp")
5066 (set_attr "i387_cw" "trunc")
5067 (set_attr "mode" "DI")])
5069 (define_insn "fix_truncdi_i387_with_temp"
5070 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5071 (fix:DI (match_operand 1 "register_operand" "f,f")))
5072 (use (match_operand:HI 2 "memory_operand" "m,m"))
5073 (use (match_operand:HI 3 "memory_operand" "m,m"))
5074 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5075 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5076 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5078 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5080 [(set_attr "type" "fistp")
5081 (set_attr "i387_cw" "trunc")
5082 (set_attr "mode" "DI")])
5085 [(set (match_operand:DI 0 "register_operand" "")
5086 (fix:DI (match_operand 1 "register_operand" "")))
5087 (use (match_operand:HI 2 "memory_operand" ""))
5088 (use (match_operand:HI 3 "memory_operand" ""))
5089 (clobber (match_operand:DI 4 "memory_operand" ""))
5090 (clobber (match_scratch 5 ""))]
5092 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5095 (clobber (match_dup 5))])
5096 (set (match_dup 0) (match_dup 4))]
5100 [(set (match_operand:DI 0 "memory_operand" "")
5101 (fix:DI (match_operand 1 "register_operand" "")))
5102 (use (match_operand:HI 2 "memory_operand" ""))
5103 (use (match_operand:HI 3 "memory_operand" ""))
5104 (clobber (match_operand:DI 4 "memory_operand" ""))
5105 (clobber (match_scratch 5 ""))]
5107 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5110 (clobber (match_dup 5))])]
5113 (define_insn "fix_trunc<mode>_i387"
5114 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5115 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5116 (use (match_operand:HI 2 "memory_operand" "m"))
5117 (use (match_operand:HI 3 "memory_operand" "m"))]
5118 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5120 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5121 "* return output_fix_trunc (insn, operands, 0);"
5122 [(set_attr "type" "fistp")
5123 (set_attr "i387_cw" "trunc")
5124 (set_attr "mode" "<MODE>")])
5126 (define_insn "fix_trunc<mode>_i387_with_temp"
5127 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5128 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5129 (use (match_operand:HI 2 "memory_operand" "m,m"))
5130 (use (match_operand:HI 3 "memory_operand" "m,m"))
5131 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5132 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5134 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5136 [(set_attr "type" "fistp")
5137 (set_attr "i387_cw" "trunc")
5138 (set_attr "mode" "<MODE>")])
5141 [(set (match_operand:X87MODEI12 0 "register_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 4) (fix:X87MODEI12 (match_dup 1)))
5149 (use (match_dup 3))])
5150 (set (match_dup 0) (match_dup 4))]
5154 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5155 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5156 (use (match_operand:HI 2 "memory_operand" ""))
5157 (use (match_operand:HI 3 "memory_operand" ""))
5158 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5160 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5162 (use (match_dup 3))])]
5165 (define_insn "x86_fnstcw_1"
5166 [(set (match_operand:HI 0 "memory_operand" "=m")
5167 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5170 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5171 (set_attr "mode" "HI")
5172 (set_attr "unit" "i387")])
5174 (define_insn "x86_fldcw_1"
5175 [(set (reg:HI FPCR_REG)
5176 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5179 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5180 (set_attr "mode" "HI")
5181 (set_attr "unit" "i387")
5182 (set_attr "athlon_decode" "vector")
5183 (set_attr "amdfam10_decode" "vector")])
5185 ;; Conversion between fixed point and floating point.
5187 ;; Even though we only accept memory inputs, the backend _really_
5188 ;; wants to be able to do this between registers.
5190 (define_expand "floathi<mode>2"
5191 [(set (match_operand:X87MODEF 0 "register_operand" "")
5192 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5194 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5195 || TARGET_MIX_SSE_I387)"
5198 ;; Pre-reload splitter to add memory clobber to the pattern.
5199 (define_insn_and_split "*floathi<mode>2_1"
5200 [(set (match_operand:X87MODEF 0 "register_operand" "")
5201 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5203 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5204 || TARGET_MIX_SSE_I387)
5205 && can_create_pseudo_p ()"
5208 [(parallel [(set (match_dup 0)
5209 (float:X87MODEF (match_dup 1)))
5210 (clobber (match_dup 2))])]
5211 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5213 (define_insn "*floathi<mode>2_i387_with_temp"
5214 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5215 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5216 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5218 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5219 || TARGET_MIX_SSE_I387)"
5221 [(set_attr "type" "fmov,multi")
5222 (set_attr "mode" "<MODE>")
5223 (set_attr "unit" "*,i387")
5224 (set_attr "fp_int_src" "true")])
5226 (define_insn "*floathi<mode>2_i387"
5227 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5228 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5230 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5231 || TARGET_MIX_SSE_I387)"
5233 [(set_attr "type" "fmov")
5234 (set_attr "mode" "<MODE>")
5235 (set_attr "fp_int_src" "true")])
5238 [(set (match_operand:X87MODEF 0 "register_operand" "")
5239 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5240 (clobber (match_operand:HI 2 "memory_operand" ""))]
5242 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5243 || TARGET_MIX_SSE_I387)
5244 && reload_completed"
5245 [(set (match_dup 2) (match_dup 1))
5246 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5250 [(set (match_operand:X87MODEF 0 "register_operand" "")
5251 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5252 (clobber (match_operand:HI 2 "memory_operand" ""))]
5254 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5255 || TARGET_MIX_SSE_I387)
5256 && reload_completed"
5257 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5260 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5261 [(set (match_operand:X87MODEF 0 "register_operand" "")
5263 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5265 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5266 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5268 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5269 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5270 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5272 rtx reg = gen_reg_rtx (XFmode);
5275 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5277 if (<X87MODEF:MODE>mode == SFmode)
5278 insn = gen_truncxfsf2 (operands[0], reg);
5279 else if (<X87MODEF:MODE>mode == DFmode)
5280 insn = gen_truncxfdf2 (operands[0], reg);
5289 ;; Pre-reload splitter to add memory clobber to the pattern.
5290 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5291 [(set (match_operand:X87MODEF 0 "register_operand" "")
5292 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5294 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5295 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5296 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5297 || TARGET_MIX_SSE_I387))
5298 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5299 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5300 && ((<SSEMODEI24:MODE>mode == SImode
5301 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5302 && optimize_function_for_speed_p (cfun)
5303 && flag_trapping_math)
5304 || !(TARGET_INTER_UNIT_CONVERSIONS
5305 || optimize_function_for_size_p (cfun)))))
5306 && can_create_pseudo_p ()"
5309 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5310 (clobber (match_dup 2))])]
5312 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5314 /* Avoid store forwarding (partial memory) stall penalty
5315 by passing DImode value through XMM registers. */
5316 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5317 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5318 && optimize_function_for_speed_p (cfun))
5320 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5327 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5328 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5330 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5331 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5332 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5333 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5335 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5336 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5337 (set_attr "unit" "*,i387,*,*,*")
5338 (set_attr "athlon_decode" "*,*,double,direct,double")
5339 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5340 (set_attr "fp_int_src" "true")])
5342 (define_insn "*floatsi<mode>2_vector_mixed"
5343 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5344 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5345 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5346 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5350 [(set_attr "type" "fmov,sseicvt")
5351 (set_attr "mode" "<MODE>,<ssevecmode>")
5352 (set_attr "unit" "i387,*")
5353 (set_attr "athlon_decode" "*,direct")
5354 (set_attr "amdfam10_decode" "*,double")
5355 (set_attr "fp_int_src" "true")])
5357 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5358 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5360 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5361 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5362 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5363 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5365 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5366 (set_attr "mode" "<MODEF:MODE>")
5367 (set_attr "unit" "*,i387,*,*")
5368 (set_attr "athlon_decode" "*,*,double,direct")
5369 (set_attr "amdfam10_decode" "*,*,vector,double")
5370 (set_attr "fp_int_src" "true")])
5373 [(set (match_operand:MODEF 0 "register_operand" "")
5374 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5375 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5376 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5377 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5378 && TARGET_INTER_UNIT_CONVERSIONS
5380 && (SSE_REG_P (operands[0])
5381 || (GET_CODE (operands[0]) == SUBREG
5382 && SSE_REG_P (operands[0])))"
5383 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5387 [(set (match_operand:MODEF 0 "register_operand" "")
5388 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5389 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5390 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5391 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5392 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5394 && (SSE_REG_P (operands[0])
5395 || (GET_CODE (operands[0]) == SUBREG
5396 && SSE_REG_P (operands[0])))"
5397 [(set (match_dup 2) (match_dup 1))
5398 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5401 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5402 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5404 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5405 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5406 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5407 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5410 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5411 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5412 [(set_attr "type" "fmov,sseicvt,sseicvt")
5413 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5414 (set_attr "mode" "<MODEF:MODE>")
5415 (set (attr "prefix_rex")
5417 (and (eq_attr "prefix" "maybe_vex")
5418 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5420 (const_string "*")))
5421 (set_attr "unit" "i387,*,*")
5422 (set_attr "athlon_decode" "*,double,direct")
5423 (set_attr "amdfam10_decode" "*,vector,double")
5424 (set_attr "fp_int_src" "true")])
5426 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5427 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5429 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5430 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5431 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5432 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5435 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5436 [(set_attr "type" "fmov,sseicvt")
5437 (set_attr "prefix" "orig,maybe_vex")
5438 (set_attr "mode" "<MODEF:MODE>")
5439 (set (attr "prefix_rex")
5441 (and (eq_attr "prefix" "maybe_vex")
5442 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5444 (const_string "*")))
5445 (set_attr "athlon_decode" "*,direct")
5446 (set_attr "amdfam10_decode" "*,double")
5447 (set_attr "fp_int_src" "true")])
5449 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5450 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5452 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5453 (clobber (match_operand:SI 2 "memory_operand" "=m,X,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>,<MODE>,<ssevecmode>")
5459 (set_attr "athlon_decode" "double,direct,double")
5460 (set_attr "amdfam10_decode" "vector,double,double")
5461 (set_attr "fp_int_src" "true")])
5463 (define_insn "*floatsi<mode>2_vector_sse"
5464 [(set (match_operand:MODEF 0 "register_operand" "=x")
5465 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5466 "TARGET_SSE2 && TARGET_SSE_MATH
5467 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5469 [(set_attr "type" "sseicvt")
5470 (set_attr "mode" "<MODE>")
5471 (set_attr "athlon_decode" "direct")
5472 (set_attr "amdfam10_decode" "double")
5473 (set_attr "fp_int_src" "true")])
5476 [(set (match_operand:MODEF 0 "register_operand" "")
5477 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5478 (clobber (match_operand:SI 2 "memory_operand" ""))]
5479 "TARGET_SSE2 && TARGET_SSE_MATH
5480 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5482 && (SSE_REG_P (operands[0])
5483 || (GET_CODE (operands[0]) == SUBREG
5484 && SSE_REG_P (operands[0])))"
5487 rtx op1 = operands[1];
5489 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5491 if (GET_CODE (op1) == SUBREG)
5492 op1 = SUBREG_REG (op1);
5494 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5496 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5497 emit_insn (gen_sse2_loadld (operands[4],
5498 CONST0_RTX (V4SImode), operands[1]));
5500 /* We can ignore possible trapping value in the
5501 high part of SSE register for non-trapping math. */
5502 else if (SSE_REG_P (op1) && !flag_trapping_math)
5503 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5506 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5507 emit_move_insn (operands[2], operands[1]);
5508 emit_insn (gen_sse2_loadld (operands[4],
5509 CONST0_RTX (V4SImode), operands[2]));
5512 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5517 [(set (match_operand:MODEF 0 "register_operand" "")
5518 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5519 (clobber (match_operand:SI 2 "memory_operand" ""))]
5520 "TARGET_SSE2 && TARGET_SSE_MATH
5521 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5523 && (SSE_REG_P (operands[0])
5524 || (GET_CODE (operands[0]) == SUBREG
5525 && SSE_REG_P (operands[0])))"
5528 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5530 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5532 emit_insn (gen_sse2_loadld (operands[4],
5533 CONST0_RTX (V4SImode), operands[1]));
5535 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5540 [(set (match_operand:MODEF 0 "register_operand" "")
5541 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5542 "TARGET_SSE2 && TARGET_SSE_MATH
5543 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5545 && (SSE_REG_P (operands[0])
5546 || (GET_CODE (operands[0]) == SUBREG
5547 && SSE_REG_P (operands[0])))"
5550 rtx op1 = operands[1];
5552 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5554 if (GET_CODE (op1) == SUBREG)
5555 op1 = SUBREG_REG (op1);
5557 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5559 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5560 emit_insn (gen_sse2_loadld (operands[4],
5561 CONST0_RTX (V4SImode), operands[1]));
5563 /* We can ignore possible trapping value in the
5564 high part of SSE register for non-trapping math. */
5565 else if (SSE_REG_P (op1) && !flag_trapping_math)
5566 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5570 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5575 [(set (match_operand:MODEF 0 "register_operand" "")
5576 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5577 "TARGET_SSE2 && TARGET_SSE_MATH
5578 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5580 && (SSE_REG_P (operands[0])
5581 || (GET_CODE (operands[0]) == SUBREG
5582 && SSE_REG_P (operands[0])))"
5585 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5587 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5589 emit_insn (gen_sse2_loadld (operands[4],
5590 CONST0_RTX (V4SImode), operands[1]));
5592 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5596 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5597 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5599 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5600 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5601 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5602 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5604 [(set_attr "type" "sseicvt")
5605 (set_attr "mode" "<MODEF:MODE>")
5606 (set_attr "athlon_decode" "double,direct")
5607 (set_attr "amdfam10_decode" "vector,double")
5608 (set_attr "fp_int_src" "true")])
5610 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5611 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5613 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5614 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5615 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5616 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5617 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5618 [(set_attr "type" "sseicvt")
5619 (set_attr "prefix" "maybe_vex")
5620 (set_attr "mode" "<MODEF:MODE>")
5621 (set (attr "prefix_rex")
5623 (and (eq_attr "prefix" "maybe_vex")
5624 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5626 (const_string "*")))
5627 (set_attr "athlon_decode" "double,direct")
5628 (set_attr "amdfam10_decode" "vector,double")
5629 (set_attr "fp_int_src" "true")])
5632 [(set (match_operand:MODEF 0 "register_operand" "")
5633 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5634 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5635 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5636 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5637 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5639 && (SSE_REG_P (operands[0])
5640 || (GET_CODE (operands[0]) == SUBREG
5641 && SSE_REG_P (operands[0])))"
5642 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5645 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5646 [(set (match_operand:MODEF 0 "register_operand" "=x")
5648 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5649 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5650 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5651 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5652 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5653 [(set_attr "type" "sseicvt")
5654 (set_attr "prefix" "maybe_vex")
5655 (set_attr "mode" "<MODEF:MODE>")
5656 (set (attr "prefix_rex")
5658 (and (eq_attr "prefix" "maybe_vex")
5659 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5661 (const_string "*")))
5662 (set_attr "athlon_decode" "direct")
5663 (set_attr "amdfam10_decode" "double")
5664 (set_attr "fp_int_src" "true")])
5667 [(set (match_operand:MODEF 0 "register_operand" "")
5668 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5669 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5670 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5671 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5672 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5674 && (SSE_REG_P (operands[0])
5675 || (GET_CODE (operands[0]) == SUBREG
5676 && SSE_REG_P (operands[0])))"
5677 [(set (match_dup 2) (match_dup 1))
5678 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5682 [(set (match_operand:MODEF 0 "register_operand" "")
5683 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5684 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5685 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5686 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5688 && (SSE_REG_P (operands[0])
5689 || (GET_CODE (operands[0]) == SUBREG
5690 && SSE_REG_P (operands[0])))"
5691 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5694 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5695 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5697 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5698 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5700 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5704 [(set_attr "type" "fmov,multi")
5705 (set_attr "mode" "<X87MODEF:MODE>")
5706 (set_attr "unit" "*,i387")
5707 (set_attr "fp_int_src" "true")])
5709 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5710 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5712 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5714 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5716 [(set_attr "type" "fmov")
5717 (set_attr "mode" "<X87MODEF:MODE>")
5718 (set_attr "fp_int_src" "true")])
5721 [(set (match_operand:X87MODEF 0 "register_operand" "")
5722 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_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 2) (match_dup 1))
5729 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5733 [(set (match_operand:X87MODEF 0 "register_operand" "")
5734 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5735 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5737 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5739 && FP_REG_P (operands[0])"
5740 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5743 ;; Avoid store forwarding (partial memory) stall penalty
5744 ;; by passing DImode value through XMM registers. */
5746 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5747 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5749 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5750 (clobber (match_scratch:V4SI 3 "=X,x"))
5751 (clobber (match_scratch:V4SI 4 "=X,x"))
5752 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5753 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5754 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5755 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5757 [(set_attr "type" "multi")
5758 (set_attr "mode" "<X87MODEF:MODE>")
5759 (set_attr "unit" "i387")
5760 (set_attr "fp_int_src" "true")])
5763 [(set (match_operand:X87MODEF 0 "register_operand" "")
5764 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5765 (clobber (match_scratch:V4SI 3 ""))
5766 (clobber (match_scratch:V4SI 4 ""))
5767 (clobber (match_operand:DI 2 "memory_operand" ""))]
5768 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5769 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5770 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5772 && FP_REG_P (operands[0])"
5773 [(set (match_dup 2) (match_dup 3))
5774 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5776 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5777 Assemble the 64-bit DImode value in an xmm register. */
5778 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5779 gen_rtx_SUBREG (SImode, operands[1], 0)));
5780 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5781 gen_rtx_SUBREG (SImode, operands[1], 4)));
5782 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5785 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5789 [(set (match_operand:X87MODEF 0 "register_operand" "")
5790 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5791 (clobber (match_scratch:V4SI 3 ""))
5792 (clobber (match_scratch:V4SI 4 ""))
5793 (clobber (match_operand:DI 2 "memory_operand" ""))]
5794 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5795 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5796 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5798 && FP_REG_P (operands[0])"
5799 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5802 ;; Avoid store forwarding (partial memory) stall penalty by extending
5803 ;; SImode value to DImode through XMM register instead of pushing two
5804 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5805 ;; targets benefit from this optimization. Also note that fild
5806 ;; loads from memory only.
5808 (define_insn "*floatunssi<mode>2_1"
5809 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5810 (unsigned_float:X87MODEF
5811 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5812 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5813 (clobber (match_scratch:SI 3 "=X,x"))]
5815 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5818 [(set_attr "type" "multi")
5819 (set_attr "mode" "<MODE>")])
5822 [(set (match_operand:X87MODEF 0 "register_operand" "")
5823 (unsigned_float:X87MODEF
5824 (match_operand:SI 1 "register_operand" "")))
5825 (clobber (match_operand:DI 2 "memory_operand" ""))
5826 (clobber (match_scratch:SI 3 ""))]
5828 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5830 && reload_completed"
5831 [(set (match_dup 2) (match_dup 1))
5833 (float:X87MODEF (match_dup 2)))]
5834 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5837 [(set (match_operand:X87MODEF 0 "register_operand" "")
5838 (unsigned_float:X87MODEF
5839 (match_operand:SI 1 "memory_operand" "")))
5840 (clobber (match_operand:DI 2 "memory_operand" ""))
5841 (clobber (match_scratch:SI 3 ""))]
5843 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5845 && reload_completed"
5846 [(set (match_dup 2) (match_dup 3))
5848 (float:X87MODEF (match_dup 2)))]
5850 emit_move_insn (operands[3], operands[1]);
5851 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5854 (define_expand "floatunssi<mode>2"
5856 [(set (match_operand:X87MODEF 0 "register_operand" "")
5857 (unsigned_float:X87MODEF
5858 (match_operand:SI 1 "nonimmediate_operand" "")))
5859 (clobber (match_dup 2))
5860 (clobber (match_scratch:SI 3 ""))])]
5862 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5864 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5866 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5868 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5873 enum ix86_stack_slot slot = (virtuals_instantiated
5876 operands[2] = assign_386_stack_local (DImode, slot);
5880 (define_expand "floatunsdisf2"
5881 [(use (match_operand:SF 0 "register_operand" ""))
5882 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5883 "TARGET_64BIT && TARGET_SSE_MATH"
5884 "x86_emit_floatuns (operands); DONE;")
5886 (define_expand "floatunsdidf2"
5887 [(use (match_operand:DF 0 "register_operand" ""))
5888 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5889 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5890 && TARGET_SSE2 && TARGET_SSE_MATH"
5893 x86_emit_floatuns (operands);
5895 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5901 (define_expand "add<mode>3"
5902 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5903 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5904 (match_operand:SDWIM 2 "<general_operand>" "")))]
5906 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5908 (define_insn_and_split "*add<dwi>3_doubleword"
5909 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5911 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5912 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5913 (clobber (reg:CC FLAGS_REG))]
5914 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5917 [(parallel [(set (reg:CC FLAGS_REG)
5918 (unspec:CC [(match_dup 1) (match_dup 2)]
5921 (plus:DWIH (match_dup 1) (match_dup 2)))])
5922 (parallel [(set (match_dup 3)
5926 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5928 (clobber (reg:CC FLAGS_REG))])]
5929 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5931 (define_insn "*add<mode>3_cc"
5932 [(set (reg:CC FLAGS_REG)
5934 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5935 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5937 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5938 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5939 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5940 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5941 [(set_attr "type" "alu")
5942 (set_attr "mode" "<MODE>")])
5944 (define_insn "addqi3_cc"
5945 [(set (reg:CC FLAGS_REG)
5947 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5948 (match_operand:QI 2 "general_operand" "qn,qm")]
5950 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5951 (plus:QI (match_dup 1) (match_dup 2)))]
5952 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5953 "add{b}\t{%2, %0|%0, %2}"
5954 [(set_attr "type" "alu")
5955 (set_attr "mode" "QI")])
5957 (define_insn "*lea_1"
5958 [(set (match_operand:DWIH 0 "register_operand" "=r")
5959 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5961 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5962 [(set_attr "type" "lea")
5963 (set_attr "mode" "<MODE>")])
5965 (define_insn "*lea_2"
5966 [(set (match_operand:SI 0 "register_operand" "=r")
5967 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5969 "lea{l}\t{%a1, %0|%0, %a1}"
5970 [(set_attr "type" "lea")
5971 (set_attr "mode" "SI")])
5973 (define_insn "*lea_2_zext"
5974 [(set (match_operand:DI 0 "register_operand" "=r")
5976 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5978 "lea{l}\t{%a1, %k0|%k0, %a1}"
5979 [(set_attr "type" "lea")
5980 (set_attr "mode" "SI")])
5982 (define_insn "*add<mode>_1"
5983 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5985 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5986 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5987 (clobber (reg:CC FLAGS_REG))]
5988 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5990 switch (get_attr_type (insn))
5993 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5994 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5997 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5998 if (operands[2] == const1_rtx)
5999 return "inc{<imodesuffix>}\t%0";
6002 gcc_assert (operands[2] == constm1_rtx);
6003 return "dec{<imodesuffix>}\t%0";
6007 /* Use add as much as possible to replace lea for AGU optimization. */
6008 if (which_alternative == 2 && TARGET_OPT_AGU)
6009 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6011 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6013 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6014 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6015 if (CONST_INT_P (operands[2])
6016 /* Avoid overflows. */
6017 && (<MODE>mode != DImode
6018 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6019 && (INTVAL (operands[2]) == 128
6020 || (INTVAL (operands[2]) < 0
6021 && INTVAL (operands[2]) != -128)))
6023 operands[2] = GEN_INT (-INTVAL (operands[2]));
6024 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6026 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6030 (cond [(and (eq_attr "alternative" "2")
6031 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6032 (const_string "lea")
6033 (eq_attr "alternative" "3")
6034 (const_string "lea")
6035 ; Current assemblers are broken and do not allow @GOTOFF in
6036 ; ought but a memory context.
6037 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6038 (const_string "lea")
6039 (match_operand:SWI48 2 "incdec_operand" "")
6040 (const_string "incdec")
6042 (const_string "alu")))
6043 (set (attr "length_immediate")
6045 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6047 (const_string "*")))
6048 (set_attr "mode" "<MODE>")])
6050 ;; It may seem that nonimmediate operand is proper one for operand 1.
6051 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6052 ;; we take care in ix86_binary_operator_ok to not allow two memory
6053 ;; operands so proper swapping will be done in reload. This allow
6054 ;; patterns constructed from addsi_1 to match.
6056 (define_insn "*addsi_1_zext"
6057 [(set (match_operand:DI 0 "register_operand" "=r,r")
6059 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6060 (match_operand:SI 2 "general_operand" "g,li"))))
6061 (clobber (reg:CC FLAGS_REG))]
6062 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6064 switch (get_attr_type (insn))
6067 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6068 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6071 if (operands[2] == const1_rtx)
6072 return "inc{l}\t%k0";
6075 gcc_assert (operands[2] == constm1_rtx);
6076 return "dec{l}\t%k0";
6080 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6081 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6082 if (CONST_INT_P (operands[2])
6083 && (INTVAL (operands[2]) == 128
6084 || (INTVAL (operands[2]) < 0
6085 && INTVAL (operands[2]) != -128)))
6087 operands[2] = GEN_INT (-INTVAL (operands[2]));
6088 return "sub{l}\t{%2, %k0|%k0, %2}";
6090 return "add{l}\t{%2, %k0|%k0, %2}";
6094 (cond [(eq_attr "alternative" "1")
6095 (const_string "lea")
6096 ; Current assemblers are broken and do not allow @GOTOFF in
6097 ; ought but a memory context.
6098 (match_operand:SI 2 "pic_symbolic_operand" "")
6099 (const_string "lea")
6100 (match_operand:SI 2 "incdec_operand" "")
6101 (const_string "incdec")
6103 (const_string "alu")))
6104 (set (attr "length_immediate")
6106 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6108 (const_string "*")))
6109 (set_attr "mode" "SI")])
6111 (define_insn "*addhi_1"
6112 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6113 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6114 (match_operand:HI 2 "general_operand" "rn,rm")))
6115 (clobber (reg:CC FLAGS_REG))]
6116 "TARGET_PARTIAL_REG_STALL
6117 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6119 switch (get_attr_type (insn))
6122 if (operands[2] == const1_rtx)
6123 return "inc{w}\t%0";
6126 gcc_assert (operands[2] == constm1_rtx);
6127 return "dec{w}\t%0";
6131 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6132 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6133 if (CONST_INT_P (operands[2])
6134 && (INTVAL (operands[2]) == 128
6135 || (INTVAL (operands[2]) < 0
6136 && INTVAL (operands[2]) != -128)))
6138 operands[2] = GEN_INT (-INTVAL (operands[2]));
6139 return "sub{w}\t{%2, %0|%0, %2}";
6141 return "add{w}\t{%2, %0|%0, %2}";
6145 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6146 (const_string "incdec")
6147 (const_string "alu")))
6148 (set (attr "length_immediate")
6150 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6152 (const_string "*")))
6153 (set_attr "mode" "HI")])
6155 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6156 ;; type optimizations enabled by define-splits. This is not important
6157 ;; for PII, and in fact harmful because of partial register stalls.
6159 (define_insn "*addhi_1_lea"
6160 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6161 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6162 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6163 (clobber (reg:CC FLAGS_REG))]
6164 "!TARGET_PARTIAL_REG_STALL
6165 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6167 switch (get_attr_type (insn))
6172 if (operands[2] == const1_rtx)
6173 return "inc{w}\t%0";
6176 gcc_assert (operands[2] == constm1_rtx);
6177 return "dec{w}\t%0";
6181 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6182 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6183 if (CONST_INT_P (operands[2])
6184 && (INTVAL (operands[2]) == 128
6185 || (INTVAL (operands[2]) < 0
6186 && INTVAL (operands[2]) != -128)))
6188 operands[2] = GEN_INT (-INTVAL (operands[2]));
6189 return "sub{w}\t{%2, %0|%0, %2}";
6191 return "add{w}\t{%2, %0|%0, %2}";
6195 (if_then_else (eq_attr "alternative" "2")
6196 (const_string "lea")
6197 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6198 (const_string "incdec")
6199 (const_string "alu"))))
6200 (set (attr "length_immediate")
6202 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6204 (const_string "*")))
6205 (set_attr "mode" "HI,HI,SI")])
6207 (define_insn "*addqi_1"
6208 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6209 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6210 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6211 (clobber (reg:CC FLAGS_REG))]
6212 "TARGET_PARTIAL_REG_STALL
6213 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6215 int widen = (which_alternative == 2);
6216 switch (get_attr_type (insn))
6219 if (operands[2] == const1_rtx)
6220 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6223 gcc_assert (operands[2] == constm1_rtx);
6224 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6228 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6229 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6230 if (CONST_INT_P (operands[2])
6231 && (INTVAL (operands[2]) == 128
6232 || (INTVAL (operands[2]) < 0
6233 && INTVAL (operands[2]) != -128)))
6235 operands[2] = GEN_INT (-INTVAL (operands[2]));
6237 return "sub{l}\t{%2, %k0|%k0, %2}";
6239 return "sub{b}\t{%2, %0|%0, %2}";
6242 return "add{l}\t{%k2, %k0|%k0, %k2}";
6244 return "add{b}\t{%2, %0|%0, %2}";
6248 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6249 (const_string "incdec")
6250 (const_string "alu")))
6251 (set (attr "length_immediate")
6253 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6255 (const_string "*")))
6256 (set_attr "mode" "QI,QI,SI")])
6258 ;; %%% Potential partial reg stall on alternative 2. What to do?
6259 (define_insn "*addqi_1_lea"
6260 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6261 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6262 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6263 (clobber (reg:CC FLAGS_REG))]
6264 "!TARGET_PARTIAL_REG_STALL
6265 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6267 int widen = (which_alternative == 2);
6268 switch (get_attr_type (insn))
6273 if (operands[2] == const1_rtx)
6274 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6277 gcc_assert (operands[2] == constm1_rtx);
6278 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6282 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6283 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6284 if (CONST_INT_P (operands[2])
6285 && (INTVAL (operands[2]) == 128
6286 || (INTVAL (operands[2]) < 0
6287 && INTVAL (operands[2]) != -128)))
6289 operands[2] = GEN_INT (-INTVAL (operands[2]));
6291 return "sub{l}\t{%2, %k0|%k0, %2}";
6293 return "sub{b}\t{%2, %0|%0, %2}";
6296 return "add{l}\t{%k2, %k0|%k0, %k2}";
6298 return "add{b}\t{%2, %0|%0, %2}";
6302 (if_then_else (eq_attr "alternative" "3")
6303 (const_string "lea")
6304 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6305 (const_string "incdec")
6306 (const_string "alu"))))
6307 (set (attr "length_immediate")
6309 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6311 (const_string "*")))
6312 (set_attr "mode" "QI,QI,SI,SI")])
6314 (define_insn "*addqi_1_slp"
6315 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6316 (plus:QI (match_dup 0)
6317 (match_operand:QI 1 "general_operand" "qn,qnm")))
6318 (clobber (reg:CC FLAGS_REG))]
6319 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6320 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6322 switch (get_attr_type (insn))
6325 if (operands[1] == const1_rtx)
6326 return "inc{b}\t%0";
6329 gcc_assert (operands[1] == constm1_rtx);
6330 return "dec{b}\t%0";
6334 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6335 if (CONST_INT_P (operands[1])
6336 && INTVAL (operands[1]) < 0)
6338 operands[1] = GEN_INT (-INTVAL (operands[1]));
6339 return "sub{b}\t{%1, %0|%0, %1}";
6341 return "add{b}\t{%1, %0|%0, %1}";
6345 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6346 (const_string "incdec")
6347 (const_string "alu1")))
6348 (set (attr "memory")
6349 (if_then_else (match_operand 1 "memory_operand" "")
6350 (const_string "load")
6351 (const_string "none")))
6352 (set_attr "mode" "QI")])
6354 (define_insn "*add<mode>_2"
6355 [(set (reg FLAGS_REG)
6358 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6359 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6361 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6362 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6363 "ix86_match_ccmode (insn, CCGOCmode)
6364 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6365 /* Current assemblers are broken and do not allow @GOTOFF in
6366 ought but a memory context. */
6367 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6369 switch (get_attr_type (insn))
6372 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6373 if (operands[2] == const1_rtx)
6374 return "inc{<imodesuffix>}\t%0";
6377 gcc_assert (operands[2] == constm1_rtx);
6378 return "dec{<imodesuffix>}\t%0";
6382 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6383 /* ???? In DImode, we ought to handle there the 32bit case too
6384 - do we need new constraint? */
6385 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6386 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6387 if (CONST_INT_P (operands[2])
6388 /* Avoid overflows. */
6389 && (<MODE>mode != DImode
6390 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6391 && (INTVAL (operands[2]) == 128
6392 || (INTVAL (operands[2]) < 0
6393 && INTVAL (operands[2]) != -128)))
6395 operands[2] = GEN_INT (-INTVAL (operands[2]));
6396 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6398 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6402 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6403 (const_string "incdec")
6404 (const_string "alu")))
6405 (set (attr "length_immediate")
6407 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6409 (const_string "*")))
6410 (set_attr "mode" "<MODE>")])
6412 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6413 (define_insn "*addsi_2_zext"
6414 [(set (reg FLAGS_REG)
6416 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6417 (match_operand:SI 2 "general_operand" "g"))
6419 (set (match_operand:DI 0 "register_operand" "=r")
6420 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6421 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6422 && ix86_binary_operator_ok (PLUS, SImode, operands)
6423 /* Current assemblers are broken and do not allow @GOTOFF in
6424 ought but a memory context. */
6425 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6427 switch (get_attr_type (insn))
6430 if (operands[2] == const1_rtx)
6431 return "inc{l}\t%k0";
6434 gcc_assert (operands[2] == constm1_rtx);
6435 return "dec{l}\t%k0";
6439 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6440 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6441 if (CONST_INT_P (operands[2])
6442 && (INTVAL (operands[2]) == 128
6443 || (INTVAL (operands[2]) < 0
6444 && INTVAL (operands[2]) != -128)))
6446 operands[2] = GEN_INT (-INTVAL (operands[2]));
6447 return "sub{l}\t{%2, %k0|%k0, %2}";
6449 return "add{l}\t{%2, %k0|%k0, %2}";
6453 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6454 (const_string "incdec")
6455 (const_string "alu")))
6456 (set (attr "length_immediate")
6458 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6460 (const_string "*")))
6461 (set_attr "mode" "SI")])
6463 (define_insn "*addhi_2"
6464 [(set (reg FLAGS_REG)
6466 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6467 (match_operand:HI 2 "general_operand" "rmn,rn"))
6469 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6470 (plus:HI (match_dup 1) (match_dup 2)))]
6471 "ix86_match_ccmode (insn, CCGOCmode)
6472 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6474 switch (get_attr_type (insn))
6477 if (operands[2] == const1_rtx)
6478 return "inc{w}\t%0";
6481 gcc_assert (operands[2] == constm1_rtx);
6482 return "dec{w}\t%0";
6486 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6487 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6488 if (CONST_INT_P (operands[2])
6489 && (INTVAL (operands[2]) == 128
6490 || (INTVAL (operands[2]) < 0
6491 && INTVAL (operands[2]) != -128)))
6493 operands[2] = GEN_INT (-INTVAL (operands[2]));
6494 return "sub{w}\t{%2, %0|%0, %2}";
6496 return "add{w}\t{%2, %0|%0, %2}";
6500 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6501 (const_string "incdec")
6502 (const_string "alu")))
6503 (set (attr "length_immediate")
6505 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6507 (const_string "*")))
6508 (set_attr "mode" "HI")])
6510 (define_insn "*addqi_2"
6511 [(set (reg FLAGS_REG)
6513 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6514 (match_operand:QI 2 "general_operand" "qmn,qn"))
6516 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6517 (plus:QI (match_dup 1) (match_dup 2)))]
6518 "ix86_match_ccmode (insn, CCGOCmode)
6519 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6521 switch (get_attr_type (insn))
6524 if (operands[2] == const1_rtx)
6525 return "inc{b}\t%0";
6528 gcc_assert (operands[2] == constm1_rtx
6529 || (CONST_INT_P (operands[2])
6530 && INTVAL (operands[2]) == 255));
6531 return "dec{b}\t%0";
6535 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6536 if (CONST_INT_P (operands[2])
6537 && INTVAL (operands[2]) < 0)
6539 operands[2] = GEN_INT (-INTVAL (operands[2]));
6540 return "sub{b}\t{%2, %0|%0, %2}";
6542 return "add{b}\t{%2, %0|%0, %2}";
6546 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6547 (const_string "incdec")
6548 (const_string "alu")))
6549 (set_attr "mode" "QI")])
6551 (define_insn "*add<mode>_3"
6552 [(set (reg FLAGS_REG)
6554 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6555 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6556 (clobber (match_scratch:SWI48 0 "=r"))]
6557 "ix86_match_ccmode (insn, CCZmode)
6558 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6559 /* Current assemblers are broken and do not allow @GOTOFF in
6560 ought but a memory context. */
6561 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6563 switch (get_attr_type (insn))
6566 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6567 if (operands[2] == const1_rtx)
6568 return "inc{<imodesuffix>}\t%0";
6571 gcc_assert (operands[2] == constm1_rtx);
6572 return "dec{<imodesuffix>}\t%0";
6576 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6577 /* ???? In DImode, we ought to handle there the 32bit case too
6578 - do we need new constraint? */
6579 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6580 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6581 if (CONST_INT_P (operands[2])
6582 /* Avoid overflows. */
6583 && (<MODE>mode != DImode
6584 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6585 && (INTVAL (operands[2]) == 128
6586 || (INTVAL (operands[2]) < 0
6587 && INTVAL (operands[2]) != -128)))
6589 operands[2] = GEN_INT (-INTVAL (operands[2]));
6590 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6592 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6596 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6597 (const_string "incdec")
6598 (const_string "alu")))
6599 (set (attr "length_immediate")
6601 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6603 (const_string "*")))
6604 (set_attr "mode" "<MODE>")])
6606 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6607 (define_insn "*addsi_3_zext"
6608 [(set (reg FLAGS_REG)
6610 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6611 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6612 (set (match_operand:DI 0 "register_operand" "=r")
6613 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6614 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6615 && ix86_binary_operator_ok (PLUS, SImode, operands)
6616 /* Current assemblers are broken and do not allow @GOTOFF in
6617 ought but a memory context. */
6618 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6620 switch (get_attr_type (insn))
6623 if (operands[2] == const1_rtx)
6624 return "inc{l}\t%k0";
6627 gcc_assert (operands[2] == constm1_rtx);
6628 return "dec{l}\t%k0";
6632 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6633 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6634 if (CONST_INT_P (operands[2])
6635 && (INTVAL (operands[2]) == 128
6636 || (INTVAL (operands[2]) < 0
6637 && INTVAL (operands[2]) != -128)))
6639 operands[2] = GEN_INT (-INTVAL (operands[2]));
6640 return "sub{l}\t{%2, %k0|%k0, %2}";
6642 return "add{l}\t{%2, %k0|%k0, %2}";
6646 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6647 (const_string "incdec")
6648 (const_string "alu")))
6649 (set (attr "length_immediate")
6651 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6653 (const_string "*")))
6654 (set_attr "mode" "SI")])
6656 (define_insn "*addhi_3"
6657 [(set (reg FLAGS_REG)
6659 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6660 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6661 (clobber (match_scratch:HI 0 "=r"))]
6662 "ix86_match_ccmode (insn, CCZmode)
6663 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6665 switch (get_attr_type (insn))
6668 if (operands[2] == const1_rtx)
6669 return "inc{w}\t%0";
6672 gcc_assert (operands[2] == constm1_rtx);
6673 return "dec{w}\t%0";
6677 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6678 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6679 if (CONST_INT_P (operands[2])
6680 && (INTVAL (operands[2]) == 128
6681 || (INTVAL (operands[2]) < 0
6682 && INTVAL (operands[2]) != -128)))
6684 operands[2] = GEN_INT (-INTVAL (operands[2]));
6685 return "sub{w}\t{%2, %0|%0, %2}";
6687 return "add{w}\t{%2, %0|%0, %2}";
6691 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6692 (const_string "incdec")
6693 (const_string "alu")))
6694 (set (attr "length_immediate")
6696 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6698 (const_string "*")))
6699 (set_attr "mode" "HI")])
6701 (define_insn "*addqi_3"
6702 [(set (reg FLAGS_REG)
6704 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6705 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6706 (clobber (match_scratch:QI 0 "=q"))]
6707 "ix86_match_ccmode (insn, CCZmode)
6708 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6710 switch (get_attr_type (insn))
6713 if (operands[2] == const1_rtx)
6714 return "inc{b}\t%0";
6717 gcc_assert (operands[2] == constm1_rtx
6718 || (CONST_INT_P (operands[2])
6719 && INTVAL (operands[2]) == 255));
6720 return "dec{b}\t%0";
6724 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6725 if (CONST_INT_P (operands[2])
6726 && INTVAL (operands[2]) < 0)
6728 operands[2] = GEN_INT (-INTVAL (operands[2]));
6729 return "sub{b}\t{%2, %0|%0, %2}";
6731 return "add{b}\t{%2, %0|%0, %2}";
6735 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6736 (const_string "incdec")
6737 (const_string "alu")))
6738 (set_attr "mode" "QI")])
6740 ; For comparisons against 1, -1 and 128, we may generate better code
6741 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6742 ; is matched then. We can't accept general immediate, because for
6743 ; case of overflows, the result is messed up.
6744 ; This pattern also don't hold of 0x8000000000000000, since the value
6745 ; overflows when negated.
6746 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6747 ; only for comparisons not depending on it.
6749 (define_insn "*adddi_4"
6750 [(set (reg FLAGS_REG)
6752 (match_operand:DI 1 "nonimmediate_operand" "0")
6753 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6754 (clobber (match_scratch:DI 0 "=rm"))]
6756 && ix86_match_ccmode (insn, CCGCmode)"
6758 switch (get_attr_type (insn))
6761 if (operands[2] == constm1_rtx)
6762 return "inc{q}\t%0";
6765 gcc_assert (operands[2] == const1_rtx);
6766 return "dec{q}\t%0";
6770 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6771 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6772 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6773 if ((INTVAL (operands[2]) == -128
6774 || (INTVAL (operands[2]) > 0
6775 && INTVAL (operands[2]) != 128))
6776 /* Avoid overflows. */
6777 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6778 return "sub{q}\t{%2, %0|%0, %2}";
6779 operands[2] = GEN_INT (-INTVAL (operands[2]));
6780 return "add{q}\t{%2, %0|%0, %2}";
6784 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6785 (const_string "incdec")
6786 (const_string "alu")))
6787 (set (attr "length_immediate")
6789 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6791 (const_string "*")))
6792 (set_attr "mode" "DI")])
6794 ; For comparisons against 1, -1 and 128, we may generate better code
6795 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6796 ; is matched then. We can't accept general immediate, because for
6797 ; case of overflows, the result is messed up.
6798 ; This pattern also don't hold of 0x80000000, since the value overflows
6800 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6801 ; only for comparisons not depending on it.
6803 (define_insn "*addsi_4"
6804 [(set (reg FLAGS_REG)
6806 (match_operand:SI 1 "nonimmediate_operand" "0")
6807 (match_operand:SI 2 "const_int_operand" "n")))
6808 (clobber (match_scratch:SI 0 "=rm"))]
6809 "ix86_match_ccmode (insn, CCGCmode)
6810 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6812 switch (get_attr_type (insn))
6815 if (operands[2] == constm1_rtx)
6816 return "inc{l}\t%0";
6819 gcc_assert (operands[2] == const1_rtx);
6820 return "dec{l}\t%0";
6824 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6825 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6826 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6827 if ((INTVAL (operands[2]) == -128
6828 || (INTVAL (operands[2]) > 0
6829 && INTVAL (operands[2]) != 128)))
6830 return "sub{l}\t{%2, %0|%0, %2}";
6831 operands[2] = GEN_INT (-INTVAL (operands[2]));
6832 return "add{l}\t{%2, %0|%0, %2}";
6836 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6837 (const_string "incdec")
6838 (const_string "alu")))
6839 (set (attr "length_immediate")
6841 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6843 (const_string "*")))
6844 (set_attr "mode" "SI")])
6846 ; See comments above addsi_4 for details.
6848 (define_insn "*addhi_4"
6849 [(set (reg FLAGS_REG)
6851 (match_operand:HI 1 "nonimmediate_operand" "0")
6852 (match_operand:HI 2 "const_int_operand" "n")))
6853 (clobber (match_scratch:HI 0 "=rm"))]
6854 "ix86_match_ccmode (insn, CCGCmode)
6855 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6857 switch (get_attr_type (insn))
6860 if (operands[2] == constm1_rtx)
6861 return "inc{w}\t%0";
6864 gcc_assert (operands[2] == const1_rtx);
6865 return "dec{w}\t%0";
6869 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6870 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6871 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6872 if ((INTVAL (operands[2]) == -128
6873 || (INTVAL (operands[2]) > 0
6874 && INTVAL (operands[2]) != 128)))
6875 return "sub{w}\t{%2, %0|%0, %2}";
6876 operands[2] = GEN_INT (-INTVAL (operands[2]));
6877 return "add{w}\t{%2, %0|%0, %2}";
6881 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6882 (const_string "incdec")
6883 (const_string "alu")))
6884 (set (attr "length_immediate")
6886 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6888 (const_string "*")))
6889 (set_attr "mode" "HI")])
6891 ; See comments above addsi_4 for details.
6893 (define_insn "*addqi_4"
6894 [(set (reg FLAGS_REG)
6896 (match_operand:QI 1 "nonimmediate_operand" "0")
6897 (match_operand:QI 2 "const_int_operand" "n")))
6898 (clobber (match_scratch:QI 0 "=qm"))]
6899 "ix86_match_ccmode (insn, CCGCmode)
6900 && (INTVAL (operands[2]) & 0xff) != 0x80"
6902 switch (get_attr_type (insn))
6905 if (operands[2] == constm1_rtx
6906 || (CONST_INT_P (operands[2])
6907 && INTVAL (operands[2]) == 255))
6908 return "inc{b}\t%0";
6911 gcc_assert (operands[2] == const1_rtx);
6912 return "dec{b}\t%0";
6916 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6917 if (INTVAL (operands[2]) < 0)
6919 operands[2] = GEN_INT (-INTVAL (operands[2]));
6920 return "add{b}\t{%2, %0|%0, %2}";
6922 return "sub{b}\t{%2, %0|%0, %2}";
6926 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6927 (const_string "incdec")
6928 (const_string "alu")))
6929 (set_attr "mode" "QI")])
6931 (define_insn "*add<mode>_5"
6932 [(set (reg FLAGS_REG)
6935 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6936 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6938 (clobber (match_scratch:SWI48 0 "=r"))]
6939 "ix86_match_ccmode (insn, CCGOCmode)
6940 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6941 /* Current assemblers are broken and do not allow @GOTOFF in
6942 ought but a memory context. */
6943 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6945 switch (get_attr_type (insn))
6948 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6949 if (operands[2] == const1_rtx)
6950 return "inc{<imodesuffix>}\t%0";
6953 gcc_assert (operands[2] == constm1_rtx);
6954 return "dec{<imodesuffix>}\t%0";
6958 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6959 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6960 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6961 if (CONST_INT_P (operands[2])
6962 /* Avoid overflows. */
6963 && (<MODE>mode != DImode
6964 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6965 && (INTVAL (operands[2]) == 128
6966 || (INTVAL (operands[2]) < 0
6967 && INTVAL (operands[2]) != -128)))
6969 operands[2] = GEN_INT (-INTVAL (operands[2]));
6970 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6972 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6976 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6977 (const_string "incdec")
6978 (const_string "alu")))
6979 (set (attr "length_immediate")
6981 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6983 (const_string "*")))
6984 (set_attr "mode" "<MODE>")])
6986 (define_insn "*addhi_5"
6987 [(set (reg FLAGS_REG)
6989 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6990 (match_operand:HI 2 "general_operand" "rmn"))
6992 (clobber (match_scratch:HI 0 "=r"))]
6993 "ix86_match_ccmode (insn, CCGOCmode)
6994 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6996 switch (get_attr_type (insn))
6999 if (operands[2] == const1_rtx)
7000 return "inc{w}\t%0";
7003 gcc_assert (operands[2] == constm1_rtx);
7004 return "dec{w}\t%0";
7008 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
7009 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7010 if (CONST_INT_P (operands[2])
7011 && (INTVAL (operands[2]) == 128
7012 || (INTVAL (operands[2]) < 0
7013 && INTVAL (operands[2]) != -128)))
7015 operands[2] = GEN_INT (-INTVAL (operands[2]));
7016 return "sub{w}\t{%2, %0|%0, %2}";
7018 return "add{w}\t{%2, %0|%0, %2}";
7022 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7023 (const_string "incdec")
7024 (const_string "alu")))
7025 (set (attr "length_immediate")
7027 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7029 (const_string "*")))
7030 (set_attr "mode" "HI")])
7032 (define_insn "*addqi_5"
7033 [(set (reg FLAGS_REG)
7035 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7036 (match_operand:QI 2 "general_operand" "qmn"))
7038 (clobber (match_scratch:QI 0 "=q"))]
7039 "ix86_match_ccmode (insn, CCGOCmode)
7040 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7042 switch (get_attr_type (insn))
7045 if (operands[2] == const1_rtx)
7046 return "inc{b}\t%0";
7049 gcc_assert (operands[2] == constm1_rtx
7050 || (CONST_INT_P (operands[2])
7051 && INTVAL (operands[2]) == 255));
7052 return "dec{b}\t%0";
7056 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
7057 if (CONST_INT_P (operands[2])
7058 && INTVAL (operands[2]) < 0)
7060 operands[2] = GEN_INT (-INTVAL (operands[2]));
7061 return "sub{b}\t{%2, %0|%0, %2}";
7063 return "add{b}\t{%2, %0|%0, %2}";
7067 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7068 (const_string "incdec")
7069 (const_string "alu")))
7070 (set_attr "mode" "QI")])
7072 (define_insn "*addqi_ext_1_rex64"
7073 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7078 (match_operand 1 "ext_register_operand" "0")
7081 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7082 (clobber (reg:CC FLAGS_REG))]
7085 switch (get_attr_type (insn))
7088 if (operands[2] == const1_rtx)
7089 return "inc{b}\t%h0";
7092 gcc_assert (operands[2] == constm1_rtx
7093 || (CONST_INT_P (operands[2])
7094 && INTVAL (operands[2]) == 255));
7095 return "dec{b}\t%h0";
7099 return "add{b}\t{%2, %h0|%h0, %2}";
7103 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7104 (const_string "incdec")
7105 (const_string "alu")))
7106 (set_attr "modrm" "1")
7107 (set_attr "mode" "QI")])
7109 (define_insn "addqi_ext_1"
7110 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7115 (match_operand 1 "ext_register_operand" "0")
7118 (match_operand:QI 2 "general_operand" "Qmn")))
7119 (clobber (reg:CC FLAGS_REG))]
7122 switch (get_attr_type (insn))
7125 if (operands[2] == const1_rtx)
7126 return "inc{b}\t%h0";
7129 gcc_assert (operands[2] == constm1_rtx
7130 || (CONST_INT_P (operands[2])
7131 && INTVAL (operands[2]) == 255));
7132 return "dec{b}\t%h0";
7136 return "add{b}\t{%2, %h0|%h0, %2}";
7140 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7141 (const_string "incdec")
7142 (const_string "alu")))
7143 (set_attr "modrm" "1")
7144 (set_attr "mode" "QI")])
7146 (define_insn "*addqi_ext_2"
7147 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7152 (match_operand 1 "ext_register_operand" "%0")
7156 (match_operand 2 "ext_register_operand" "Q")
7159 (clobber (reg:CC FLAGS_REG))]
7161 "add{b}\t{%h2, %h0|%h0, %h2}"
7162 [(set_attr "type" "alu")
7163 (set_attr "mode" "QI")])
7165 ;; The lea patterns for non-Pmodes needs to be matched by
7166 ;; several insns converted to real lea by splitters.
7168 (define_insn_and_split "*lea_general_1"
7169 [(set (match_operand 0 "register_operand" "=r")
7170 (plus (plus (match_operand 1 "index_register_operand" "l")
7171 (match_operand 2 "register_operand" "r"))
7172 (match_operand 3 "immediate_operand" "i")))]
7173 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7174 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7175 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7176 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7177 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7178 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7179 || GET_MODE (operands[3]) == VOIDmode)"
7181 "&& reload_completed"
7185 operands[0] = gen_lowpart (SImode, operands[0]);
7186 operands[1] = gen_lowpart (Pmode, operands[1]);
7187 operands[2] = gen_lowpart (Pmode, operands[2]);
7188 operands[3] = gen_lowpart (Pmode, operands[3]);
7189 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7191 if (Pmode != SImode)
7192 pat = gen_rtx_SUBREG (SImode, pat, 0);
7193 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7196 [(set_attr "type" "lea")
7197 (set_attr "mode" "SI")])
7199 (define_insn_and_split "*lea_general_1_zext"
7200 [(set (match_operand:DI 0 "register_operand" "=r")
7203 (match_operand:SI 1 "index_register_operand" "l")
7204 (match_operand:SI 2 "register_operand" "r"))
7205 (match_operand:SI 3 "immediate_operand" "i"))))]
7208 "&& reload_completed"
7210 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7212 (match_dup 3)) 0)))]
7214 operands[1] = gen_lowpart (Pmode, operands[1]);
7215 operands[2] = gen_lowpart (Pmode, operands[2]);
7216 operands[3] = gen_lowpart (Pmode, operands[3]);
7218 [(set_attr "type" "lea")
7219 (set_attr "mode" "SI")])
7221 (define_insn_and_split "*lea_general_2"
7222 [(set (match_operand 0 "register_operand" "=r")
7223 (plus (mult (match_operand 1 "index_register_operand" "l")
7224 (match_operand 2 "const248_operand" "i"))
7225 (match_operand 3 "nonmemory_operand" "ri")))]
7226 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7227 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7228 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7229 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7230 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7231 || GET_MODE (operands[3]) == VOIDmode)"
7233 "&& reload_completed"
7237 operands[0] = gen_lowpart (SImode, operands[0]);
7238 operands[1] = gen_lowpart (Pmode, operands[1]);
7239 operands[3] = gen_lowpart (Pmode, operands[3]);
7240 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7242 if (Pmode != SImode)
7243 pat = gen_rtx_SUBREG (SImode, pat, 0);
7244 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7247 [(set_attr "type" "lea")
7248 (set_attr "mode" "SI")])
7250 (define_insn_and_split "*lea_general_2_zext"
7251 [(set (match_operand:DI 0 "register_operand" "=r")
7254 (match_operand:SI 1 "index_register_operand" "l")
7255 (match_operand:SI 2 "const248_operand" "n"))
7256 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7259 "&& reload_completed"
7261 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7263 (match_dup 3)) 0)))]
7265 operands[1] = gen_lowpart (Pmode, operands[1]);
7266 operands[3] = gen_lowpart (Pmode, operands[3]);
7268 [(set_attr "type" "lea")
7269 (set_attr "mode" "SI")])
7271 (define_insn_and_split "*lea_general_3"
7272 [(set (match_operand 0 "register_operand" "=r")
7273 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7274 (match_operand 2 "const248_operand" "i"))
7275 (match_operand 3 "register_operand" "r"))
7276 (match_operand 4 "immediate_operand" "i")))]
7277 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7278 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7279 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7280 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7281 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7283 "&& reload_completed"
7287 operands[0] = gen_lowpart (SImode, operands[0]);
7288 operands[1] = gen_lowpart (Pmode, operands[1]);
7289 operands[3] = gen_lowpart (Pmode, operands[3]);
7290 operands[4] = gen_lowpart (Pmode, operands[4]);
7291 pat = gen_rtx_PLUS (Pmode,
7292 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7296 if (Pmode != SImode)
7297 pat = gen_rtx_SUBREG (SImode, pat, 0);
7298 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7301 [(set_attr "type" "lea")
7302 (set_attr "mode" "SI")])
7304 (define_insn_and_split "*lea_general_3_zext"
7305 [(set (match_operand:DI 0 "register_operand" "=r")
7309 (match_operand:SI 1 "index_register_operand" "l")
7310 (match_operand:SI 2 "const248_operand" "n"))
7311 (match_operand:SI 3 "register_operand" "r"))
7312 (match_operand:SI 4 "immediate_operand" "i"))))]
7315 "&& reload_completed"
7317 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7320 (match_dup 4)) 0)))]
7322 operands[1] = gen_lowpart (Pmode, operands[1]);
7323 operands[3] = gen_lowpart (Pmode, operands[3]);
7324 operands[4] = gen_lowpart (Pmode, operands[4]);
7326 [(set_attr "type" "lea")
7327 (set_attr "mode" "SI")])
7329 ;; Convert lea to the lea pattern to avoid flags dependency.
7331 [(set (match_operand:DI 0 "register_operand" "")
7332 (plus:DI (match_operand:DI 1 "register_operand" "")
7333 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7334 (clobber (reg:CC FLAGS_REG))]
7335 "TARGET_64BIT && reload_completed
7336 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7338 (plus:DI (match_dup 1)
7342 ;; Convert lea to the lea pattern to avoid flags dependency.
7344 [(set (match_operand 0 "register_operand" "")
7345 (plus (match_operand 1 "register_operand" "")
7346 (match_operand 2 "nonmemory_operand" "")))
7347 (clobber (reg:CC FLAGS_REG))]
7348 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7352 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7353 may confuse gen_lowpart. */
7354 if (GET_MODE (operands[0]) != Pmode)
7356 operands[1] = gen_lowpart (Pmode, operands[1]);
7357 operands[2] = gen_lowpart (Pmode, operands[2]);
7359 operands[0] = gen_lowpart (SImode, operands[0]);
7360 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7361 if (Pmode != SImode)
7362 pat = gen_rtx_SUBREG (SImode, pat, 0);
7363 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7367 ;; Convert lea to the lea pattern to avoid flags dependency.
7369 [(set (match_operand:DI 0 "register_operand" "")
7371 (plus:SI (match_operand:SI 1 "register_operand" "")
7372 (match_operand:SI 2 "nonmemory_operand" ""))))
7373 (clobber (reg:CC FLAGS_REG))]
7374 "TARGET_64BIT && reload_completed
7375 && true_regnum (operands[0]) != true_regnum (operands[1])"
7377 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7379 operands[1] = gen_lowpart (Pmode, operands[1]);
7380 operands[2] = gen_lowpart (Pmode, operands[2]);
7383 ;; Subtract instructions
7385 (define_expand "sub<mode>3"
7386 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7387 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7388 (match_operand:SDWIM 2 "<general_operand>" "")))]
7390 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7392 (define_insn_and_split "*sub<dwi>3_doubleword"
7393 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7395 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7396 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7397 (clobber (reg:CC FLAGS_REG))]
7398 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7401 [(parallel [(set (reg:CC FLAGS_REG)
7402 (compare:CC (match_dup 1) (match_dup 2)))
7404 (minus:DWIH (match_dup 1) (match_dup 2)))])
7405 (parallel [(set (match_dup 3)
7409 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7411 (clobber (reg:CC FLAGS_REG))])]
7412 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7414 (define_insn "*sub<mode>_1"
7415 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7417 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7418 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7419 (clobber (reg:CC FLAGS_REG))]
7420 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7421 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7422 [(set_attr "type" "alu")
7423 (set_attr "mode" "<MODE>")])
7425 (define_insn "*subsi_1_zext"
7426 [(set (match_operand:DI 0 "register_operand" "=r")
7428 (minus:SI (match_operand:SI 1 "register_operand" "0")
7429 (match_operand:SI 2 "general_operand" "g"))))
7430 (clobber (reg:CC FLAGS_REG))]
7431 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7432 "sub{l}\t{%2, %k0|%k0, %2}"
7433 [(set_attr "type" "alu")
7434 (set_attr "mode" "SI")])
7436 (define_insn "*subqi_1_slp"
7437 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7438 (minus:QI (match_dup 0)
7439 (match_operand:QI 1 "general_operand" "qn,qm")))
7440 (clobber (reg:CC FLAGS_REG))]
7441 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7442 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7443 "sub{b}\t{%1, %0|%0, %1}"
7444 [(set_attr "type" "alu1")
7445 (set_attr "mode" "QI")])
7447 (define_insn "*sub<mode>_2"
7448 [(set (reg FLAGS_REG)
7451 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7452 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7454 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7455 (minus:SWI (match_dup 1) (match_dup 2)))]
7456 "ix86_match_ccmode (insn, CCGOCmode)
7457 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7458 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7459 [(set_attr "type" "alu")
7460 (set_attr "mode" "<MODE>")])
7462 (define_insn "*subsi_2_zext"
7463 [(set (reg FLAGS_REG)
7465 (minus:SI (match_operand:SI 1 "register_operand" "0")
7466 (match_operand:SI 2 "general_operand" "g"))
7468 (set (match_operand:DI 0 "register_operand" "=r")
7470 (minus:SI (match_dup 1)
7472 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7473 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7474 "sub{l}\t{%2, %k0|%k0, %2}"
7475 [(set_attr "type" "alu")
7476 (set_attr "mode" "SI")])
7478 (define_insn "*sub<mode>_3"
7479 [(set (reg FLAGS_REG)
7480 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7481 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7482 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7483 (minus:SWI (match_dup 1) (match_dup 2)))]
7484 "ix86_match_ccmode (insn, CCmode)
7485 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7486 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7487 [(set_attr "type" "alu")
7488 (set_attr "mode" "<MODE>")])
7490 (define_insn "*subsi_3_zext"
7491 [(set (reg FLAGS_REG)
7492 (compare (match_operand:SI 1 "register_operand" "0")
7493 (match_operand:SI 2 "general_operand" "g")))
7494 (set (match_operand:DI 0 "register_operand" "=r")
7496 (minus:SI (match_dup 1)
7498 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7499 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7500 "sub{l}\t{%2, %1|%1, %2}"
7501 [(set_attr "type" "alu")
7502 (set_attr "mode" "SI")])
7504 ;; Add with carry and subtract with borrow
7506 (define_expand "<plusminus_insn><mode>3_carry"
7508 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7510 (match_operand:SWI 1 "nonimmediate_operand" "")
7511 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7512 [(match_operand 3 "flags_reg_operand" "")
7514 (match_operand:SWI 2 "<general_operand>" ""))))
7515 (clobber (reg:CC FLAGS_REG))])]
7516 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7519 (define_insn "*<plusminus_insn><mode>3_carry"
7520 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7522 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7524 (match_operator 3 "ix86_carry_flag_operator"
7525 [(reg FLAGS_REG) (const_int 0)])
7526 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7527 (clobber (reg:CC FLAGS_REG))]
7528 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7529 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7530 [(set_attr "type" "alu")
7531 (set_attr "use_carry" "1")
7532 (set_attr "pent_pair" "pu")
7533 (set_attr "mode" "<MODE>")])
7535 (define_insn "*addsi3_carry_zext"
7536 [(set (match_operand:DI 0 "register_operand" "=r")
7538 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7539 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7540 [(reg FLAGS_REG) (const_int 0)])
7541 (match_operand:SI 2 "general_operand" "g")))))
7542 (clobber (reg:CC FLAGS_REG))]
7543 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7544 "adc{l}\t{%2, %k0|%k0, %2}"
7545 [(set_attr "type" "alu")
7546 (set_attr "use_carry" "1")
7547 (set_attr "pent_pair" "pu")
7548 (set_attr "mode" "SI")])
7550 (define_insn "*subsi3_carry_zext"
7551 [(set (match_operand:DI 0 "register_operand" "=r")
7553 (minus:SI (match_operand:SI 1 "register_operand" "0")
7554 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7555 [(reg FLAGS_REG) (const_int 0)])
7556 (match_operand:SI 2 "general_operand" "g")))))
7557 (clobber (reg:CC FLAGS_REG))]
7558 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7559 "sbb{l}\t{%2, %k0|%k0, %2}"
7560 [(set_attr "type" "alu")
7561 (set_attr "pent_pair" "pu")
7562 (set_attr "mode" "SI")])
7564 ;; Overflow setting add and subtract instructions
7566 (define_insn "*add<mode>3_cconly_overflow"
7567 [(set (reg:CCC FLAGS_REG)
7570 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7571 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7573 (clobber (match_scratch:SWI 0 "=<r>"))]
7574 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7575 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7576 [(set_attr "type" "alu")
7577 (set_attr "mode" "<MODE>")])
7579 (define_insn "*sub<mode>3_cconly_overflow"
7580 [(set (reg:CCC FLAGS_REG)
7583 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7584 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7587 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7588 [(set_attr "type" "icmp")
7589 (set_attr "mode" "<MODE>")])
7591 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7592 [(set (reg:CCC FLAGS_REG)
7595 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7596 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7598 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7599 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7600 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7601 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7602 [(set_attr "type" "alu")
7603 (set_attr "mode" "<MODE>")])
7605 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7606 [(set (reg:CCC FLAGS_REG)
7609 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7610 (match_operand:SI 2 "general_operand" "g"))
7612 (set (match_operand:DI 0 "register_operand" "=r")
7613 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7614 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7615 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7616 [(set_attr "type" "alu")
7617 (set_attr "mode" "SI")])
7619 ;; The patterns that match these are at the end of this file.
7621 (define_expand "<plusminus_insn>xf3"
7622 [(set (match_operand:XF 0 "register_operand" "")
7624 (match_operand:XF 1 "register_operand" "")
7625 (match_operand:XF 2 "register_operand" "")))]
7629 (define_expand "<plusminus_insn><mode>3"
7630 [(set (match_operand:MODEF 0 "register_operand" "")
7632 (match_operand:MODEF 1 "register_operand" "")
7633 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7634 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7635 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7638 ;; Multiply instructions
7640 (define_expand "mul<mode>3"
7641 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7643 (match_operand:SWIM248 1 "register_operand" "")
7644 (match_operand:SWIM248 2 "<general_operand>" "")))
7645 (clobber (reg:CC FLAGS_REG))])]
7649 (define_expand "mulqi3"
7650 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7652 (match_operand:QI 1 "register_operand" "")
7653 (match_operand:QI 2 "nonimmediate_operand" "")))
7654 (clobber (reg:CC FLAGS_REG))])]
7655 "TARGET_QIMODE_MATH"
7659 ;; IMUL reg32/64, reg32/64, imm8 Direct
7660 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7661 ;; IMUL reg32/64, reg32/64, imm32 Direct
7662 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7663 ;; IMUL reg32/64, reg32/64 Direct
7664 ;; IMUL reg32/64, mem32/64 Direct
7666 (define_insn "*mul<mode>3_1"
7667 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7669 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7670 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7671 (clobber (reg:CC FLAGS_REG))]
7672 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7674 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7675 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7676 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7677 [(set_attr "type" "imul")
7678 (set_attr "prefix_0f" "0,0,1")
7679 (set (attr "athlon_decode")
7680 (cond [(eq_attr "cpu" "athlon")
7681 (const_string "vector")
7682 (eq_attr "alternative" "1")
7683 (const_string "vector")
7684 (and (eq_attr "alternative" "2")
7685 (match_operand 1 "memory_operand" ""))
7686 (const_string "vector")]
7687 (const_string "direct")))
7688 (set (attr "amdfam10_decode")
7689 (cond [(and (eq_attr "alternative" "0,1")
7690 (match_operand 1 "memory_operand" ""))
7691 (const_string "vector")]
7692 (const_string "direct")))
7693 (set_attr "mode" "<MODE>")])
7695 (define_insn "*mulsi3_1_zext"
7696 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7698 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7699 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7700 (clobber (reg:CC FLAGS_REG))]
7702 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7704 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7705 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7706 imul{l}\t{%2, %k0|%k0, %2}"
7707 [(set_attr "type" "imul")
7708 (set_attr "prefix_0f" "0,0,1")
7709 (set (attr "athlon_decode")
7710 (cond [(eq_attr "cpu" "athlon")
7711 (const_string "vector")
7712 (eq_attr "alternative" "1")
7713 (const_string "vector")
7714 (and (eq_attr "alternative" "2")
7715 (match_operand 1 "memory_operand" ""))
7716 (const_string "vector")]
7717 (const_string "direct")))
7718 (set (attr "amdfam10_decode")
7719 (cond [(and (eq_attr "alternative" "0,1")
7720 (match_operand 1 "memory_operand" ""))
7721 (const_string "vector")]
7722 (const_string "direct")))
7723 (set_attr "mode" "SI")])
7726 ;; IMUL reg16, reg16, imm8 VectorPath
7727 ;; IMUL reg16, mem16, imm8 VectorPath
7728 ;; IMUL reg16, reg16, imm16 VectorPath
7729 ;; IMUL reg16, mem16, imm16 VectorPath
7730 ;; IMUL reg16, reg16 Direct
7731 ;; IMUL reg16, mem16 Direct
7733 (define_insn "*mulhi3_1"
7734 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7735 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7736 (match_operand:HI 2 "general_operand" "K,n,mr")))
7737 (clobber (reg:CC FLAGS_REG))]
7739 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7741 imul{w}\t{%2, %1, %0|%0, %1, %2}
7742 imul{w}\t{%2, %1, %0|%0, %1, %2}
7743 imul{w}\t{%2, %0|%0, %2}"
7744 [(set_attr "type" "imul")
7745 (set_attr "prefix_0f" "0,0,1")
7746 (set (attr "athlon_decode")
7747 (cond [(eq_attr "cpu" "athlon")
7748 (const_string "vector")
7749 (eq_attr "alternative" "1,2")
7750 (const_string "vector")]
7751 (const_string "direct")))
7752 (set (attr "amdfam10_decode")
7753 (cond [(eq_attr "alternative" "0,1")
7754 (const_string "vector")]
7755 (const_string "direct")))
7756 (set_attr "mode" "HI")])
7762 (define_insn "*mulqi3_1"
7763 [(set (match_operand:QI 0 "register_operand" "=a")
7764 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7765 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7766 (clobber (reg:CC FLAGS_REG))]
7768 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7770 [(set_attr "type" "imul")
7771 (set_attr "length_immediate" "0")
7772 (set (attr "athlon_decode")
7773 (if_then_else (eq_attr "cpu" "athlon")
7774 (const_string "vector")
7775 (const_string "direct")))
7776 (set_attr "amdfam10_decode" "direct")
7777 (set_attr "mode" "QI")])
7779 (define_expand "<u>mul<mode><dwi>3"
7780 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7783 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7785 (match_operand:DWIH 2 "register_operand" ""))))
7786 (clobber (reg:CC FLAGS_REG))])]
7790 (define_expand "<u>mulqihi3"
7791 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7794 (match_operand:QI 1 "nonimmediate_operand" ""))
7796 (match_operand:QI 2 "register_operand" ""))))
7797 (clobber (reg:CC FLAGS_REG))])]
7798 "TARGET_QIMODE_MATH"
7801 (define_insn "*<u>mul<mode><dwi>3_1"
7802 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7805 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7807 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7808 (clobber (reg:CC FLAGS_REG))]
7809 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7810 "<sgnprefix>mul{<imodesuffix>}\t%2"
7811 [(set_attr "type" "imul")
7812 (set_attr "length_immediate" "0")
7813 (set (attr "athlon_decode")
7814 (if_then_else (eq_attr "cpu" "athlon")
7815 (const_string "vector")
7816 (const_string "double")))
7817 (set_attr "amdfam10_decode" "double")
7818 (set_attr "mode" "<MODE>")])
7820 (define_insn "*<u>mulqihi3_1"
7821 [(set (match_operand:HI 0 "register_operand" "=a")
7824 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7826 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7827 (clobber (reg:CC FLAGS_REG))]
7829 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7830 "<sgnprefix>mul{b}\t%2"
7831 [(set_attr "type" "imul")
7832 (set_attr "length_immediate" "0")
7833 (set (attr "athlon_decode")
7834 (if_then_else (eq_attr "cpu" "athlon")
7835 (const_string "vector")
7836 (const_string "direct")))
7837 (set_attr "amdfam10_decode" "direct")
7838 (set_attr "mode" "QI")])
7840 (define_expand "<s>mul<mode>3_highpart"
7841 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7846 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7848 (match_operand:SWI48 2 "register_operand" "")))
7850 (clobber (match_scratch:SWI48 3 ""))
7851 (clobber (reg:CC FLAGS_REG))])]
7853 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7855 (define_insn "*<s>muldi3_highpart_1"
7856 [(set (match_operand:DI 0 "register_operand" "=d")
7861 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7863 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7865 (clobber (match_scratch:DI 3 "=1"))
7866 (clobber (reg:CC FLAGS_REG))]
7868 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7869 "<sgnprefix>mul{q}\t%2"
7870 [(set_attr "type" "imul")
7871 (set_attr "length_immediate" "0")
7872 (set (attr "athlon_decode")
7873 (if_then_else (eq_attr "cpu" "athlon")
7874 (const_string "vector")
7875 (const_string "double")))
7876 (set_attr "amdfam10_decode" "double")
7877 (set_attr "mode" "DI")])
7879 (define_insn "*<s>mulsi3_highpart_1"
7880 [(set (match_operand:SI 0 "register_operand" "=d")
7885 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7887 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7889 (clobber (match_scratch:SI 3 "=1"))
7890 (clobber (reg:CC FLAGS_REG))]
7891 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7892 "<sgnprefix>mul{l}\t%2"
7893 [(set_attr "type" "imul")
7894 (set_attr "length_immediate" "0")
7895 (set (attr "athlon_decode")
7896 (if_then_else (eq_attr "cpu" "athlon")
7897 (const_string "vector")
7898 (const_string "double")))
7899 (set_attr "amdfam10_decode" "double")
7900 (set_attr "mode" "SI")])
7902 (define_insn "*<s>mulsi3_highpart_zext"
7903 [(set (match_operand:DI 0 "register_operand" "=d")
7904 (zero_extend:DI (truncate:SI
7906 (mult:DI (any_extend:DI
7907 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7909 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7911 (clobber (match_scratch:SI 3 "=1"))
7912 (clobber (reg:CC FLAGS_REG))]
7914 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7915 "<sgnprefix>mul{l}\t%2"
7916 [(set_attr "type" "imul")
7917 (set_attr "length_immediate" "0")
7918 (set (attr "athlon_decode")
7919 (if_then_else (eq_attr "cpu" "athlon")
7920 (const_string "vector")
7921 (const_string "double")))
7922 (set_attr "amdfam10_decode" "double")
7923 (set_attr "mode" "SI")])
7925 ;; The patterns that match these are at the end of this file.
7927 (define_expand "mulxf3"
7928 [(set (match_operand:XF 0 "register_operand" "")
7929 (mult:XF (match_operand:XF 1 "register_operand" "")
7930 (match_operand:XF 2 "register_operand" "")))]
7934 (define_expand "mul<mode>3"
7935 [(set (match_operand:MODEF 0 "register_operand" "")
7936 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7937 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7938 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7939 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7942 ;; Divide instructions
7944 (define_insn "<u>divqi3"
7945 [(set (match_operand:QI 0 "register_operand" "=a")
7947 (match_operand:HI 1 "register_operand" "0")
7948 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7949 (clobber (reg:CC FLAGS_REG))]
7950 "TARGET_QIMODE_MATH"
7951 "<sgnprefix>div{b}\t%2"
7952 [(set_attr "type" "idiv")
7953 (set_attr "mode" "QI")])
7955 ;; The patterns that match these are at the end of this file.
7957 (define_expand "divxf3"
7958 [(set (match_operand:XF 0 "register_operand" "")
7959 (div:XF (match_operand:XF 1 "register_operand" "")
7960 (match_operand:XF 2 "register_operand" "")))]
7964 (define_expand "divdf3"
7965 [(set (match_operand:DF 0 "register_operand" "")
7966 (div:DF (match_operand:DF 1 "register_operand" "")
7967 (match_operand:DF 2 "nonimmediate_operand" "")))]
7968 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7969 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7972 (define_expand "divsf3"
7973 [(set (match_operand:SF 0 "register_operand" "")
7974 (div:SF (match_operand:SF 1 "register_operand" "")
7975 (match_operand:SF 2 "nonimmediate_operand" "")))]
7976 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7979 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7980 && flag_finite_math_only && !flag_trapping_math
7981 && flag_unsafe_math_optimizations)
7983 ix86_emit_swdivsf (operands[0], operands[1],
7984 operands[2], SFmode);
7989 ;; Divmod instructions.
7991 (define_expand "divmod<mode>4"
7992 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7994 (match_operand:SWIM248 1 "register_operand" "")
7995 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7996 (set (match_operand:SWIM248 3 "register_operand" "")
7997 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7998 (clobber (reg:CC FLAGS_REG))])]
8002 (define_insn_and_split "*divmod<mode>4"
8003 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8004 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8005 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8006 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8007 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8008 (clobber (reg:CC FLAGS_REG))]
8011 "&& reload_completed"
8012 [(parallel [(set (match_dup 1)
8013 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8014 (clobber (reg:CC FLAGS_REG))])
8015 (parallel [(set (match_dup 0)
8016 (div:SWIM248 (match_dup 2) (match_dup 3)))
8018 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8020 (clobber (reg:CC FLAGS_REG))])]
8022 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8024 if (<MODE>mode != HImode
8025 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8026 operands[4] = operands[2];
8029 /* Avoid use of cltd in favor of a mov+shift. */
8030 emit_move_insn (operands[1], operands[2]);
8031 operands[4] = operands[1];
8034 [(set_attr "type" "multi")
8035 (set_attr "mode" "<MODE>")])
8037 (define_insn "*divmod<mode>4_noext"
8038 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8039 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8040 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8041 (set (match_operand:SWIM248 1 "register_operand" "=d")
8042 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8043 (use (match_operand:SWIM248 4 "register_operand" "1"))
8044 (clobber (reg:CC FLAGS_REG))]
8046 "idiv{<imodesuffix>}\t%3"
8047 [(set_attr "type" "idiv")
8048 (set_attr "mode" "<MODE>")])
8050 (define_expand "udivmod<mode>4"
8051 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8053 (match_operand:SWIM248 1 "register_operand" "")
8054 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8055 (set (match_operand:SWIM248 3 "register_operand" "")
8056 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8057 (clobber (reg:CC FLAGS_REG))])]
8061 (define_insn_and_split "*udivmod<mode>4"
8062 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8063 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8064 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8065 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8066 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8067 (clobber (reg:CC FLAGS_REG))]
8070 "&& reload_completed"
8071 [(set (match_dup 1) (const_int 0))
8072 (parallel [(set (match_dup 0)
8073 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8075 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8077 (clobber (reg:CC FLAGS_REG))])]
8079 [(set_attr "type" "multi")
8080 (set_attr "mode" "<MODE>")])
8082 (define_insn "*udivmod<mode>4_noext"
8083 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8084 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8085 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8086 (set (match_operand:SWIM248 1 "register_operand" "=d")
8087 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8088 (use (match_operand:SWIM248 4 "register_operand" "1"))
8089 (clobber (reg:CC FLAGS_REG))]
8091 "div{<imodesuffix>}\t%3"
8092 [(set_attr "type" "idiv")
8093 (set_attr "mode" "<MODE>")])
8095 ;; We cannot use div/idiv for double division, because it causes
8096 ;; "division by zero" on the overflow and that's not what we expect
8097 ;; from truncate. Because true (non truncating) double division is
8098 ;; never generated, we can't create this insn anyway.
8101 ; [(set (match_operand:SI 0 "register_operand" "=a")
8103 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8105 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8106 ; (set (match_operand:SI 3 "register_operand" "=d")
8108 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8109 ; (clobber (reg:CC FLAGS_REG))]
8111 ; "div{l}\t{%2, %0|%0, %2}"
8112 ; [(set_attr "type" "idiv")])
8114 ;;- Logical AND instructions
8116 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8117 ;; Note that this excludes ah.
8119 (define_expand "testsi_ccno_1"
8120 [(set (reg:CCNO FLAGS_REG)
8122 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8123 (match_operand:SI 1 "nonmemory_operand" ""))
8128 (define_expand "testqi_ccz_1"
8129 [(set (reg:CCZ FLAGS_REG)
8130 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8131 (match_operand:QI 1 "nonmemory_operand" ""))
8136 (define_insn "*testdi_1"
8137 [(set (reg FLAGS_REG)
8140 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8141 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8143 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8144 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8146 test{l}\t{%k1, %k0|%k0, %k1}
8147 test{l}\t{%k1, %k0|%k0, %k1}
8148 test{q}\t{%1, %0|%0, %1}
8149 test{q}\t{%1, %0|%0, %1}
8150 test{q}\t{%1, %0|%0, %1}"
8151 [(set_attr "type" "test")
8152 (set_attr "modrm" "0,1,0,1,1")
8153 (set_attr "mode" "SI,SI,DI,DI,DI")])
8155 (define_insn "*testqi_1_maybe_si"
8156 [(set (reg FLAGS_REG)
8159 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8160 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8162 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8163 && ix86_match_ccmode (insn,
8164 CONST_INT_P (operands[1])
8165 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8167 if (which_alternative == 3)
8169 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8170 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8171 return "test{l}\t{%1, %k0|%k0, %1}";
8173 return "test{b}\t{%1, %0|%0, %1}";
8175 [(set_attr "type" "test")
8176 (set_attr "modrm" "0,1,1,1")
8177 (set_attr "mode" "QI,QI,QI,SI")
8178 (set_attr "pent_pair" "uv,np,uv,np")])
8180 (define_insn "*test<mode>_1"
8181 [(set (reg FLAGS_REG)
8184 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8185 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8187 "ix86_match_ccmode (insn, CCNOmode)
8188 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8189 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8190 [(set_attr "type" "test")
8191 (set_attr "modrm" "0,1,1")
8192 (set_attr "mode" "<MODE>")
8193 (set_attr "pent_pair" "uv,np,uv")])
8195 (define_expand "testqi_ext_ccno_0"
8196 [(set (reg:CCNO FLAGS_REG)
8200 (match_operand 0 "ext_register_operand" "")
8203 (match_operand 1 "const_int_operand" ""))
8208 (define_insn "*testqi_ext_0"
8209 [(set (reg FLAGS_REG)
8213 (match_operand 0 "ext_register_operand" "Q")
8216 (match_operand 1 "const_int_operand" "n"))
8218 "ix86_match_ccmode (insn, CCNOmode)"
8219 "test{b}\t{%1, %h0|%h0, %1}"
8220 [(set_attr "type" "test")
8221 (set_attr "mode" "QI")
8222 (set_attr "length_immediate" "1")
8223 (set_attr "modrm" "1")
8224 (set_attr "pent_pair" "np")])
8226 (define_insn "*testqi_ext_1_rex64"
8227 [(set (reg FLAGS_REG)
8231 (match_operand 0 "ext_register_operand" "Q")
8235 (match_operand:QI 1 "register_operand" "Q")))
8237 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8238 "test{b}\t{%1, %h0|%h0, %1}"
8239 [(set_attr "type" "test")
8240 (set_attr "mode" "QI")])
8242 (define_insn "*testqi_ext_1"
8243 [(set (reg FLAGS_REG)
8247 (match_operand 0 "ext_register_operand" "Q")
8251 (match_operand:QI 1 "general_operand" "Qm")))
8253 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8254 "test{b}\t{%1, %h0|%h0, %1}"
8255 [(set_attr "type" "test")
8256 (set_attr "mode" "QI")])
8258 (define_insn "*testqi_ext_2"
8259 [(set (reg FLAGS_REG)
8263 (match_operand 0 "ext_register_operand" "Q")
8267 (match_operand 1 "ext_register_operand" "Q")
8271 "ix86_match_ccmode (insn, CCNOmode)"
8272 "test{b}\t{%h1, %h0|%h0, %h1}"
8273 [(set_attr "type" "test")
8274 (set_attr "mode" "QI")])
8276 (define_insn "*testqi_ext_3_rex64"
8277 [(set (reg FLAGS_REG)
8278 (compare (zero_extract:DI
8279 (match_operand 0 "nonimmediate_operand" "rm")
8280 (match_operand:DI 1 "const_int_operand" "")
8281 (match_operand:DI 2 "const_int_operand" ""))
8284 && ix86_match_ccmode (insn, CCNOmode)
8285 && INTVAL (operands[1]) > 0
8286 && INTVAL (operands[2]) >= 0
8287 /* Ensure that resulting mask is zero or sign extended operand. */
8288 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8289 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8290 && INTVAL (operands[1]) > 32))
8291 && (GET_MODE (operands[0]) == SImode
8292 || GET_MODE (operands[0]) == DImode
8293 || GET_MODE (operands[0]) == HImode
8294 || GET_MODE (operands[0]) == QImode)"
8297 ;; Combine likes to form bit extractions for some tests. Humor it.
8298 (define_insn "*testqi_ext_3"
8299 [(set (reg FLAGS_REG)
8300 (compare (zero_extract:SI
8301 (match_operand 0 "nonimmediate_operand" "rm")
8302 (match_operand:SI 1 "const_int_operand" "")
8303 (match_operand:SI 2 "const_int_operand" ""))
8305 "ix86_match_ccmode (insn, CCNOmode)
8306 && INTVAL (operands[1]) > 0
8307 && INTVAL (operands[2]) >= 0
8308 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8309 && (GET_MODE (operands[0]) == SImode
8310 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8311 || GET_MODE (operands[0]) == HImode
8312 || GET_MODE (operands[0]) == QImode)"
8316 [(set (match_operand 0 "flags_reg_operand" "")
8317 (match_operator 1 "compare_operator"
8319 (match_operand 2 "nonimmediate_operand" "")
8320 (match_operand 3 "const_int_operand" "")
8321 (match_operand 4 "const_int_operand" ""))
8323 "ix86_match_ccmode (insn, CCNOmode)"
8324 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8326 rtx val = operands[2];
8327 HOST_WIDE_INT len = INTVAL (operands[3]);
8328 HOST_WIDE_INT pos = INTVAL (operands[4]);
8330 enum machine_mode mode, submode;
8332 mode = GET_MODE (val);
8335 /* ??? Combine likes to put non-volatile mem extractions in QImode
8336 no matter the size of the test. So find a mode that works. */
8337 if (! MEM_VOLATILE_P (val))
8339 mode = smallest_mode_for_size (pos + len, MODE_INT);
8340 val = adjust_address (val, mode, 0);
8343 else if (GET_CODE (val) == SUBREG
8344 && (submode = GET_MODE (SUBREG_REG (val)),
8345 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8346 && pos + len <= GET_MODE_BITSIZE (submode)
8347 && GET_MODE_CLASS (submode) == MODE_INT)
8349 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8351 val = SUBREG_REG (val);
8353 else if (mode == HImode && pos + len <= 8)
8355 /* Small HImode tests can be converted to QImode. */
8357 val = gen_lowpart (QImode, val);
8360 if (len == HOST_BITS_PER_WIDE_INT)
8363 mask = ((HOST_WIDE_INT)1 << len) - 1;
8366 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8369 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8370 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8371 ;; this is relatively important trick.
8372 ;; Do the conversion only post-reload to avoid limiting of the register class
8375 [(set (match_operand 0 "flags_reg_operand" "")
8376 (match_operator 1 "compare_operator"
8377 [(and (match_operand 2 "register_operand" "")
8378 (match_operand 3 "const_int_operand" ""))
8381 && QI_REG_P (operands[2])
8382 && GET_MODE (operands[2]) != QImode
8383 && ((ix86_match_ccmode (insn, CCZmode)
8384 && !(INTVAL (operands[3]) & ~(255 << 8)))
8385 || (ix86_match_ccmode (insn, CCNOmode)
8386 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8389 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8392 "operands[2] = gen_lowpart (SImode, operands[2]);
8393 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8396 [(set (match_operand 0 "flags_reg_operand" "")
8397 (match_operator 1 "compare_operator"
8398 [(and (match_operand 2 "nonimmediate_operand" "")
8399 (match_operand 3 "const_int_operand" ""))
8402 && GET_MODE (operands[2]) != QImode
8403 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8404 && ((ix86_match_ccmode (insn, CCZmode)
8405 && !(INTVAL (operands[3]) & ~255))
8406 || (ix86_match_ccmode (insn, CCNOmode)
8407 && !(INTVAL (operands[3]) & ~127)))"
8409 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8411 "operands[2] = gen_lowpart (QImode, operands[2]);
8412 operands[3] = gen_lowpart (QImode, operands[3]);")
8414 ;; %%% This used to optimize known byte-wide and operations to memory,
8415 ;; and sometimes to QImode registers. If this is considered useful,
8416 ;; it should be done with splitters.
8418 (define_expand "and<mode>3"
8419 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8420 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8421 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8423 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8425 (define_insn "*anddi_1"
8426 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8428 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8429 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8430 (clobber (reg:CC FLAGS_REG))]
8431 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8433 switch (get_attr_type (insn))
8437 enum machine_mode mode;
8439 gcc_assert (CONST_INT_P (operands[2]));
8440 if (INTVAL (operands[2]) == 0xff)
8444 gcc_assert (INTVAL (operands[2]) == 0xffff);
8448 operands[1] = gen_lowpart (mode, operands[1]);
8450 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8452 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8456 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8457 if (get_attr_mode (insn) == MODE_SI)
8458 return "and{l}\t{%k2, %k0|%k0, %k2}";
8460 return "and{q}\t{%2, %0|%0, %2}";
8463 [(set_attr "type" "alu,alu,alu,imovx")
8464 (set_attr "length_immediate" "*,*,*,0")
8465 (set (attr "prefix_rex")
8467 (and (eq_attr "type" "imovx")
8468 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8469 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8471 (const_string "*")))
8472 (set_attr "mode" "SI,DI,DI,SI")])
8474 (define_insn "*andsi_1"
8475 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8476 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8477 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8478 (clobber (reg:CC FLAGS_REG))]
8479 "ix86_binary_operator_ok (AND, SImode, operands)"
8481 switch (get_attr_type (insn))
8485 enum machine_mode mode;
8487 gcc_assert (CONST_INT_P (operands[2]));
8488 if (INTVAL (operands[2]) == 0xff)
8492 gcc_assert (INTVAL (operands[2]) == 0xffff);
8496 operands[1] = gen_lowpart (mode, operands[1]);
8498 return "movz{bl|x}\t{%1, %0|%0, %1}";
8500 return "movz{wl|x}\t{%1, %0|%0, %1}";
8504 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8505 return "and{l}\t{%2, %0|%0, %2}";
8508 [(set_attr "type" "alu,alu,imovx")
8509 (set (attr "prefix_rex")
8511 (and (eq_attr "type" "imovx")
8512 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8513 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8515 (const_string "*")))
8516 (set_attr "length_immediate" "*,*,0")
8517 (set_attr "mode" "SI")])
8519 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8520 (define_insn "*andsi_1_zext"
8521 [(set (match_operand:DI 0 "register_operand" "=r")
8523 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8524 (match_operand:SI 2 "general_operand" "g"))))
8525 (clobber (reg:CC FLAGS_REG))]
8526 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8527 "and{l}\t{%2, %k0|%k0, %2}"
8528 [(set_attr "type" "alu")
8529 (set_attr "mode" "SI")])
8531 (define_insn "*andhi_1"
8532 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8533 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8534 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8535 (clobber (reg:CC FLAGS_REG))]
8536 "ix86_binary_operator_ok (AND, HImode, operands)"
8538 switch (get_attr_type (insn))
8541 gcc_assert (CONST_INT_P (operands[2]));
8542 gcc_assert (INTVAL (operands[2]) == 0xff);
8543 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8546 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8548 return "and{w}\t{%2, %0|%0, %2}";
8551 [(set_attr "type" "alu,alu,imovx")
8552 (set_attr "length_immediate" "*,*,0")
8553 (set (attr "prefix_rex")
8555 (and (eq_attr "type" "imovx")
8556 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8558 (const_string "*")))
8559 (set_attr "mode" "HI,HI,SI")])
8561 ;; %%% Potential partial reg stall on alternative 2. What to do?
8562 (define_insn "*andqi_1"
8563 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8564 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8565 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8566 (clobber (reg:CC FLAGS_REG))]
8567 "ix86_binary_operator_ok (AND, QImode, operands)"
8569 and{b}\t{%2, %0|%0, %2}
8570 and{b}\t{%2, %0|%0, %2}
8571 and{l}\t{%k2, %k0|%k0, %k2}"
8572 [(set_attr "type" "alu")
8573 (set_attr "mode" "QI,QI,SI")])
8575 (define_insn "*andqi_1_slp"
8576 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8577 (and:QI (match_dup 0)
8578 (match_operand:QI 1 "general_operand" "qn,qmn")))
8579 (clobber (reg:CC FLAGS_REG))]
8580 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8581 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8582 "and{b}\t{%1, %0|%0, %1}"
8583 [(set_attr "type" "alu1")
8584 (set_attr "mode" "QI")])
8587 [(set (match_operand 0 "register_operand" "")
8589 (const_int -65536)))
8590 (clobber (reg:CC FLAGS_REG))]
8591 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8592 || optimize_function_for_size_p (cfun)"
8593 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8594 "operands[1] = gen_lowpart (HImode, operands[0]);")
8597 [(set (match_operand 0 "ext_register_operand" "")
8600 (clobber (reg:CC FLAGS_REG))]
8601 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8602 && reload_completed"
8603 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8604 "operands[1] = gen_lowpart (QImode, operands[0]);")
8607 [(set (match_operand 0 "ext_register_operand" "")
8609 (const_int -65281)))
8610 (clobber (reg:CC FLAGS_REG))]
8611 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8612 && reload_completed"
8613 [(parallel [(set (zero_extract:SI (match_dup 0)
8617 (zero_extract:SI (match_dup 0)
8620 (zero_extract:SI (match_dup 0)
8623 (clobber (reg:CC FLAGS_REG))])]
8624 "operands[0] = gen_lowpart (SImode, operands[0]);")
8626 (define_insn "*anddi_2"
8627 [(set (reg FLAGS_REG)
8630 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8631 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8633 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8634 (and:DI (match_dup 1) (match_dup 2)))]
8635 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8636 && ix86_binary_operator_ok (AND, DImode, operands)"
8638 and{l}\t{%k2, %k0|%k0, %k2}
8639 and{q}\t{%2, %0|%0, %2}
8640 and{q}\t{%2, %0|%0, %2}"
8641 [(set_attr "type" "alu")
8642 (set_attr "mode" "SI,DI,DI")])
8644 (define_insn "*andqi_2_maybe_si"
8645 [(set (reg FLAGS_REG)
8647 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8648 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8650 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8651 (and:QI (match_dup 1) (match_dup 2)))]
8652 "ix86_binary_operator_ok (AND, QImode, operands)
8653 && ix86_match_ccmode (insn,
8654 CONST_INT_P (operands[2])
8655 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8657 if (which_alternative == 2)
8659 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8660 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8661 return "and{l}\t{%2, %k0|%k0, %2}";
8663 return "and{b}\t{%2, %0|%0, %2}";
8665 [(set_attr "type" "alu")
8666 (set_attr "mode" "QI,QI,SI")])
8668 (define_insn "*and<mode>_2"
8669 [(set (reg FLAGS_REG)
8670 (compare (and:SWI124
8671 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8672 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8674 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8675 (and:SWI124 (match_dup 1) (match_dup 2)))]
8676 "ix86_match_ccmode (insn, CCNOmode)
8677 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8678 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8679 [(set_attr "type" "alu")
8680 (set_attr "mode" "<MODE>")])
8682 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8683 (define_insn "*andsi_2_zext"
8684 [(set (reg FLAGS_REG)
8686 (match_operand:SI 1 "nonimmediate_operand" "%0")
8687 (match_operand:SI 2 "general_operand" "g"))
8689 (set (match_operand:DI 0 "register_operand" "=r")
8690 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8691 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8692 && ix86_binary_operator_ok (AND, SImode, operands)"
8693 "and{l}\t{%2, %k0|%k0, %2}"
8694 [(set_attr "type" "alu")
8695 (set_attr "mode" "SI")])
8697 (define_insn "*andqi_2_slp"
8698 [(set (reg FLAGS_REG)
8700 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8701 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8703 (set (strict_low_part (match_dup 0))
8704 (and:QI (match_dup 0) (match_dup 1)))]
8705 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8706 && ix86_match_ccmode (insn, CCNOmode)
8707 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8708 "and{b}\t{%1, %0|%0, %1}"
8709 [(set_attr "type" "alu1")
8710 (set_attr "mode" "QI")])
8712 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8713 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8714 ;; for a QImode operand, which of course failed.
8715 (define_insn "andqi_ext_0"
8716 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8721 (match_operand 1 "ext_register_operand" "0")
8724 (match_operand 2 "const_int_operand" "n")))
8725 (clobber (reg:CC FLAGS_REG))]
8727 "and{b}\t{%2, %h0|%h0, %2}"
8728 [(set_attr "type" "alu")
8729 (set_attr "length_immediate" "1")
8730 (set_attr "modrm" "1")
8731 (set_attr "mode" "QI")])
8733 ;; Generated by peephole translating test to and. This shows up
8734 ;; often in fp comparisons.
8735 (define_insn "*andqi_ext_0_cc"
8736 [(set (reg FLAGS_REG)
8740 (match_operand 1 "ext_register_operand" "0")
8743 (match_operand 2 "const_int_operand" "n"))
8745 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8754 "ix86_match_ccmode (insn, CCNOmode)"
8755 "and{b}\t{%2, %h0|%h0, %2}"
8756 [(set_attr "type" "alu")
8757 (set_attr "length_immediate" "1")
8758 (set_attr "modrm" "1")
8759 (set_attr "mode" "QI")])
8761 (define_insn "*andqi_ext_1_rex64"
8762 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8767 (match_operand 1 "ext_register_operand" "0")
8771 (match_operand 2 "ext_register_operand" "Q"))))
8772 (clobber (reg:CC FLAGS_REG))]
8774 "and{b}\t{%2, %h0|%h0, %2}"
8775 [(set_attr "type" "alu")
8776 (set_attr "length_immediate" "0")
8777 (set_attr "mode" "QI")])
8779 (define_insn "*andqi_ext_1"
8780 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8785 (match_operand 1 "ext_register_operand" "0")
8789 (match_operand:QI 2 "general_operand" "Qm"))))
8790 (clobber (reg:CC FLAGS_REG))]
8792 "and{b}\t{%2, %h0|%h0, %2}"
8793 [(set_attr "type" "alu")
8794 (set_attr "length_immediate" "0")
8795 (set_attr "mode" "QI")])
8797 (define_insn "*andqi_ext_2"
8798 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8803 (match_operand 1 "ext_register_operand" "%0")
8807 (match_operand 2 "ext_register_operand" "Q")
8810 (clobber (reg:CC FLAGS_REG))]
8812 "and{b}\t{%h2, %h0|%h0, %h2}"
8813 [(set_attr "type" "alu")
8814 (set_attr "length_immediate" "0")
8815 (set_attr "mode" "QI")])
8817 ;; Convert wide AND instructions with immediate operand to shorter QImode
8818 ;; equivalents when possible.
8819 ;; Don't do the splitting with memory operands, since it introduces risk
8820 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8821 ;; for size, but that can (should?) be handled by generic code instead.
8823 [(set (match_operand 0 "register_operand" "")
8824 (and (match_operand 1 "register_operand" "")
8825 (match_operand 2 "const_int_operand" "")))
8826 (clobber (reg:CC FLAGS_REG))]
8828 && QI_REG_P (operands[0])
8829 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8830 && !(~INTVAL (operands[2]) & ~(255 << 8))
8831 && GET_MODE (operands[0]) != QImode"
8832 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8833 (and:SI (zero_extract:SI (match_dup 1)
8834 (const_int 8) (const_int 8))
8836 (clobber (reg:CC FLAGS_REG))])]
8837 "operands[0] = gen_lowpart (SImode, operands[0]);
8838 operands[1] = gen_lowpart (SImode, operands[1]);
8839 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8841 ;; Since AND can be encoded with sign extended immediate, this is only
8842 ;; profitable when 7th bit is not set.
8844 [(set (match_operand 0 "register_operand" "")
8845 (and (match_operand 1 "general_operand" "")
8846 (match_operand 2 "const_int_operand" "")))
8847 (clobber (reg:CC FLAGS_REG))]
8849 && ANY_QI_REG_P (operands[0])
8850 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8851 && !(~INTVAL (operands[2]) & ~255)
8852 && !(INTVAL (operands[2]) & 128)
8853 && GET_MODE (operands[0]) != QImode"
8854 [(parallel [(set (strict_low_part (match_dup 0))
8855 (and:QI (match_dup 1)
8857 (clobber (reg:CC FLAGS_REG))])]
8858 "operands[0] = gen_lowpart (QImode, operands[0]);
8859 operands[1] = gen_lowpart (QImode, operands[1]);
8860 operands[2] = gen_lowpart (QImode, operands[2]);")
8862 ;; Logical inclusive OR instructions
8864 ;; %%% This used to optimize known byte-wide and operations to memory.
8865 ;; If this is considered useful, it should be done with splitters.
8867 (define_expand "ior<mode>3"
8868 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8869 (ior:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8870 (match_operand:SWIM 2 "<general_operand>" "")))]
8872 "ix86_expand_binary_operator (IOR, <MODE>mode, operands); DONE;")
8874 (define_insn "*ior<mode>_1"
8875 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8876 (ior:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8877 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8878 (clobber (reg:CC FLAGS_REG))]
8879 "ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
8880 "or{<imodesuffix>}\t{%2, %0|%0, %2}"
8881 [(set_attr "type" "alu")
8882 (set_attr "mode" "<MODE>")])
8884 ;; %%% Potential partial reg stall on alternative 2. What to do?
8885 (define_insn "*iorqi_1"
8886 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8887 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8888 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8889 (clobber (reg:CC FLAGS_REG))]
8890 "ix86_binary_operator_ok (IOR, QImode, operands)"
8892 or{b}\t{%2, %0|%0, %2}
8893 or{b}\t{%2, %0|%0, %2}
8894 or{l}\t{%k2, %k0|%k0, %k2}"
8895 [(set_attr "type" "alu")
8896 (set_attr "mode" "QI,QI,SI")])
8898 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8899 (define_insn "*iorsi_1_zext"
8900 [(set (match_operand:DI 0 "register_operand" "=r")
8902 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8903 (match_operand:SI 2 "general_operand" "g"))))
8904 (clobber (reg:CC FLAGS_REG))]
8905 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8906 "or{l}\t{%2, %k0|%k0, %2}"
8907 [(set_attr "type" "alu")
8908 (set_attr "mode" "SI")])
8910 (define_insn "*iorsi_1_zext_imm"
8911 [(set (match_operand:DI 0 "register_operand" "=r")
8912 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8913 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8914 (clobber (reg:CC FLAGS_REG))]
8915 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8916 "or{l}\t{%2, %k0|%k0, %2}"
8917 [(set_attr "type" "alu")
8918 (set_attr "mode" "SI")])
8920 (define_insn "*iorqi_1_slp"
8921 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8922 (ior:QI (match_dup 0)
8923 (match_operand:QI 1 "general_operand" "qmn,qn")))
8924 (clobber (reg:CC FLAGS_REG))]
8925 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8926 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8927 "or{b}\t{%1, %0|%0, %1}"
8928 [(set_attr "type" "alu1")
8929 (set_attr "mode" "QI")])
8931 (define_insn "*ior<mode>_2"
8932 [(set (reg FLAGS_REG)
8934 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8935 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8937 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8938 (ior:SWI (match_dup 1) (match_dup 2)))]
8939 "ix86_match_ccmode (insn, CCNOmode)
8940 && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
8941 "or{<imodesuffix>}\t{%2, %0|%0, %2}"
8942 [(set_attr "type" "alu")
8943 (set_attr "mode" "<MODE>")])
8945 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8946 ;; ??? Special case for immediate operand is missing - it is tricky.
8947 (define_insn "*iorsi_2_zext"
8948 [(set (reg FLAGS_REG)
8949 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8950 (match_operand:SI 2 "general_operand" "g"))
8952 (set (match_operand:DI 0 "register_operand" "=r")
8953 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
8954 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8955 && ix86_binary_operator_ok (IOR, SImode, operands)"
8956 "or{l}\t{%2, %k0|%k0, %2}"
8957 [(set_attr "type" "alu")
8958 (set_attr "mode" "SI")])
8960 (define_insn "*iorsi_2_zext_imm"
8961 [(set (reg FLAGS_REG)
8963 (match_operand:SI 1 "nonimmediate_operand" "%0")
8964 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8966 (set (match_operand:DI 0 "register_operand" "=r")
8967 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8968 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8969 && ix86_binary_operator_ok (IOR, SImode, operands)"
8970 "or{l}\t{%2, %k0|%k0, %2}"
8971 [(set_attr "type" "alu")
8972 (set_attr "mode" "SI")])
8974 (define_insn "*iorqi_2_slp"
8975 [(set (reg FLAGS_REG)
8976 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8977 (match_operand:QI 1 "general_operand" "qmn,qn"))
8979 (set (strict_low_part (match_dup 0))
8980 (ior:QI (match_dup 0) (match_dup 1)))]
8981 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8982 && ix86_match_ccmode (insn, CCNOmode)
8983 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8984 "or{b}\t{%1, %0|%0, %1}"
8985 [(set_attr "type" "alu1")
8986 (set_attr "mode" "QI")])
8988 (define_insn "*ior<mode>_3"
8989 [(set (reg FLAGS_REG)
8991 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8992 (match_operand:SWI 2 "<general_operand>" "<g>"))
8994 (clobber (match_scratch:SWI 0 "=<r>"))]
8995 "ix86_match_ccmode (insn, CCNOmode)
8996 && ix86_binary_operator_ok (IOR, <MODE>mode, operands)"
8997 "or{<imodesuffix>}\t{%2, %0|%0, %2}"
8998 [(set_attr "type" "alu")
8999 (set_attr "mode" "<MODE>")])
9001 (define_insn "*iorqi_ext_0"
9002 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9007 (match_operand 1 "ext_register_operand" "0")
9010 (match_operand 2 "const_int_operand" "n")))
9011 (clobber (reg:CC FLAGS_REG))]
9012 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9013 "or{b}\t{%2, %h0|%h0, %2}"
9014 [(set_attr "type" "alu")
9015 (set_attr "length_immediate" "1")
9016 (set_attr "modrm" "1")
9017 (set_attr "mode" "QI")])
9019 (define_insn "*iorqi_ext_1_rex64"
9020 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9025 (match_operand 1 "ext_register_operand" "0")
9029 (match_operand 2 "ext_register_operand" "Q"))))
9030 (clobber (reg:CC FLAGS_REG))]
9032 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9033 "or{b}\t{%2, %h0|%h0, %2}"
9034 [(set_attr "type" "alu")
9035 (set_attr "length_immediate" "0")
9036 (set_attr "mode" "QI")])
9038 (define_insn "*iorqi_ext_1"
9039 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9044 (match_operand 1 "ext_register_operand" "0")
9048 (match_operand:QI 2 "general_operand" "Qm"))))
9049 (clobber (reg:CC FLAGS_REG))]
9051 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9052 "or{b}\t{%2, %h0|%h0, %2}"
9053 [(set_attr "type" "alu")
9054 (set_attr "length_immediate" "0")
9055 (set_attr "mode" "QI")])
9057 (define_insn "*iorqi_ext_2"
9058 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9062 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9065 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9068 (clobber (reg:CC FLAGS_REG))]
9069 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9070 "ior{b}\t{%h2, %h0|%h0, %h2}"
9071 [(set_attr "type" "alu")
9072 (set_attr "length_immediate" "0")
9073 (set_attr "mode" "QI")])
9076 [(set (match_operand 0 "register_operand" "")
9077 (ior (match_operand 1 "register_operand" "")
9078 (match_operand 2 "const_int_operand" "")))
9079 (clobber (reg:CC FLAGS_REG))]
9081 && QI_REG_P (operands[0])
9082 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9083 && !(INTVAL (operands[2]) & ~(255 << 8))
9084 && GET_MODE (operands[0]) != QImode"
9085 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9086 (ior:SI (zero_extract:SI (match_dup 1)
9087 (const_int 8) (const_int 8))
9089 (clobber (reg:CC FLAGS_REG))])]
9090 "operands[0] = gen_lowpart (SImode, operands[0]);
9091 operands[1] = gen_lowpart (SImode, operands[1]);
9092 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9094 ;; Since OR can be encoded with sign extended immediate, this is only
9095 ;; profitable when 7th bit is set.
9097 [(set (match_operand 0 "register_operand" "")
9098 (ior (match_operand 1 "general_operand" "")
9099 (match_operand 2 "const_int_operand" "")))
9100 (clobber (reg:CC FLAGS_REG))]
9102 && ANY_QI_REG_P (operands[0])
9103 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9104 && !(INTVAL (operands[2]) & ~255)
9105 && (INTVAL (operands[2]) & 128)
9106 && GET_MODE (operands[0]) != QImode"
9107 [(parallel [(set (strict_low_part (match_dup 0))
9108 (ior:QI (match_dup 1)
9110 (clobber (reg:CC FLAGS_REG))])]
9111 "operands[0] = gen_lowpart (QImode, operands[0]);
9112 operands[1] = gen_lowpart (QImode, operands[1]);
9113 operands[2] = gen_lowpart (QImode, operands[2]);")
9115 ;; Logical XOR instructions
9117 ;; %%% This used to optimize known byte-wide and operations to memory.
9118 ;; If this is considered useful, it should be done with splitters.
9120 (define_expand "xor<mode>3"
9121 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9122 (xor:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
9123 (match_operand:SWIM 2 "<general_operand>" "")))]
9125 "ix86_expand_binary_operator (XOR, <MODE>mode, operands); DONE;")
9127 (define_insn "*xor<mode>_1"
9128 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
9129 (xor:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
9130 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
9131 (clobber (reg:CC FLAGS_REG))]
9132 "ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
9133 "xor{<imodesuffix>}\t{%2, %0|%0, %2}"
9134 [(set_attr "type" "alu")
9135 (set_attr "mode" "<MODE>")])
9137 ;; %%% Potential partial reg stall on alternative 2. What to do?
9138 (define_insn "*xorqi_1"
9139 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9140 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9141 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9142 (clobber (reg:CC FLAGS_REG))]
9143 "ix86_binary_operator_ok (XOR, QImode, operands)"
9145 xor{b}\t{%2, %0|%0, %2}
9146 xor{b}\t{%2, %0|%0, %2}
9147 xor{l}\t{%k2, %k0|%k0, %k2}"
9148 [(set_attr "type" "alu")
9149 (set_attr "mode" "QI,QI,SI")])
9151 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9152 ;; Add speccase for immediates
9153 (define_insn "*xorsi_1_zext"
9154 [(set (match_operand:DI 0 "register_operand" "=r")
9156 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9157 (match_operand:SI 2 "general_operand" "g"))))
9158 (clobber (reg:CC FLAGS_REG))]
9159 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9160 "xor{l}\t{%2, %k0|%k0, %2}"
9161 [(set_attr "type" "alu")
9162 (set_attr "mode" "SI")])
9164 (define_insn "*xorsi_1_zext_imm"
9165 [(set (match_operand:DI 0 "register_operand" "=r")
9166 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9167 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9168 (clobber (reg:CC FLAGS_REG))]
9169 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9170 "xor{l}\t{%2, %k0|%k0, %2}"
9171 [(set_attr "type" "alu")
9172 (set_attr "mode" "SI")])
9174 (define_insn "*xorqi_1_slp"
9175 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9176 (xor:QI (match_dup 0)
9177 (match_operand:QI 1 "general_operand" "qn,qmn")))
9178 (clobber (reg:CC FLAGS_REG))]
9179 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9180 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9181 "xor{b}\t{%1, %0|%0, %1}"
9182 [(set_attr "type" "alu1")
9183 (set_attr "mode" "QI")])
9185 (define_insn "*xor<mode>_2"
9186 [(set (reg FLAGS_REG)
9188 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
9189 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
9191 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
9192 (xor:SWI (match_dup 1) (match_dup 2)))]
9193 "ix86_match_ccmode (insn, CCNOmode)
9194 && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
9195 "xor{<imodesuffix>}\t{%2, %0|%0, %2}"
9196 [(set_attr "type" "alu")
9197 (set_attr "mode" "<MODE>")])
9199 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9200 ;; ??? Special case for immediate operand is missing - it is tricky.
9201 (define_insn "*xorsi_2_zext"
9202 [(set (reg FLAGS_REG)
9203 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9204 (match_operand:SI 2 "general_operand" "g"))
9206 (set (match_operand:DI 0 "register_operand" "=r")
9207 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9208 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9209 && ix86_binary_operator_ok (XOR, SImode, operands)"
9210 "xor{l}\t{%2, %k0|%k0, %2}"
9211 [(set_attr "type" "alu")
9212 (set_attr "mode" "SI")])
9214 (define_insn "*xorsi_2_zext_imm"
9215 [(set (reg FLAGS_REG)
9216 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9217 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9219 (set (match_operand:DI 0 "register_operand" "=r")
9220 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9221 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9222 && ix86_binary_operator_ok (XOR, SImode, operands)"
9223 "xor{l}\t{%2, %k0|%k0, %2}"
9224 [(set_attr "type" "alu")
9225 (set_attr "mode" "SI")])
9227 (define_insn "*xorqi_2_slp"
9228 [(set (reg FLAGS_REG)
9229 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9230 (match_operand:QI 1 "general_operand" "qmn,qn"))
9232 (set (strict_low_part (match_dup 0))
9233 (xor:QI (match_dup 0) (match_dup 1)))]
9234 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9235 && ix86_match_ccmode (insn, CCNOmode)
9236 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9237 "xor{b}\t{%1, %0|%0, %1}"
9238 [(set_attr "type" "alu1")
9239 (set_attr "mode" "QI")])
9241 (define_insn "*xor<mode>_3"
9242 [(set (reg FLAGS_REG)
9244 (match_operand:SWI 1 "nonimmediate_operand" "%0")
9245 (match_operand:SWI 2 "<general_operand>" "<g>"))
9247 (clobber (match_scratch:SWI 0 "=<r>"))]
9248 "ix86_match_ccmode (insn, CCNOmode)
9249 && ix86_binary_operator_ok (XOR, <MODE>mode, operands)"
9250 "xor{<imodesuffix>}\t{%2, %0|%0, %2}"
9251 [(set_attr "type" "alu")
9252 (set_attr "mode" "<MODE>")])
9254 (define_insn "*xorqi_ext_0"
9255 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9260 (match_operand 1 "ext_register_operand" "0")
9263 (match_operand 2 "const_int_operand" "n")))
9264 (clobber (reg:CC FLAGS_REG))]
9265 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9266 "xor{b}\t{%2, %h0|%h0, %2}"
9267 [(set_attr "type" "alu")
9268 (set_attr "length_immediate" "1")
9269 (set_attr "modrm" "1")
9270 (set_attr "mode" "QI")])
9272 (define_insn "*xorqi_ext_1_rex64"
9273 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9278 (match_operand 1 "ext_register_operand" "0")
9282 (match_operand 2 "ext_register_operand" "Q"))))
9283 (clobber (reg:CC FLAGS_REG))]
9285 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9286 "xor{b}\t{%2, %h0|%h0, %2}"
9287 [(set_attr "type" "alu")
9288 (set_attr "length_immediate" "0")
9289 (set_attr "mode" "QI")])
9291 (define_insn "*xorqi_ext_1"
9292 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9297 (match_operand 1 "ext_register_operand" "0")
9301 (match_operand:QI 2 "general_operand" "Qm"))))
9302 (clobber (reg:CC FLAGS_REG))]
9304 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9305 "xor{b}\t{%2, %h0|%h0, %2}"
9306 [(set_attr "type" "alu")
9307 (set_attr "length_immediate" "0")
9308 (set_attr "mode" "QI")])
9310 (define_insn "*xorqi_ext_2"
9311 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9315 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9318 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9321 (clobber (reg:CC FLAGS_REG))]
9322 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
9323 "xor{b}\t{%h2, %h0|%h0, %h2}"
9324 [(set_attr "type" "alu")
9325 (set_attr "length_immediate" "0")
9326 (set_attr "mode" "QI")])
9328 (define_expand "xorqi_cc_ext_1"
9330 (set (reg:CCNO FLAGS_REG)
9334 (match_operand 1 "ext_register_operand" "")
9337 (match_operand:QI 2 "general_operand" ""))
9339 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9351 (define_insn "*xorqi_cc_ext_1_rex64"
9352 [(set (reg FLAGS_REG)
9356 (match_operand 1 "ext_register_operand" "0")
9359 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9361 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9370 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9371 "xor{b}\t{%2, %h0|%h0, %2}"
9372 [(set_attr "type" "alu")
9373 (set_attr "modrm" "1")
9374 (set_attr "mode" "QI")])
9376 (define_insn "*xorqi_cc_ext_1"
9377 [(set (reg FLAGS_REG)
9381 (match_operand 1 "ext_register_operand" "0")
9384 (match_operand:QI 2 "general_operand" "qmn"))
9386 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9395 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9396 "xor{b}\t{%2, %h0|%h0, %2}"
9397 [(set_attr "type" "alu")
9398 (set_attr "modrm" "1")
9399 (set_attr "mode" "QI")])
9402 [(set (match_operand 0 "register_operand" "")
9403 (xor (match_operand 1 "register_operand" "")
9404 (match_operand 2 "const_int_operand" "")))
9405 (clobber (reg:CC FLAGS_REG))]
9407 && QI_REG_P (operands[0])
9408 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9409 && !(INTVAL (operands[2]) & ~(255 << 8))
9410 && GET_MODE (operands[0]) != QImode"
9411 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9412 (xor:SI (zero_extract:SI (match_dup 1)
9413 (const_int 8) (const_int 8))
9415 (clobber (reg:CC FLAGS_REG))])]
9416 "operands[0] = gen_lowpart (SImode, operands[0]);
9417 operands[1] = gen_lowpart (SImode, operands[1]);
9418 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9420 ;; Since XOR can be encoded with sign extended immediate, this is only
9421 ;; profitable when 7th bit is set.
9423 [(set (match_operand 0 "register_operand" "")
9424 (xor (match_operand 1 "general_operand" "")
9425 (match_operand 2 "const_int_operand" "")))
9426 (clobber (reg:CC FLAGS_REG))]
9428 && ANY_QI_REG_P (operands[0])
9429 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9430 && !(INTVAL (operands[2]) & ~255)
9431 && (INTVAL (operands[2]) & 128)
9432 && GET_MODE (operands[0]) != QImode"
9433 [(parallel [(set (strict_low_part (match_dup 0))
9434 (xor:QI (match_dup 1)
9436 (clobber (reg:CC FLAGS_REG))])]
9437 "operands[0] = gen_lowpart (QImode, operands[0]);
9438 operands[1] = gen_lowpart (QImode, operands[1]);
9439 operands[2] = gen_lowpart (QImode, operands[2]);")
9441 ;; Negation instructions
9443 (define_expand "neg<mode>2"
9444 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9445 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9447 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9449 (define_insn_and_split "*neg<dwi>2_doubleword"
9450 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9451 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9452 (clobber (reg:CC FLAGS_REG))]
9453 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9457 [(set (reg:CCZ FLAGS_REG)
9458 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9459 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9462 (plus:DWIH (match_dup 3)
9463 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9465 (clobber (reg:CC FLAGS_REG))])
9468 (neg:DWIH (match_dup 2)))
9469 (clobber (reg:CC FLAGS_REG))])]
9470 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9472 (define_insn "*neg<mode>2_1"
9473 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9474 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9475 (clobber (reg:CC FLAGS_REG))]
9476 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9477 "neg{<imodesuffix>}\t%0"
9478 [(set_attr "type" "negnot")
9479 (set_attr "mode" "<MODE>")])
9481 ;; Combine is quite creative about this pattern.
9482 (define_insn "*negsi2_1_zext"
9483 [(set (match_operand:DI 0 "register_operand" "=r")
9485 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9488 (clobber (reg:CC FLAGS_REG))]
9489 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9491 [(set_attr "type" "negnot")
9492 (set_attr "mode" "SI")])
9494 ;; The problem with neg is that it does not perform (compare x 0),
9495 ;; it really performs (compare 0 x), which leaves us with the zero
9496 ;; flag being the only useful item.
9498 (define_insn "*neg<mode>2_cmpz"
9499 [(set (reg:CCZ FLAGS_REG)
9501 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9503 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9504 (neg:SWI (match_dup 1)))]
9505 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9506 "neg{<imodesuffix>}\t%0"
9507 [(set_attr "type" "negnot")
9508 (set_attr "mode" "<MODE>")])
9510 (define_insn "*negsi2_cmpz_zext"
9511 [(set (reg:CCZ FLAGS_REG)
9515 (match_operand:DI 1 "register_operand" "0")
9519 (set (match_operand:DI 0 "register_operand" "=r")
9520 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9523 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9525 [(set_attr "type" "negnot")
9526 (set_attr "mode" "SI")])
9528 ;; Changing of sign for FP values is doable using integer unit too.
9530 (define_expand "<code><mode>2"
9531 [(set (match_operand:X87MODEF 0 "register_operand" "")
9532 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9533 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9534 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9536 (define_insn "*absneg<mode>2_mixed"
9537 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9538 (match_operator:MODEF 3 "absneg_operator"
9539 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9540 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9541 (clobber (reg:CC FLAGS_REG))]
9542 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9545 (define_insn "*absneg<mode>2_sse"
9546 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9547 (match_operator:MODEF 3 "absneg_operator"
9548 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9549 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9550 (clobber (reg:CC FLAGS_REG))]
9551 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9554 (define_insn "*absneg<mode>2_i387"
9555 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9556 (match_operator:X87MODEF 3 "absneg_operator"
9557 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9558 (use (match_operand 2 "" ""))
9559 (clobber (reg:CC FLAGS_REG))]
9560 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9563 (define_expand "<code>tf2"
9564 [(set (match_operand:TF 0 "register_operand" "")
9565 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9567 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9569 (define_insn "*absnegtf2_sse"
9570 [(set (match_operand:TF 0 "register_operand" "=x,x")
9571 (match_operator:TF 3 "absneg_operator"
9572 [(match_operand:TF 1 "register_operand" "0,x")]))
9573 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9574 (clobber (reg:CC FLAGS_REG))]
9578 ;; Splitters for fp abs and neg.
9581 [(set (match_operand 0 "fp_register_operand" "")
9582 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9583 (use (match_operand 2 "" ""))
9584 (clobber (reg:CC FLAGS_REG))]
9586 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9589 [(set (match_operand 0 "register_operand" "")
9590 (match_operator 3 "absneg_operator"
9591 [(match_operand 1 "register_operand" "")]))
9592 (use (match_operand 2 "nonimmediate_operand" ""))
9593 (clobber (reg:CC FLAGS_REG))]
9594 "reload_completed && SSE_REG_P (operands[0])"
9595 [(set (match_dup 0) (match_dup 3))]
9597 enum machine_mode mode = GET_MODE (operands[0]);
9598 enum machine_mode vmode = GET_MODE (operands[2]);
9601 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9602 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9603 if (operands_match_p (operands[0], operands[2]))
9606 operands[1] = operands[2];
9609 if (GET_CODE (operands[3]) == ABS)
9610 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9612 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9617 [(set (match_operand:SF 0 "register_operand" "")
9618 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9619 (use (match_operand:V4SF 2 "" ""))
9620 (clobber (reg:CC FLAGS_REG))]
9622 [(parallel [(set (match_dup 0) (match_dup 1))
9623 (clobber (reg:CC FLAGS_REG))])]
9626 operands[0] = gen_lowpart (SImode, operands[0]);
9627 if (GET_CODE (operands[1]) == ABS)
9629 tmp = gen_int_mode (0x7fffffff, SImode);
9630 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9634 tmp = gen_int_mode (0x80000000, SImode);
9635 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9641 [(set (match_operand:DF 0 "register_operand" "")
9642 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9643 (use (match_operand 2 "" ""))
9644 (clobber (reg:CC FLAGS_REG))]
9646 [(parallel [(set (match_dup 0) (match_dup 1))
9647 (clobber (reg:CC FLAGS_REG))])]
9652 tmp = gen_lowpart (DImode, operands[0]);
9653 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9656 if (GET_CODE (operands[1]) == ABS)
9659 tmp = gen_rtx_NOT (DImode, tmp);
9663 operands[0] = gen_highpart (SImode, operands[0]);
9664 if (GET_CODE (operands[1]) == ABS)
9666 tmp = gen_int_mode (0x7fffffff, SImode);
9667 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9671 tmp = gen_int_mode (0x80000000, SImode);
9672 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9679 [(set (match_operand:XF 0 "register_operand" "")
9680 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9681 (use (match_operand 2 "" ""))
9682 (clobber (reg:CC FLAGS_REG))]
9684 [(parallel [(set (match_dup 0) (match_dup 1))
9685 (clobber (reg:CC FLAGS_REG))])]
9688 operands[0] = gen_rtx_REG (SImode,
9689 true_regnum (operands[0])
9690 + (TARGET_64BIT ? 1 : 2));
9691 if (GET_CODE (operands[1]) == ABS)
9693 tmp = GEN_INT (0x7fff);
9694 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9698 tmp = GEN_INT (0x8000);
9699 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9704 ;; Conditionalize these after reload. If they match before reload, we
9705 ;; lose the clobber and ability to use integer instructions.
9707 (define_insn "*<code><mode>2_1"
9708 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9709 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9711 && (reload_completed
9712 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9714 [(set_attr "type" "fsgn")
9715 (set_attr "mode" "<MODE>")])
9717 (define_insn "*<code>extendsfdf2"
9718 [(set (match_operand:DF 0 "register_operand" "=f")
9719 (absneg:DF (float_extend:DF
9720 (match_operand:SF 1 "register_operand" "0"))))]
9721 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9723 [(set_attr "type" "fsgn")
9724 (set_attr "mode" "DF")])
9726 (define_insn "*<code>extendsfxf2"
9727 [(set (match_operand:XF 0 "register_operand" "=f")
9728 (absneg:XF (float_extend:XF
9729 (match_operand:SF 1 "register_operand" "0"))))]
9732 [(set_attr "type" "fsgn")
9733 (set_attr "mode" "XF")])
9735 (define_insn "*<code>extenddfxf2"
9736 [(set (match_operand:XF 0 "register_operand" "=f")
9737 (absneg:XF (float_extend:XF
9738 (match_operand:DF 1 "register_operand" "0"))))]
9741 [(set_attr "type" "fsgn")
9742 (set_attr "mode" "XF")])
9744 ;; Copysign instructions
9746 (define_mode_iterator CSGNMODE [SF DF TF])
9747 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9749 (define_expand "copysign<mode>3"
9750 [(match_operand:CSGNMODE 0 "register_operand" "")
9751 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9752 (match_operand:CSGNMODE 2 "register_operand" "")]
9753 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9754 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9756 ix86_expand_copysign (operands);
9760 (define_insn_and_split "copysign<mode>3_const"
9761 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9763 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9764 (match_operand:CSGNMODE 2 "register_operand" "0")
9765 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9767 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9768 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9770 "&& reload_completed"
9773 ix86_split_copysign_const (operands);
9777 (define_insn "copysign<mode>3_var"
9778 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9780 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9781 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9782 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9783 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9785 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9786 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9787 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9791 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9793 [(match_operand:CSGNMODE 2 "register_operand" "")
9794 (match_operand:CSGNMODE 3 "register_operand" "")
9795 (match_operand:<CSGNVMODE> 4 "" "")
9796 (match_operand:<CSGNVMODE> 5 "" "")]
9798 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9799 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9800 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9801 && reload_completed"
9804 ix86_split_copysign_var (operands);
9808 ;; One complement instructions
9810 (define_expand "one_cmpl<mode>2"
9811 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9812 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9814 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9816 (define_insn "*one_cmpl<mode>2_1"
9817 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9818 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9819 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9820 "not{<imodesuffix>}\t%0"
9821 [(set_attr "type" "negnot")
9822 (set_attr "mode" "<MODE>")])
9824 ;; %%% Potential partial reg stall on alternative 1. What to do?
9825 (define_insn "*one_cmplqi2_1"
9826 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9827 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9828 "ix86_unary_operator_ok (NOT, QImode, operands)"
9832 [(set_attr "type" "negnot")
9833 (set_attr "mode" "QI,SI")])
9835 ;; ??? Currently never generated - xor is used instead.
9836 (define_insn "*one_cmplsi2_1_zext"
9837 [(set (match_operand:DI 0 "register_operand" "=r")
9839 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9840 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9842 [(set_attr "type" "negnot")
9843 (set_attr "mode" "SI")])
9845 (define_insn "*one_cmpl<mode>2_2"
9846 [(set (reg FLAGS_REG)
9847 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9849 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9850 (not:SWI (match_dup 1)))]
9851 "ix86_match_ccmode (insn, CCNOmode)
9852 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9854 [(set_attr "type" "alu1")
9855 (set_attr "mode" "<MODE>")])
9858 [(set (match_operand 0 "flags_reg_operand" "")
9859 (match_operator 2 "compare_operator"
9860 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9862 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9863 (not:SWI (match_dup 3)))]
9864 "ix86_match_ccmode (insn, CCNOmode)"
9865 [(parallel [(set (match_dup 0)
9866 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9869 (xor:SWI (match_dup 3) (const_int -1)))])]
9872 ;; ??? Currently never generated - xor is used instead.
9873 (define_insn "*one_cmplsi2_2_zext"
9874 [(set (reg FLAGS_REG)
9875 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9877 (set (match_operand:DI 0 "register_operand" "=r")
9878 (zero_extend:DI (not:SI (match_dup 1))))]
9879 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9880 && ix86_unary_operator_ok (NOT, SImode, operands)"
9882 [(set_attr "type" "alu1")
9883 (set_attr "mode" "SI")])
9886 [(set (match_operand 0 "flags_reg_operand" "")
9887 (match_operator 2 "compare_operator"
9888 [(not:SI (match_operand:SI 3 "register_operand" ""))
9890 (set (match_operand:DI 1 "register_operand" "")
9891 (zero_extend:DI (not:SI (match_dup 3))))]
9892 "ix86_match_ccmode (insn, CCNOmode)"
9893 [(parallel [(set (match_dup 0)
9894 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9897 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9900 ;; Arithmetic shift instructions
9902 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9903 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9904 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9905 ;; from the assembler input.
9907 ;; This instruction shifts the target reg/mem as usual, but instead of
9908 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9909 ;; is a left shift double, bits are taken from the high order bits of
9910 ;; reg, else if the insn is a shift right double, bits are taken from the
9911 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9912 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9914 ;; Since sh[lr]d does not change the `reg' operand, that is done
9915 ;; separately, making all shifts emit pairs of shift double and normal
9916 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9917 ;; support a 63 bit shift, each shift where the count is in a reg expands
9918 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9920 ;; If the shift count is a constant, we need never emit more than one
9921 ;; shift pair, instead using moves and sign extension for counts greater
9924 (define_expand "ashlti3"
9925 [(set (match_operand:TI 0 "register_operand" "")
9926 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
9927 (match_operand:QI 2 "nonmemory_operand" "")))]
9929 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
9931 ;; This pattern must be defined before *ashlti3_1 to prevent
9932 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
9934 (define_insn "*avx_ashlti3"
9935 [(set (match_operand:TI 0 "register_operand" "=x")
9936 (ashift:TI (match_operand:TI 1 "register_operand" "x")
9937 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
9940 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
9941 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
9943 [(set_attr "type" "sseishft")
9944 (set_attr "prefix" "vex")
9945 (set_attr "length_immediate" "1")
9946 (set_attr "mode" "TI")])
9948 (define_insn "sse2_ashlti3"
9949 [(set (match_operand:TI 0 "register_operand" "=x")
9950 (ashift:TI (match_operand:TI 1 "register_operand" "0")
9951 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
9954 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
9955 return "pslldq\t{%2, %0|%0, %2}";
9957 [(set_attr "type" "sseishft")
9958 (set_attr "prefix_data16" "1")
9959 (set_attr "length_immediate" "1")
9960 (set_attr "mode" "TI")])
9962 (define_insn "*ashlti3_1"
9963 [(set (match_operand:TI 0 "register_operand" "=&r,r")
9964 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
9965 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
9966 (clobber (reg:CC FLAGS_REG))]
9969 [(set_attr "type" "multi")])
9972 [(match_scratch:DI 3 "r")
9973 (parallel [(set (match_operand:TI 0 "register_operand" "")
9974 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9975 (match_operand:QI 2 "nonmemory_operand" "")))
9976 (clobber (reg:CC FLAGS_REG))])
9980 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
9983 [(set (match_operand:TI 0 "register_operand" "")
9984 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9985 (match_operand:QI 2 "nonmemory_operand" "")))
9986 (clobber (reg:CC FLAGS_REG))]
9987 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9988 ? epilogue_completed : reload_completed)"
9990 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
9992 (define_insn "x86_64_shld"
9993 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9994 (ior:DI (ashift:DI (match_dup 0)
9995 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9996 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9997 (minus:QI (const_int 64) (match_dup 2)))))
9998 (clobber (reg:CC FLAGS_REG))]
10000 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10001 [(set_attr "type" "ishift")
10002 (set_attr "prefix_0f" "1")
10003 (set_attr "mode" "DI")
10004 (set_attr "athlon_decode" "vector")
10005 (set_attr "amdfam10_decode" "vector")])
10007 (define_expand "x86_64_shift_adj_1"
10008 [(set (reg:CCZ FLAGS_REG)
10009 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10012 (set (match_operand:DI 0 "register_operand" "")
10013 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10014 (match_operand:DI 1 "register_operand" "")
10017 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10018 (match_operand:DI 3 "register_operand" "r")
10023 (define_expand "x86_64_shift_adj_2"
10024 [(use (match_operand:DI 0 "register_operand" ""))
10025 (use (match_operand:DI 1 "register_operand" ""))
10026 (use (match_operand:QI 2 "register_operand" ""))]
10029 rtx label = gen_label_rtx ();
10032 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10034 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10035 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10036 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10037 gen_rtx_LABEL_REF (VOIDmode, label),
10039 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10040 JUMP_LABEL (tmp) = label;
10042 emit_move_insn (operands[0], operands[1]);
10043 ix86_expand_clear (operands[1]);
10045 emit_label (label);
10046 LABEL_NUSES (label) = 1;
10051 (define_expand "ashldi3"
10052 [(set (match_operand:DI 0 "shiftdi_operand" "")
10053 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10054 (match_operand:QI 2 "nonmemory_operand" "")))]
10056 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10058 (define_insn "*ashldi3_1_rex64"
10059 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10060 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10061 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10062 (clobber (reg:CC FLAGS_REG))]
10063 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10065 switch (get_attr_type (insn))
10068 gcc_assert (operands[2] == const1_rtx);
10069 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10070 return "add{q}\t%0, %0";
10073 gcc_assert (CONST_INT_P (operands[2]));
10074 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10075 operands[1] = gen_rtx_MULT (DImode, operands[1],
10076 GEN_INT (1 << INTVAL (operands[2])));
10077 return "lea{q}\t{%a1, %0|%0, %a1}";
10080 if (REG_P (operands[2]))
10081 return "sal{q}\t{%b2, %0|%0, %b2}";
10082 else if (operands[2] == const1_rtx
10083 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10084 return "sal{q}\t%0";
10086 return "sal{q}\t{%2, %0|%0, %2}";
10089 [(set (attr "type")
10090 (cond [(eq_attr "alternative" "1")
10091 (const_string "lea")
10092 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10094 (match_operand 0 "register_operand" ""))
10095 (match_operand 2 "const1_operand" ""))
10096 (const_string "alu")
10098 (const_string "ishift")))
10099 (set (attr "length_immediate")
10101 (ior (eq_attr "type" "alu")
10102 (and (eq_attr "type" "ishift")
10103 (and (match_operand 2 "const1_operand" "")
10104 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10107 (const_string "*")))
10108 (set_attr "mode" "DI")])
10110 ;; Convert lea to the lea pattern to avoid flags dependency.
10112 [(set (match_operand:DI 0 "register_operand" "")
10113 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10114 (match_operand:QI 2 "immediate_operand" "")))
10115 (clobber (reg:CC FLAGS_REG))]
10116 "TARGET_64BIT && reload_completed
10117 && true_regnum (operands[0]) != true_regnum (operands[1])"
10118 [(set (match_dup 0)
10119 (mult:DI (match_dup 1)
10121 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10123 ;; This pattern can't accept a variable shift count, since shifts by
10124 ;; zero don't affect the flags. We assume that shifts by constant
10125 ;; zero are optimized away.
10126 (define_insn "*ashldi3_cmp_rex64"
10127 [(set (reg FLAGS_REG)
10129 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10130 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10132 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10133 (ashift:DI (match_dup 1) (match_dup 2)))]
10135 && (optimize_function_for_size_p (cfun)
10136 || !TARGET_PARTIAL_FLAG_REG_STALL
10137 || (operands[2] == const1_rtx
10139 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10140 && ix86_match_ccmode (insn, CCGOCmode)
10141 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10143 switch (get_attr_type (insn))
10146 gcc_assert (operands[2] == const1_rtx);
10147 return "add{q}\t%0, %0";
10150 if (REG_P (operands[2]))
10151 return "sal{q}\t{%b2, %0|%0, %b2}";
10152 else if (operands[2] == const1_rtx
10153 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10154 return "sal{q}\t%0";
10156 return "sal{q}\t{%2, %0|%0, %2}";
10159 [(set (attr "type")
10160 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10162 (match_operand 0 "register_operand" ""))
10163 (match_operand 2 "const1_operand" ""))
10164 (const_string "alu")
10166 (const_string "ishift")))
10167 (set (attr "length_immediate")
10169 (ior (eq_attr "type" "alu")
10170 (and (eq_attr "type" "ishift")
10171 (and (match_operand 2 "const1_operand" "")
10172 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10175 (const_string "*")))
10176 (set_attr "mode" "DI")])
10178 (define_insn "*ashldi3_cconly_rex64"
10179 [(set (reg FLAGS_REG)
10181 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10182 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10184 (clobber (match_scratch:DI 0 "=r"))]
10186 && (optimize_function_for_size_p (cfun)
10187 || !TARGET_PARTIAL_FLAG_REG_STALL
10188 || (operands[2] == const1_rtx
10190 || TARGET_DOUBLE_WITH_ADD)))
10191 && ix86_match_ccmode (insn, CCGOCmode)
10192 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10194 switch (get_attr_type (insn))
10197 gcc_assert (operands[2] == const1_rtx);
10198 return "add{q}\t%0, %0";
10201 if (REG_P (operands[2]))
10202 return "sal{q}\t{%b2, %0|%0, %b2}";
10203 else if (operands[2] == const1_rtx
10204 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10205 return "sal{q}\t%0";
10207 return "sal{q}\t{%2, %0|%0, %2}";
10210 [(set (attr "type")
10211 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10213 (match_operand 0 "register_operand" ""))
10214 (match_operand 2 "const1_operand" ""))
10215 (const_string "alu")
10217 (const_string "ishift")))
10218 (set (attr "length_immediate")
10220 (ior (eq_attr "type" "alu")
10221 (and (eq_attr "type" "ishift")
10222 (and (match_operand 2 "const1_operand" "")
10223 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10226 (const_string "*")))
10227 (set_attr "mode" "DI")])
10229 (define_insn "*ashldi3_1"
10230 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10231 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10232 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10233 (clobber (reg:CC FLAGS_REG))]
10236 [(set_attr "type" "multi")])
10238 ;; By default we don't ask for a scratch register, because when DImode
10239 ;; values are manipulated, registers are already at a premium. But if
10240 ;; we have one handy, we won't turn it away.
10242 [(match_scratch:SI 3 "r")
10243 (parallel [(set (match_operand:DI 0 "register_operand" "")
10244 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10245 (match_operand:QI 2 "nonmemory_operand" "")))
10246 (clobber (reg:CC FLAGS_REG))])
10248 "!TARGET_64BIT && TARGET_CMOVE"
10250 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10253 [(set (match_operand:DI 0 "register_operand" "")
10254 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10255 (match_operand:QI 2 "nonmemory_operand" "")))
10256 (clobber (reg:CC FLAGS_REG))]
10257 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10258 ? epilogue_completed : reload_completed)"
10260 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10262 (define_insn "x86_shld"
10263 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10264 (ior:SI (ashift:SI (match_dup 0)
10265 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10266 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10267 (minus:QI (const_int 32) (match_dup 2)))))
10268 (clobber (reg:CC FLAGS_REG))]
10270 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10271 [(set_attr "type" "ishift")
10272 (set_attr "prefix_0f" "1")
10273 (set_attr "mode" "SI")
10274 (set_attr "pent_pair" "np")
10275 (set_attr "athlon_decode" "vector")
10276 (set_attr "amdfam10_decode" "vector")])
10278 (define_expand "x86_shift_adj_1"
10279 [(set (reg:CCZ FLAGS_REG)
10280 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10283 (set (match_operand:SI 0 "register_operand" "")
10284 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10285 (match_operand:SI 1 "register_operand" "")
10288 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10289 (match_operand:SI 3 "register_operand" "r")
10294 (define_expand "x86_shift_adj_2"
10295 [(use (match_operand:SI 0 "register_operand" ""))
10296 (use (match_operand:SI 1 "register_operand" ""))
10297 (use (match_operand:QI 2 "register_operand" ""))]
10300 rtx label = gen_label_rtx ();
10303 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10305 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10306 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10307 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10308 gen_rtx_LABEL_REF (VOIDmode, label),
10310 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10311 JUMP_LABEL (tmp) = label;
10313 emit_move_insn (operands[0], operands[1]);
10314 ix86_expand_clear (operands[1]);
10316 emit_label (label);
10317 LABEL_NUSES (label) = 1;
10322 (define_expand "ashlsi3"
10323 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10324 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10325 (match_operand:QI 2 "nonmemory_operand" "")))]
10327 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10329 (define_insn "*ashlsi3_1"
10330 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10331 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10332 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10333 (clobber (reg:CC FLAGS_REG))]
10334 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10336 switch (get_attr_type (insn))
10339 gcc_assert (operands[2] == const1_rtx);
10340 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10341 return "add{l}\t%0, %0";
10347 if (REG_P (operands[2]))
10348 return "sal{l}\t{%b2, %0|%0, %b2}";
10349 else if (operands[2] == const1_rtx
10350 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10351 return "sal{l}\t%0";
10353 return "sal{l}\t{%2, %0|%0, %2}";
10356 [(set (attr "type")
10357 (cond [(eq_attr "alternative" "1")
10358 (const_string "lea")
10359 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10361 (match_operand 0 "register_operand" ""))
10362 (match_operand 2 "const1_operand" ""))
10363 (const_string "alu")
10365 (const_string "ishift")))
10366 (set (attr "length_immediate")
10368 (ior (eq_attr "type" "alu")
10369 (and (eq_attr "type" "ishift")
10370 (and (match_operand 2 "const1_operand" "")
10371 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10374 (const_string "*")))
10375 (set_attr "mode" "SI")])
10377 ;; Convert lea to the lea pattern to avoid flags dependency.
10379 [(set (match_operand 0 "register_operand" "")
10380 (ashift (match_operand 1 "index_register_operand" "")
10381 (match_operand:QI 2 "const_int_operand" "")))
10382 (clobber (reg:CC FLAGS_REG))]
10384 && true_regnum (operands[0]) != true_regnum (operands[1])
10385 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10389 enum machine_mode mode = GET_MODE (operands[0]);
10391 if (GET_MODE_SIZE (mode) < 4)
10392 operands[0] = gen_lowpart (SImode, operands[0]);
10394 operands[1] = gen_lowpart (Pmode, operands[1]);
10395 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10397 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10398 if (Pmode != SImode)
10399 pat = gen_rtx_SUBREG (SImode, pat, 0);
10400 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10404 ;; Rare case of shifting RSP is handled by generating move and shift
10406 [(set (match_operand 0 "register_operand" "")
10407 (ashift (match_operand 1 "register_operand" "")
10408 (match_operand:QI 2 "const_int_operand" "")))
10409 (clobber (reg:CC FLAGS_REG))]
10411 && true_regnum (operands[0]) != true_regnum (operands[1])"
10415 emit_move_insn (operands[0], operands[1]);
10416 pat = gen_rtx_SET (VOIDmode, operands[0],
10417 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10418 operands[0], operands[2]));
10419 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10420 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10424 (define_insn "*ashlsi3_1_zext"
10425 [(set (match_operand:DI 0 "register_operand" "=r,r")
10426 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10427 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10428 (clobber (reg:CC FLAGS_REG))]
10429 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10431 switch (get_attr_type (insn))
10434 gcc_assert (operands[2] == const1_rtx);
10435 return "add{l}\t%k0, %k0";
10441 if (REG_P (operands[2]))
10442 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10443 else if (operands[2] == const1_rtx
10444 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10445 return "sal{l}\t%k0";
10447 return "sal{l}\t{%2, %k0|%k0, %2}";
10450 [(set (attr "type")
10451 (cond [(eq_attr "alternative" "1")
10452 (const_string "lea")
10453 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10455 (match_operand 2 "const1_operand" ""))
10456 (const_string "alu")
10458 (const_string "ishift")))
10459 (set (attr "length_immediate")
10461 (ior (eq_attr "type" "alu")
10462 (and (eq_attr "type" "ishift")
10463 (and (match_operand 2 "const1_operand" "")
10464 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10467 (const_string "*")))
10468 (set_attr "mode" "SI")])
10470 ;; Convert lea to the lea pattern to avoid flags dependency.
10472 [(set (match_operand:DI 0 "register_operand" "")
10473 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10474 (match_operand:QI 2 "const_int_operand" ""))))
10475 (clobber (reg:CC FLAGS_REG))]
10476 "TARGET_64BIT && reload_completed
10477 && true_regnum (operands[0]) != true_regnum (operands[1])"
10478 [(set (match_dup 0) (zero_extend:DI
10479 (subreg:SI (mult:SI (match_dup 1)
10480 (match_dup 2)) 0)))]
10482 operands[1] = gen_lowpart (Pmode, operands[1]);
10483 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10486 ;; This pattern can't accept a variable shift count, since shifts by
10487 ;; zero don't affect the flags. We assume that shifts by constant
10488 ;; zero are optimized away.
10489 (define_insn "*ashlsi3_cmp"
10490 [(set (reg FLAGS_REG)
10492 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10493 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10495 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10496 (ashift:SI (match_dup 1) (match_dup 2)))]
10497 "(optimize_function_for_size_p (cfun)
10498 || !TARGET_PARTIAL_FLAG_REG_STALL
10499 || (operands[2] == const1_rtx
10501 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10502 && ix86_match_ccmode (insn, CCGOCmode)
10503 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10505 switch (get_attr_type (insn))
10508 gcc_assert (operands[2] == const1_rtx);
10509 return "add{l}\t%0, %0";
10512 if (REG_P (operands[2]))
10513 return "sal{l}\t{%b2, %0|%0, %b2}";
10514 else if (operands[2] == const1_rtx
10515 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10516 return "sal{l}\t%0";
10518 return "sal{l}\t{%2, %0|%0, %2}";
10521 [(set (attr "type")
10522 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10524 (match_operand 0 "register_operand" ""))
10525 (match_operand 2 "const1_operand" ""))
10526 (const_string "alu")
10528 (const_string "ishift")))
10529 (set (attr "length_immediate")
10531 (ior (eq_attr "type" "alu")
10532 (and (eq_attr "type" "ishift")
10533 (and (match_operand 2 "const1_operand" "")
10534 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10537 (const_string "*")))
10538 (set_attr "mode" "SI")])
10540 (define_insn "*ashlsi3_cconly"
10541 [(set (reg FLAGS_REG)
10543 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10544 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10546 (clobber (match_scratch:SI 0 "=r"))]
10547 "(optimize_function_for_size_p (cfun)
10548 || !TARGET_PARTIAL_FLAG_REG_STALL
10549 || (operands[2] == const1_rtx
10551 || TARGET_DOUBLE_WITH_ADD)))
10552 && ix86_match_ccmode (insn, CCGOCmode)
10553 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10555 switch (get_attr_type (insn))
10558 gcc_assert (operands[2] == const1_rtx);
10559 return "add{l}\t%0, %0";
10562 if (REG_P (operands[2]))
10563 return "sal{l}\t{%b2, %0|%0, %b2}";
10564 else if (operands[2] == const1_rtx
10565 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10566 return "sal{l}\t%0";
10568 return "sal{l}\t{%2, %0|%0, %2}";
10571 [(set (attr "type")
10572 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10574 (match_operand 0 "register_operand" ""))
10575 (match_operand 2 "const1_operand" ""))
10576 (const_string "alu")
10578 (const_string "ishift")))
10579 (set (attr "length_immediate")
10581 (ior (eq_attr "type" "alu")
10582 (and (eq_attr "type" "ishift")
10583 (and (match_operand 2 "const1_operand" "")
10584 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10587 (const_string "*")))
10588 (set_attr "mode" "SI")])
10590 (define_insn "*ashlsi3_cmp_zext"
10591 [(set (reg FLAGS_REG)
10593 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10594 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10596 (set (match_operand:DI 0 "register_operand" "=r")
10597 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10599 && (optimize_function_for_size_p (cfun)
10600 || !TARGET_PARTIAL_FLAG_REG_STALL
10601 || (operands[2] == const1_rtx
10603 || TARGET_DOUBLE_WITH_ADD)))
10604 && ix86_match_ccmode (insn, CCGOCmode)
10605 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10607 switch (get_attr_type (insn))
10610 gcc_assert (operands[2] == const1_rtx);
10611 return "add{l}\t%k0, %k0";
10614 if (REG_P (operands[2]))
10615 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10616 else if (operands[2] == const1_rtx
10617 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10618 return "sal{l}\t%k0";
10620 return "sal{l}\t{%2, %k0|%k0, %2}";
10623 [(set (attr "type")
10624 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10626 (match_operand 2 "const1_operand" ""))
10627 (const_string "alu")
10629 (const_string "ishift")))
10630 (set (attr "length_immediate")
10632 (ior (eq_attr "type" "alu")
10633 (and (eq_attr "type" "ishift")
10634 (and (match_operand 2 "const1_operand" "")
10635 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10638 (const_string "*")))
10639 (set_attr "mode" "SI")])
10641 (define_expand "ashlhi3"
10642 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10643 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10644 (match_operand:QI 2 "nonmemory_operand" "")))]
10645 "TARGET_HIMODE_MATH"
10646 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10648 (define_insn "*ashlhi3_1_lea"
10649 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10650 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10651 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10652 (clobber (reg:CC FLAGS_REG))]
10653 "!TARGET_PARTIAL_REG_STALL
10654 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10656 switch (get_attr_type (insn))
10661 gcc_assert (operands[2] == const1_rtx);
10662 return "add{w}\t%0, %0";
10665 if (REG_P (operands[2]))
10666 return "sal{w}\t{%b2, %0|%0, %b2}";
10667 else if (operands[2] == const1_rtx
10668 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10669 return "sal{w}\t%0";
10671 return "sal{w}\t{%2, %0|%0, %2}";
10674 [(set (attr "type")
10675 (cond [(eq_attr "alternative" "1")
10676 (const_string "lea")
10677 (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" "HI,SI")])
10695 (define_insn "*ashlhi3_1"
10696 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10697 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10698 (match_operand:QI 2 "nonmemory_operand" "cI")))
10699 (clobber (reg:CC FLAGS_REG))]
10700 "TARGET_PARTIAL_REG_STALL
10701 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10703 switch (get_attr_type (insn))
10706 gcc_assert (operands[2] == const1_rtx);
10707 return "add{w}\t%0, %0";
10710 if (REG_P (operands[2]))
10711 return "sal{w}\t{%b2, %0|%0, %b2}";
10712 else if (operands[2] == const1_rtx
10713 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10714 return "sal{w}\t%0";
10716 return "sal{w}\t{%2, %0|%0, %2}";
10719 [(set (attr "type")
10720 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10722 (match_operand 0 "register_operand" ""))
10723 (match_operand 2 "const1_operand" ""))
10724 (const_string "alu")
10726 (const_string "ishift")))
10727 (set (attr "length_immediate")
10729 (ior (eq_attr "type" "alu")
10730 (and (eq_attr "type" "ishift")
10731 (and (match_operand 2 "const1_operand" "")
10732 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10735 (const_string "*")))
10736 (set_attr "mode" "HI")])
10738 ;; This pattern can't accept a variable shift count, since shifts by
10739 ;; zero don't affect the flags. We assume that shifts by constant
10740 ;; zero are optimized away.
10741 (define_insn "*ashlhi3_cmp"
10742 [(set (reg FLAGS_REG)
10744 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10745 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10747 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10748 (ashift:HI (match_dup 1) (match_dup 2)))]
10749 "(optimize_function_for_size_p (cfun)
10750 || !TARGET_PARTIAL_FLAG_REG_STALL
10751 || (operands[2] == const1_rtx
10753 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10754 && ix86_match_ccmode (insn, CCGOCmode)
10755 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10757 switch (get_attr_type (insn))
10760 gcc_assert (operands[2] == const1_rtx);
10761 return "add{w}\t%0, %0";
10764 if (REG_P (operands[2]))
10765 return "sal{w}\t{%b2, %0|%0, %b2}";
10766 else if (operands[2] == const1_rtx
10767 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10768 return "sal{w}\t%0";
10770 return "sal{w}\t{%2, %0|%0, %2}";
10773 [(set (attr "type")
10774 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10776 (match_operand 0 "register_operand" ""))
10777 (match_operand 2 "const1_operand" ""))
10778 (const_string "alu")
10780 (const_string "ishift")))
10781 (set (attr "length_immediate")
10783 (ior (eq_attr "type" "alu")
10784 (and (eq_attr "type" "ishift")
10785 (and (match_operand 2 "const1_operand" "")
10786 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10789 (const_string "*")))
10790 (set_attr "mode" "HI")])
10792 (define_insn "*ashlhi3_cconly"
10793 [(set (reg FLAGS_REG)
10795 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10796 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10798 (clobber (match_scratch:HI 0 "=r"))]
10799 "(optimize_function_for_size_p (cfun)
10800 || !TARGET_PARTIAL_FLAG_REG_STALL
10801 || (operands[2] == const1_rtx
10803 || TARGET_DOUBLE_WITH_ADD)))
10804 && ix86_match_ccmode (insn, CCGOCmode)
10805 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10807 switch (get_attr_type (insn))
10810 gcc_assert (operands[2] == const1_rtx);
10811 return "add{w}\t%0, %0";
10814 if (REG_P (operands[2]))
10815 return "sal{w}\t{%b2, %0|%0, %b2}";
10816 else if (operands[2] == const1_rtx
10817 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10818 return "sal{w}\t%0";
10820 return "sal{w}\t{%2, %0|%0, %2}";
10823 [(set (attr "type")
10824 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10826 (match_operand 0 "register_operand" ""))
10827 (match_operand 2 "const1_operand" ""))
10828 (const_string "alu")
10830 (const_string "ishift")))
10831 (set (attr "length_immediate")
10833 (ior (eq_attr "type" "alu")
10834 (and (eq_attr "type" "ishift")
10835 (and (match_operand 2 "const1_operand" "")
10836 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10839 (const_string "*")))
10840 (set_attr "mode" "HI")])
10842 (define_expand "ashlqi3"
10843 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10844 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10845 (match_operand:QI 2 "nonmemory_operand" "")))]
10846 "TARGET_QIMODE_MATH"
10847 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10849 ;; %%% Potential partial reg stall on alternative 2. What to do?
10851 (define_insn "*ashlqi3_1_lea"
10852 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10853 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10854 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10855 (clobber (reg:CC FLAGS_REG))]
10856 "!TARGET_PARTIAL_REG_STALL
10857 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10859 switch (get_attr_type (insn))
10864 gcc_assert (operands[2] == const1_rtx);
10865 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10866 return "add{l}\t%k0, %k0";
10868 return "add{b}\t%0, %0";
10871 if (REG_P (operands[2]))
10873 if (get_attr_mode (insn) == MODE_SI)
10874 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10876 return "sal{b}\t{%b2, %0|%0, %b2}";
10878 else if (operands[2] == const1_rtx
10879 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10881 if (get_attr_mode (insn) == MODE_SI)
10882 return "sal{l}\t%0";
10884 return "sal{b}\t%0";
10888 if (get_attr_mode (insn) == MODE_SI)
10889 return "sal{l}\t{%2, %k0|%k0, %2}";
10891 return "sal{b}\t{%2, %0|%0, %2}";
10895 [(set (attr "type")
10896 (cond [(eq_attr "alternative" "2")
10897 (const_string "lea")
10898 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10900 (match_operand 0 "register_operand" ""))
10901 (match_operand 2 "const1_operand" ""))
10902 (const_string "alu")
10904 (const_string "ishift")))
10905 (set (attr "length_immediate")
10907 (ior (eq_attr "type" "alu")
10908 (and (eq_attr "type" "ishift")
10909 (and (match_operand 2 "const1_operand" "")
10910 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10913 (const_string "*")))
10914 (set_attr "mode" "QI,SI,SI")])
10916 (define_insn "*ashlqi3_1"
10917 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10918 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10919 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10920 (clobber (reg:CC FLAGS_REG))]
10921 "TARGET_PARTIAL_REG_STALL
10922 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10924 switch (get_attr_type (insn))
10927 gcc_assert (operands[2] == const1_rtx);
10928 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10929 return "add{l}\t%k0, %k0";
10931 return "add{b}\t%0, %0";
10934 if (REG_P (operands[2]))
10936 if (get_attr_mode (insn) == MODE_SI)
10937 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10939 return "sal{b}\t{%b2, %0|%0, %b2}";
10941 else if (operands[2] == const1_rtx
10942 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10944 if (get_attr_mode (insn) == MODE_SI)
10945 return "sal{l}\t%0";
10947 return "sal{b}\t%0";
10951 if (get_attr_mode (insn) == MODE_SI)
10952 return "sal{l}\t{%2, %k0|%k0, %2}";
10954 return "sal{b}\t{%2, %0|%0, %2}";
10958 [(set (attr "type")
10959 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10961 (match_operand 0 "register_operand" ""))
10962 (match_operand 2 "const1_operand" ""))
10963 (const_string "alu")
10965 (const_string "ishift")))
10966 (set (attr "length_immediate")
10968 (ior (eq_attr "type" "alu")
10969 (and (eq_attr "type" "ishift")
10970 (and (match_operand 2 "const1_operand" "")
10971 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10974 (const_string "*")))
10975 (set_attr "mode" "QI,SI")])
10977 ;; This pattern can't accept a variable shift count, since shifts by
10978 ;; zero don't affect the flags. We assume that shifts by constant
10979 ;; zero are optimized away.
10980 (define_insn "*ashlqi3_cmp"
10981 [(set (reg FLAGS_REG)
10983 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10984 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10986 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10987 (ashift:QI (match_dup 1) (match_dup 2)))]
10988 "(optimize_function_for_size_p (cfun)
10989 || !TARGET_PARTIAL_FLAG_REG_STALL
10990 || (operands[2] == const1_rtx
10992 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10993 && ix86_match_ccmode (insn, CCGOCmode)
10994 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10996 switch (get_attr_type (insn))
10999 gcc_assert (operands[2] == const1_rtx);
11000 return "add{b}\t%0, %0";
11003 if (REG_P (operands[2]))
11004 return "sal{b}\t{%b2, %0|%0, %b2}";
11005 else if (operands[2] == const1_rtx
11006 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11007 return "sal{b}\t%0";
11009 return "sal{b}\t{%2, %0|%0, %2}";
11012 [(set (attr "type")
11013 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11015 (match_operand 0 "register_operand" ""))
11016 (match_operand 2 "const1_operand" ""))
11017 (const_string "alu")
11019 (const_string "ishift")))
11020 (set (attr "length_immediate")
11022 (ior (eq_attr "type" "alu")
11023 (and (eq_attr "type" "ishift")
11024 (and (match_operand 2 "const1_operand" "")
11025 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11028 (const_string "*")))
11029 (set_attr "mode" "QI")])
11031 (define_insn "*ashlqi3_cconly"
11032 [(set (reg FLAGS_REG)
11034 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11035 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11037 (clobber (match_scratch:QI 0 "=q"))]
11038 "(optimize_function_for_size_p (cfun)
11039 || !TARGET_PARTIAL_FLAG_REG_STALL
11040 || (operands[2] == const1_rtx
11042 || TARGET_DOUBLE_WITH_ADD)))
11043 && ix86_match_ccmode (insn, CCGOCmode)
11044 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11046 switch (get_attr_type (insn))
11049 gcc_assert (operands[2] == const1_rtx);
11050 return "add{b}\t%0, %0";
11053 if (REG_P (operands[2]))
11054 return "sal{b}\t{%b2, %0|%0, %b2}";
11055 else if (operands[2] == const1_rtx
11056 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11057 return "sal{b}\t%0";
11059 return "sal{b}\t{%2, %0|%0, %2}";
11062 [(set (attr "type")
11063 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11065 (match_operand 0 "register_operand" ""))
11066 (match_operand 2 "const1_operand" ""))
11067 (const_string "alu")
11069 (const_string "ishift")))
11070 (set (attr "length_immediate")
11072 (ior (eq_attr "type" "alu")
11073 (and (eq_attr "type" "ishift")
11074 (and (match_operand 2 "const1_operand" "")
11075 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11078 (const_string "*")))
11079 (set_attr "mode" "QI")])
11081 ;; See comment above `ashldi3' about how this works.
11083 (define_expand "ashrti3"
11084 [(set (match_operand:TI 0 "register_operand" "")
11085 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11086 (match_operand:QI 2 "nonmemory_operand" "")))]
11088 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11090 (define_insn "*ashrti3_1"
11091 [(set (match_operand:TI 0 "register_operand" "=r")
11092 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11093 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11094 (clobber (reg:CC FLAGS_REG))]
11097 [(set_attr "type" "multi")])
11100 [(match_scratch:DI 3 "r")
11101 (parallel [(set (match_operand:TI 0 "register_operand" "")
11102 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11103 (match_operand:QI 2 "nonmemory_operand" "")))
11104 (clobber (reg:CC FLAGS_REG))])
11108 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11111 [(set (match_operand:TI 0 "register_operand" "")
11112 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11113 (match_operand:QI 2 "nonmemory_operand" "")))
11114 (clobber (reg:CC FLAGS_REG))]
11115 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11116 ? epilogue_completed : reload_completed)"
11118 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11120 (define_insn "x86_64_shrd"
11121 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11122 (ior:DI (ashiftrt:DI (match_dup 0)
11123 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11124 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11125 (minus:QI (const_int 64) (match_dup 2)))))
11126 (clobber (reg:CC FLAGS_REG))]
11128 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11129 [(set_attr "type" "ishift")
11130 (set_attr "prefix_0f" "1")
11131 (set_attr "mode" "DI")
11132 (set_attr "athlon_decode" "vector")
11133 (set_attr "amdfam10_decode" "vector")])
11135 (define_expand "ashrdi3"
11136 [(set (match_operand:DI 0 "shiftdi_operand" "")
11137 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11138 (match_operand:QI 2 "nonmemory_operand" "")))]
11140 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11142 (define_expand "x86_64_shift_adj_3"
11143 [(use (match_operand:DI 0 "register_operand" ""))
11144 (use (match_operand:DI 1 "register_operand" ""))
11145 (use (match_operand:QI 2 "register_operand" ""))]
11148 rtx label = gen_label_rtx ();
11151 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11153 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11154 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11155 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11156 gen_rtx_LABEL_REF (VOIDmode, label),
11158 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11159 JUMP_LABEL (tmp) = label;
11161 emit_move_insn (operands[0], operands[1]);
11162 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11164 emit_label (label);
11165 LABEL_NUSES (label) = 1;
11170 (define_insn "ashrdi3_63_rex64"
11171 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11172 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11173 (match_operand:DI 2 "const_int_operand" "i,i")))
11174 (clobber (reg:CC FLAGS_REG))]
11175 "TARGET_64BIT && INTVAL (operands[2]) == 63
11176 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11177 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11180 sar{q}\t{%2, %0|%0, %2}"
11181 [(set_attr "type" "imovx,ishift")
11182 (set_attr "prefix_0f" "0,*")
11183 (set_attr "length_immediate" "0,*")
11184 (set_attr "modrm" "0,1")
11185 (set_attr "mode" "DI")])
11187 (define_insn "*ashrdi3_1_one_bit_rex64"
11188 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11189 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11190 (match_operand:QI 2 "const1_operand" "")))
11191 (clobber (reg:CC FLAGS_REG))]
11193 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11194 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11196 [(set_attr "type" "ishift")
11197 (set_attr "length_immediate" "0")
11198 (set_attr "mode" "DI")])
11200 (define_insn "*ashrdi3_1_rex64"
11201 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11202 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11203 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11204 (clobber (reg:CC FLAGS_REG))]
11205 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11207 sar{q}\t{%2, %0|%0, %2}
11208 sar{q}\t{%b2, %0|%0, %b2}"
11209 [(set_attr "type" "ishift")
11210 (set_attr "mode" "DI")])
11212 ;; This pattern can't accept a variable shift count, since shifts by
11213 ;; zero don't affect the flags. We assume that shifts by constant
11214 ;; zero are optimized away.
11215 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11216 [(set (reg FLAGS_REG)
11218 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11219 (match_operand:QI 2 "const1_operand" ""))
11221 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11222 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11224 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11225 && ix86_match_ccmode (insn, CCGOCmode)
11226 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11228 [(set_attr "type" "ishift")
11229 (set_attr "length_immediate" "0")
11230 (set_attr "mode" "DI")])
11232 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11233 [(set (reg FLAGS_REG)
11235 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11236 (match_operand:QI 2 "const1_operand" ""))
11238 (clobber (match_scratch:DI 0 "=r"))]
11240 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11241 && ix86_match_ccmode (insn, CCGOCmode)
11242 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11244 [(set_attr "type" "ishift")
11245 (set_attr "length_immediate" "0")
11246 (set_attr "mode" "DI")])
11248 ;; This pattern can't accept a variable shift count, since shifts by
11249 ;; zero don't affect the flags. We assume that shifts by constant
11250 ;; zero are optimized away.
11251 (define_insn "*ashrdi3_cmp_rex64"
11252 [(set (reg FLAGS_REG)
11254 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11255 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11257 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11258 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11260 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11261 && ix86_match_ccmode (insn, CCGOCmode)
11262 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11263 "sar{q}\t{%2, %0|%0, %2}"
11264 [(set_attr "type" "ishift")
11265 (set_attr "mode" "DI")])
11267 (define_insn "*ashrdi3_cconly_rex64"
11268 [(set (reg FLAGS_REG)
11270 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11271 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11273 (clobber (match_scratch:DI 0 "=r"))]
11275 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11276 && ix86_match_ccmode (insn, CCGOCmode)
11277 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11278 "sar{q}\t{%2, %0|%0, %2}"
11279 [(set_attr "type" "ishift")
11280 (set_attr "mode" "DI")])
11282 (define_insn "*ashrdi3_1"
11283 [(set (match_operand:DI 0 "register_operand" "=r")
11284 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11285 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11286 (clobber (reg:CC FLAGS_REG))]
11289 [(set_attr "type" "multi")])
11291 ;; By default we don't ask for a scratch register, because when DImode
11292 ;; values are manipulated, registers are already at a premium. But if
11293 ;; we have one handy, we won't turn it away.
11295 [(match_scratch:SI 3 "r")
11296 (parallel [(set (match_operand:DI 0 "register_operand" "")
11297 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11298 (match_operand:QI 2 "nonmemory_operand" "")))
11299 (clobber (reg:CC FLAGS_REG))])
11301 "!TARGET_64BIT && TARGET_CMOVE"
11303 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11306 [(set (match_operand:DI 0 "register_operand" "")
11307 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11308 (match_operand:QI 2 "nonmemory_operand" "")))
11309 (clobber (reg:CC FLAGS_REG))]
11310 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11311 ? epilogue_completed : reload_completed)"
11313 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11315 (define_insn "x86_shrd"
11316 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11317 (ior:SI (ashiftrt:SI (match_dup 0)
11318 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11319 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11320 (minus:QI (const_int 32) (match_dup 2)))))
11321 (clobber (reg:CC FLAGS_REG))]
11323 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11324 [(set_attr "type" "ishift")
11325 (set_attr "prefix_0f" "1")
11326 (set_attr "pent_pair" "np")
11327 (set_attr "mode" "SI")])
11329 (define_expand "x86_shift_adj_3"
11330 [(use (match_operand:SI 0 "register_operand" ""))
11331 (use (match_operand:SI 1 "register_operand" ""))
11332 (use (match_operand:QI 2 "register_operand" ""))]
11335 rtx label = gen_label_rtx ();
11338 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11340 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11341 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11342 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11343 gen_rtx_LABEL_REF (VOIDmode, label),
11345 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11346 JUMP_LABEL (tmp) = label;
11348 emit_move_insn (operands[0], operands[1]);
11349 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11351 emit_label (label);
11352 LABEL_NUSES (label) = 1;
11357 (define_expand "ashrsi3_31"
11358 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11359 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11360 (match_operand:SI 2 "const_int_operand" "i,i")))
11361 (clobber (reg:CC FLAGS_REG))])]
11364 (define_insn "*ashrsi3_31"
11365 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11366 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11367 (match_operand:SI 2 "const_int_operand" "i,i")))
11368 (clobber (reg:CC FLAGS_REG))]
11369 "INTVAL (operands[2]) == 31
11370 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11371 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11374 sar{l}\t{%2, %0|%0, %2}"
11375 [(set_attr "type" "imovx,ishift")
11376 (set_attr "prefix_0f" "0,*")
11377 (set_attr "length_immediate" "0,*")
11378 (set_attr "modrm" "0,1")
11379 (set_attr "mode" "SI")])
11381 (define_insn "*ashrsi3_31_zext"
11382 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11383 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11384 (match_operand:SI 2 "const_int_operand" "i,i"))))
11385 (clobber (reg:CC FLAGS_REG))]
11386 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11387 && INTVAL (operands[2]) == 31
11388 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11391 sar{l}\t{%2, %k0|%k0, %2}"
11392 [(set_attr "type" "imovx,ishift")
11393 (set_attr "prefix_0f" "0,*")
11394 (set_attr "length_immediate" "0,*")
11395 (set_attr "modrm" "0,1")
11396 (set_attr "mode" "SI")])
11398 (define_expand "ashrsi3"
11399 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11400 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11401 (match_operand:QI 2 "nonmemory_operand" "")))]
11403 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11405 (define_insn "*ashrsi3_1_one_bit"
11406 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11407 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11408 (match_operand:QI 2 "const1_operand" "")))
11409 (clobber (reg:CC FLAGS_REG))]
11410 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11411 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11413 [(set_attr "type" "ishift")
11414 (set_attr "length_immediate" "0")
11415 (set_attr "mode" "SI")])
11417 (define_insn "*ashrsi3_1_one_bit_zext"
11418 [(set (match_operand:DI 0 "register_operand" "=r")
11419 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11420 (match_operand:QI 2 "const1_operand" ""))))
11421 (clobber (reg:CC FLAGS_REG))]
11423 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11424 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11426 [(set_attr "type" "ishift")
11427 (set_attr "length_immediate" "0")
11428 (set_attr "mode" "SI")])
11430 (define_insn "*ashrsi3_1"
11431 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11432 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11433 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11434 (clobber (reg:CC FLAGS_REG))]
11435 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11437 sar{l}\t{%2, %0|%0, %2}
11438 sar{l}\t{%b2, %0|%0, %b2}"
11439 [(set_attr "type" "ishift")
11440 (set_attr "mode" "SI")])
11442 (define_insn "*ashrsi3_1_zext"
11443 [(set (match_operand:DI 0 "register_operand" "=r,r")
11444 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11445 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11446 (clobber (reg:CC FLAGS_REG))]
11447 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11449 sar{l}\t{%2, %k0|%k0, %2}
11450 sar{l}\t{%b2, %k0|%k0, %b2}"
11451 [(set_attr "type" "ishift")
11452 (set_attr "mode" "SI")])
11454 ;; This pattern can't accept a variable shift count, since shifts by
11455 ;; zero don't affect the flags. We assume that shifts by constant
11456 ;; zero are optimized away.
11457 (define_insn "*ashrsi3_one_bit_cmp"
11458 [(set (reg FLAGS_REG)
11460 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11461 (match_operand:QI 2 "const1_operand" ""))
11463 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11464 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11465 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11466 && ix86_match_ccmode (insn, CCGOCmode)
11467 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11469 [(set_attr "type" "ishift")
11470 (set_attr "length_immediate" "0")
11471 (set_attr "mode" "SI")])
11473 (define_insn "*ashrsi3_one_bit_cconly"
11474 [(set (reg FLAGS_REG)
11476 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11477 (match_operand:QI 2 "const1_operand" ""))
11479 (clobber (match_scratch:SI 0 "=r"))]
11480 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11481 && ix86_match_ccmode (insn, CCGOCmode)
11482 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11484 [(set_attr "type" "ishift")
11485 (set_attr "length_immediate" "0")
11486 (set_attr "mode" "SI")])
11488 (define_insn "*ashrsi3_one_bit_cmp_zext"
11489 [(set (reg FLAGS_REG)
11491 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11492 (match_operand:QI 2 "const1_operand" ""))
11494 (set (match_operand:DI 0 "register_operand" "=r")
11495 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11497 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11498 && ix86_match_ccmode (insn, CCmode)
11499 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11501 [(set_attr "type" "ishift")
11502 (set_attr "length_immediate" "0")
11503 (set_attr "mode" "SI")])
11505 ;; This pattern can't accept a variable shift count, since shifts by
11506 ;; zero don't affect the flags. We assume that shifts by constant
11507 ;; zero are optimized away.
11508 (define_insn "*ashrsi3_cmp"
11509 [(set (reg FLAGS_REG)
11511 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11512 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11514 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11515 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11516 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11517 && ix86_match_ccmode (insn, CCGOCmode)
11518 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11519 "sar{l}\t{%2, %0|%0, %2}"
11520 [(set_attr "type" "ishift")
11521 (set_attr "mode" "SI")])
11523 (define_insn "*ashrsi3_cconly"
11524 [(set (reg FLAGS_REG)
11526 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11527 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11529 (clobber (match_scratch:SI 0 "=r"))]
11530 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11531 && ix86_match_ccmode (insn, CCGOCmode)
11532 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11533 "sar{l}\t{%2, %0|%0, %2}"
11534 [(set_attr "type" "ishift")
11535 (set_attr "mode" "SI")])
11537 (define_insn "*ashrsi3_cmp_zext"
11538 [(set (reg FLAGS_REG)
11540 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11541 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11543 (set (match_operand:DI 0 "register_operand" "=r")
11544 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11546 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11547 && ix86_match_ccmode (insn, CCGOCmode)
11548 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11549 "sar{l}\t{%2, %k0|%k0, %2}"
11550 [(set_attr "type" "ishift")
11551 (set_attr "mode" "SI")])
11553 (define_expand "ashrhi3"
11554 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11555 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11556 (match_operand:QI 2 "nonmemory_operand" "")))]
11557 "TARGET_HIMODE_MATH"
11558 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11560 (define_insn "*ashrhi3_1_one_bit"
11561 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11562 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11563 (match_operand:QI 2 "const1_operand" "")))
11564 (clobber (reg:CC FLAGS_REG))]
11565 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11566 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11568 [(set_attr "type" "ishift")
11569 (set_attr "length_immediate" "0")
11570 (set_attr "mode" "HI")])
11572 (define_insn "*ashrhi3_1"
11573 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11574 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11575 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11576 (clobber (reg:CC FLAGS_REG))]
11577 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11579 sar{w}\t{%2, %0|%0, %2}
11580 sar{w}\t{%b2, %0|%0, %b2}"
11581 [(set_attr "type" "ishift")
11582 (set_attr "mode" "HI")])
11584 ;; This pattern can't accept a variable shift count, since shifts by
11585 ;; zero don't affect the flags. We assume that shifts by constant
11586 ;; zero are optimized away.
11587 (define_insn "*ashrhi3_one_bit_cmp"
11588 [(set (reg FLAGS_REG)
11590 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11591 (match_operand:QI 2 "const1_operand" ""))
11593 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11594 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11595 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11596 && ix86_match_ccmode (insn, CCGOCmode)
11597 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11599 [(set_attr "type" "ishift")
11600 (set_attr "length_immediate" "0")
11601 (set_attr "mode" "HI")])
11603 (define_insn "*ashrhi3_one_bit_cconly"
11604 [(set (reg FLAGS_REG)
11606 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11607 (match_operand:QI 2 "const1_operand" ""))
11609 (clobber (match_scratch:HI 0 "=r"))]
11610 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11611 && ix86_match_ccmode (insn, CCGOCmode)
11612 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11614 [(set_attr "type" "ishift")
11615 (set_attr "length_immediate" "0")
11616 (set_attr "mode" "HI")])
11618 ;; This pattern can't accept a variable shift count, since shifts by
11619 ;; zero don't affect the flags. We assume that shifts by constant
11620 ;; zero are optimized away.
11621 (define_insn "*ashrhi3_cmp"
11622 [(set (reg FLAGS_REG)
11624 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11625 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11627 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11628 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11629 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11630 && ix86_match_ccmode (insn, CCGOCmode)
11631 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11632 "sar{w}\t{%2, %0|%0, %2}"
11633 [(set_attr "type" "ishift")
11634 (set_attr "mode" "HI")])
11636 (define_insn "*ashrhi3_cconly"
11637 [(set (reg FLAGS_REG)
11639 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11640 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11642 (clobber (match_scratch:HI 0 "=r"))]
11643 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11644 && ix86_match_ccmode (insn, CCGOCmode)
11645 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11646 "sar{w}\t{%2, %0|%0, %2}"
11647 [(set_attr "type" "ishift")
11648 (set_attr "mode" "HI")])
11650 (define_expand "ashrqi3"
11651 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11652 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11653 (match_operand:QI 2 "nonmemory_operand" "")))]
11654 "TARGET_QIMODE_MATH"
11655 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11657 (define_insn "*ashrqi3_1_one_bit"
11658 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11659 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11660 (match_operand:QI 2 "const1_operand" "")))
11661 (clobber (reg:CC FLAGS_REG))]
11662 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11663 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11665 [(set_attr "type" "ishift")
11666 (set_attr "length_immediate" "0")
11667 (set_attr "mode" "QI")])
11669 (define_insn "*ashrqi3_1_one_bit_slp"
11670 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11671 (ashiftrt:QI (match_dup 0)
11672 (match_operand:QI 1 "const1_operand" "")))
11673 (clobber (reg:CC FLAGS_REG))]
11674 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11675 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11676 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11678 [(set_attr "type" "ishift1")
11679 (set_attr "length_immediate" "0")
11680 (set_attr "mode" "QI")])
11682 (define_insn "*ashrqi3_1"
11683 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11684 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11685 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11686 (clobber (reg:CC FLAGS_REG))]
11687 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11689 sar{b}\t{%2, %0|%0, %2}
11690 sar{b}\t{%b2, %0|%0, %b2}"
11691 [(set_attr "type" "ishift")
11692 (set_attr "mode" "QI")])
11694 (define_insn "*ashrqi3_1_slp"
11695 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11696 (ashiftrt:QI (match_dup 0)
11697 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11698 (clobber (reg:CC FLAGS_REG))]
11699 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11700 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11702 sar{b}\t{%1, %0|%0, %1}
11703 sar{b}\t{%b1, %0|%0, %b1}"
11704 [(set_attr "type" "ishift1")
11705 (set_attr "mode" "QI")])
11707 ;; This pattern can't accept a variable shift count, since shifts by
11708 ;; zero don't affect the flags. We assume that shifts by constant
11709 ;; zero are optimized away.
11710 (define_insn "*ashrqi3_one_bit_cmp"
11711 [(set (reg FLAGS_REG)
11713 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11714 (match_operand:QI 2 "const1_operand" "I"))
11716 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11717 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11718 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11719 && ix86_match_ccmode (insn, CCGOCmode)
11720 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11722 [(set_attr "type" "ishift")
11723 (set_attr "length_immediate" "0")
11724 (set_attr "mode" "QI")])
11726 (define_insn "*ashrqi3_one_bit_cconly"
11727 [(set (reg FLAGS_REG)
11729 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11730 (match_operand:QI 2 "const1_operand" ""))
11732 (clobber (match_scratch:QI 0 "=q"))]
11733 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11734 && ix86_match_ccmode (insn, CCGOCmode)
11735 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11737 [(set_attr "type" "ishift")
11738 (set_attr "length_immediate" "0")
11739 (set_attr "mode" "QI")])
11741 ;; This pattern can't accept a variable shift count, since shifts by
11742 ;; zero don't affect the flags. We assume that shifts by constant
11743 ;; zero are optimized away.
11744 (define_insn "*ashrqi3_cmp"
11745 [(set (reg FLAGS_REG)
11747 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11748 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11750 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11751 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11752 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11753 && ix86_match_ccmode (insn, CCGOCmode)
11754 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11755 "sar{b}\t{%2, %0|%0, %2}"
11756 [(set_attr "type" "ishift")
11757 (set_attr "mode" "QI")])
11759 (define_insn "*ashrqi3_cconly"
11760 [(set (reg FLAGS_REG)
11762 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11763 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11765 (clobber (match_scratch:QI 0 "=q"))]
11766 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11767 && ix86_match_ccmode (insn, CCGOCmode)
11768 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11769 "sar{b}\t{%2, %0|%0, %2}"
11770 [(set_attr "type" "ishift")
11771 (set_attr "mode" "QI")])
11774 ;; Logical shift instructions
11776 ;; See comment above `ashldi3' about how this works.
11778 (define_expand "lshrti3"
11779 [(set (match_operand:TI 0 "register_operand" "")
11780 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11781 (match_operand:QI 2 "nonmemory_operand" "")))]
11783 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
11785 ;; This pattern must be defined before *lshrti3_1 to prevent
11786 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
11788 (define_insn "*avx_lshrti3"
11789 [(set (match_operand:TI 0 "register_operand" "=x")
11790 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
11791 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11794 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11795 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
11797 [(set_attr "type" "sseishft")
11798 (set_attr "prefix" "vex")
11799 (set_attr "length_immediate" "1")
11800 (set_attr "mode" "TI")])
11802 (define_insn "sse2_lshrti3"
11803 [(set (match_operand:TI 0 "register_operand" "=x")
11804 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11805 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11808 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11809 return "psrldq\t{%2, %0|%0, %2}";
11811 [(set_attr "type" "sseishft")
11812 (set_attr "prefix_data16" "1")
11813 (set_attr "length_immediate" "1")
11814 (set_attr "mode" "TI")])
11816 (define_insn "*lshrti3_1"
11817 [(set (match_operand:TI 0 "register_operand" "=r")
11818 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11819 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11820 (clobber (reg:CC FLAGS_REG))]
11823 [(set_attr "type" "multi")])
11826 [(match_scratch:DI 3 "r")
11827 (parallel [(set (match_operand:TI 0 "register_operand" "")
11828 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11829 (match_operand:QI 2 "nonmemory_operand" "")))
11830 (clobber (reg:CC FLAGS_REG))])
11834 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11837 [(set (match_operand:TI 0 "register_operand" "")
11838 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11839 (match_operand:QI 2 "nonmemory_operand" "")))
11840 (clobber (reg:CC FLAGS_REG))]
11841 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11842 ? epilogue_completed : reload_completed)"
11844 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11846 (define_expand "lshrdi3"
11847 [(set (match_operand:DI 0 "shiftdi_operand" "")
11848 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11849 (match_operand:QI 2 "nonmemory_operand" "")))]
11851 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11853 (define_insn "*lshrdi3_1_one_bit_rex64"
11854 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11855 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11856 (match_operand:QI 2 "const1_operand" "")))
11857 (clobber (reg:CC FLAGS_REG))]
11859 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11860 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11862 [(set_attr "type" "ishift")
11863 (set_attr "length_immediate" "0")
11864 (set_attr "mode" "DI")])
11866 (define_insn "*lshrdi3_1_rex64"
11867 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11868 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11869 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11870 (clobber (reg:CC FLAGS_REG))]
11871 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11873 shr{q}\t{%2, %0|%0, %2}
11874 shr{q}\t{%b2, %0|%0, %b2}"
11875 [(set_attr "type" "ishift")
11876 (set_attr "mode" "DI")])
11878 ;; This pattern can't accept a variable shift count, since shifts by
11879 ;; zero don't affect the flags. We assume that shifts by constant
11880 ;; zero are optimized away.
11881 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11882 [(set (reg FLAGS_REG)
11884 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11885 (match_operand:QI 2 "const1_operand" ""))
11887 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11888 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11890 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11891 && ix86_match_ccmode (insn, CCGOCmode)
11892 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11894 [(set_attr "type" "ishift")
11895 (set_attr "length_immediate" "0")
11896 (set_attr "mode" "DI")])
11898 (define_insn "*lshrdi3_cconly_one_bit_rex64"
11899 [(set (reg FLAGS_REG)
11901 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11902 (match_operand:QI 2 "const1_operand" ""))
11904 (clobber (match_scratch:DI 0 "=r"))]
11906 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11907 && ix86_match_ccmode (insn, CCGOCmode)
11908 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11910 [(set_attr "type" "ishift")
11911 (set_attr "length_immediate" "0")
11912 (set_attr "mode" "DI")])
11914 ;; This pattern can't accept a variable shift count, since shifts by
11915 ;; zero don't affect the flags. We assume that shifts by constant
11916 ;; zero are optimized away.
11917 (define_insn "*lshrdi3_cmp_rex64"
11918 [(set (reg FLAGS_REG)
11920 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11921 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11923 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11924 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11926 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11927 && ix86_match_ccmode (insn, CCGOCmode)
11928 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11929 "shr{q}\t{%2, %0|%0, %2}"
11930 [(set_attr "type" "ishift")
11931 (set_attr "mode" "DI")])
11933 (define_insn "*lshrdi3_cconly_rex64"
11934 [(set (reg FLAGS_REG)
11936 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11937 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11939 (clobber (match_scratch:DI 0 "=r"))]
11941 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11942 && ix86_match_ccmode (insn, CCGOCmode)
11943 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11944 "shr{q}\t{%2, %0|%0, %2}"
11945 [(set_attr "type" "ishift")
11946 (set_attr "mode" "DI")])
11948 (define_insn "*lshrdi3_1"
11949 [(set (match_operand:DI 0 "register_operand" "=r")
11950 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11951 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11952 (clobber (reg:CC FLAGS_REG))]
11955 [(set_attr "type" "multi")])
11957 ;; By default we don't ask for a scratch register, because when DImode
11958 ;; values are manipulated, registers are already at a premium. But if
11959 ;; we have one handy, we won't turn it away.
11961 [(match_scratch:SI 3 "r")
11962 (parallel [(set (match_operand:DI 0 "register_operand" "")
11963 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11964 (match_operand:QI 2 "nonmemory_operand" "")))
11965 (clobber (reg:CC FLAGS_REG))])
11967 "!TARGET_64BIT && TARGET_CMOVE"
11969 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11972 [(set (match_operand:DI 0 "register_operand" "")
11973 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11974 (match_operand:QI 2 "nonmemory_operand" "")))
11975 (clobber (reg:CC FLAGS_REG))]
11976 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11977 ? epilogue_completed : reload_completed)"
11979 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11981 (define_expand "lshrsi3"
11982 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11983 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11984 (match_operand:QI 2 "nonmemory_operand" "")))]
11986 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11988 (define_insn "*lshrsi3_1_one_bit"
11989 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11990 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11991 (match_operand:QI 2 "const1_operand" "")))
11992 (clobber (reg:CC FLAGS_REG))]
11993 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11994 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11996 [(set_attr "type" "ishift")
11997 (set_attr "length_immediate" "0")
11998 (set_attr "mode" "SI")])
12000 (define_insn "*lshrsi3_1_one_bit_zext"
12001 [(set (match_operand:DI 0 "register_operand" "=r")
12002 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12003 (match_operand:QI 2 "const1_operand" "")))
12004 (clobber (reg:CC FLAGS_REG))]
12006 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12007 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12009 [(set_attr "type" "ishift")
12010 (set_attr "length_immediate" "0")
12011 (set_attr "mode" "SI")])
12013 (define_insn "*lshrsi3_1"
12014 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12015 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12016 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12017 (clobber (reg:CC FLAGS_REG))]
12018 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12020 shr{l}\t{%2, %0|%0, %2}
12021 shr{l}\t{%b2, %0|%0, %b2}"
12022 [(set_attr "type" "ishift")
12023 (set_attr "mode" "SI")])
12025 (define_insn "*lshrsi3_1_zext"
12026 [(set (match_operand:DI 0 "register_operand" "=r,r")
12028 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12029 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12030 (clobber (reg:CC FLAGS_REG))]
12031 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12033 shr{l}\t{%2, %k0|%k0, %2}
12034 shr{l}\t{%b2, %k0|%k0, %b2}"
12035 [(set_attr "type" "ishift")
12036 (set_attr "mode" "SI")])
12038 ;; This pattern can't accept a variable shift count, since shifts by
12039 ;; zero don't affect the flags. We assume that shifts by constant
12040 ;; zero are optimized away.
12041 (define_insn "*lshrsi3_one_bit_cmp"
12042 [(set (reg FLAGS_REG)
12044 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12045 (match_operand:QI 2 "const1_operand" ""))
12047 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12048 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12049 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12050 && ix86_match_ccmode (insn, CCGOCmode)
12051 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12053 [(set_attr "type" "ishift")
12054 (set_attr "length_immediate" "0")
12055 (set_attr "mode" "SI")])
12057 (define_insn "*lshrsi3_one_bit_cconly"
12058 [(set (reg FLAGS_REG)
12060 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12061 (match_operand:QI 2 "const1_operand" ""))
12063 (clobber (match_scratch:SI 0 "=r"))]
12064 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12065 && ix86_match_ccmode (insn, CCGOCmode)
12066 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12068 [(set_attr "type" "ishift")
12069 (set_attr "length_immediate" "0")
12070 (set_attr "mode" "SI")])
12072 (define_insn "*lshrsi3_cmp_one_bit_zext"
12073 [(set (reg FLAGS_REG)
12075 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12076 (match_operand:QI 2 "const1_operand" ""))
12078 (set (match_operand:DI 0 "register_operand" "=r")
12079 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12081 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12082 && ix86_match_ccmode (insn, CCGOCmode)
12083 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12085 [(set_attr "type" "ishift")
12086 (set_attr "length_immediate" "0")
12087 (set_attr "mode" "SI")])
12089 ;; This pattern can't accept a variable shift count, since shifts by
12090 ;; zero don't affect the flags. We assume that shifts by constant
12091 ;; zero are optimized away.
12092 (define_insn "*lshrsi3_cmp"
12093 [(set (reg FLAGS_REG)
12095 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12096 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12098 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12099 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12100 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12101 && ix86_match_ccmode (insn, CCGOCmode)
12102 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12103 "shr{l}\t{%2, %0|%0, %2}"
12104 [(set_attr "type" "ishift")
12105 (set_attr "mode" "SI")])
12107 (define_insn "*lshrsi3_cconly"
12108 [(set (reg FLAGS_REG)
12110 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12111 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12113 (clobber (match_scratch:SI 0 "=r"))]
12114 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12115 && ix86_match_ccmode (insn, CCGOCmode)
12116 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12117 "shr{l}\t{%2, %0|%0, %2}"
12118 [(set_attr "type" "ishift")
12119 (set_attr "mode" "SI")])
12121 (define_insn "*lshrsi3_cmp_zext"
12122 [(set (reg FLAGS_REG)
12124 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12125 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12127 (set (match_operand:DI 0 "register_operand" "=r")
12128 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12130 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12131 && ix86_match_ccmode (insn, CCGOCmode)
12132 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12133 "shr{l}\t{%2, %k0|%k0, %2}"
12134 [(set_attr "type" "ishift")
12135 (set_attr "mode" "SI")])
12137 (define_expand "lshrhi3"
12138 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12139 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12140 (match_operand:QI 2 "nonmemory_operand" "")))]
12141 "TARGET_HIMODE_MATH"
12142 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12144 (define_insn "*lshrhi3_1_one_bit"
12145 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12146 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12147 (match_operand:QI 2 "const1_operand" "")))
12148 (clobber (reg:CC FLAGS_REG))]
12149 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12150 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12152 [(set_attr "type" "ishift")
12153 (set_attr "length_immediate" "0")
12154 (set_attr "mode" "HI")])
12156 (define_insn "*lshrhi3_1"
12157 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12158 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12159 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12160 (clobber (reg:CC FLAGS_REG))]
12161 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12163 shr{w}\t{%2, %0|%0, %2}
12164 shr{w}\t{%b2, %0|%0, %b2}"
12165 [(set_attr "type" "ishift")
12166 (set_attr "mode" "HI")])
12168 ;; This pattern can't accept a variable shift count, since shifts by
12169 ;; zero don't affect the flags. We assume that shifts by constant
12170 ;; zero are optimized away.
12171 (define_insn "*lshrhi3_one_bit_cmp"
12172 [(set (reg FLAGS_REG)
12174 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12175 (match_operand:QI 2 "const1_operand" ""))
12177 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12178 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12179 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12180 && ix86_match_ccmode (insn, CCGOCmode)
12181 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12183 [(set_attr "type" "ishift")
12184 (set_attr "length_immediate" "0")
12185 (set_attr "mode" "HI")])
12187 (define_insn "*lshrhi3_one_bit_cconly"
12188 [(set (reg FLAGS_REG)
12190 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12191 (match_operand:QI 2 "const1_operand" ""))
12193 (clobber (match_scratch:HI 0 "=r"))]
12194 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12195 && ix86_match_ccmode (insn, CCGOCmode)
12196 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12198 [(set_attr "type" "ishift")
12199 (set_attr "length_immediate" "0")
12200 (set_attr "mode" "HI")])
12202 ;; This pattern can't accept a variable shift count, since shifts by
12203 ;; zero don't affect the flags. We assume that shifts by constant
12204 ;; zero are optimized away.
12205 (define_insn "*lshrhi3_cmp"
12206 [(set (reg FLAGS_REG)
12208 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12209 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12211 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12212 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12213 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12214 && ix86_match_ccmode (insn, CCGOCmode)
12215 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12216 "shr{w}\t{%2, %0|%0, %2}"
12217 [(set_attr "type" "ishift")
12218 (set_attr "mode" "HI")])
12220 (define_insn "*lshrhi3_cconly"
12221 [(set (reg FLAGS_REG)
12223 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12224 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12226 (clobber (match_scratch:HI 0 "=r"))]
12227 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12228 && ix86_match_ccmode (insn, CCGOCmode)
12229 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12230 "shr{w}\t{%2, %0|%0, %2}"
12231 [(set_attr "type" "ishift")
12232 (set_attr "mode" "HI")])
12234 (define_expand "lshrqi3"
12235 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12236 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12237 (match_operand:QI 2 "nonmemory_operand" "")))]
12238 "TARGET_QIMODE_MATH"
12239 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12241 (define_insn "*lshrqi3_1_one_bit"
12242 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12243 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12244 (match_operand:QI 2 "const1_operand" "")))
12245 (clobber (reg:CC FLAGS_REG))]
12246 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12247 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12249 [(set_attr "type" "ishift")
12250 (set_attr "length_immediate" "0")
12251 (set_attr "mode" "QI")])
12253 (define_insn "*lshrqi3_1_one_bit_slp"
12254 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12255 (lshiftrt:QI (match_dup 0)
12256 (match_operand:QI 1 "const1_operand" "")))
12257 (clobber (reg:CC FLAGS_REG))]
12258 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12259 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12261 [(set_attr "type" "ishift1")
12262 (set_attr "length_immediate" "0")
12263 (set_attr "mode" "QI")])
12265 (define_insn "*lshrqi3_1"
12266 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12267 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12268 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12269 (clobber (reg:CC FLAGS_REG))]
12270 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12272 shr{b}\t{%2, %0|%0, %2}
12273 shr{b}\t{%b2, %0|%0, %b2}"
12274 [(set_attr "type" "ishift")
12275 (set_attr "mode" "QI")])
12277 (define_insn "*lshrqi3_1_slp"
12278 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12279 (lshiftrt:QI (match_dup 0)
12280 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12281 (clobber (reg:CC FLAGS_REG))]
12282 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12283 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12285 shr{b}\t{%1, %0|%0, %1}
12286 shr{b}\t{%b1, %0|%0, %b1}"
12287 [(set_attr "type" "ishift1")
12288 (set_attr "mode" "QI")])
12290 ;; This pattern can't accept a variable shift count, since shifts by
12291 ;; zero don't affect the flags. We assume that shifts by constant
12292 ;; zero are optimized away.
12293 (define_insn "*lshrqi2_one_bit_cmp"
12294 [(set (reg FLAGS_REG)
12296 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12297 (match_operand:QI 2 "const1_operand" ""))
12299 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12300 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12301 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12302 && ix86_match_ccmode (insn, CCGOCmode)
12303 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12305 [(set_attr "type" "ishift")
12306 (set_attr "length_immediate" "0")
12307 (set_attr "mode" "QI")])
12309 (define_insn "*lshrqi2_one_bit_cconly"
12310 [(set (reg FLAGS_REG)
12312 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12313 (match_operand:QI 2 "const1_operand" ""))
12315 (clobber (match_scratch:QI 0 "=q"))]
12316 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12317 && ix86_match_ccmode (insn, CCGOCmode)
12318 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12320 [(set_attr "type" "ishift")
12321 (set_attr "length_immediate" "0")
12322 (set_attr "mode" "QI")])
12324 ;; This pattern can't accept a variable shift count, since shifts by
12325 ;; zero don't affect the flags. We assume that shifts by constant
12326 ;; zero are optimized away.
12327 (define_insn "*lshrqi2_cmp"
12328 [(set (reg FLAGS_REG)
12330 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12331 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12333 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12334 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12335 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12336 && ix86_match_ccmode (insn, CCGOCmode)
12337 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12338 "shr{b}\t{%2, %0|%0, %2}"
12339 [(set_attr "type" "ishift")
12340 (set_attr "mode" "QI")])
12342 (define_insn "*lshrqi2_cconly"
12343 [(set (reg FLAGS_REG)
12345 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12346 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12348 (clobber (match_scratch:QI 0 "=q"))]
12349 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12350 && ix86_match_ccmode (insn, CCGOCmode)
12351 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12352 "shr{b}\t{%2, %0|%0, %2}"
12353 [(set_attr "type" "ishift")
12354 (set_attr "mode" "QI")])
12356 ;; Rotate instructions
12358 (define_expand "rotldi3"
12359 [(set (match_operand:DI 0 "shiftdi_operand" "")
12360 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12361 (match_operand:QI 2 "nonmemory_operand" "")))]
12366 ix86_expand_binary_operator (ROTATE, DImode, operands);
12369 if (!const_1_to_31_operand (operands[2], VOIDmode))
12371 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12375 ;; Implement rotation using two double-precision shift instructions
12376 ;; and a scratch register.
12377 (define_insn_and_split "ix86_rotldi3"
12378 [(set (match_operand:DI 0 "register_operand" "=r")
12379 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12380 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12381 (clobber (reg:CC FLAGS_REG))
12382 (clobber (match_scratch:SI 3 "=&r"))]
12385 "&& reload_completed"
12386 [(set (match_dup 3) (match_dup 4))
12388 [(set (match_dup 4)
12389 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12390 (lshiftrt:SI (match_dup 5)
12391 (minus:QI (const_int 32) (match_dup 2)))))
12392 (clobber (reg:CC FLAGS_REG))])
12394 [(set (match_dup 5)
12395 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12396 (lshiftrt:SI (match_dup 3)
12397 (minus:QI (const_int 32) (match_dup 2)))))
12398 (clobber (reg:CC FLAGS_REG))])]
12399 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12401 (define_insn "*rotlsi3_1_one_bit_rex64"
12402 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12403 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12404 (match_operand:QI 2 "const1_operand" "")))
12405 (clobber (reg:CC FLAGS_REG))]
12407 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12408 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12410 [(set_attr "type" "rotate")
12411 (set_attr "length_immediate" "0")
12412 (set_attr "mode" "DI")])
12414 (define_insn "*rotldi3_1_rex64"
12415 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12416 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12417 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12418 (clobber (reg:CC FLAGS_REG))]
12419 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12421 rol{q}\t{%2, %0|%0, %2}
12422 rol{q}\t{%b2, %0|%0, %b2}"
12423 [(set_attr "type" "rotate")
12424 (set_attr "mode" "DI")])
12426 (define_expand "rotlsi3"
12427 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12428 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12429 (match_operand:QI 2 "nonmemory_operand" "")))]
12431 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12433 (define_insn "*rotlsi3_1_one_bit"
12434 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12435 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12436 (match_operand:QI 2 "const1_operand" "")))
12437 (clobber (reg:CC FLAGS_REG))]
12438 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12439 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12441 [(set_attr "type" "rotate")
12442 (set_attr "length_immediate" "0")
12443 (set_attr "mode" "SI")])
12445 (define_insn "*rotlsi3_1_one_bit_zext"
12446 [(set (match_operand:DI 0 "register_operand" "=r")
12448 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12449 (match_operand:QI 2 "const1_operand" ""))))
12450 (clobber (reg:CC FLAGS_REG))]
12452 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12453 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12455 [(set_attr "type" "rotate")
12456 (set_attr "length_immediate" "0")
12457 (set_attr "mode" "SI")])
12459 (define_insn "*rotlsi3_1"
12460 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12461 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12462 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12463 (clobber (reg:CC FLAGS_REG))]
12464 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12466 rol{l}\t{%2, %0|%0, %2}
12467 rol{l}\t{%b2, %0|%0, %b2}"
12468 [(set_attr "type" "rotate")
12469 (set_attr "mode" "SI")])
12471 (define_insn "*rotlsi3_1_zext"
12472 [(set (match_operand:DI 0 "register_operand" "=r,r")
12474 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12475 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12476 (clobber (reg:CC FLAGS_REG))]
12477 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12479 rol{l}\t{%2, %k0|%k0, %2}
12480 rol{l}\t{%b2, %k0|%k0, %b2}"
12481 [(set_attr "type" "rotate")
12482 (set_attr "mode" "SI")])
12484 (define_expand "rotlhi3"
12485 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12486 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12487 (match_operand:QI 2 "nonmemory_operand" "")))]
12488 "TARGET_HIMODE_MATH"
12489 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12491 (define_insn "*rotlhi3_1_one_bit"
12492 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12493 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12494 (match_operand:QI 2 "const1_operand" "")))
12495 (clobber (reg:CC FLAGS_REG))]
12496 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12497 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12499 [(set_attr "type" "rotate")
12500 (set_attr "length_immediate" "0")
12501 (set_attr "mode" "HI")])
12503 (define_insn "*rotlhi3_1"
12504 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12505 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12506 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12507 (clobber (reg:CC FLAGS_REG))]
12508 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12510 rol{w}\t{%2, %0|%0, %2}
12511 rol{w}\t{%b2, %0|%0, %b2}"
12512 [(set_attr "type" "rotate")
12513 (set_attr "mode" "HI")])
12516 [(set (match_operand:HI 0 "register_operand" "")
12517 (rotate:HI (match_dup 0) (const_int 8)))
12518 (clobber (reg:CC FLAGS_REG))]
12520 [(parallel [(set (strict_low_part (match_dup 0))
12521 (bswap:HI (match_dup 0)))
12522 (clobber (reg:CC FLAGS_REG))])]
12525 (define_expand "rotlqi3"
12526 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12527 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12528 (match_operand:QI 2 "nonmemory_operand" "")))]
12529 "TARGET_QIMODE_MATH"
12530 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12532 (define_insn "*rotlqi3_1_one_bit_slp"
12533 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12534 (rotate:QI (match_dup 0)
12535 (match_operand:QI 1 "const1_operand" "")))
12536 (clobber (reg:CC FLAGS_REG))]
12537 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12538 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12540 [(set_attr "type" "rotate1")
12541 (set_attr "length_immediate" "0")
12542 (set_attr "mode" "QI")])
12544 (define_insn "*rotlqi3_1_one_bit"
12545 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12546 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12547 (match_operand:QI 2 "const1_operand" "")))
12548 (clobber (reg:CC FLAGS_REG))]
12549 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12550 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12552 [(set_attr "type" "rotate")
12553 (set_attr "length_immediate" "0")
12554 (set_attr "mode" "QI")])
12556 (define_insn "*rotlqi3_1_slp"
12557 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12558 (rotate:QI (match_dup 0)
12559 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12560 (clobber (reg:CC FLAGS_REG))]
12561 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12562 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12564 rol{b}\t{%1, %0|%0, %1}
12565 rol{b}\t{%b1, %0|%0, %b1}"
12566 [(set_attr "type" "rotate1")
12567 (set_attr "mode" "QI")])
12569 (define_insn "*rotlqi3_1"
12570 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12571 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12572 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12573 (clobber (reg:CC FLAGS_REG))]
12574 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12576 rol{b}\t{%2, %0|%0, %2}
12577 rol{b}\t{%b2, %0|%0, %b2}"
12578 [(set_attr "type" "rotate")
12579 (set_attr "mode" "QI")])
12581 (define_expand "rotrdi3"
12582 [(set (match_operand:DI 0 "shiftdi_operand" "")
12583 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12584 (match_operand:QI 2 "nonmemory_operand" "")))]
12589 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12592 if (!const_1_to_31_operand (operands[2], VOIDmode))
12594 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12598 ;; Implement rotation using two double-precision shift instructions
12599 ;; and a scratch register.
12600 (define_insn_and_split "ix86_rotrdi3"
12601 [(set (match_operand:DI 0 "register_operand" "=r")
12602 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12603 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12604 (clobber (reg:CC FLAGS_REG))
12605 (clobber (match_scratch:SI 3 "=&r"))]
12608 "&& reload_completed"
12609 [(set (match_dup 3) (match_dup 4))
12611 [(set (match_dup 4)
12612 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12613 (ashift:SI (match_dup 5)
12614 (minus:QI (const_int 32) (match_dup 2)))))
12615 (clobber (reg:CC FLAGS_REG))])
12617 [(set (match_dup 5)
12618 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12619 (ashift:SI (match_dup 3)
12620 (minus:QI (const_int 32) (match_dup 2)))))
12621 (clobber (reg:CC FLAGS_REG))])]
12622 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12624 (define_insn "*rotrdi3_1_one_bit_rex64"
12625 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12626 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12627 (match_operand:QI 2 "const1_operand" "")))
12628 (clobber (reg:CC FLAGS_REG))]
12630 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12631 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12633 [(set_attr "type" "rotate")
12634 (set_attr "length_immediate" "0")
12635 (set_attr "mode" "DI")])
12637 (define_insn "*rotrdi3_1_rex64"
12638 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12639 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12640 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12641 (clobber (reg:CC FLAGS_REG))]
12642 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12644 ror{q}\t{%2, %0|%0, %2}
12645 ror{q}\t{%b2, %0|%0, %b2}"
12646 [(set_attr "type" "rotate")
12647 (set_attr "mode" "DI")])
12649 (define_expand "rotrsi3"
12650 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12651 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12652 (match_operand:QI 2 "nonmemory_operand" "")))]
12654 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12656 (define_insn "*rotrsi3_1_one_bit"
12657 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12658 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12659 (match_operand:QI 2 "const1_operand" "")))
12660 (clobber (reg:CC FLAGS_REG))]
12661 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12662 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12664 [(set_attr "type" "rotate")
12665 (set_attr "length_immediate" "0")
12666 (set_attr "mode" "SI")])
12668 (define_insn "*rotrsi3_1_one_bit_zext"
12669 [(set (match_operand:DI 0 "register_operand" "=r")
12671 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12672 (match_operand:QI 2 "const1_operand" ""))))
12673 (clobber (reg:CC FLAGS_REG))]
12675 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12676 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12678 [(set_attr "type" "rotate")
12679 (set_attr "length_immediate" "0")
12680 (set_attr "mode" "SI")])
12682 (define_insn "*rotrsi3_1"
12683 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12684 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12685 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12686 (clobber (reg:CC FLAGS_REG))]
12687 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12689 ror{l}\t{%2, %0|%0, %2}
12690 ror{l}\t{%b2, %0|%0, %b2}"
12691 [(set_attr "type" "rotate")
12692 (set_attr "mode" "SI")])
12694 (define_insn "*rotrsi3_1_zext"
12695 [(set (match_operand:DI 0 "register_operand" "=r,r")
12697 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12698 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12699 (clobber (reg:CC FLAGS_REG))]
12700 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12702 ror{l}\t{%2, %k0|%k0, %2}
12703 ror{l}\t{%b2, %k0|%k0, %b2}"
12704 [(set_attr "type" "rotate")
12705 (set_attr "mode" "SI")])
12707 (define_expand "rotrhi3"
12708 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12709 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12710 (match_operand:QI 2 "nonmemory_operand" "")))]
12711 "TARGET_HIMODE_MATH"
12712 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12714 (define_insn "*rotrhi3_one_bit"
12715 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12716 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12717 (match_operand:QI 2 "const1_operand" "")))
12718 (clobber (reg:CC FLAGS_REG))]
12719 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12720 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12722 [(set_attr "type" "rotate")
12723 (set_attr "length_immediate" "0")
12724 (set_attr "mode" "HI")])
12726 (define_insn "*rotrhi3_1"
12727 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12728 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12729 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12730 (clobber (reg:CC FLAGS_REG))]
12731 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12733 ror{w}\t{%2, %0|%0, %2}
12734 ror{w}\t{%b2, %0|%0, %b2}"
12735 [(set_attr "type" "rotate")
12736 (set_attr "mode" "HI")])
12739 [(set (match_operand:HI 0 "register_operand" "")
12740 (rotatert:HI (match_dup 0) (const_int 8)))
12741 (clobber (reg:CC FLAGS_REG))]
12743 [(parallel [(set (strict_low_part (match_dup 0))
12744 (bswap:HI (match_dup 0)))
12745 (clobber (reg:CC FLAGS_REG))])]
12748 (define_expand "rotrqi3"
12749 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12750 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12751 (match_operand:QI 2 "nonmemory_operand" "")))]
12752 "TARGET_QIMODE_MATH"
12753 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12755 (define_insn "*rotrqi3_1_one_bit"
12756 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12757 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12758 (match_operand:QI 2 "const1_operand" "")))
12759 (clobber (reg:CC FLAGS_REG))]
12760 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12761 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12763 [(set_attr "type" "rotate")
12764 (set_attr "length_immediate" "0")
12765 (set_attr "mode" "QI")])
12767 (define_insn "*rotrqi3_1_one_bit_slp"
12768 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12769 (rotatert:QI (match_dup 0)
12770 (match_operand:QI 1 "const1_operand" "")))
12771 (clobber (reg:CC FLAGS_REG))]
12772 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12773 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12775 [(set_attr "type" "rotate1")
12776 (set_attr "length_immediate" "0")
12777 (set_attr "mode" "QI")])
12779 (define_insn "*rotrqi3_1"
12780 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12781 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12782 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12783 (clobber (reg:CC FLAGS_REG))]
12784 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12786 ror{b}\t{%2, %0|%0, %2}
12787 ror{b}\t{%b2, %0|%0, %b2}"
12788 [(set_attr "type" "rotate")
12789 (set_attr "mode" "QI")])
12791 (define_insn "*rotrqi3_1_slp"
12792 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12793 (rotatert:QI (match_dup 0)
12794 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12795 (clobber (reg:CC FLAGS_REG))]
12796 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12797 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12799 ror{b}\t{%1, %0|%0, %1}
12800 ror{b}\t{%b1, %0|%0, %b1}"
12801 [(set_attr "type" "rotate1")
12802 (set_attr "mode" "QI")])
12804 ;; Bit set / bit test instructions
12806 (define_expand "extv"
12807 [(set (match_operand:SI 0 "register_operand" "")
12808 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12809 (match_operand:SI 2 "const8_operand" "")
12810 (match_operand:SI 3 "const8_operand" "")))]
12813 /* Handle extractions from %ah et al. */
12814 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12817 /* From mips.md: extract_bit_field doesn't verify that our source
12818 matches the predicate, so check it again here. */
12819 if (! ext_register_operand (operands[1], VOIDmode))
12823 (define_expand "extzv"
12824 [(set (match_operand:SI 0 "register_operand" "")
12825 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12826 (match_operand:SI 2 "const8_operand" "")
12827 (match_operand:SI 3 "const8_operand" "")))]
12830 /* Handle extractions from %ah et al. */
12831 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12834 /* From mips.md: extract_bit_field doesn't verify that our source
12835 matches the predicate, so check it again here. */
12836 if (! ext_register_operand (operands[1], VOIDmode))
12840 (define_expand "insv"
12841 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12842 (match_operand 1 "const8_operand" "")
12843 (match_operand 2 "const8_operand" ""))
12844 (match_operand 3 "register_operand" ""))]
12847 /* Handle insertions to %ah et al. */
12848 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12851 /* From mips.md: insert_bit_field doesn't verify that our source
12852 matches the predicate, so check it again here. */
12853 if (! ext_register_operand (operands[0], VOIDmode))
12857 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12859 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12864 ;; %%% bts, btr, btc, bt.
12865 ;; In general these instructions are *slow* when applied to memory,
12866 ;; since they enforce atomic operation. When applied to registers,
12867 ;; it depends on the cpu implementation. They're never faster than
12868 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12869 ;; no point. But in 64-bit, we can't hold the relevant immediates
12870 ;; within the instruction itself, so operating on bits in the high
12871 ;; 32-bits of a register becomes easier.
12873 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12874 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12875 ;; negdf respectively, so they can never be disabled entirely.
12877 (define_insn "*btsq"
12878 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12880 (match_operand:DI 1 "const_0_to_63_operand" ""))
12882 (clobber (reg:CC FLAGS_REG))]
12883 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12884 "bts{q}\t{%1, %0|%0, %1}"
12885 [(set_attr "type" "alu1")
12886 (set_attr "prefix_0f" "1")
12887 (set_attr "mode" "DI")])
12889 (define_insn "*btrq"
12890 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12892 (match_operand:DI 1 "const_0_to_63_operand" ""))
12894 (clobber (reg:CC FLAGS_REG))]
12895 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12896 "btr{q}\t{%1, %0|%0, %1}"
12897 [(set_attr "type" "alu1")
12898 (set_attr "prefix_0f" "1")
12899 (set_attr "mode" "DI")])
12901 (define_insn "*btcq"
12902 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12904 (match_operand:DI 1 "const_0_to_63_operand" ""))
12905 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12906 (clobber (reg:CC FLAGS_REG))]
12907 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12908 "btc{q}\t{%1, %0|%0, %1}"
12909 [(set_attr "type" "alu1")
12910 (set_attr "prefix_0f" "1")
12911 (set_attr "mode" "DI")])
12913 ;; Allow Nocona to avoid these instructions if a register is available.
12916 [(match_scratch:DI 2 "r")
12917 (parallel [(set (zero_extract:DI
12918 (match_operand:DI 0 "register_operand" "")
12920 (match_operand:DI 1 "const_0_to_63_operand" ""))
12922 (clobber (reg:CC FLAGS_REG))])]
12923 "TARGET_64BIT && !TARGET_USE_BT"
12926 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12929 if (HOST_BITS_PER_WIDE_INT >= 64)
12930 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12931 else if (i < HOST_BITS_PER_WIDE_INT)
12932 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12934 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12936 op1 = immed_double_const (lo, hi, DImode);
12939 emit_move_insn (operands[2], op1);
12943 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12948 [(match_scratch:DI 2 "r")
12949 (parallel [(set (zero_extract:DI
12950 (match_operand:DI 0 "register_operand" "")
12952 (match_operand:DI 1 "const_0_to_63_operand" ""))
12954 (clobber (reg:CC FLAGS_REG))])]
12955 "TARGET_64BIT && !TARGET_USE_BT"
12958 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12961 if (HOST_BITS_PER_WIDE_INT >= 64)
12962 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12963 else if (i < HOST_BITS_PER_WIDE_INT)
12964 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12966 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12968 op1 = immed_double_const (~lo, ~hi, DImode);
12971 emit_move_insn (operands[2], op1);
12975 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12980 [(match_scratch:DI 2 "r")
12981 (parallel [(set (zero_extract:DI
12982 (match_operand:DI 0 "register_operand" "")
12984 (match_operand:DI 1 "const_0_to_63_operand" ""))
12985 (not:DI (zero_extract:DI
12986 (match_dup 0) (const_int 1) (match_dup 1))))
12987 (clobber (reg:CC FLAGS_REG))])]
12988 "TARGET_64BIT && !TARGET_USE_BT"
12991 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12994 if (HOST_BITS_PER_WIDE_INT >= 64)
12995 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12996 else if (i < HOST_BITS_PER_WIDE_INT)
12997 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12999 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13001 op1 = immed_double_const (lo, hi, DImode);
13004 emit_move_insn (operands[2], op1);
13008 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13012 (define_insn "*btdi_rex64"
13013 [(set (reg:CCC FLAGS_REG)
13016 (match_operand:DI 0 "register_operand" "r")
13018 (match_operand:DI 1 "nonmemory_operand" "rN"))
13020 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13021 "bt{q}\t{%1, %0|%0, %1}"
13022 [(set_attr "type" "alu1")
13023 (set_attr "prefix_0f" "1")
13024 (set_attr "mode" "DI")])
13026 (define_insn "*btsi"
13027 [(set (reg:CCC FLAGS_REG)
13030 (match_operand:SI 0 "register_operand" "r")
13032 (match_operand:SI 1 "nonmemory_operand" "rN"))
13034 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13035 "bt{l}\t{%1, %0|%0, %1}"
13036 [(set_attr "type" "alu1")
13037 (set_attr "prefix_0f" "1")
13038 (set_attr "mode" "SI")])
13040 ;; Store-flag instructions.
13042 ;; For all sCOND expanders, also expand the compare or test insn that
13043 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13045 (define_insn_and_split "*setcc_di_1"
13046 [(set (match_operand:DI 0 "register_operand" "=q")
13047 (match_operator:DI 1 "ix86_comparison_operator"
13048 [(reg FLAGS_REG) (const_int 0)]))]
13049 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
13051 "&& reload_completed"
13052 [(set (match_dup 2) (match_dup 1))
13053 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
13055 PUT_MODE (operands[1], QImode);
13056 operands[2] = gen_lowpart (QImode, operands[0]);
13059 (define_insn_and_split "*setcc_si_1_and"
13060 [(set (match_operand:SI 0 "register_operand" "=q")
13061 (match_operator:SI 1 "ix86_comparison_operator"
13062 [(reg FLAGS_REG) (const_int 0)]))
13063 (clobber (reg:CC FLAGS_REG))]
13064 "!TARGET_PARTIAL_REG_STALL
13065 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
13067 "&& reload_completed"
13068 [(set (match_dup 2) (match_dup 1))
13069 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
13070 (clobber (reg:CC FLAGS_REG))])]
13072 PUT_MODE (operands[1], QImode);
13073 operands[2] = gen_lowpart (QImode, operands[0]);
13076 (define_insn_and_split "*setcc_si_1_movzbl"
13077 [(set (match_operand:SI 0 "register_operand" "=q")
13078 (match_operator:SI 1 "ix86_comparison_operator"
13079 [(reg FLAGS_REG) (const_int 0)]))]
13080 "!TARGET_PARTIAL_REG_STALL
13081 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
13083 "&& reload_completed"
13084 [(set (match_dup 2) (match_dup 1))
13085 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
13087 PUT_MODE (operands[1], QImode);
13088 operands[2] = gen_lowpart (QImode, operands[0]);
13091 (define_insn "*setcc_qi"
13092 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13093 (match_operator:QI 1 "ix86_comparison_operator"
13094 [(reg FLAGS_REG) (const_int 0)]))]
13097 [(set_attr "type" "setcc")
13098 (set_attr "mode" "QI")])
13100 (define_insn "*setcc_qi_slp"
13101 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13102 (match_operator:QI 1 "ix86_comparison_operator"
13103 [(reg FLAGS_REG) (const_int 0)]))]
13106 [(set_attr "type" "setcc")
13107 (set_attr "mode" "QI")])
13109 ;; In general it is not safe to assume too much about CCmode registers,
13110 ;; so simplify-rtx stops when it sees a second one. Under certain
13111 ;; conditions this is safe on x86, so help combine not create
13118 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13119 (ne:QI (match_operator 1 "ix86_comparison_operator"
13120 [(reg FLAGS_REG) (const_int 0)])
13123 [(set (match_dup 0) (match_dup 1))]
13125 PUT_MODE (operands[1], QImode);
13129 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13130 (ne:QI (match_operator 1 "ix86_comparison_operator"
13131 [(reg FLAGS_REG) (const_int 0)])
13134 [(set (match_dup 0) (match_dup 1))]
13136 PUT_MODE (operands[1], QImode);
13140 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13141 (eq:QI (match_operator 1 "ix86_comparison_operator"
13142 [(reg FLAGS_REG) (const_int 0)])
13145 [(set (match_dup 0) (match_dup 1))]
13147 rtx new_op1 = copy_rtx (operands[1]);
13148 operands[1] = new_op1;
13149 PUT_MODE (new_op1, QImode);
13150 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13151 GET_MODE (XEXP (new_op1, 0))));
13153 /* Make sure that (a) the CCmode we have for the flags is strong
13154 enough for the reversed compare or (b) we have a valid FP compare. */
13155 if (! ix86_comparison_operator (new_op1, VOIDmode))
13160 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13161 (eq:QI (match_operator 1 "ix86_comparison_operator"
13162 [(reg FLAGS_REG) (const_int 0)])
13165 [(set (match_dup 0) (match_dup 1))]
13167 rtx new_op1 = copy_rtx (operands[1]);
13168 operands[1] = new_op1;
13169 PUT_MODE (new_op1, QImode);
13170 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13171 GET_MODE (XEXP (new_op1, 0))));
13173 /* Make sure that (a) the CCmode we have for the flags is strong
13174 enough for the reversed compare or (b) we have a valid FP compare. */
13175 if (! ix86_comparison_operator (new_op1, VOIDmode))
13179 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13180 ;; subsequent logical operations are used to imitate conditional moves.
13181 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13184 (define_insn "*avx_setcc<mode>"
13185 [(set (match_operand:MODEF 0 "register_operand" "=x")
13186 (match_operator:MODEF 1 "avx_comparison_float_operator"
13187 [(match_operand:MODEF 2 "register_operand" "x")
13188 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13190 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13191 [(set_attr "type" "ssecmp")
13192 (set_attr "prefix" "vex")
13193 (set_attr "length_immediate" "1")
13194 (set_attr "mode" "<MODE>")])
13196 (define_insn "*sse_setcc<mode>"
13197 [(set (match_operand:MODEF 0 "register_operand" "=x")
13198 (match_operator:MODEF 1 "sse_comparison_operator"
13199 [(match_operand:MODEF 2 "register_operand" "0")
13200 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13201 "SSE_FLOAT_MODE_P (<MODE>mode)"
13202 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13203 [(set_attr "type" "ssecmp")
13204 (set_attr "length_immediate" "1")
13205 (set_attr "mode" "<MODE>")])
13207 ;; Basic conditional jump instructions.
13208 ;; We ignore the overflow flag for signed branch instructions.
13210 (define_insn "*jcc_1"
13212 (if_then_else (match_operator 1 "ix86_comparison_operator"
13213 [(reg FLAGS_REG) (const_int 0)])
13214 (label_ref (match_operand 0 "" ""))
13218 [(set_attr "type" "ibr")
13219 (set_attr "modrm" "0")
13220 (set (attr "length")
13221 (if_then_else (and (ge (minus (match_dup 0) (pc))
13223 (lt (minus (match_dup 0) (pc))
13228 (define_insn "*jcc_2"
13230 (if_then_else (match_operator 1 "ix86_comparison_operator"
13231 [(reg FLAGS_REG) (const_int 0)])
13233 (label_ref (match_operand 0 "" ""))))]
13236 [(set_attr "type" "ibr")
13237 (set_attr "modrm" "0")
13238 (set (attr "length")
13239 (if_then_else (and (ge (minus (match_dup 0) (pc))
13241 (lt (minus (match_dup 0) (pc))
13246 ;; In general it is not safe to assume too much about CCmode registers,
13247 ;; so simplify-rtx stops when it sees a second one. Under certain
13248 ;; conditions this is safe on x86, so help combine not create
13256 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13257 [(reg FLAGS_REG) (const_int 0)])
13259 (label_ref (match_operand 1 "" ""))
13263 (if_then_else (match_dup 0)
13264 (label_ref (match_dup 1))
13267 PUT_MODE (operands[0], VOIDmode);
13272 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13273 [(reg FLAGS_REG) (const_int 0)])
13275 (label_ref (match_operand 1 "" ""))
13279 (if_then_else (match_dup 0)
13280 (label_ref (match_dup 1))
13283 rtx new_op0 = copy_rtx (operands[0]);
13284 operands[0] = new_op0;
13285 PUT_MODE (new_op0, VOIDmode);
13286 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13287 GET_MODE (XEXP (new_op0, 0))));
13289 /* Make sure that (a) the CCmode we have for the flags is strong
13290 enough for the reversed compare or (b) we have a valid FP compare. */
13291 if (! ix86_comparison_operator (new_op0, VOIDmode))
13295 ;; zero_extend in SImode is correct, since this is what combine pass
13296 ;; generates from shift insn with QImode operand. Actually, the mode of
13297 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
13298 ;; appropriate modulo of the bit offset value.
13300 (define_insn_and_split "*jcc_btdi_rex64"
13302 (if_then_else (match_operator 0 "bt_comparison_operator"
13304 (match_operand:DI 1 "register_operand" "r")
13307 (match_operand:QI 2 "register_operand" "r")))
13309 (label_ref (match_operand 3 "" ""))
13311 (clobber (reg:CC FLAGS_REG))]
13312 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13315 [(set (reg:CCC FLAGS_REG)
13323 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13324 (label_ref (match_dup 3))
13327 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13329 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13332 ;; avoid useless masking of bit offset operand
13333 (define_insn_and_split "*jcc_btdi_mask_rex64"
13335 (if_then_else (match_operator 0 "bt_comparison_operator"
13337 (match_operand:DI 1 "register_operand" "r")
13340 (match_operand:SI 2 "register_operand" "r")
13341 (match_operand:SI 3 "const_int_operand" "n")))])
13342 (label_ref (match_operand 4 "" ""))
13344 (clobber (reg:CC FLAGS_REG))]
13345 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13346 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13349 [(set (reg:CCC FLAGS_REG)
13357 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13358 (label_ref (match_dup 4))
13361 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13363 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13366 (define_insn_and_split "*jcc_btsi"
13368 (if_then_else (match_operator 0 "bt_comparison_operator"
13370 (match_operand:SI 1 "register_operand" "r")
13373 (match_operand:QI 2 "register_operand" "r")))
13375 (label_ref (match_operand 3 "" ""))
13377 (clobber (reg:CC FLAGS_REG))]
13378 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13381 [(set (reg:CCC FLAGS_REG)
13389 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13390 (label_ref (match_dup 3))
13393 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13395 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13398 ;; avoid useless masking of bit offset operand
13399 (define_insn_and_split "*jcc_btsi_mask"
13401 (if_then_else (match_operator 0 "bt_comparison_operator"
13403 (match_operand:SI 1 "register_operand" "r")
13406 (match_operand:SI 2 "register_operand" "r")
13407 (match_operand:SI 3 "const_int_operand" "n")))])
13408 (label_ref (match_operand 4 "" ""))
13410 (clobber (reg:CC FLAGS_REG))]
13411 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13412 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13415 [(set (reg:CCC FLAGS_REG)
13423 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13424 (label_ref (match_dup 4))
13426 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13428 (define_insn_and_split "*jcc_btsi_1"
13430 (if_then_else (match_operator 0 "bt_comparison_operator"
13433 (match_operand:SI 1 "register_operand" "r")
13434 (match_operand:QI 2 "register_operand" "r"))
13437 (label_ref (match_operand 3 "" ""))
13439 (clobber (reg:CC FLAGS_REG))]
13440 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13443 [(set (reg:CCC FLAGS_REG)
13451 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13452 (label_ref (match_dup 3))
13455 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13457 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13460 ;; avoid useless masking of bit offset operand
13461 (define_insn_and_split "*jcc_btsi_mask_1"
13464 (match_operator 0 "bt_comparison_operator"
13467 (match_operand:SI 1 "register_operand" "r")
13470 (match_operand:SI 2 "register_operand" "r")
13471 (match_operand:SI 3 "const_int_operand" "n")) 0))
13474 (label_ref (match_operand 4 "" ""))
13476 (clobber (reg:CC FLAGS_REG))]
13477 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13478 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13481 [(set (reg:CCC FLAGS_REG)
13489 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13490 (label_ref (match_dup 4))
13492 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13494 ;; Define combination compare-and-branch fp compare instructions to help
13497 (define_insn "*fp_jcc_3_387"
13499 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13500 [(match_operand 1 "register_operand" "f")
13501 (match_operand 2 "nonimmediate_operand" "fm")])
13502 (label_ref (match_operand 3 "" ""))
13504 (clobber (reg:CCFP FPSR_REG))
13505 (clobber (reg:CCFP FLAGS_REG))
13506 (clobber (match_scratch:HI 4 "=a"))]
13508 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13509 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13510 && SELECT_CC_MODE (GET_CODE (operands[0]),
13511 operands[1], operands[2]) == CCFPmode
13515 (define_insn "*fp_jcc_4_387"
13517 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13518 [(match_operand 1 "register_operand" "f")
13519 (match_operand 2 "nonimmediate_operand" "fm")])
13521 (label_ref (match_operand 3 "" ""))))
13522 (clobber (reg:CCFP FPSR_REG))
13523 (clobber (reg:CCFP FLAGS_REG))
13524 (clobber (match_scratch:HI 4 "=a"))]
13526 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13527 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13528 && SELECT_CC_MODE (GET_CODE (operands[0]),
13529 operands[1], operands[2]) == CCFPmode
13533 (define_insn "*fp_jcc_5_387"
13535 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13536 [(match_operand 1 "register_operand" "f")
13537 (match_operand 2 "register_operand" "f")])
13538 (label_ref (match_operand 3 "" ""))
13540 (clobber (reg:CCFP FPSR_REG))
13541 (clobber (reg:CCFP FLAGS_REG))
13542 (clobber (match_scratch:HI 4 "=a"))]
13543 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13544 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13548 (define_insn "*fp_jcc_6_387"
13550 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13551 [(match_operand 1 "register_operand" "f")
13552 (match_operand 2 "register_operand" "f")])
13554 (label_ref (match_operand 3 "" ""))))
13555 (clobber (reg:CCFP FPSR_REG))
13556 (clobber (reg:CCFP FLAGS_REG))
13557 (clobber (match_scratch:HI 4 "=a"))]
13558 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13559 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13563 (define_insn "*fp_jcc_7_387"
13565 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13566 [(match_operand 1 "register_operand" "f")
13567 (match_operand 2 "const0_operand" "")])
13568 (label_ref (match_operand 3 "" ""))
13570 (clobber (reg:CCFP FPSR_REG))
13571 (clobber (reg:CCFP FLAGS_REG))
13572 (clobber (match_scratch:HI 4 "=a"))]
13573 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13574 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13575 && SELECT_CC_MODE (GET_CODE (operands[0]),
13576 operands[1], operands[2]) == CCFPmode
13580 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13581 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13582 ;; with a precedence over other operators and is always put in the first
13583 ;; place. Swap condition and operands to match ficom instruction.
13585 (define_insn "*fp_jcc_8<mode>_387"
13587 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13588 [(match_operator 1 "float_operator"
13589 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13590 (match_operand 3 "register_operand" "f,f")])
13591 (label_ref (match_operand 4 "" ""))
13593 (clobber (reg:CCFP FPSR_REG))
13594 (clobber (reg:CCFP FLAGS_REG))
13595 (clobber (match_scratch:HI 5 "=a,a"))]
13596 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13597 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13598 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13599 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13605 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13606 [(match_operand 1 "register_operand" "")
13607 (match_operand 2 "nonimmediate_operand" "")])
13608 (match_operand 3 "" "")
13609 (match_operand 4 "" "")))
13610 (clobber (reg:CCFP FPSR_REG))
13611 (clobber (reg:CCFP FLAGS_REG))]
13615 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13616 operands[3], operands[4], NULL_RTX, NULL_RTX);
13622 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13623 [(match_operand 1 "register_operand" "")
13624 (match_operand 2 "general_operand" "")])
13625 (match_operand 3 "" "")
13626 (match_operand 4 "" "")))
13627 (clobber (reg:CCFP FPSR_REG))
13628 (clobber (reg:CCFP FLAGS_REG))
13629 (clobber (match_scratch:HI 5 "=a"))]
13633 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13634 operands[3], operands[4], operands[5], NULL_RTX);
13640 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13641 [(match_operator 1 "float_operator"
13642 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13643 (match_operand 3 "register_operand" "")])
13644 (match_operand 4 "" "")
13645 (match_operand 5 "" "")))
13646 (clobber (reg:CCFP FPSR_REG))
13647 (clobber (reg:CCFP FLAGS_REG))
13648 (clobber (match_scratch:HI 6 "=a"))]
13652 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13653 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13654 operands[3], operands[7],
13655 operands[4], operands[5], operands[6], NULL_RTX);
13659 ;; %%% Kill this when reload knows how to do it.
13662 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13663 [(match_operator 1 "float_operator"
13664 [(match_operand:X87MODEI12 2 "register_operand" "")])
13665 (match_operand 3 "register_operand" "")])
13666 (match_operand 4 "" "")
13667 (match_operand 5 "" "")))
13668 (clobber (reg:CCFP FPSR_REG))
13669 (clobber (reg:CCFP FLAGS_REG))
13670 (clobber (match_scratch:HI 6 "=a"))]
13674 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13675 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13676 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13677 operands[3], operands[7],
13678 operands[4], operands[5], operands[6], operands[2]);
13682 ;; Unconditional and other jump instructions
13684 (define_insn "jump"
13686 (label_ref (match_operand 0 "" "")))]
13689 [(set_attr "type" "ibr")
13690 (set (attr "length")
13691 (if_then_else (and (ge (minus (match_dup 0) (pc))
13693 (lt (minus (match_dup 0) (pc))
13697 (set_attr "modrm" "0")])
13699 (define_expand "indirect_jump"
13700 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13704 (define_insn "*indirect_jump"
13705 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13708 [(set_attr "type" "ibr")
13709 (set_attr "length_immediate" "0")])
13711 (define_expand "tablejump"
13712 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
13713 (use (label_ref (match_operand 1 "" "")))])]
13716 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13717 relative. Convert the relative address to an absolute address. */
13721 enum rtx_code code;
13723 /* We can't use @GOTOFF for text labels on VxWorks;
13724 see gotoff_operand. */
13725 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13729 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13731 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13735 op1 = pic_offset_table_rtx;
13740 op0 = pic_offset_table_rtx;
13744 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13749 (define_insn "*tablejump_1"
13750 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
13751 (use (label_ref (match_operand 1 "" "")))]
13754 [(set_attr "type" "ibr")
13755 (set_attr "length_immediate" "0")])
13757 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13760 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13761 (set (match_operand:QI 1 "register_operand" "")
13762 (match_operator:QI 2 "ix86_comparison_operator"
13763 [(reg FLAGS_REG) (const_int 0)]))
13764 (set (match_operand 3 "q_regs_operand" "")
13765 (zero_extend (match_dup 1)))]
13766 "(peep2_reg_dead_p (3, operands[1])
13767 || operands_match_p (operands[1], operands[3]))
13768 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13769 [(set (match_dup 4) (match_dup 0))
13770 (set (strict_low_part (match_dup 5))
13773 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13774 operands[5] = gen_lowpart (QImode, operands[3]);
13775 ix86_expand_clear (operands[3]);
13778 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13781 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13782 (set (match_operand:QI 1 "register_operand" "")
13783 (match_operator:QI 2 "ix86_comparison_operator"
13784 [(reg FLAGS_REG) (const_int 0)]))
13785 (parallel [(set (match_operand 3 "q_regs_operand" "")
13786 (zero_extend (match_dup 1)))
13787 (clobber (reg:CC FLAGS_REG))])]
13788 "(peep2_reg_dead_p (3, operands[1])
13789 || operands_match_p (operands[1], operands[3]))
13790 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13791 [(set (match_dup 4) (match_dup 0))
13792 (set (strict_low_part (match_dup 5))
13795 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13796 operands[5] = gen_lowpart (QImode, operands[3]);
13797 ix86_expand_clear (operands[3]);
13800 ;; Call instructions.
13802 ;; The predicates normally associated with named expanders are not properly
13803 ;; checked for calls. This is a bug in the generic code, but it isn't that
13804 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13806 ;; P6 processors will jump to the address after the decrement when %esp
13807 ;; is used as a call operand, so they will execute return address as a code.
13808 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13810 ;; Call subroutine returning no value.
13812 (define_expand "call_pop"
13813 [(parallel [(call (match_operand:QI 0 "" "")
13814 (match_operand:SI 1 "" ""))
13815 (set (reg:SI SP_REG)
13816 (plus:SI (reg:SI SP_REG)
13817 (match_operand:SI 3 "" "")))])]
13820 ix86_expand_call (NULL, operands[0], operands[1],
13821 operands[2], operands[3], 0);
13825 (define_insn "*call_pop_0"
13826 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13827 (match_operand:SI 1 "" ""))
13828 (set (reg:SI SP_REG)
13829 (plus:SI (reg:SI SP_REG)
13830 (match_operand:SI 2 "immediate_operand" "")))]
13833 if (SIBLING_CALL_P (insn))
13836 return "call\t%P0";
13838 [(set_attr "type" "call")])
13840 (define_insn "*call_pop_1"
13841 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13842 (match_operand:SI 1 "" ""))
13843 (set (reg:SI SP_REG)
13844 (plus:SI (reg:SI SP_REG)
13845 (match_operand:SI 2 "immediate_operand" "i")))]
13846 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13848 if (constant_call_address_operand (operands[0], Pmode))
13849 return "call\t%P0";
13850 return "call\t%A0";
13852 [(set_attr "type" "call")])
13854 (define_insn "*sibcall_pop_1"
13855 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13856 (match_operand:SI 1 "" ""))
13857 (set (reg:SI SP_REG)
13858 (plus:SI (reg:SI SP_REG)
13859 (match_operand:SI 2 "immediate_operand" "i,i")))]
13860 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13864 [(set_attr "type" "call")])
13866 (define_expand "call"
13867 [(call (match_operand:QI 0 "" "")
13868 (match_operand 1 "" ""))
13869 (use (match_operand 2 "" ""))]
13872 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13876 (define_expand "sibcall"
13877 [(call (match_operand:QI 0 "" "")
13878 (match_operand 1 "" ""))
13879 (use (match_operand 2 "" ""))]
13882 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13886 (define_insn "*call_0"
13887 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13888 (match_operand 1 "" ""))]
13891 if (SIBLING_CALL_P (insn))
13894 return "call\t%P0";
13896 [(set_attr "type" "call")])
13898 (define_insn "*call_1"
13899 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13900 (match_operand 1 "" ""))]
13901 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13903 if (constant_call_address_operand (operands[0], Pmode))
13904 return "call\t%P0";
13905 return "call\t%A0";
13907 [(set_attr "type" "call")])
13909 (define_insn "*sibcall_1"
13910 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13911 (match_operand 1 "" ""))]
13912 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13916 [(set_attr "type" "call")])
13918 (define_insn "*call_1_rex64"
13919 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13920 (match_operand 1 "" ""))]
13921 "TARGET_64BIT && !SIBLING_CALL_P (insn)
13922 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13924 if (constant_call_address_operand (operands[0], Pmode))
13925 return "call\t%P0";
13926 return "call\t%A0";
13928 [(set_attr "type" "call")])
13930 (define_insn "*call_1_rex64_ms_sysv"
13931 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13932 (match_operand 1 "" ""))
13933 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13934 (clobber (reg:TI XMM6_REG))
13935 (clobber (reg:TI XMM7_REG))
13936 (clobber (reg:TI XMM8_REG))
13937 (clobber (reg:TI XMM9_REG))
13938 (clobber (reg:TI XMM10_REG))
13939 (clobber (reg:TI XMM11_REG))
13940 (clobber (reg:TI XMM12_REG))
13941 (clobber (reg:TI XMM13_REG))
13942 (clobber (reg:TI XMM14_REG))
13943 (clobber (reg:TI XMM15_REG))
13944 (clobber (reg:DI SI_REG))
13945 (clobber (reg:DI DI_REG))]
13946 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13948 if (constant_call_address_operand (operands[0], Pmode))
13949 return "call\t%P0";
13950 return "call\t%A0";
13952 [(set_attr "type" "call")])
13954 (define_insn "*call_1_rex64_large"
13955 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13956 (match_operand 1 "" ""))]
13957 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13959 [(set_attr "type" "call")])
13961 (define_insn "*sibcall_1_rex64"
13962 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13963 (match_operand 1 "" ""))]
13964 "TARGET_64BIT && SIBLING_CALL_P (insn)"
13968 [(set_attr "type" "call")])
13970 ;; Call subroutine, returning value in operand 0
13971 (define_expand "call_value_pop"
13972 [(parallel [(set (match_operand 0 "" "")
13973 (call (match_operand:QI 1 "" "")
13974 (match_operand:SI 2 "" "")))
13975 (set (reg:SI SP_REG)
13976 (plus:SI (reg:SI SP_REG)
13977 (match_operand:SI 4 "" "")))])]
13980 ix86_expand_call (operands[0], operands[1], operands[2],
13981 operands[3], operands[4], 0);
13985 (define_expand "call_value"
13986 [(set (match_operand 0 "" "")
13987 (call (match_operand:QI 1 "" "")
13988 (match_operand:SI 2 "" "")))
13989 (use (match_operand:SI 3 "" ""))]
13990 ;; Operand 3 is not used on the i386.
13993 ix86_expand_call (operands[0], operands[1], operands[2],
13994 operands[3], NULL, 0);
13998 (define_expand "sibcall_value"
13999 [(set (match_operand 0 "" "")
14000 (call (match_operand:QI 1 "" "")
14001 (match_operand:SI 2 "" "")))
14002 (use (match_operand:SI 3 "" ""))]
14003 ;; Operand 3 is not used on the i386.
14006 ix86_expand_call (operands[0], operands[1], operands[2],
14007 operands[3], NULL, 1);
14011 ;; Call subroutine returning any type.
14013 (define_expand "untyped_call"
14014 [(parallel [(call (match_operand 0 "" "")
14016 (match_operand 1 "" "")
14017 (match_operand 2 "" "")])]
14022 /* In order to give reg-stack an easier job in validating two
14023 coprocessor registers as containing a possible return value,
14024 simply pretend the untyped call returns a complex long double
14027 We can't use SSE_REGPARM_MAX here since callee is unprototyped
14028 and should have the default ABI. */
14030 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14031 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14032 operands[0], const0_rtx,
14033 GEN_INT ((TARGET_64BIT
14034 ? (ix86_abi == SYSV_ABI
14035 ? X86_64_SSE_REGPARM_MAX
14036 : X86_64_MS_SSE_REGPARM_MAX)
14037 : X86_32_SSE_REGPARM_MAX)
14041 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14043 rtx set = XVECEXP (operands[2], 0, i);
14044 emit_move_insn (SET_DEST (set), SET_SRC (set));
14047 /* The optimizer does not know that the call sets the function value
14048 registers we stored in the result block. We avoid problems by
14049 claiming that all hard registers are used and clobbered at this
14051 emit_insn (gen_blockage ());
14056 ;; Prologue and epilogue instructions
14058 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14059 ;; all of memory. This blocks insns from being moved across this point.
14061 (define_insn "blockage"
14062 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14065 [(set_attr "length" "0")])
14067 ;; Do not schedule instructions accessing memory across this point.
14069 (define_expand "memory_blockage"
14070 [(set (match_dup 0)
14071 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14074 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14075 MEM_VOLATILE_P (operands[0]) = 1;
14078 (define_insn "*memory_blockage"
14079 [(set (match_operand:BLK 0 "" "")
14080 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14083 [(set_attr "length" "0")])
14085 ;; As USE insns aren't meaningful after reload, this is used instead
14086 ;; to prevent deleting instructions setting registers for PIC code
14087 (define_insn "prologue_use"
14088 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14091 [(set_attr "length" "0")])
14093 ;; Insn emitted into the body of a function to return from a function.
14094 ;; This is only done if the function's epilogue is known to be simple.
14095 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14097 (define_expand "return"
14099 "ix86_can_use_return_insn_p ()"
14101 if (crtl->args.pops_args)
14103 rtx popc = GEN_INT (crtl->args.pops_args);
14104 emit_jump_insn (gen_return_pop_internal (popc));
14109 (define_insn "return_internal"
14113 [(set_attr "length" "1")
14114 (set_attr "atom_unit" "jeu")
14115 (set_attr "length_immediate" "0")
14116 (set_attr "modrm" "0")])
14118 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14119 ;; instruction Athlon and K8 have.
14121 (define_insn "return_internal_long"
14123 (unspec [(const_int 0)] UNSPEC_REP)]
14126 [(set_attr "length" "2")
14127 (set_attr "atom_unit" "jeu")
14128 (set_attr "length_immediate" "0")
14129 (set_attr "prefix_rep" "1")
14130 (set_attr "modrm" "0")])
14132 (define_insn "return_pop_internal"
14134 (use (match_operand:SI 0 "const_int_operand" ""))]
14137 [(set_attr "length" "3")
14138 (set_attr "atom_unit" "jeu")
14139 (set_attr "length_immediate" "2")
14140 (set_attr "modrm" "0")])
14142 (define_insn "return_indirect_internal"
14144 (use (match_operand:SI 0 "register_operand" "r"))]
14147 [(set_attr "type" "ibr")
14148 (set_attr "length_immediate" "0")])
14154 [(set_attr "length" "1")
14155 (set_attr "length_immediate" "0")
14156 (set_attr "modrm" "0")])
14158 (define_insn "vswapmov"
14159 [(set (match_operand:SI 0 "register_operand" "=r")
14160 (match_operand:SI 1 "register_operand" "r"))
14161 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
14163 "movl.s\t{%1, %0|%0, %1}"
14164 [(set_attr "length" "2")
14165 (set_attr "length_immediate" "0")
14166 (set_attr "modrm" "0")])
14168 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
14169 ;; branch prediction penalty for the third jump in a 16-byte
14173 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14176 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
14177 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
14179 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14180 The align insn is used to avoid 3 jump instructions in the row to improve
14181 branch prediction and the benefits hardly outweigh the cost of extra 8
14182 nops on the average inserted by full alignment pseudo operation. */
14186 [(set_attr "length" "16")])
14188 (define_expand "prologue"
14191 "ix86_expand_prologue (); DONE;")
14193 (define_insn "set_got"
14194 [(set (match_operand:SI 0 "register_operand" "=r")
14195 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14196 (clobber (reg:CC FLAGS_REG))]
14198 { return output_set_got (operands[0], NULL_RTX); }
14199 [(set_attr "type" "multi")
14200 (set_attr "length" "12")])
14202 (define_insn "set_got_labelled"
14203 [(set (match_operand:SI 0 "register_operand" "=r")
14204 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14206 (clobber (reg:CC FLAGS_REG))]
14208 { return output_set_got (operands[0], operands[1]); }
14209 [(set_attr "type" "multi")
14210 (set_attr "length" "12")])
14212 (define_insn "set_got_rex64"
14213 [(set (match_operand:DI 0 "register_operand" "=r")
14214 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14216 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14217 [(set_attr "type" "lea")
14218 (set_attr "length_address" "4")
14219 (set_attr "mode" "DI")])
14221 (define_insn "set_rip_rex64"
14222 [(set (match_operand:DI 0 "register_operand" "=r")
14223 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
14225 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14226 [(set_attr "type" "lea")
14227 (set_attr "length_address" "4")
14228 (set_attr "mode" "DI")])
14230 (define_insn "set_got_offset_rex64"
14231 [(set (match_operand:DI 0 "register_operand" "=r")
14233 [(label_ref (match_operand 1 "" ""))]
14234 UNSPEC_SET_GOT_OFFSET))]
14236 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14237 [(set_attr "type" "imov")
14238 (set_attr "length_immediate" "0")
14239 (set_attr "length_address" "8")
14240 (set_attr "mode" "DI")])
14242 (define_expand "epilogue"
14245 "ix86_expand_epilogue (1); DONE;")
14247 (define_expand "sibcall_epilogue"
14250 "ix86_expand_epilogue (0); DONE;")
14252 (define_expand "eh_return"
14253 [(use (match_operand 0 "register_operand" ""))]
14256 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14258 /* Tricky bit: we write the address of the handler to which we will
14259 be returning into someone else's stack frame, one word below the
14260 stack address we wish to restore. */
14261 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14262 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14263 tmp = gen_rtx_MEM (Pmode, tmp);
14264 emit_move_insn (tmp, ra);
14266 emit_jump_insn (gen_eh_return_internal ());
14271 (define_insn_and_split "eh_return_internal"
14275 "epilogue_completed"
14277 "ix86_expand_epilogue (2); DONE;")
14279 (define_insn "leave"
14280 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14281 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14282 (clobber (mem:BLK (scratch)))]
14285 [(set_attr "type" "leave")])
14287 (define_insn "leave_rex64"
14288 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14289 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14290 (clobber (mem:BLK (scratch)))]
14293 [(set_attr "type" "leave")])
14295 (define_expand "ffssi2"
14297 [(set (match_operand:SI 0 "register_operand" "")
14298 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14299 (clobber (match_scratch:SI 2 ""))
14300 (clobber (reg:CC FLAGS_REG))])]
14305 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14310 (define_expand "ffs_cmove"
14311 [(set (match_dup 2) (const_int -1))
14312 (parallel [(set (reg:CCZ FLAGS_REG)
14313 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14315 (set (match_operand:SI 0 "register_operand" "")
14316 (ctz:SI (match_dup 1)))])
14317 (set (match_dup 0) (if_then_else:SI
14318 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14321 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14322 (clobber (reg:CC FLAGS_REG))])]
14324 "operands[2] = gen_reg_rtx (SImode);")
14326 (define_insn_and_split "*ffs_no_cmove"
14327 [(set (match_operand:SI 0 "register_operand" "=r")
14328 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14329 (clobber (match_scratch:SI 2 "=&q"))
14330 (clobber (reg:CC FLAGS_REG))]
14333 "&& reload_completed"
14334 [(parallel [(set (reg:CCZ FLAGS_REG)
14335 (compare:CCZ (match_dup 1) (const_int 0)))
14336 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14337 (set (strict_low_part (match_dup 3))
14338 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14339 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14340 (clobber (reg:CC FLAGS_REG))])
14341 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14342 (clobber (reg:CC FLAGS_REG))])
14343 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14344 (clobber (reg:CC FLAGS_REG))])]
14346 operands[3] = gen_lowpart (QImode, operands[2]);
14347 ix86_expand_clear (operands[2]);
14350 (define_insn "*ffssi_1"
14351 [(set (reg:CCZ FLAGS_REG)
14352 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14354 (set (match_operand:SI 0 "register_operand" "=r")
14355 (ctz:SI (match_dup 1)))]
14357 "bsf{l}\t{%1, %0|%0, %1}"
14358 [(set_attr "type" "alu1")
14359 (set_attr "prefix_0f" "1")
14360 (set_attr "mode" "SI")])
14362 (define_expand "ffsdi2"
14363 [(set (match_dup 2) (const_int -1))
14364 (parallel [(set (reg:CCZ FLAGS_REG)
14365 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14367 (set (match_operand:DI 0 "register_operand" "")
14368 (ctz:DI (match_dup 1)))])
14369 (set (match_dup 0) (if_then_else:DI
14370 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14373 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14374 (clobber (reg:CC FLAGS_REG))])]
14376 "operands[2] = gen_reg_rtx (DImode);")
14378 (define_insn "*ffsdi_1"
14379 [(set (reg:CCZ FLAGS_REG)
14380 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14382 (set (match_operand:DI 0 "register_operand" "=r")
14383 (ctz:DI (match_dup 1)))]
14385 "bsf{q}\t{%1, %0|%0, %1}"
14386 [(set_attr "type" "alu1")
14387 (set_attr "prefix_0f" "1")
14388 (set_attr "mode" "DI")])
14390 (define_insn "ctzsi2"
14391 [(set (match_operand:SI 0 "register_operand" "=r")
14392 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14393 (clobber (reg:CC FLAGS_REG))]
14395 "bsf{l}\t{%1, %0|%0, %1}"
14396 [(set_attr "type" "alu1")
14397 (set_attr "prefix_0f" "1")
14398 (set_attr "mode" "SI")])
14400 (define_insn "ctzdi2"
14401 [(set (match_operand:DI 0 "register_operand" "=r")
14402 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14403 (clobber (reg:CC FLAGS_REG))]
14405 "bsf{q}\t{%1, %0|%0, %1}"
14406 [(set_attr "type" "alu1")
14407 (set_attr "prefix_0f" "1")
14408 (set_attr "mode" "DI")])
14410 (define_expand "clzsi2"
14412 [(set (match_operand:SI 0 "register_operand" "")
14413 (minus:SI (const_int 31)
14414 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14415 (clobber (reg:CC FLAGS_REG))])
14417 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14418 (clobber (reg:CC FLAGS_REG))])]
14423 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14428 (define_insn "clzsi2_abm"
14429 [(set (match_operand:SI 0 "register_operand" "=r")
14430 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14431 (clobber (reg:CC FLAGS_REG))]
14433 "lzcnt{l}\t{%1, %0|%0, %1}"
14434 [(set_attr "prefix_rep" "1")
14435 (set_attr "type" "bitmanip")
14436 (set_attr "mode" "SI")])
14439 [(set (match_operand:SI 0 "register_operand" "=r")
14440 (minus:SI (const_int 31)
14441 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14442 (clobber (reg:CC FLAGS_REG))]
14444 "bsr{l}\t{%1, %0|%0, %1}"
14445 [(set_attr "type" "alu1")
14446 (set_attr "prefix_0f" "1")
14447 (set_attr "mode" "SI")])
14449 (define_insn "popcount<mode>2"
14450 [(set (match_operand:SWI248 0 "register_operand" "=r")
14452 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14453 (clobber (reg:CC FLAGS_REG))]
14457 return "popcnt\t{%1, %0|%0, %1}";
14459 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14462 [(set_attr "prefix_rep" "1")
14463 (set_attr "type" "bitmanip")
14464 (set_attr "mode" "<MODE>")])
14466 (define_insn "*popcount<mode>2_cmp"
14467 [(set (reg FLAGS_REG)
14470 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14472 (set (match_operand:SWI248 0 "register_operand" "=r")
14473 (popcount:SWI248 (match_dup 1)))]
14474 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14477 return "popcnt\t{%1, %0|%0, %1}";
14479 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14482 [(set_attr "prefix_rep" "1")
14483 (set_attr "type" "bitmanip")
14484 (set_attr "mode" "<MODE>")])
14486 (define_insn "*popcountsi2_cmp_zext"
14487 [(set (reg FLAGS_REG)
14489 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14491 (set (match_operand:DI 0 "register_operand" "=r")
14492 (zero_extend:DI(popcount:SI (match_dup 1))))]
14493 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14496 return "popcnt\t{%1, %0|%0, %1}";
14498 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14501 [(set_attr "prefix_rep" "1")
14502 (set_attr "type" "bitmanip")
14503 (set_attr "mode" "SI")])
14505 (define_expand "bswapsi2"
14506 [(set (match_operand:SI 0 "register_operand" "")
14507 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14510 if (!(TARGET_BSWAP || TARGET_MOVBE))
14512 rtx x = operands[0];
14514 emit_move_insn (x, operands[1]);
14515 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14516 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14517 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14522 (define_insn "*bswapsi_movbe"
14523 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14524 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14525 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14528 movbe\t{%1, %0|%0, %1}
14529 movbe\t{%1, %0|%0, %1}"
14530 [(set_attr "type" "*,imov,imov")
14531 (set_attr "modrm" "*,1,1")
14532 (set_attr "prefix_0f" "1")
14533 (set_attr "prefix_extra" "*,1,1")
14534 (set_attr "length" "2,*,*")
14535 (set_attr "mode" "SI")])
14537 (define_insn "*bswapsi_1"
14538 [(set (match_operand:SI 0 "register_operand" "=r")
14539 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14542 [(set_attr "prefix_0f" "1")
14543 (set_attr "length" "2")])
14545 (define_insn "*bswaphi_lowpart_1"
14546 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14547 (bswap:HI (match_dup 0)))
14548 (clobber (reg:CC FLAGS_REG))]
14549 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14551 xchg{b}\t{%h0, %b0|%b0, %h0}
14552 rol{w}\t{$8, %0|%0, 8}"
14553 [(set_attr "length" "2,4")
14554 (set_attr "mode" "QI,HI")])
14556 (define_insn "bswaphi_lowpart"
14557 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14558 (bswap:HI (match_dup 0)))
14559 (clobber (reg:CC FLAGS_REG))]
14561 "rol{w}\t{$8, %0|%0, 8}"
14562 [(set_attr "length" "4")
14563 (set_attr "mode" "HI")])
14565 (define_expand "bswapdi2"
14566 [(set (match_operand:DI 0 "register_operand" "")
14567 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14571 (define_insn "*bswapdi_movbe"
14572 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14573 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14574 "TARGET_64BIT && TARGET_MOVBE
14575 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14578 movbe\t{%1, %0|%0, %1}
14579 movbe\t{%1, %0|%0, %1}"
14580 [(set_attr "type" "*,imov,imov")
14581 (set_attr "modrm" "*,1,1")
14582 (set_attr "prefix_0f" "1")
14583 (set_attr "prefix_extra" "*,1,1")
14584 (set_attr "length" "3,*,*")
14585 (set_attr "mode" "DI")])
14587 (define_insn "*bswapdi_1"
14588 [(set (match_operand:DI 0 "register_operand" "=r")
14589 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14592 [(set_attr "prefix_0f" "1")
14593 (set_attr "length" "3")])
14595 (define_expand "clzdi2"
14597 [(set (match_operand:DI 0 "register_operand" "")
14598 (minus:DI (const_int 63)
14599 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14600 (clobber (reg:CC FLAGS_REG))])
14602 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14603 (clobber (reg:CC FLAGS_REG))])]
14608 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14613 (define_insn "clzdi2_abm"
14614 [(set (match_operand:DI 0 "register_operand" "=r")
14615 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14616 (clobber (reg:CC FLAGS_REG))]
14617 "TARGET_64BIT && TARGET_ABM"
14618 "lzcnt{q}\t{%1, %0|%0, %1}"
14619 [(set_attr "prefix_rep" "1")
14620 (set_attr "type" "bitmanip")
14621 (set_attr "mode" "DI")])
14623 (define_insn "bsr_rex64"
14624 [(set (match_operand:DI 0 "register_operand" "=r")
14625 (minus:DI (const_int 63)
14626 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14627 (clobber (reg:CC FLAGS_REG))]
14629 "bsr{q}\t{%1, %0|%0, %1}"
14630 [(set_attr "type" "alu1")
14631 (set_attr "prefix_0f" "1")
14632 (set_attr "mode" "DI")])
14634 (define_expand "clzhi2"
14636 [(set (match_operand:HI 0 "register_operand" "")
14637 (minus:HI (const_int 15)
14638 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14639 (clobber (reg:CC FLAGS_REG))])
14641 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14642 (clobber (reg:CC FLAGS_REG))])]
14647 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14652 (define_insn "clzhi2_abm"
14653 [(set (match_operand:HI 0 "register_operand" "=r")
14654 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14655 (clobber (reg:CC FLAGS_REG))]
14657 "lzcnt{w}\t{%1, %0|%0, %1}"
14658 [(set_attr "prefix_rep" "1")
14659 (set_attr "type" "bitmanip")
14660 (set_attr "mode" "HI")])
14662 (define_insn "*bsrhi"
14663 [(set (match_operand:HI 0 "register_operand" "=r")
14664 (minus:HI (const_int 15)
14665 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14666 (clobber (reg:CC FLAGS_REG))]
14668 "bsr{w}\t{%1, %0|%0, %1}"
14669 [(set_attr "type" "alu1")
14670 (set_attr "prefix_0f" "1")
14671 (set_attr "mode" "HI")])
14673 (define_expand "paritydi2"
14674 [(set (match_operand:DI 0 "register_operand" "")
14675 (parity:DI (match_operand:DI 1 "register_operand" "")))]
14678 rtx scratch = gen_reg_rtx (QImode);
14681 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14682 NULL_RTX, operands[1]));
14684 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14685 gen_rtx_REG (CCmode, FLAGS_REG),
14687 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14690 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14693 rtx tmp = gen_reg_rtx (SImode);
14695 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14696 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14701 (define_insn_and_split "paritydi2_cmp"
14702 [(set (reg:CC FLAGS_REG)
14703 (parity:CC (match_operand:DI 3 "register_operand" "0")))
14704 (clobber (match_scratch:DI 0 "=r"))
14705 (clobber (match_scratch:SI 1 "=&r"))
14706 (clobber (match_scratch:HI 2 "=Q"))]
14709 "&& reload_completed"
14711 [(set (match_dup 1)
14712 (xor:SI (match_dup 1) (match_dup 4)))
14713 (clobber (reg:CC FLAGS_REG))])
14715 [(set (reg:CC FLAGS_REG)
14716 (parity:CC (match_dup 1)))
14717 (clobber (match_dup 1))
14718 (clobber (match_dup 2))])]
14720 operands[4] = gen_lowpart (SImode, operands[3]);
14724 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14725 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14728 operands[1] = gen_highpart (SImode, operands[3]);
14731 (define_expand "paritysi2"
14732 [(set (match_operand:SI 0 "register_operand" "")
14733 (parity:SI (match_operand:SI 1 "register_operand" "")))]
14736 rtx scratch = gen_reg_rtx (QImode);
14739 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14741 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14742 gen_rtx_REG (CCmode, FLAGS_REG),
14744 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14746 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14750 (define_insn_and_split "paritysi2_cmp"
14751 [(set (reg:CC FLAGS_REG)
14752 (parity:CC (match_operand:SI 2 "register_operand" "0")))
14753 (clobber (match_scratch:SI 0 "=r"))
14754 (clobber (match_scratch:HI 1 "=&Q"))]
14757 "&& reload_completed"
14759 [(set (match_dup 1)
14760 (xor:HI (match_dup 1) (match_dup 3)))
14761 (clobber (reg:CC FLAGS_REG))])
14763 [(set (reg:CC FLAGS_REG)
14764 (parity:CC (match_dup 1)))
14765 (clobber (match_dup 1))])]
14767 operands[3] = gen_lowpart (HImode, operands[2]);
14769 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14770 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14773 (define_insn "*parityhi2_cmp"
14774 [(set (reg:CC FLAGS_REG)
14775 (parity:CC (match_operand:HI 1 "register_operand" "0")))
14776 (clobber (match_scratch:HI 0 "=Q"))]
14778 "xor{b}\t{%h0, %b0|%b0, %h0}"
14779 [(set_attr "length" "2")
14780 (set_attr "mode" "HI")])
14782 (define_insn "*parityqi2_cmp"
14783 [(set (reg:CC FLAGS_REG)
14784 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
14787 [(set_attr "length" "2")
14788 (set_attr "mode" "QI")])
14790 ;; Thread-local storage patterns for ELF.
14792 ;; Note that these code sequences must appear exactly as shown
14793 ;; in order to allow linker relaxation.
14795 (define_insn "*tls_global_dynamic_32_gnu"
14796 [(set (match_operand:SI 0 "register_operand" "=a")
14797 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14798 (match_operand:SI 2 "tls_symbolic_operand" "")
14799 (match_operand:SI 3 "call_insn_operand" "")]
14801 (clobber (match_scratch:SI 4 "=d"))
14802 (clobber (match_scratch:SI 5 "=c"))
14803 (clobber (reg:CC FLAGS_REG))]
14804 "!TARGET_64BIT && TARGET_GNU_TLS"
14805 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
14806 [(set_attr "type" "multi")
14807 (set_attr "length" "12")])
14809 (define_insn "*tls_global_dynamic_32_sun"
14810 [(set (match_operand:SI 0 "register_operand" "=a")
14811 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14812 (match_operand:SI 2 "tls_symbolic_operand" "")
14813 (match_operand:SI 3 "call_insn_operand" "")]
14815 (clobber (match_scratch:SI 4 "=d"))
14816 (clobber (match_scratch:SI 5 "=c"))
14817 (clobber (reg:CC FLAGS_REG))]
14818 "!TARGET_64BIT && TARGET_SUN_TLS"
14819 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
14820 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
14821 [(set_attr "type" "multi")
14822 (set_attr "length" "14")])
14824 (define_expand "tls_global_dynamic_32"
14825 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14828 (match_operand:SI 1 "tls_symbolic_operand" "")
14831 (clobber (match_scratch:SI 4 ""))
14832 (clobber (match_scratch:SI 5 ""))
14833 (clobber (reg:CC FLAGS_REG))])]
14837 operands[2] = pic_offset_table_rtx;
14840 operands[2] = gen_reg_rtx (Pmode);
14841 emit_insn (gen_set_got (operands[2]));
14843 if (TARGET_GNU2_TLS)
14845 emit_insn (gen_tls_dynamic_gnu2_32
14846 (operands[0], operands[1], operands[2]));
14849 operands[3] = ix86_tls_get_addr ();
14852 (define_insn "*tls_global_dynamic_64"
14853 [(set (match_operand:DI 0 "register_operand" "=a")
14854 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14855 (match_operand:DI 3 "" "")))
14856 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14859 { 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"; }
14860 [(set_attr "type" "multi")
14861 (set_attr "length" "16")])
14863 (define_expand "tls_global_dynamic_64"
14864 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14865 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14866 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14870 if (TARGET_GNU2_TLS)
14872 emit_insn (gen_tls_dynamic_gnu2_64
14873 (operands[0], operands[1]));
14876 operands[2] = ix86_tls_get_addr ();
14879 (define_insn "*tls_local_dynamic_base_32_gnu"
14880 [(set (match_operand:SI 0 "register_operand" "=a")
14881 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14882 (match_operand:SI 2 "call_insn_operand" "")]
14883 UNSPEC_TLS_LD_BASE))
14884 (clobber (match_scratch:SI 3 "=d"))
14885 (clobber (match_scratch:SI 4 "=c"))
14886 (clobber (reg:CC FLAGS_REG))]
14887 "!TARGET_64BIT && TARGET_GNU_TLS"
14888 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
14889 [(set_attr "type" "multi")
14890 (set_attr "length" "11")])
14892 (define_insn "*tls_local_dynamic_base_32_sun"
14893 [(set (match_operand:SI 0 "register_operand" "=a")
14894 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14895 (match_operand:SI 2 "call_insn_operand" "")]
14896 UNSPEC_TLS_LD_BASE))
14897 (clobber (match_scratch:SI 3 "=d"))
14898 (clobber (match_scratch:SI 4 "=c"))
14899 (clobber (reg:CC FLAGS_REG))]
14900 "!TARGET_64BIT && TARGET_SUN_TLS"
14901 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
14902 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
14903 [(set_attr "type" "multi")
14904 (set_attr "length" "13")])
14906 (define_expand "tls_local_dynamic_base_32"
14907 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14908 (unspec:SI [(match_dup 1) (match_dup 2)]
14909 UNSPEC_TLS_LD_BASE))
14910 (clobber (match_scratch:SI 3 ""))
14911 (clobber (match_scratch:SI 4 ""))
14912 (clobber (reg:CC FLAGS_REG))])]
14916 operands[1] = pic_offset_table_rtx;
14919 operands[1] = gen_reg_rtx (Pmode);
14920 emit_insn (gen_set_got (operands[1]));
14922 if (TARGET_GNU2_TLS)
14924 emit_insn (gen_tls_dynamic_gnu2_32
14925 (operands[0], ix86_tls_module_base (), operands[1]));
14928 operands[2] = ix86_tls_get_addr ();
14931 (define_insn "*tls_local_dynamic_base_64"
14932 [(set (match_operand:DI 0 "register_operand" "=a")
14933 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14934 (match_operand:DI 2 "" "")))
14935 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14937 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
14938 [(set_attr "type" "multi")
14939 (set_attr "length" "12")])
14941 (define_expand "tls_local_dynamic_base_64"
14942 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14943 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14944 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14947 if (TARGET_GNU2_TLS)
14949 emit_insn (gen_tls_dynamic_gnu2_64
14950 (operands[0], ix86_tls_module_base ()));
14953 operands[1] = ix86_tls_get_addr ();
14956 ;; Local dynamic of a single variable is a lose. Show combine how
14957 ;; to convert that back to global dynamic.
14959 (define_insn_and_split "*tls_local_dynamic_32_once"
14960 [(set (match_operand:SI 0 "register_operand" "=a")
14961 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14962 (match_operand:SI 2 "call_insn_operand" "")]
14963 UNSPEC_TLS_LD_BASE)
14964 (const:SI (unspec:SI
14965 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14967 (clobber (match_scratch:SI 4 "=d"))
14968 (clobber (match_scratch:SI 5 "=c"))
14969 (clobber (reg:CC FLAGS_REG))]
14973 [(parallel [(set (match_dup 0)
14974 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14976 (clobber (match_dup 4))
14977 (clobber (match_dup 5))
14978 (clobber (reg:CC FLAGS_REG))])]
14981 ;; Load and add the thread base pointer from %gs:0.
14983 (define_insn "*load_tp_si"
14984 [(set (match_operand:SI 0 "register_operand" "=r")
14985 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14987 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14988 [(set_attr "type" "imov")
14989 (set_attr "modrm" "0")
14990 (set_attr "length" "7")
14991 (set_attr "memory" "load")
14992 (set_attr "imm_disp" "false")])
14994 (define_insn "*add_tp_si"
14995 [(set (match_operand:SI 0 "register_operand" "=r")
14996 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14997 (match_operand:SI 1 "register_operand" "0")))
14998 (clobber (reg:CC FLAGS_REG))]
15000 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15001 [(set_attr "type" "alu")
15002 (set_attr "modrm" "0")
15003 (set_attr "length" "7")
15004 (set_attr "memory" "load")
15005 (set_attr "imm_disp" "false")])
15007 (define_insn "*load_tp_di"
15008 [(set (match_operand:DI 0 "register_operand" "=r")
15009 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15011 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15012 [(set_attr "type" "imov")
15013 (set_attr "modrm" "0")
15014 (set_attr "length" "7")
15015 (set_attr "memory" "load")
15016 (set_attr "imm_disp" "false")])
15018 (define_insn "*add_tp_di"
15019 [(set (match_operand:DI 0 "register_operand" "=r")
15020 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15021 (match_operand:DI 1 "register_operand" "0")))
15022 (clobber (reg:CC FLAGS_REG))]
15024 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15025 [(set_attr "type" "alu")
15026 (set_attr "modrm" "0")
15027 (set_attr "length" "7")
15028 (set_attr "memory" "load")
15029 (set_attr "imm_disp" "false")])
15031 ;; GNU2 TLS patterns can be split.
15033 (define_expand "tls_dynamic_gnu2_32"
15034 [(set (match_dup 3)
15035 (plus:SI (match_operand:SI 2 "register_operand" "")
15037 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15040 [(set (match_operand:SI 0 "register_operand" "")
15041 (unspec:SI [(match_dup 1) (match_dup 3)
15042 (match_dup 2) (reg:SI SP_REG)]
15044 (clobber (reg:CC FLAGS_REG))])]
15045 "!TARGET_64BIT && TARGET_GNU2_TLS"
15047 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15048 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15051 (define_insn "*tls_dynamic_lea_32"
15052 [(set (match_operand:SI 0 "register_operand" "=r")
15053 (plus:SI (match_operand:SI 1 "register_operand" "b")
15055 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15056 UNSPEC_TLSDESC))))]
15057 "!TARGET_64BIT && TARGET_GNU2_TLS"
15058 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15059 [(set_attr "type" "lea")
15060 (set_attr "mode" "SI")
15061 (set_attr "length" "6")
15062 (set_attr "length_address" "4")])
15064 (define_insn "*tls_dynamic_call_32"
15065 [(set (match_operand:SI 0 "register_operand" "=a")
15066 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15067 (match_operand:SI 2 "register_operand" "0")
15068 ;; we have to make sure %ebx still points to the GOT
15069 (match_operand:SI 3 "register_operand" "b")
15072 (clobber (reg:CC FLAGS_REG))]
15073 "!TARGET_64BIT && TARGET_GNU2_TLS"
15074 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15075 [(set_attr "type" "call")
15076 (set_attr "length" "2")
15077 (set_attr "length_address" "0")])
15079 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15080 [(set (match_operand:SI 0 "register_operand" "=&a")
15082 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15083 (match_operand:SI 4 "" "")
15084 (match_operand:SI 2 "register_operand" "b")
15087 (const:SI (unspec:SI
15088 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15090 (clobber (reg:CC FLAGS_REG))]
15091 "!TARGET_64BIT && TARGET_GNU2_TLS"
15094 [(set (match_dup 0) (match_dup 5))]
15096 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15097 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15100 (define_expand "tls_dynamic_gnu2_64"
15101 [(set (match_dup 2)
15102 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15105 [(set (match_operand:DI 0 "register_operand" "")
15106 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15108 (clobber (reg:CC FLAGS_REG))])]
15109 "TARGET_64BIT && TARGET_GNU2_TLS"
15111 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15112 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15115 (define_insn "*tls_dynamic_lea_64"
15116 [(set (match_operand:DI 0 "register_operand" "=r")
15117 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15119 "TARGET_64BIT && TARGET_GNU2_TLS"
15120 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15121 [(set_attr "type" "lea")
15122 (set_attr "mode" "DI")
15123 (set_attr "length" "7")
15124 (set_attr "length_address" "4")])
15126 (define_insn "*tls_dynamic_call_64"
15127 [(set (match_operand:DI 0 "register_operand" "=a")
15128 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15129 (match_operand:DI 2 "register_operand" "0")
15132 (clobber (reg:CC FLAGS_REG))]
15133 "TARGET_64BIT && TARGET_GNU2_TLS"
15134 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15135 [(set_attr "type" "call")
15136 (set_attr "length" "2")
15137 (set_attr "length_address" "0")])
15139 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15140 [(set (match_operand:DI 0 "register_operand" "=&a")
15142 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15143 (match_operand:DI 3 "" "")
15146 (const:DI (unspec:DI
15147 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15149 (clobber (reg:CC FLAGS_REG))]
15150 "TARGET_64BIT && TARGET_GNU2_TLS"
15153 [(set (match_dup 0) (match_dup 4))]
15155 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15156 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15161 ;; These patterns match the binary 387 instructions for addM3, subM3,
15162 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15163 ;; SFmode. The first is the normal insn, the second the same insn but
15164 ;; with one operand a conversion, and the third the same insn but with
15165 ;; the other operand a conversion. The conversion may be SFmode or
15166 ;; SImode if the target mode DFmode, but only SImode if the target mode
15169 ;; Gcc is slightly more smart about handling normal two address instructions
15170 ;; so use special patterns for add and mull.
15172 (define_insn "*fop_<mode>_comm_mixed_avx"
15173 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15174 (match_operator:MODEF 3 "binary_fp_operator"
15175 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15176 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15177 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15178 && COMMUTATIVE_ARITH_P (operands[3])
15179 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15180 "* return output_387_binary_op (insn, operands);"
15181 [(set (attr "type")
15182 (if_then_else (eq_attr "alternative" "1")
15183 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15184 (const_string "ssemul")
15185 (const_string "sseadd"))
15186 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15187 (const_string "fmul")
15188 (const_string "fop"))))
15189 (set_attr "prefix" "orig,maybe_vex")
15190 (set_attr "mode" "<MODE>")])
15192 (define_insn "*fop_<mode>_comm_mixed"
15193 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15194 (match_operator:MODEF 3 "binary_fp_operator"
15195 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15196 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15197 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15198 && COMMUTATIVE_ARITH_P (operands[3])
15199 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15200 "* return output_387_binary_op (insn, operands);"
15201 [(set (attr "type")
15202 (if_then_else (eq_attr "alternative" "1")
15203 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15204 (const_string "ssemul")
15205 (const_string "sseadd"))
15206 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15207 (const_string "fmul")
15208 (const_string "fop"))))
15209 (set_attr "mode" "<MODE>")])
15211 (define_insn "*fop_<mode>_comm_avx"
15212 [(set (match_operand:MODEF 0 "register_operand" "=x")
15213 (match_operator:MODEF 3 "binary_fp_operator"
15214 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
15215 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15216 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15217 && COMMUTATIVE_ARITH_P (operands[3])
15218 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15219 "* return output_387_binary_op (insn, operands);"
15220 [(set (attr "type")
15221 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15222 (const_string "ssemul")
15223 (const_string "sseadd")))
15224 (set_attr "prefix" "vex")
15225 (set_attr "mode" "<MODE>")])
15227 (define_insn "*fop_<mode>_comm_sse"
15228 [(set (match_operand:MODEF 0 "register_operand" "=x")
15229 (match_operator:MODEF 3 "binary_fp_operator"
15230 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15231 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15232 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15233 && COMMUTATIVE_ARITH_P (operands[3])
15234 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15235 "* return output_387_binary_op (insn, operands);"
15236 [(set (attr "type")
15237 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15238 (const_string "ssemul")
15239 (const_string "sseadd")))
15240 (set_attr "mode" "<MODE>")])
15242 (define_insn "*fop_<mode>_comm_i387"
15243 [(set (match_operand:MODEF 0 "register_operand" "=f")
15244 (match_operator:MODEF 3 "binary_fp_operator"
15245 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15246 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15247 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15248 && COMMUTATIVE_ARITH_P (operands[3])
15249 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15250 "* return output_387_binary_op (insn, operands);"
15251 [(set (attr "type")
15252 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15253 (const_string "fmul")
15254 (const_string "fop")))
15255 (set_attr "mode" "<MODE>")])
15257 (define_insn "*fop_<mode>_1_mixed_avx"
15258 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15259 (match_operator:MODEF 3 "binary_fp_operator"
15260 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
15261 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15262 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15263 && !COMMUTATIVE_ARITH_P (operands[3])
15264 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15265 "* return output_387_binary_op (insn, operands);"
15266 [(set (attr "type")
15267 (cond [(and (eq_attr "alternative" "2")
15268 (match_operand:MODEF 3 "mult_operator" ""))
15269 (const_string "ssemul")
15270 (and (eq_attr "alternative" "2")
15271 (match_operand:MODEF 3 "div_operator" ""))
15272 (const_string "ssediv")
15273 (eq_attr "alternative" "2")
15274 (const_string "sseadd")
15275 (match_operand:MODEF 3 "mult_operator" "")
15276 (const_string "fmul")
15277 (match_operand:MODEF 3 "div_operator" "")
15278 (const_string "fdiv")
15280 (const_string "fop")))
15281 (set_attr "prefix" "orig,orig,maybe_vex")
15282 (set_attr "mode" "<MODE>")])
15284 (define_insn "*fop_<mode>_1_mixed"
15285 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15286 (match_operator:MODEF 3 "binary_fp_operator"
15287 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15288 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15289 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15290 && !COMMUTATIVE_ARITH_P (operands[3])
15291 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15292 "* return output_387_binary_op (insn, operands);"
15293 [(set (attr "type")
15294 (cond [(and (eq_attr "alternative" "2")
15295 (match_operand:MODEF 3 "mult_operator" ""))
15296 (const_string "ssemul")
15297 (and (eq_attr "alternative" "2")
15298 (match_operand:MODEF 3 "div_operator" ""))
15299 (const_string "ssediv")
15300 (eq_attr "alternative" "2")
15301 (const_string "sseadd")
15302 (match_operand:MODEF 3 "mult_operator" "")
15303 (const_string "fmul")
15304 (match_operand:MODEF 3 "div_operator" "")
15305 (const_string "fdiv")
15307 (const_string "fop")))
15308 (set_attr "mode" "<MODE>")])
15310 (define_insn "*rcpsf2_sse"
15311 [(set (match_operand:SF 0 "register_operand" "=x")
15312 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15315 "%vrcpss\t{%1, %d0|%d0, %1}"
15316 [(set_attr "type" "sse")
15317 (set_attr "atom_sse_attr" "rcp")
15318 (set_attr "prefix" "maybe_vex")
15319 (set_attr "mode" "SF")])
15321 (define_insn "*fop_<mode>_1_avx"
15322 [(set (match_operand:MODEF 0 "register_operand" "=x")
15323 (match_operator:MODEF 3 "binary_fp_operator"
15324 [(match_operand:MODEF 1 "register_operand" "x")
15325 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15326 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15327 && !COMMUTATIVE_ARITH_P (operands[3])"
15328 "* return output_387_binary_op (insn, operands);"
15329 [(set (attr "type")
15330 (cond [(match_operand:MODEF 3 "mult_operator" "")
15331 (const_string "ssemul")
15332 (match_operand:MODEF 3 "div_operator" "")
15333 (const_string "ssediv")
15335 (const_string "sseadd")))
15336 (set_attr "prefix" "vex")
15337 (set_attr "mode" "<MODE>")])
15339 (define_insn "*fop_<mode>_1_sse"
15340 [(set (match_operand:MODEF 0 "register_operand" "=x")
15341 (match_operator:MODEF 3 "binary_fp_operator"
15342 [(match_operand:MODEF 1 "register_operand" "0")
15343 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15344 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15345 && !COMMUTATIVE_ARITH_P (operands[3])"
15346 "* return output_387_binary_op (insn, operands);"
15347 [(set (attr "type")
15348 (cond [(match_operand:MODEF 3 "mult_operator" "")
15349 (const_string "ssemul")
15350 (match_operand:MODEF 3 "div_operator" "")
15351 (const_string "ssediv")
15353 (const_string "sseadd")))
15354 (set_attr "mode" "<MODE>")])
15356 ;; This pattern is not fully shadowed by the pattern above.
15357 (define_insn "*fop_<mode>_1_i387"
15358 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15359 (match_operator:MODEF 3 "binary_fp_operator"
15360 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15361 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15362 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15363 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15364 && !COMMUTATIVE_ARITH_P (operands[3])
15365 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15366 "* return output_387_binary_op (insn, operands);"
15367 [(set (attr "type")
15368 (cond [(match_operand:MODEF 3 "mult_operator" "")
15369 (const_string "fmul")
15370 (match_operand:MODEF 3 "div_operator" "")
15371 (const_string "fdiv")
15373 (const_string "fop")))
15374 (set_attr "mode" "<MODE>")])
15376 ;; ??? Add SSE splitters for these!
15377 (define_insn "*fop_<MODEF:mode>_2_i387"
15378 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15379 (match_operator:MODEF 3 "binary_fp_operator"
15381 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15382 (match_operand:MODEF 2 "register_operand" "0,0")]))]
15383 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15384 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15385 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15386 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15387 [(set (attr "type")
15388 (cond [(match_operand:MODEF 3 "mult_operator" "")
15389 (const_string "fmul")
15390 (match_operand:MODEF 3 "div_operator" "")
15391 (const_string "fdiv")
15393 (const_string "fop")))
15394 (set_attr "fp_int_src" "true")
15395 (set_attr "mode" "<X87MODEI12:MODE>")])
15397 (define_insn "*fop_<MODEF:mode>_3_i387"
15398 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15399 (match_operator:MODEF 3 "binary_fp_operator"
15400 [(match_operand:MODEF 1 "register_operand" "0,0")
15402 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15403 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15404 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15405 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15406 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15407 [(set (attr "type")
15408 (cond [(match_operand:MODEF 3 "mult_operator" "")
15409 (const_string "fmul")
15410 (match_operand:MODEF 3 "div_operator" "")
15411 (const_string "fdiv")
15413 (const_string "fop")))
15414 (set_attr "fp_int_src" "true")
15415 (set_attr "mode" "<MODE>")])
15417 (define_insn "*fop_df_4_i387"
15418 [(set (match_operand:DF 0 "register_operand" "=f,f")
15419 (match_operator:DF 3 "binary_fp_operator"
15421 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15422 (match_operand:DF 2 "register_operand" "0,f")]))]
15423 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15424 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15425 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15426 "* return output_387_binary_op (insn, operands);"
15427 [(set (attr "type")
15428 (cond [(match_operand:DF 3 "mult_operator" "")
15429 (const_string "fmul")
15430 (match_operand:DF 3 "div_operator" "")
15431 (const_string "fdiv")
15433 (const_string "fop")))
15434 (set_attr "mode" "SF")])
15436 (define_insn "*fop_df_5_i387"
15437 [(set (match_operand:DF 0 "register_operand" "=f,f")
15438 (match_operator:DF 3 "binary_fp_operator"
15439 [(match_operand:DF 1 "register_operand" "0,f")
15441 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15442 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15443 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15444 "* return output_387_binary_op (insn, operands);"
15445 [(set (attr "type")
15446 (cond [(match_operand:DF 3 "mult_operator" "")
15447 (const_string "fmul")
15448 (match_operand:DF 3 "div_operator" "")
15449 (const_string "fdiv")
15451 (const_string "fop")))
15452 (set_attr "mode" "SF")])
15454 (define_insn "*fop_df_6_i387"
15455 [(set (match_operand:DF 0 "register_operand" "=f,f")
15456 (match_operator:DF 3 "binary_fp_operator"
15458 (match_operand:SF 1 "register_operand" "0,f"))
15460 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15461 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15462 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15463 "* return output_387_binary_op (insn, operands);"
15464 [(set (attr "type")
15465 (cond [(match_operand:DF 3 "mult_operator" "")
15466 (const_string "fmul")
15467 (match_operand:DF 3 "div_operator" "")
15468 (const_string "fdiv")
15470 (const_string "fop")))
15471 (set_attr "mode" "SF")])
15473 (define_insn "*fop_xf_comm_i387"
15474 [(set (match_operand:XF 0 "register_operand" "=f")
15475 (match_operator:XF 3 "binary_fp_operator"
15476 [(match_operand:XF 1 "register_operand" "%0")
15477 (match_operand:XF 2 "register_operand" "f")]))]
15479 && COMMUTATIVE_ARITH_P (operands[3])"
15480 "* return output_387_binary_op (insn, operands);"
15481 [(set (attr "type")
15482 (if_then_else (match_operand:XF 3 "mult_operator" "")
15483 (const_string "fmul")
15484 (const_string "fop")))
15485 (set_attr "mode" "XF")])
15487 (define_insn "*fop_xf_1_i387"
15488 [(set (match_operand:XF 0 "register_operand" "=f,f")
15489 (match_operator:XF 3 "binary_fp_operator"
15490 [(match_operand:XF 1 "register_operand" "0,f")
15491 (match_operand:XF 2 "register_operand" "f,0")]))]
15493 && !COMMUTATIVE_ARITH_P (operands[3])"
15494 "* return output_387_binary_op (insn, operands);"
15495 [(set (attr "type")
15496 (cond [(match_operand:XF 3 "mult_operator" "")
15497 (const_string "fmul")
15498 (match_operand:XF 3 "div_operator" "")
15499 (const_string "fdiv")
15501 (const_string "fop")))
15502 (set_attr "mode" "XF")])
15504 (define_insn "*fop_xf_2_i387"
15505 [(set (match_operand:XF 0 "register_operand" "=f,f")
15506 (match_operator:XF 3 "binary_fp_operator"
15508 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15509 (match_operand:XF 2 "register_operand" "0,0")]))]
15510 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15511 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15512 [(set (attr "type")
15513 (cond [(match_operand:XF 3 "mult_operator" "")
15514 (const_string "fmul")
15515 (match_operand:XF 3 "div_operator" "")
15516 (const_string "fdiv")
15518 (const_string "fop")))
15519 (set_attr "fp_int_src" "true")
15520 (set_attr "mode" "<MODE>")])
15522 (define_insn "*fop_xf_3_i387"
15523 [(set (match_operand:XF 0 "register_operand" "=f,f")
15524 (match_operator:XF 3 "binary_fp_operator"
15525 [(match_operand:XF 1 "register_operand" "0,0")
15527 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15528 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15529 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15530 [(set (attr "type")
15531 (cond [(match_operand:XF 3 "mult_operator" "")
15532 (const_string "fmul")
15533 (match_operand:XF 3 "div_operator" "")
15534 (const_string "fdiv")
15536 (const_string "fop")))
15537 (set_attr "fp_int_src" "true")
15538 (set_attr "mode" "<MODE>")])
15540 (define_insn "*fop_xf_4_i387"
15541 [(set (match_operand:XF 0 "register_operand" "=f,f")
15542 (match_operator:XF 3 "binary_fp_operator"
15544 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15545 (match_operand:XF 2 "register_operand" "0,f")]))]
15547 "* return output_387_binary_op (insn, operands);"
15548 [(set (attr "type")
15549 (cond [(match_operand:XF 3 "mult_operator" "")
15550 (const_string "fmul")
15551 (match_operand:XF 3 "div_operator" "")
15552 (const_string "fdiv")
15554 (const_string "fop")))
15555 (set_attr "mode" "<MODE>")])
15557 (define_insn "*fop_xf_5_i387"
15558 [(set (match_operand:XF 0 "register_operand" "=f,f")
15559 (match_operator:XF 3 "binary_fp_operator"
15560 [(match_operand:XF 1 "register_operand" "0,f")
15562 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15564 "* return output_387_binary_op (insn, operands);"
15565 [(set (attr "type")
15566 (cond [(match_operand:XF 3 "mult_operator" "")
15567 (const_string "fmul")
15568 (match_operand:XF 3 "div_operator" "")
15569 (const_string "fdiv")
15571 (const_string "fop")))
15572 (set_attr "mode" "<MODE>")])
15574 (define_insn "*fop_xf_6_i387"
15575 [(set (match_operand:XF 0 "register_operand" "=f,f")
15576 (match_operator:XF 3 "binary_fp_operator"
15578 (match_operand:MODEF 1 "register_operand" "0,f"))
15580 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15582 "* return output_387_binary_op (insn, operands);"
15583 [(set (attr "type")
15584 (cond [(match_operand:XF 3 "mult_operator" "")
15585 (const_string "fmul")
15586 (match_operand:XF 3 "div_operator" "")
15587 (const_string "fdiv")
15589 (const_string "fop")))
15590 (set_attr "mode" "<MODE>")])
15593 [(set (match_operand 0 "register_operand" "")
15594 (match_operator 3 "binary_fp_operator"
15595 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15596 (match_operand 2 "register_operand" "")]))]
15598 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15599 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15602 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15603 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15604 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15605 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15606 GET_MODE (operands[3]),
15609 ix86_free_from_memory (GET_MODE (operands[1]));
15614 [(set (match_operand 0 "register_operand" "")
15615 (match_operator 3 "binary_fp_operator"
15616 [(match_operand 1 "register_operand" "")
15617 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15619 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15620 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15623 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15624 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15625 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15626 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15627 GET_MODE (operands[3]),
15630 ix86_free_from_memory (GET_MODE (operands[2]));
15634 ;; FPU special functions.
15636 ;; This pattern implements a no-op XFmode truncation for
15637 ;; all fancy i386 XFmode math functions.
15639 (define_insn "truncxf<mode>2_i387_noop_unspec"
15640 [(set (match_operand:MODEF 0 "register_operand" "=f")
15641 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15642 UNSPEC_TRUNC_NOOP))]
15643 "TARGET_USE_FANCY_MATH_387"
15644 "* return output_387_reg_move (insn, operands);"
15645 [(set_attr "type" "fmov")
15646 (set_attr "mode" "<MODE>")])
15648 (define_insn "sqrtxf2"
15649 [(set (match_operand:XF 0 "register_operand" "=f")
15650 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15651 "TARGET_USE_FANCY_MATH_387"
15653 [(set_attr "type" "fpspc")
15654 (set_attr "mode" "XF")
15655 (set_attr "athlon_decode" "direct")
15656 (set_attr "amdfam10_decode" "direct")])
15658 (define_insn "sqrt_extend<mode>xf2_i387"
15659 [(set (match_operand:XF 0 "register_operand" "=f")
15662 (match_operand:MODEF 1 "register_operand" "0"))))]
15663 "TARGET_USE_FANCY_MATH_387"
15665 [(set_attr "type" "fpspc")
15666 (set_attr "mode" "XF")
15667 (set_attr "athlon_decode" "direct")
15668 (set_attr "amdfam10_decode" "direct")])
15670 (define_insn "*rsqrtsf2_sse"
15671 [(set (match_operand:SF 0 "register_operand" "=x")
15672 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15675 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15676 [(set_attr "type" "sse")
15677 (set_attr "atom_sse_attr" "rcp")
15678 (set_attr "prefix" "maybe_vex")
15679 (set_attr "mode" "SF")])
15681 (define_expand "rsqrtsf2"
15682 [(set (match_operand:SF 0 "register_operand" "")
15683 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15687 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15691 (define_insn "*sqrt<mode>2_sse"
15692 [(set (match_operand:MODEF 0 "register_operand" "=x")
15694 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15695 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15696 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15697 [(set_attr "type" "sse")
15698 (set_attr "atom_sse_attr" "sqrt")
15699 (set_attr "prefix" "maybe_vex")
15700 (set_attr "mode" "<MODE>")
15701 (set_attr "athlon_decode" "*")
15702 (set_attr "amdfam10_decode" "*")])
15704 (define_expand "sqrt<mode>2"
15705 [(set (match_operand:MODEF 0 "register_operand" "")
15707 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15708 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15709 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15711 if (<MODE>mode == SFmode
15712 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
15713 && flag_finite_math_only && !flag_trapping_math
15714 && flag_unsafe_math_optimizations)
15716 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15720 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15722 rtx op0 = gen_reg_rtx (XFmode);
15723 rtx op1 = force_reg (<MODE>mode, operands[1]);
15725 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15726 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15731 (define_insn "fpremxf4_i387"
15732 [(set (match_operand:XF 0 "register_operand" "=f")
15733 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15734 (match_operand:XF 3 "register_operand" "1")]
15736 (set (match_operand:XF 1 "register_operand" "=u")
15737 (unspec:XF [(match_dup 2) (match_dup 3)]
15739 (set (reg:CCFP FPSR_REG)
15740 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15742 "TARGET_USE_FANCY_MATH_387"
15744 [(set_attr "type" "fpspc")
15745 (set_attr "mode" "XF")])
15747 (define_expand "fmodxf3"
15748 [(use (match_operand:XF 0 "register_operand" ""))
15749 (use (match_operand:XF 1 "general_operand" ""))
15750 (use (match_operand:XF 2 "general_operand" ""))]
15751 "TARGET_USE_FANCY_MATH_387"
15753 rtx label = gen_label_rtx ();
15755 rtx op1 = gen_reg_rtx (XFmode);
15756 rtx op2 = gen_reg_rtx (XFmode);
15758 emit_move_insn (op2, operands[2]);
15759 emit_move_insn (op1, operands[1]);
15761 emit_label (label);
15762 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15763 ix86_emit_fp_unordered_jump (label);
15764 LABEL_NUSES (label) = 1;
15766 emit_move_insn (operands[0], op1);
15770 (define_expand "fmod<mode>3"
15771 [(use (match_operand:MODEF 0 "register_operand" ""))
15772 (use (match_operand:MODEF 1 "general_operand" ""))
15773 (use (match_operand:MODEF 2 "general_operand" ""))]
15774 "TARGET_USE_FANCY_MATH_387"
15776 rtx label = gen_label_rtx ();
15778 rtx op1 = gen_reg_rtx (XFmode);
15779 rtx op2 = gen_reg_rtx (XFmode);
15781 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15782 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15784 emit_label (label);
15785 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15786 ix86_emit_fp_unordered_jump (label);
15787 LABEL_NUSES (label) = 1;
15789 /* Truncate the result properly for strict SSE math. */
15790 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15791 && !TARGET_MIX_SSE_I387)
15792 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15794 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15799 (define_insn "fprem1xf4_i387"
15800 [(set (match_operand:XF 0 "register_operand" "=f")
15801 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15802 (match_operand:XF 3 "register_operand" "1")]
15804 (set (match_operand:XF 1 "register_operand" "=u")
15805 (unspec:XF [(match_dup 2) (match_dup 3)]
15807 (set (reg:CCFP FPSR_REG)
15808 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15810 "TARGET_USE_FANCY_MATH_387"
15812 [(set_attr "type" "fpspc")
15813 (set_attr "mode" "XF")])
15815 (define_expand "remainderxf3"
15816 [(use (match_operand:XF 0 "register_operand" ""))
15817 (use (match_operand:XF 1 "general_operand" ""))
15818 (use (match_operand:XF 2 "general_operand" ""))]
15819 "TARGET_USE_FANCY_MATH_387"
15821 rtx label = gen_label_rtx ();
15823 rtx op1 = gen_reg_rtx (XFmode);
15824 rtx op2 = gen_reg_rtx (XFmode);
15826 emit_move_insn (op2, operands[2]);
15827 emit_move_insn (op1, operands[1]);
15829 emit_label (label);
15830 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15831 ix86_emit_fp_unordered_jump (label);
15832 LABEL_NUSES (label) = 1;
15834 emit_move_insn (operands[0], op1);
15838 (define_expand "remainder<mode>3"
15839 [(use (match_operand:MODEF 0 "register_operand" ""))
15840 (use (match_operand:MODEF 1 "general_operand" ""))
15841 (use (match_operand:MODEF 2 "general_operand" ""))]
15842 "TARGET_USE_FANCY_MATH_387"
15844 rtx label = gen_label_rtx ();
15846 rtx op1 = gen_reg_rtx (XFmode);
15847 rtx op2 = gen_reg_rtx (XFmode);
15849 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15850 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15852 emit_label (label);
15854 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15855 ix86_emit_fp_unordered_jump (label);
15856 LABEL_NUSES (label) = 1;
15858 /* Truncate the result properly for strict SSE math. */
15859 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15860 && !TARGET_MIX_SSE_I387)
15861 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15863 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15868 (define_insn "*sinxf2_i387"
15869 [(set (match_operand:XF 0 "register_operand" "=f")
15870 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15871 "TARGET_USE_FANCY_MATH_387
15872 && flag_unsafe_math_optimizations"
15874 [(set_attr "type" "fpspc")
15875 (set_attr "mode" "XF")])
15877 (define_insn "*sin_extend<mode>xf2_i387"
15878 [(set (match_operand:XF 0 "register_operand" "=f")
15879 (unspec:XF [(float_extend:XF
15880 (match_operand:MODEF 1 "register_operand" "0"))]
15882 "TARGET_USE_FANCY_MATH_387
15883 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15884 || TARGET_MIX_SSE_I387)
15885 && flag_unsafe_math_optimizations"
15887 [(set_attr "type" "fpspc")
15888 (set_attr "mode" "XF")])
15890 (define_insn "*cosxf2_i387"
15891 [(set (match_operand:XF 0 "register_operand" "=f")
15892 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15893 "TARGET_USE_FANCY_MATH_387
15894 && flag_unsafe_math_optimizations"
15896 [(set_attr "type" "fpspc")
15897 (set_attr "mode" "XF")])
15899 (define_insn "*cos_extend<mode>xf2_i387"
15900 [(set (match_operand:XF 0 "register_operand" "=f")
15901 (unspec:XF [(float_extend:XF
15902 (match_operand:MODEF 1 "register_operand" "0"))]
15904 "TARGET_USE_FANCY_MATH_387
15905 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15906 || TARGET_MIX_SSE_I387)
15907 && flag_unsafe_math_optimizations"
15909 [(set_attr "type" "fpspc")
15910 (set_attr "mode" "XF")])
15912 ;; When sincos pattern is defined, sin and cos builtin functions will be
15913 ;; expanded to sincos pattern with one of its outputs left unused.
15914 ;; CSE pass will figure out if two sincos patterns can be combined,
15915 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15916 ;; depending on the unused output.
15918 (define_insn "sincosxf3"
15919 [(set (match_operand:XF 0 "register_operand" "=f")
15920 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15921 UNSPEC_SINCOS_COS))
15922 (set (match_operand:XF 1 "register_operand" "=u")
15923 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15924 "TARGET_USE_FANCY_MATH_387
15925 && flag_unsafe_math_optimizations"
15927 [(set_attr "type" "fpspc")
15928 (set_attr "mode" "XF")])
15931 [(set (match_operand:XF 0 "register_operand" "")
15932 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15933 UNSPEC_SINCOS_COS))
15934 (set (match_operand:XF 1 "register_operand" "")
15935 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15936 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15937 && !(reload_completed || reload_in_progress)"
15938 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15942 [(set (match_operand:XF 0 "register_operand" "")
15943 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15944 UNSPEC_SINCOS_COS))
15945 (set (match_operand:XF 1 "register_operand" "")
15946 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15947 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15948 && !(reload_completed || reload_in_progress)"
15949 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15952 (define_insn "sincos_extend<mode>xf3_i387"
15953 [(set (match_operand:XF 0 "register_operand" "=f")
15954 (unspec:XF [(float_extend:XF
15955 (match_operand:MODEF 2 "register_operand" "0"))]
15956 UNSPEC_SINCOS_COS))
15957 (set (match_operand:XF 1 "register_operand" "=u")
15958 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15959 "TARGET_USE_FANCY_MATH_387
15960 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15961 || TARGET_MIX_SSE_I387)
15962 && flag_unsafe_math_optimizations"
15964 [(set_attr "type" "fpspc")
15965 (set_attr "mode" "XF")])
15968 [(set (match_operand:XF 0 "register_operand" "")
15969 (unspec:XF [(float_extend:XF
15970 (match_operand:MODEF 2 "register_operand" ""))]
15971 UNSPEC_SINCOS_COS))
15972 (set (match_operand:XF 1 "register_operand" "")
15973 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15974 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15975 && !(reload_completed || reload_in_progress)"
15976 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15980 [(set (match_operand:XF 0 "register_operand" "")
15981 (unspec:XF [(float_extend:XF
15982 (match_operand:MODEF 2 "register_operand" ""))]
15983 UNSPEC_SINCOS_COS))
15984 (set (match_operand:XF 1 "register_operand" "")
15985 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15986 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15987 && !(reload_completed || reload_in_progress)"
15988 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15991 (define_expand "sincos<mode>3"
15992 [(use (match_operand:MODEF 0 "register_operand" ""))
15993 (use (match_operand:MODEF 1 "register_operand" ""))
15994 (use (match_operand:MODEF 2 "register_operand" ""))]
15995 "TARGET_USE_FANCY_MATH_387
15996 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15997 || TARGET_MIX_SSE_I387)
15998 && flag_unsafe_math_optimizations"
16000 rtx op0 = gen_reg_rtx (XFmode);
16001 rtx op1 = gen_reg_rtx (XFmode);
16003 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16004 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16005 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16009 (define_insn "fptanxf4_i387"
16010 [(set (match_operand:XF 0 "register_operand" "=f")
16011 (match_operand:XF 3 "const_double_operand" "F"))
16012 (set (match_operand:XF 1 "register_operand" "=u")
16013 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16015 "TARGET_USE_FANCY_MATH_387
16016 && flag_unsafe_math_optimizations
16017 && standard_80387_constant_p (operands[3]) == 2"
16019 [(set_attr "type" "fpspc")
16020 (set_attr "mode" "XF")])
16022 (define_insn "fptan_extend<mode>xf4_i387"
16023 [(set (match_operand:MODEF 0 "register_operand" "=f")
16024 (match_operand:MODEF 3 "const_double_operand" "F"))
16025 (set (match_operand:XF 1 "register_operand" "=u")
16026 (unspec:XF [(float_extend:XF
16027 (match_operand:MODEF 2 "register_operand" "0"))]
16029 "TARGET_USE_FANCY_MATH_387
16030 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16031 || TARGET_MIX_SSE_I387)
16032 && flag_unsafe_math_optimizations
16033 && standard_80387_constant_p (operands[3]) == 2"
16035 [(set_attr "type" "fpspc")
16036 (set_attr "mode" "XF")])
16038 (define_expand "tanxf2"
16039 [(use (match_operand:XF 0 "register_operand" ""))
16040 (use (match_operand:XF 1 "register_operand" ""))]
16041 "TARGET_USE_FANCY_MATH_387
16042 && flag_unsafe_math_optimizations"
16044 rtx one = gen_reg_rtx (XFmode);
16045 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16047 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16051 (define_expand "tan<mode>2"
16052 [(use (match_operand:MODEF 0 "register_operand" ""))
16053 (use (match_operand:MODEF 1 "register_operand" ""))]
16054 "TARGET_USE_FANCY_MATH_387
16055 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16056 || TARGET_MIX_SSE_I387)
16057 && flag_unsafe_math_optimizations"
16059 rtx op0 = gen_reg_rtx (XFmode);
16061 rtx one = gen_reg_rtx (<MODE>mode);
16062 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16064 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16065 operands[1], op2));
16066 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16070 (define_insn "*fpatanxf3_i387"
16071 [(set (match_operand:XF 0 "register_operand" "=f")
16072 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16073 (match_operand:XF 2 "register_operand" "u")]
16075 (clobber (match_scratch:XF 3 "=2"))]
16076 "TARGET_USE_FANCY_MATH_387
16077 && flag_unsafe_math_optimizations"
16079 [(set_attr "type" "fpspc")
16080 (set_attr "mode" "XF")])
16082 (define_insn "fpatan_extend<mode>xf3_i387"
16083 [(set (match_operand:XF 0 "register_operand" "=f")
16084 (unspec:XF [(float_extend:XF
16085 (match_operand:MODEF 1 "register_operand" "0"))
16087 (match_operand:MODEF 2 "register_operand" "u"))]
16089 (clobber (match_scratch:XF 3 "=2"))]
16090 "TARGET_USE_FANCY_MATH_387
16091 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16092 || TARGET_MIX_SSE_I387)
16093 && flag_unsafe_math_optimizations"
16095 [(set_attr "type" "fpspc")
16096 (set_attr "mode" "XF")])
16098 (define_expand "atan2xf3"
16099 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16100 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16101 (match_operand:XF 1 "register_operand" "")]
16103 (clobber (match_scratch:XF 3 ""))])]
16104 "TARGET_USE_FANCY_MATH_387
16105 && flag_unsafe_math_optimizations"
16108 (define_expand "atan2<mode>3"
16109 [(use (match_operand:MODEF 0 "register_operand" ""))
16110 (use (match_operand:MODEF 1 "register_operand" ""))
16111 (use (match_operand:MODEF 2 "register_operand" ""))]
16112 "TARGET_USE_FANCY_MATH_387
16113 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16114 || TARGET_MIX_SSE_I387)
16115 && flag_unsafe_math_optimizations"
16117 rtx op0 = gen_reg_rtx (XFmode);
16119 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16120 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16124 (define_expand "atanxf2"
16125 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16126 (unspec:XF [(match_dup 2)
16127 (match_operand:XF 1 "register_operand" "")]
16129 (clobber (match_scratch:XF 3 ""))])]
16130 "TARGET_USE_FANCY_MATH_387
16131 && flag_unsafe_math_optimizations"
16133 operands[2] = gen_reg_rtx (XFmode);
16134 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16137 (define_expand "atan<mode>2"
16138 [(use (match_operand:MODEF 0 "register_operand" ""))
16139 (use (match_operand:MODEF 1 "register_operand" ""))]
16140 "TARGET_USE_FANCY_MATH_387
16141 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16142 || TARGET_MIX_SSE_I387)
16143 && flag_unsafe_math_optimizations"
16145 rtx op0 = gen_reg_rtx (XFmode);
16147 rtx op2 = gen_reg_rtx (<MODE>mode);
16148 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16150 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16151 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16155 (define_expand "asinxf2"
16156 [(set (match_dup 2)
16157 (mult:XF (match_operand:XF 1 "register_operand" "")
16159 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16160 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16161 (parallel [(set (match_operand:XF 0 "register_operand" "")
16162 (unspec:XF [(match_dup 5) (match_dup 1)]
16164 (clobber (match_scratch:XF 6 ""))])]
16165 "TARGET_USE_FANCY_MATH_387
16166 && flag_unsafe_math_optimizations"
16170 if (optimize_insn_for_size_p ())
16173 for (i = 2; i < 6; i++)
16174 operands[i] = gen_reg_rtx (XFmode);
16176 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16179 (define_expand "asin<mode>2"
16180 [(use (match_operand:MODEF 0 "register_operand" ""))
16181 (use (match_operand:MODEF 1 "general_operand" ""))]
16182 "TARGET_USE_FANCY_MATH_387
16183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16184 || TARGET_MIX_SSE_I387)
16185 && flag_unsafe_math_optimizations"
16187 rtx op0 = gen_reg_rtx (XFmode);
16188 rtx op1 = gen_reg_rtx (XFmode);
16190 if (optimize_insn_for_size_p ())
16193 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16194 emit_insn (gen_asinxf2 (op0, op1));
16195 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16199 (define_expand "acosxf2"
16200 [(set (match_dup 2)
16201 (mult:XF (match_operand:XF 1 "register_operand" "")
16203 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16204 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16205 (parallel [(set (match_operand:XF 0 "register_operand" "")
16206 (unspec:XF [(match_dup 1) (match_dup 5)]
16208 (clobber (match_scratch:XF 6 ""))])]
16209 "TARGET_USE_FANCY_MATH_387
16210 && flag_unsafe_math_optimizations"
16214 if (optimize_insn_for_size_p ())
16217 for (i = 2; i < 6; i++)
16218 operands[i] = gen_reg_rtx (XFmode);
16220 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16223 (define_expand "acos<mode>2"
16224 [(use (match_operand:MODEF 0 "register_operand" ""))
16225 (use (match_operand:MODEF 1 "general_operand" ""))]
16226 "TARGET_USE_FANCY_MATH_387
16227 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16228 || TARGET_MIX_SSE_I387)
16229 && flag_unsafe_math_optimizations"
16231 rtx op0 = gen_reg_rtx (XFmode);
16232 rtx op1 = gen_reg_rtx (XFmode);
16234 if (optimize_insn_for_size_p ())
16237 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16238 emit_insn (gen_acosxf2 (op0, op1));
16239 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16243 (define_insn "fyl2xxf3_i387"
16244 [(set (match_operand:XF 0 "register_operand" "=f")
16245 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16246 (match_operand:XF 2 "register_operand" "u")]
16248 (clobber (match_scratch:XF 3 "=2"))]
16249 "TARGET_USE_FANCY_MATH_387
16250 && flag_unsafe_math_optimizations"
16252 [(set_attr "type" "fpspc")
16253 (set_attr "mode" "XF")])
16255 (define_insn "fyl2x_extend<mode>xf3_i387"
16256 [(set (match_operand:XF 0 "register_operand" "=f")
16257 (unspec:XF [(float_extend:XF
16258 (match_operand:MODEF 1 "register_operand" "0"))
16259 (match_operand:XF 2 "register_operand" "u")]
16261 (clobber (match_scratch:XF 3 "=2"))]
16262 "TARGET_USE_FANCY_MATH_387
16263 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16264 || TARGET_MIX_SSE_I387)
16265 && flag_unsafe_math_optimizations"
16267 [(set_attr "type" "fpspc")
16268 (set_attr "mode" "XF")])
16270 (define_expand "logxf2"
16271 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16272 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16273 (match_dup 2)] UNSPEC_FYL2X))
16274 (clobber (match_scratch:XF 3 ""))])]
16275 "TARGET_USE_FANCY_MATH_387
16276 && flag_unsafe_math_optimizations"
16278 operands[2] = gen_reg_rtx (XFmode);
16279 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16282 (define_expand "log<mode>2"
16283 [(use (match_operand:MODEF 0 "register_operand" ""))
16284 (use (match_operand:MODEF 1 "register_operand" ""))]
16285 "TARGET_USE_FANCY_MATH_387
16286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16287 || TARGET_MIX_SSE_I387)
16288 && flag_unsafe_math_optimizations"
16290 rtx op0 = gen_reg_rtx (XFmode);
16292 rtx op2 = gen_reg_rtx (XFmode);
16293 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16295 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16296 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16300 (define_expand "log10xf2"
16301 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16302 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16303 (match_dup 2)] UNSPEC_FYL2X))
16304 (clobber (match_scratch:XF 3 ""))])]
16305 "TARGET_USE_FANCY_MATH_387
16306 && flag_unsafe_math_optimizations"
16308 operands[2] = gen_reg_rtx (XFmode);
16309 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16312 (define_expand "log10<mode>2"
16313 [(use (match_operand:MODEF 0 "register_operand" ""))
16314 (use (match_operand:MODEF 1 "register_operand" ""))]
16315 "TARGET_USE_FANCY_MATH_387
16316 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16317 || TARGET_MIX_SSE_I387)
16318 && flag_unsafe_math_optimizations"
16320 rtx op0 = gen_reg_rtx (XFmode);
16322 rtx op2 = gen_reg_rtx (XFmode);
16323 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16325 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16326 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16330 (define_expand "log2xf2"
16331 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16332 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16333 (match_dup 2)] UNSPEC_FYL2X))
16334 (clobber (match_scratch:XF 3 ""))])]
16335 "TARGET_USE_FANCY_MATH_387
16336 && flag_unsafe_math_optimizations"
16338 operands[2] = gen_reg_rtx (XFmode);
16339 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16342 (define_expand "log2<mode>2"
16343 [(use (match_operand:MODEF 0 "register_operand" ""))
16344 (use (match_operand:MODEF 1 "register_operand" ""))]
16345 "TARGET_USE_FANCY_MATH_387
16346 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16347 || TARGET_MIX_SSE_I387)
16348 && flag_unsafe_math_optimizations"
16350 rtx op0 = gen_reg_rtx (XFmode);
16352 rtx op2 = gen_reg_rtx (XFmode);
16353 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16355 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16356 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16360 (define_insn "fyl2xp1xf3_i387"
16361 [(set (match_operand:XF 0 "register_operand" "=f")
16362 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16363 (match_operand:XF 2 "register_operand" "u")]
16365 (clobber (match_scratch:XF 3 "=2"))]
16366 "TARGET_USE_FANCY_MATH_387
16367 && flag_unsafe_math_optimizations"
16369 [(set_attr "type" "fpspc")
16370 (set_attr "mode" "XF")])
16372 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16373 [(set (match_operand:XF 0 "register_operand" "=f")
16374 (unspec:XF [(float_extend:XF
16375 (match_operand:MODEF 1 "register_operand" "0"))
16376 (match_operand:XF 2 "register_operand" "u")]
16378 (clobber (match_scratch:XF 3 "=2"))]
16379 "TARGET_USE_FANCY_MATH_387
16380 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16381 || TARGET_MIX_SSE_I387)
16382 && flag_unsafe_math_optimizations"
16384 [(set_attr "type" "fpspc")
16385 (set_attr "mode" "XF")])
16387 (define_expand "log1pxf2"
16388 [(use (match_operand:XF 0 "register_operand" ""))
16389 (use (match_operand:XF 1 "register_operand" ""))]
16390 "TARGET_USE_FANCY_MATH_387
16391 && flag_unsafe_math_optimizations"
16393 if (optimize_insn_for_size_p ())
16396 ix86_emit_i387_log1p (operands[0], operands[1]);
16400 (define_expand "log1p<mode>2"
16401 [(use (match_operand:MODEF 0 "register_operand" ""))
16402 (use (match_operand:MODEF 1 "register_operand" ""))]
16403 "TARGET_USE_FANCY_MATH_387
16404 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16405 || TARGET_MIX_SSE_I387)
16406 && flag_unsafe_math_optimizations"
16410 if (optimize_insn_for_size_p ())
16413 op0 = gen_reg_rtx (XFmode);
16415 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16417 ix86_emit_i387_log1p (op0, operands[1]);
16418 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16422 (define_insn "fxtractxf3_i387"
16423 [(set (match_operand:XF 0 "register_operand" "=f")
16424 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16425 UNSPEC_XTRACT_FRACT))
16426 (set (match_operand:XF 1 "register_operand" "=u")
16427 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16428 "TARGET_USE_FANCY_MATH_387
16429 && flag_unsafe_math_optimizations"
16431 [(set_attr "type" "fpspc")
16432 (set_attr "mode" "XF")])
16434 (define_insn "fxtract_extend<mode>xf3_i387"
16435 [(set (match_operand:XF 0 "register_operand" "=f")
16436 (unspec:XF [(float_extend:XF
16437 (match_operand:MODEF 2 "register_operand" "0"))]
16438 UNSPEC_XTRACT_FRACT))
16439 (set (match_operand:XF 1 "register_operand" "=u")
16440 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16441 "TARGET_USE_FANCY_MATH_387
16442 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16443 || TARGET_MIX_SSE_I387)
16444 && flag_unsafe_math_optimizations"
16446 [(set_attr "type" "fpspc")
16447 (set_attr "mode" "XF")])
16449 (define_expand "logbxf2"
16450 [(parallel [(set (match_dup 2)
16451 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16452 UNSPEC_XTRACT_FRACT))
16453 (set (match_operand:XF 0 "register_operand" "")
16454 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16455 "TARGET_USE_FANCY_MATH_387
16456 && flag_unsafe_math_optimizations"
16458 operands[2] = gen_reg_rtx (XFmode);
16461 (define_expand "logb<mode>2"
16462 [(use (match_operand:MODEF 0 "register_operand" ""))
16463 (use (match_operand:MODEF 1 "register_operand" ""))]
16464 "TARGET_USE_FANCY_MATH_387
16465 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16466 || TARGET_MIX_SSE_I387)
16467 && flag_unsafe_math_optimizations"
16469 rtx op0 = gen_reg_rtx (XFmode);
16470 rtx op1 = gen_reg_rtx (XFmode);
16472 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16473 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16477 (define_expand "ilogbxf2"
16478 [(use (match_operand:SI 0 "register_operand" ""))
16479 (use (match_operand:XF 1 "register_operand" ""))]
16480 "TARGET_USE_FANCY_MATH_387
16481 && flag_unsafe_math_optimizations"
16485 if (optimize_insn_for_size_p ())
16488 op0 = gen_reg_rtx (XFmode);
16489 op1 = gen_reg_rtx (XFmode);
16491 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16492 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16496 (define_expand "ilogb<mode>2"
16497 [(use (match_operand:SI 0 "register_operand" ""))
16498 (use (match_operand:MODEF 1 "register_operand" ""))]
16499 "TARGET_USE_FANCY_MATH_387
16500 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16501 || TARGET_MIX_SSE_I387)
16502 && flag_unsafe_math_optimizations"
16506 if (optimize_insn_for_size_p ())
16509 op0 = gen_reg_rtx (XFmode);
16510 op1 = gen_reg_rtx (XFmode);
16512 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16513 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16517 (define_insn "*f2xm1xf2_i387"
16518 [(set (match_operand:XF 0 "register_operand" "=f")
16519 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16521 "TARGET_USE_FANCY_MATH_387
16522 && flag_unsafe_math_optimizations"
16524 [(set_attr "type" "fpspc")
16525 (set_attr "mode" "XF")])
16527 (define_insn "*fscalexf4_i387"
16528 [(set (match_operand:XF 0 "register_operand" "=f")
16529 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16530 (match_operand:XF 3 "register_operand" "1")]
16531 UNSPEC_FSCALE_FRACT))
16532 (set (match_operand:XF 1 "register_operand" "=u")
16533 (unspec:XF [(match_dup 2) (match_dup 3)]
16534 UNSPEC_FSCALE_EXP))]
16535 "TARGET_USE_FANCY_MATH_387
16536 && flag_unsafe_math_optimizations"
16538 [(set_attr "type" "fpspc")
16539 (set_attr "mode" "XF")])
16541 (define_expand "expNcorexf3"
16542 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16543 (match_operand:XF 2 "register_operand" "")))
16544 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16545 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16546 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16547 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16548 (parallel [(set (match_operand:XF 0 "register_operand" "")
16549 (unspec:XF [(match_dup 8) (match_dup 4)]
16550 UNSPEC_FSCALE_FRACT))
16552 (unspec:XF [(match_dup 8) (match_dup 4)]
16553 UNSPEC_FSCALE_EXP))])]
16554 "TARGET_USE_FANCY_MATH_387
16555 && flag_unsafe_math_optimizations"
16559 if (optimize_insn_for_size_p ())
16562 for (i = 3; i < 10; i++)
16563 operands[i] = gen_reg_rtx (XFmode);
16565 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16568 (define_expand "expxf2"
16569 [(use (match_operand:XF 0 "register_operand" ""))
16570 (use (match_operand:XF 1 "register_operand" ""))]
16571 "TARGET_USE_FANCY_MATH_387
16572 && flag_unsafe_math_optimizations"
16576 if (optimize_insn_for_size_p ())
16579 op2 = gen_reg_rtx (XFmode);
16580 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16582 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16586 (define_expand "exp<mode>2"
16587 [(use (match_operand:MODEF 0 "register_operand" ""))
16588 (use (match_operand:MODEF 1 "general_operand" ""))]
16589 "TARGET_USE_FANCY_MATH_387
16590 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16591 || TARGET_MIX_SSE_I387)
16592 && flag_unsafe_math_optimizations"
16596 if (optimize_insn_for_size_p ())
16599 op0 = gen_reg_rtx (XFmode);
16600 op1 = gen_reg_rtx (XFmode);
16602 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16603 emit_insn (gen_expxf2 (op0, op1));
16604 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16608 (define_expand "exp10xf2"
16609 [(use (match_operand:XF 0 "register_operand" ""))
16610 (use (match_operand:XF 1 "register_operand" ""))]
16611 "TARGET_USE_FANCY_MATH_387
16612 && flag_unsafe_math_optimizations"
16616 if (optimize_insn_for_size_p ())
16619 op2 = gen_reg_rtx (XFmode);
16620 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16622 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16626 (define_expand "exp10<mode>2"
16627 [(use (match_operand:MODEF 0 "register_operand" ""))
16628 (use (match_operand:MODEF 1 "general_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"
16636 if (optimize_insn_for_size_p ())
16639 op0 = gen_reg_rtx (XFmode);
16640 op1 = gen_reg_rtx (XFmode);
16642 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16643 emit_insn (gen_exp10xf2 (op0, op1));
16644 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16648 (define_expand "exp2xf2"
16649 [(use (match_operand:XF 0 "register_operand" ""))
16650 (use (match_operand:XF 1 "register_operand" ""))]
16651 "TARGET_USE_FANCY_MATH_387
16652 && flag_unsafe_math_optimizations"
16656 if (optimize_insn_for_size_p ())
16659 op2 = gen_reg_rtx (XFmode);
16660 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16662 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16666 (define_expand "exp2<mode>2"
16667 [(use (match_operand:MODEF 0 "register_operand" ""))
16668 (use (match_operand:MODEF 1 "general_operand" ""))]
16669 "TARGET_USE_FANCY_MATH_387
16670 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16671 || TARGET_MIX_SSE_I387)
16672 && flag_unsafe_math_optimizations"
16676 if (optimize_insn_for_size_p ())
16679 op0 = gen_reg_rtx (XFmode);
16680 op1 = gen_reg_rtx (XFmode);
16682 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16683 emit_insn (gen_exp2xf2 (op0, op1));
16684 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16688 (define_expand "expm1xf2"
16689 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16691 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16692 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16693 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16694 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16695 (parallel [(set (match_dup 7)
16696 (unspec:XF [(match_dup 6) (match_dup 4)]
16697 UNSPEC_FSCALE_FRACT))
16699 (unspec:XF [(match_dup 6) (match_dup 4)]
16700 UNSPEC_FSCALE_EXP))])
16701 (parallel [(set (match_dup 10)
16702 (unspec:XF [(match_dup 9) (match_dup 8)]
16703 UNSPEC_FSCALE_FRACT))
16704 (set (match_dup 11)
16705 (unspec:XF [(match_dup 9) (match_dup 8)]
16706 UNSPEC_FSCALE_EXP))])
16707 (set (match_dup 12) (minus:XF (match_dup 10)
16708 (float_extend:XF (match_dup 13))))
16709 (set (match_operand:XF 0 "register_operand" "")
16710 (plus:XF (match_dup 12) (match_dup 7)))]
16711 "TARGET_USE_FANCY_MATH_387
16712 && flag_unsafe_math_optimizations"
16716 if (optimize_insn_for_size_p ())
16719 for (i = 2; i < 13; i++)
16720 operands[i] = gen_reg_rtx (XFmode);
16723 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16725 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16728 (define_expand "expm1<mode>2"
16729 [(use (match_operand:MODEF 0 "register_operand" ""))
16730 (use (match_operand:MODEF 1 "general_operand" ""))]
16731 "TARGET_USE_FANCY_MATH_387
16732 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16733 || TARGET_MIX_SSE_I387)
16734 && flag_unsafe_math_optimizations"
16738 if (optimize_insn_for_size_p ())
16741 op0 = gen_reg_rtx (XFmode);
16742 op1 = gen_reg_rtx (XFmode);
16744 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16745 emit_insn (gen_expm1xf2 (op0, op1));
16746 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16750 (define_expand "ldexpxf3"
16751 [(set (match_dup 3)
16752 (float:XF (match_operand:SI 2 "register_operand" "")))
16753 (parallel [(set (match_operand:XF 0 " register_operand" "")
16754 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16756 UNSPEC_FSCALE_FRACT))
16758 (unspec:XF [(match_dup 1) (match_dup 3)]
16759 UNSPEC_FSCALE_EXP))])]
16760 "TARGET_USE_FANCY_MATH_387
16761 && flag_unsafe_math_optimizations"
16763 if (optimize_insn_for_size_p ())
16766 operands[3] = gen_reg_rtx (XFmode);
16767 operands[4] = gen_reg_rtx (XFmode);
16770 (define_expand "ldexp<mode>3"
16771 [(use (match_operand:MODEF 0 "register_operand" ""))
16772 (use (match_operand:MODEF 1 "general_operand" ""))
16773 (use (match_operand:SI 2 "register_operand" ""))]
16774 "TARGET_USE_FANCY_MATH_387
16775 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16776 || TARGET_MIX_SSE_I387)
16777 && flag_unsafe_math_optimizations"
16781 if (optimize_insn_for_size_p ())
16784 op0 = gen_reg_rtx (XFmode);
16785 op1 = gen_reg_rtx (XFmode);
16787 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16788 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16789 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16793 (define_expand "scalbxf3"
16794 [(parallel [(set (match_operand:XF 0 " register_operand" "")
16795 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16796 (match_operand:XF 2 "register_operand" "")]
16797 UNSPEC_FSCALE_FRACT))
16799 (unspec:XF [(match_dup 1) (match_dup 2)]
16800 UNSPEC_FSCALE_EXP))])]
16801 "TARGET_USE_FANCY_MATH_387
16802 && flag_unsafe_math_optimizations"
16804 if (optimize_insn_for_size_p ())
16807 operands[3] = gen_reg_rtx (XFmode);
16810 (define_expand "scalb<mode>3"
16811 [(use (match_operand:MODEF 0 "register_operand" ""))
16812 (use (match_operand:MODEF 1 "general_operand" ""))
16813 (use (match_operand:MODEF 2 "general_operand" ""))]
16814 "TARGET_USE_FANCY_MATH_387
16815 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16816 || TARGET_MIX_SSE_I387)
16817 && flag_unsafe_math_optimizations"
16821 if (optimize_insn_for_size_p ())
16824 op0 = gen_reg_rtx (XFmode);
16825 op1 = gen_reg_rtx (XFmode);
16826 op2 = gen_reg_rtx (XFmode);
16828 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16829 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16830 emit_insn (gen_scalbxf3 (op0, op1, op2));
16831 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16835 (define_expand "significandxf2"
16836 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16837 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16838 UNSPEC_XTRACT_FRACT))
16840 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16841 "TARGET_USE_FANCY_MATH_387
16842 && flag_unsafe_math_optimizations"
16844 operands[2] = gen_reg_rtx (XFmode);
16847 (define_expand "significand<mode>2"
16848 [(use (match_operand:MODEF 0 "register_operand" ""))
16849 (use (match_operand:MODEF 1 "register_operand" ""))]
16850 "TARGET_USE_FANCY_MATH_387
16851 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16852 || TARGET_MIX_SSE_I387)
16853 && flag_unsafe_math_optimizations"
16855 rtx op0 = gen_reg_rtx (XFmode);
16856 rtx op1 = gen_reg_rtx (XFmode);
16858 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16859 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16864 (define_insn "sse4_1_round<mode>2"
16865 [(set (match_operand:MODEF 0 "register_operand" "=x")
16866 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
16867 (match_operand:SI 2 "const_0_to_15_operand" "n")]
16870 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16871 [(set_attr "type" "ssecvt")
16872 (set_attr "prefix_extra" "1")
16873 (set_attr "prefix" "maybe_vex")
16874 (set_attr "mode" "<MODE>")])
16876 (define_insn "rintxf2"
16877 [(set (match_operand:XF 0 "register_operand" "=f")
16878 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16880 "TARGET_USE_FANCY_MATH_387
16881 && flag_unsafe_math_optimizations"
16883 [(set_attr "type" "fpspc")
16884 (set_attr "mode" "XF")])
16886 (define_expand "rint<mode>2"
16887 [(use (match_operand:MODEF 0 "register_operand" ""))
16888 (use (match_operand:MODEF 1 "register_operand" ""))]
16889 "(TARGET_USE_FANCY_MATH_387
16890 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16891 || TARGET_MIX_SSE_I387)
16892 && flag_unsafe_math_optimizations)
16893 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16894 && !flag_trapping_math)"
16896 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16897 && !flag_trapping_math)
16899 if (!TARGET_ROUND && optimize_insn_for_size_p ())
16902 emit_insn (gen_sse4_1_round<mode>2
16903 (operands[0], operands[1], GEN_INT (0x04)));
16905 ix86_expand_rint (operand0, operand1);
16909 rtx op0 = gen_reg_rtx (XFmode);
16910 rtx op1 = gen_reg_rtx (XFmode);
16912 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16913 emit_insn (gen_rintxf2 (op0, op1));
16915 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16920 (define_expand "round<mode>2"
16921 [(match_operand:MODEF 0 "register_operand" "")
16922 (match_operand:MODEF 1 "nonimmediate_operand" "")]
16923 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16924 && !flag_trapping_math && !flag_rounding_math"
16926 if (optimize_insn_for_size_p ())
16928 if (TARGET_64BIT || (<MODE>mode != DFmode))
16929 ix86_expand_round (operand0, operand1);
16931 ix86_expand_rounddf_32 (operand0, operand1);
16935 (define_insn_and_split "*fistdi2_1"
16936 [(set (match_operand:DI 0 "nonimmediate_operand" "")
16937 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16939 "TARGET_USE_FANCY_MATH_387
16940 && can_create_pseudo_p ()"
16945 if (memory_operand (operands[0], VOIDmode))
16946 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16949 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16950 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16955 [(set_attr "type" "fpspc")
16956 (set_attr "mode" "DI")])
16958 (define_insn "fistdi2"
16959 [(set (match_operand:DI 0 "memory_operand" "=m")
16960 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16962 (clobber (match_scratch:XF 2 "=&1f"))]
16963 "TARGET_USE_FANCY_MATH_387"
16964 "* return output_fix_trunc (insn, operands, 0);"
16965 [(set_attr "type" "fpspc")
16966 (set_attr "mode" "DI")])
16968 (define_insn "fistdi2_with_temp"
16969 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16970 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16972 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16973 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16974 "TARGET_USE_FANCY_MATH_387"
16976 [(set_attr "type" "fpspc")
16977 (set_attr "mode" "DI")])
16980 [(set (match_operand:DI 0 "register_operand" "")
16981 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16983 (clobber (match_operand:DI 2 "memory_operand" ""))
16984 (clobber (match_scratch 3 ""))]
16986 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16987 (clobber (match_dup 3))])
16988 (set (match_dup 0) (match_dup 2))]
16992 [(set (match_operand:DI 0 "memory_operand" "")
16993 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16995 (clobber (match_operand:DI 2 "memory_operand" ""))
16996 (clobber (match_scratch 3 ""))]
16998 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16999 (clobber (match_dup 3))])]
17002 (define_insn_and_split "*fist<mode>2_1"
17003 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17004 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17006 "TARGET_USE_FANCY_MATH_387
17007 && can_create_pseudo_p ()"
17012 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17013 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17017 [(set_attr "type" "fpspc")
17018 (set_attr "mode" "<MODE>")])
17020 (define_insn "fist<mode>2"
17021 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17022 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17024 "TARGET_USE_FANCY_MATH_387"
17025 "* return output_fix_trunc (insn, operands, 0);"
17026 [(set_attr "type" "fpspc")
17027 (set_attr "mode" "<MODE>")])
17029 (define_insn "fist<mode>2_with_temp"
17030 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17031 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17033 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17034 "TARGET_USE_FANCY_MATH_387"
17036 [(set_attr "type" "fpspc")
17037 (set_attr "mode" "<MODE>")])
17040 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17041 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17043 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17045 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17046 (set (match_dup 0) (match_dup 2))]
17050 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17051 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17053 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17055 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17058 (define_expand "lrintxf<mode>2"
17059 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17060 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17062 "TARGET_USE_FANCY_MATH_387"
17065 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17066 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17067 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17068 UNSPEC_FIX_NOTRUNC))]
17069 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17070 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17073 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17074 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17075 (match_operand:MODEF 1 "register_operand" "")]
17076 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17077 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17078 && !flag_trapping_math && !flag_rounding_math"
17080 if (optimize_insn_for_size_p ())
17082 ix86_expand_lround (operand0, operand1);
17086 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17087 (define_insn_and_split "frndintxf2_floor"
17088 [(set (match_operand:XF 0 "register_operand" "")
17089 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17090 UNSPEC_FRNDINT_FLOOR))
17091 (clobber (reg:CC FLAGS_REG))]
17092 "TARGET_USE_FANCY_MATH_387
17093 && flag_unsafe_math_optimizations
17094 && can_create_pseudo_p ()"
17099 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17101 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17102 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17104 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17105 operands[2], operands[3]));
17108 [(set_attr "type" "frndint")
17109 (set_attr "i387_cw" "floor")
17110 (set_attr "mode" "XF")])
17112 (define_insn "frndintxf2_floor_i387"
17113 [(set (match_operand:XF 0 "register_operand" "=f")
17114 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17115 UNSPEC_FRNDINT_FLOOR))
17116 (use (match_operand:HI 2 "memory_operand" "m"))
17117 (use (match_operand:HI 3 "memory_operand" "m"))]
17118 "TARGET_USE_FANCY_MATH_387
17119 && flag_unsafe_math_optimizations"
17120 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17121 [(set_attr "type" "frndint")
17122 (set_attr "i387_cw" "floor")
17123 (set_attr "mode" "XF")])
17125 (define_expand "floorxf2"
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"
17131 if (optimize_insn_for_size_p ())
17133 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17137 (define_expand "floor<mode>2"
17138 [(use (match_operand:MODEF 0 "register_operand" ""))
17139 (use (match_operand:MODEF 1 "register_operand" ""))]
17140 "(TARGET_USE_FANCY_MATH_387
17141 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17142 || TARGET_MIX_SSE_I387)
17143 && flag_unsafe_math_optimizations)
17144 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17145 && !flag_trapping_math)"
17147 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17148 && !flag_trapping_math
17149 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17151 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17154 emit_insn (gen_sse4_1_round<mode>2
17155 (operands[0], operands[1], GEN_INT (0x01)));
17156 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17157 ix86_expand_floorceil (operand0, operand1, true);
17159 ix86_expand_floorceildf_32 (operand0, operand1, true);
17165 if (optimize_insn_for_size_p ())
17168 op0 = gen_reg_rtx (XFmode);
17169 op1 = gen_reg_rtx (XFmode);
17170 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17171 emit_insn (gen_frndintxf2_floor (op0, op1));
17173 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17178 (define_insn_and_split "*fist<mode>2_floor_1"
17179 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17180 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17181 UNSPEC_FIST_FLOOR))
17182 (clobber (reg:CC FLAGS_REG))]
17183 "TARGET_USE_FANCY_MATH_387
17184 && flag_unsafe_math_optimizations
17185 && can_create_pseudo_p ()"
17190 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17192 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17193 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17194 if (memory_operand (operands[0], VOIDmode))
17195 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17196 operands[2], operands[3]));
17199 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17200 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17201 operands[2], operands[3],
17206 [(set_attr "type" "fistp")
17207 (set_attr "i387_cw" "floor")
17208 (set_attr "mode" "<MODE>")])
17210 (define_insn "fistdi2_floor"
17211 [(set (match_operand:DI 0 "memory_operand" "=m")
17212 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17213 UNSPEC_FIST_FLOOR))
17214 (use (match_operand:HI 2 "memory_operand" "m"))
17215 (use (match_operand:HI 3 "memory_operand" "m"))
17216 (clobber (match_scratch:XF 4 "=&1f"))]
17217 "TARGET_USE_FANCY_MATH_387
17218 && flag_unsafe_math_optimizations"
17219 "* return output_fix_trunc (insn, operands, 0);"
17220 [(set_attr "type" "fistp")
17221 (set_attr "i387_cw" "floor")
17222 (set_attr "mode" "DI")])
17224 (define_insn "fistdi2_floor_with_temp"
17225 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17226 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17227 UNSPEC_FIST_FLOOR))
17228 (use (match_operand:HI 2 "memory_operand" "m,m"))
17229 (use (match_operand:HI 3 "memory_operand" "m,m"))
17230 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17231 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17232 "TARGET_USE_FANCY_MATH_387
17233 && flag_unsafe_math_optimizations"
17235 [(set_attr "type" "fistp")
17236 (set_attr "i387_cw" "floor")
17237 (set_attr "mode" "DI")])
17240 [(set (match_operand:DI 0 "register_operand" "")
17241 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17242 UNSPEC_FIST_FLOOR))
17243 (use (match_operand:HI 2 "memory_operand" ""))
17244 (use (match_operand:HI 3 "memory_operand" ""))
17245 (clobber (match_operand:DI 4 "memory_operand" ""))
17246 (clobber (match_scratch 5 ""))]
17248 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17249 (use (match_dup 2))
17250 (use (match_dup 3))
17251 (clobber (match_dup 5))])
17252 (set (match_dup 0) (match_dup 4))]
17256 [(set (match_operand:DI 0 "memory_operand" "")
17257 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17258 UNSPEC_FIST_FLOOR))
17259 (use (match_operand:HI 2 "memory_operand" ""))
17260 (use (match_operand:HI 3 "memory_operand" ""))
17261 (clobber (match_operand:DI 4 "memory_operand" ""))
17262 (clobber (match_scratch 5 ""))]
17264 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17265 (use (match_dup 2))
17266 (use (match_dup 3))
17267 (clobber (match_dup 5))])]
17270 (define_insn "fist<mode>2_floor"
17271 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17272 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17273 UNSPEC_FIST_FLOOR))
17274 (use (match_operand:HI 2 "memory_operand" "m"))
17275 (use (match_operand:HI 3 "memory_operand" "m"))]
17276 "TARGET_USE_FANCY_MATH_387
17277 && flag_unsafe_math_optimizations"
17278 "* return output_fix_trunc (insn, operands, 0);"
17279 [(set_attr "type" "fistp")
17280 (set_attr "i387_cw" "floor")
17281 (set_attr "mode" "<MODE>")])
17283 (define_insn "fist<mode>2_floor_with_temp"
17284 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17285 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17286 UNSPEC_FIST_FLOOR))
17287 (use (match_operand:HI 2 "memory_operand" "m,m"))
17288 (use (match_operand:HI 3 "memory_operand" "m,m"))
17289 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17290 "TARGET_USE_FANCY_MATH_387
17291 && flag_unsafe_math_optimizations"
17293 [(set_attr "type" "fistp")
17294 (set_attr "i387_cw" "floor")
17295 (set_attr "mode" "<MODE>")])
17298 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17299 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17300 UNSPEC_FIST_FLOOR))
17301 (use (match_operand:HI 2 "memory_operand" ""))
17302 (use (match_operand:HI 3 "memory_operand" ""))
17303 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17305 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17306 UNSPEC_FIST_FLOOR))
17307 (use (match_dup 2))
17308 (use (match_dup 3))])
17309 (set (match_dup 0) (match_dup 4))]
17313 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17314 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17315 UNSPEC_FIST_FLOOR))
17316 (use (match_operand:HI 2 "memory_operand" ""))
17317 (use (match_operand:HI 3 "memory_operand" ""))
17318 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17320 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17321 UNSPEC_FIST_FLOOR))
17322 (use (match_dup 2))
17323 (use (match_dup 3))])]
17326 (define_expand "lfloorxf<mode>2"
17327 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17328 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17329 UNSPEC_FIST_FLOOR))
17330 (clobber (reg:CC FLAGS_REG))])]
17331 "TARGET_USE_FANCY_MATH_387
17332 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17333 && flag_unsafe_math_optimizations"
17336 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17337 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17338 (match_operand:MODEF 1 "register_operand" "")]
17339 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17340 && !flag_trapping_math"
17342 if (TARGET_64BIT && optimize_insn_for_size_p ())
17344 ix86_expand_lfloorceil (operand0, operand1, true);
17348 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17349 (define_insn_and_split "frndintxf2_ceil"
17350 [(set (match_operand:XF 0 "register_operand" "")
17351 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17352 UNSPEC_FRNDINT_CEIL))
17353 (clobber (reg:CC FLAGS_REG))]
17354 "TARGET_USE_FANCY_MATH_387
17355 && flag_unsafe_math_optimizations
17356 && can_create_pseudo_p ()"
17361 ix86_optimize_mode_switching[I387_CEIL] = 1;
17363 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17364 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17366 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17367 operands[2], operands[3]));
17370 [(set_attr "type" "frndint")
17371 (set_attr "i387_cw" "ceil")
17372 (set_attr "mode" "XF")])
17374 (define_insn "frndintxf2_ceil_i387"
17375 [(set (match_operand:XF 0 "register_operand" "=f")
17376 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17377 UNSPEC_FRNDINT_CEIL))
17378 (use (match_operand:HI 2 "memory_operand" "m"))
17379 (use (match_operand:HI 3 "memory_operand" "m"))]
17380 "TARGET_USE_FANCY_MATH_387
17381 && flag_unsafe_math_optimizations"
17382 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17383 [(set_attr "type" "frndint")
17384 (set_attr "i387_cw" "ceil")
17385 (set_attr "mode" "XF")])
17387 (define_expand "ceilxf2"
17388 [(use (match_operand:XF 0 "register_operand" ""))
17389 (use (match_operand:XF 1 "register_operand" ""))]
17390 "TARGET_USE_FANCY_MATH_387
17391 && flag_unsafe_math_optimizations"
17393 if (optimize_insn_for_size_p ())
17395 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17399 (define_expand "ceil<mode>2"
17400 [(use (match_operand:MODEF 0 "register_operand" ""))
17401 (use (match_operand:MODEF 1 "register_operand" ""))]
17402 "(TARGET_USE_FANCY_MATH_387
17403 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17404 || TARGET_MIX_SSE_I387)
17405 && flag_unsafe_math_optimizations)
17406 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17407 && !flag_trapping_math)"
17409 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17410 && !flag_trapping_math
17411 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17414 emit_insn (gen_sse4_1_round<mode>2
17415 (operands[0], operands[1], GEN_INT (0x02)));
17416 else if (optimize_insn_for_size_p ())
17418 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17419 ix86_expand_floorceil (operand0, operand1, false);
17421 ix86_expand_floorceildf_32 (operand0, operand1, false);
17427 if (optimize_insn_for_size_p ())
17430 op0 = gen_reg_rtx (XFmode);
17431 op1 = gen_reg_rtx (XFmode);
17432 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17433 emit_insn (gen_frndintxf2_ceil (op0, op1));
17435 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17440 (define_insn_and_split "*fist<mode>2_ceil_1"
17441 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17442 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17444 (clobber (reg:CC FLAGS_REG))]
17445 "TARGET_USE_FANCY_MATH_387
17446 && flag_unsafe_math_optimizations
17447 && can_create_pseudo_p ()"
17452 ix86_optimize_mode_switching[I387_CEIL] = 1;
17454 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17455 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17456 if (memory_operand (operands[0], VOIDmode))
17457 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17458 operands[2], operands[3]));
17461 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17462 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17463 operands[2], operands[3],
17468 [(set_attr "type" "fistp")
17469 (set_attr "i387_cw" "ceil")
17470 (set_attr "mode" "<MODE>")])
17472 (define_insn "fistdi2_ceil"
17473 [(set (match_operand:DI 0 "memory_operand" "=m")
17474 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17476 (use (match_operand:HI 2 "memory_operand" "m"))
17477 (use (match_operand:HI 3 "memory_operand" "m"))
17478 (clobber (match_scratch:XF 4 "=&1f"))]
17479 "TARGET_USE_FANCY_MATH_387
17480 && flag_unsafe_math_optimizations"
17481 "* return output_fix_trunc (insn, operands, 0);"
17482 [(set_attr "type" "fistp")
17483 (set_attr "i387_cw" "ceil")
17484 (set_attr "mode" "DI")])
17486 (define_insn "fistdi2_ceil_with_temp"
17487 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17488 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17490 (use (match_operand:HI 2 "memory_operand" "m,m"))
17491 (use (match_operand:HI 3 "memory_operand" "m,m"))
17492 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17493 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17494 "TARGET_USE_FANCY_MATH_387
17495 && flag_unsafe_math_optimizations"
17497 [(set_attr "type" "fistp")
17498 (set_attr "i387_cw" "ceil")
17499 (set_attr "mode" "DI")])
17502 [(set (match_operand:DI 0 "register_operand" "")
17503 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17505 (use (match_operand:HI 2 "memory_operand" ""))
17506 (use (match_operand:HI 3 "memory_operand" ""))
17507 (clobber (match_operand:DI 4 "memory_operand" ""))
17508 (clobber (match_scratch 5 ""))]
17510 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17511 (use (match_dup 2))
17512 (use (match_dup 3))
17513 (clobber (match_dup 5))])
17514 (set (match_dup 0) (match_dup 4))]
17518 [(set (match_operand:DI 0 "memory_operand" "")
17519 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17521 (use (match_operand:HI 2 "memory_operand" ""))
17522 (use (match_operand:HI 3 "memory_operand" ""))
17523 (clobber (match_operand:DI 4 "memory_operand" ""))
17524 (clobber (match_scratch 5 ""))]
17526 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17527 (use (match_dup 2))
17528 (use (match_dup 3))
17529 (clobber (match_dup 5))])]
17532 (define_insn "fist<mode>2_ceil"
17533 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17534 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17536 (use (match_operand:HI 2 "memory_operand" "m"))
17537 (use (match_operand:HI 3 "memory_operand" "m"))]
17538 "TARGET_USE_FANCY_MATH_387
17539 && flag_unsafe_math_optimizations"
17540 "* return output_fix_trunc (insn, operands, 0);"
17541 [(set_attr "type" "fistp")
17542 (set_attr "i387_cw" "ceil")
17543 (set_attr "mode" "<MODE>")])
17545 (define_insn "fist<mode>2_ceil_with_temp"
17546 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17547 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17549 (use (match_operand:HI 2 "memory_operand" "m,m"))
17550 (use (match_operand:HI 3 "memory_operand" "m,m"))
17551 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17552 "TARGET_USE_FANCY_MATH_387
17553 && flag_unsafe_math_optimizations"
17555 [(set_attr "type" "fistp")
17556 (set_attr "i387_cw" "ceil")
17557 (set_attr "mode" "<MODE>")])
17560 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17561 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17563 (use (match_operand:HI 2 "memory_operand" ""))
17564 (use (match_operand:HI 3 "memory_operand" ""))
17565 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17567 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17569 (use (match_dup 2))
17570 (use (match_dup 3))])
17571 (set (match_dup 0) (match_dup 4))]
17575 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17576 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17578 (use (match_operand:HI 2 "memory_operand" ""))
17579 (use (match_operand:HI 3 "memory_operand" ""))
17580 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17582 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17584 (use (match_dup 2))
17585 (use (match_dup 3))])]
17588 (define_expand "lceilxf<mode>2"
17589 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17590 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17592 (clobber (reg:CC FLAGS_REG))])]
17593 "TARGET_USE_FANCY_MATH_387
17594 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17595 && flag_unsafe_math_optimizations"
17598 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17599 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17600 (match_operand:MODEF 1 "register_operand" "")]
17601 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17602 && !flag_trapping_math"
17604 ix86_expand_lfloorceil (operand0, operand1, false);
17608 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17609 (define_insn_and_split "frndintxf2_trunc"
17610 [(set (match_operand:XF 0 "register_operand" "")
17611 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17612 UNSPEC_FRNDINT_TRUNC))
17613 (clobber (reg:CC FLAGS_REG))]
17614 "TARGET_USE_FANCY_MATH_387
17615 && flag_unsafe_math_optimizations
17616 && can_create_pseudo_p ()"
17621 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17623 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17624 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17626 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17627 operands[2], operands[3]));
17630 [(set_attr "type" "frndint")
17631 (set_attr "i387_cw" "trunc")
17632 (set_attr "mode" "XF")])
17634 (define_insn "frndintxf2_trunc_i387"
17635 [(set (match_operand:XF 0 "register_operand" "=f")
17636 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17637 UNSPEC_FRNDINT_TRUNC))
17638 (use (match_operand:HI 2 "memory_operand" "m"))
17639 (use (match_operand:HI 3 "memory_operand" "m"))]
17640 "TARGET_USE_FANCY_MATH_387
17641 && flag_unsafe_math_optimizations"
17642 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17643 [(set_attr "type" "frndint")
17644 (set_attr "i387_cw" "trunc")
17645 (set_attr "mode" "XF")])
17647 (define_expand "btruncxf2"
17648 [(use (match_operand:XF 0 "register_operand" ""))
17649 (use (match_operand:XF 1 "register_operand" ""))]
17650 "TARGET_USE_FANCY_MATH_387
17651 && flag_unsafe_math_optimizations"
17653 if (optimize_insn_for_size_p ())
17655 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17659 (define_expand "btrunc<mode>2"
17660 [(use (match_operand:MODEF 0 "register_operand" ""))
17661 (use (match_operand:MODEF 1 "register_operand" ""))]
17662 "(TARGET_USE_FANCY_MATH_387
17663 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17664 || TARGET_MIX_SSE_I387)
17665 && flag_unsafe_math_optimizations)
17666 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17667 && !flag_trapping_math)"
17669 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17670 && !flag_trapping_math
17671 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17674 emit_insn (gen_sse4_1_round<mode>2
17675 (operands[0], operands[1], GEN_INT (0x03)));
17676 else if (optimize_insn_for_size_p ())
17678 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17679 ix86_expand_trunc (operand0, operand1);
17681 ix86_expand_truncdf_32 (operand0, operand1);
17687 if (optimize_insn_for_size_p ())
17690 op0 = gen_reg_rtx (XFmode);
17691 op1 = gen_reg_rtx (XFmode);
17692 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17693 emit_insn (gen_frndintxf2_trunc (op0, op1));
17695 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17700 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17701 (define_insn_and_split "frndintxf2_mask_pm"
17702 [(set (match_operand:XF 0 "register_operand" "")
17703 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17704 UNSPEC_FRNDINT_MASK_PM))
17705 (clobber (reg:CC FLAGS_REG))]
17706 "TARGET_USE_FANCY_MATH_387
17707 && flag_unsafe_math_optimizations
17708 && can_create_pseudo_p ()"
17713 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17715 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17716 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17718 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17719 operands[2], operands[3]));
17722 [(set_attr "type" "frndint")
17723 (set_attr "i387_cw" "mask_pm")
17724 (set_attr "mode" "XF")])
17726 (define_insn "frndintxf2_mask_pm_i387"
17727 [(set (match_operand:XF 0 "register_operand" "=f")
17728 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17729 UNSPEC_FRNDINT_MASK_PM))
17730 (use (match_operand:HI 2 "memory_operand" "m"))
17731 (use (match_operand:HI 3 "memory_operand" "m"))]
17732 "TARGET_USE_FANCY_MATH_387
17733 && flag_unsafe_math_optimizations"
17734 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17735 [(set_attr "type" "frndint")
17736 (set_attr "i387_cw" "mask_pm")
17737 (set_attr "mode" "XF")])
17739 (define_expand "nearbyintxf2"
17740 [(use (match_operand:XF 0 "register_operand" ""))
17741 (use (match_operand:XF 1 "register_operand" ""))]
17742 "TARGET_USE_FANCY_MATH_387
17743 && flag_unsafe_math_optimizations"
17745 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17750 (define_expand "nearbyint<mode>2"
17751 [(use (match_operand:MODEF 0 "register_operand" ""))
17752 (use (match_operand:MODEF 1 "register_operand" ""))]
17753 "TARGET_USE_FANCY_MATH_387
17754 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17755 || TARGET_MIX_SSE_I387)
17756 && flag_unsafe_math_optimizations"
17758 rtx op0 = gen_reg_rtx (XFmode);
17759 rtx op1 = gen_reg_rtx (XFmode);
17761 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17762 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17764 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17768 (define_insn "fxam<mode>2_i387"
17769 [(set (match_operand:HI 0 "register_operand" "=a")
17771 [(match_operand:X87MODEF 1 "register_operand" "f")]
17773 "TARGET_USE_FANCY_MATH_387"
17774 "fxam\n\tfnstsw\t%0"
17775 [(set_attr "type" "multi")
17776 (set_attr "length" "4")
17777 (set_attr "unit" "i387")
17778 (set_attr "mode" "<MODE>")])
17780 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17781 [(set (match_operand:HI 0 "register_operand" "")
17783 [(match_operand:MODEF 1 "memory_operand" "")]
17785 "TARGET_USE_FANCY_MATH_387
17786 && can_create_pseudo_p ()"
17789 [(set (match_dup 2)(match_dup 1))
17791 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17793 operands[2] = gen_reg_rtx (<MODE>mode);
17795 MEM_VOLATILE_P (operands[1]) = 1;
17797 [(set_attr "type" "multi")
17798 (set_attr "unit" "i387")
17799 (set_attr "mode" "<MODE>")])
17801 (define_expand "isinfxf2"
17802 [(use (match_operand:SI 0 "register_operand" ""))
17803 (use (match_operand:XF 1 "register_operand" ""))]
17804 "TARGET_USE_FANCY_MATH_387
17805 && TARGET_C99_FUNCTIONS"
17807 rtx mask = GEN_INT (0x45);
17808 rtx val = GEN_INT (0x05);
17812 rtx scratch = gen_reg_rtx (HImode);
17813 rtx res = gen_reg_rtx (QImode);
17815 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17817 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17818 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17819 cond = gen_rtx_fmt_ee (EQ, QImode,
17820 gen_rtx_REG (CCmode, FLAGS_REG),
17822 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17823 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17827 (define_expand "isinf<mode>2"
17828 [(use (match_operand:SI 0 "register_operand" ""))
17829 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
17830 "TARGET_USE_FANCY_MATH_387
17831 && TARGET_C99_FUNCTIONS
17832 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17834 rtx mask = GEN_INT (0x45);
17835 rtx val = GEN_INT (0x05);
17839 rtx scratch = gen_reg_rtx (HImode);
17840 rtx res = gen_reg_rtx (QImode);
17842 /* Remove excess precision by forcing value through memory. */
17843 if (memory_operand (operands[1], VOIDmode))
17844 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17847 enum ix86_stack_slot slot = (virtuals_instantiated
17850 rtx temp = assign_386_stack_local (<MODE>mode, slot);
17852 emit_move_insn (temp, operands[1]);
17853 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17856 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17857 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17858 cond = gen_rtx_fmt_ee (EQ, QImode,
17859 gen_rtx_REG (CCmode, FLAGS_REG),
17861 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17862 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17866 (define_expand "signbit<mode>2"
17867 [(use (match_operand:SI 0 "register_operand" ""))
17868 (use (match_operand:X87MODEF 1 "register_operand" ""))]
17869 "TARGET_USE_FANCY_MATH_387
17870 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17872 rtx mask = GEN_INT (0x0200);
17874 rtx scratch = gen_reg_rtx (HImode);
17876 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17877 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
17881 ;; Block operation instructions
17884 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17887 [(set_attr "length" "1")
17888 (set_attr "length_immediate" "0")
17889 (set_attr "modrm" "0")])
17891 (define_expand "movmemsi"
17892 [(use (match_operand:BLK 0 "memory_operand" ""))
17893 (use (match_operand:BLK 1 "memory_operand" ""))
17894 (use (match_operand:SI 2 "nonmemory_operand" ""))
17895 (use (match_operand:SI 3 "const_int_operand" ""))
17896 (use (match_operand:SI 4 "const_int_operand" ""))
17897 (use (match_operand:SI 5 "const_int_operand" ""))]
17900 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17901 operands[4], operands[5]))
17907 (define_expand "movmemdi"
17908 [(use (match_operand:BLK 0 "memory_operand" ""))
17909 (use (match_operand:BLK 1 "memory_operand" ""))
17910 (use (match_operand:DI 2 "nonmemory_operand" ""))
17911 (use (match_operand:DI 3 "const_int_operand" ""))
17912 (use (match_operand:SI 4 "const_int_operand" ""))
17913 (use (match_operand:SI 5 "const_int_operand" ""))]
17916 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17917 operands[4], operands[5]))
17923 ;; Most CPUs don't like single string operations
17924 ;; Handle this case here to simplify previous expander.
17926 (define_expand "strmov"
17927 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17928 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17929 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17930 (clobber (reg:CC FLAGS_REG))])
17931 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17932 (clobber (reg:CC FLAGS_REG))])]
17935 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17937 /* If .md ever supports :P for Pmode, these can be directly
17938 in the pattern above. */
17939 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17940 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17942 /* Can't use this if the user has appropriated esi or edi. */
17943 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17944 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17946 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17947 operands[2], operands[3],
17948 operands[5], operands[6]));
17952 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17955 (define_expand "strmov_singleop"
17956 [(parallel [(set (match_operand 1 "memory_operand" "")
17957 (match_operand 3 "memory_operand" ""))
17958 (set (match_operand 0 "register_operand" "")
17959 (match_operand 4 "" ""))
17960 (set (match_operand 2 "register_operand" "")
17961 (match_operand 5 "" ""))])]
17963 "ix86_current_function_needs_cld = 1;")
17965 (define_insn "*strmovdi_rex_1"
17966 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17967 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17968 (set (match_operand:DI 0 "register_operand" "=D")
17969 (plus:DI (match_dup 2)
17971 (set (match_operand:DI 1 "register_operand" "=S")
17972 (plus:DI (match_dup 3)
17976 [(set_attr "type" "str")
17977 (set_attr "mode" "DI")
17978 (set_attr "memory" "both")])
17980 (define_insn "*strmovsi_1"
17981 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17982 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17983 (set (match_operand:SI 0 "register_operand" "=D")
17984 (plus:SI (match_dup 2)
17986 (set (match_operand:SI 1 "register_operand" "=S")
17987 (plus:SI (match_dup 3)
17991 [(set_attr "type" "str")
17992 (set_attr "mode" "SI")
17993 (set_attr "memory" "both")])
17995 (define_insn "*strmovsi_rex_1"
17996 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17997 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17998 (set (match_operand:DI 0 "register_operand" "=D")
17999 (plus:DI (match_dup 2)
18001 (set (match_operand:DI 1 "register_operand" "=S")
18002 (plus:DI (match_dup 3)
18006 [(set_attr "type" "str")
18007 (set_attr "mode" "SI")
18008 (set_attr "memory" "both")])
18010 (define_insn "*strmovhi_1"
18011 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18012 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18013 (set (match_operand:SI 0 "register_operand" "=D")
18014 (plus:SI (match_dup 2)
18016 (set (match_operand:SI 1 "register_operand" "=S")
18017 (plus:SI (match_dup 3)
18021 [(set_attr "type" "str")
18022 (set_attr "memory" "both")
18023 (set_attr "mode" "HI")])
18025 (define_insn "*strmovhi_rex_1"
18026 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18027 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18028 (set (match_operand:DI 0 "register_operand" "=D")
18029 (plus:DI (match_dup 2)
18031 (set (match_operand:DI 1 "register_operand" "=S")
18032 (plus:DI (match_dup 3)
18036 [(set_attr "type" "str")
18037 (set_attr "memory" "both")
18038 (set_attr "mode" "HI")])
18040 (define_insn "*strmovqi_1"
18041 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18042 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18043 (set (match_operand:SI 0 "register_operand" "=D")
18044 (plus:SI (match_dup 2)
18046 (set (match_operand:SI 1 "register_operand" "=S")
18047 (plus:SI (match_dup 3)
18051 [(set_attr "type" "str")
18052 (set_attr "memory" "both")
18053 (set_attr "mode" "QI")])
18055 (define_insn "*strmovqi_rex_1"
18056 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18057 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18058 (set (match_operand:DI 0 "register_operand" "=D")
18059 (plus:DI (match_dup 2)
18061 (set (match_operand:DI 1 "register_operand" "=S")
18062 (plus:DI (match_dup 3)
18066 [(set_attr "type" "str")
18067 (set_attr "memory" "both")
18068 (set_attr "prefix_rex" "0")
18069 (set_attr "mode" "QI")])
18071 (define_expand "rep_mov"
18072 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18073 (set (match_operand 0 "register_operand" "")
18074 (match_operand 5 "" ""))
18075 (set (match_operand 2 "register_operand" "")
18076 (match_operand 6 "" ""))
18077 (set (match_operand 1 "memory_operand" "")
18078 (match_operand 3 "memory_operand" ""))
18079 (use (match_dup 4))])]
18081 "ix86_current_function_needs_cld = 1;")
18083 (define_insn "*rep_movdi_rex64"
18084 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18085 (set (match_operand:DI 0 "register_operand" "=D")
18086 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18088 (match_operand:DI 3 "register_operand" "0")))
18089 (set (match_operand:DI 1 "register_operand" "=S")
18090 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18091 (match_operand:DI 4 "register_operand" "1")))
18092 (set (mem:BLK (match_dup 3))
18093 (mem:BLK (match_dup 4)))
18094 (use (match_dup 5))]
18097 [(set_attr "type" "str")
18098 (set_attr "prefix_rep" "1")
18099 (set_attr "memory" "both")
18100 (set_attr "mode" "DI")])
18102 (define_insn "*rep_movsi"
18103 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18104 (set (match_operand:SI 0 "register_operand" "=D")
18105 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18107 (match_operand:SI 3 "register_operand" "0")))
18108 (set (match_operand:SI 1 "register_operand" "=S")
18109 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18110 (match_operand:SI 4 "register_operand" "1")))
18111 (set (mem:BLK (match_dup 3))
18112 (mem:BLK (match_dup 4)))
18113 (use (match_dup 5))]
18116 [(set_attr "type" "str")
18117 (set_attr "prefix_rep" "1")
18118 (set_attr "memory" "both")
18119 (set_attr "mode" "SI")])
18121 (define_insn "*rep_movsi_rex64"
18122 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18123 (set (match_operand:DI 0 "register_operand" "=D")
18124 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18126 (match_operand:DI 3 "register_operand" "0")))
18127 (set (match_operand:DI 1 "register_operand" "=S")
18128 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18129 (match_operand:DI 4 "register_operand" "1")))
18130 (set (mem:BLK (match_dup 3))
18131 (mem:BLK (match_dup 4)))
18132 (use (match_dup 5))]
18135 [(set_attr "type" "str")
18136 (set_attr "prefix_rep" "1")
18137 (set_attr "memory" "both")
18138 (set_attr "mode" "SI")])
18140 (define_insn "*rep_movqi"
18141 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18142 (set (match_operand:SI 0 "register_operand" "=D")
18143 (plus:SI (match_operand:SI 3 "register_operand" "0")
18144 (match_operand:SI 5 "register_operand" "2")))
18145 (set (match_operand:SI 1 "register_operand" "=S")
18146 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18147 (set (mem:BLK (match_dup 3))
18148 (mem:BLK (match_dup 4)))
18149 (use (match_dup 5))]
18152 [(set_attr "type" "str")
18153 (set_attr "prefix_rep" "1")
18154 (set_attr "memory" "both")
18155 (set_attr "mode" "SI")])
18157 (define_insn "*rep_movqi_rex64"
18158 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18159 (set (match_operand:DI 0 "register_operand" "=D")
18160 (plus:DI (match_operand:DI 3 "register_operand" "0")
18161 (match_operand:DI 5 "register_operand" "2")))
18162 (set (match_operand:DI 1 "register_operand" "=S")
18163 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18164 (set (mem:BLK (match_dup 3))
18165 (mem:BLK (match_dup 4)))
18166 (use (match_dup 5))]
18169 [(set_attr "type" "str")
18170 (set_attr "prefix_rep" "1")
18171 (set_attr "memory" "both")
18172 (set_attr "mode" "SI")])
18174 (define_expand "setmemsi"
18175 [(use (match_operand:BLK 0 "memory_operand" ""))
18176 (use (match_operand:SI 1 "nonmemory_operand" ""))
18177 (use (match_operand 2 "const_int_operand" ""))
18178 (use (match_operand 3 "const_int_operand" ""))
18179 (use (match_operand:SI 4 "const_int_operand" ""))
18180 (use (match_operand:SI 5 "const_int_operand" ""))]
18183 if (ix86_expand_setmem (operands[0], operands[1],
18184 operands[2], operands[3],
18185 operands[4], operands[5]))
18191 (define_expand "setmemdi"
18192 [(use (match_operand:BLK 0 "memory_operand" ""))
18193 (use (match_operand:DI 1 "nonmemory_operand" ""))
18194 (use (match_operand 2 "const_int_operand" ""))
18195 (use (match_operand 3 "const_int_operand" ""))
18196 (use (match_operand 4 "const_int_operand" ""))
18197 (use (match_operand 5 "const_int_operand" ""))]
18200 if (ix86_expand_setmem (operands[0], operands[1],
18201 operands[2], operands[3],
18202 operands[4], operands[5]))
18208 ;; Most CPUs don't like single string operations
18209 ;; Handle this case here to simplify previous expander.
18211 (define_expand "strset"
18212 [(set (match_operand 1 "memory_operand" "")
18213 (match_operand 2 "register_operand" ""))
18214 (parallel [(set (match_operand 0 "register_operand" "")
18216 (clobber (reg:CC FLAGS_REG))])]
18219 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18220 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18222 /* If .md ever supports :P for Pmode, this can be directly
18223 in the pattern above. */
18224 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18225 GEN_INT (GET_MODE_SIZE (GET_MODE
18227 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18229 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18235 (define_expand "strset_singleop"
18236 [(parallel [(set (match_operand 1 "memory_operand" "")
18237 (match_operand 2 "register_operand" ""))
18238 (set (match_operand 0 "register_operand" "")
18239 (match_operand 3 "" ""))])]
18241 "ix86_current_function_needs_cld = 1;")
18243 (define_insn "*strsetdi_rex_1"
18244 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18245 (match_operand:DI 2 "register_operand" "a"))
18246 (set (match_operand:DI 0 "register_operand" "=D")
18247 (plus:DI (match_dup 1)
18251 [(set_attr "type" "str")
18252 (set_attr "memory" "store")
18253 (set_attr "mode" "DI")])
18255 (define_insn "*strsetsi_1"
18256 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18257 (match_operand:SI 2 "register_operand" "a"))
18258 (set (match_operand:SI 0 "register_operand" "=D")
18259 (plus:SI (match_dup 1)
18263 [(set_attr "type" "str")
18264 (set_attr "memory" "store")
18265 (set_attr "mode" "SI")])
18267 (define_insn "*strsetsi_rex_1"
18268 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18269 (match_operand:SI 2 "register_operand" "a"))
18270 (set (match_operand:DI 0 "register_operand" "=D")
18271 (plus:DI (match_dup 1)
18275 [(set_attr "type" "str")
18276 (set_attr "memory" "store")
18277 (set_attr "mode" "SI")])
18279 (define_insn "*strsethi_1"
18280 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18281 (match_operand:HI 2 "register_operand" "a"))
18282 (set (match_operand:SI 0 "register_operand" "=D")
18283 (plus:SI (match_dup 1)
18287 [(set_attr "type" "str")
18288 (set_attr "memory" "store")
18289 (set_attr "mode" "HI")])
18291 (define_insn "*strsethi_rex_1"
18292 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18293 (match_operand:HI 2 "register_operand" "a"))
18294 (set (match_operand:DI 0 "register_operand" "=D")
18295 (plus:DI (match_dup 1)
18299 [(set_attr "type" "str")
18300 (set_attr "memory" "store")
18301 (set_attr "mode" "HI")])
18303 (define_insn "*strsetqi_1"
18304 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18305 (match_operand:QI 2 "register_operand" "a"))
18306 (set (match_operand:SI 0 "register_operand" "=D")
18307 (plus:SI (match_dup 1)
18311 [(set_attr "type" "str")
18312 (set_attr "memory" "store")
18313 (set_attr "mode" "QI")])
18315 (define_insn "*strsetqi_rex_1"
18316 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18317 (match_operand:QI 2 "register_operand" "a"))
18318 (set (match_operand:DI 0 "register_operand" "=D")
18319 (plus:DI (match_dup 1)
18323 [(set_attr "type" "str")
18324 (set_attr "memory" "store")
18325 (set_attr "prefix_rex" "0")
18326 (set_attr "mode" "QI")])
18328 (define_expand "rep_stos"
18329 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18330 (set (match_operand 0 "register_operand" "")
18331 (match_operand 4 "" ""))
18332 (set (match_operand 2 "memory_operand" "") (const_int 0))
18333 (use (match_operand 3 "register_operand" ""))
18334 (use (match_dup 1))])]
18336 "ix86_current_function_needs_cld = 1;")
18338 (define_insn "*rep_stosdi_rex64"
18339 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18340 (set (match_operand:DI 0 "register_operand" "=D")
18341 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18343 (match_operand:DI 3 "register_operand" "0")))
18344 (set (mem:BLK (match_dup 3))
18346 (use (match_operand:DI 2 "register_operand" "a"))
18347 (use (match_dup 4))]
18350 [(set_attr "type" "str")
18351 (set_attr "prefix_rep" "1")
18352 (set_attr "memory" "store")
18353 (set_attr "mode" "DI")])
18355 (define_insn "*rep_stossi"
18356 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18357 (set (match_operand:SI 0 "register_operand" "=D")
18358 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18360 (match_operand:SI 3 "register_operand" "0")))
18361 (set (mem:BLK (match_dup 3))
18363 (use (match_operand:SI 2 "register_operand" "a"))
18364 (use (match_dup 4))]
18367 [(set_attr "type" "str")
18368 (set_attr "prefix_rep" "1")
18369 (set_attr "memory" "store")
18370 (set_attr "mode" "SI")])
18372 (define_insn "*rep_stossi_rex64"
18373 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18374 (set (match_operand:DI 0 "register_operand" "=D")
18375 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18377 (match_operand:DI 3 "register_operand" "0")))
18378 (set (mem:BLK (match_dup 3))
18380 (use (match_operand:SI 2 "register_operand" "a"))
18381 (use (match_dup 4))]
18384 [(set_attr "type" "str")
18385 (set_attr "prefix_rep" "1")
18386 (set_attr "memory" "store")
18387 (set_attr "mode" "SI")])
18389 (define_insn "*rep_stosqi"
18390 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18391 (set (match_operand:SI 0 "register_operand" "=D")
18392 (plus:SI (match_operand:SI 3 "register_operand" "0")
18393 (match_operand:SI 4 "register_operand" "1")))
18394 (set (mem:BLK (match_dup 3))
18396 (use (match_operand:QI 2 "register_operand" "a"))
18397 (use (match_dup 4))]
18400 [(set_attr "type" "str")
18401 (set_attr "prefix_rep" "1")
18402 (set_attr "memory" "store")
18403 (set_attr "mode" "QI")])
18405 (define_insn "*rep_stosqi_rex64"
18406 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18407 (set (match_operand:DI 0 "register_operand" "=D")
18408 (plus:DI (match_operand:DI 3 "register_operand" "0")
18409 (match_operand:DI 4 "register_operand" "1")))
18410 (set (mem:BLK (match_dup 3))
18412 (use (match_operand:QI 2 "register_operand" "a"))
18413 (use (match_dup 4))]
18416 [(set_attr "type" "str")
18417 (set_attr "prefix_rep" "1")
18418 (set_attr "memory" "store")
18419 (set_attr "prefix_rex" "0")
18420 (set_attr "mode" "QI")])
18422 (define_expand "cmpstrnsi"
18423 [(set (match_operand:SI 0 "register_operand" "")
18424 (compare:SI (match_operand:BLK 1 "general_operand" "")
18425 (match_operand:BLK 2 "general_operand" "")))
18426 (use (match_operand 3 "general_operand" ""))
18427 (use (match_operand 4 "immediate_operand" ""))]
18430 rtx addr1, addr2, out, outlow, count, countreg, align;
18432 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18435 /* Can't use this if the user has appropriated esi or edi. */
18436 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18441 out = gen_reg_rtx (SImode);
18443 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18444 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18445 if (addr1 != XEXP (operands[1], 0))
18446 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18447 if (addr2 != XEXP (operands[2], 0))
18448 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18450 count = operands[3];
18451 countreg = ix86_zero_extend_to_Pmode (count);
18453 /* %%% Iff we are testing strict equality, we can use known alignment
18454 to good advantage. This may be possible with combine, particularly
18455 once cc0 is dead. */
18456 align = operands[4];
18458 if (CONST_INT_P (count))
18460 if (INTVAL (count) == 0)
18462 emit_move_insn (operands[0], const0_rtx);
18465 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18466 operands[1], operands[2]));
18470 rtx (*cmp_insn)(rtx, rtx);
18473 cmp_insn = gen_cmpdi_1;
18475 cmp_insn = gen_cmpsi_1;
18476 emit_insn (cmp_insn (countreg, countreg));
18477 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18478 operands[1], operands[2]));
18481 outlow = gen_lowpart (QImode, out);
18482 emit_insn (gen_cmpintqi (outlow));
18483 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18485 if (operands[0] != out)
18486 emit_move_insn (operands[0], out);
18491 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18493 (define_expand "cmpintqi"
18494 [(set (match_dup 1)
18495 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18497 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18498 (parallel [(set (match_operand:QI 0 "register_operand" "")
18499 (minus:QI (match_dup 1)
18501 (clobber (reg:CC FLAGS_REG))])]
18503 "operands[1] = gen_reg_rtx (QImode);
18504 operands[2] = gen_reg_rtx (QImode);")
18506 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18507 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18509 (define_expand "cmpstrnqi_nz_1"
18510 [(parallel [(set (reg:CC FLAGS_REG)
18511 (compare:CC (match_operand 4 "memory_operand" "")
18512 (match_operand 5 "memory_operand" "")))
18513 (use (match_operand 2 "register_operand" ""))
18514 (use (match_operand:SI 3 "immediate_operand" ""))
18515 (clobber (match_operand 0 "register_operand" ""))
18516 (clobber (match_operand 1 "register_operand" ""))
18517 (clobber (match_dup 2))])]
18519 "ix86_current_function_needs_cld = 1;")
18521 (define_insn "*cmpstrnqi_nz_1"
18522 [(set (reg:CC FLAGS_REG)
18523 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18524 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18525 (use (match_operand:SI 6 "register_operand" "2"))
18526 (use (match_operand:SI 3 "immediate_operand" "i"))
18527 (clobber (match_operand:SI 0 "register_operand" "=S"))
18528 (clobber (match_operand:SI 1 "register_operand" "=D"))
18529 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18532 [(set_attr "type" "str")
18533 (set_attr "mode" "QI")
18534 (set_attr "prefix_rep" "1")])
18536 (define_insn "*cmpstrnqi_nz_rex_1"
18537 [(set (reg:CC FLAGS_REG)
18538 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18539 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18540 (use (match_operand:DI 6 "register_operand" "2"))
18541 (use (match_operand:SI 3 "immediate_operand" "i"))
18542 (clobber (match_operand:DI 0 "register_operand" "=S"))
18543 (clobber (match_operand:DI 1 "register_operand" "=D"))
18544 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18547 [(set_attr "type" "str")
18548 (set_attr "mode" "QI")
18549 (set_attr "prefix_rex" "0")
18550 (set_attr "prefix_rep" "1")])
18552 ;; The same, but the count is not known to not be zero.
18554 (define_expand "cmpstrnqi_1"
18555 [(parallel [(set (reg:CC FLAGS_REG)
18556 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18558 (compare:CC (match_operand 4 "memory_operand" "")
18559 (match_operand 5 "memory_operand" ""))
18561 (use (match_operand:SI 3 "immediate_operand" ""))
18562 (use (reg:CC FLAGS_REG))
18563 (clobber (match_operand 0 "register_operand" ""))
18564 (clobber (match_operand 1 "register_operand" ""))
18565 (clobber (match_dup 2))])]
18567 "ix86_current_function_needs_cld = 1;")
18569 (define_insn "*cmpstrnqi_1"
18570 [(set (reg:CC FLAGS_REG)
18571 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18573 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18574 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18576 (use (match_operand:SI 3 "immediate_operand" "i"))
18577 (use (reg:CC FLAGS_REG))
18578 (clobber (match_operand:SI 0 "register_operand" "=S"))
18579 (clobber (match_operand:SI 1 "register_operand" "=D"))
18580 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18583 [(set_attr "type" "str")
18584 (set_attr "mode" "QI")
18585 (set_attr "prefix_rep" "1")])
18587 (define_insn "*cmpstrnqi_rex_1"
18588 [(set (reg:CC FLAGS_REG)
18589 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18591 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18592 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18594 (use (match_operand:SI 3 "immediate_operand" "i"))
18595 (use (reg:CC FLAGS_REG))
18596 (clobber (match_operand:DI 0 "register_operand" "=S"))
18597 (clobber (match_operand:DI 1 "register_operand" "=D"))
18598 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18601 [(set_attr "type" "str")
18602 (set_attr "mode" "QI")
18603 (set_attr "prefix_rex" "0")
18604 (set_attr "prefix_rep" "1")])
18606 (define_expand "strlensi"
18607 [(set (match_operand:SI 0 "register_operand" "")
18608 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18609 (match_operand:QI 2 "immediate_operand" "")
18610 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18613 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18619 (define_expand "strlendi"
18620 [(set (match_operand:DI 0 "register_operand" "")
18621 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18622 (match_operand:QI 2 "immediate_operand" "")
18623 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18626 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18632 (define_expand "strlenqi_1"
18633 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18634 (clobber (match_operand 1 "register_operand" ""))
18635 (clobber (reg:CC FLAGS_REG))])]
18637 "ix86_current_function_needs_cld = 1;")
18639 (define_insn "*strlenqi_1"
18640 [(set (match_operand:SI 0 "register_operand" "=&c")
18641 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18642 (match_operand:QI 2 "register_operand" "a")
18643 (match_operand:SI 3 "immediate_operand" "i")
18644 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18645 (clobber (match_operand:SI 1 "register_operand" "=D"))
18646 (clobber (reg:CC FLAGS_REG))]
18649 [(set_attr "type" "str")
18650 (set_attr "mode" "QI")
18651 (set_attr "prefix_rep" "1")])
18653 (define_insn "*strlenqi_rex_1"
18654 [(set (match_operand:DI 0 "register_operand" "=&c")
18655 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18656 (match_operand:QI 2 "register_operand" "a")
18657 (match_operand:DI 3 "immediate_operand" "i")
18658 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18659 (clobber (match_operand:DI 1 "register_operand" "=D"))
18660 (clobber (reg:CC FLAGS_REG))]
18663 [(set_attr "type" "str")
18664 (set_attr "mode" "QI")
18665 (set_attr "prefix_rex" "0")
18666 (set_attr "prefix_rep" "1")])
18668 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18669 ;; handled in combine, but it is not currently up to the task.
18670 ;; When used for their truth value, the cmpstrn* expanders generate
18679 ;; The intermediate three instructions are unnecessary.
18681 ;; This one handles cmpstrn*_nz_1...
18684 (set (reg:CC FLAGS_REG)
18685 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18686 (mem:BLK (match_operand 5 "register_operand" ""))))
18687 (use (match_operand 6 "register_operand" ""))
18688 (use (match_operand:SI 3 "immediate_operand" ""))
18689 (clobber (match_operand 0 "register_operand" ""))
18690 (clobber (match_operand 1 "register_operand" ""))
18691 (clobber (match_operand 2 "register_operand" ""))])
18692 (set (match_operand:QI 7 "register_operand" "")
18693 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18694 (set (match_operand:QI 8 "register_operand" "")
18695 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18696 (set (reg FLAGS_REG)
18697 (compare (match_dup 7) (match_dup 8)))
18699 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18701 (set (reg:CC FLAGS_REG)
18702 (compare:CC (mem:BLK (match_dup 4))
18703 (mem:BLK (match_dup 5))))
18704 (use (match_dup 6))
18705 (use (match_dup 3))
18706 (clobber (match_dup 0))
18707 (clobber (match_dup 1))
18708 (clobber (match_dup 2))])]
18711 ;; ...and this one handles cmpstrn*_1.
18714 (set (reg:CC FLAGS_REG)
18715 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18717 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18718 (mem:BLK (match_operand 5 "register_operand" "")))
18720 (use (match_operand:SI 3 "immediate_operand" ""))
18721 (use (reg:CC FLAGS_REG))
18722 (clobber (match_operand 0 "register_operand" ""))
18723 (clobber (match_operand 1 "register_operand" ""))
18724 (clobber (match_operand 2 "register_operand" ""))])
18725 (set (match_operand:QI 7 "register_operand" "")
18726 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18727 (set (match_operand:QI 8 "register_operand" "")
18728 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18729 (set (reg FLAGS_REG)
18730 (compare (match_dup 7) (match_dup 8)))
18732 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18734 (set (reg:CC FLAGS_REG)
18735 (if_then_else:CC (ne (match_dup 6)
18737 (compare:CC (mem:BLK (match_dup 4))
18738 (mem:BLK (match_dup 5)))
18740 (use (match_dup 3))
18741 (use (reg:CC FLAGS_REG))
18742 (clobber (match_dup 0))
18743 (clobber (match_dup 1))
18744 (clobber (match_dup 2))])]
18749 ;; Conditional move instructions.
18751 (define_expand "mov<mode>cc"
18752 [(set (match_operand:SWIM 0 "register_operand" "")
18753 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
18754 (match_operand:SWIM 2 "general_operand" "")
18755 (match_operand:SWIM 3 "general_operand" "")))]
18757 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18759 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18760 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18761 ;; So just document what we're doing explicitly.
18763 (define_expand "x86_mov<mode>cc_0_m1"
18765 [(set (match_operand:SWI48 0 "register_operand" "")
18766 (if_then_else:SWI48
18767 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18768 [(match_operand 1 "flags_reg_operand" "")
18772 (clobber (reg:CC FLAGS_REG))])]
18776 (define_insn "*x86_mov<mode>cc_0_m1"
18777 [(set (match_operand:SWI48 0 "register_operand" "=r")
18778 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18779 [(reg FLAGS_REG) (const_int 0)])
18782 (clobber (reg:CC FLAGS_REG))]
18784 "sbb{<imodesuffix>}\t%0, %0"
18785 ; Since we don't have the proper number of operands for an alu insn,
18786 ; fill in all the blanks.
18787 [(set_attr "type" "alu")
18788 (set_attr "use_carry" "1")
18789 (set_attr "pent_pair" "pu")
18790 (set_attr "memory" "none")
18791 (set_attr "imm_disp" "false")
18792 (set_attr "mode" "<MODE>")
18793 (set_attr "length_immediate" "0")])
18795 (define_insn "*x86_mov<mode>cc_0_m1_se"
18796 [(set (match_operand:SWI48 0 "register_operand" "=r")
18797 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18798 [(reg FLAGS_REG) (const_int 0)])
18801 (clobber (reg:CC FLAGS_REG))]
18803 "sbb{<imodesuffix>}\t%0, %0"
18804 [(set_attr "type" "alu")
18805 (set_attr "use_carry" "1")
18806 (set_attr "pent_pair" "pu")
18807 (set_attr "memory" "none")
18808 (set_attr "imm_disp" "false")
18809 (set_attr "mode" "<MODE>")
18810 (set_attr "length_immediate" "0")])
18812 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18813 [(set (match_operand:SWI48 0 "register_operand" "=r")
18814 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18815 [(reg FLAGS_REG) (const_int 0)])))]
18817 "sbb{<imodesuffix>}\t%0, %0"
18818 [(set_attr "type" "alu")
18819 (set_attr "use_carry" "1")
18820 (set_attr "pent_pair" "pu")
18821 (set_attr "memory" "none")
18822 (set_attr "imm_disp" "false")
18823 (set_attr "mode" "<MODE>")
18824 (set_attr "length_immediate" "0")])
18826 (define_insn "*mov<mode>cc_noc"
18827 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18828 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18829 [(reg FLAGS_REG) (const_int 0)])
18830 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18831 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18832 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18834 cmov%O2%C1\t{%2, %0|%0, %2}
18835 cmov%O2%c1\t{%3, %0|%0, %3}"
18836 [(set_attr "type" "icmov")
18837 (set_attr "mode" "<MODE>")])
18839 (define_insn_and_split "*movqicc_noc"
18840 [(set (match_operand:QI 0 "register_operand" "=r,r")
18841 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18842 [(match_operand 4 "flags_reg_operand" "")
18844 (match_operand:QI 2 "register_operand" "r,0")
18845 (match_operand:QI 3 "register_operand" "0,r")))]
18846 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18848 "&& reload_completed"
18849 [(set (match_dup 0)
18850 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18853 "operands[0] = gen_lowpart (SImode, operands[0]);
18854 operands[2] = gen_lowpart (SImode, operands[2]);
18855 operands[3] = gen_lowpart (SImode, operands[3]);"
18856 [(set_attr "type" "icmov")
18857 (set_attr "mode" "SI")])
18859 (define_expand "mov<mode>cc"
18860 [(set (match_operand:X87MODEF 0 "register_operand" "")
18861 (if_then_else:X87MODEF
18862 (match_operand 1 "ix86_fp_comparison_operator" "")
18863 (match_operand:X87MODEF 2 "register_operand" "")
18864 (match_operand:X87MODEF 3 "register_operand" "")))]
18865 "(TARGET_80387 && TARGET_CMOVE)
18866 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18867 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18869 (define_insn "*movsfcc_1_387"
18870 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18871 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18872 [(reg FLAGS_REG) (const_int 0)])
18873 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18874 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18875 "TARGET_80387 && TARGET_CMOVE
18876 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18878 fcmov%F1\t{%2, %0|%0, %2}
18879 fcmov%f1\t{%3, %0|%0, %3}
18880 cmov%O2%C1\t{%2, %0|%0, %2}
18881 cmov%O2%c1\t{%3, %0|%0, %3}"
18882 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18883 (set_attr "mode" "SF,SF,SI,SI")])
18885 (define_insn "*movdfcc_1"
18886 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18887 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18888 [(reg FLAGS_REG) (const_int 0)])
18889 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18890 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18891 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18892 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18894 fcmov%F1\t{%2, %0|%0, %2}
18895 fcmov%f1\t{%3, %0|%0, %3}
18898 [(set_attr "type" "fcmov,fcmov,multi,multi")
18899 (set_attr "mode" "DF")])
18901 (define_insn "*movdfcc_1_rex64"
18902 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18903 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18904 [(reg FLAGS_REG) (const_int 0)])
18905 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18906 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18907 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18908 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18910 fcmov%F1\t{%2, %0|%0, %2}
18911 fcmov%f1\t{%3, %0|%0, %3}
18912 cmov%O2%C1\t{%2, %0|%0, %2}
18913 cmov%O2%c1\t{%3, %0|%0, %3}"
18914 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18915 (set_attr "mode" "DF")])
18918 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18919 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18920 [(match_operand 4 "flags_reg_operand" "")
18922 (match_operand:DF 2 "nonimmediate_operand" "")
18923 (match_operand:DF 3 "nonimmediate_operand" "")))]
18924 "!TARGET_64BIT && reload_completed"
18925 [(set (match_dup 2)
18926 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18930 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18933 "split_di (&operands[2], 2, &operands[5], &operands[7]);
18934 split_di (&operands[0], 1, &operands[2], &operands[3]);")
18936 (define_insn "*movxfcc_1"
18937 [(set (match_operand:XF 0 "register_operand" "=f,f")
18938 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18939 [(reg FLAGS_REG) (const_int 0)])
18940 (match_operand:XF 2 "register_operand" "f,0")
18941 (match_operand:XF 3 "register_operand" "0,f")))]
18942 "TARGET_80387 && TARGET_CMOVE"
18944 fcmov%F1\t{%2, %0|%0, %2}
18945 fcmov%f1\t{%3, %0|%0, %3}"
18946 [(set_attr "type" "fcmov")
18947 (set_attr "mode" "XF")])
18949 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18950 ;; the scalar versions to have only XMM registers as operands.
18952 ;; XOP conditional move
18953 (define_insn "*xop_pcmov_<mode>"
18954 [(set (match_operand:MODEF 0 "register_operand" "=x")
18955 (if_then_else:MODEF
18956 (match_operand:MODEF 1 "register_operand" "x")
18957 (match_operand:MODEF 2 "register_operand" "x")
18958 (match_operand:MODEF 3 "register_operand" "x")))]
18960 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18961 [(set_attr "type" "sse4arg")])
18963 ;; These versions of the min/max patterns are intentionally ignorant of
18964 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18965 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18966 ;; are undefined in this condition, we're certain this is correct.
18968 (define_insn "*avx_<code><mode>3"
18969 [(set (match_operand:MODEF 0 "register_operand" "=x")
18971 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18972 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18973 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18974 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18975 [(set_attr "type" "sseadd")
18976 (set_attr "prefix" "vex")
18977 (set_attr "mode" "<MODE>")])
18979 (define_insn "<code><mode>3"
18980 [(set (match_operand:MODEF 0 "register_operand" "=x")
18982 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18983 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18984 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18985 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18986 [(set_attr "type" "sseadd")
18987 (set_attr "mode" "<MODE>")])
18989 ;; These versions of the min/max patterns implement exactly the operations
18990 ;; min = (op1 < op2 ? op1 : op2)
18991 ;; max = (!(op1 < op2) ? op1 : op2)
18992 ;; Their operands are not commutative, and thus they may be used in the
18993 ;; presence of -0.0 and NaN.
18995 (define_insn "*avx_ieee_smin<mode>3"
18996 [(set (match_operand:MODEF 0 "register_operand" "=x")
18998 [(match_operand:MODEF 1 "register_operand" "x")
18999 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19001 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19002 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19003 [(set_attr "type" "sseadd")
19004 (set_attr "prefix" "vex")
19005 (set_attr "mode" "<MODE>")])
19007 (define_insn "*ieee_smin<mode>3"
19008 [(set (match_operand:MODEF 0 "register_operand" "=x")
19010 [(match_operand:MODEF 1 "register_operand" "0")
19011 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19013 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19014 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19015 [(set_attr "type" "sseadd")
19016 (set_attr "mode" "<MODE>")])
19018 (define_insn "*avx_ieee_smax<mode>3"
19019 [(set (match_operand:MODEF 0 "register_operand" "=x")
19021 [(match_operand:MODEF 1 "register_operand" "0")
19022 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19024 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19025 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19026 [(set_attr "type" "sseadd")
19027 (set_attr "prefix" "vex")
19028 (set_attr "mode" "<MODE>")])
19030 (define_insn "*ieee_smax<mode>3"
19031 [(set (match_operand:MODEF 0 "register_operand" "=x")
19033 [(match_operand:MODEF 1 "register_operand" "0")
19034 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19036 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19037 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19038 [(set_attr "type" "sseadd")
19039 (set_attr "mode" "<MODE>")])
19041 ;; Make two stack loads independent:
19043 ;; fld %st(0) -> fld bb
19044 ;; fmul bb fmul %st(1), %st
19046 ;; Actually we only match the last two instructions for simplicity.
19048 [(set (match_operand 0 "fp_register_operand" "")
19049 (match_operand 1 "fp_register_operand" ""))
19051 (match_operator 2 "binary_fp_operator"
19053 (match_operand 3 "memory_operand" "")]))]
19054 "REGNO (operands[0]) != REGNO (operands[1])"
19055 [(set (match_dup 0) (match_dup 3))
19056 (set (match_dup 0) (match_dup 4))]
19058 ;; The % modifier is not operational anymore in peephole2's, so we have to
19059 ;; swap the operands manually in the case of addition and multiplication.
19060 "if (COMMUTATIVE_ARITH_P (operands[2]))
19061 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19062 operands[0], operands[1]);
19064 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19065 operands[1], operands[0]);")
19067 ;; Conditional addition patterns
19068 (define_expand "add<mode>cc"
19069 [(match_operand:SWI 0 "register_operand" "")
19070 (match_operand 1 "comparison_operator" "")
19071 (match_operand:SWI 2 "register_operand" "")
19072 (match_operand:SWI 3 "const_int_operand" "")]
19074 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19077 ;; Misc patterns (?)
19079 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19080 ;; Otherwise there will be nothing to keep
19082 ;; [(set (reg ebp) (reg esp))]
19083 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19084 ;; (clobber (eflags)]
19085 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19087 ;; in proper program order.
19088 (define_insn "pro_epilogue_adjust_stack_1"
19089 [(set (match_operand:SI 0 "register_operand" "=r,r")
19090 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19091 (match_operand:SI 2 "immediate_operand" "i,i")))
19092 (clobber (reg:CC FLAGS_REG))
19093 (clobber (mem:BLK (scratch)))]
19096 switch (get_attr_type (insn))
19099 return "mov{l}\t{%1, %0|%0, %1}";
19102 if (CONST_INT_P (operands[2])
19103 && (INTVAL (operands[2]) == 128
19104 || (INTVAL (operands[2]) < 0
19105 && INTVAL (operands[2]) != -128)))
19107 operands[2] = GEN_INT (-INTVAL (operands[2]));
19108 return "sub{l}\t{%2, %0|%0, %2}";
19110 return "add{l}\t{%2, %0|%0, %2}";
19113 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19114 return "lea{l}\t{%a2, %0|%0, %a2}";
19117 gcc_unreachable ();
19120 [(set (attr "type")
19121 (cond [(and (eq_attr "alternative" "0")
19122 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19123 (const_string "alu")
19124 (match_operand:SI 2 "const0_operand" "")
19125 (const_string "imov")
19127 (const_string "lea")))
19128 (set (attr "length_immediate")
19129 (cond [(eq_attr "type" "imov")
19131 (and (eq_attr "type" "alu")
19132 (match_operand 2 "const128_operand" ""))
19135 (const_string "*")))
19136 (set_attr "mode" "SI")])
19138 (define_insn "pro_epilogue_adjust_stack_rex64"
19139 [(set (match_operand:DI 0 "register_operand" "=r,r")
19140 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19141 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19142 (clobber (reg:CC FLAGS_REG))
19143 (clobber (mem:BLK (scratch)))]
19146 switch (get_attr_type (insn))
19149 return "mov{q}\t{%1, %0|%0, %1}";
19152 if (CONST_INT_P (operands[2])
19153 /* Avoid overflows. */
19154 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19155 && (INTVAL (operands[2]) == 128
19156 || (INTVAL (operands[2]) < 0
19157 && INTVAL (operands[2]) != -128)))
19159 operands[2] = GEN_INT (-INTVAL (operands[2]));
19160 return "sub{q}\t{%2, %0|%0, %2}";
19162 return "add{q}\t{%2, %0|%0, %2}";
19165 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19166 return "lea{q}\t{%a2, %0|%0, %a2}";
19169 gcc_unreachable ();
19172 [(set (attr "type")
19173 (cond [(and (eq_attr "alternative" "0")
19174 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19175 (const_string "alu")
19176 (match_operand:DI 2 "const0_operand" "")
19177 (const_string "imov")
19179 (const_string "lea")))
19180 (set (attr "length_immediate")
19181 (cond [(eq_attr "type" "imov")
19183 (and (eq_attr "type" "alu")
19184 (match_operand 2 "const128_operand" ""))
19187 (const_string "*")))
19188 (set_attr "mode" "DI")])
19190 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19191 [(set (match_operand:DI 0 "register_operand" "=r,r")
19192 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19193 (match_operand:DI 3 "immediate_operand" "i,i")))
19194 (use (match_operand:DI 2 "register_operand" "r,r"))
19195 (clobber (reg:CC FLAGS_REG))
19196 (clobber (mem:BLK (scratch)))]
19199 switch (get_attr_type (insn))
19202 return "add{q}\t{%2, %0|%0, %2}";
19205 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19206 return "lea{q}\t{%a2, %0|%0, %a2}";
19209 gcc_unreachable ();
19212 [(set_attr "type" "alu,lea")
19213 (set_attr "mode" "DI")])
19215 (define_insn "allocate_stack_worker_32"
19216 [(set (match_operand:SI 0 "register_operand" "=a")
19217 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
19218 UNSPECV_STACK_PROBE))
19219 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
19220 (clobber (reg:CC FLAGS_REG))]
19221 "!TARGET_64BIT && TARGET_STACK_PROBE"
19223 [(set_attr "type" "multi")
19224 (set_attr "length" "5")])
19226 (define_insn "allocate_stack_worker_64"
19227 [(set (match_operand:DI 0 "register_operand" "=a")
19228 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
19229 UNSPECV_STACK_PROBE))
19230 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
19231 (clobber (reg:DI R10_REG))
19232 (clobber (reg:DI R11_REG))
19233 (clobber (reg:CC FLAGS_REG))]
19234 "TARGET_64BIT && TARGET_STACK_PROBE"
19236 [(set_attr "type" "multi")
19237 (set_attr "length" "5")])
19239 (define_expand "allocate_stack"
19240 [(match_operand 0 "register_operand" "")
19241 (match_operand 1 "general_operand" "")]
19242 "TARGET_STACK_PROBE"
19246 #ifndef CHECK_STACK_LIMIT
19247 #define CHECK_STACK_LIMIT 0
19250 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19251 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19253 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19254 stack_pointer_rtx, 0, OPTAB_DIRECT);
19255 if (x != stack_pointer_rtx)
19256 emit_move_insn (stack_pointer_rtx, x);
19260 x = copy_to_mode_reg (Pmode, operands[1]);
19262 x = gen_allocate_stack_worker_64 (x, x);
19264 x = gen_allocate_stack_worker_32 (x, x);
19268 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19272 ;; Use IOR for stack probes, this is shorter.
19273 (define_expand "probe_stack"
19274 [(match_operand 0 "memory_operand" "")]
19277 if (GET_MODE (operands[0]) == DImode)
19278 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
19280 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
19284 (define_expand "builtin_setjmp_receiver"
19285 [(label_ref (match_operand 0 "" ""))]
19286 "!TARGET_64BIT && flag_pic"
19292 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19293 rtx label_rtx = gen_label_rtx ();
19294 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19295 xops[0] = xops[1] = picreg;
19296 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19297 ix86_expand_binary_operator (MINUS, SImode, xops);
19301 emit_insn (gen_set_got (pic_offset_table_rtx));
19305 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19308 [(set (match_operand 0 "register_operand" "")
19309 (match_operator 3 "promotable_binary_operator"
19310 [(match_operand 1 "register_operand" "")
19311 (match_operand 2 "aligned_operand" "")]))
19312 (clobber (reg:CC FLAGS_REG))]
19313 "! TARGET_PARTIAL_REG_STALL && reload_completed
19314 && ((GET_MODE (operands[0]) == HImode
19315 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19316 /* ??? next two lines just !satisfies_constraint_K (...) */
19317 || !CONST_INT_P (operands[2])
19318 || satisfies_constraint_K (operands[2])))
19319 || (GET_MODE (operands[0]) == QImode
19320 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19321 [(parallel [(set (match_dup 0)
19322 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19323 (clobber (reg:CC FLAGS_REG))])]
19324 "operands[0] = gen_lowpart (SImode, operands[0]);
19325 operands[1] = gen_lowpart (SImode, operands[1]);
19326 if (GET_CODE (operands[3]) != ASHIFT)
19327 operands[2] = gen_lowpart (SImode, operands[2]);
19328 PUT_MODE (operands[3], SImode);")
19330 ; Promote the QImode tests, as i386 has encoding of the AND
19331 ; instruction with 32-bit sign-extended immediate and thus the
19332 ; instruction size is unchanged, except in the %eax case for
19333 ; which it is increased by one byte, hence the ! optimize_size.
19335 [(set (match_operand 0 "flags_reg_operand" "")
19336 (match_operator 2 "compare_operator"
19337 [(and (match_operand 3 "aligned_operand" "")
19338 (match_operand 4 "const_int_operand" ""))
19340 (set (match_operand 1 "register_operand" "")
19341 (and (match_dup 3) (match_dup 4)))]
19342 "! TARGET_PARTIAL_REG_STALL && reload_completed
19343 && optimize_insn_for_speed_p ()
19344 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19345 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19346 /* Ensure that the operand will remain sign-extended immediate. */
19347 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19348 [(parallel [(set (match_dup 0)
19349 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19352 (and:SI (match_dup 3) (match_dup 4)))])]
19355 = gen_int_mode (INTVAL (operands[4])
19356 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19357 operands[1] = gen_lowpart (SImode, operands[1]);
19358 operands[3] = gen_lowpart (SImode, operands[3]);
19361 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19362 ; the TEST instruction with 32-bit sign-extended immediate and thus
19363 ; the instruction size would at least double, which is not what we
19364 ; want even with ! optimize_size.
19366 [(set (match_operand 0 "flags_reg_operand" "")
19367 (match_operator 1 "compare_operator"
19368 [(and (match_operand:HI 2 "aligned_operand" "")
19369 (match_operand:HI 3 "const_int_operand" ""))
19371 "! TARGET_PARTIAL_REG_STALL && reload_completed
19372 && ! TARGET_FAST_PREFIX
19373 && optimize_insn_for_speed_p ()
19374 /* Ensure that the operand will remain sign-extended immediate. */
19375 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19376 [(set (match_dup 0)
19377 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19381 = gen_int_mode (INTVAL (operands[3])
19382 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19383 operands[2] = gen_lowpart (SImode, operands[2]);
19387 [(set (match_operand 0 "register_operand" "")
19388 (neg (match_operand 1 "register_operand" "")))
19389 (clobber (reg:CC FLAGS_REG))]
19390 "! TARGET_PARTIAL_REG_STALL && reload_completed
19391 && (GET_MODE (operands[0]) == HImode
19392 || (GET_MODE (operands[0]) == QImode
19393 && (TARGET_PROMOTE_QImode
19394 || optimize_insn_for_size_p ())))"
19395 [(parallel [(set (match_dup 0)
19396 (neg:SI (match_dup 1)))
19397 (clobber (reg:CC FLAGS_REG))])]
19398 "operands[0] = gen_lowpart (SImode, operands[0]);
19399 operands[1] = gen_lowpart (SImode, operands[1]);")
19402 [(set (match_operand 0 "register_operand" "")
19403 (not (match_operand 1 "register_operand" "")))]
19404 "! TARGET_PARTIAL_REG_STALL && reload_completed
19405 && (GET_MODE (operands[0]) == HImode
19406 || (GET_MODE (operands[0]) == QImode
19407 && (TARGET_PROMOTE_QImode
19408 || optimize_insn_for_size_p ())))"
19409 [(set (match_dup 0)
19410 (not:SI (match_dup 1)))]
19411 "operands[0] = gen_lowpart (SImode, operands[0]);
19412 operands[1] = gen_lowpart (SImode, operands[1]);")
19415 [(set (match_operand 0 "register_operand" "")
19416 (if_then_else (match_operator 1 "comparison_operator"
19417 [(reg FLAGS_REG) (const_int 0)])
19418 (match_operand 2 "register_operand" "")
19419 (match_operand 3 "register_operand" "")))]
19420 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19421 && (GET_MODE (operands[0]) == HImode
19422 || (GET_MODE (operands[0]) == QImode
19423 && (TARGET_PROMOTE_QImode
19424 || optimize_insn_for_size_p ())))"
19425 [(set (match_dup 0)
19426 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19427 "operands[0] = gen_lowpart (SImode, operands[0]);
19428 operands[2] = gen_lowpart (SImode, operands[2]);
19429 operands[3] = gen_lowpart (SImode, operands[3]);")
19432 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19433 ;; transform a complex memory operation into two memory to register operations.
19435 ;; Don't push memory operands
19437 [(set (match_operand:SI 0 "push_operand" "")
19438 (match_operand:SI 1 "memory_operand" ""))
19439 (match_scratch:SI 2 "r")]
19440 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19441 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19442 [(set (match_dup 2) (match_dup 1))
19443 (set (match_dup 0) (match_dup 2))]
19447 [(set (match_operand:DI 0 "push_operand" "")
19448 (match_operand:DI 1 "memory_operand" ""))
19449 (match_scratch:DI 2 "r")]
19450 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19451 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19452 [(set (match_dup 2) (match_dup 1))
19453 (set (match_dup 0) (match_dup 2))]
19456 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19459 [(set (match_operand:SF 0 "push_operand" "")
19460 (match_operand:SF 1 "memory_operand" ""))
19461 (match_scratch:SF 2 "r")]
19462 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19463 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19464 [(set (match_dup 2) (match_dup 1))
19465 (set (match_dup 0) (match_dup 2))]
19469 [(set (match_operand:HI 0 "push_operand" "")
19470 (match_operand:HI 1 "memory_operand" ""))
19471 (match_scratch:HI 2 "r")]
19472 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19473 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19474 [(set (match_dup 2) (match_dup 1))
19475 (set (match_dup 0) (match_dup 2))]
19479 [(set (match_operand:QI 0 "push_operand" "")
19480 (match_operand:QI 1 "memory_operand" ""))
19481 (match_scratch:QI 2 "q")]
19482 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19483 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19484 [(set (match_dup 2) (match_dup 1))
19485 (set (match_dup 0) (match_dup 2))]
19488 ;; Don't move an immediate directly to memory when the instruction
19491 [(match_scratch:SI 1 "r")
19492 (set (match_operand:SI 0 "memory_operand" "")
19494 "optimize_insn_for_speed_p ()
19495 && ! TARGET_USE_MOV0
19496 && TARGET_SPLIT_LONG_MOVES
19497 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19498 && peep2_regno_dead_p (0, FLAGS_REG)"
19499 [(parallel [(set (match_dup 1) (const_int 0))
19500 (clobber (reg:CC FLAGS_REG))])
19501 (set (match_dup 0) (match_dup 1))]
19505 [(match_scratch:HI 1 "r")
19506 (set (match_operand:HI 0 "memory_operand" "")
19508 "optimize_insn_for_speed_p ()
19509 && ! TARGET_USE_MOV0
19510 && TARGET_SPLIT_LONG_MOVES
19511 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19512 && peep2_regno_dead_p (0, FLAGS_REG)"
19513 [(parallel [(set (match_dup 2) (const_int 0))
19514 (clobber (reg:CC FLAGS_REG))])
19515 (set (match_dup 0) (match_dup 1))]
19516 "operands[2] = gen_lowpart (SImode, operands[1]);")
19519 [(match_scratch:QI 1 "q")
19520 (set (match_operand:QI 0 "memory_operand" "")
19522 "optimize_insn_for_speed_p ()
19523 && ! TARGET_USE_MOV0
19524 && TARGET_SPLIT_LONG_MOVES
19525 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19526 && peep2_regno_dead_p (0, FLAGS_REG)"
19527 [(parallel [(set (match_dup 2) (const_int 0))
19528 (clobber (reg:CC FLAGS_REG))])
19529 (set (match_dup 0) (match_dup 1))]
19530 "operands[2] = gen_lowpart (SImode, operands[1]);")
19533 [(match_scratch:SI 2 "r")
19534 (set (match_operand:SI 0 "memory_operand" "")
19535 (match_operand:SI 1 "immediate_operand" ""))]
19536 "optimize_insn_for_speed_p ()
19537 && TARGET_SPLIT_LONG_MOVES
19538 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19539 [(set (match_dup 2) (match_dup 1))
19540 (set (match_dup 0) (match_dup 2))]
19544 [(match_scratch:HI 2 "r")
19545 (set (match_operand:HI 0 "memory_operand" "")
19546 (match_operand:HI 1 "immediate_operand" ""))]
19547 "optimize_insn_for_speed_p ()
19548 && TARGET_SPLIT_LONG_MOVES
19549 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19550 [(set (match_dup 2) (match_dup 1))
19551 (set (match_dup 0) (match_dup 2))]
19555 [(match_scratch:QI 2 "q")
19556 (set (match_operand:QI 0 "memory_operand" "")
19557 (match_operand:QI 1 "immediate_operand" ""))]
19558 "optimize_insn_for_speed_p ()
19559 && TARGET_SPLIT_LONG_MOVES
19560 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19561 [(set (match_dup 2) (match_dup 1))
19562 (set (match_dup 0) (match_dup 2))]
19565 ;; Don't compare memory with zero, load and use a test instead.
19567 [(set (match_operand 0 "flags_reg_operand" "")
19568 (match_operator 1 "compare_operator"
19569 [(match_operand:SI 2 "memory_operand" "")
19571 (match_scratch:SI 3 "r")]
19572 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19573 [(set (match_dup 3) (match_dup 2))
19574 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19577 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19578 ;; Don't split NOTs with a displacement operand, because resulting XOR
19579 ;; will not be pairable anyway.
19581 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19582 ;; represented using a modRM byte. The XOR replacement is long decoded,
19583 ;; so this split helps here as well.
19585 ;; Note: Can't do this as a regular split because we can't get proper
19586 ;; lifetime information then.
19589 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19590 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19591 "optimize_insn_for_speed_p ()
19592 && ((TARGET_NOT_UNPAIRABLE
19593 && (!MEM_P (operands[0])
19594 || !memory_displacement_operand (operands[0], SImode)))
19595 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19596 && peep2_regno_dead_p (0, FLAGS_REG)"
19597 [(parallel [(set (match_dup 0)
19598 (xor:SI (match_dup 1) (const_int -1)))
19599 (clobber (reg:CC FLAGS_REG))])]
19603 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19604 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19605 "optimize_insn_for_speed_p ()
19606 && ((TARGET_NOT_UNPAIRABLE
19607 && (!MEM_P (operands[0])
19608 || !memory_displacement_operand (operands[0], HImode)))
19609 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19610 && peep2_regno_dead_p (0, FLAGS_REG)"
19611 [(parallel [(set (match_dup 0)
19612 (xor:HI (match_dup 1) (const_int -1)))
19613 (clobber (reg:CC FLAGS_REG))])]
19617 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19618 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19619 "optimize_insn_for_speed_p ()
19620 && ((TARGET_NOT_UNPAIRABLE
19621 && (!MEM_P (operands[0])
19622 || !memory_displacement_operand (operands[0], QImode)))
19623 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19624 && peep2_regno_dead_p (0, FLAGS_REG)"
19625 [(parallel [(set (match_dup 0)
19626 (xor:QI (match_dup 1) (const_int -1)))
19627 (clobber (reg:CC FLAGS_REG))])]
19630 ;; Non pairable "test imm, reg" instructions can be translated to
19631 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19632 ;; byte opcode instead of two, have a short form for byte operands),
19633 ;; so do it for other CPUs as well. Given that the value was dead,
19634 ;; this should not create any new dependencies. Pass on the sub-word
19635 ;; versions if we're concerned about partial register stalls.
19638 [(set (match_operand 0 "flags_reg_operand" "")
19639 (match_operator 1 "compare_operator"
19640 [(and:SI (match_operand:SI 2 "register_operand" "")
19641 (match_operand:SI 3 "immediate_operand" ""))
19643 "ix86_match_ccmode (insn, CCNOmode)
19644 && (true_regnum (operands[2]) != AX_REG
19645 || satisfies_constraint_K (operands[3]))
19646 && peep2_reg_dead_p (1, operands[2])"
19648 [(set (match_dup 0)
19649 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19652 (and:SI (match_dup 2) (match_dup 3)))])]
19655 ;; We don't need to handle HImode case, because it will be promoted to SImode
19656 ;; on ! TARGET_PARTIAL_REG_STALL
19659 [(set (match_operand 0 "flags_reg_operand" "")
19660 (match_operator 1 "compare_operator"
19661 [(and:QI (match_operand:QI 2 "register_operand" "")
19662 (match_operand:QI 3 "immediate_operand" ""))
19664 "! TARGET_PARTIAL_REG_STALL
19665 && ix86_match_ccmode (insn, CCNOmode)
19666 && true_regnum (operands[2]) != AX_REG
19667 && peep2_reg_dead_p (1, operands[2])"
19669 [(set (match_dup 0)
19670 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19673 (and:QI (match_dup 2) (match_dup 3)))])]
19677 [(set (match_operand 0 "flags_reg_operand" "")
19678 (match_operator 1 "compare_operator"
19681 (match_operand 2 "ext_register_operand" "")
19684 (match_operand 3 "const_int_operand" ""))
19686 "! TARGET_PARTIAL_REG_STALL
19687 && ix86_match_ccmode (insn, CCNOmode)
19688 && true_regnum (operands[2]) != AX_REG
19689 && peep2_reg_dead_p (1, operands[2])"
19690 [(parallel [(set (match_dup 0)
19699 (set (zero_extract:SI (match_dup 2)
19710 ;; Don't do logical operations with memory inputs.
19712 [(match_scratch:SI 2 "r")
19713 (parallel [(set (match_operand:SI 0 "register_operand" "")
19714 (match_operator:SI 3 "arith_or_logical_operator"
19716 (match_operand:SI 1 "memory_operand" "")]))
19717 (clobber (reg:CC FLAGS_REG))])]
19718 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19719 [(set (match_dup 2) (match_dup 1))
19720 (parallel [(set (match_dup 0)
19721 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19722 (clobber (reg:CC FLAGS_REG))])]
19726 [(match_scratch:SI 2 "r")
19727 (parallel [(set (match_operand:SI 0 "register_operand" "")
19728 (match_operator:SI 3 "arith_or_logical_operator"
19729 [(match_operand:SI 1 "memory_operand" "")
19731 (clobber (reg:CC FLAGS_REG))])]
19732 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19733 [(set (match_dup 2) (match_dup 1))
19734 (parallel [(set (match_dup 0)
19735 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19736 (clobber (reg:CC FLAGS_REG))])]
19739 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
19740 ;; refers to the destination of the load!
19743 [(set (match_operand:SI 0 "register_operand" "")
19744 (match_operand:SI 1 "register_operand" ""))
19745 (parallel [(set (match_dup 0)
19746 (match_operator:SI 3 "commutative_operator"
19748 (match_operand:SI 2 "memory_operand" "")]))
19749 (clobber (reg:CC FLAGS_REG))])]
19750 "REGNO (operands[0]) != REGNO (operands[1])
19751 && GENERAL_REGNO_P (REGNO (operands[0]))
19752 && GENERAL_REGNO_P (REGNO (operands[1]))"
19753 [(set (match_dup 0) (match_dup 4))
19754 (parallel [(set (match_dup 0)
19755 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19756 (clobber (reg:CC FLAGS_REG))])]
19757 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
19760 [(set (match_operand 0 "register_operand" "")
19761 (match_operand 1 "register_operand" ""))
19763 (match_operator 3 "commutative_operator"
19765 (match_operand 2 "memory_operand" "")]))]
19766 "REGNO (operands[0]) != REGNO (operands[1])
19767 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
19768 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
19769 [(set (match_dup 0) (match_dup 2))
19771 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
19774 ; Don't do logical operations with memory outputs
19776 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19777 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19778 ; the same decoder scheduling characteristics as the original.
19781 [(match_scratch:SI 2 "r")
19782 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19783 (match_operator:SI 3 "arith_or_logical_operator"
19785 (match_operand:SI 1 "nonmemory_operand" "")]))
19786 (clobber (reg:CC FLAGS_REG))])]
19787 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19788 /* Do not split stack checking probes. */
19789 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19790 [(set (match_dup 2) (match_dup 0))
19791 (parallel [(set (match_dup 2)
19792 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19793 (clobber (reg:CC FLAGS_REG))])
19794 (set (match_dup 0) (match_dup 2))]
19798 [(match_scratch:SI 2 "r")
19799 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19800 (match_operator:SI 3 "arith_or_logical_operator"
19801 [(match_operand:SI 1 "nonmemory_operand" "")
19803 (clobber (reg:CC FLAGS_REG))])]
19804 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19805 /* Do not split stack checking probes. */
19806 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19807 [(set (match_dup 2) (match_dup 0))
19808 (parallel [(set (match_dup 2)
19809 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19810 (clobber (reg:CC FLAGS_REG))])
19811 (set (match_dup 0) (match_dup 2))]
19814 ;; Attempt to always use XOR for zeroing registers.
19816 [(set (match_operand 0 "register_operand" "")
19817 (match_operand 1 "const0_operand" ""))]
19818 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19819 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19820 && GENERAL_REG_P (operands[0])
19821 && peep2_regno_dead_p (0, FLAGS_REG)"
19822 [(parallel [(set (match_dup 0) (const_int 0))
19823 (clobber (reg:CC FLAGS_REG))])]
19825 operands[0] = gen_lowpart (word_mode, operands[0]);
19829 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19831 "(GET_MODE (operands[0]) == QImode
19832 || GET_MODE (operands[0]) == HImode)
19833 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19834 && peep2_regno_dead_p (0, FLAGS_REG)"
19835 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19836 (clobber (reg:CC FLAGS_REG))])])
19838 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19840 [(set (match_operand 0 "register_operand" "")
19842 "(GET_MODE (operands[0]) == HImode
19843 || GET_MODE (operands[0]) == SImode
19844 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19845 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
19846 && peep2_regno_dead_p (0, FLAGS_REG)"
19847 [(parallel [(set (match_dup 0) (const_int -1))
19848 (clobber (reg:CC FLAGS_REG))])]
19849 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19852 ;; Attempt to convert simple leas to adds. These can be created by
19855 [(set (match_operand:SI 0 "register_operand" "")
19856 (plus:SI (match_dup 0)
19857 (match_operand:SI 1 "nonmemory_operand" "")))]
19858 "peep2_regno_dead_p (0, FLAGS_REG)"
19859 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19860 (clobber (reg:CC FLAGS_REG))])]
19864 [(set (match_operand:SI 0 "register_operand" "")
19865 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19866 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19867 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19868 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19869 (clobber (reg:CC FLAGS_REG))])]
19870 "operands[2] = gen_lowpart (SImode, operands[2]);")
19873 [(set (match_operand:DI 0 "register_operand" "")
19874 (plus:DI (match_dup 0)
19875 (match_operand:DI 1 "x86_64_general_operand" "")))]
19876 "peep2_regno_dead_p (0, FLAGS_REG)"
19877 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19878 (clobber (reg:CC FLAGS_REG))])]
19882 [(set (match_operand:SI 0 "register_operand" "")
19883 (mult:SI (match_dup 0)
19884 (match_operand:SI 1 "const_int_operand" "")))]
19885 "exact_log2 (INTVAL (operands[1])) >= 0
19886 && peep2_regno_dead_p (0, FLAGS_REG)"
19887 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19888 (clobber (reg:CC FLAGS_REG))])]
19889 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19892 [(set (match_operand:DI 0 "register_operand" "")
19893 (mult:DI (match_dup 0)
19894 (match_operand:DI 1 "const_int_operand" "")))]
19895 "exact_log2 (INTVAL (operands[1])) >= 0
19896 && peep2_regno_dead_p (0, FLAGS_REG)"
19897 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19898 (clobber (reg:CC FLAGS_REG))])]
19899 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19902 [(set (match_operand:SI 0 "register_operand" "")
19903 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19904 (match_operand:DI 2 "const_int_operand" "")) 0))]
19905 "exact_log2 (INTVAL (operands[2])) >= 0
19906 && REGNO (operands[0]) == REGNO (operands[1])
19907 && peep2_regno_dead_p (0, FLAGS_REG)"
19908 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19909 (clobber (reg:CC FLAGS_REG))])]
19910 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19912 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19913 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19914 ;; many CPUs it is also faster, since special hardware to avoid esp
19915 ;; dependencies is present.
19917 ;; While some of these conversions may be done using splitters, we use peepholes
19918 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19920 ;; Convert prologue esp subtractions to push.
19921 ;; We need register to push. In order to keep verify_flow_info happy we have
19923 ;; - use scratch and clobber it in order to avoid dependencies
19924 ;; - use already live register
19925 ;; We can't use the second way right now, since there is no reliable way how to
19926 ;; verify that given register is live. First choice will also most likely in
19927 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19928 ;; call clobbered registers are dead. We may want to use base pointer as an
19929 ;; alternative when no register is available later.
19932 [(match_scratch:SI 0 "r")
19933 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19934 (clobber (reg:CC FLAGS_REG))
19935 (clobber (mem:BLK (scratch)))])]
19936 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19937 [(clobber (match_dup 0))
19938 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19939 (clobber (mem:BLK (scratch)))])])
19942 [(match_scratch:SI 0 "r")
19943 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19944 (clobber (reg:CC FLAGS_REG))
19945 (clobber (mem:BLK (scratch)))])]
19946 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19947 [(clobber (match_dup 0))
19948 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19949 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19950 (clobber (mem:BLK (scratch)))])])
19952 ;; Convert esp subtractions to push.
19954 [(match_scratch:SI 0 "r")
19955 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19956 (clobber (reg:CC FLAGS_REG))])]
19957 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19958 [(clobber (match_dup 0))
19959 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19962 [(match_scratch:SI 0 "r")
19963 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19964 (clobber (reg:CC FLAGS_REG))])]
19965 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19966 [(clobber (match_dup 0))
19967 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19968 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19970 ;; Convert epilogue deallocator to pop.
19972 [(match_scratch:SI 0 "r")
19973 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19974 (clobber (reg:CC FLAGS_REG))
19975 (clobber (mem:BLK (scratch)))])]
19976 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19977 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19978 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19979 (clobber (mem:BLK (scratch)))])]
19982 ;; Two pops case is tricky, since pop causes dependency on destination register.
19983 ;; We use two registers if available.
19985 [(match_scratch:SI 0 "r")
19986 (match_scratch:SI 1 "r")
19987 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19988 (clobber (reg:CC FLAGS_REG))
19989 (clobber (mem:BLK (scratch)))])]
19990 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19991 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19992 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19993 (clobber (mem:BLK (scratch)))])
19994 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19995 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19999 [(match_scratch:SI 0 "r")
20000 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20001 (clobber (reg:CC FLAGS_REG))
20002 (clobber (mem:BLK (scratch)))])]
20003 "optimize_insn_for_size_p ()"
20004 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20005 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20006 (clobber (mem:BLK (scratch)))])
20007 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20008 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20011 ;; Convert esp additions to pop.
20013 [(match_scratch:SI 0 "r")
20014 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20015 (clobber (reg:CC FLAGS_REG))])]
20017 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20018 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20021 ;; Two pops case is tricky, since pop causes dependency on destination register.
20022 ;; We use two registers if available.
20024 [(match_scratch:SI 0 "r")
20025 (match_scratch:SI 1 "r")
20026 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20027 (clobber (reg:CC FLAGS_REG))])]
20029 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20030 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20031 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20032 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20036 [(match_scratch:SI 0 "r")
20037 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20038 (clobber (reg:CC FLAGS_REG))])]
20039 "optimize_insn_for_size_p ()"
20040 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20041 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20042 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20043 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20046 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20047 ;; required and register dies. Similarly for 128 to -128.
20049 [(set (match_operand 0 "flags_reg_operand" "")
20050 (match_operator 1 "compare_operator"
20051 [(match_operand 2 "register_operand" "")
20052 (match_operand 3 "const_int_operand" "")]))]
20053 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20054 && incdec_operand (operands[3], GET_MODE (operands[3])))
20055 || (!TARGET_FUSE_CMP_AND_BRANCH
20056 && INTVAL (operands[3]) == 128))
20057 && ix86_match_ccmode (insn, CCGCmode)
20058 && peep2_reg_dead_p (1, operands[2])"
20059 [(parallel [(set (match_dup 0)
20060 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20061 (clobber (match_dup 2))])]
20065 [(match_scratch:DI 0 "r")
20066 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20067 (clobber (reg:CC FLAGS_REG))
20068 (clobber (mem:BLK (scratch)))])]
20069 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20070 [(clobber (match_dup 0))
20071 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20072 (clobber (mem:BLK (scratch)))])])
20075 [(match_scratch:DI 0 "r")
20076 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20077 (clobber (reg:CC FLAGS_REG))
20078 (clobber (mem:BLK (scratch)))])]
20079 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20080 [(clobber (match_dup 0))
20081 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20082 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20083 (clobber (mem:BLK (scratch)))])])
20085 ;; Convert esp subtractions to push.
20087 [(match_scratch:DI 0 "r")
20088 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20089 (clobber (reg:CC FLAGS_REG))])]
20090 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20091 [(clobber (match_dup 0))
20092 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20095 [(match_scratch:DI 0 "r")
20096 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20097 (clobber (reg:CC FLAGS_REG))])]
20098 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20099 [(clobber (match_dup 0))
20100 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20101 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20103 ;; Convert epilogue deallocator to pop.
20105 [(match_scratch:DI 0 "r")
20106 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20107 (clobber (reg:CC FLAGS_REG))
20108 (clobber (mem:BLK (scratch)))])]
20109 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20110 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20111 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20112 (clobber (mem:BLK (scratch)))])]
20115 ;; Two pops case is tricky, since pop causes dependency on destination register.
20116 ;; We use two registers if available.
20118 [(match_scratch:DI 0 "r")
20119 (match_scratch:DI 1 "r")
20120 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20121 (clobber (reg:CC FLAGS_REG))
20122 (clobber (mem:BLK (scratch)))])]
20123 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20124 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20125 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20126 (clobber (mem:BLK (scratch)))])
20127 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20128 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20132 [(match_scratch:DI 0 "r")
20133 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20134 (clobber (reg:CC FLAGS_REG))
20135 (clobber (mem:BLK (scratch)))])]
20136 "optimize_insn_for_size_p ()"
20137 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20138 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20139 (clobber (mem:BLK (scratch)))])
20140 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20141 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20144 ;; Convert esp additions to pop.
20146 [(match_scratch:DI 0 "r")
20147 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20148 (clobber (reg:CC FLAGS_REG))])]
20150 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20151 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20154 ;; Two pops case is tricky, since pop causes dependency on destination register.
20155 ;; We use two registers if available.
20157 [(match_scratch:DI 0 "r")
20158 (match_scratch:DI 1 "r")
20159 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20160 (clobber (reg:CC FLAGS_REG))])]
20162 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20163 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20164 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20165 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20169 [(match_scratch:DI 0 "r")
20170 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20171 (clobber (reg:CC FLAGS_REG))])]
20172 "optimize_insn_for_size_p ()"
20173 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20174 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20175 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20176 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20179 ;; Convert imul by three, five and nine into lea
20182 [(set (match_operand:SI 0 "register_operand" "")
20183 (mult:SI (match_operand:SI 1 "register_operand" "")
20184 (match_operand:SI 2 "const_int_operand" "")))
20185 (clobber (reg:CC FLAGS_REG))])]
20186 "INTVAL (operands[2]) == 3
20187 || INTVAL (operands[2]) == 5
20188 || INTVAL (operands[2]) == 9"
20189 [(set (match_dup 0)
20190 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20192 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20196 [(set (match_operand:SI 0 "register_operand" "")
20197 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20198 (match_operand:SI 2 "const_int_operand" "")))
20199 (clobber (reg:CC FLAGS_REG))])]
20200 "optimize_insn_for_speed_p ()
20201 && (INTVAL (operands[2]) == 3
20202 || INTVAL (operands[2]) == 5
20203 || INTVAL (operands[2]) == 9)"
20204 [(set (match_dup 0) (match_dup 1))
20206 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20208 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20212 [(set (match_operand:DI 0 "register_operand" "")
20213 (mult:DI (match_operand:DI 1 "register_operand" "")
20214 (match_operand:DI 2 "const_int_operand" "")))
20215 (clobber (reg:CC FLAGS_REG))])]
20217 && (INTVAL (operands[2]) == 3
20218 || INTVAL (operands[2]) == 5
20219 || INTVAL (operands[2]) == 9)"
20220 [(set (match_dup 0)
20221 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20223 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20227 [(set (match_operand:DI 0 "register_operand" "")
20228 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20229 (match_operand:DI 2 "const_int_operand" "")))
20230 (clobber (reg:CC FLAGS_REG))])]
20232 && optimize_insn_for_speed_p ()
20233 && (INTVAL (operands[2]) == 3
20234 || INTVAL (operands[2]) == 5
20235 || INTVAL (operands[2]) == 9)"
20236 [(set (match_dup 0) (match_dup 1))
20238 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20240 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20242 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20243 ;; imul $32bit_imm, reg, reg is direct decoded.
20245 [(match_scratch:DI 3 "r")
20246 (parallel [(set (match_operand:DI 0 "register_operand" "")
20247 (mult:DI (match_operand:DI 1 "memory_operand" "")
20248 (match_operand:DI 2 "immediate_operand" "")))
20249 (clobber (reg:CC FLAGS_REG))])]
20250 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20251 && !satisfies_constraint_K (operands[2])"
20252 [(set (match_dup 3) (match_dup 1))
20253 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20254 (clobber (reg:CC FLAGS_REG))])]
20258 [(match_scratch:SI 3 "r")
20259 (parallel [(set (match_operand:SI 0 "register_operand" "")
20260 (mult:SI (match_operand:SI 1 "memory_operand" "")
20261 (match_operand:SI 2 "immediate_operand" "")))
20262 (clobber (reg:CC FLAGS_REG))])]
20263 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20264 && !satisfies_constraint_K (operands[2])"
20265 [(set (match_dup 3) (match_dup 1))
20266 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20267 (clobber (reg:CC FLAGS_REG))])]
20271 [(match_scratch:SI 3 "r")
20272 (parallel [(set (match_operand:DI 0 "register_operand" "")
20274 (mult:SI (match_operand:SI 1 "memory_operand" "")
20275 (match_operand:SI 2 "immediate_operand" ""))))
20276 (clobber (reg:CC FLAGS_REG))])]
20277 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20278 && !satisfies_constraint_K (operands[2])"
20279 [(set (match_dup 3) (match_dup 1))
20280 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20281 (clobber (reg:CC FLAGS_REG))])]
20284 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20285 ;; Convert it into imul reg, reg
20286 ;; It would be better to force assembler to encode instruction using long
20287 ;; immediate, but there is apparently no way to do so.
20289 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20290 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20291 (match_operand:DI 2 "const_int_operand" "")))
20292 (clobber (reg:CC FLAGS_REG))])
20293 (match_scratch:DI 3 "r")]
20294 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20295 && satisfies_constraint_K (operands[2])"
20296 [(set (match_dup 3) (match_dup 2))
20297 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20298 (clobber (reg:CC FLAGS_REG))])]
20300 if (!rtx_equal_p (operands[0], operands[1]))
20301 emit_move_insn (operands[0], operands[1]);
20305 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20306 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20307 (match_operand:SI 2 "const_int_operand" "")))
20308 (clobber (reg:CC FLAGS_REG))])
20309 (match_scratch:SI 3 "r")]
20310 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20311 && satisfies_constraint_K (operands[2])"
20312 [(set (match_dup 3) (match_dup 2))
20313 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20314 (clobber (reg:CC FLAGS_REG))])]
20316 if (!rtx_equal_p (operands[0], operands[1]))
20317 emit_move_insn (operands[0], operands[1]);
20321 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20322 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20323 (match_operand:HI 2 "immediate_operand" "")))
20324 (clobber (reg:CC FLAGS_REG))])
20325 (match_scratch:HI 3 "r")]
20326 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20327 [(set (match_dup 3) (match_dup 2))
20328 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20329 (clobber (reg:CC FLAGS_REG))])]
20331 if (!rtx_equal_p (operands[0], operands[1]))
20332 emit_move_insn (operands[0], operands[1]);
20335 ;; After splitting up read-modify operations, array accesses with memory
20336 ;; operands might end up in form:
20338 ;; movl 4(%esp), %edx
20340 ;; instead of pre-splitting:
20342 ;; addl 4(%esp), %eax
20344 ;; movl 4(%esp), %edx
20345 ;; leal (%edx,%eax,4), %eax
20348 [(parallel [(set (match_operand 0 "register_operand" "")
20349 (ashift (match_operand 1 "register_operand" "")
20350 (match_operand 2 "const_int_operand" "")))
20351 (clobber (reg:CC FLAGS_REG))])
20352 (set (match_operand 3 "register_operand")
20353 (match_operand 4 "x86_64_general_operand" ""))
20354 (parallel [(set (match_operand 5 "register_operand" "")
20355 (plus (match_operand 6 "register_operand" "")
20356 (match_operand 7 "register_operand" "")))
20357 (clobber (reg:CC FLAGS_REG))])]
20358 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20359 /* Validate MODE for lea. */
20360 && ((!TARGET_PARTIAL_REG_STALL
20361 && (GET_MODE (operands[0]) == QImode
20362 || GET_MODE (operands[0]) == HImode))
20363 || GET_MODE (operands[0]) == SImode
20364 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20365 /* We reorder load and the shift. */
20366 && !rtx_equal_p (operands[1], operands[3])
20367 && !reg_overlap_mentioned_p (operands[0], operands[4])
20368 /* Last PLUS must consist of operand 0 and 3. */
20369 && !rtx_equal_p (operands[0], operands[3])
20370 && (rtx_equal_p (operands[3], operands[6])
20371 || rtx_equal_p (operands[3], operands[7]))
20372 && (rtx_equal_p (operands[0], operands[6])
20373 || rtx_equal_p (operands[0], operands[7]))
20374 /* The intermediate operand 0 must die or be same as output. */
20375 && (rtx_equal_p (operands[0], operands[5])
20376 || peep2_reg_dead_p (3, operands[0]))"
20377 [(set (match_dup 3) (match_dup 4))
20378 (set (match_dup 0) (match_dup 1))]
20380 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20381 int scale = 1 << INTVAL (operands[2]);
20382 rtx index = gen_lowpart (Pmode, operands[1]);
20383 rtx base = gen_lowpart (Pmode, operands[3]);
20384 rtx dest = gen_lowpart (mode, operands[5]);
20386 operands[1] = gen_rtx_PLUS (Pmode, base,
20387 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20389 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20390 operands[0] = dest;
20393 ;; Call-value patterns last so that the wildcard operand does not
20394 ;; disrupt insn-recog's switch tables.
20396 (define_insn "*call_value_pop_0"
20397 [(set (match_operand 0 "" "")
20398 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20399 (match_operand:SI 2 "" "")))
20400 (set (reg:SI SP_REG)
20401 (plus:SI (reg:SI SP_REG)
20402 (match_operand:SI 3 "immediate_operand" "")))]
20405 if (SIBLING_CALL_P (insn))
20408 return "call\t%P1";
20410 [(set_attr "type" "callv")])
20412 (define_insn "*call_value_pop_1"
20413 [(set (match_operand 0 "" "")
20414 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20415 (match_operand:SI 2 "" "")))
20416 (set (reg:SI SP_REG)
20417 (plus:SI (reg:SI SP_REG)
20418 (match_operand:SI 3 "immediate_operand" "i")))]
20419 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20421 if (constant_call_address_operand (operands[1], Pmode))
20422 return "call\t%P1";
20423 return "call\t%A1";
20425 [(set_attr "type" "callv")])
20427 (define_insn "*sibcall_value_pop_1"
20428 [(set (match_operand 0 "" "")
20429 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20430 (match_operand:SI 2 "" "")))
20431 (set (reg:SI SP_REG)
20432 (plus:SI (reg:SI SP_REG)
20433 (match_operand:SI 3 "immediate_operand" "i,i")))]
20434 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20438 [(set_attr "type" "callv")])
20440 (define_insn "*call_value_0"
20441 [(set (match_operand 0 "" "")
20442 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20443 (match_operand:SI 2 "" "")))]
20446 if (SIBLING_CALL_P (insn))
20449 return "call\t%P1";
20451 [(set_attr "type" "callv")])
20453 (define_insn "*call_value_0_rex64"
20454 [(set (match_operand 0 "" "")
20455 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20456 (match_operand:DI 2 "const_int_operand" "")))]
20459 if (SIBLING_CALL_P (insn))
20462 return "call\t%P1";
20464 [(set_attr "type" "callv")])
20466 (define_insn "*call_value_0_rex64_ms_sysv"
20467 [(set (match_operand 0 "" "")
20468 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20469 (match_operand:DI 2 "const_int_operand" "")))
20470 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20471 (clobber (reg:TI XMM6_REG))
20472 (clobber (reg:TI XMM7_REG))
20473 (clobber (reg:TI XMM8_REG))
20474 (clobber (reg:TI XMM9_REG))
20475 (clobber (reg:TI XMM10_REG))
20476 (clobber (reg:TI XMM11_REG))
20477 (clobber (reg:TI XMM12_REG))
20478 (clobber (reg:TI XMM13_REG))
20479 (clobber (reg:TI XMM14_REG))
20480 (clobber (reg:TI XMM15_REG))
20481 (clobber (reg:DI SI_REG))
20482 (clobber (reg:DI DI_REG))]
20483 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20485 if (SIBLING_CALL_P (insn))
20488 return "call\t%P1";
20490 [(set_attr "type" "callv")])
20492 (define_insn "*call_value_1"
20493 [(set (match_operand 0 "" "")
20494 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20495 (match_operand:SI 2 "" "")))]
20496 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20498 if (constant_call_address_operand (operands[1], Pmode))
20499 return "call\t%P1";
20500 return "call\t%A1";
20502 [(set_attr "type" "callv")])
20504 (define_insn "*sibcall_value_1"
20505 [(set (match_operand 0 "" "")
20506 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20507 (match_operand:SI 2 "" "")))]
20508 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20512 [(set_attr "type" "callv")])
20514 (define_insn "*call_value_1_rex64"
20515 [(set (match_operand 0 "" "")
20516 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20517 (match_operand:DI 2 "" "")))]
20518 "TARGET_64BIT && !SIBLING_CALL_P (insn)
20519 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20521 if (constant_call_address_operand (operands[1], Pmode))
20522 return "call\t%P1";
20523 return "call\t%A1";
20525 [(set_attr "type" "callv")])
20527 (define_insn "*call_value_1_rex64_ms_sysv"
20528 [(set (match_operand 0 "" "")
20529 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20530 (match_operand:DI 2 "" "")))
20531 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20532 (clobber (reg:TI XMM6_REG))
20533 (clobber (reg:TI XMM7_REG))
20534 (clobber (reg:TI XMM8_REG))
20535 (clobber (reg:TI XMM9_REG))
20536 (clobber (reg:TI XMM10_REG))
20537 (clobber (reg:TI XMM11_REG))
20538 (clobber (reg:TI XMM12_REG))
20539 (clobber (reg:TI XMM13_REG))
20540 (clobber (reg:TI XMM14_REG))
20541 (clobber (reg:TI XMM15_REG))
20542 (clobber (reg:DI SI_REG))
20543 (clobber (reg:DI DI_REG))]
20544 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20546 if (constant_call_address_operand (operands[1], Pmode))
20547 return "call\t%P1";
20548 return "call\t%A1";
20550 [(set_attr "type" "callv")])
20552 (define_insn "*call_value_1_rex64_large"
20553 [(set (match_operand 0 "" "")
20554 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20555 (match_operand:DI 2 "" "")))]
20556 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20558 [(set_attr "type" "callv")])
20560 (define_insn "*sibcall_value_1_rex64"
20561 [(set (match_operand 0 "" "")
20562 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20563 (match_operand:DI 2 "" "")))]
20564 "TARGET_64BIT && SIBLING_CALL_P (insn)"
20568 [(set_attr "type" "callv")])
20570 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20571 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20572 ;; caught for use by garbage collectors and the like. Using an insn that
20573 ;; maps to SIGILL makes it more likely the program will rightfully die.
20574 ;; Keeping with tradition, "6" is in honor of #UD.
20575 (define_insn "trap"
20576 [(trap_if (const_int 1) (const_int 6))]
20578 { return ASM_SHORT "0x0b0f"; }
20579 [(set_attr "length" "2")])
20581 (define_expand "sse_prologue_save"
20582 [(parallel [(set (match_operand:BLK 0 "" "")
20583 (unspec:BLK [(reg:DI XMM0_REG)
20590 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20591 (use (match_operand:DI 1 "register_operand" ""))
20592 (use (match_operand:DI 2 "immediate_operand" ""))
20593 (use (label_ref:DI (match_operand 3 "" "")))])]
20597 (define_insn "*sse_prologue_save_insn"
20598 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20599 (match_operand:DI 4 "const_int_operand" "n")))
20600 (unspec:BLK [(reg:DI XMM0_REG)
20607 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20608 (use (match_operand:DI 1 "register_operand" "r"))
20609 (use (match_operand:DI 2 "const_int_operand" "i"))
20610 (use (label_ref:DI (match_operand 3 "" "X")))]
20612 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20613 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20616 operands[0] = gen_rtx_MEM (Pmode,
20617 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20618 /* VEX instruction with a REX prefix will #UD. */
20619 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20620 gcc_unreachable ();
20622 output_asm_insn ("jmp\t%A1", operands);
20623 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20625 operands[4] = adjust_address (operands[0], DImode, i*16);
20626 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20627 PUT_MODE (operands[4], TImode);
20628 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20629 output_asm_insn ("rex", operands);
20630 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20632 (*targetm.asm_out.internal_label) (asm_out_file, "L",
20633 CODE_LABEL_NUMBER (operands[3]));
20636 [(set_attr "type" "other")
20637 (set_attr "length_immediate" "0")
20638 (set_attr "length_address" "0")
20639 (set (attr "length")
20641 (eq (symbol_ref "TARGET_AVX") (const_int 0))
20642 (const_string "34")
20643 (const_string "42")))
20644 (set_attr "memory" "store")
20645 (set_attr "modrm" "0")
20646 (set_attr "prefix" "maybe_vex")
20647 (set_attr "mode" "DI")])
20649 (define_expand "prefetch"
20650 [(prefetch (match_operand 0 "address_operand" "")
20651 (match_operand:SI 1 "const_int_operand" "")
20652 (match_operand:SI 2 "const_int_operand" ""))]
20653 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20655 int rw = INTVAL (operands[1]);
20656 int locality = INTVAL (operands[2]);
20658 gcc_assert (rw == 0 || rw == 1);
20659 gcc_assert (locality >= 0 && locality <= 3);
20660 gcc_assert (GET_MODE (operands[0]) == Pmode
20661 || GET_MODE (operands[0]) == VOIDmode);
20663 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20664 supported by SSE counterpart or the SSE prefetch is not available
20665 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20667 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20668 operands[2] = GEN_INT (3);
20670 operands[1] = const0_rtx;
20673 (define_insn "*prefetch_sse"
20674 [(prefetch (match_operand:SI 0 "address_operand" "p")
20676 (match_operand:SI 1 "const_int_operand" ""))]
20677 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20679 static const char * const patterns[4] = {
20680 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20683 int locality = INTVAL (operands[1]);
20684 gcc_assert (locality >= 0 && locality <= 3);
20686 return patterns[locality];
20688 [(set_attr "type" "sse")
20689 (set_attr "atom_sse_attr" "prefetch")
20690 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20691 (set_attr "memory" "none")])
20693 (define_insn "*prefetch_sse_rex"
20694 [(prefetch (match_operand:DI 0 "address_operand" "p")
20696 (match_operand:SI 1 "const_int_operand" ""))]
20697 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20699 static const char * const patterns[4] = {
20700 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20703 int locality = INTVAL (operands[1]);
20704 gcc_assert (locality >= 0 && locality <= 3);
20706 return patterns[locality];
20708 [(set_attr "type" "sse")
20709 (set_attr "atom_sse_attr" "prefetch")
20710 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20711 (set_attr "memory" "none")])
20713 (define_insn "*prefetch_3dnow"
20714 [(prefetch (match_operand:SI 0 "address_operand" "p")
20715 (match_operand:SI 1 "const_int_operand" "n")
20717 "TARGET_3DNOW && !TARGET_64BIT"
20719 if (INTVAL (operands[1]) == 0)
20720 return "prefetch\t%a0";
20722 return "prefetchw\t%a0";
20724 [(set_attr "type" "mmx")
20725 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20726 (set_attr "memory" "none")])
20728 (define_insn "*prefetch_3dnow_rex"
20729 [(prefetch (match_operand:DI 0 "address_operand" "p")
20730 (match_operand:SI 1 "const_int_operand" "n")
20732 "TARGET_3DNOW && TARGET_64BIT"
20734 if (INTVAL (operands[1]) == 0)
20735 return "prefetch\t%a0";
20737 return "prefetchw\t%a0";
20739 [(set_attr "type" "mmx")
20740 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20741 (set_attr "memory" "none")])
20743 (define_expand "stack_protect_set"
20744 [(match_operand 0 "memory_operand" "")
20745 (match_operand 1 "memory_operand" "")]
20748 #ifdef TARGET_THREAD_SSP_OFFSET
20750 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20751 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20753 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20754 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20757 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20759 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20764 (define_insn "stack_protect_set_si"
20765 [(set (match_operand:SI 0 "memory_operand" "=m")
20766 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20767 (set (match_scratch:SI 2 "=&r") (const_int 0))
20768 (clobber (reg:CC FLAGS_REG))]
20770 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20771 [(set_attr "type" "multi")])
20773 (define_insn "stack_protect_set_di"
20774 [(set (match_operand:DI 0 "memory_operand" "=m")
20775 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20776 (set (match_scratch:DI 2 "=&r") (const_int 0))
20777 (clobber (reg:CC FLAGS_REG))]
20779 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20780 [(set_attr "type" "multi")])
20782 (define_insn "stack_tls_protect_set_si"
20783 [(set (match_operand:SI 0 "memory_operand" "=m")
20784 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20785 (set (match_scratch:SI 2 "=&r") (const_int 0))
20786 (clobber (reg:CC FLAGS_REG))]
20788 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20789 [(set_attr "type" "multi")])
20791 (define_insn "stack_tls_protect_set_di"
20792 [(set (match_operand:DI 0 "memory_operand" "=m")
20793 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20794 (set (match_scratch:DI 2 "=&r") (const_int 0))
20795 (clobber (reg:CC FLAGS_REG))]
20798 /* The kernel uses a different segment register for performance reasons; a
20799 system call would not have to trash the userspace segment register,
20800 which would be expensive */
20801 if (ix86_cmodel != CM_KERNEL)
20802 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20804 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20806 [(set_attr "type" "multi")])
20808 (define_expand "stack_protect_test"
20809 [(match_operand 0 "memory_operand" "")
20810 (match_operand 1 "memory_operand" "")
20811 (match_operand 2 "" "")]
20814 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20816 #ifdef TARGET_THREAD_SSP_OFFSET
20818 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20819 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20821 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20822 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20825 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20827 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20830 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20831 flags, const0_rtx, operands[2]));
20835 (define_insn "stack_protect_test_si"
20836 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20837 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20838 (match_operand:SI 2 "memory_operand" "m")]
20840 (clobber (match_scratch:SI 3 "=&r"))]
20842 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20843 [(set_attr "type" "multi")])
20845 (define_insn "stack_protect_test_di"
20846 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20847 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20848 (match_operand:DI 2 "memory_operand" "m")]
20850 (clobber (match_scratch:DI 3 "=&r"))]
20852 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20853 [(set_attr "type" "multi")])
20855 (define_insn "stack_tls_protect_test_si"
20856 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20857 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20858 (match_operand:SI 2 "const_int_operand" "i")]
20859 UNSPEC_SP_TLS_TEST))
20860 (clobber (match_scratch:SI 3 "=r"))]
20862 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
20863 [(set_attr "type" "multi")])
20865 (define_insn "stack_tls_protect_test_di"
20866 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20867 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20868 (match_operand:DI 2 "const_int_operand" "i")]
20869 UNSPEC_SP_TLS_TEST))
20870 (clobber (match_scratch:DI 3 "=r"))]
20873 /* The kernel uses a different segment register for performance reasons; a
20874 system call would not have to trash the userspace segment register,
20875 which would be expensive */
20876 if (ix86_cmodel != CM_KERNEL)
20877 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
20879 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
20881 [(set_attr "type" "multi")])
20883 (define_insn "sse4_2_crc32<mode>"
20884 [(set (match_operand:SI 0 "register_operand" "=r")
20886 [(match_operand:SI 1 "register_operand" "0")
20887 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20889 "TARGET_SSE4_2 || TARGET_CRC32"
20890 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20891 [(set_attr "type" "sselog1")
20892 (set_attr "prefix_rep" "1")
20893 (set_attr "prefix_extra" "1")
20894 (set (attr "prefix_data16")
20895 (if_then_else (match_operand:HI 2 "" "")
20897 (const_string "*")))
20898 (set (attr "prefix_rex")
20899 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
20901 (const_string "*")))
20902 (set_attr "mode" "SI")])
20904 (define_insn "sse4_2_crc32di"
20905 [(set (match_operand:DI 0 "register_operand" "=r")
20907 [(match_operand:DI 1 "register_operand" "0")
20908 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20910 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20911 "crc32{q}\t{%2, %0|%0, %2}"
20912 [(set_attr "type" "sselog1")
20913 (set_attr "prefix_rep" "1")
20914 (set_attr "prefix_extra" "1")
20915 (set_attr "mode" "DI")])
20917 (define_expand "rdpmc"
20918 [(match_operand:DI 0 "register_operand" "")
20919 (match_operand:SI 1 "register_operand" "")]
20922 rtx reg = gen_reg_rtx (DImode);
20925 /* Force operand 1 into ECX. */
20926 rtx ecx = gen_rtx_REG (SImode, CX_REG);
20927 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
20928 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20933 rtvec vec = rtvec_alloc (2);
20934 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20935 rtx upper = gen_reg_rtx (DImode);
20936 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20937 gen_rtvec (1, const0_rtx),
20939 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20940 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20942 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20943 NULL, 1, OPTAB_DIRECT);
20944 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20948 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20949 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20953 (define_insn "*rdpmc"
20954 [(set (match_operand:DI 0 "register_operand" "=A")
20955 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20959 [(set_attr "type" "other")
20960 (set_attr "length" "2")])
20962 (define_insn "*rdpmc_rex64"
20963 [(set (match_operand:DI 0 "register_operand" "=a")
20964 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20966 (set (match_operand:DI 1 "register_operand" "=d")
20967 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20970 [(set_attr "type" "other")
20971 (set_attr "length" "2")])
20973 (define_expand "rdtsc"
20974 [(set (match_operand:DI 0 "register_operand" "")
20975 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20980 rtvec vec = rtvec_alloc (2);
20981 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20982 rtx upper = gen_reg_rtx (DImode);
20983 rtx lower = gen_reg_rtx (DImode);
20984 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20985 gen_rtvec (1, const0_rtx),
20987 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20988 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20990 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20991 NULL, 1, OPTAB_DIRECT);
20992 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20994 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20999 (define_insn "*rdtsc"
21000 [(set (match_operand:DI 0 "register_operand" "=A")
21001 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21004 [(set_attr "type" "other")
21005 (set_attr "length" "2")])
21007 (define_insn "*rdtsc_rex64"
21008 [(set (match_operand:DI 0 "register_operand" "=a")
21009 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21010 (set (match_operand:DI 1 "register_operand" "=d")
21011 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21014 [(set_attr "type" "other")
21015 (set_attr "length" "2")])
21017 (define_expand "rdtscp"
21018 [(match_operand:DI 0 "register_operand" "")
21019 (match_operand:SI 1 "memory_operand" "")]
21022 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21023 gen_rtvec (1, const0_rtx),
21025 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21026 gen_rtvec (1, const0_rtx),
21028 rtx reg = gen_reg_rtx (DImode);
21029 rtx tmp = gen_reg_rtx (SImode);
21033 rtvec vec = rtvec_alloc (3);
21034 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21035 rtx upper = gen_reg_rtx (DImode);
21036 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21037 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21038 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
21040 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21041 NULL, 1, OPTAB_DIRECT);
21042 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21047 rtvec vec = rtvec_alloc (2);
21048 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21049 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21050 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
21053 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21054 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
21058 (define_insn "*rdtscp"
21059 [(set (match_operand:DI 0 "register_operand" "=A")
21060 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21061 (set (match_operand:SI 1 "register_operand" "=c")
21062 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21065 [(set_attr "type" "other")
21066 (set_attr "length" "3")])
21068 (define_insn "*rdtscp_rex64"
21069 [(set (match_operand:DI 0 "register_operand" "=a")
21070 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21071 (set (match_operand:DI 1 "register_operand" "=d")
21072 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21073 (set (match_operand:SI 2 "register_operand" "=c")
21074 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21077 [(set_attr "type" "other")
21078 (set_attr "length" "3")])
21080 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21082 ;; LWP instructions
21084 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21086 (define_insn "lwp_llwpcbhi1"
21087 [(unspec [(match_operand:HI 0 "register_operand" "r")]
21088 UNSPEC_LLWP_INTRINSIC)]
21091 [(set_attr "type" "lwp")
21092 (set_attr "mode" "HI")])
21094 (define_insn "lwp_llwpcbsi1"
21095 [(unspec [(match_operand:SI 0 "register_operand" "r")]
21096 UNSPEC_LLWP_INTRINSIC)]
21099 [(set_attr "type" "lwp")
21100 (set_attr "mode" "SI")])
21102 (define_insn "lwp_llwpcbdi1"
21103 [(unspec [(match_operand:DI 0 "register_operand" "r")]
21104 UNSPEC_LLWP_INTRINSIC)]
21107 [(set_attr "type" "lwp")
21108 (set_attr "mode" "DI")])
21110 (define_insn "lwp_slwpcbhi1"
21111 [(unspec [(match_operand:HI 0 "register_operand" "r")]
21112 UNSPEC_SLWP_INTRINSIC)]
21115 [(set_attr "type" "lwp")
21116 (set_attr "mode" "HI")])
21118 (define_insn "lwp_slwpcbsi1"
21119 [(unspec [(match_operand:SI 0 "register_operand" "r")]
21120 UNSPEC_SLWP_INTRINSIC)]
21123 [(set_attr "type" "lwp")
21124 (set_attr "mode" "SI")])
21126 (define_insn "lwp_slwpcbdi1"
21127 [(unspec [(match_operand:DI 0 "register_operand" "r")]
21128 UNSPEC_SLWP_INTRINSIC)]
21131 [(set_attr "type" "lwp")
21132 (set_attr "mode" "DI")])
21134 (define_insn "lwp_lwpvalhi3"
21135 [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21136 (match_operand:SI 1 "nonimmediate_operand" "rm")
21137 (match_operand:HI 2 "const_int_operand" "")]
21138 UNSPECV_LWPVAL_INTRINSIC)]
21140 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21141 [(set_attr "type" "lwp")
21142 (set_attr "mode" "HI")])
21144 (define_insn "lwp_lwpvalsi3"
21145 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21146 (match_operand:SI 1 "nonimmediate_operand" "rm")
21147 (match_operand:SI 2 "const_int_operand" "")]
21148 UNSPECV_LWPVAL_INTRINSIC)]
21150 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21151 [(set_attr "type" "lwp")
21152 (set_attr "mode" "SI")])
21154 (define_insn "lwp_lwpvaldi3"
21155 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21156 (match_operand:SI 1 "nonimmediate_operand" "rm")
21157 (match_operand:SI 2 "const_int_operand" "")]
21158 UNSPECV_LWPVAL_INTRINSIC)]
21160 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21161 [(set_attr "type" "lwp")
21162 (set_attr "mode" "DI")])
21164 (define_insn "lwp_lwpinshi3"
21165 [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21166 (match_operand:SI 1 "nonimmediate_operand" "rm")
21167 (match_operand:HI 2 "const_int_operand" "")]
21168 UNSPECV_LWPINS_INTRINSIC)]
21170 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21171 [(set_attr "type" "lwp")
21172 (set_attr "mode" "HI")])
21174 (define_insn "lwp_lwpinssi3"
21175 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21176 (match_operand:SI 1 "nonimmediate_operand" "rm")
21177 (match_operand:SI 2 "const_int_operand" "")]
21178 UNSPECV_LWPINS_INTRINSIC)]
21180 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21181 [(set_attr "type" "lwp")
21182 (set_attr "mode" "SI")])
21184 (define_insn "lwp_lwpinsdi3"
21185 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21186 (match_operand:SI 1 "nonimmediate_operand" "rm")
21187 (match_operand:SI 2 "const_int_operand" "")]
21188 UNSPECV_LWPINS_INTRINSIC)]
21190 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21191 [(set_attr "type" "lwp")
21192 (set_attr "mode" "DI")])
21196 (include "sync.md")