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 QImode.
751 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
753 ;; Single word integer modes without QImode and HImode.
754 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
756 ;; All math-dependant single and double word integer modes.
757 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
758 (HI "TARGET_HIMODE_MATH")
759 SI DI (TI "TARGET_64BIT")])
761 ;; Math-dependant single word integer modes.
762 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
763 (HI "TARGET_HIMODE_MATH")
764 SI (DI "TARGET_64BIT")])
766 ;; Math-dependant single word integer modes without QImode.
767 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
768 SI (DI "TARGET_64BIT")])
770 ;; Half mode for double word integer modes.
771 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
772 (DI "TARGET_64BIT")])
774 ;; Double word integer modes.
775 (define_mode_attr DWI [(SI "DI") (DI "TI")])
776 (define_mode_attr dwi [(SI "di") (DI "ti")])
778 ;; Instruction suffix for integer modes.
779 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
781 ;; Register class for integer modes.
782 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
784 ;; Immediate operand constraint for integer modes.
785 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
787 ;; General operand constraint for word modes.
788 (define_mode_attr g [(SI "g") (DI "rme")])
790 ;; Immediate operand constraint for double integer modes.
791 (define_mode_attr di [(SI "iF") (DI "e")])
793 ;; General operand predicate for integer modes.
794 (define_mode_attr general_operand
795 [(QI "general_operand")
796 (HI "general_operand")
797 (SI "general_operand")
798 (DI "x86_64_general_operand")
799 (TI "x86_64_general_operand")])
801 ;; SSE and x87 SFmode and DFmode floating point modes
802 (define_mode_iterator MODEF [SF DF])
804 ;; All x87 floating point modes
805 (define_mode_iterator X87MODEF [SF DF XF])
807 ;; All integer modes handled by x87 fisttp operator.
808 (define_mode_iterator X87MODEI [HI SI DI])
810 ;; All integer modes handled by integer x87 operators.
811 (define_mode_iterator X87MODEI12 [HI SI])
813 ;; All integer modes handled by SSE cvtts?2si* operators.
814 (define_mode_iterator SSEMODEI24 [SI DI])
816 ;; SSE asm suffix for floating point modes
817 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
819 ;; SSE vector mode corresponding to a scalar mode
820 (define_mode_attr ssevecmode
821 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
823 ;; Instruction suffix for REX 64bit operators.
824 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
826 ;; This mode iterator allows :P to be used for patterns that operate on
827 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
828 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
830 ;; Scheduling descriptions
832 (include "pentium.md")
835 (include "athlon.md")
840 ;; Operand and operator predicates and constraints
842 (include "predicates.md")
843 (include "constraints.md")
846 ;; Compare and branch/compare and store instructions.
848 (define_expand "cbranch<mode>4"
849 [(set (reg:CC FLAGS_REG)
850 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
851 (match_operand:SDWIM 2 "<general_operand>" "")))
852 (set (pc) (if_then_else
853 (match_operator 0 "comparison_operator"
854 [(reg:CC FLAGS_REG) (const_int 0)])
855 (label_ref (match_operand 3 "" ""))
859 if (MEM_P (operands[1]) && MEM_P (operands[2]))
860 operands[1] = force_reg (<MODE>mode, operands[1]);
861 ix86_compare_op0 = operands[1];
862 ix86_compare_op1 = operands[2];
863 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
867 (define_expand "cstore<mode>4"
868 [(set (reg:CC FLAGS_REG)
869 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
870 (match_operand:SWIM 3 "<general_operand>" "")))
871 (set (match_operand:QI 0 "register_operand" "")
872 (match_operator 1 "comparison_operator"
873 [(reg:CC FLAGS_REG) (const_int 0)]))]
876 if (MEM_P (operands[2]) && MEM_P (operands[3]))
877 operands[2] = force_reg (<MODE>mode, operands[2]);
878 ix86_compare_op0 = operands[2];
879 ix86_compare_op1 = operands[3];
880 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
884 (define_expand "cmp<mode>_1"
885 [(set (reg:CC FLAGS_REG)
886 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
887 (match_operand:SWI48 1 "<general_operand>" "")))]
891 (define_insn "*cmp<mode>_ccno_1"
892 [(set (reg FLAGS_REG)
893 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
894 (match_operand:SWI 1 "const0_operand" "")))]
895 "ix86_match_ccmode (insn, CCNOmode)"
897 test{<imodesuffix>}\t%0, %0
898 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
899 [(set_attr "type" "test,icmp")
900 (set_attr "length_immediate" "0,1")
901 (set_attr "mode" "<MODE>")])
903 (define_insn "*cmp<mode>_1"
904 [(set (reg FLAGS_REG)
905 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
906 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
907 "ix86_match_ccmode (insn, CCmode)"
908 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
909 [(set_attr "type" "icmp")
910 (set_attr "mode" "<MODE>")])
912 (define_insn "*cmp<mode>_minus_1"
913 [(set (reg FLAGS_REG)
915 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
916 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
918 "ix86_match_ccmode (insn, CCGOCmode)"
919 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
920 [(set_attr "type" "icmp")
921 (set_attr "mode" "<MODE>")])
923 (define_insn "*cmpqi_ext_1"
924 [(set (reg FLAGS_REG)
926 (match_operand:QI 0 "general_operand" "Qm")
929 (match_operand 1 "ext_register_operand" "Q")
932 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
933 "cmp{b}\t{%h1, %0|%0, %h1}"
934 [(set_attr "type" "icmp")
935 (set_attr "mode" "QI")])
937 (define_insn "*cmpqi_ext_1_rex64"
938 [(set (reg FLAGS_REG)
940 (match_operand:QI 0 "register_operand" "Q")
943 (match_operand 1 "ext_register_operand" "Q")
946 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
947 "cmp{b}\t{%h1, %0|%0, %h1}"
948 [(set_attr "type" "icmp")
949 (set_attr "mode" "QI")])
951 (define_insn "*cmpqi_ext_2"
952 [(set (reg FLAGS_REG)
956 (match_operand 0 "ext_register_operand" "Q")
959 (match_operand:QI 1 "const0_operand" "")))]
960 "ix86_match_ccmode (insn, CCNOmode)"
962 [(set_attr "type" "test")
963 (set_attr "length_immediate" "0")
964 (set_attr "mode" "QI")])
966 (define_expand "cmpqi_ext_3"
967 [(set (reg:CC FLAGS_REG)
971 (match_operand 0 "ext_register_operand" "")
974 (match_operand:QI 1 "immediate_operand" "")))]
978 (define_insn "*cmpqi_ext_3_insn"
979 [(set (reg FLAGS_REG)
983 (match_operand 0 "ext_register_operand" "Q")
986 (match_operand:QI 1 "general_operand" "Qmn")))]
987 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
988 "cmp{b}\t{%1, %h0|%h0, %1}"
989 [(set_attr "type" "icmp")
990 (set_attr "modrm" "1")
991 (set_attr "mode" "QI")])
993 (define_insn "*cmpqi_ext_3_insn_rex64"
994 [(set (reg FLAGS_REG)
998 (match_operand 0 "ext_register_operand" "Q")
1001 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1002 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1003 "cmp{b}\t{%1, %h0|%h0, %1}"
1004 [(set_attr "type" "icmp")
1005 (set_attr "modrm" "1")
1006 (set_attr "mode" "QI")])
1008 (define_insn "*cmpqi_ext_4"
1009 [(set (reg FLAGS_REG)
1013 (match_operand 0 "ext_register_operand" "Q")
1018 (match_operand 1 "ext_register_operand" "Q")
1020 (const_int 8)) 0)))]
1021 "ix86_match_ccmode (insn, CCmode)"
1022 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1023 [(set_attr "type" "icmp")
1024 (set_attr "mode" "QI")])
1026 ;; These implement float point compares.
1027 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1028 ;; which would allow mix and match FP modes on the compares. Which is what
1029 ;; the old patterns did, but with many more of them.
1031 (define_expand "cbranchxf4"
1032 [(set (reg:CC FLAGS_REG)
1033 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1034 (match_operand:XF 2 "nonmemory_operand" "")))
1035 (set (pc) (if_then_else
1036 (match_operator 0 "ix86_fp_comparison_operator"
1039 (label_ref (match_operand 3 "" ""))
1043 ix86_compare_op0 = operands[1];
1044 ix86_compare_op1 = operands[2];
1045 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1049 (define_expand "cstorexf4"
1050 [(set (reg:CC FLAGS_REG)
1051 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1052 (match_operand:XF 3 "nonmemory_operand" "")))
1053 (set (match_operand:QI 0 "register_operand" "")
1054 (match_operator 1 "ix86_fp_comparison_operator"
1059 ix86_compare_op0 = operands[2];
1060 ix86_compare_op1 = operands[3];
1061 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1065 (define_expand "cbranch<mode>4"
1066 [(set (reg:CC FLAGS_REG)
1067 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1068 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1069 (set (pc) (if_then_else
1070 (match_operator 0 "ix86_fp_comparison_operator"
1073 (label_ref (match_operand 3 "" ""))
1075 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1077 ix86_compare_op0 = operands[1];
1078 ix86_compare_op1 = operands[2];
1079 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1083 (define_expand "cstore<mode>4"
1084 [(set (reg:CC FLAGS_REG)
1085 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1086 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1087 (set (match_operand:QI 0 "register_operand" "")
1088 (match_operator 1 "ix86_fp_comparison_operator"
1091 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1093 ix86_compare_op0 = operands[2];
1094 ix86_compare_op1 = operands[3];
1095 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1099 (define_expand "cbranchcc4"
1100 [(set (pc) (if_then_else
1101 (match_operator 0 "comparison_operator"
1102 [(match_operand 1 "flags_reg_operand" "")
1103 (match_operand 2 "const0_operand" "")])
1104 (label_ref (match_operand 3 "" ""))
1108 ix86_compare_op0 = operands[1];
1109 ix86_compare_op1 = operands[2];
1110 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1114 (define_expand "cstorecc4"
1115 [(set (match_operand:QI 0 "register_operand" "")
1116 (match_operator 1 "comparison_operator"
1117 [(match_operand 2 "flags_reg_operand" "")
1118 (match_operand 3 "const0_operand" "")]))]
1121 ix86_compare_op0 = operands[2];
1122 ix86_compare_op1 = operands[3];
1123 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1128 ;; FP compares, step 1:
1129 ;; Set the FP condition codes.
1131 ;; CCFPmode compare with exceptions
1132 ;; CCFPUmode compare with no exceptions
1134 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1135 ;; used to manage the reg stack popping would not be preserved.
1137 (define_insn "*cmpfp_0"
1138 [(set (match_operand:HI 0 "register_operand" "=a")
1141 (match_operand 1 "register_operand" "f")
1142 (match_operand 2 "const0_operand" ""))]
1144 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1145 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1146 "* return output_fp_compare (insn, operands, 0, 0);"
1147 [(set_attr "type" "multi")
1148 (set_attr "unit" "i387")
1150 (cond [(match_operand:SF 1 "" "")
1152 (match_operand:DF 1 "" "")
1155 (const_string "XF")))])
1157 (define_insn_and_split "*cmpfp_0_cc"
1158 [(set (reg:CCFP FLAGS_REG)
1160 (match_operand 1 "register_operand" "f")
1161 (match_operand 2 "const0_operand" "")))
1162 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1163 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1164 && TARGET_SAHF && !TARGET_CMOVE
1165 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1167 "&& reload_completed"
1170 [(compare:CCFP (match_dup 1)(match_dup 2))]
1172 (set (reg:CC FLAGS_REG)
1173 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1175 [(set_attr "type" "multi")
1176 (set_attr "unit" "i387")
1178 (cond [(match_operand:SF 1 "" "")
1180 (match_operand:DF 1 "" "")
1183 (const_string "XF")))])
1185 (define_insn "*cmpfp_xf"
1186 [(set (match_operand:HI 0 "register_operand" "=a")
1189 (match_operand:XF 1 "register_operand" "f")
1190 (match_operand:XF 2 "register_operand" "f"))]
1193 "* return output_fp_compare (insn, operands, 0, 0);"
1194 [(set_attr "type" "multi")
1195 (set_attr "unit" "i387")
1196 (set_attr "mode" "XF")])
1198 (define_insn_and_split "*cmpfp_xf_cc"
1199 [(set (reg:CCFP FLAGS_REG)
1201 (match_operand:XF 1 "register_operand" "f")
1202 (match_operand:XF 2 "register_operand" "f")))
1203 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1205 && TARGET_SAHF && !TARGET_CMOVE"
1207 "&& reload_completed"
1210 [(compare:CCFP (match_dup 1)(match_dup 2))]
1212 (set (reg:CC FLAGS_REG)
1213 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1215 [(set_attr "type" "multi")
1216 (set_attr "unit" "i387")
1217 (set_attr "mode" "XF")])
1219 (define_insn "*cmpfp_<mode>"
1220 [(set (match_operand:HI 0 "register_operand" "=a")
1223 (match_operand:MODEF 1 "register_operand" "f")
1224 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1227 "* return output_fp_compare (insn, operands, 0, 0);"
1228 [(set_attr "type" "multi")
1229 (set_attr "unit" "i387")
1230 (set_attr "mode" "<MODE>")])
1232 (define_insn_and_split "*cmpfp_<mode>_cc"
1233 [(set (reg:CCFP FLAGS_REG)
1235 (match_operand:MODEF 1 "register_operand" "f")
1236 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1237 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1239 && TARGET_SAHF && !TARGET_CMOVE"
1241 "&& reload_completed"
1244 [(compare:CCFP (match_dup 1)(match_dup 2))]
1246 (set (reg:CC FLAGS_REG)
1247 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1249 [(set_attr "type" "multi")
1250 (set_attr "unit" "i387")
1251 (set_attr "mode" "<MODE>")])
1253 (define_insn "*cmpfp_u"
1254 [(set (match_operand:HI 0 "register_operand" "=a")
1257 (match_operand 1 "register_operand" "f")
1258 (match_operand 2 "register_operand" "f"))]
1260 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1261 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1262 "* return output_fp_compare (insn, operands, 0, 1);"
1263 [(set_attr "type" "multi")
1264 (set_attr "unit" "i387")
1266 (cond [(match_operand:SF 1 "" "")
1268 (match_operand:DF 1 "" "")
1271 (const_string "XF")))])
1273 (define_insn_and_split "*cmpfp_u_cc"
1274 [(set (reg:CCFPU FLAGS_REG)
1276 (match_operand 1 "register_operand" "f")
1277 (match_operand 2 "register_operand" "f")))
1278 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1279 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1280 && TARGET_SAHF && !TARGET_CMOVE
1281 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1283 "&& reload_completed"
1286 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1288 (set (reg:CC FLAGS_REG)
1289 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1291 [(set_attr "type" "multi")
1292 (set_attr "unit" "i387")
1294 (cond [(match_operand:SF 1 "" "")
1296 (match_operand:DF 1 "" "")
1299 (const_string "XF")))])
1301 (define_insn "*cmpfp_<mode>"
1302 [(set (match_operand:HI 0 "register_operand" "=a")
1305 (match_operand 1 "register_operand" "f")
1306 (match_operator 3 "float_operator"
1307 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1309 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1310 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1311 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1312 "* return output_fp_compare (insn, operands, 0, 0);"
1313 [(set_attr "type" "multi")
1314 (set_attr "unit" "i387")
1315 (set_attr "fp_int_src" "true")
1316 (set_attr "mode" "<MODE>")])
1318 (define_insn_and_split "*cmpfp_<mode>_cc"
1319 [(set (reg:CCFP FLAGS_REG)
1321 (match_operand 1 "register_operand" "f")
1322 (match_operator 3 "float_operator"
1323 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1324 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1325 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1326 && TARGET_SAHF && !TARGET_CMOVE
1327 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1328 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1330 "&& reload_completed"
1335 (match_op_dup 3 [(match_dup 2)]))]
1337 (set (reg:CC FLAGS_REG)
1338 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1340 [(set_attr "type" "multi")
1341 (set_attr "unit" "i387")
1342 (set_attr "fp_int_src" "true")
1343 (set_attr "mode" "<MODE>")])
1345 ;; FP compares, step 2
1346 ;; Move the fpsw to ax.
1348 (define_insn "x86_fnstsw_1"
1349 [(set (match_operand:HI 0 "register_operand" "=a")
1350 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1353 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1354 (set_attr "mode" "SI")
1355 (set_attr "unit" "i387")])
1357 ;; FP compares, step 3
1358 ;; Get ax into flags, general case.
1360 (define_insn "x86_sahf_1"
1361 [(set (reg:CC FLAGS_REG)
1362 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1366 #ifdef HAVE_AS_IX86_SAHF
1369 return ASM_BYTE "0x9e";
1372 [(set_attr "length" "1")
1373 (set_attr "athlon_decode" "vector")
1374 (set_attr "amdfam10_decode" "direct")
1375 (set_attr "mode" "SI")])
1377 ;; Pentium Pro can do steps 1 through 3 in one go.
1378 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1379 (define_insn "*cmpfp_i_mixed"
1380 [(set (reg:CCFP FLAGS_REG)
1381 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1382 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1383 "TARGET_MIX_SSE_I387
1384 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1385 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1386 "* return output_fp_compare (insn, operands, 1, 0);"
1387 [(set_attr "type" "fcmp,ssecomi")
1388 (set_attr "prefix" "orig,maybe_vex")
1390 (if_then_else (match_operand:SF 1 "" "")
1392 (const_string "DF")))
1393 (set (attr "prefix_rep")
1394 (if_then_else (eq_attr "type" "ssecomi")
1396 (const_string "*")))
1397 (set (attr "prefix_data16")
1398 (cond [(eq_attr "type" "fcmp")
1400 (eq_attr "mode" "DF")
1403 (const_string "0")))
1404 (set_attr "athlon_decode" "vector")
1405 (set_attr "amdfam10_decode" "direct")])
1407 (define_insn "*cmpfp_i_sse"
1408 [(set (reg:CCFP FLAGS_REG)
1409 (compare:CCFP (match_operand 0 "register_operand" "x")
1410 (match_operand 1 "nonimmediate_operand" "xm")))]
1412 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1413 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1414 "* return output_fp_compare (insn, operands, 1, 0);"
1415 [(set_attr "type" "ssecomi")
1416 (set_attr "prefix" "maybe_vex")
1418 (if_then_else (match_operand:SF 1 "" "")
1420 (const_string "DF")))
1421 (set_attr "prefix_rep" "0")
1422 (set (attr "prefix_data16")
1423 (if_then_else (eq_attr "mode" "DF")
1425 (const_string "0")))
1426 (set_attr "athlon_decode" "vector")
1427 (set_attr "amdfam10_decode" "direct")])
1429 (define_insn "*cmpfp_i_i387"
1430 [(set (reg:CCFP FLAGS_REG)
1431 (compare:CCFP (match_operand 0 "register_operand" "f")
1432 (match_operand 1 "register_operand" "f")))]
1433 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1435 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1436 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1437 "* return output_fp_compare (insn, operands, 1, 0);"
1438 [(set_attr "type" "fcmp")
1440 (cond [(match_operand:SF 1 "" "")
1442 (match_operand:DF 1 "" "")
1445 (const_string "XF")))
1446 (set_attr "athlon_decode" "vector")
1447 (set_attr "amdfam10_decode" "direct")])
1449 (define_insn "*cmpfp_iu_mixed"
1450 [(set (reg:CCFPU FLAGS_REG)
1451 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1452 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1453 "TARGET_MIX_SSE_I387
1454 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1455 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1456 "* return output_fp_compare (insn, operands, 1, 1);"
1457 [(set_attr "type" "fcmp,ssecomi")
1458 (set_attr "prefix" "orig,maybe_vex")
1460 (if_then_else (match_operand:SF 1 "" "")
1462 (const_string "DF")))
1463 (set (attr "prefix_rep")
1464 (if_then_else (eq_attr "type" "ssecomi")
1466 (const_string "*")))
1467 (set (attr "prefix_data16")
1468 (cond [(eq_attr "type" "fcmp")
1470 (eq_attr "mode" "DF")
1473 (const_string "0")))
1474 (set_attr "athlon_decode" "vector")
1475 (set_attr "amdfam10_decode" "direct")])
1477 (define_insn "*cmpfp_iu_sse"
1478 [(set (reg:CCFPU FLAGS_REG)
1479 (compare:CCFPU (match_operand 0 "register_operand" "x")
1480 (match_operand 1 "nonimmediate_operand" "xm")))]
1482 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1483 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1484 "* return output_fp_compare (insn, operands, 1, 1);"
1485 [(set_attr "type" "ssecomi")
1486 (set_attr "prefix" "maybe_vex")
1488 (if_then_else (match_operand:SF 1 "" "")
1490 (const_string "DF")))
1491 (set_attr "prefix_rep" "0")
1492 (set (attr "prefix_data16")
1493 (if_then_else (eq_attr "mode" "DF")
1495 (const_string "0")))
1496 (set_attr "athlon_decode" "vector")
1497 (set_attr "amdfam10_decode" "direct")])
1499 (define_insn "*cmpfp_iu_387"
1500 [(set (reg:CCFPU FLAGS_REG)
1501 (compare:CCFPU (match_operand 0 "register_operand" "f")
1502 (match_operand 1 "register_operand" "f")))]
1503 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1505 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1506 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1507 "* return output_fp_compare (insn, operands, 1, 1);"
1508 [(set_attr "type" "fcmp")
1510 (cond [(match_operand:SF 1 "" "")
1512 (match_operand:DF 1 "" "")
1515 (const_string "XF")))
1516 (set_attr "athlon_decode" "vector")
1517 (set_attr "amdfam10_decode" "direct")])
1519 ;; Move instructions.
1521 ;; General case of fullword move.
1523 (define_expand "movsi"
1524 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1525 (match_operand:SI 1 "general_operand" ""))]
1527 "ix86_expand_move (SImode, operands); DONE;")
1529 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1532 ;; %%% We don't use a post-inc memory reference because x86 is not a
1533 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1534 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1535 ;; targets without our curiosities, and it is just as easy to represent
1536 ;; this differently.
1538 (define_insn "*pushsi2"
1539 [(set (match_operand:SI 0 "push_operand" "=<")
1540 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1543 [(set_attr "type" "push")
1544 (set_attr "mode" "SI")])
1546 ;; For 64BIT abi we always round up to 8 bytes.
1547 (define_insn "*pushsi2_rex64"
1548 [(set (match_operand:SI 0 "push_operand" "=X")
1549 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1552 [(set_attr "type" "push")
1553 (set_attr "mode" "SI")])
1555 (define_insn "*pushsi2_prologue"
1556 [(set (match_operand:SI 0 "push_operand" "=<")
1557 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1558 (clobber (mem:BLK (scratch)))]
1561 [(set_attr "type" "push")
1562 (set_attr "mode" "SI")])
1564 (define_insn "*popsi1_epilogue"
1565 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1566 (mem:SI (reg:SI SP_REG)))
1567 (set (reg:SI SP_REG)
1568 (plus:SI (reg:SI SP_REG) (const_int 4)))
1569 (clobber (mem:BLK (scratch)))]
1572 [(set_attr "type" "pop")
1573 (set_attr "mode" "SI")])
1575 (define_insn "popsi1"
1576 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1577 (mem:SI (reg:SI SP_REG)))
1578 (set (reg:SI SP_REG)
1579 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1582 [(set_attr "type" "pop")
1583 (set_attr "mode" "SI")])
1585 (define_insn "*movsi_xor"
1586 [(set (match_operand:SI 0 "register_operand" "=r")
1587 (match_operand:SI 1 "const0_operand" ""))
1588 (clobber (reg:CC FLAGS_REG))]
1591 [(set_attr "type" "alu1")
1592 (set_attr "mode" "SI")
1593 (set_attr "length_immediate" "0")])
1595 (define_insn "*movsi_or"
1596 [(set (match_operand:SI 0 "register_operand" "=r")
1597 (match_operand:SI 1 "immediate_operand" "i"))
1598 (clobber (reg:CC FLAGS_REG))]
1600 && operands[1] == constm1_rtx"
1602 operands[1] = constm1_rtx;
1603 return "or{l}\t{%1, %0|%0, %1}";
1605 [(set_attr "type" "alu1")
1606 (set_attr "mode" "SI")
1607 (set_attr "length_immediate" "1")])
1609 (define_insn "*movsi_1"
1610 [(set (match_operand:SI 0 "nonimmediate_operand"
1611 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1612 (match_operand:SI 1 "general_operand"
1613 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1614 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1616 switch (get_attr_type (insn))
1619 if (get_attr_mode (insn) == MODE_TI)
1620 return "%vpxor\t%0, %d0";
1621 return "%vxorps\t%0, %d0";
1624 switch (get_attr_mode (insn))
1627 return "%vmovdqa\t{%1, %0|%0, %1}";
1629 return "%vmovaps\t{%1, %0|%0, %1}";
1631 return "%vmovd\t{%1, %0|%0, %1}";
1633 return "%vmovss\t{%1, %0|%0, %1}";
1639 return "pxor\t%0, %0";
1642 if (get_attr_mode (insn) == MODE_DI)
1643 return "movq\t{%1, %0|%0, %1}";
1644 return "movd\t{%1, %0|%0, %1}";
1647 return "lea{l}\t{%1, %0|%0, %1}";
1650 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1651 return "mov{l}\t{%1, %0|%0, %1}";
1655 (cond [(eq_attr "alternative" "2")
1656 (const_string "mmx")
1657 (eq_attr "alternative" "3,4,5")
1658 (const_string "mmxmov")
1659 (eq_attr "alternative" "6")
1660 (const_string "sselog1")
1661 (eq_attr "alternative" "7,8,9,10,11")
1662 (const_string "ssemov")
1663 (match_operand:DI 1 "pic_32bit_operand" "")
1664 (const_string "lea")
1666 (const_string "imov")))
1667 (set (attr "prefix")
1668 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1669 (const_string "orig")
1670 (const_string "maybe_vex")))
1671 (set (attr "prefix_data16")
1672 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1674 (const_string "*")))
1676 (cond [(eq_attr "alternative" "2,3")
1678 (eq_attr "alternative" "6,7")
1680 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1681 (const_string "V4SF")
1682 (const_string "TI"))
1683 (and (eq_attr "alternative" "8,9,10,11")
1684 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1687 (const_string "SI")))])
1689 ;; Stores and loads of ax to arbitrary constant address.
1690 ;; We fake an second form of instruction to force reload to load address
1691 ;; into register when rax is not available
1692 (define_insn "*movabssi_1_rex64"
1693 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1694 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1695 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1697 movabs{l}\t{%1, %P0|%P0, %1}
1698 mov{l}\t{%1, %a0|%a0, %1}"
1699 [(set_attr "type" "imov")
1700 (set_attr "modrm" "0,*")
1701 (set_attr "length_address" "8,0")
1702 (set_attr "length_immediate" "0,*")
1703 (set_attr "memory" "store")
1704 (set_attr "mode" "SI")])
1706 (define_insn "*movabssi_2_rex64"
1707 [(set (match_operand:SI 0 "register_operand" "=a,r")
1708 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1709 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1711 movabs{l}\t{%P1, %0|%0, %P1}
1712 mov{l}\t{%a1, %0|%0, %a1}"
1713 [(set_attr "type" "imov")
1714 (set_attr "modrm" "0,*")
1715 (set_attr "length_address" "8,0")
1716 (set_attr "length_immediate" "0")
1717 (set_attr "memory" "load")
1718 (set_attr "mode" "SI")])
1720 (define_insn "*swapsi"
1721 [(set (match_operand:SI 0 "register_operand" "+r")
1722 (match_operand:SI 1 "register_operand" "+r"))
1727 [(set_attr "type" "imov")
1728 (set_attr "mode" "SI")
1729 (set_attr "pent_pair" "np")
1730 (set_attr "athlon_decode" "vector")
1731 (set_attr "amdfam10_decode" "double")])
1733 (define_expand "movhi"
1734 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1735 (match_operand:HI 1 "general_operand" ""))]
1737 "ix86_expand_move (HImode, operands); DONE;")
1739 (define_insn "*pushhi2"
1740 [(set (match_operand:HI 0 "push_operand" "=X")
1741 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1744 [(set_attr "type" "push")
1745 (set_attr "mode" "SI")])
1747 ;; For 64BIT abi we always round up to 8 bytes.
1748 (define_insn "*pushhi2_rex64"
1749 [(set (match_operand:HI 0 "push_operand" "=X")
1750 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1753 [(set_attr "type" "push")
1754 (set_attr "mode" "DI")])
1756 (define_insn "*movhi_1"
1757 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1758 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1759 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1761 switch (get_attr_type (insn))
1764 /* movzwl is faster than movw on p2 due to partial word stalls,
1765 though not as fast as an aligned movl. */
1766 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1768 if (get_attr_mode (insn) == MODE_SI)
1769 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1771 return "mov{w}\t{%1, %0|%0, %1}";
1775 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1776 (const_string "imov")
1777 (and (eq_attr "alternative" "0")
1778 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1780 (eq (symbol_ref "TARGET_HIMODE_MATH")
1782 (const_string "imov")
1783 (and (eq_attr "alternative" "1,2")
1784 (match_operand:HI 1 "aligned_operand" ""))
1785 (const_string "imov")
1786 (and (ne (symbol_ref "TARGET_MOVX")
1788 (eq_attr "alternative" "0,2"))
1789 (const_string "imovx")
1791 (const_string "imov")))
1793 (cond [(eq_attr "type" "imovx")
1795 (and (eq_attr "alternative" "1,2")
1796 (match_operand:HI 1 "aligned_operand" ""))
1798 (and (eq_attr "alternative" "0")
1799 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1801 (eq (symbol_ref "TARGET_HIMODE_MATH")
1805 (const_string "HI")))])
1807 ;; Stores and loads of ax to arbitrary constant address.
1808 ;; We fake an second form of instruction to force reload to load address
1809 ;; into register when rax is not available
1810 (define_insn "*movabshi_1_rex64"
1811 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1812 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1813 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1815 movabs{w}\t{%1, %P0|%P0, %1}
1816 mov{w}\t{%1, %a0|%a0, %1}"
1817 [(set_attr "type" "imov")
1818 (set_attr "modrm" "0,*")
1819 (set_attr "length_address" "8,0")
1820 (set_attr "length_immediate" "0,*")
1821 (set_attr "memory" "store")
1822 (set_attr "mode" "HI")])
1824 (define_insn "*movabshi_2_rex64"
1825 [(set (match_operand:HI 0 "register_operand" "=a,r")
1826 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1827 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1829 movabs{w}\t{%P1, %0|%0, %P1}
1830 mov{w}\t{%a1, %0|%0, %a1}"
1831 [(set_attr "type" "imov")
1832 (set_attr "modrm" "0,*")
1833 (set_attr "length_address" "8,0")
1834 (set_attr "length_immediate" "0")
1835 (set_attr "memory" "load")
1836 (set_attr "mode" "HI")])
1838 (define_insn "*swaphi_1"
1839 [(set (match_operand:HI 0 "register_operand" "+r")
1840 (match_operand:HI 1 "register_operand" "+r"))
1843 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1845 [(set_attr "type" "imov")
1846 (set_attr "mode" "SI")
1847 (set_attr "pent_pair" "np")
1848 (set_attr "athlon_decode" "vector")
1849 (set_attr "amdfam10_decode" "double")])
1851 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1852 (define_insn "*swaphi_2"
1853 [(set (match_operand:HI 0 "register_operand" "+r")
1854 (match_operand:HI 1 "register_operand" "+r"))
1857 "TARGET_PARTIAL_REG_STALL"
1859 [(set_attr "type" "imov")
1860 (set_attr "mode" "HI")
1861 (set_attr "pent_pair" "np")
1862 (set_attr "athlon_decode" "vector")])
1864 (define_expand "movstricthi"
1865 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1866 (match_operand:HI 1 "general_operand" ""))]
1869 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1871 /* Don't generate memory->memory moves, go through a register */
1872 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1873 operands[1] = force_reg (HImode, operands[1]);
1876 (define_insn "*movstricthi_1"
1877 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1878 (match_operand:HI 1 "general_operand" "rn,m"))]
1879 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1880 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1881 "mov{w}\t{%1, %0|%0, %1}"
1882 [(set_attr "type" "imov")
1883 (set_attr "mode" "HI")])
1885 (define_insn "*movstricthi_xor"
1886 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1887 (match_operand:HI 1 "const0_operand" ""))
1888 (clobber (reg:CC FLAGS_REG))]
1891 [(set_attr "type" "alu1")
1892 (set_attr "mode" "HI")
1893 (set_attr "length_immediate" "0")])
1895 (define_expand "movqi"
1896 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1897 (match_operand:QI 1 "general_operand" ""))]
1899 "ix86_expand_move (QImode, operands); DONE;")
1901 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1902 ;; "push a byte". But actually we use pushl, which has the effect
1903 ;; of rounding the amount pushed up to a word.
1905 (define_insn "*pushqi2"
1906 [(set (match_operand:QI 0 "push_operand" "=X")
1907 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1910 [(set_attr "type" "push")
1911 (set_attr "mode" "SI")])
1913 ;; For 64BIT abi we always round up to 8 bytes.
1914 (define_insn "*pushqi2_rex64"
1915 [(set (match_operand:QI 0 "push_operand" "=X")
1916 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1919 [(set_attr "type" "push")
1920 (set_attr "mode" "DI")])
1922 ;; Situation is quite tricky about when to choose full sized (SImode) move
1923 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1924 ;; partial register dependency machines (such as AMD Athlon), where QImode
1925 ;; moves issue extra dependency and for partial register stalls machines
1926 ;; that don't use QImode patterns (and QImode move cause stall on the next
1929 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1930 ;; register stall machines with, where we use QImode instructions, since
1931 ;; partial register stall can be caused there. Then we use movzx.
1932 (define_insn "*movqi_1"
1933 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1934 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1935 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1937 switch (get_attr_type (insn))
1940 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1941 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1943 if (get_attr_mode (insn) == MODE_SI)
1944 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1946 return "mov{b}\t{%1, %0|%0, %1}";
1950 (cond [(and (eq_attr "alternative" "5")
1951 (not (match_operand:QI 1 "aligned_operand" "")))
1952 (const_string "imovx")
1953 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1954 (const_string "imov")
1955 (and (eq_attr "alternative" "3")
1956 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1958 (eq (symbol_ref "TARGET_QIMODE_MATH")
1960 (const_string "imov")
1961 (eq_attr "alternative" "3,5")
1962 (const_string "imovx")
1963 (and (ne (symbol_ref "TARGET_MOVX")
1965 (eq_attr "alternative" "2"))
1966 (const_string "imovx")
1968 (const_string "imov")))
1970 (cond [(eq_attr "alternative" "3,4,5")
1972 (eq_attr "alternative" "6")
1974 (eq_attr "type" "imovx")
1976 (and (eq_attr "type" "imov")
1977 (and (eq_attr "alternative" "0,1")
1978 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1980 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1982 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1985 ;; Avoid partial register stalls when not using QImode arithmetic
1986 (and (eq_attr "type" "imov")
1987 (and (eq_attr "alternative" "0,1")
1988 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
1990 (eq (symbol_ref "TARGET_QIMODE_MATH")
1994 (const_string "QI")))])
1996 (define_insn "*swapqi_1"
1997 [(set (match_operand:QI 0 "register_operand" "+r")
1998 (match_operand:QI 1 "register_operand" "+r"))
2001 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2003 [(set_attr "type" "imov")
2004 (set_attr "mode" "SI")
2005 (set_attr "pent_pair" "np")
2006 (set_attr "athlon_decode" "vector")
2007 (set_attr "amdfam10_decode" "vector")])
2009 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2010 (define_insn "*swapqi_2"
2011 [(set (match_operand:QI 0 "register_operand" "+q")
2012 (match_operand:QI 1 "register_operand" "+q"))
2015 "TARGET_PARTIAL_REG_STALL"
2017 [(set_attr "type" "imov")
2018 (set_attr "mode" "QI")
2019 (set_attr "pent_pair" "np")
2020 (set_attr "athlon_decode" "vector")])
2022 (define_expand "movstrictqi"
2023 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2024 (match_operand:QI 1 "general_operand" ""))]
2027 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2029 /* Don't generate memory->memory moves, go through a register. */
2030 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2031 operands[1] = force_reg (QImode, operands[1]);
2034 (define_insn "*movstrictqi_1"
2035 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2036 (match_operand:QI 1 "general_operand" "*qn,m"))]
2037 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2038 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2039 "mov{b}\t{%1, %0|%0, %1}"
2040 [(set_attr "type" "imov")
2041 (set_attr "mode" "QI")])
2043 (define_insn "*movstrictqi_xor"
2044 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2045 (match_operand:QI 1 "const0_operand" ""))
2046 (clobber (reg:CC FLAGS_REG))]
2049 [(set_attr "type" "alu1")
2050 (set_attr "mode" "QI")
2051 (set_attr "length_immediate" "0")])
2053 (define_insn "*movsi_extv_1"
2054 [(set (match_operand:SI 0 "register_operand" "=R")
2055 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2059 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2060 [(set_attr "type" "imovx")
2061 (set_attr "mode" "SI")])
2063 (define_insn "*movhi_extv_1"
2064 [(set (match_operand:HI 0 "register_operand" "=R")
2065 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2069 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2070 [(set_attr "type" "imovx")
2071 (set_attr "mode" "SI")])
2073 (define_insn "*movqi_extv_1"
2074 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2075 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2080 switch (get_attr_type (insn))
2083 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2085 return "mov{b}\t{%h1, %0|%0, %h1}";
2089 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2090 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2091 (ne (symbol_ref "TARGET_MOVX")
2093 (const_string "imovx")
2094 (const_string "imov")))
2096 (if_then_else (eq_attr "type" "imovx")
2098 (const_string "QI")))])
2100 (define_insn "*movqi_extv_1_rex64"
2101 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2102 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2107 switch (get_attr_type (insn))
2110 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2112 return "mov{b}\t{%h1, %0|%0, %h1}";
2116 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2117 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2118 (ne (symbol_ref "TARGET_MOVX")
2120 (const_string "imovx")
2121 (const_string "imov")))
2123 (if_then_else (eq_attr "type" "imovx")
2125 (const_string "QI")))])
2127 ;; Stores and loads of ax to arbitrary constant address.
2128 ;; We fake an second form of instruction to force reload to load address
2129 ;; into register when rax is not available
2130 (define_insn "*movabsqi_1_rex64"
2131 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2132 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2133 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2135 movabs{b}\t{%1, %P0|%P0, %1}
2136 mov{b}\t{%1, %a0|%a0, %1}"
2137 [(set_attr "type" "imov")
2138 (set_attr "modrm" "0,*")
2139 (set_attr "length_address" "8,0")
2140 (set_attr "length_immediate" "0,*")
2141 (set_attr "memory" "store")
2142 (set_attr "mode" "QI")])
2144 (define_insn "*movabsqi_2_rex64"
2145 [(set (match_operand:QI 0 "register_operand" "=a,r")
2146 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2147 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2149 movabs{b}\t{%P1, %0|%0, %P1}
2150 mov{b}\t{%a1, %0|%0, %a1}"
2151 [(set_attr "type" "imov")
2152 (set_attr "modrm" "0,*")
2153 (set_attr "length_address" "8,0")
2154 (set_attr "length_immediate" "0")
2155 (set_attr "memory" "load")
2156 (set_attr "mode" "QI")])
2158 (define_insn "*movdi_extzv_1"
2159 [(set (match_operand:DI 0 "register_operand" "=R")
2160 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2164 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2165 [(set_attr "type" "imovx")
2166 (set_attr "mode" "SI")])
2168 (define_insn "*movsi_extzv_1"
2169 [(set (match_operand:SI 0 "register_operand" "=R")
2170 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2174 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2175 [(set_attr "type" "imovx")
2176 (set_attr "mode" "SI")])
2178 (define_insn "*movqi_extzv_2"
2179 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2180 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2185 switch (get_attr_type (insn))
2188 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2190 return "mov{b}\t{%h1, %0|%0, %h1}";
2194 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2195 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2196 (ne (symbol_ref "TARGET_MOVX")
2198 (const_string "imovx")
2199 (const_string "imov")))
2201 (if_then_else (eq_attr "type" "imovx")
2203 (const_string "QI")))])
2205 (define_insn "*movqi_extzv_2_rex64"
2206 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2207 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2212 switch (get_attr_type (insn))
2215 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2217 return "mov{b}\t{%h1, %0|%0, %h1}";
2221 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2222 (ne (symbol_ref "TARGET_MOVX")
2224 (const_string "imovx")
2225 (const_string "imov")))
2227 (if_then_else (eq_attr "type" "imovx")
2229 (const_string "QI")))])
2231 (define_insn "movsi_insv_1"
2232 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2235 (match_operand:SI 1 "general_operand" "Qmn"))]
2237 "mov{b}\t{%b1, %h0|%h0, %b1}"
2238 [(set_attr "type" "imov")
2239 (set_attr "mode" "QI")])
2241 (define_insn "*movsi_insv_1_rex64"
2242 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2245 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2247 "mov{b}\t{%b1, %h0|%h0, %b1}"
2248 [(set_attr "type" "imov")
2249 (set_attr "mode" "QI")])
2251 (define_insn "movdi_insv_1_rex64"
2252 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2255 (match_operand:DI 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 "*movqi_insv_2"
2262 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2265 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2268 "mov{b}\t{%h1, %h0|%h0, %h1}"
2269 [(set_attr "type" "imov")
2270 (set_attr "mode" "QI")])
2272 (define_expand "movdi"
2273 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2274 (match_operand:DI 1 "general_operand" ""))]
2276 "ix86_expand_move (DImode, operands); DONE;")
2278 (define_insn "*pushdi"
2279 [(set (match_operand:DI 0 "push_operand" "=<")
2280 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2284 (define_insn "*pushdi2_rex64"
2285 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2286 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2291 [(set_attr "type" "push,multi")
2292 (set_attr "mode" "DI")])
2294 ;; Convert impossible pushes of immediate to existing instructions.
2295 ;; First try to get scratch register and go through it. In case this
2296 ;; fails, push sign extended lower part first and then overwrite
2297 ;; upper part by 32bit move.
2299 [(match_scratch:DI 2 "r")
2300 (set (match_operand:DI 0 "push_operand" "")
2301 (match_operand:DI 1 "immediate_operand" ""))]
2302 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2303 && !x86_64_immediate_operand (operands[1], DImode)"
2304 [(set (match_dup 2) (match_dup 1))
2305 (set (match_dup 0) (match_dup 2))]
2308 ;; We need to define this as both peepholer and splitter for case
2309 ;; peephole2 pass is not run.
2310 ;; "&& 1" is needed to keep it from matching the previous pattern.
2312 [(set (match_operand:DI 0 "push_operand" "")
2313 (match_operand:DI 1 "immediate_operand" ""))]
2314 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2315 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2316 [(set (match_dup 0) (match_dup 1))
2317 (set (match_dup 2) (match_dup 3))]
2318 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2319 operands[1] = gen_lowpart (DImode, operands[2]);
2320 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2325 [(set (match_operand:DI 0 "push_operand" "")
2326 (match_operand:DI 1 "immediate_operand" ""))]
2327 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2328 ? epilogue_completed : reload_completed)
2329 && !symbolic_operand (operands[1], DImode)
2330 && !x86_64_immediate_operand (operands[1], DImode)"
2331 [(set (match_dup 0) (match_dup 1))
2332 (set (match_dup 2) (match_dup 3))]
2333 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2334 operands[1] = gen_lowpart (DImode, operands[2]);
2335 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2339 (define_insn "*pushdi2_prologue_rex64"
2340 [(set (match_operand:DI 0 "push_operand" "=<")
2341 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2342 (clobber (mem:BLK (scratch)))]
2345 [(set_attr "type" "push")
2346 (set_attr "mode" "DI")])
2348 (define_insn "*popdi1_epilogue_rex64"
2349 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2350 (mem:DI (reg:DI SP_REG)))
2351 (set (reg:DI SP_REG)
2352 (plus:DI (reg:DI SP_REG) (const_int 8)))
2353 (clobber (mem:BLK (scratch)))]
2356 [(set_attr "type" "pop")
2357 (set_attr "mode" "DI")])
2359 (define_insn "popdi1"
2360 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2361 (mem:DI (reg:DI SP_REG)))
2362 (set (reg:DI SP_REG)
2363 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2366 [(set_attr "type" "pop")
2367 (set_attr "mode" "DI")])
2369 (define_insn "*movdi_xor_rex64"
2370 [(set (match_operand:DI 0 "register_operand" "=r")
2371 (match_operand:DI 1 "const0_operand" ""))
2372 (clobber (reg:CC FLAGS_REG))]
2374 && reload_completed"
2376 [(set_attr "type" "alu1")
2377 (set_attr "mode" "SI")
2378 (set_attr "length_immediate" "0")])
2380 (define_insn "*movdi_or_rex64"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2382 (match_operand:DI 1 "const_int_operand" "i"))
2383 (clobber (reg:CC FLAGS_REG))]
2386 && operands[1] == constm1_rtx"
2388 operands[1] = constm1_rtx;
2389 return "or{q}\t{%1, %0|%0, %1}";
2391 [(set_attr "type" "alu1")
2392 (set_attr "mode" "DI")
2393 (set_attr "length_immediate" "1")])
2395 (define_insn "*movdi_2"
2396 [(set (match_operand:DI 0 "nonimmediate_operand"
2397 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2398 (match_operand:DI 1 "general_operand"
2399 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2400 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2405 movq\t{%1, %0|%0, %1}
2406 movq\t{%1, %0|%0, %1}
2408 %vmovq\t{%1, %0|%0, %1}
2409 %vmovdqa\t{%1, %0|%0, %1}
2410 %vmovq\t{%1, %0|%0, %1}
2412 movlps\t{%1, %0|%0, %1}
2413 movaps\t{%1, %0|%0, %1}
2414 movlps\t{%1, %0|%0, %1}"
2415 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2416 (set (attr "prefix")
2417 (if_then_else (eq_attr "alternative" "5,6,7,8")
2418 (const_string "vex")
2419 (const_string "orig")))
2420 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2423 [(set (match_operand:DI 0 "push_operand" "")
2424 (match_operand:DI 1 "general_operand" ""))]
2425 "!TARGET_64BIT && reload_completed
2426 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2428 "ix86_split_long_move (operands); DONE;")
2430 ;; %%% This multiword shite has got to go.
2432 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2433 (match_operand:DI 1 "general_operand" ""))]
2434 "!TARGET_64BIT && reload_completed
2435 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2436 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2438 "ix86_split_long_move (operands); DONE;")
2440 (define_insn "*movdi_1_rex64"
2441 [(set (match_operand:DI 0 "nonimmediate_operand"
2442 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2443 (match_operand:DI 1 "general_operand"
2444 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2445 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2447 switch (get_attr_type (insn))
2450 if (SSE_REG_P (operands[0]))
2451 return "movq2dq\t{%1, %0|%0, %1}";
2453 return "movdq2q\t{%1, %0|%0, %1}";
2458 if (get_attr_mode (insn) == MODE_TI)
2459 return "vmovdqa\t{%1, %0|%0, %1}";
2461 return "vmovq\t{%1, %0|%0, %1}";
2464 if (get_attr_mode (insn) == MODE_TI)
2465 return "movdqa\t{%1, %0|%0, %1}";
2469 /* Moves from and into integer register is done using movd
2470 opcode with REX prefix. */
2471 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2472 return "movd\t{%1, %0|%0, %1}";
2473 return "movq\t{%1, %0|%0, %1}";
2476 return "%vpxor\t%0, %d0";
2479 return "pxor\t%0, %0";
2485 return "lea{q}\t{%a1, %0|%0, %a1}";
2488 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2489 if (get_attr_mode (insn) == MODE_SI)
2490 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2491 else if (which_alternative == 2)
2492 return "movabs{q}\t{%1, %0|%0, %1}";
2494 return "mov{q}\t{%1, %0|%0, %1}";
2498 (cond [(eq_attr "alternative" "5")
2499 (const_string "mmx")
2500 (eq_attr "alternative" "6,7,8,9,10")
2501 (const_string "mmxmov")
2502 (eq_attr "alternative" "11")
2503 (const_string "sselog1")
2504 (eq_attr "alternative" "12,13,14,15,16")
2505 (const_string "ssemov")
2506 (eq_attr "alternative" "17,18")
2507 (const_string "ssecvt")
2508 (eq_attr "alternative" "4")
2509 (const_string "multi")
2510 (match_operand:DI 1 "pic_32bit_operand" "")
2511 (const_string "lea")
2513 (const_string "imov")))
2516 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2518 (const_string "*")))
2519 (set (attr "length_immediate")
2521 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2523 (const_string "*")))
2524 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2525 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2526 (set (attr "prefix")
2527 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2528 (const_string "maybe_vex")
2529 (const_string "orig")))
2530 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2532 ;; Stores and loads of ax to arbitrary constant address.
2533 ;; We fake an second form of instruction to force reload to load address
2534 ;; into register when rax is not available
2535 (define_insn "*movabsdi_1_rex64"
2536 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2537 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2538 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2540 movabs{q}\t{%1, %P0|%P0, %1}
2541 mov{q}\t{%1, %a0|%a0, %1}"
2542 [(set_attr "type" "imov")
2543 (set_attr "modrm" "0,*")
2544 (set_attr "length_address" "8,0")
2545 (set_attr "length_immediate" "0,*")
2546 (set_attr "memory" "store")
2547 (set_attr "mode" "DI")])
2549 (define_insn "*movabsdi_2_rex64"
2550 [(set (match_operand:DI 0 "register_operand" "=a,r")
2551 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2552 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2554 movabs{q}\t{%P1, %0|%0, %P1}
2555 mov{q}\t{%a1, %0|%0, %a1}"
2556 [(set_attr "type" "imov")
2557 (set_attr "modrm" "0,*")
2558 (set_attr "length_address" "8,0")
2559 (set_attr "length_immediate" "0")
2560 (set_attr "memory" "load")
2561 (set_attr "mode" "DI")])
2563 ;; Convert impossible stores of immediate to existing instructions.
2564 ;; First try to get scratch register and go through it. In case this
2565 ;; fails, move by 32bit parts.
2567 [(match_scratch:DI 2 "r")
2568 (set (match_operand:DI 0 "memory_operand" "")
2569 (match_operand:DI 1 "immediate_operand" ""))]
2570 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2571 && !x86_64_immediate_operand (operands[1], DImode)"
2572 [(set (match_dup 2) (match_dup 1))
2573 (set (match_dup 0) (match_dup 2))]
2576 ;; We need to define this as both peepholer and splitter for case
2577 ;; peephole2 pass is not run.
2578 ;; "&& 1" is needed to keep it from matching the previous pattern.
2580 [(set (match_operand:DI 0 "memory_operand" "")
2581 (match_operand:DI 1 "immediate_operand" ""))]
2582 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2583 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2584 [(set (match_dup 2) (match_dup 3))
2585 (set (match_dup 4) (match_dup 5))]
2586 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2589 [(set (match_operand:DI 0 "memory_operand" "")
2590 (match_operand:DI 1 "immediate_operand" ""))]
2591 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2592 ? epilogue_completed : reload_completed)
2593 && !symbolic_operand (operands[1], DImode)
2594 && !x86_64_immediate_operand (operands[1], DImode)"
2595 [(set (match_dup 2) (match_dup 3))
2596 (set (match_dup 4) (match_dup 5))]
2597 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2599 (define_insn "*swapdi_rex64"
2600 [(set (match_operand:DI 0 "register_operand" "+r")
2601 (match_operand:DI 1 "register_operand" "+r"))
2606 [(set_attr "type" "imov")
2607 (set_attr "mode" "DI")
2608 (set_attr "pent_pair" "np")
2609 (set_attr "athlon_decode" "vector")
2610 (set_attr "amdfam10_decode" "double")])
2612 (define_expand "movoi"
2613 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2614 (match_operand:OI 1 "general_operand" ""))]
2616 "ix86_expand_move (OImode, operands); DONE;")
2618 (define_insn "*movoi_internal"
2619 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2620 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2622 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2624 switch (which_alternative)
2627 return "vxorps\t%0, %0, %0";
2630 if (misaligned_operand (operands[0], OImode)
2631 || misaligned_operand (operands[1], OImode))
2632 return "vmovdqu\t{%1, %0|%0, %1}";
2634 return "vmovdqa\t{%1, %0|%0, %1}";
2639 [(set_attr "type" "sselog1,ssemov,ssemov")
2640 (set_attr "prefix" "vex")
2641 (set_attr "mode" "OI")])
2643 (define_expand "movti"
2644 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2645 (match_operand:TI 1 "nonimmediate_operand" ""))]
2646 "TARGET_SSE || TARGET_64BIT"
2649 ix86_expand_move (TImode, operands);
2650 else if (push_operand (operands[0], TImode))
2651 ix86_expand_push (TImode, operands[1]);
2653 ix86_expand_vector_move (TImode, operands);
2657 (define_insn "*movti_internal"
2658 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2659 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2660 "TARGET_SSE && !TARGET_64BIT
2661 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2663 switch (which_alternative)
2666 if (get_attr_mode (insn) == MODE_V4SF)
2667 return "%vxorps\t%0, %d0";
2669 return "%vpxor\t%0, %d0";
2672 /* TDmode values are passed as TImode on the stack. Moving them
2673 to stack may result in unaligned memory access. */
2674 if (misaligned_operand (operands[0], TImode)
2675 || misaligned_operand (operands[1], TImode))
2677 if (get_attr_mode (insn) == MODE_V4SF)
2678 return "%vmovups\t{%1, %0|%0, %1}";
2680 return "%vmovdqu\t{%1, %0|%0, %1}";
2684 if (get_attr_mode (insn) == MODE_V4SF)
2685 return "%vmovaps\t{%1, %0|%0, %1}";
2687 return "%vmovdqa\t{%1, %0|%0, %1}";
2693 [(set_attr "type" "sselog1,ssemov,ssemov")
2694 (set_attr "prefix" "maybe_vex")
2696 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2697 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2698 (const_string "V4SF")
2699 (and (eq_attr "alternative" "2")
2700 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2702 (const_string "V4SF")]
2703 (const_string "TI")))])
2705 (define_insn "*movti_rex64"
2706 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2707 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2709 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2711 switch (which_alternative)
2717 if (get_attr_mode (insn) == MODE_V4SF)
2718 return "%vxorps\t%0, %d0";
2720 return "%vpxor\t%0, %d0";
2723 /* TDmode values are passed as TImode on the stack. Moving them
2724 to stack may result in unaligned memory access. */
2725 if (misaligned_operand (operands[0], TImode)
2726 || misaligned_operand (operands[1], TImode))
2728 if (get_attr_mode (insn) == MODE_V4SF)
2729 return "%vmovups\t{%1, %0|%0, %1}";
2731 return "%vmovdqu\t{%1, %0|%0, %1}";
2735 if (get_attr_mode (insn) == MODE_V4SF)
2736 return "%vmovaps\t{%1, %0|%0, %1}";
2738 return "%vmovdqa\t{%1, %0|%0, %1}";
2744 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2745 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2747 (cond [(eq_attr "alternative" "2,3")
2749 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2751 (const_string "V4SF")
2752 (const_string "TI"))
2753 (eq_attr "alternative" "4")
2755 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2757 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2759 (const_string "V4SF")
2760 (const_string "TI"))]
2761 (const_string "DI")))])
2764 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2765 (match_operand:TI 1 "general_operand" ""))]
2766 "reload_completed && !SSE_REG_P (operands[0])
2767 && !SSE_REG_P (operands[1])"
2769 "ix86_split_long_move (operands); DONE;")
2771 ;; This expands to what emit_move_complex would generate if we didn't
2772 ;; have a movti pattern. Having this avoids problems with reload on
2773 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2774 ;; to have around all the time.
2775 (define_expand "movcdi"
2776 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2777 (match_operand:CDI 1 "general_operand" ""))]
2780 if (push_operand (operands[0], CDImode))
2781 emit_move_complex_push (CDImode, operands[0], operands[1]);
2783 emit_move_complex_parts (operands[0], operands[1]);
2787 (define_expand "movsf"
2788 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2789 (match_operand:SF 1 "general_operand" ""))]
2791 "ix86_expand_move (SFmode, operands); DONE;")
2793 (define_insn "*pushsf"
2794 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2795 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2798 /* Anything else should be already split before reg-stack. */
2799 gcc_assert (which_alternative == 1);
2800 return "push{l}\t%1";
2802 [(set_attr "type" "multi,push,multi")
2803 (set_attr "unit" "i387,*,*")
2804 (set_attr "mode" "SF,SI,SF")])
2806 (define_insn "*pushsf_rex64"
2807 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2808 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2811 /* Anything else should be already split before reg-stack. */
2812 gcc_assert (which_alternative == 1);
2813 return "push{q}\t%q1";
2815 [(set_attr "type" "multi,push,multi")
2816 (set_attr "unit" "i387,*,*")
2817 (set_attr "mode" "SF,DI,SF")])
2820 [(set (match_operand:SF 0 "push_operand" "")
2821 (match_operand:SF 1 "memory_operand" ""))]
2823 && MEM_P (operands[1])
2824 && (operands[2] = find_constant_src (insn))"
2828 ;; %%% Kill this when call knows how to work this out.
2830 [(set (match_operand:SF 0 "push_operand" "")
2831 (match_operand:SF 1 "any_fp_register_operand" ""))]
2833 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2834 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2837 [(set (match_operand:SF 0 "push_operand" "")
2838 (match_operand:SF 1 "any_fp_register_operand" ""))]
2840 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2841 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2843 (define_insn "*movsf_1"
2844 [(set (match_operand:SF 0 "nonimmediate_operand"
2845 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2846 (match_operand:SF 1 "general_operand"
2847 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2848 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2849 && (reload_in_progress || reload_completed
2850 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2851 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2852 && standard_80387_constant_p (operands[1]))
2853 || GET_CODE (operands[1]) != CONST_DOUBLE
2854 || memory_operand (operands[0], SFmode))"
2856 switch (which_alternative)
2860 return output_387_reg_move (insn, operands);
2863 return standard_80387_constant_opcode (operands[1]);
2867 return "mov{l}\t{%1, %0|%0, %1}";
2869 if (get_attr_mode (insn) == MODE_TI)
2870 return "%vpxor\t%0, %d0";
2872 return "%vxorps\t%0, %d0";
2874 if (get_attr_mode (insn) == MODE_V4SF)
2875 return "%vmovaps\t{%1, %0|%0, %1}";
2877 return "%vmovss\t{%1, %d0|%d0, %1}";
2880 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2881 : "vmovss\t{%1, %0|%0, %1}";
2883 return "movss\t{%1, %0|%0, %1}";
2885 return "%vmovss\t{%1, %0|%0, %1}";
2887 case 9: case 10: case 14: case 15:
2888 return "movd\t{%1, %0|%0, %1}";
2890 return "%vmovd\t{%1, %0|%0, %1}";
2893 return "movq\t{%1, %0|%0, %1}";
2899 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2900 (set (attr "prefix")
2901 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2902 (const_string "maybe_vex")
2903 (const_string "orig")))
2905 (cond [(eq_attr "alternative" "3,4,9,10")
2907 (eq_attr "alternative" "5")
2909 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2911 (ne (symbol_ref "TARGET_SSE2")
2913 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2916 (const_string "V4SF"))
2917 /* For architectures resolving dependencies on
2918 whole SSE registers use APS move to break dependency
2919 chains, otherwise use short move to avoid extra work.
2921 Do the same for architectures resolving dependencies on
2922 the parts. While in DF mode it is better to always handle
2923 just register parts, the SF mode is different due to lack
2924 of instructions to load just part of the register. It is
2925 better to maintain the whole registers in single format
2926 to avoid problems on using packed logical operations. */
2927 (eq_attr "alternative" "6")
2929 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2931 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2933 (const_string "V4SF")
2934 (const_string "SF"))
2935 (eq_attr "alternative" "11")
2936 (const_string "DI")]
2937 (const_string "SF")))])
2939 (define_insn "*swapsf"
2940 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2941 (match_operand:SF 1 "fp_register_operand" "+f"))
2944 "reload_completed || TARGET_80387"
2946 if (STACK_TOP_P (operands[0]))
2951 [(set_attr "type" "fxch")
2952 (set_attr "mode" "SF")])
2954 (define_expand "movdf"
2955 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2956 (match_operand:DF 1 "general_operand" ""))]
2958 "ix86_expand_move (DFmode, operands); DONE;")
2960 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2961 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2962 ;; On the average, pushdf using integers can be still shorter. Allow this
2963 ;; pattern for optimize_size too.
2965 (define_insn "*pushdf_nointeger"
2966 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2967 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2968 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2970 /* This insn should be already split before reg-stack. */
2973 [(set_attr "type" "multi")
2974 (set_attr "unit" "i387,*,*,*")
2975 (set_attr "mode" "DF,SI,SI,DF")])
2977 (define_insn "*pushdf_integer"
2978 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2979 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2980 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2982 /* This insn should be already split before reg-stack. */
2985 [(set_attr "type" "multi")
2986 (set_attr "unit" "i387,*,*")
2987 (set_attr "mode" "DF,SI,DF")])
2989 ;; %%% Kill this when call knows how to work this out.
2991 [(set (match_operand:DF 0 "push_operand" "")
2992 (match_operand:DF 1 "any_fp_register_operand" ""))]
2994 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
2995 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
2999 [(set (match_operand:DF 0 "push_operand" "")
3000 (match_operand:DF 1 "general_operand" ""))]
3003 "ix86_split_long_move (operands); DONE;")
3005 ;; Moving is usually shorter when only FP registers are used. This separate
3006 ;; movdf pattern avoids the use of integer registers for FP operations
3007 ;; when optimizing for size.
3009 (define_insn "*movdf_nointeger"
3010 [(set (match_operand:DF 0 "nonimmediate_operand"
3011 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3012 (match_operand:DF 1 "general_operand"
3013 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3014 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3015 && ((optimize_function_for_size_p (cfun)
3016 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3017 && (reload_in_progress || reload_completed
3018 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3019 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3020 && optimize_function_for_size_p (cfun)
3021 && !memory_operand (operands[0], DFmode)
3022 && standard_80387_constant_p (operands[1]))
3023 || GET_CODE (operands[1]) != CONST_DOUBLE
3024 || ((optimize_function_for_size_p (cfun)
3025 || !TARGET_MEMORY_MISMATCH_STALL
3026 || reload_in_progress || reload_completed)
3027 && memory_operand (operands[0], DFmode)))"
3029 switch (which_alternative)
3033 return output_387_reg_move (insn, operands);
3036 return standard_80387_constant_opcode (operands[1]);
3042 switch (get_attr_mode (insn))
3045 return "%vxorps\t%0, %d0";
3047 return "%vxorpd\t%0, %d0";
3049 return "%vpxor\t%0, %d0";
3056 switch (get_attr_mode (insn))
3059 return "%vmovaps\t{%1, %0|%0, %1}";
3061 return "%vmovapd\t{%1, %0|%0, %1}";
3063 return "%vmovdqa\t{%1, %0|%0, %1}";
3065 return "%vmovq\t{%1, %0|%0, %1}";
3069 if (REG_P (operands[0]) && REG_P (operands[1]))
3070 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3072 return "vmovsd\t{%1, %0|%0, %1}";
3075 return "movsd\t{%1, %0|%0, %1}";
3079 if (REG_P (operands[0]))
3080 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3082 return "vmovlpd\t{%1, %0|%0, %1}";
3085 return "movlpd\t{%1, %0|%0, %1}";
3089 if (REG_P (operands[0]))
3090 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3092 return "vmovlps\t{%1, %0|%0, %1}";
3095 return "movlps\t{%1, %0|%0, %1}";
3104 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3105 (set (attr "prefix")
3106 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3107 (const_string "orig")
3108 (const_string "maybe_vex")))
3109 (set (attr "prefix_data16")
3110 (if_then_else (eq_attr "mode" "V1DF")
3112 (const_string "*")))
3114 (cond [(eq_attr "alternative" "0,1,2")
3116 (eq_attr "alternative" "3,4")
3119 /* For SSE1, we have many fewer alternatives. */
3120 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3121 (cond [(eq_attr "alternative" "5,6")
3122 (const_string "V4SF")
3124 (const_string "V2SF"))
3126 /* xorps is one byte shorter. */
3127 (eq_attr "alternative" "5")
3128 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3130 (const_string "V4SF")
3131 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3135 (const_string "V2DF"))
3137 /* For architectures resolving dependencies on
3138 whole SSE registers use APD move to break dependency
3139 chains, otherwise use short move to avoid extra work.
3141 movaps encodes one byte shorter. */
3142 (eq_attr "alternative" "6")
3144 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3146 (const_string "V4SF")
3147 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3149 (const_string "V2DF")
3151 (const_string "DF"))
3152 /* For architectures resolving dependencies on register
3153 parts we may avoid extra work to zero out upper part
3155 (eq_attr "alternative" "7")
3157 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3159 (const_string "V1DF")
3160 (const_string "DF"))
3162 (const_string "DF")))])
3164 (define_insn "*movdf_integer_rex64"
3165 [(set (match_operand:DF 0 "nonimmediate_operand"
3166 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3167 (match_operand:DF 1 "general_operand"
3168 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3169 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3170 && (reload_in_progress || reload_completed
3171 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3172 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3173 && optimize_function_for_size_p (cfun)
3174 && standard_80387_constant_p (operands[1]))
3175 || GET_CODE (operands[1]) != CONST_DOUBLE
3176 || memory_operand (operands[0], DFmode))"
3178 switch (which_alternative)
3182 return output_387_reg_move (insn, operands);
3185 return standard_80387_constant_opcode (operands[1]);
3192 switch (get_attr_mode (insn))
3195 return "%vxorps\t%0, %d0";
3197 return "%vxorpd\t%0, %d0";
3199 return "%vpxor\t%0, %d0";
3206 switch (get_attr_mode (insn))
3209 return "%vmovaps\t{%1, %0|%0, %1}";
3211 return "%vmovapd\t{%1, %0|%0, %1}";
3213 return "%vmovdqa\t{%1, %0|%0, %1}";
3215 return "%vmovq\t{%1, %0|%0, %1}";
3219 if (REG_P (operands[0]) && REG_P (operands[1]))
3220 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3222 return "vmovsd\t{%1, %0|%0, %1}";
3225 return "movsd\t{%1, %0|%0, %1}";
3227 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3229 return "%vmovlps\t{%1, %d0|%d0, %1}";
3236 return "%vmovd\t{%1, %0|%0, %1}";
3242 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3243 (set (attr "prefix")
3244 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3245 (const_string "orig")
3246 (const_string "maybe_vex")))
3247 (set (attr "prefix_data16")
3248 (if_then_else (eq_attr "mode" "V1DF")
3250 (const_string "*")))
3252 (cond [(eq_attr "alternative" "0,1,2")
3254 (eq_attr "alternative" "3,4,9,10")
3257 /* For SSE1, we have many fewer alternatives. */
3258 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3259 (cond [(eq_attr "alternative" "5,6")
3260 (const_string "V4SF")
3262 (const_string "V2SF"))
3264 /* xorps is one byte shorter. */
3265 (eq_attr "alternative" "5")
3266 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3268 (const_string "V4SF")
3269 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3273 (const_string "V2DF"))
3275 /* For architectures resolving dependencies on
3276 whole SSE registers use APD move to break dependency
3277 chains, otherwise use short move to avoid extra work.
3279 movaps encodes one byte shorter. */
3280 (eq_attr "alternative" "6")
3282 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3284 (const_string "V4SF")
3285 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3287 (const_string "V2DF")
3289 (const_string "DF"))
3290 /* For architectures resolving dependencies on register
3291 parts we may avoid extra work to zero out upper part
3293 (eq_attr "alternative" "7")
3295 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3297 (const_string "V1DF")
3298 (const_string "DF"))
3300 (const_string "DF")))])
3302 (define_insn "*movdf_integer"
3303 [(set (match_operand:DF 0 "nonimmediate_operand"
3304 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3305 (match_operand:DF 1 "general_operand"
3306 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3307 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3308 && optimize_function_for_speed_p (cfun)
3309 && TARGET_INTEGER_DFMODE_MOVES
3310 && (reload_in_progress || reload_completed
3311 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3312 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3313 && optimize_function_for_size_p (cfun)
3314 && standard_80387_constant_p (operands[1]))
3315 || GET_CODE (operands[1]) != CONST_DOUBLE
3316 || memory_operand (operands[0], DFmode))"
3318 switch (which_alternative)
3322 return output_387_reg_move (insn, operands);
3325 return standard_80387_constant_opcode (operands[1]);
3332 switch (get_attr_mode (insn))
3335 return "xorps\t%0, %0";
3337 return "xorpd\t%0, %0";
3339 return "pxor\t%0, %0";
3346 switch (get_attr_mode (insn))
3349 return "movaps\t{%1, %0|%0, %1}";
3351 return "movapd\t{%1, %0|%0, %1}";
3353 return "movdqa\t{%1, %0|%0, %1}";
3355 return "movq\t{%1, %0|%0, %1}";
3357 return "movsd\t{%1, %0|%0, %1}";
3359 return "movlpd\t{%1, %0|%0, %1}";
3361 return "movlps\t{%1, %0|%0, %1}";
3370 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3371 (set (attr "prefix_data16")
3372 (if_then_else (eq_attr "mode" "V1DF")
3374 (const_string "*")))
3376 (cond [(eq_attr "alternative" "0,1,2")
3378 (eq_attr "alternative" "3,4")
3381 /* For SSE1, we have many fewer alternatives. */
3382 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3383 (cond [(eq_attr "alternative" "5,6")
3384 (const_string "V4SF")
3386 (const_string "V2SF"))
3388 /* xorps is one byte shorter. */
3389 (eq_attr "alternative" "5")
3390 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3392 (const_string "V4SF")
3393 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3397 (const_string "V2DF"))
3399 /* For architectures resolving dependencies on
3400 whole SSE registers use APD move to break dependency
3401 chains, otherwise use short move to avoid extra work.
3403 movaps encodes one byte shorter. */
3404 (eq_attr "alternative" "6")
3406 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3408 (const_string "V4SF")
3409 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3411 (const_string "V2DF")
3413 (const_string "DF"))
3414 /* For architectures resolving dependencies on register
3415 parts we may avoid extra work to zero out upper part
3417 (eq_attr "alternative" "7")
3419 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3421 (const_string "V1DF")
3422 (const_string "DF"))
3424 (const_string "DF")))])
3427 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3428 (match_operand:DF 1 "general_operand" ""))]
3430 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3431 && ! (ANY_FP_REG_P (operands[0]) ||
3432 (GET_CODE (operands[0]) == SUBREG
3433 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3434 && ! (ANY_FP_REG_P (operands[1]) ||
3435 (GET_CODE (operands[1]) == SUBREG
3436 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3438 "ix86_split_long_move (operands); DONE;")
3440 (define_insn "*swapdf"
3441 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3442 (match_operand:DF 1 "fp_register_operand" "+f"))
3445 "reload_completed || TARGET_80387"
3447 if (STACK_TOP_P (operands[0]))
3452 [(set_attr "type" "fxch")
3453 (set_attr "mode" "DF")])
3455 (define_expand "movxf"
3456 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3457 (match_operand:XF 1 "general_operand" ""))]
3459 "ix86_expand_move (XFmode, operands); DONE;")
3461 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3462 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3463 ;; Pushing using integer instructions is longer except for constants
3464 ;; and direct memory references.
3465 ;; (assuming that any given constant is pushed only once, but this ought to be
3466 ;; handled elsewhere).
3468 (define_insn "*pushxf_nointeger"
3469 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3470 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3471 "optimize_function_for_size_p (cfun)"
3473 /* This insn should be already split before reg-stack. */
3476 [(set_attr "type" "multi")
3477 (set_attr "unit" "i387,*,*")
3478 (set_attr "mode" "XF,SI,SI")])
3480 (define_insn "*pushxf_integer"
3481 [(set (match_operand:XF 0 "push_operand" "=<,<")
3482 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3483 "optimize_function_for_speed_p (cfun)"
3485 /* This insn should be already split before reg-stack. */
3488 [(set_attr "type" "multi")
3489 (set_attr "unit" "i387,*")
3490 (set_attr "mode" "XF,SI")])
3493 [(set (match_operand 0 "push_operand" "")
3494 (match_operand 1 "general_operand" ""))]
3496 && (GET_MODE (operands[0]) == XFmode
3497 || GET_MODE (operands[0]) == DFmode)
3498 && !ANY_FP_REG_P (operands[1])"
3500 "ix86_split_long_move (operands); DONE;")
3503 [(set (match_operand:XF 0 "push_operand" "")
3504 (match_operand:XF 1 "any_fp_register_operand" ""))]
3506 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3507 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3508 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3510 ;; Do not use integer registers when optimizing for size
3511 (define_insn "*movxf_nointeger"
3512 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3513 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3514 "optimize_function_for_size_p (cfun)
3515 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3516 && (reload_in_progress || reload_completed
3517 || standard_80387_constant_p (operands[1])
3518 || GET_CODE (operands[1]) != CONST_DOUBLE
3519 || memory_operand (operands[0], XFmode))"
3521 switch (which_alternative)
3525 return output_387_reg_move (insn, operands);
3528 return standard_80387_constant_opcode (operands[1]);
3536 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3537 (set_attr "mode" "XF,XF,XF,SI,SI")])
3539 (define_insn "*movxf_integer"
3540 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3541 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3542 "optimize_function_for_speed_p (cfun)
3543 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3544 && (reload_in_progress || reload_completed
3545 || GET_CODE (operands[1]) != CONST_DOUBLE
3546 || memory_operand (operands[0], XFmode))"
3548 switch (which_alternative)
3552 return output_387_reg_move (insn, operands);
3555 return standard_80387_constant_opcode (operands[1]);
3564 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3565 (set_attr "mode" "XF,XF,XF,SI,SI")])
3567 (define_expand "movtf"
3568 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3569 (match_operand:TF 1 "nonimmediate_operand" ""))]
3572 ix86_expand_move (TFmode, operands);
3576 (define_insn "*movtf_internal"
3577 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3578 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3580 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3582 switch (which_alternative)
3586 if (get_attr_mode (insn) == MODE_V4SF)
3587 return "%vmovaps\t{%1, %0|%0, %1}";
3589 return "%vmovdqa\t{%1, %0|%0, %1}";
3591 if (get_attr_mode (insn) == MODE_V4SF)
3592 return "%vxorps\t%0, %d0";
3594 return "%vpxor\t%0, %d0";
3602 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3603 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3605 (cond [(eq_attr "alternative" "0,2")
3607 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3609 (const_string "V4SF")
3610 (const_string "TI"))
3611 (eq_attr "alternative" "1")
3613 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3615 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3617 (const_string "V4SF")
3618 (const_string "TI"))]
3619 (const_string "DI")))])
3621 (define_insn "*pushtf_sse"
3622 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3623 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3626 /* This insn should be already split before reg-stack. */
3629 [(set_attr "type" "multi")
3630 (set_attr "unit" "sse,*,*")
3631 (set_attr "mode" "TF,SI,SI")])
3634 [(set (match_operand:TF 0 "push_operand" "")
3635 (match_operand:TF 1 "general_operand" ""))]
3636 "TARGET_SSE2 && reload_completed
3637 && !SSE_REG_P (operands[1])"
3639 "ix86_split_long_move (operands); DONE;")
3642 [(set (match_operand:TF 0 "push_operand" "")
3643 (match_operand:TF 1 "any_fp_register_operand" ""))]
3645 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3646 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3650 [(set (match_operand 0 "nonimmediate_operand" "")
3651 (match_operand 1 "general_operand" ""))]
3653 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3654 && GET_MODE (operands[0]) == XFmode
3655 && ! (ANY_FP_REG_P (operands[0]) ||
3656 (GET_CODE (operands[0]) == SUBREG
3657 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3658 && ! (ANY_FP_REG_P (operands[1]) ||
3659 (GET_CODE (operands[1]) == SUBREG
3660 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3662 "ix86_split_long_move (operands); DONE;")
3665 [(set (match_operand 0 "register_operand" "")
3666 (match_operand 1 "memory_operand" ""))]
3668 && MEM_P (operands[1])
3669 && (GET_MODE (operands[0]) == TFmode
3670 || GET_MODE (operands[0]) == XFmode
3671 || GET_MODE (operands[0]) == SFmode
3672 || GET_MODE (operands[0]) == DFmode)
3673 && (operands[2] = find_constant_src (insn))"
3674 [(set (match_dup 0) (match_dup 2))]
3676 rtx c = operands[2];
3677 rtx r = operands[0];
3679 if (GET_CODE (r) == SUBREG)
3684 if (!standard_sse_constant_p (c))
3687 else if (FP_REG_P (r))
3689 if (!standard_80387_constant_p (c))
3692 else if (MMX_REG_P (r))
3697 [(set (match_operand 0 "register_operand" "")
3698 (float_extend (match_operand 1 "memory_operand" "")))]
3700 && MEM_P (operands[1])
3701 && (GET_MODE (operands[0]) == TFmode
3702 || GET_MODE (operands[0]) == XFmode
3703 || GET_MODE (operands[0]) == SFmode
3704 || GET_MODE (operands[0]) == DFmode)
3705 && (operands[2] = find_constant_src (insn))"
3706 [(set (match_dup 0) (match_dup 2))]
3708 rtx c = operands[2];
3709 rtx r = operands[0];
3711 if (GET_CODE (r) == SUBREG)
3716 if (!standard_sse_constant_p (c))
3719 else if (FP_REG_P (r))
3721 if (!standard_80387_constant_p (c))
3724 else if (MMX_REG_P (r))
3728 (define_insn "swapxf"
3729 [(set (match_operand:XF 0 "register_operand" "+f")
3730 (match_operand:XF 1 "register_operand" "+f"))
3735 if (STACK_TOP_P (operands[0]))
3740 [(set_attr "type" "fxch")
3741 (set_attr "mode" "XF")])
3743 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3745 [(set (match_operand:X87MODEF 0 "register_operand" "")
3746 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3747 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3748 && (standard_80387_constant_p (operands[1]) == 8
3749 || standard_80387_constant_p (operands[1]) == 9)"
3750 [(set (match_dup 0)(match_dup 1))
3752 (neg:X87MODEF (match_dup 0)))]
3756 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3757 if (real_isnegzero (&r))
3758 operands[1] = CONST0_RTX (<MODE>mode);
3760 operands[1] = CONST1_RTX (<MODE>mode);
3764 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3765 (match_operand:TF 1 "general_operand" ""))]
3767 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3769 "ix86_split_long_move (operands); DONE;")
3771 ;; Zero extension instructions
3773 (define_expand "zero_extendhisi2"
3774 [(set (match_operand:SI 0 "register_operand" "")
3775 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3778 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3780 operands[1] = force_reg (HImode, operands[1]);
3781 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3786 (define_insn "zero_extendhisi2_and"
3787 [(set (match_operand:SI 0 "register_operand" "=r")
3788 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3789 (clobber (reg:CC FLAGS_REG))]
3790 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3792 [(set_attr "type" "alu1")
3793 (set_attr "mode" "SI")])
3796 [(set (match_operand:SI 0 "register_operand" "")
3797 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3798 (clobber (reg:CC FLAGS_REG))]
3799 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3800 && optimize_function_for_speed_p (cfun)"
3801 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3802 (clobber (reg:CC FLAGS_REG))])]
3805 (define_insn "*zero_extendhisi2_movzwl"
3806 [(set (match_operand:SI 0 "register_operand" "=r")
3807 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3808 "!TARGET_ZERO_EXTEND_WITH_AND
3809 || optimize_function_for_size_p (cfun)"
3810 "movz{wl|x}\t{%1, %0|%0, %1}"
3811 [(set_attr "type" "imovx")
3812 (set_attr "mode" "SI")])
3814 (define_expand "zero_extendqihi2"
3816 [(set (match_operand:HI 0 "register_operand" "")
3817 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3818 (clobber (reg:CC FLAGS_REG))])]
3822 (define_insn "*zero_extendqihi2_and"
3823 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3824 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3825 (clobber (reg:CC FLAGS_REG))]
3826 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3828 [(set_attr "type" "alu1")
3829 (set_attr "mode" "HI")])
3831 (define_insn "*zero_extendqihi2_movzbw_and"
3832 [(set (match_operand:HI 0 "register_operand" "=r,r")
3833 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3834 (clobber (reg:CC FLAGS_REG))]
3835 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3837 [(set_attr "type" "imovx,alu1")
3838 (set_attr "mode" "HI")])
3840 ; zero extend to SImode here to avoid partial register stalls
3841 (define_insn "*zero_extendqihi2_movzbl"
3842 [(set (match_operand:HI 0 "register_operand" "=r")
3843 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3844 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3845 && reload_completed"
3846 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3847 [(set_attr "type" "imovx")
3848 (set_attr "mode" "SI")])
3850 ;; For the movzbw case strip only the clobber
3852 [(set (match_operand:HI 0 "register_operand" "")
3853 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3854 (clobber (reg:CC FLAGS_REG))]
3856 && (!TARGET_ZERO_EXTEND_WITH_AND
3857 || optimize_function_for_size_p (cfun))
3858 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3859 [(set (match_operand:HI 0 "register_operand" "")
3860 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3862 ;; When source and destination does not overlap, clear destination
3863 ;; first and then do the movb
3865 [(set (match_operand:HI 0 "register_operand" "")
3866 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3867 (clobber (reg:CC FLAGS_REG))]
3869 && ANY_QI_REG_P (operands[0])
3870 && (TARGET_ZERO_EXTEND_WITH_AND
3871 && optimize_function_for_speed_p (cfun))
3872 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3873 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3875 operands[2] = gen_lowpart (QImode, operands[0]);
3876 ix86_expand_clear (operands[0]);
3879 ;; Rest is handled by single and.
3881 [(set (match_operand:HI 0 "register_operand" "")
3882 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3883 (clobber (reg:CC FLAGS_REG))]
3885 && true_regnum (operands[0]) == true_regnum (operands[1])"
3886 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3887 (clobber (reg:CC FLAGS_REG))])]
3890 (define_expand "zero_extendqisi2"
3892 [(set (match_operand:SI 0 "register_operand" "")
3893 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3894 (clobber (reg:CC FLAGS_REG))])]
3898 (define_insn "*zero_extendqisi2_and"
3899 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3900 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3901 (clobber (reg:CC FLAGS_REG))]
3902 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3904 [(set_attr "type" "alu1")
3905 (set_attr "mode" "SI")])
3907 (define_insn "*zero_extendqisi2_movzbl_and"
3908 [(set (match_operand:SI 0 "register_operand" "=r,r")
3909 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3910 (clobber (reg:CC FLAGS_REG))]
3911 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3913 [(set_attr "type" "imovx,alu1")
3914 (set_attr "mode" "SI")])
3916 (define_insn "*zero_extendqisi2_movzbl"
3917 [(set (match_operand:SI 0 "register_operand" "=r")
3918 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3919 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3920 && reload_completed"
3921 "movz{bl|x}\t{%1, %0|%0, %1}"
3922 [(set_attr "type" "imovx")
3923 (set_attr "mode" "SI")])
3925 ;; For the movzbl case strip only the clobber
3927 [(set (match_operand:SI 0 "register_operand" "")
3928 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3929 (clobber (reg:CC FLAGS_REG))]
3931 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3932 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3934 (zero_extend:SI (match_dup 1)))])
3936 ;; When source and destination does not overlap, clear destination
3937 ;; first and then do the movb
3939 [(set (match_operand:SI 0 "register_operand" "")
3940 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3941 (clobber (reg:CC FLAGS_REG))]
3943 && ANY_QI_REG_P (operands[0])
3944 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3945 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3946 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3947 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3949 operands[2] = gen_lowpart (QImode, operands[0]);
3950 ix86_expand_clear (operands[0]);
3953 ;; Rest is handled by single and.
3955 [(set (match_operand:SI 0 "register_operand" "")
3956 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3957 (clobber (reg:CC FLAGS_REG))]
3959 && true_regnum (operands[0]) == true_regnum (operands[1])"
3960 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3961 (clobber (reg:CC FLAGS_REG))])]
3964 ;; %%% Kill me once multi-word ops are sane.
3965 (define_expand "zero_extendsidi2"
3966 [(set (match_operand:DI 0 "register_operand" "")
3967 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3972 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3977 (define_insn "zero_extendsidi2_32"
3978 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3980 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3981 (clobber (reg:CC FLAGS_REG))]
3987 movd\t{%1, %0|%0, %1}
3988 movd\t{%1, %0|%0, %1}
3989 %vmovd\t{%1, %0|%0, %1}
3990 %vmovd\t{%1, %0|%0, %1}"
3991 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
3992 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
3993 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
3995 (define_insn "zero_extendsidi2_rex64"
3996 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
3998 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4001 mov\t{%k1, %k0|%k0, %k1}
4003 movd\t{%1, %0|%0, %1}
4004 movd\t{%1, %0|%0, %1}
4005 %vmovd\t{%1, %0|%0, %1}
4006 %vmovd\t{%1, %0|%0, %1}"
4007 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4008 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4009 (set_attr "prefix_0f" "0,*,*,*,*,*")
4010 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4013 [(set (match_operand:DI 0 "memory_operand" "")
4014 (zero_extend:DI (match_dup 0)))]
4016 [(set (match_dup 4) (const_int 0))]
4017 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4020 [(set (match_operand:DI 0 "register_operand" "")
4021 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4022 (clobber (reg:CC FLAGS_REG))]
4023 "!TARGET_64BIT && reload_completed
4024 && true_regnum (operands[0]) == true_regnum (operands[1])"
4025 [(set (match_dup 4) (const_int 0))]
4026 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4029 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4030 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4031 (clobber (reg:CC FLAGS_REG))]
4032 "!TARGET_64BIT && reload_completed
4033 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4034 [(set (match_dup 3) (match_dup 1))
4035 (set (match_dup 4) (const_int 0))]
4036 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4038 (define_insn "zero_extendhidi2"
4039 [(set (match_operand:DI 0 "register_operand" "=r")
4040 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4042 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4043 [(set_attr "type" "imovx")
4044 (set_attr "mode" "SI")])
4046 (define_insn "zero_extendqidi2"
4047 [(set (match_operand:DI 0 "register_operand" "=r")
4048 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4050 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4051 [(set_attr "type" "imovx")
4052 (set_attr "mode" "SI")])
4054 ;; Sign extension instructions
4056 (define_expand "extendsidi2"
4057 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4058 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4059 (clobber (reg:CC FLAGS_REG))
4060 (clobber (match_scratch:SI 2 ""))])]
4065 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4070 (define_insn "*extendsidi2_1"
4071 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4072 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4073 (clobber (reg:CC FLAGS_REG))
4074 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4078 (define_insn "extendsidi2_rex64"
4079 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4080 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4084 movs{lq|x}\t{%1, %0|%0, %1}"
4085 [(set_attr "type" "imovx")
4086 (set_attr "mode" "DI")
4087 (set_attr "prefix_0f" "0")
4088 (set_attr "modrm" "0,1")])
4090 (define_insn "extendhidi2"
4091 [(set (match_operand:DI 0 "register_operand" "=r")
4092 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4094 "movs{wq|x}\t{%1, %0|%0, %1}"
4095 [(set_attr "type" "imovx")
4096 (set_attr "mode" "DI")])
4098 (define_insn "extendqidi2"
4099 [(set (match_operand:DI 0 "register_operand" "=r")
4100 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4102 "movs{bq|x}\t{%1, %0|%0, %1}"
4103 [(set_attr "type" "imovx")
4104 (set_attr "mode" "DI")])
4106 ;; Extend to memory case when source register does die.
4108 [(set (match_operand:DI 0 "memory_operand" "")
4109 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4110 (clobber (reg:CC FLAGS_REG))
4111 (clobber (match_operand:SI 2 "register_operand" ""))]
4113 && dead_or_set_p (insn, operands[1])
4114 && !reg_mentioned_p (operands[1], operands[0]))"
4115 [(set (match_dup 3) (match_dup 1))
4116 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4117 (clobber (reg:CC FLAGS_REG))])
4118 (set (match_dup 4) (match_dup 1))]
4119 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4121 ;; Extend to memory case when source register does not die.
4123 [(set (match_operand:DI 0 "memory_operand" "")
4124 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4125 (clobber (reg:CC FLAGS_REG))
4126 (clobber (match_operand:SI 2 "register_operand" ""))]
4130 split_di (&operands[0], 1, &operands[3], &operands[4]);
4132 emit_move_insn (operands[3], operands[1]);
4134 /* Generate a cltd if possible and doing so it profitable. */
4135 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4136 && true_regnum (operands[1]) == AX_REG
4137 && true_regnum (operands[2]) == DX_REG)
4139 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4143 emit_move_insn (operands[2], operands[1]);
4144 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4146 emit_move_insn (operands[4], operands[2]);
4150 ;; Extend to register case. Optimize case where source and destination
4151 ;; registers match and cases where we can use cltd.
4153 [(set (match_operand:DI 0 "register_operand" "")
4154 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4155 (clobber (reg:CC FLAGS_REG))
4156 (clobber (match_scratch:SI 2 ""))]
4160 split_di (&operands[0], 1, &operands[3], &operands[4]);
4162 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4163 emit_move_insn (operands[3], operands[1]);
4165 /* Generate a cltd if possible and doing so it profitable. */
4166 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4167 && true_regnum (operands[3]) == AX_REG)
4169 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4173 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4174 emit_move_insn (operands[4], operands[1]);
4176 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4180 (define_insn "extendhisi2"
4181 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4182 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4185 switch (get_attr_prefix_0f (insn))
4188 return "{cwtl|cwde}";
4190 return "movs{wl|x}\t{%1, %0|%0, %1}";
4193 [(set_attr "type" "imovx")
4194 (set_attr "mode" "SI")
4195 (set (attr "prefix_0f")
4196 ;; movsx is short decodable while cwtl is vector decoded.
4197 (if_then_else (and (eq_attr "cpu" "!k6")
4198 (eq_attr "alternative" "0"))
4200 (const_string "1")))
4202 (if_then_else (eq_attr "prefix_0f" "0")
4204 (const_string "1")))])
4206 (define_insn "*extendhisi2_zext"
4207 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4209 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4212 switch (get_attr_prefix_0f (insn))
4215 return "{cwtl|cwde}";
4217 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4220 [(set_attr "type" "imovx")
4221 (set_attr "mode" "SI")
4222 (set (attr "prefix_0f")
4223 ;; movsx is short decodable while cwtl is vector decoded.
4224 (if_then_else (and (eq_attr "cpu" "!k6")
4225 (eq_attr "alternative" "0"))
4227 (const_string "1")))
4229 (if_then_else (eq_attr "prefix_0f" "0")
4231 (const_string "1")))])
4233 (define_insn "extendqihi2"
4234 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4235 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4238 switch (get_attr_prefix_0f (insn))
4241 return "{cbtw|cbw}";
4243 return "movs{bw|x}\t{%1, %0|%0, %1}";
4246 [(set_attr "type" "imovx")
4247 (set_attr "mode" "HI")
4248 (set (attr "prefix_0f")
4249 ;; movsx is short decodable while cwtl is vector decoded.
4250 (if_then_else (and (eq_attr "cpu" "!k6")
4251 (eq_attr "alternative" "0"))
4253 (const_string "1")))
4255 (if_then_else (eq_attr "prefix_0f" "0")
4257 (const_string "1")))])
4259 (define_insn "extendqisi2"
4260 [(set (match_operand:SI 0 "register_operand" "=r")
4261 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4263 "movs{bl|x}\t{%1, %0|%0, %1}"
4264 [(set_attr "type" "imovx")
4265 (set_attr "mode" "SI")])
4267 (define_insn "*extendqisi2_zext"
4268 [(set (match_operand:DI 0 "register_operand" "=r")
4270 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4272 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4273 [(set_attr "type" "imovx")
4274 (set_attr "mode" "SI")])
4276 ;; Conversions between float and double.
4278 ;; These are all no-ops in the model used for the 80387. So just
4281 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4282 (define_insn "*dummy_extendsfdf2"
4283 [(set (match_operand:DF 0 "push_operand" "=<")
4284 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4289 [(set (match_operand:DF 0 "push_operand" "")
4290 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4292 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4293 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4295 (define_insn "*dummy_extendsfxf2"
4296 [(set (match_operand:XF 0 "push_operand" "=<")
4297 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4302 [(set (match_operand:XF 0 "push_operand" "")
4303 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4305 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4306 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4307 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4310 [(set (match_operand:XF 0 "push_operand" "")
4311 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4313 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4314 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4315 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4317 (define_expand "extendsfdf2"
4318 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4319 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4320 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4322 /* ??? Needed for compress_float_constant since all fp constants
4323 are LEGITIMATE_CONSTANT_P. */
4324 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4326 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4327 && standard_80387_constant_p (operands[1]) > 0)
4329 operands[1] = simplify_const_unary_operation
4330 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4331 emit_move_insn_1 (operands[0], operands[1]);
4334 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4338 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4340 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4342 We do the conversion post reload to avoid producing of 128bit spills
4343 that might lead to ICE on 32bit target. The sequence unlikely combine
4346 [(set (match_operand:DF 0 "register_operand" "")
4348 (match_operand:SF 1 "nonimmediate_operand" "")))]
4349 "TARGET_USE_VECTOR_FP_CONVERTS
4350 && optimize_insn_for_speed_p ()
4351 && reload_completed && SSE_REG_P (operands[0])"
4356 (parallel [(const_int 0) (const_int 1)]))))]
4358 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4359 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4360 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4361 Try to avoid move when unpacking can be done in source. */
4362 if (REG_P (operands[1]))
4364 /* If it is unsafe to overwrite upper half of source, we need
4365 to move to destination and unpack there. */
4366 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4367 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4368 && true_regnum (operands[0]) != true_regnum (operands[1]))
4370 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4371 emit_move_insn (tmp, operands[1]);
4374 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4375 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4378 emit_insn (gen_vec_setv4sf_0 (operands[3],
4379 CONST0_RTX (V4SFmode), operands[1]));
4382 (define_insn "*extendsfdf2_mixed"
4383 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4385 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4386 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4388 switch (which_alternative)
4392 return output_387_reg_move (insn, operands);
4395 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4401 [(set_attr "type" "fmov,fmov,ssecvt")
4402 (set_attr "prefix" "orig,orig,maybe_vex")
4403 (set_attr "mode" "SF,XF,DF")])
4405 (define_insn "*extendsfdf2_sse"
4406 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4407 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4408 "TARGET_SSE2 && TARGET_SSE_MATH"
4409 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4410 [(set_attr "type" "ssecvt")
4411 (set_attr "prefix" "maybe_vex")
4412 (set_attr "mode" "DF")])
4414 (define_insn "*extendsfdf2_i387"
4415 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4416 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4418 "* return output_387_reg_move (insn, operands);"
4419 [(set_attr "type" "fmov")
4420 (set_attr "mode" "SF,XF")])
4422 (define_expand "extend<mode>xf2"
4423 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4424 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4427 /* ??? Needed for compress_float_constant since all fp constants
4428 are LEGITIMATE_CONSTANT_P. */
4429 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4431 if (standard_80387_constant_p (operands[1]) > 0)
4433 operands[1] = simplify_const_unary_operation
4434 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4435 emit_move_insn_1 (operands[0], operands[1]);
4438 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4442 (define_insn "*extend<mode>xf2_i387"
4443 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4445 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4447 "* return output_387_reg_move (insn, operands);"
4448 [(set_attr "type" "fmov")
4449 (set_attr "mode" "<MODE>,XF")])
4451 ;; %%% This seems bad bad news.
4452 ;; This cannot output into an f-reg because there is no way to be sure
4453 ;; of truncating in that case. Otherwise this is just like a simple move
4454 ;; insn. So we pretend we can output to a reg in order to get better
4455 ;; register preferencing, but we really use a stack slot.
4457 ;; Conversion from DFmode to SFmode.
4459 (define_expand "truncdfsf2"
4460 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4462 (match_operand:DF 1 "nonimmediate_operand" "")))]
4463 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4465 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4467 else if (flag_unsafe_math_optimizations)
4471 enum ix86_stack_slot slot = (virtuals_instantiated
4474 rtx temp = assign_386_stack_local (SFmode, slot);
4475 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4480 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4482 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4484 We do the conversion post reload to avoid producing of 128bit spills
4485 that might lead to ICE on 32bit target. The sequence unlikely combine
4488 [(set (match_operand:SF 0 "register_operand" "")
4490 (match_operand:DF 1 "nonimmediate_operand" "")))]
4491 "TARGET_USE_VECTOR_FP_CONVERTS
4492 && optimize_insn_for_speed_p ()
4493 && reload_completed && SSE_REG_P (operands[0])"
4496 (float_truncate:V2SF
4500 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4501 operands[3] = CONST0_RTX (V2SFmode);
4502 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4503 /* Use movsd for loading from memory, unpcklpd for registers.
4504 Try to avoid move when unpacking can be done in source, or SSE3
4505 movddup is available. */
4506 if (REG_P (operands[1]))
4509 && true_regnum (operands[0]) != true_regnum (operands[1])
4510 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4511 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4513 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4514 emit_move_insn (tmp, operands[1]);
4517 else if (!TARGET_SSE3)
4518 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4519 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4522 emit_insn (gen_sse2_loadlpd (operands[4],
4523 CONST0_RTX (V2DFmode), operands[1]));
4526 (define_expand "truncdfsf2_with_temp"
4527 [(parallel [(set (match_operand:SF 0 "" "")
4528 (float_truncate:SF (match_operand:DF 1 "" "")))
4529 (clobber (match_operand:SF 2 "" ""))])]
4532 (define_insn "*truncdfsf_fast_mixed"
4533 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4535 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4536 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4538 switch (which_alternative)
4541 return output_387_reg_move (insn, operands);
4543 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4548 [(set_attr "type" "fmov,ssecvt")
4549 (set_attr "prefix" "orig,maybe_vex")
4550 (set_attr "mode" "SF")])
4552 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4553 ;; because nothing we do here is unsafe.
4554 (define_insn "*truncdfsf_fast_sse"
4555 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4557 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4558 "TARGET_SSE2 && TARGET_SSE_MATH"
4559 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4560 [(set_attr "type" "ssecvt")
4561 (set_attr "prefix" "maybe_vex")
4562 (set_attr "mode" "SF")])
4564 (define_insn "*truncdfsf_fast_i387"
4565 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4567 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4568 "TARGET_80387 && flag_unsafe_math_optimizations"
4569 "* return output_387_reg_move (insn, operands);"
4570 [(set_attr "type" "fmov")
4571 (set_attr "mode" "SF")])
4573 (define_insn "*truncdfsf_mixed"
4574 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4576 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4577 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4578 "TARGET_MIX_SSE_I387"
4580 switch (which_alternative)
4583 return output_387_reg_move (insn, operands);
4585 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4591 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4592 (set_attr "unit" "*,*,i387,i387,i387")
4593 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4594 (set_attr "mode" "SF")])
4596 (define_insn "*truncdfsf_i387"
4597 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4599 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4600 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4603 switch (which_alternative)
4606 return output_387_reg_move (insn, operands);
4612 [(set_attr "type" "fmov,multi,multi,multi")
4613 (set_attr "unit" "*,i387,i387,i387")
4614 (set_attr "mode" "SF")])
4616 (define_insn "*truncdfsf2_i387_1"
4617 [(set (match_operand:SF 0 "memory_operand" "=m")
4619 (match_operand:DF 1 "register_operand" "f")))]
4621 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4622 && !TARGET_MIX_SSE_I387"
4623 "* return output_387_reg_move (insn, operands);"
4624 [(set_attr "type" "fmov")
4625 (set_attr "mode" "SF")])
4628 [(set (match_operand:SF 0 "register_operand" "")
4630 (match_operand:DF 1 "fp_register_operand" "")))
4631 (clobber (match_operand 2 "" ""))]
4633 [(set (match_dup 2) (match_dup 1))
4634 (set (match_dup 0) (match_dup 2))]
4636 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4639 ;; Conversion from XFmode to {SF,DF}mode
4641 (define_expand "truncxf<mode>2"
4642 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4643 (float_truncate:MODEF
4644 (match_operand:XF 1 "register_operand" "")))
4645 (clobber (match_dup 2))])]
4648 if (flag_unsafe_math_optimizations)
4650 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4651 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4652 if (reg != operands[0])
4653 emit_move_insn (operands[0], reg);
4658 enum ix86_stack_slot slot = (virtuals_instantiated
4661 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4665 (define_insn "*truncxfsf2_mixed"
4666 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4668 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4669 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4672 gcc_assert (!which_alternative);
4673 return output_387_reg_move (insn, operands);
4675 [(set_attr "type" "fmov,multi,multi,multi")
4676 (set_attr "unit" "*,i387,i387,i387")
4677 (set_attr "mode" "SF")])
4679 (define_insn "*truncxfdf2_mixed"
4680 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4682 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4683 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4686 gcc_assert (!which_alternative);
4687 return output_387_reg_move (insn, operands);
4689 [(set_attr "type" "fmov,multi,multi,multi")
4690 (set_attr "unit" "*,i387,i387,i387")
4691 (set_attr "mode" "DF")])
4693 (define_insn "truncxf<mode>2_i387_noop"
4694 [(set (match_operand:MODEF 0 "register_operand" "=f")
4695 (float_truncate:MODEF
4696 (match_operand:XF 1 "register_operand" "f")))]
4697 "TARGET_80387 && flag_unsafe_math_optimizations"
4698 "* return output_387_reg_move (insn, operands);"
4699 [(set_attr "type" "fmov")
4700 (set_attr "mode" "<MODE>")])
4702 (define_insn "*truncxf<mode>2_i387"
4703 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4704 (float_truncate:MODEF
4705 (match_operand:XF 1 "register_operand" "f")))]
4707 "* return output_387_reg_move (insn, operands);"
4708 [(set_attr "type" "fmov")
4709 (set_attr "mode" "<MODE>")])
4712 [(set (match_operand:MODEF 0 "register_operand" "")
4713 (float_truncate:MODEF
4714 (match_operand:XF 1 "register_operand" "")))
4715 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4716 "TARGET_80387 && reload_completed"
4717 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4718 (set (match_dup 0) (match_dup 2))]
4722 [(set (match_operand:MODEF 0 "memory_operand" "")
4723 (float_truncate:MODEF
4724 (match_operand:XF 1 "register_operand" "")))
4725 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4727 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4730 ;; Signed conversion to DImode.
4732 (define_expand "fix_truncxfdi2"
4733 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4734 (fix:DI (match_operand:XF 1 "register_operand" "")))
4735 (clobber (reg:CC FLAGS_REG))])]
4740 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4745 (define_expand "fix_trunc<mode>di2"
4746 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4747 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4748 (clobber (reg:CC FLAGS_REG))])]
4749 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4752 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4754 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4757 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4759 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4760 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4761 if (out != operands[0])
4762 emit_move_insn (operands[0], out);
4767 ;; Signed conversion to SImode.
4769 (define_expand "fix_truncxfsi2"
4770 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4771 (fix:SI (match_operand:XF 1 "register_operand" "")))
4772 (clobber (reg:CC FLAGS_REG))])]
4777 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4782 (define_expand "fix_trunc<mode>si2"
4783 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4784 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4785 (clobber (reg:CC FLAGS_REG))])]
4786 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4789 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4791 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4794 if (SSE_FLOAT_MODE_P (<MODE>mode))
4796 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4797 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4798 if (out != operands[0])
4799 emit_move_insn (operands[0], out);
4804 ;; Signed conversion to HImode.
4806 (define_expand "fix_trunc<mode>hi2"
4807 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4808 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4809 (clobber (reg:CC FLAGS_REG))])]
4811 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4815 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4820 ;; Unsigned conversion to SImode.
4822 (define_expand "fixuns_trunc<mode>si2"
4824 [(set (match_operand:SI 0 "register_operand" "")
4826 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4828 (clobber (match_scratch:<ssevecmode> 3 ""))
4829 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4830 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4832 enum machine_mode mode = <MODE>mode;
4833 enum machine_mode vecmode = <ssevecmode>mode;
4834 REAL_VALUE_TYPE TWO31r;
4837 if (optimize_insn_for_size_p ())
4840 real_ldexp (&TWO31r, &dconst1, 31);
4841 two31 = const_double_from_real_value (TWO31r, mode);
4842 two31 = ix86_build_const_vector (mode, true, two31);
4843 operands[2] = force_reg (vecmode, two31);
4846 (define_insn_and_split "*fixuns_trunc<mode>_1"
4847 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4849 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4850 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4851 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4852 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4853 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4854 && optimize_function_for_speed_p (cfun)"
4856 "&& reload_completed"
4859 ix86_split_convert_uns_si_sse (operands);
4863 ;; Unsigned conversion to HImode.
4864 ;; Without these patterns, we'll try the unsigned SI conversion which
4865 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4867 (define_expand "fixuns_trunc<mode>hi2"
4869 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4870 (set (match_operand:HI 0 "nonimmediate_operand" "")
4871 (subreg:HI (match_dup 2) 0))]
4872 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4873 "operands[2] = gen_reg_rtx (SImode);")
4875 ;; When SSE is available, it is always faster to use it!
4876 (define_insn "fix_trunc<mode>di_sse"
4877 [(set (match_operand:DI 0 "register_operand" "=r,r")
4878 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4879 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4880 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4881 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4882 [(set_attr "type" "sseicvt")
4883 (set_attr "prefix" "maybe_vex")
4884 (set_attr "prefix_rex" "1")
4885 (set_attr "mode" "<MODE>")
4886 (set_attr "athlon_decode" "double,vector")
4887 (set_attr "amdfam10_decode" "double,double")])
4889 (define_insn "fix_trunc<mode>si_sse"
4890 [(set (match_operand:SI 0 "register_operand" "=r,r")
4891 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4892 "SSE_FLOAT_MODE_P (<MODE>mode)
4893 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4894 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4895 [(set_attr "type" "sseicvt")
4896 (set_attr "prefix" "maybe_vex")
4897 (set_attr "mode" "<MODE>")
4898 (set_attr "athlon_decode" "double,vector")
4899 (set_attr "amdfam10_decode" "double,double")])
4901 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4903 [(set (match_operand:MODEF 0 "register_operand" "")
4904 (match_operand:MODEF 1 "memory_operand" ""))
4905 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4906 (fix:SSEMODEI24 (match_dup 0)))]
4907 "TARGET_SHORTEN_X87_SSE
4908 && peep2_reg_dead_p (2, operands[0])"
4909 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4912 ;; Avoid vector decoded forms of the instruction.
4914 [(match_scratch:DF 2 "Y2")
4915 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4916 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4917 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4918 [(set (match_dup 2) (match_dup 1))
4919 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4923 [(match_scratch:SF 2 "x")
4924 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4925 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4926 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4927 [(set (match_dup 2) (match_dup 1))
4928 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4931 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4932 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4933 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4934 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4936 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4937 && (TARGET_64BIT || <MODE>mode != DImode))
4939 && can_create_pseudo_p ()"
4944 if (memory_operand (operands[0], VOIDmode))
4945 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4948 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4949 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4955 [(set_attr "type" "fisttp")
4956 (set_attr "mode" "<MODE>")])
4958 (define_insn "fix_trunc<mode>_i387_fisttp"
4959 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4960 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4961 (clobber (match_scratch:XF 2 "=&1f"))]
4962 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4964 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4965 && (TARGET_64BIT || <MODE>mode != DImode))
4966 && TARGET_SSE_MATH)"
4967 "* return output_fix_trunc (insn, operands, 1);"
4968 [(set_attr "type" "fisttp")
4969 (set_attr "mode" "<MODE>")])
4971 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4972 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4973 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4974 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4975 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4976 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4978 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4979 && (TARGET_64BIT || <MODE>mode != DImode))
4980 && TARGET_SSE_MATH)"
4982 [(set_attr "type" "fisttp")
4983 (set_attr "mode" "<MODE>")])
4986 [(set (match_operand:X87MODEI 0 "register_operand" "")
4987 (fix:X87MODEI (match_operand 1 "register_operand" "")))
4988 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
4989 (clobber (match_scratch 3 ""))]
4991 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
4992 (clobber (match_dup 3))])
4993 (set (match_dup 0) (match_dup 2))]
4997 [(set (match_operand:X87MODEI 0 "memory_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 0) (fix:X87MODEI (match_dup 1)))
5003 (clobber (match_dup 3))])]
5006 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5007 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5008 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5009 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5010 ;; function in i386.c.
5011 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5012 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5013 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5014 (clobber (reg:CC FLAGS_REG))]
5015 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5017 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5018 && (TARGET_64BIT || <MODE>mode != DImode))
5019 && can_create_pseudo_p ()"
5024 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5026 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5027 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5028 if (memory_operand (operands[0], VOIDmode))
5029 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5030 operands[2], operands[3]));
5033 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5034 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5035 operands[2], operands[3],
5040 [(set_attr "type" "fistp")
5041 (set_attr "i387_cw" "trunc")
5042 (set_attr "mode" "<MODE>")])
5044 (define_insn "fix_truncdi_i387"
5045 [(set (match_operand:DI 0 "memory_operand" "=m")
5046 (fix:DI (match_operand 1 "register_operand" "f")))
5047 (use (match_operand:HI 2 "memory_operand" "m"))
5048 (use (match_operand:HI 3 "memory_operand" "m"))
5049 (clobber (match_scratch:XF 4 "=&1f"))]
5050 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5052 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5053 "* return output_fix_trunc (insn, operands, 0);"
5054 [(set_attr "type" "fistp")
5055 (set_attr "i387_cw" "trunc")
5056 (set_attr "mode" "DI")])
5058 (define_insn "fix_truncdi_i387_with_temp"
5059 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5060 (fix:DI (match_operand 1 "register_operand" "f,f")))
5061 (use (match_operand:HI 2 "memory_operand" "m,m"))
5062 (use (match_operand:HI 3 "memory_operand" "m,m"))
5063 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5064 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5065 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5067 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5069 [(set_attr "type" "fistp")
5070 (set_attr "i387_cw" "trunc")
5071 (set_attr "mode" "DI")])
5074 [(set (match_operand:DI 0 "register_operand" "")
5075 (fix:DI (match_operand 1 "register_operand" "")))
5076 (use (match_operand:HI 2 "memory_operand" ""))
5077 (use (match_operand:HI 3 "memory_operand" ""))
5078 (clobber (match_operand:DI 4 "memory_operand" ""))
5079 (clobber (match_scratch 5 ""))]
5081 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5084 (clobber (match_dup 5))])
5085 (set (match_dup 0) (match_dup 4))]
5089 [(set (match_operand:DI 0 "memory_operand" "")
5090 (fix:DI (match_operand 1 "register_operand" "")))
5091 (use (match_operand:HI 2 "memory_operand" ""))
5092 (use (match_operand:HI 3 "memory_operand" ""))
5093 (clobber (match_operand:DI 4 "memory_operand" ""))
5094 (clobber (match_scratch 5 ""))]
5096 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5099 (clobber (match_dup 5))])]
5102 (define_insn "fix_trunc<mode>_i387"
5103 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5104 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5105 (use (match_operand:HI 2 "memory_operand" "m"))
5106 (use (match_operand:HI 3 "memory_operand" "m"))]
5107 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5109 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5110 "* return output_fix_trunc (insn, operands, 0);"
5111 [(set_attr "type" "fistp")
5112 (set_attr "i387_cw" "trunc")
5113 (set_attr "mode" "<MODE>")])
5115 (define_insn "fix_trunc<mode>_i387_with_temp"
5116 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5117 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5118 (use (match_operand:HI 2 "memory_operand" "m,m"))
5119 (use (match_operand:HI 3 "memory_operand" "m,m"))
5120 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5121 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5123 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5125 [(set_attr "type" "fistp")
5126 (set_attr "i387_cw" "trunc")
5127 (set_attr "mode" "<MODE>")])
5130 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5131 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5132 (use (match_operand:HI 2 "memory_operand" ""))
5133 (use (match_operand:HI 3 "memory_operand" ""))
5134 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5136 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5138 (use (match_dup 3))])
5139 (set (match_dup 0) (match_dup 4))]
5143 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5144 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5145 (use (match_operand:HI 2 "memory_operand" ""))
5146 (use (match_operand:HI 3 "memory_operand" ""))
5147 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5149 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5151 (use (match_dup 3))])]
5154 (define_insn "x86_fnstcw_1"
5155 [(set (match_operand:HI 0 "memory_operand" "=m")
5156 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5159 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5160 (set_attr "mode" "HI")
5161 (set_attr "unit" "i387")])
5163 (define_insn "x86_fldcw_1"
5164 [(set (reg:HI FPCR_REG)
5165 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5168 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5169 (set_attr "mode" "HI")
5170 (set_attr "unit" "i387")
5171 (set_attr "athlon_decode" "vector")
5172 (set_attr "amdfam10_decode" "vector")])
5174 ;; Conversion between fixed point and floating point.
5176 ;; Even though we only accept memory inputs, the backend _really_
5177 ;; wants to be able to do this between registers.
5179 (define_expand "floathi<mode>2"
5180 [(set (match_operand:X87MODEF 0 "register_operand" "")
5181 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5184 || TARGET_MIX_SSE_I387)"
5187 ;; Pre-reload splitter to add memory clobber to the pattern.
5188 (define_insn_and_split "*floathi<mode>2_1"
5189 [(set (match_operand:X87MODEF 0 "register_operand" "")
5190 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5192 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5193 || TARGET_MIX_SSE_I387)
5194 && can_create_pseudo_p ()"
5197 [(parallel [(set (match_dup 0)
5198 (float:X87MODEF (match_dup 1)))
5199 (clobber (match_dup 2))])]
5200 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5202 (define_insn "*floathi<mode>2_i387_with_temp"
5203 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5204 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5205 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5207 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5208 || TARGET_MIX_SSE_I387)"
5210 [(set_attr "type" "fmov,multi")
5211 (set_attr "mode" "<MODE>")
5212 (set_attr "unit" "*,i387")
5213 (set_attr "fp_int_src" "true")])
5215 (define_insn "*floathi<mode>2_i387"
5216 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5217 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5220 || TARGET_MIX_SSE_I387)"
5222 [(set_attr "type" "fmov")
5223 (set_attr "mode" "<MODE>")
5224 (set_attr "fp_int_src" "true")])
5227 [(set (match_operand:X87MODEF 0 "register_operand" "")
5228 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5229 (clobber (match_operand:HI 2 "memory_operand" ""))]
5231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5232 || TARGET_MIX_SSE_I387)
5233 && reload_completed"
5234 [(set (match_dup 2) (match_dup 1))
5235 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5239 [(set (match_operand:X87MODEF 0 "register_operand" "")
5240 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5241 (clobber (match_operand:HI 2 "memory_operand" ""))]
5243 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5244 || TARGET_MIX_SSE_I387)
5245 && reload_completed"
5246 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5249 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5250 [(set (match_operand:X87MODEF 0 "register_operand" "")
5252 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5254 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5255 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5258 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5259 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5260 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5262 rtx reg = gen_reg_rtx (XFmode);
5265 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5267 if (<X87MODEF:MODE>mode == SFmode)
5268 insn = gen_truncxfsf2 (operands[0], reg);
5269 else if (<X87MODEF:MODE>mode == DFmode)
5270 insn = gen_truncxfdf2 (operands[0], reg);
5279 ;; Pre-reload splitter to add memory clobber to the pattern.
5280 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5281 [(set (match_operand:X87MODEF 0 "register_operand" "")
5282 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5284 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5285 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5286 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5287 || TARGET_MIX_SSE_I387))
5288 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5289 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5290 && ((<SSEMODEI24:MODE>mode == SImode
5291 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5292 && optimize_function_for_speed_p (cfun)
5293 && flag_trapping_math)
5294 || !(TARGET_INTER_UNIT_CONVERSIONS
5295 || optimize_function_for_size_p (cfun)))))
5296 && can_create_pseudo_p ()"
5299 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5300 (clobber (match_dup 2))])]
5302 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5304 /* Avoid store forwarding (partial memory) stall penalty
5305 by passing DImode value through XMM registers. */
5306 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5307 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5308 && optimize_function_for_speed_p (cfun))
5310 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5317 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5318 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5320 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5321 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5322 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5323 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5325 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5326 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5327 (set_attr "unit" "*,i387,*,*,*")
5328 (set_attr "athlon_decode" "*,*,double,direct,double")
5329 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5330 (set_attr "fp_int_src" "true")])
5332 (define_insn "*floatsi<mode>2_vector_mixed"
5333 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5334 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5335 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5336 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5340 [(set_attr "type" "fmov,sseicvt")
5341 (set_attr "mode" "<MODE>,<ssevecmode>")
5342 (set_attr "unit" "i387,*")
5343 (set_attr "athlon_decode" "*,direct")
5344 (set_attr "amdfam10_decode" "*,double")
5345 (set_attr "fp_int_src" "true")])
5347 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5348 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5350 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5351 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5352 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5353 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5355 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5356 (set_attr "mode" "<MODEF:MODE>")
5357 (set_attr "unit" "*,i387,*,*")
5358 (set_attr "athlon_decode" "*,*,double,direct")
5359 (set_attr "amdfam10_decode" "*,*,vector,double")
5360 (set_attr "fp_int_src" "true")])
5363 [(set (match_operand:MODEF 0 "register_operand" "")
5364 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5365 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5366 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5367 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5368 && TARGET_INTER_UNIT_CONVERSIONS
5370 && (SSE_REG_P (operands[0])
5371 || (GET_CODE (operands[0]) == SUBREG
5372 && SSE_REG_P (operands[0])))"
5373 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5377 [(set (match_operand:MODEF 0 "register_operand" "")
5378 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5379 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5380 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5381 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5382 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5384 && (SSE_REG_P (operands[0])
5385 || (GET_CODE (operands[0]) == SUBREG
5386 && SSE_REG_P (operands[0])))"
5387 [(set (match_dup 2) (match_dup 1))
5388 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5391 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5392 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5394 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5395 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5396 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5397 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5400 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5401 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5402 [(set_attr "type" "fmov,sseicvt,sseicvt")
5403 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5404 (set_attr "mode" "<MODEF:MODE>")
5405 (set (attr "prefix_rex")
5407 (and (eq_attr "prefix" "maybe_vex")
5408 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5410 (const_string "*")))
5411 (set_attr "unit" "i387,*,*")
5412 (set_attr "athlon_decode" "*,double,direct")
5413 (set_attr "amdfam10_decode" "*,vector,double")
5414 (set_attr "fp_int_src" "true")])
5416 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5417 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5419 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5420 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5421 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5422 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5425 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5426 [(set_attr "type" "fmov,sseicvt")
5427 (set_attr "prefix" "orig,maybe_vex")
5428 (set_attr "mode" "<MODEF:MODE>")
5429 (set (attr "prefix_rex")
5431 (and (eq_attr "prefix" "maybe_vex")
5432 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5434 (const_string "*")))
5435 (set_attr "athlon_decode" "*,direct")
5436 (set_attr "amdfam10_decode" "*,double")
5437 (set_attr "fp_int_src" "true")])
5439 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5440 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5442 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5443 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5444 "TARGET_SSE2 && TARGET_SSE_MATH
5445 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5447 [(set_attr "type" "sseicvt")
5448 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5449 (set_attr "athlon_decode" "double,direct,double")
5450 (set_attr "amdfam10_decode" "vector,double,double")
5451 (set_attr "fp_int_src" "true")])
5453 (define_insn "*floatsi<mode>2_vector_sse"
5454 [(set (match_operand:MODEF 0 "register_operand" "=x")
5455 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5456 "TARGET_SSE2 && TARGET_SSE_MATH
5457 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5459 [(set_attr "type" "sseicvt")
5460 (set_attr "mode" "<MODE>")
5461 (set_attr "athlon_decode" "direct")
5462 (set_attr "amdfam10_decode" "double")
5463 (set_attr "fp_int_src" "true")])
5466 [(set (match_operand:MODEF 0 "register_operand" "")
5467 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5468 (clobber (match_operand:SI 2 "memory_operand" ""))]
5469 "TARGET_SSE2 && TARGET_SSE_MATH
5470 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5472 && (SSE_REG_P (operands[0])
5473 || (GET_CODE (operands[0]) == SUBREG
5474 && SSE_REG_P (operands[0])))"
5477 rtx op1 = operands[1];
5479 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5481 if (GET_CODE (op1) == SUBREG)
5482 op1 = SUBREG_REG (op1);
5484 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5486 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5487 emit_insn (gen_sse2_loadld (operands[4],
5488 CONST0_RTX (V4SImode), operands[1]));
5490 /* We can ignore possible trapping value in the
5491 high part of SSE register for non-trapping math. */
5492 else if (SSE_REG_P (op1) && !flag_trapping_math)
5493 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5496 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5497 emit_move_insn (operands[2], operands[1]);
5498 emit_insn (gen_sse2_loadld (operands[4],
5499 CONST0_RTX (V4SImode), operands[2]));
5502 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5507 [(set (match_operand:MODEF 0 "register_operand" "")
5508 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5509 (clobber (match_operand:SI 2 "memory_operand" ""))]
5510 "TARGET_SSE2 && TARGET_SSE_MATH
5511 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5513 && (SSE_REG_P (operands[0])
5514 || (GET_CODE (operands[0]) == SUBREG
5515 && SSE_REG_P (operands[0])))"
5518 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5520 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5522 emit_insn (gen_sse2_loadld (operands[4],
5523 CONST0_RTX (V4SImode), operands[1]));
5525 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5530 [(set (match_operand:MODEF 0 "register_operand" "")
5531 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5532 "TARGET_SSE2 && TARGET_SSE_MATH
5533 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5535 && (SSE_REG_P (operands[0])
5536 || (GET_CODE (operands[0]) == SUBREG
5537 && SSE_REG_P (operands[0])))"
5540 rtx op1 = operands[1];
5542 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5544 if (GET_CODE (op1) == SUBREG)
5545 op1 = SUBREG_REG (op1);
5547 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5549 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5550 emit_insn (gen_sse2_loadld (operands[4],
5551 CONST0_RTX (V4SImode), operands[1]));
5553 /* We can ignore possible trapping value in the
5554 high part of SSE register for non-trapping math. */
5555 else if (SSE_REG_P (op1) && !flag_trapping_math)
5556 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5560 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5565 [(set (match_operand:MODEF 0 "register_operand" "")
5566 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5567 "TARGET_SSE2 && TARGET_SSE_MATH
5568 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5570 && (SSE_REG_P (operands[0])
5571 || (GET_CODE (operands[0]) == SUBREG
5572 && SSE_REG_P (operands[0])))"
5575 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5577 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5579 emit_insn (gen_sse2_loadld (operands[4],
5580 CONST0_RTX (V4SImode), operands[1]));
5582 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5586 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5587 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5589 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5590 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5591 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5592 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5594 [(set_attr "type" "sseicvt")
5595 (set_attr "mode" "<MODEF:MODE>")
5596 (set_attr "athlon_decode" "double,direct")
5597 (set_attr "amdfam10_decode" "vector,double")
5598 (set_attr "fp_int_src" "true")])
5600 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5601 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5603 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5604 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5605 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5606 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5607 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5608 [(set_attr "type" "sseicvt")
5609 (set_attr "prefix" "maybe_vex")
5610 (set_attr "mode" "<MODEF:MODE>")
5611 (set (attr "prefix_rex")
5613 (and (eq_attr "prefix" "maybe_vex")
5614 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5616 (const_string "*")))
5617 (set_attr "athlon_decode" "double,direct")
5618 (set_attr "amdfam10_decode" "vector,double")
5619 (set_attr "fp_int_src" "true")])
5622 [(set (match_operand:MODEF 0 "register_operand" "")
5623 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5624 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5625 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5626 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5627 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5629 && (SSE_REG_P (operands[0])
5630 || (GET_CODE (operands[0]) == SUBREG
5631 && SSE_REG_P (operands[0])))"
5632 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5635 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5636 [(set (match_operand:MODEF 0 "register_operand" "=x")
5638 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5639 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5640 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5641 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5642 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5643 [(set_attr "type" "sseicvt")
5644 (set_attr "prefix" "maybe_vex")
5645 (set_attr "mode" "<MODEF:MODE>")
5646 (set (attr "prefix_rex")
5648 (and (eq_attr "prefix" "maybe_vex")
5649 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5651 (const_string "*")))
5652 (set_attr "athlon_decode" "direct")
5653 (set_attr "amdfam10_decode" "double")
5654 (set_attr "fp_int_src" "true")])
5657 [(set (match_operand:MODEF 0 "register_operand" "")
5658 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5659 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5660 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5661 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5662 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5664 && (SSE_REG_P (operands[0])
5665 || (GET_CODE (operands[0]) == SUBREG
5666 && SSE_REG_P (operands[0])))"
5667 [(set (match_dup 2) (match_dup 1))
5668 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5672 [(set (match_operand:MODEF 0 "register_operand" "")
5673 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5674 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5675 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5676 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5678 && (SSE_REG_P (operands[0])
5679 || (GET_CODE (operands[0]) == SUBREG
5680 && SSE_REG_P (operands[0])))"
5681 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5684 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5685 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5687 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5688 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5690 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5694 [(set_attr "type" "fmov,multi")
5695 (set_attr "mode" "<X87MODEF:MODE>")
5696 (set_attr "unit" "*,i387")
5697 (set_attr "fp_int_src" "true")])
5699 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5700 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5702 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5704 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5706 [(set_attr "type" "fmov")
5707 (set_attr "mode" "<X87MODEF:MODE>")
5708 (set_attr "fp_int_src" "true")])
5711 [(set (match_operand:X87MODEF 0 "register_operand" "")
5712 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5713 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5715 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5717 && FP_REG_P (operands[0])"
5718 [(set (match_dup 2) (match_dup 1))
5719 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5723 [(set (match_operand:X87MODEF 0 "register_operand" "")
5724 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5725 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5727 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5729 && FP_REG_P (operands[0])"
5730 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5733 ;; Avoid store forwarding (partial memory) stall penalty
5734 ;; by passing DImode value through XMM registers. */
5736 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5737 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5739 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5740 (clobber (match_scratch:V4SI 3 "=X,x"))
5741 (clobber (match_scratch:V4SI 4 "=X,x"))
5742 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5743 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5744 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5745 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5747 [(set_attr "type" "multi")
5748 (set_attr "mode" "<X87MODEF:MODE>")
5749 (set_attr "unit" "i387")
5750 (set_attr "fp_int_src" "true")])
5753 [(set (match_operand:X87MODEF 0 "register_operand" "")
5754 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5755 (clobber (match_scratch:V4SI 3 ""))
5756 (clobber (match_scratch:V4SI 4 ""))
5757 (clobber (match_operand:DI 2 "memory_operand" ""))]
5758 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5759 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5760 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5762 && FP_REG_P (operands[0])"
5763 [(set (match_dup 2) (match_dup 3))
5764 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5766 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5767 Assemble the 64-bit DImode value in an xmm register. */
5768 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5769 gen_rtx_SUBREG (SImode, operands[1], 0)));
5770 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5771 gen_rtx_SUBREG (SImode, operands[1], 4)));
5772 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5774 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5778 [(set (match_operand:X87MODEF 0 "register_operand" "")
5779 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5780 (clobber (match_scratch:V4SI 3 ""))
5781 (clobber (match_scratch:V4SI 4 ""))
5782 (clobber (match_operand:DI 2 "memory_operand" ""))]
5783 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5784 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5785 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5787 && FP_REG_P (operands[0])"
5788 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5791 ;; Avoid store forwarding (partial memory) stall penalty by extending
5792 ;; SImode value to DImode through XMM register instead of pushing two
5793 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5794 ;; targets benefit from this optimization. Also note that fild
5795 ;; loads from memory only.
5797 (define_insn "*floatunssi<mode>2_1"
5798 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5799 (unsigned_float:X87MODEF
5800 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5801 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5802 (clobber (match_scratch:SI 3 "=X,x"))]
5804 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5807 [(set_attr "type" "multi")
5808 (set_attr "mode" "<MODE>")])
5811 [(set (match_operand:X87MODEF 0 "register_operand" "")
5812 (unsigned_float:X87MODEF
5813 (match_operand:SI 1 "register_operand" "")))
5814 (clobber (match_operand:DI 2 "memory_operand" ""))
5815 (clobber (match_scratch:SI 3 ""))]
5817 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5819 && reload_completed"
5820 [(set (match_dup 2) (match_dup 1))
5822 (float:X87MODEF (match_dup 2)))]
5823 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5826 [(set (match_operand:X87MODEF 0 "register_operand" "")
5827 (unsigned_float:X87MODEF
5828 (match_operand:SI 1 "memory_operand" "")))
5829 (clobber (match_operand:DI 2 "memory_operand" ""))
5830 (clobber (match_scratch:SI 3 ""))]
5832 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5834 && reload_completed"
5835 [(set (match_dup 2) (match_dup 3))
5837 (float:X87MODEF (match_dup 2)))]
5839 emit_move_insn (operands[3], operands[1]);
5840 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5843 (define_expand "floatunssi<mode>2"
5845 [(set (match_operand:X87MODEF 0 "register_operand" "")
5846 (unsigned_float:X87MODEF
5847 (match_operand:SI 1 "nonimmediate_operand" "")))
5848 (clobber (match_dup 2))
5849 (clobber (match_scratch:SI 3 ""))])]
5851 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5853 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5855 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5857 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5862 enum ix86_stack_slot slot = (virtuals_instantiated
5865 operands[2] = assign_386_stack_local (DImode, slot);
5869 (define_expand "floatunsdisf2"
5870 [(use (match_operand:SF 0 "register_operand" ""))
5871 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5872 "TARGET_64BIT && TARGET_SSE_MATH"
5873 "x86_emit_floatuns (operands); DONE;")
5875 (define_expand "floatunsdidf2"
5876 [(use (match_operand:DF 0 "register_operand" ""))
5877 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5878 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5879 && TARGET_SSE2 && TARGET_SSE_MATH"
5882 x86_emit_floatuns (operands);
5884 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5890 (define_expand "add<mode>3"
5891 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5892 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5893 (match_operand:SDWIM 2 "<general_operand>" "")))]
5895 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5897 (define_insn_and_split "*add<dwi>3_doubleword"
5898 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5900 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5901 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5902 (clobber (reg:CC FLAGS_REG))]
5903 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5906 [(parallel [(set (reg:CC FLAGS_REG)
5907 (unspec:CC [(match_dup 1) (match_dup 2)]
5910 (plus:DWIH (match_dup 1) (match_dup 2)))])
5911 (parallel [(set (match_dup 3)
5915 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5917 (clobber (reg:CC FLAGS_REG))])]
5918 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5920 (define_insn "*add<mode>3_cc"
5921 [(set (reg:CC FLAGS_REG)
5923 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5924 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5926 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5927 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5928 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5929 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5930 [(set_attr "type" "alu")
5931 (set_attr "mode" "<MODE>")])
5933 (define_insn "addqi3_cc"
5934 [(set (reg:CC FLAGS_REG)
5936 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5937 (match_operand:QI 2 "general_operand" "qn,qm")]
5939 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5940 (plus:QI (match_dup 1) (match_dup 2)))]
5941 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5942 "add{b}\t{%2, %0|%0, %2}"
5943 [(set_attr "type" "alu")
5944 (set_attr "mode" "QI")])
5946 (define_insn "*lea_1"
5947 [(set (match_operand:DWIH 0 "register_operand" "=r")
5948 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5950 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5951 [(set_attr "type" "lea")
5952 (set_attr "mode" "<MODE>")])
5954 (define_insn "*lea_2"
5955 [(set (match_operand:SI 0 "register_operand" "=r")
5956 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5958 "lea{l}\t{%a1, %0|%0, %a1}"
5959 [(set_attr "type" "lea")
5960 (set_attr "mode" "SI")])
5962 (define_insn "*lea_2_zext"
5963 [(set (match_operand:DI 0 "register_operand" "=r")
5965 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5967 "lea{l}\t{%a1, %k0|%k0, %a1}"
5968 [(set_attr "type" "lea")
5969 (set_attr "mode" "SI")])
5971 (define_insn "*add<mode>_1"
5972 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5974 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5975 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5976 (clobber (reg:CC FLAGS_REG))]
5977 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5979 switch (get_attr_type (insn))
5982 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5983 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5986 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5987 if (operands[2] == const1_rtx)
5988 return "inc{<imodesuffix>}\t%0";
5991 gcc_assert (operands[2] == constm1_rtx);
5992 return "dec{<imodesuffix>}\t%0";
5996 /* Use add as much as possible to replace lea for AGU optimization. */
5997 if (which_alternative == 2 && TARGET_OPT_AGU)
5998 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6000 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6002 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6003 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6004 if (CONST_INT_P (operands[2])
6005 /* Avoid overflows. */
6006 && (<MODE>mode != DImode
6007 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6008 && (INTVAL (operands[2]) == 128
6009 || (INTVAL (operands[2]) < 0
6010 && INTVAL (operands[2]) != -128)))
6012 operands[2] = GEN_INT (-INTVAL (operands[2]));
6013 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6015 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6019 (cond [(and (eq_attr "alternative" "2")
6020 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6021 (const_string "lea")
6022 (eq_attr "alternative" "3")
6023 (const_string "lea")
6024 ; Current assemblers are broken and do not allow @GOTOFF in
6025 ; ought but a memory context.
6026 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6027 (const_string "lea")
6028 (match_operand:SWI48 2 "incdec_operand" "")
6029 (const_string "incdec")
6031 (const_string "alu")))
6032 (set (attr "length_immediate")
6034 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6036 (const_string "*")))
6037 (set_attr "mode" "<MODE>")])
6039 ;; It may seem that nonimmediate operand is proper one for operand 1.
6040 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6041 ;; we take care in ix86_binary_operator_ok to not allow two memory
6042 ;; operands so proper swapping will be done in reload. This allow
6043 ;; patterns constructed from addsi_1 to match.
6045 (define_insn "*addsi_1_zext"
6046 [(set (match_operand:DI 0 "register_operand" "=r,r")
6048 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6049 (match_operand:SI 2 "general_operand" "g,li"))))
6050 (clobber (reg:CC FLAGS_REG))]
6051 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6053 switch (get_attr_type (insn))
6056 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6057 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6060 if (operands[2] == const1_rtx)
6061 return "inc{l}\t%k0";
6064 gcc_assert (operands[2] == constm1_rtx);
6065 return "dec{l}\t%k0";
6069 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6070 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6071 if (CONST_INT_P (operands[2])
6072 && (INTVAL (operands[2]) == 128
6073 || (INTVAL (operands[2]) < 0
6074 && INTVAL (operands[2]) != -128)))
6076 operands[2] = GEN_INT (-INTVAL (operands[2]));
6077 return "sub{l}\t{%2, %k0|%k0, %2}";
6079 return "add{l}\t{%2, %k0|%k0, %2}";
6083 (cond [(eq_attr "alternative" "1")
6084 (const_string "lea")
6085 ; Current assemblers are broken and do not allow @GOTOFF in
6086 ; ought but a memory context.
6087 (match_operand:SI 2 "pic_symbolic_operand" "")
6088 (const_string "lea")
6089 (match_operand:SI 2 "incdec_operand" "")
6090 (const_string "incdec")
6092 (const_string "alu")))
6093 (set (attr "length_immediate")
6095 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6097 (const_string "*")))
6098 (set_attr "mode" "SI")])
6100 (define_insn "*addhi_1"
6101 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6102 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6103 (match_operand:HI 2 "general_operand" "rn,rm")))
6104 (clobber (reg:CC FLAGS_REG))]
6105 "TARGET_PARTIAL_REG_STALL
6106 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6108 switch (get_attr_type (insn))
6111 if (operands[2] == const1_rtx)
6112 return "inc{w}\t%0";
6115 gcc_assert (operands[2] == constm1_rtx);
6116 return "dec{w}\t%0";
6120 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6121 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6122 if (CONST_INT_P (operands[2])
6123 && (INTVAL (operands[2]) == 128
6124 || (INTVAL (operands[2]) < 0
6125 && INTVAL (operands[2]) != -128)))
6127 operands[2] = GEN_INT (-INTVAL (operands[2]));
6128 return "sub{w}\t{%2, %0|%0, %2}";
6130 return "add{w}\t{%2, %0|%0, %2}";
6134 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6135 (const_string "incdec")
6136 (const_string "alu")))
6137 (set (attr "length_immediate")
6139 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6141 (const_string "*")))
6142 (set_attr "mode" "HI")])
6144 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6145 ;; type optimizations enabled by define-splits. This is not important
6146 ;; for PII, and in fact harmful because of partial register stalls.
6148 (define_insn "*addhi_1_lea"
6149 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6150 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6151 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6152 (clobber (reg:CC FLAGS_REG))]
6153 "!TARGET_PARTIAL_REG_STALL
6154 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6156 switch (get_attr_type (insn))
6161 if (operands[2] == const1_rtx)
6162 return "inc{w}\t%0";
6165 gcc_assert (operands[2] == constm1_rtx);
6166 return "dec{w}\t%0";
6170 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6171 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6172 if (CONST_INT_P (operands[2])
6173 && (INTVAL (operands[2]) == 128
6174 || (INTVAL (operands[2]) < 0
6175 && INTVAL (operands[2]) != -128)))
6177 operands[2] = GEN_INT (-INTVAL (operands[2]));
6178 return "sub{w}\t{%2, %0|%0, %2}";
6180 return "add{w}\t{%2, %0|%0, %2}";
6184 (if_then_else (eq_attr "alternative" "2")
6185 (const_string "lea")
6186 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6187 (const_string "incdec")
6188 (const_string "alu"))))
6189 (set (attr "length_immediate")
6191 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6193 (const_string "*")))
6194 (set_attr "mode" "HI,HI,SI")])
6196 (define_insn "*addqi_1"
6197 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6198 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6199 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6200 (clobber (reg:CC FLAGS_REG))]
6201 "TARGET_PARTIAL_REG_STALL
6202 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6204 int widen = (which_alternative == 2);
6205 switch (get_attr_type (insn))
6208 if (operands[2] == const1_rtx)
6209 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6212 gcc_assert (operands[2] == constm1_rtx);
6213 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6217 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6218 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6219 if (CONST_INT_P (operands[2])
6220 && (INTVAL (operands[2]) == 128
6221 || (INTVAL (operands[2]) < 0
6222 && INTVAL (operands[2]) != -128)))
6224 operands[2] = GEN_INT (-INTVAL (operands[2]));
6226 return "sub{l}\t{%2, %k0|%k0, %2}";
6228 return "sub{b}\t{%2, %0|%0, %2}";
6231 return "add{l}\t{%k2, %k0|%k0, %k2}";
6233 return "add{b}\t{%2, %0|%0, %2}";
6237 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6238 (const_string "incdec")
6239 (const_string "alu")))
6240 (set (attr "length_immediate")
6242 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6244 (const_string "*")))
6245 (set_attr "mode" "QI,QI,SI")])
6247 ;; %%% Potential partial reg stall on alternative 2. What to do?
6248 (define_insn "*addqi_1_lea"
6249 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6250 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6251 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6252 (clobber (reg:CC FLAGS_REG))]
6253 "!TARGET_PARTIAL_REG_STALL
6254 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6256 int widen = (which_alternative == 2);
6257 switch (get_attr_type (insn))
6262 if (operands[2] == const1_rtx)
6263 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6266 gcc_assert (operands[2] == constm1_rtx);
6267 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6271 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'.
6272 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6273 if (CONST_INT_P (operands[2])
6274 && (INTVAL (operands[2]) == 128
6275 || (INTVAL (operands[2]) < 0
6276 && INTVAL (operands[2]) != -128)))
6278 operands[2] = GEN_INT (-INTVAL (operands[2]));
6280 return "sub{l}\t{%2, %k0|%k0, %2}";
6282 return "sub{b}\t{%2, %0|%0, %2}";
6285 return "add{l}\t{%k2, %k0|%k0, %k2}";
6287 return "add{b}\t{%2, %0|%0, %2}";
6291 (if_then_else (eq_attr "alternative" "3")
6292 (const_string "lea")
6293 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6294 (const_string "incdec")
6295 (const_string "alu"))))
6296 (set (attr "length_immediate")
6298 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6300 (const_string "*")))
6301 (set_attr "mode" "QI,QI,SI,SI")])
6303 (define_insn "*addqi_1_slp"
6304 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6305 (plus:QI (match_dup 0)
6306 (match_operand:QI 1 "general_operand" "qn,qnm")))
6307 (clobber (reg:CC FLAGS_REG))]
6308 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6309 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6311 switch (get_attr_type (insn))
6314 if (operands[1] == const1_rtx)
6315 return "inc{b}\t%0";
6318 gcc_assert (operands[1] == constm1_rtx);
6319 return "dec{b}\t%0";
6323 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6324 if (CONST_INT_P (operands[1])
6325 && INTVAL (operands[1]) < 0)
6327 operands[1] = GEN_INT (-INTVAL (operands[1]));
6328 return "sub{b}\t{%1, %0|%0, %1}";
6330 return "add{b}\t{%1, %0|%0, %1}";
6334 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6335 (const_string "incdec")
6336 (const_string "alu1")))
6337 (set (attr "memory")
6338 (if_then_else (match_operand 1 "memory_operand" "")
6339 (const_string "load")
6340 (const_string "none")))
6341 (set_attr "mode" "QI")])
6343 (define_insn "*add<mode>_2"
6344 [(set (reg FLAGS_REG)
6347 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6348 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6350 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6351 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6352 "ix86_match_ccmode (insn, CCGOCmode)
6353 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6354 /* Current assemblers are broken and do not allow @GOTOFF in
6355 ought but a memory context. */
6356 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6358 switch (get_attr_type (insn))
6361 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6362 if (operands[2] == const1_rtx)
6363 return "inc{<imodesuffix>}\t%0";
6366 gcc_assert (operands[2] == constm1_rtx);
6367 return "dec{<imodesuffix>}\t%0";
6371 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6372 /* ???? In DImode, we ought to handle there the 32bit case too
6373 - do we need new constraint? */
6374 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6375 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6376 if (CONST_INT_P (operands[2])
6377 /* Avoid overflows. */
6378 && (<MODE>mode != DImode
6379 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6380 && (INTVAL (operands[2]) == 128
6381 || (INTVAL (operands[2]) < 0
6382 && INTVAL (operands[2]) != -128)))
6384 operands[2] = GEN_INT (-INTVAL (operands[2]));
6385 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6387 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6391 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6392 (const_string "incdec")
6393 (const_string "alu")))
6394 (set (attr "length_immediate")
6396 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6398 (const_string "*")))
6399 (set_attr "mode" "<MODE>")])
6401 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6402 (define_insn "*addsi_2_zext"
6403 [(set (reg FLAGS_REG)
6405 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6406 (match_operand:SI 2 "general_operand" "g"))
6408 (set (match_operand:DI 0 "register_operand" "=r")
6409 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6410 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6411 && ix86_binary_operator_ok (PLUS, SImode, operands)
6412 /* Current assemblers are broken and do not allow @GOTOFF in
6413 ought but a memory context. */
6414 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6416 switch (get_attr_type (insn))
6419 if (operands[2] == const1_rtx)
6420 return "inc{l}\t%k0";
6423 gcc_assert (operands[2] == constm1_rtx);
6424 return "dec{l}\t%k0";
6428 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6429 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6430 if (CONST_INT_P (operands[2])
6431 && (INTVAL (operands[2]) == 128
6432 || (INTVAL (operands[2]) < 0
6433 && INTVAL (operands[2]) != -128)))
6435 operands[2] = GEN_INT (-INTVAL (operands[2]));
6436 return "sub{l}\t{%2, %k0|%k0, %2}";
6438 return "add{l}\t{%2, %k0|%k0, %2}";
6442 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6443 (const_string "incdec")
6444 (const_string "alu")))
6445 (set (attr "length_immediate")
6447 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6449 (const_string "*")))
6450 (set_attr "mode" "SI")])
6452 (define_insn "*addhi_2"
6453 [(set (reg FLAGS_REG)
6455 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6456 (match_operand:HI 2 "general_operand" "rmn,rn"))
6458 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6459 (plus:HI (match_dup 1) (match_dup 2)))]
6460 "ix86_match_ccmode (insn, CCGOCmode)
6461 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6463 switch (get_attr_type (insn))
6466 if (operands[2] == const1_rtx)
6467 return "inc{w}\t%0";
6470 gcc_assert (operands[2] == constm1_rtx);
6471 return "dec{w}\t%0";
6475 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6476 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6477 if (CONST_INT_P (operands[2])
6478 && (INTVAL (operands[2]) == 128
6479 || (INTVAL (operands[2]) < 0
6480 && INTVAL (operands[2]) != -128)))
6482 operands[2] = GEN_INT (-INTVAL (operands[2]));
6483 return "sub{w}\t{%2, %0|%0, %2}";
6485 return "add{w}\t{%2, %0|%0, %2}";
6489 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6490 (const_string "incdec")
6491 (const_string "alu")))
6492 (set (attr "length_immediate")
6494 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6496 (const_string "*")))
6497 (set_attr "mode" "HI")])
6499 (define_insn "*addqi_2"
6500 [(set (reg FLAGS_REG)
6502 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6503 (match_operand:QI 2 "general_operand" "qmn,qn"))
6505 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6506 (plus:QI (match_dup 1) (match_dup 2)))]
6507 "ix86_match_ccmode (insn, CCGOCmode)
6508 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6510 switch (get_attr_type (insn))
6513 if (operands[2] == const1_rtx)
6514 return "inc{b}\t%0";
6517 gcc_assert (operands[2] == constm1_rtx
6518 || (CONST_INT_P (operands[2])
6519 && INTVAL (operands[2]) == 255));
6520 return "dec{b}\t%0";
6524 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6525 if (CONST_INT_P (operands[2])
6526 && INTVAL (operands[2]) < 0)
6528 operands[2] = GEN_INT (-INTVAL (operands[2]));
6529 return "sub{b}\t{%2, %0|%0, %2}";
6531 return "add{b}\t{%2, %0|%0, %2}";
6535 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6536 (const_string "incdec")
6537 (const_string "alu")))
6538 (set_attr "mode" "QI")])
6540 (define_insn "*add<mode>_3"
6541 [(set (reg FLAGS_REG)
6543 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6544 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6545 (clobber (match_scratch:SWI48 0 "=r"))]
6546 "ix86_match_ccmode (insn, CCZmode)
6547 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6548 /* Current assemblers are broken and do not allow @GOTOFF in
6549 ought but a memory context. */
6550 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6552 switch (get_attr_type (insn))
6555 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6556 if (operands[2] == const1_rtx)
6557 return "inc{<imodesuffix>}\t%0";
6560 gcc_assert (operands[2] == constm1_rtx);
6561 return "dec{<imodesuffix>}\t%0";
6565 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6566 /* ???? In DImode, we ought to handle there the 32bit case too
6567 - do we need new constraint? */
6568 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6569 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6570 if (CONST_INT_P (operands[2])
6571 /* Avoid overflows. */
6572 && (<MODE>mode != DImode
6573 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6574 && (INTVAL (operands[2]) == 128
6575 || (INTVAL (operands[2]) < 0
6576 && INTVAL (operands[2]) != -128)))
6578 operands[2] = GEN_INT (-INTVAL (operands[2]));
6579 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6581 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6585 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6586 (const_string "incdec")
6587 (const_string "alu")))
6588 (set (attr "length_immediate")
6590 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6592 (const_string "*")))
6593 (set_attr "mode" "<MODE>")])
6595 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6596 (define_insn "*addsi_3_zext"
6597 [(set (reg FLAGS_REG)
6599 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6600 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6601 (set (match_operand:DI 0 "register_operand" "=r")
6602 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6603 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6604 && ix86_binary_operator_ok (PLUS, SImode, operands)
6605 /* Current assemblers are broken and do not allow @GOTOFF in
6606 ought but a memory context. */
6607 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6609 switch (get_attr_type (insn))
6612 if (operands[2] == const1_rtx)
6613 return "inc{l}\t%k0";
6616 gcc_assert (operands[2] == constm1_rtx);
6617 return "dec{l}\t%k0";
6621 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6622 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6623 if (CONST_INT_P (operands[2])
6624 && (INTVAL (operands[2]) == 128
6625 || (INTVAL (operands[2]) < 0
6626 && INTVAL (operands[2]) != -128)))
6628 operands[2] = GEN_INT (-INTVAL (operands[2]));
6629 return "sub{l}\t{%2, %k0|%k0, %2}";
6631 return "add{l}\t{%2, %k0|%k0, %2}";
6635 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6636 (const_string "incdec")
6637 (const_string "alu")))
6638 (set (attr "length_immediate")
6640 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6642 (const_string "*")))
6643 (set_attr "mode" "SI")])
6645 (define_insn "*addhi_3"
6646 [(set (reg FLAGS_REG)
6648 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6649 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6650 (clobber (match_scratch:HI 0 "=r"))]
6651 "ix86_match_ccmode (insn, CCZmode)
6652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6654 switch (get_attr_type (insn))
6657 if (operands[2] == const1_rtx)
6658 return "inc{w}\t%0";
6661 gcc_assert (operands[2] == constm1_rtx);
6662 return "dec{w}\t%0";
6666 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6667 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6668 if (CONST_INT_P (operands[2])
6669 && (INTVAL (operands[2]) == 128
6670 || (INTVAL (operands[2]) < 0
6671 && INTVAL (operands[2]) != -128)))
6673 operands[2] = GEN_INT (-INTVAL (operands[2]));
6674 return "sub{w}\t{%2, %0|%0, %2}";
6676 return "add{w}\t{%2, %0|%0, %2}";
6680 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6681 (const_string "incdec")
6682 (const_string "alu")))
6683 (set (attr "length_immediate")
6685 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6687 (const_string "*")))
6688 (set_attr "mode" "HI")])
6690 (define_insn "*addqi_3"
6691 [(set (reg FLAGS_REG)
6693 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6694 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6695 (clobber (match_scratch:QI 0 "=q"))]
6696 "ix86_match_ccmode (insn, CCZmode)
6697 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6699 switch (get_attr_type (insn))
6702 if (operands[2] == const1_rtx)
6703 return "inc{b}\t%0";
6706 gcc_assert (operands[2] == constm1_rtx
6707 || (CONST_INT_P (operands[2])
6708 && INTVAL (operands[2]) == 255));
6709 return "dec{b}\t%0";
6713 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
6714 if (CONST_INT_P (operands[2])
6715 && INTVAL (operands[2]) < 0)
6717 operands[2] = GEN_INT (-INTVAL (operands[2]));
6718 return "sub{b}\t{%2, %0|%0, %2}";
6720 return "add{b}\t{%2, %0|%0, %2}";
6724 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6725 (const_string "incdec")
6726 (const_string "alu")))
6727 (set_attr "mode" "QI")])
6729 ; For comparisons against 1, -1 and 128, we may generate better code
6730 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6731 ; is matched then. We can't accept general immediate, because for
6732 ; case of overflows, the result is messed up.
6733 ; This pattern also don't hold of 0x8000000000000000, since the value
6734 ; overflows when negated.
6735 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6736 ; only for comparisons not depending on it.
6738 (define_insn "*adddi_4"
6739 [(set (reg FLAGS_REG)
6741 (match_operand:DI 1 "nonimmediate_operand" "0")
6742 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6743 (clobber (match_scratch:DI 0 "=rm"))]
6745 && ix86_match_ccmode (insn, CCGCmode)"
6747 switch (get_attr_type (insn))
6750 if (operands[2] == constm1_rtx)
6751 return "inc{q}\t%0";
6754 gcc_assert (operands[2] == const1_rtx);
6755 return "dec{q}\t%0";
6759 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6760 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6761 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6762 if ((INTVAL (operands[2]) == -128
6763 || (INTVAL (operands[2]) > 0
6764 && INTVAL (operands[2]) != 128))
6765 /* Avoid overflows. */
6766 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6767 return "sub{q}\t{%2, %0|%0, %2}";
6768 operands[2] = GEN_INT (-INTVAL (operands[2]));
6769 return "add{q}\t{%2, %0|%0, %2}";
6773 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6774 (const_string "incdec")
6775 (const_string "alu")))
6776 (set (attr "length_immediate")
6778 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6780 (const_string "*")))
6781 (set_attr "mode" "DI")])
6783 ; For comparisons against 1, -1 and 128, we may generate better code
6784 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6785 ; is matched then. We can't accept general immediate, because for
6786 ; case of overflows, the result is messed up.
6787 ; This pattern also don't hold of 0x80000000, since the value overflows
6789 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6790 ; only for comparisons not depending on it.
6792 (define_insn "*addsi_4"
6793 [(set (reg FLAGS_REG)
6795 (match_operand:SI 1 "nonimmediate_operand" "0")
6796 (match_operand:SI 2 "const_int_operand" "n")))
6797 (clobber (match_scratch:SI 0 "=rm"))]
6798 "ix86_match_ccmode (insn, CCGCmode)
6799 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
6801 switch (get_attr_type (insn))
6804 if (operands[2] == constm1_rtx)
6805 return "inc{l}\t%0";
6808 gcc_assert (operands[2] == const1_rtx);
6809 return "dec{l}\t%0";
6813 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6814 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6815 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6816 if ((INTVAL (operands[2]) == -128
6817 || (INTVAL (operands[2]) > 0
6818 && INTVAL (operands[2]) != 128)))
6819 return "sub{l}\t{%2, %0|%0, %2}";
6820 operands[2] = GEN_INT (-INTVAL (operands[2]));
6821 return "add{l}\t{%2, %0|%0, %2}";
6825 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6826 (const_string "incdec")
6827 (const_string "alu")))
6828 (set (attr "length_immediate")
6830 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6832 (const_string "*")))
6833 (set_attr "mode" "SI")])
6835 ; See comments above addsi_4 for details.
6837 (define_insn "*addhi_4"
6838 [(set (reg FLAGS_REG)
6840 (match_operand:HI 1 "nonimmediate_operand" "0")
6841 (match_operand:HI 2 "const_int_operand" "n")))
6842 (clobber (match_scratch:HI 0 "=rm"))]
6843 "ix86_match_ccmode (insn, CCGCmode)
6844 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
6846 switch (get_attr_type (insn))
6849 if (operands[2] == constm1_rtx)
6850 return "inc{w}\t%0";
6853 gcc_assert (operands[2] == const1_rtx);
6854 return "dec{w}\t%0";
6858 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6859 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6860 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6861 if ((INTVAL (operands[2]) == -128
6862 || (INTVAL (operands[2]) > 0
6863 && INTVAL (operands[2]) != 128)))
6864 return "sub{w}\t{%2, %0|%0, %2}";
6865 operands[2] = GEN_INT (-INTVAL (operands[2]));
6866 return "add{w}\t{%2, %0|%0, %2}";
6870 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6871 (const_string "incdec")
6872 (const_string "alu")))
6873 (set (attr "length_immediate")
6875 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6877 (const_string "*")))
6878 (set_attr "mode" "HI")])
6880 ; See comments above addsi_4 for details.
6882 (define_insn "*addqi_4"
6883 [(set (reg FLAGS_REG)
6885 (match_operand:QI 1 "nonimmediate_operand" "0")
6886 (match_operand:QI 2 "const_int_operand" "n")))
6887 (clobber (match_scratch:QI 0 "=qm"))]
6888 "ix86_match_ccmode (insn, CCGCmode)
6889 && (INTVAL (operands[2]) & 0xff) != 0x80"
6891 switch (get_attr_type (insn))
6894 if (operands[2] == constm1_rtx
6895 || (CONST_INT_P (operands[2])
6896 && INTVAL (operands[2]) == 255))
6897 return "inc{b}\t%0";
6900 gcc_assert (operands[2] == const1_rtx);
6901 return "dec{b}\t%0";
6905 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6906 if (INTVAL (operands[2]) < 0)
6908 operands[2] = GEN_INT (-INTVAL (operands[2]));
6909 return "add{b}\t{%2, %0|%0, %2}";
6911 return "sub{b}\t{%2, %0|%0, %2}";
6915 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6916 (const_string "incdec")
6917 (const_string "alu")))
6918 (set_attr "mode" "QI")])
6920 (define_insn "*add<mode>_5"
6921 [(set (reg FLAGS_REG)
6924 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6925 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6927 (clobber (match_scratch:SWI48 0 "=r"))]
6928 "ix86_match_ccmode (insn, CCGOCmode)
6929 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6930 /* Current assemblers are broken and do not allow @GOTOFF in
6931 ought but a memory context. */
6932 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6934 switch (get_attr_type (insn))
6937 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6938 if (operands[2] == const1_rtx)
6939 return "inc{<imodesuffix>}\t%0";
6942 gcc_assert (operands[2] == constm1_rtx);
6943 return "dec{<imodesuffix>}\t%0";
6947 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6948 /* Make things pretty and `subl $4,%eax' rather than `addl $-4,%eax'.
6949 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6950 if (CONST_INT_P (operands[2])
6951 /* Avoid overflows. */
6952 && (<MODE>mode != DImode
6953 || ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6954 && (INTVAL (operands[2]) == 128
6955 || (INTVAL (operands[2]) < 0
6956 && INTVAL (operands[2]) != -128)))
6958 operands[2] = GEN_INT (-INTVAL (operands[2]));
6959 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6961 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6965 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6966 (const_string "incdec")
6967 (const_string "alu")))
6968 (set (attr "length_immediate")
6970 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6972 (const_string "*")))
6973 (set_attr "mode" "<MODE>")])
6975 (define_insn "*addhi_5"
6976 [(set (reg FLAGS_REG)
6978 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6979 (match_operand:HI 2 "general_operand" "rmn"))
6981 (clobber (match_scratch:HI 0 "=r"))]
6982 "ix86_match_ccmode (insn, CCGOCmode)
6983 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6985 switch (get_attr_type (insn))
6988 if (operands[2] == const1_rtx)
6989 return "inc{w}\t%0";
6992 gcc_assert (operands[2] == constm1_rtx);
6993 return "dec{w}\t%0";
6997 /* Make things pretty and `subw $4,%ax' rather than `addw $-4,%ax'.
6998 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6999 if (CONST_INT_P (operands[2])
7000 && (INTVAL (operands[2]) == 128
7001 || (INTVAL (operands[2]) < 0
7002 && INTVAL (operands[2]) != -128)))
7004 operands[2] = GEN_INT (-INTVAL (operands[2]));
7005 return "sub{w}\t{%2, %0|%0, %2}";
7007 return "add{w}\t{%2, %0|%0, %2}";
7011 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7012 (const_string "incdec")
7013 (const_string "alu")))
7014 (set (attr "length_immediate")
7016 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7018 (const_string "*")))
7019 (set_attr "mode" "HI")])
7021 (define_insn "*addqi_5"
7022 [(set (reg FLAGS_REG)
7024 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7025 (match_operand:QI 2 "general_operand" "qmn"))
7027 (clobber (match_scratch:QI 0 "=q"))]
7028 "ix86_match_ccmode (insn, CCGOCmode)
7029 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7031 switch (get_attr_type (insn))
7034 if (operands[2] == const1_rtx)
7035 return "inc{b}\t%0";
7038 gcc_assert (operands[2] == constm1_rtx
7039 || (CONST_INT_P (operands[2])
7040 && INTVAL (operands[2]) == 255));
7041 return "dec{b}\t%0";
7045 /* Make things pretty and `subb $4,%al' rather than `addb $-4,%al'. */
7046 if (CONST_INT_P (operands[2])
7047 && INTVAL (operands[2]) < 0)
7049 operands[2] = GEN_INT (-INTVAL (operands[2]));
7050 return "sub{b}\t{%2, %0|%0, %2}";
7052 return "add{b}\t{%2, %0|%0, %2}";
7056 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7057 (const_string "incdec")
7058 (const_string "alu")))
7059 (set_attr "mode" "QI")])
7061 (define_insn "*addqi_ext_1_rex64"
7062 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7067 (match_operand 1 "ext_register_operand" "0")
7070 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7071 (clobber (reg:CC FLAGS_REG))]
7074 switch (get_attr_type (insn))
7077 if (operands[2] == const1_rtx)
7078 return "inc{b}\t%h0";
7081 gcc_assert (operands[2] == constm1_rtx
7082 || (CONST_INT_P (operands[2])
7083 && INTVAL (operands[2]) == 255));
7084 return "dec{b}\t%h0";
7088 return "add{b}\t{%2, %h0|%h0, %2}";
7092 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7093 (const_string "incdec")
7094 (const_string "alu")))
7095 (set_attr "modrm" "1")
7096 (set_attr "mode" "QI")])
7098 (define_insn "addqi_ext_1"
7099 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7104 (match_operand 1 "ext_register_operand" "0")
7107 (match_operand:QI 2 "general_operand" "Qmn")))
7108 (clobber (reg:CC FLAGS_REG))]
7111 switch (get_attr_type (insn))
7114 if (operands[2] == const1_rtx)
7115 return "inc{b}\t%h0";
7118 gcc_assert (operands[2] == constm1_rtx
7119 || (CONST_INT_P (operands[2])
7120 && INTVAL (operands[2]) == 255));
7121 return "dec{b}\t%h0";
7125 return "add{b}\t{%2, %h0|%h0, %2}";
7129 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7130 (const_string "incdec")
7131 (const_string "alu")))
7132 (set_attr "modrm" "1")
7133 (set_attr "mode" "QI")])
7135 (define_insn "*addqi_ext_2"
7136 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7141 (match_operand 1 "ext_register_operand" "%0")
7145 (match_operand 2 "ext_register_operand" "Q")
7148 (clobber (reg:CC FLAGS_REG))]
7150 "add{b}\t{%h2, %h0|%h0, %h2}"
7151 [(set_attr "type" "alu")
7152 (set_attr "mode" "QI")])
7154 ;; The lea patterns for non-Pmodes needs to be matched by
7155 ;; several insns converted to real lea by splitters.
7157 (define_insn_and_split "*lea_general_1"
7158 [(set (match_operand 0 "register_operand" "=r")
7159 (plus (plus (match_operand 1 "index_register_operand" "l")
7160 (match_operand 2 "register_operand" "r"))
7161 (match_operand 3 "immediate_operand" "i")))]
7162 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7163 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7164 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7165 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7166 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7167 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7168 || GET_MODE (operands[3]) == VOIDmode)"
7170 "&& reload_completed"
7174 operands[0] = gen_lowpart (SImode, operands[0]);
7175 operands[1] = gen_lowpart (Pmode, operands[1]);
7176 operands[2] = gen_lowpart (Pmode, operands[2]);
7177 operands[3] = gen_lowpart (Pmode, operands[3]);
7178 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7180 if (Pmode != SImode)
7181 pat = gen_rtx_SUBREG (SImode, pat, 0);
7182 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7185 [(set_attr "type" "lea")
7186 (set_attr "mode" "SI")])
7188 (define_insn_and_split "*lea_general_1_zext"
7189 [(set (match_operand:DI 0 "register_operand" "=r")
7192 (match_operand:SI 1 "index_register_operand" "l")
7193 (match_operand:SI 2 "register_operand" "r"))
7194 (match_operand:SI 3 "immediate_operand" "i"))))]
7197 "&& reload_completed"
7199 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7201 (match_dup 3)) 0)))]
7203 operands[1] = gen_lowpart (Pmode, operands[1]);
7204 operands[2] = gen_lowpart (Pmode, operands[2]);
7205 operands[3] = gen_lowpart (Pmode, operands[3]);
7207 [(set_attr "type" "lea")
7208 (set_attr "mode" "SI")])
7210 (define_insn_and_split "*lea_general_2"
7211 [(set (match_operand 0 "register_operand" "=r")
7212 (plus (mult (match_operand 1 "index_register_operand" "l")
7213 (match_operand 2 "const248_operand" "i"))
7214 (match_operand 3 "nonmemory_operand" "ri")))]
7215 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7216 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7217 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7218 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7219 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7220 || GET_MODE (operands[3]) == VOIDmode)"
7222 "&& reload_completed"
7226 operands[0] = gen_lowpart (SImode, operands[0]);
7227 operands[1] = gen_lowpart (Pmode, operands[1]);
7228 operands[3] = gen_lowpart (Pmode, operands[3]);
7229 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7231 if (Pmode != SImode)
7232 pat = gen_rtx_SUBREG (SImode, pat, 0);
7233 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7236 [(set_attr "type" "lea")
7237 (set_attr "mode" "SI")])
7239 (define_insn_and_split "*lea_general_2_zext"
7240 [(set (match_operand:DI 0 "register_operand" "=r")
7243 (match_operand:SI 1 "index_register_operand" "l")
7244 (match_operand:SI 2 "const248_operand" "n"))
7245 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7248 "&& reload_completed"
7250 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7252 (match_dup 3)) 0)))]
7254 operands[1] = gen_lowpart (Pmode, operands[1]);
7255 operands[3] = gen_lowpart (Pmode, operands[3]);
7257 [(set_attr "type" "lea")
7258 (set_attr "mode" "SI")])
7260 (define_insn_and_split "*lea_general_3"
7261 [(set (match_operand 0 "register_operand" "=r")
7262 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7263 (match_operand 2 "const248_operand" "i"))
7264 (match_operand 3 "register_operand" "r"))
7265 (match_operand 4 "immediate_operand" "i")))]
7266 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7267 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7268 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7269 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7270 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7272 "&& reload_completed"
7276 operands[0] = gen_lowpart (SImode, operands[0]);
7277 operands[1] = gen_lowpart (Pmode, operands[1]);
7278 operands[3] = gen_lowpart (Pmode, operands[3]);
7279 operands[4] = gen_lowpart (Pmode, operands[4]);
7280 pat = gen_rtx_PLUS (Pmode,
7281 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7285 if (Pmode != SImode)
7286 pat = gen_rtx_SUBREG (SImode, pat, 0);
7287 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7290 [(set_attr "type" "lea")
7291 (set_attr "mode" "SI")])
7293 (define_insn_and_split "*lea_general_3_zext"
7294 [(set (match_operand:DI 0 "register_operand" "=r")
7298 (match_operand:SI 1 "index_register_operand" "l")
7299 (match_operand:SI 2 "const248_operand" "n"))
7300 (match_operand:SI 3 "register_operand" "r"))
7301 (match_operand:SI 4 "immediate_operand" "i"))))]
7304 "&& reload_completed"
7306 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7309 (match_dup 4)) 0)))]
7311 operands[1] = gen_lowpart (Pmode, operands[1]);
7312 operands[3] = gen_lowpart (Pmode, operands[3]);
7313 operands[4] = gen_lowpart (Pmode, operands[4]);
7315 [(set_attr "type" "lea")
7316 (set_attr "mode" "SI")])
7318 ;; Convert lea to the lea pattern to avoid flags dependency.
7320 [(set (match_operand:DI 0 "register_operand" "")
7321 (plus:DI (match_operand:DI 1 "register_operand" "")
7322 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7323 (clobber (reg:CC FLAGS_REG))]
7324 "TARGET_64BIT && reload_completed
7325 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7327 (plus:DI (match_dup 1)
7331 ;; Convert lea to the lea pattern to avoid flags dependency.
7333 [(set (match_operand 0 "register_operand" "")
7334 (plus (match_operand 1 "register_operand" "")
7335 (match_operand 2 "nonmemory_operand" "")))
7336 (clobber (reg:CC FLAGS_REG))]
7337 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7341 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7342 may confuse gen_lowpart. */
7343 if (GET_MODE (operands[0]) != Pmode)
7345 operands[1] = gen_lowpart (Pmode, operands[1]);
7346 operands[2] = gen_lowpart (Pmode, operands[2]);
7348 operands[0] = gen_lowpart (SImode, operands[0]);
7349 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7350 if (Pmode != SImode)
7351 pat = gen_rtx_SUBREG (SImode, pat, 0);
7352 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7356 ;; Convert lea to the lea pattern to avoid flags dependency.
7358 [(set (match_operand:DI 0 "register_operand" "")
7360 (plus:SI (match_operand:SI 1 "register_operand" "")
7361 (match_operand:SI 2 "nonmemory_operand" ""))))
7362 (clobber (reg:CC FLAGS_REG))]
7363 "TARGET_64BIT && reload_completed
7364 && true_regnum (operands[0]) != true_regnum (operands[1])"
7366 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7368 operands[1] = gen_lowpart (Pmode, operands[1]);
7369 operands[2] = gen_lowpart (Pmode, operands[2]);
7372 ;; Subtract instructions
7374 (define_expand "sub<mode>3"
7375 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7376 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7377 (match_operand:SDWIM 2 "<general_operand>" "")))]
7379 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7381 (define_insn_and_split "*sub<dwi>3_doubleword"
7382 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7384 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7385 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7386 (clobber (reg:CC FLAGS_REG))]
7387 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7390 [(parallel [(set (reg:CC FLAGS_REG)
7391 (compare:CC (match_dup 1) (match_dup 2)))
7393 (minus:DWIH (match_dup 1) (match_dup 2)))])
7394 (parallel [(set (match_dup 3)
7398 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7400 (clobber (reg:CC FLAGS_REG))])]
7401 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7403 (define_insn "*sub<mode>_1"
7404 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7406 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7407 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7408 (clobber (reg:CC FLAGS_REG))]
7409 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7410 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7411 [(set_attr "type" "alu")
7412 (set_attr "mode" "<MODE>")])
7414 (define_insn "*subsi_1_zext"
7415 [(set (match_operand:DI 0 "register_operand" "=r")
7417 (minus:SI (match_operand:SI 1 "register_operand" "0")
7418 (match_operand:SI 2 "general_operand" "g"))))
7419 (clobber (reg:CC FLAGS_REG))]
7420 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7421 "sub{l}\t{%2, %k0|%k0, %2}"
7422 [(set_attr "type" "alu")
7423 (set_attr "mode" "SI")])
7425 (define_insn "*subqi_1_slp"
7426 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7427 (minus:QI (match_dup 0)
7428 (match_operand:QI 1 "general_operand" "qn,qm")))
7429 (clobber (reg:CC FLAGS_REG))]
7430 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7431 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7432 "sub{b}\t{%1, %0|%0, %1}"
7433 [(set_attr "type" "alu1")
7434 (set_attr "mode" "QI")])
7436 (define_insn "*sub<mode>_2"
7437 [(set (reg FLAGS_REG)
7440 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7441 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7443 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7444 (minus:SWI (match_dup 1) (match_dup 2)))]
7445 "ix86_match_ccmode (insn, CCGOCmode)
7446 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7447 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7448 [(set_attr "type" "alu")
7449 (set_attr "mode" "<MODE>")])
7451 (define_insn "*subsi_2_zext"
7452 [(set (reg FLAGS_REG)
7454 (minus:SI (match_operand:SI 1 "register_operand" "0")
7455 (match_operand:SI 2 "general_operand" "g"))
7457 (set (match_operand:DI 0 "register_operand" "=r")
7459 (minus:SI (match_dup 1)
7461 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7462 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7463 "sub{l}\t{%2, %k0|%k0, %2}"
7464 [(set_attr "type" "alu")
7465 (set_attr "mode" "SI")])
7467 (define_insn "*sub<mode>_3"
7468 [(set (reg FLAGS_REG)
7469 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7470 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7471 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7472 (minus:SWI (match_dup 1) (match_dup 2)))]
7473 "ix86_match_ccmode (insn, CCmode)
7474 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7475 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7476 [(set_attr "type" "alu")
7477 (set_attr "mode" "<MODE>")])
7479 (define_insn "*subsi_3_zext"
7480 [(set (reg FLAGS_REG)
7481 (compare (match_operand:SI 1 "register_operand" "0")
7482 (match_operand:SI 2 "general_operand" "g")))
7483 (set (match_operand:DI 0 "register_operand" "=r")
7485 (minus:SI (match_dup 1)
7487 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7488 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7489 "sub{l}\t{%2, %1|%1, %2}"
7490 [(set_attr "type" "alu")
7491 (set_attr "mode" "SI")])
7493 ;; Add with carry and subtract with borrow
7495 (define_expand "<plusminus_insn><mode>3_carry"
7497 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7499 (match_operand:SWI 1 "nonimmediate_operand" "")
7500 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7501 [(match_operand 3 "flags_reg_operand" "")
7503 (match_operand:SWI 2 "<general_operand>" ""))))
7504 (clobber (reg:CC FLAGS_REG))])]
7505 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7508 (define_insn "*<plusminus_insn><mode>3_carry"
7509 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7511 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7513 (match_operator 3 "ix86_carry_flag_operator"
7514 [(reg FLAGS_REG) (const_int 0)])
7515 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7516 (clobber (reg:CC FLAGS_REG))]
7517 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7518 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7519 [(set_attr "type" "alu")
7520 (set_attr "use_carry" "1")
7521 (set_attr "pent_pair" "pu")
7522 (set_attr "mode" "<MODE>")])
7524 (define_insn "*addsi3_carry_zext"
7525 [(set (match_operand:DI 0 "register_operand" "=r")
7527 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7528 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7529 [(reg FLAGS_REG) (const_int 0)])
7530 (match_operand:SI 2 "general_operand" "g")))))
7531 (clobber (reg:CC FLAGS_REG))]
7532 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7533 "adc{l}\t{%2, %k0|%k0, %2}"
7534 [(set_attr "type" "alu")
7535 (set_attr "use_carry" "1")
7536 (set_attr "pent_pair" "pu")
7537 (set_attr "mode" "SI")])
7539 (define_insn "*subsi3_carry_zext"
7540 [(set (match_operand:DI 0 "register_operand" "=r")
7542 (minus:SI (match_operand:SI 1 "register_operand" "0")
7543 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7544 [(reg FLAGS_REG) (const_int 0)])
7545 (match_operand:SI 2 "general_operand" "g")))))
7546 (clobber (reg:CC FLAGS_REG))]
7547 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7548 "sbb{l}\t{%2, %k0|%k0, %2}"
7549 [(set_attr "type" "alu")
7550 (set_attr "pent_pair" "pu")
7551 (set_attr "mode" "SI")])
7553 ;; Overflow setting add and subtract instructions
7555 (define_insn "*add<mode>3_cconly_overflow"
7556 [(set (reg:CCC FLAGS_REG)
7559 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7560 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7562 (clobber (match_scratch:SWI 0 "=<r>"))]
7563 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7564 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7565 [(set_attr "type" "alu")
7566 (set_attr "mode" "<MODE>")])
7568 (define_insn "*sub<mode>3_cconly_overflow"
7569 [(set (reg:CCC FLAGS_REG)
7572 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7573 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7576 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7577 [(set_attr "type" "icmp")
7578 (set_attr "mode" "<MODE>")])
7580 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7581 [(set (reg:CCC FLAGS_REG)
7584 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7585 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7587 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7588 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7589 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7590 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7591 [(set_attr "type" "alu")
7592 (set_attr "mode" "<MODE>")])
7594 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7595 [(set (reg:CCC FLAGS_REG)
7598 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7599 (match_operand:SI 2 "general_operand" "g"))
7601 (set (match_operand:DI 0 "register_operand" "=r")
7602 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7603 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7604 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7605 [(set_attr "type" "alu")
7606 (set_attr "mode" "SI")])
7608 ;; The patterns that match these are at the end of this file.
7610 (define_expand "<plusminus_insn>xf3"
7611 [(set (match_operand:XF 0 "register_operand" "")
7613 (match_operand:XF 1 "register_operand" "")
7614 (match_operand:XF 2 "register_operand" "")))]
7618 (define_expand "<plusminus_insn><mode>3"
7619 [(set (match_operand:MODEF 0 "register_operand" "")
7621 (match_operand:MODEF 1 "register_operand" "")
7622 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7623 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7624 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7627 ;; Multiply instructions
7629 (define_expand "mul<mode>3"
7630 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7632 (match_operand:SWIM248 1 "register_operand" "")
7633 (match_operand:SWIM248 2 "<general_operand>" "")))
7634 (clobber (reg:CC FLAGS_REG))])]
7638 (define_expand "mulqi3"
7639 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7641 (match_operand:QI 1 "register_operand" "")
7642 (match_operand:QI 2 "nonimmediate_operand" "")))
7643 (clobber (reg:CC FLAGS_REG))])]
7644 "TARGET_QIMODE_MATH"
7648 ;; IMUL reg32/64, reg32/64, imm8 Direct
7649 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7650 ;; IMUL reg32/64, reg32/64, imm32 Direct
7651 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7652 ;; IMUL reg32/64, reg32/64 Direct
7653 ;; IMUL reg32/64, mem32/64 Direct
7655 (define_insn "*mul<mode>3_1"
7656 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7658 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7659 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7660 (clobber (reg:CC FLAGS_REG))]
7661 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7663 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7664 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7665 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7666 [(set_attr "type" "imul")
7667 (set_attr "prefix_0f" "0,0,1")
7668 (set (attr "athlon_decode")
7669 (cond [(eq_attr "cpu" "athlon")
7670 (const_string "vector")
7671 (eq_attr "alternative" "1")
7672 (const_string "vector")
7673 (and (eq_attr "alternative" "2")
7674 (match_operand 1 "memory_operand" ""))
7675 (const_string "vector")]
7676 (const_string "direct")))
7677 (set (attr "amdfam10_decode")
7678 (cond [(and (eq_attr "alternative" "0,1")
7679 (match_operand 1 "memory_operand" ""))
7680 (const_string "vector")]
7681 (const_string "direct")))
7682 (set_attr "mode" "<MODE>")])
7684 (define_insn "*mulsi3_1_zext"
7685 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7687 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7688 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7689 (clobber (reg:CC FLAGS_REG))]
7691 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7693 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7694 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7695 imul{l}\t{%2, %k0|%k0, %2}"
7696 [(set_attr "type" "imul")
7697 (set_attr "prefix_0f" "0,0,1")
7698 (set (attr "athlon_decode")
7699 (cond [(eq_attr "cpu" "athlon")
7700 (const_string "vector")
7701 (eq_attr "alternative" "1")
7702 (const_string "vector")
7703 (and (eq_attr "alternative" "2")
7704 (match_operand 1 "memory_operand" ""))
7705 (const_string "vector")]
7706 (const_string "direct")))
7707 (set (attr "amdfam10_decode")
7708 (cond [(and (eq_attr "alternative" "0,1")
7709 (match_operand 1 "memory_operand" ""))
7710 (const_string "vector")]
7711 (const_string "direct")))
7712 (set_attr "mode" "SI")])
7715 ;; IMUL reg16, reg16, imm8 VectorPath
7716 ;; IMUL reg16, mem16, imm8 VectorPath
7717 ;; IMUL reg16, reg16, imm16 VectorPath
7718 ;; IMUL reg16, mem16, imm16 VectorPath
7719 ;; IMUL reg16, reg16 Direct
7720 ;; IMUL reg16, mem16 Direct
7722 (define_insn "*mulhi3_1"
7723 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7724 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7725 (match_operand:HI 2 "general_operand" "K,n,mr")))
7726 (clobber (reg:CC FLAGS_REG))]
7728 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7730 imul{w}\t{%2, %1, %0|%0, %1, %2}
7731 imul{w}\t{%2, %1, %0|%0, %1, %2}
7732 imul{w}\t{%2, %0|%0, %2}"
7733 [(set_attr "type" "imul")
7734 (set_attr "prefix_0f" "0,0,1")
7735 (set (attr "athlon_decode")
7736 (cond [(eq_attr "cpu" "athlon")
7737 (const_string "vector")
7738 (eq_attr "alternative" "1,2")
7739 (const_string "vector")]
7740 (const_string "direct")))
7741 (set (attr "amdfam10_decode")
7742 (cond [(eq_attr "alternative" "0,1")
7743 (const_string "vector")]
7744 (const_string "direct")))
7745 (set_attr "mode" "HI")])
7751 (define_insn "*mulqi3_1"
7752 [(set (match_operand:QI 0 "register_operand" "=a")
7753 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7754 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7755 (clobber (reg:CC FLAGS_REG))]
7757 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7759 [(set_attr "type" "imul")
7760 (set_attr "length_immediate" "0")
7761 (set (attr "athlon_decode")
7762 (if_then_else (eq_attr "cpu" "athlon")
7763 (const_string "vector")
7764 (const_string "direct")))
7765 (set_attr "amdfam10_decode" "direct")
7766 (set_attr "mode" "QI")])
7768 (define_expand "<u>mul<mode><dwi>3"
7769 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7772 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7774 (match_operand:DWIH 2 "register_operand" ""))))
7775 (clobber (reg:CC FLAGS_REG))])]
7779 (define_expand "<u>mulqihi3"
7780 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7783 (match_operand:QI 1 "nonimmediate_operand" ""))
7785 (match_operand:QI 2 "register_operand" ""))))
7786 (clobber (reg:CC FLAGS_REG))])]
7787 "TARGET_QIMODE_MATH"
7790 (define_insn "*<u>mul<mode><dwi>3_1"
7791 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7794 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7796 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7797 (clobber (reg:CC FLAGS_REG))]
7798 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7799 "<sgnprefix>mul{<imodesuffix>}\t%2"
7800 [(set_attr "type" "imul")
7801 (set_attr "length_immediate" "0")
7802 (set (attr "athlon_decode")
7803 (if_then_else (eq_attr "cpu" "athlon")
7804 (const_string "vector")
7805 (const_string "double")))
7806 (set_attr "amdfam10_decode" "double")
7807 (set_attr "mode" "<MODE>")])
7809 (define_insn "*<u>mulqihi3_1"
7810 [(set (match_operand:HI 0 "register_operand" "=a")
7813 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7815 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7816 (clobber (reg:CC FLAGS_REG))]
7818 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7819 "<sgnprefix>mul{b}\t%2"
7820 [(set_attr "type" "imul")
7821 (set_attr "length_immediate" "0")
7822 (set (attr "athlon_decode")
7823 (if_then_else (eq_attr "cpu" "athlon")
7824 (const_string "vector")
7825 (const_string "direct")))
7826 (set_attr "amdfam10_decode" "direct")
7827 (set_attr "mode" "QI")])
7829 (define_expand "<s>mul<mode>3_highpart"
7830 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7835 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7837 (match_operand:SWI48 2 "register_operand" "")))
7839 (clobber (match_scratch:SWI48 3 ""))
7840 (clobber (reg:CC FLAGS_REG))])]
7842 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7844 (define_insn "*<s>muldi3_highpart_1"
7845 [(set (match_operand:DI 0 "register_operand" "=d")
7850 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7852 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7854 (clobber (match_scratch:DI 3 "=1"))
7855 (clobber (reg:CC FLAGS_REG))]
7857 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7858 "<sgnprefix>mul{q}\t%2"
7859 [(set_attr "type" "imul")
7860 (set_attr "length_immediate" "0")
7861 (set (attr "athlon_decode")
7862 (if_then_else (eq_attr "cpu" "athlon")
7863 (const_string "vector")
7864 (const_string "double")))
7865 (set_attr "amdfam10_decode" "double")
7866 (set_attr "mode" "DI")])
7868 (define_insn "*<s>mulsi3_highpart_1"
7869 [(set (match_operand:SI 0 "register_operand" "=d")
7874 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7876 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7878 (clobber (match_scratch:SI 3 "=1"))
7879 (clobber (reg:CC FLAGS_REG))]
7880 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7881 "<sgnprefix>mul{l}\t%2"
7882 [(set_attr "type" "imul")
7883 (set_attr "length_immediate" "0")
7884 (set (attr "athlon_decode")
7885 (if_then_else (eq_attr "cpu" "athlon")
7886 (const_string "vector")
7887 (const_string "double")))
7888 (set_attr "amdfam10_decode" "double")
7889 (set_attr "mode" "SI")])
7891 (define_insn "*<s>mulsi3_highpart_zext"
7892 [(set (match_operand:DI 0 "register_operand" "=d")
7893 (zero_extend:DI (truncate:SI
7895 (mult:DI (any_extend:DI
7896 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7898 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7900 (clobber (match_scratch:SI 3 "=1"))
7901 (clobber (reg:CC FLAGS_REG))]
7903 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7904 "<sgnprefix>mul{l}\t%2"
7905 [(set_attr "type" "imul")
7906 (set_attr "length_immediate" "0")
7907 (set (attr "athlon_decode")
7908 (if_then_else (eq_attr "cpu" "athlon")
7909 (const_string "vector")
7910 (const_string "double")))
7911 (set_attr "amdfam10_decode" "double")
7912 (set_attr "mode" "SI")])
7914 ;; The patterns that match these are at the end of this file.
7916 (define_expand "mulxf3"
7917 [(set (match_operand:XF 0 "register_operand" "")
7918 (mult:XF (match_operand:XF 1 "register_operand" "")
7919 (match_operand:XF 2 "register_operand" "")))]
7923 (define_expand "mul<mode>3"
7924 [(set (match_operand:MODEF 0 "register_operand" "")
7925 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7926 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7927 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7928 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7931 ;; Divide instructions
7933 (define_insn "<u>divqi3"
7934 [(set (match_operand:QI 0 "register_operand" "=a")
7936 (match_operand:HI 1 "register_operand" "0")
7937 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7938 (clobber (reg:CC FLAGS_REG))]
7939 "TARGET_QIMODE_MATH"
7940 "<sgnprefix>div{b}\t%2"
7941 [(set_attr "type" "idiv")
7942 (set_attr "mode" "QI")])
7944 ;; The patterns that match these are at the end of this file.
7946 (define_expand "divxf3"
7947 [(set (match_operand:XF 0 "register_operand" "")
7948 (div:XF (match_operand:XF 1 "register_operand" "")
7949 (match_operand:XF 2 "register_operand" "")))]
7953 (define_expand "divdf3"
7954 [(set (match_operand:DF 0 "register_operand" "")
7955 (div:DF (match_operand:DF 1 "register_operand" "")
7956 (match_operand:DF 2 "nonimmediate_operand" "")))]
7957 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7958 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7961 (define_expand "divsf3"
7962 [(set (match_operand:SF 0 "register_operand" "")
7963 (div:SF (match_operand:SF 1 "register_operand" "")
7964 (match_operand:SF 2 "nonimmediate_operand" "")))]
7965 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7968 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7969 && flag_finite_math_only && !flag_trapping_math
7970 && flag_unsafe_math_optimizations)
7972 ix86_emit_swdivsf (operands[0], operands[1],
7973 operands[2], SFmode);
7978 ;; Divmod instructions.
7980 (define_expand "divmod<mode>4"
7981 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7983 (match_operand:SWIM248 1 "register_operand" "")
7984 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7985 (set (match_operand:SWIM248 3 "register_operand" "")
7986 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7987 (clobber (reg:CC FLAGS_REG))])]
7991 (define_insn_and_split "*divmod<mode>4"
7992 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7993 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7994 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7995 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7996 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7997 (clobber (reg:CC FLAGS_REG))]
8000 "&& reload_completed"
8001 [(parallel [(set (match_dup 1)
8002 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
8003 (clobber (reg:CC FLAGS_REG))])
8004 (parallel [(set (match_dup 0)
8005 (div:SWIM248 (match_dup 2) (match_dup 3)))
8007 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8009 (clobber (reg:CC FLAGS_REG))])]
8011 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
8013 if (<MODE>mode != HImode
8014 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
8015 operands[4] = operands[2];
8018 /* Avoid use of cltd in favor of a mov+shift. */
8019 emit_move_insn (operands[1], operands[2]);
8020 operands[4] = operands[1];
8023 [(set_attr "type" "multi")
8024 (set_attr "mode" "<MODE>")])
8026 (define_insn "*divmod<mode>4_noext"
8027 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8028 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8029 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8030 (set (match_operand:SWIM248 1 "register_operand" "=d")
8031 (mod:SWIM248 (match_dup 2) (match_dup 3)))
8032 (use (match_operand:SWIM248 4 "register_operand" "1"))
8033 (clobber (reg:CC FLAGS_REG))]
8035 "idiv{<imodesuffix>}\t%3"
8036 [(set_attr "type" "idiv")
8037 (set_attr "mode" "<MODE>")])
8039 (define_expand "udivmod<mode>4"
8040 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
8042 (match_operand:SWIM248 1 "register_operand" "")
8043 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
8044 (set (match_operand:SWIM248 3 "register_operand" "")
8045 (umod:SWIM248 (match_dup 1) (match_dup 2)))
8046 (clobber (reg:CC FLAGS_REG))])]
8050 (define_insn_and_split "*udivmod<mode>4"
8051 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8052 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8053 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8054 (set (match_operand:SWIM248 1 "register_operand" "=&d")
8055 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8056 (clobber (reg:CC FLAGS_REG))]
8059 "&& reload_completed"
8060 [(set (match_dup 1) (const_int 0))
8061 (parallel [(set (match_dup 0)
8062 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
8064 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8066 (clobber (reg:CC FLAGS_REG))])]
8068 [(set_attr "type" "multi")
8069 (set_attr "mode" "<MODE>")])
8071 (define_insn "*udivmod<mode>4_noext"
8072 [(set (match_operand:SWIM248 0 "register_operand" "=a")
8073 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
8074 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
8075 (set (match_operand:SWIM248 1 "register_operand" "=d")
8076 (umod:SWIM248 (match_dup 2) (match_dup 3)))
8077 (use (match_operand:SWIM248 4 "register_operand" "1"))
8078 (clobber (reg:CC FLAGS_REG))]
8080 "div{<imodesuffix>}\t%3"
8081 [(set_attr "type" "idiv")
8082 (set_attr "mode" "<MODE>")])
8084 ;; We cannot use div/idiv for double division, because it causes
8085 ;; "division by zero" on the overflow and that's not what we expect
8086 ;; from truncate. Because true (non truncating) double division is
8087 ;; never generated, we can't create this insn anyway.
8090 ; [(set (match_operand:SI 0 "register_operand" "=a")
8092 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
8094 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
8095 ; (set (match_operand:SI 3 "register_operand" "=d")
8097 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
8098 ; (clobber (reg:CC FLAGS_REG))]
8100 ; "div{l}\t{%2, %0|%0, %2}"
8101 ; [(set_attr "type" "idiv")])
8103 ;;- Logical AND instructions
8105 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
8106 ;; Note that this excludes ah.
8108 (define_insn "*testdi_1_rex64"
8109 [(set (reg FLAGS_REG)
8111 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
8112 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
8114 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8115 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8117 test{l}\t{%k1, %k0|%k0, %k1}
8118 test{l}\t{%k1, %k0|%k0, %k1}
8119 test{q}\t{%1, %0|%0, %1}
8120 test{q}\t{%1, %0|%0, %1}
8121 test{q}\t{%1, %0|%0, %1}"
8122 [(set_attr "type" "test")
8123 (set_attr "modrm" "0,1,0,1,1")
8124 (set_attr "mode" "SI,SI,DI,DI,DI")
8125 (set_attr "pent_pair" "uv,np,uv,np,uv")])
8127 (define_insn "testsi_1"
8128 [(set (reg FLAGS_REG)
8130 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
8131 (match_operand:SI 1 "general_operand" "i,i,ri"))
8133 "ix86_match_ccmode (insn, CCNOmode)
8134 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8135 "test{l}\t{%1, %0|%0, %1}"
8136 [(set_attr "type" "test")
8137 (set_attr "modrm" "0,1,1")
8138 (set_attr "mode" "SI")
8139 (set_attr "pent_pair" "uv,np,uv")])
8141 (define_expand "testsi_ccno_1"
8142 [(set (reg:CCNO FLAGS_REG)
8144 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
8145 (match_operand:SI 1 "nonmemory_operand" ""))
8150 (define_insn "*testhi_1"
8151 [(set (reg FLAGS_REG)
8152 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
8153 (match_operand:HI 1 "general_operand" "n,n,rn"))
8155 "ix86_match_ccmode (insn, CCNOmode)
8156 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8157 "test{w}\t{%1, %0|%0, %1}"
8158 [(set_attr "type" "test")
8159 (set_attr "modrm" "0,1,1")
8160 (set_attr "mode" "HI")
8161 (set_attr "pent_pair" "uv,np,uv")])
8163 (define_expand "testqi_ccz_1"
8164 [(set (reg:CCZ FLAGS_REG)
8165 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
8166 (match_operand:QI 1 "nonmemory_operand" ""))
8171 (define_insn "*testqi_1_maybe_si"
8172 [(set (reg FLAGS_REG)
8175 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8176 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8178 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8179 && ix86_match_ccmode (insn,
8180 CONST_INT_P (operands[1])
8181 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8183 if (which_alternative == 3)
8185 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8186 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8187 return "test{l}\t{%1, %k0|%k0, %1}";
8189 return "test{b}\t{%1, %0|%0, %1}";
8191 [(set_attr "type" "test")
8192 (set_attr "modrm" "0,1,1,1")
8193 (set_attr "mode" "QI,QI,QI,SI")
8194 (set_attr "pent_pair" "uv,np,uv,np")])
8196 (define_insn "*testqi_1"
8197 [(set (reg FLAGS_REG)
8200 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
8201 (match_operand:QI 1 "general_operand" "n,n,qn"))
8203 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8204 && ix86_match_ccmode (insn, CCNOmode)"
8205 "test{b}\t{%1, %0|%0, %1}"
8206 [(set_attr "type" "test")
8207 (set_attr "modrm" "0,1,1")
8208 (set_attr "mode" "QI")
8209 (set_attr "pent_pair" "uv,np,uv")])
8211 (define_expand "testqi_ext_ccno_0"
8212 [(set (reg:CCNO FLAGS_REG)
8216 (match_operand 0 "ext_register_operand" "")
8219 (match_operand 1 "const_int_operand" ""))
8224 (define_insn "*testqi_ext_0"
8225 [(set (reg FLAGS_REG)
8229 (match_operand 0 "ext_register_operand" "Q")
8232 (match_operand 1 "const_int_operand" "n"))
8234 "ix86_match_ccmode (insn, CCNOmode)"
8235 "test{b}\t{%1, %h0|%h0, %1}"
8236 [(set_attr "type" "test")
8237 (set_attr "mode" "QI")
8238 (set_attr "length_immediate" "1")
8239 (set_attr "modrm" "1")
8240 (set_attr "pent_pair" "np")])
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 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8255 "test{b}\t{%1, %h0|%h0, %1}"
8256 [(set_attr "type" "test")
8257 (set_attr "mode" "QI")])
8259 (define_insn "*testqi_ext_1_rex64"
8260 [(set (reg FLAGS_REG)
8264 (match_operand 0 "ext_register_operand" "Q")
8268 (match_operand:QI 1 "register_operand" "Q")))
8270 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8271 "test{b}\t{%1, %h0|%h0, %1}"
8272 [(set_attr "type" "test")
8273 (set_attr "mode" "QI")])
8275 (define_insn "*testqi_ext_2"
8276 [(set (reg FLAGS_REG)
8280 (match_operand 0 "ext_register_operand" "Q")
8284 (match_operand 1 "ext_register_operand" "Q")
8288 "ix86_match_ccmode (insn, CCNOmode)"
8289 "test{b}\t{%h1, %h0|%h0, %h1}"
8290 [(set_attr "type" "test")
8291 (set_attr "mode" "QI")])
8293 ;; Combine likes to form bit extractions for some tests. Humor it.
8294 (define_insn "*testqi_ext_3"
8295 [(set (reg FLAGS_REG)
8296 (compare (zero_extract:SI
8297 (match_operand 0 "nonimmediate_operand" "rm")
8298 (match_operand:SI 1 "const_int_operand" "")
8299 (match_operand:SI 2 "const_int_operand" ""))
8301 "ix86_match_ccmode (insn, CCNOmode)
8302 && INTVAL (operands[1]) > 0
8303 && INTVAL (operands[2]) >= 0
8304 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8305 && (GET_MODE (operands[0]) == SImode
8306 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8307 || GET_MODE (operands[0]) == HImode
8308 || GET_MODE (operands[0]) == QImode)"
8311 (define_insn "*testqi_ext_3_rex64"
8312 [(set (reg FLAGS_REG)
8313 (compare (zero_extract:DI
8314 (match_operand 0 "nonimmediate_operand" "rm")
8315 (match_operand:DI 1 "const_int_operand" "")
8316 (match_operand:DI 2 "const_int_operand" ""))
8319 && ix86_match_ccmode (insn, CCNOmode)
8320 && INTVAL (operands[1]) > 0
8321 && INTVAL (operands[2]) >= 0
8322 /* Ensure that resulting mask is zero or sign extended operand. */
8323 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8324 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8325 && INTVAL (operands[1]) > 32))
8326 && (GET_MODE (operands[0]) == SImode
8327 || GET_MODE (operands[0]) == DImode
8328 || GET_MODE (operands[0]) == HImode
8329 || GET_MODE (operands[0]) == QImode)"
8333 [(set (match_operand 0 "flags_reg_operand" "")
8334 (match_operator 1 "compare_operator"
8336 (match_operand 2 "nonimmediate_operand" "")
8337 (match_operand 3 "const_int_operand" "")
8338 (match_operand 4 "const_int_operand" ""))
8340 "ix86_match_ccmode (insn, CCNOmode)"
8341 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8343 rtx val = operands[2];
8344 HOST_WIDE_INT len = INTVAL (operands[3]);
8345 HOST_WIDE_INT pos = INTVAL (operands[4]);
8347 enum machine_mode mode, submode;
8349 mode = GET_MODE (val);
8352 /* ??? Combine likes to put non-volatile mem extractions in QImode
8353 no matter the size of the test. So find a mode that works. */
8354 if (! MEM_VOLATILE_P (val))
8356 mode = smallest_mode_for_size (pos + len, MODE_INT);
8357 val = adjust_address (val, mode, 0);
8360 else if (GET_CODE (val) == SUBREG
8361 && (submode = GET_MODE (SUBREG_REG (val)),
8362 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8363 && pos + len <= GET_MODE_BITSIZE (submode)
8364 && GET_MODE_CLASS (submode) == MODE_INT)
8366 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8368 val = SUBREG_REG (val);
8370 else if (mode == HImode && pos + len <= 8)
8372 /* Small HImode tests can be converted to QImode. */
8374 val = gen_lowpart (QImode, val);
8377 if (len == HOST_BITS_PER_WIDE_INT)
8380 mask = ((HOST_WIDE_INT)1 << len) - 1;
8383 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8386 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8387 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8388 ;; this is relatively important trick.
8389 ;; Do the conversion only post-reload to avoid limiting of the register class
8392 [(set (match_operand 0 "flags_reg_operand" "")
8393 (match_operator 1 "compare_operator"
8394 [(and (match_operand 2 "register_operand" "")
8395 (match_operand 3 "const_int_operand" ""))
8398 && QI_REG_P (operands[2])
8399 && GET_MODE (operands[2]) != QImode
8400 && ((ix86_match_ccmode (insn, CCZmode)
8401 && !(INTVAL (operands[3]) & ~(255 << 8)))
8402 || (ix86_match_ccmode (insn, CCNOmode)
8403 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8406 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8409 "operands[2] = gen_lowpart (SImode, operands[2]);
8410 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8413 [(set (match_operand 0 "flags_reg_operand" "")
8414 (match_operator 1 "compare_operator"
8415 [(and (match_operand 2 "nonimmediate_operand" "")
8416 (match_operand 3 "const_int_operand" ""))
8419 && GET_MODE (operands[2]) != QImode
8420 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8421 && ((ix86_match_ccmode (insn, CCZmode)
8422 && !(INTVAL (operands[3]) & ~255))
8423 || (ix86_match_ccmode (insn, CCNOmode)
8424 && !(INTVAL (operands[3]) & ~127)))"
8426 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8428 "operands[2] = gen_lowpart (QImode, operands[2]);
8429 operands[3] = gen_lowpart (QImode, operands[3]);")
8432 ;; %%% This used to optimize known byte-wide and operations to memory,
8433 ;; and sometimes to QImode registers. If this is considered useful,
8434 ;; it should be done with splitters.
8436 (define_expand "anddi3"
8437 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8438 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
8439 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
8441 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
8443 (define_insn "*anddi_1_rex64"
8444 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8445 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8446 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8447 (clobber (reg:CC FLAGS_REG))]
8448 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8450 switch (get_attr_type (insn))
8454 enum machine_mode mode;
8456 gcc_assert (CONST_INT_P (operands[2]));
8457 if (INTVAL (operands[2]) == 0xff)
8461 gcc_assert (INTVAL (operands[2]) == 0xffff);
8465 operands[1] = gen_lowpart (mode, operands[1]);
8467 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8469 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8473 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8474 if (get_attr_mode (insn) == MODE_SI)
8475 return "and{l}\t{%k2, %k0|%k0, %k2}";
8477 return "and{q}\t{%2, %0|%0, %2}";
8480 [(set_attr "type" "alu,alu,alu,imovx")
8481 (set_attr "length_immediate" "*,*,*,0")
8482 (set (attr "prefix_rex")
8484 (and (eq_attr "type" "imovx")
8485 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8486 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8488 (const_string "*")))
8489 (set_attr "mode" "SI,DI,DI,SI")])
8491 (define_insn "*anddi_2"
8492 [(set (reg FLAGS_REG)
8493 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8494 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8496 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8497 (and:DI (match_dup 1) (match_dup 2)))]
8498 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8499 && ix86_binary_operator_ok (AND, DImode, operands)"
8501 and{l}\t{%k2, %k0|%k0, %k2}
8502 and{q}\t{%2, %0|%0, %2}
8503 and{q}\t{%2, %0|%0, %2}"
8504 [(set_attr "type" "alu")
8505 (set_attr "mode" "SI,DI,DI")])
8507 (define_expand "andsi3"
8508 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8509 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
8510 (match_operand:SI 2 "general_operand" "")))]
8512 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
8514 (define_insn "*andsi_1"
8515 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8516 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8517 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8518 (clobber (reg:CC FLAGS_REG))]
8519 "ix86_binary_operator_ok (AND, SImode, operands)"
8521 switch (get_attr_type (insn))
8525 enum machine_mode mode;
8527 gcc_assert (CONST_INT_P (operands[2]));
8528 if (INTVAL (operands[2]) == 0xff)
8532 gcc_assert (INTVAL (operands[2]) == 0xffff);
8536 operands[1] = gen_lowpart (mode, operands[1]);
8538 return "movz{bl|x}\t{%1, %0|%0, %1}";
8540 return "movz{wl|x}\t{%1, %0|%0, %1}";
8544 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8545 return "and{l}\t{%2, %0|%0, %2}";
8548 [(set_attr "type" "alu,alu,imovx")
8549 (set (attr "prefix_rex")
8551 (and (eq_attr "type" "imovx")
8552 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8553 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8555 (const_string "*")))
8556 (set_attr "length_immediate" "*,*,0")
8557 (set_attr "mode" "SI")])
8560 [(set (match_operand 0 "register_operand" "")
8562 (const_int -65536)))
8563 (clobber (reg:CC FLAGS_REG))]
8564 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
8565 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8566 "operands[1] = gen_lowpart (HImode, operands[0]);")
8569 [(set (match_operand 0 "ext_register_operand" "")
8572 (clobber (reg:CC FLAGS_REG))]
8573 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8574 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8575 "operands[1] = gen_lowpart (QImode, operands[0]);")
8578 [(set (match_operand 0 "ext_register_operand" "")
8580 (const_int -65281)))
8581 (clobber (reg:CC FLAGS_REG))]
8582 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
8583 [(parallel [(set (zero_extract:SI (match_dup 0)
8587 (zero_extract:SI (match_dup 0)
8590 (zero_extract:SI (match_dup 0)
8593 (clobber (reg:CC FLAGS_REG))])]
8594 "operands[0] = gen_lowpart (SImode, operands[0]);")
8596 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8597 (define_insn "*andsi_1_zext"
8598 [(set (match_operand:DI 0 "register_operand" "=r")
8600 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8601 (match_operand:SI 2 "general_operand" "g"))))
8602 (clobber (reg:CC FLAGS_REG))]
8603 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8604 "and{l}\t{%2, %k0|%k0, %2}"
8605 [(set_attr "type" "alu")
8606 (set_attr "mode" "SI")])
8608 (define_insn "*andsi_2"
8609 [(set (reg FLAGS_REG)
8610 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8611 (match_operand:SI 2 "general_operand" "g,ri"))
8613 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
8614 (and:SI (match_dup 1) (match_dup 2)))]
8615 "ix86_match_ccmode (insn, CCNOmode)
8616 && ix86_binary_operator_ok (AND, SImode, operands)"
8617 "and{l}\t{%2, %0|%0, %2}"
8618 [(set_attr "type" "alu")
8619 (set_attr "mode" "SI")])
8621 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8622 (define_insn "*andsi_2_zext"
8623 [(set (reg FLAGS_REG)
8624 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8625 (match_operand:SI 2 "general_operand" "g"))
8627 (set (match_operand:DI 0 "register_operand" "=r")
8628 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8629 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8630 && ix86_binary_operator_ok (AND, SImode, operands)"
8631 "and{l}\t{%2, %k0|%k0, %2}"
8632 [(set_attr "type" "alu")
8633 (set_attr "mode" "SI")])
8635 (define_expand "andhi3"
8636 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8637 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
8638 (match_operand:HI 2 "general_operand" "")))]
8639 "TARGET_HIMODE_MATH"
8640 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
8642 (define_insn "*andhi_1"
8643 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8644 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8645 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8646 (clobber (reg:CC FLAGS_REG))]
8647 "ix86_binary_operator_ok (AND, HImode, operands)"
8649 switch (get_attr_type (insn))
8652 gcc_assert (CONST_INT_P (operands[2]));
8653 gcc_assert (INTVAL (operands[2]) == 0xff);
8654 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8657 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8659 return "and{w}\t{%2, %0|%0, %2}";
8662 [(set_attr "type" "alu,alu,imovx")
8663 (set_attr "length_immediate" "*,*,0")
8664 (set (attr "prefix_rex")
8666 (and (eq_attr "type" "imovx")
8667 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8669 (const_string "*")))
8670 (set_attr "mode" "HI,HI,SI")])
8672 (define_insn "*andhi_2"
8673 [(set (reg FLAGS_REG)
8674 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
8675 (match_operand:HI 2 "general_operand" "rmn,rn"))
8677 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
8678 (and:HI (match_dup 1) (match_dup 2)))]
8679 "ix86_match_ccmode (insn, CCNOmode)
8680 && ix86_binary_operator_ok (AND, HImode, operands)"
8681 "and{w}\t{%2, %0|%0, %2}"
8682 [(set_attr "type" "alu")
8683 (set_attr "mode" "HI")])
8685 (define_expand "andqi3"
8686 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8687 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
8688 (match_operand:QI 2 "general_operand" "")))]
8689 "TARGET_QIMODE_MATH"
8690 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
8692 ;; %%% Potential partial reg stall on alternative 2. What to do?
8693 (define_insn "*andqi_1"
8694 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8695 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8696 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8697 (clobber (reg:CC FLAGS_REG))]
8698 "ix86_binary_operator_ok (AND, QImode, operands)"
8700 and{b}\t{%2, %0|%0, %2}
8701 and{b}\t{%2, %0|%0, %2}
8702 and{l}\t{%k2, %k0|%k0, %k2}"
8703 [(set_attr "type" "alu")
8704 (set_attr "mode" "QI,QI,SI")])
8706 (define_insn "*andqi_1_slp"
8707 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8708 (and:QI (match_dup 0)
8709 (match_operand:QI 1 "general_operand" "qn,qmn")))
8710 (clobber (reg:CC FLAGS_REG))]
8711 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8712 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8713 "and{b}\t{%1, %0|%0, %1}"
8714 [(set_attr "type" "alu1")
8715 (set_attr "mode" "QI")])
8717 (define_insn "*andqi_2_maybe_si"
8718 [(set (reg FLAGS_REG)
8720 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8721 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8723 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8724 (and:QI (match_dup 1) (match_dup 2)))]
8725 "ix86_binary_operator_ok (AND, QImode, operands)
8726 && ix86_match_ccmode (insn,
8727 CONST_INT_P (operands[2])
8728 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8730 if (which_alternative == 2)
8732 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8733 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8734 return "and{l}\t{%2, %k0|%k0, %2}";
8736 return "and{b}\t{%2, %0|%0, %2}";
8738 [(set_attr "type" "alu")
8739 (set_attr "mode" "QI,QI,SI")])
8741 (define_insn "*andqi_2"
8742 [(set (reg FLAGS_REG)
8744 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
8745 (match_operand:QI 2 "general_operand" "qmn,qn"))
8747 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
8748 (and:QI (match_dup 1) (match_dup 2)))]
8749 "ix86_match_ccmode (insn, CCNOmode)
8750 && ix86_binary_operator_ok (AND, QImode, operands)"
8751 "and{b}\t{%2, %0|%0, %2}"
8752 [(set_attr "type" "alu")
8753 (set_attr "mode" "QI")])
8755 (define_insn "*andqi_2_slp"
8756 [(set (reg FLAGS_REG)
8758 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8759 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8761 (set (strict_low_part (match_dup 0))
8762 (and:QI (match_dup 0) (match_dup 1)))]
8763 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8764 && ix86_match_ccmode (insn, CCNOmode)
8765 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8766 "and{b}\t{%1, %0|%0, %1}"
8767 [(set_attr "type" "alu1")
8768 (set_attr "mode" "QI")])
8770 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8771 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8772 ;; for a QImode operand, which of course failed.
8774 (define_insn "andqi_ext_0"
8775 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8780 (match_operand 1 "ext_register_operand" "0")
8783 (match_operand 2 "const_int_operand" "n")))
8784 (clobber (reg:CC FLAGS_REG))]
8786 "and{b}\t{%2, %h0|%h0, %2}"
8787 [(set_attr "type" "alu")
8788 (set_attr "length_immediate" "1")
8789 (set_attr "modrm" "1")
8790 (set_attr "mode" "QI")])
8792 ;; Generated by peephole translating test to and. This shows up
8793 ;; often in fp comparisons.
8795 (define_insn "*andqi_ext_0_cc"
8796 [(set (reg FLAGS_REG)
8800 (match_operand 1 "ext_register_operand" "0")
8803 (match_operand 2 "const_int_operand" "n"))
8805 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8814 "ix86_match_ccmode (insn, CCNOmode)"
8815 "and{b}\t{%2, %h0|%h0, %2}"
8816 [(set_attr "type" "alu")
8817 (set_attr "length_immediate" "1")
8818 (set_attr "modrm" "1")
8819 (set_attr "mode" "QI")])
8821 (define_insn "*andqi_ext_1"
8822 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8827 (match_operand 1 "ext_register_operand" "0")
8831 (match_operand:QI 2 "general_operand" "Qm"))))
8832 (clobber (reg:CC FLAGS_REG))]
8834 "and{b}\t{%2, %h0|%h0, %2}"
8835 [(set_attr "type" "alu")
8836 (set_attr "length_immediate" "0")
8837 (set_attr "mode" "QI")])
8839 (define_insn "*andqi_ext_1_rex64"
8840 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8845 (match_operand 1 "ext_register_operand" "0")
8849 (match_operand 2 "ext_register_operand" "Q"))))
8850 (clobber (reg:CC FLAGS_REG))]
8852 "and{b}\t{%2, %h0|%h0, %2}"
8853 [(set_attr "type" "alu")
8854 (set_attr "length_immediate" "0")
8855 (set_attr "mode" "QI")])
8857 (define_insn "*andqi_ext_2"
8858 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8863 (match_operand 1 "ext_register_operand" "%0")
8867 (match_operand 2 "ext_register_operand" "Q")
8870 (clobber (reg:CC FLAGS_REG))]
8872 "and{b}\t{%h2, %h0|%h0, %h2}"
8873 [(set_attr "type" "alu")
8874 (set_attr "length_immediate" "0")
8875 (set_attr "mode" "QI")])
8877 ;; Convert wide AND instructions with immediate operand to shorter QImode
8878 ;; equivalents when possible.
8879 ;; Don't do the splitting with memory operands, since it introduces risk
8880 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8881 ;; for size, but that can (should?) be handled by generic code instead.
8883 [(set (match_operand 0 "register_operand" "")
8884 (and (match_operand 1 "register_operand" "")
8885 (match_operand 2 "const_int_operand" "")))
8886 (clobber (reg:CC FLAGS_REG))]
8888 && QI_REG_P (operands[0])
8889 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8890 && !(~INTVAL (operands[2]) & ~(255 << 8))
8891 && GET_MODE (operands[0]) != QImode"
8892 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8893 (and:SI (zero_extract:SI (match_dup 1)
8894 (const_int 8) (const_int 8))
8896 (clobber (reg:CC FLAGS_REG))])]
8897 "operands[0] = gen_lowpart (SImode, operands[0]);
8898 operands[1] = gen_lowpart (SImode, operands[1]);
8899 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8901 ;; Since AND can be encoded with sign extended immediate, this is only
8902 ;; profitable when 7th bit is not set.
8904 [(set (match_operand 0 "register_operand" "")
8905 (and (match_operand 1 "general_operand" "")
8906 (match_operand 2 "const_int_operand" "")))
8907 (clobber (reg:CC FLAGS_REG))]
8909 && ANY_QI_REG_P (operands[0])
8910 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8911 && !(~INTVAL (operands[2]) & ~255)
8912 && !(INTVAL (operands[2]) & 128)
8913 && GET_MODE (operands[0]) != QImode"
8914 [(parallel [(set (strict_low_part (match_dup 0))
8915 (and:QI (match_dup 1)
8917 (clobber (reg:CC FLAGS_REG))])]
8918 "operands[0] = gen_lowpart (QImode, operands[0]);
8919 operands[1] = gen_lowpart (QImode, operands[1]);
8920 operands[2] = gen_lowpart (QImode, operands[2]);")
8922 ;; Logical inclusive OR instructions
8924 ;; %%% This used to optimize known byte-wide and operations to memory.
8925 ;; If this is considered useful, it should be done with splitters.
8927 (define_expand "iordi3"
8928 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8929 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
8930 (match_operand:DI 2 "x86_64_general_operand" "")))]
8932 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
8934 (define_insn "*iordi_1_rex64"
8935 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8936 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8937 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
8938 (clobber (reg:CC FLAGS_REG))]
8940 && ix86_binary_operator_ok (IOR, DImode, operands)"
8941 "or{q}\t{%2, %0|%0, %2}"
8942 [(set_attr "type" "alu")
8943 (set_attr "mode" "DI")])
8945 (define_insn "*iordi_2_rex64"
8946 [(set (reg FLAGS_REG)
8947 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
8948 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
8950 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
8951 (ior:DI (match_dup 1) (match_dup 2)))]
8953 && ix86_match_ccmode (insn, CCNOmode)
8954 && ix86_binary_operator_ok (IOR, DImode, operands)"
8955 "or{q}\t{%2, %0|%0, %2}"
8956 [(set_attr "type" "alu")
8957 (set_attr "mode" "DI")])
8959 (define_insn "*iordi_3_rex64"
8960 [(set (reg FLAGS_REG)
8961 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
8962 (match_operand:DI 2 "x86_64_general_operand" "rem"))
8964 (clobber (match_scratch:DI 0 "=r"))]
8966 && ix86_match_ccmode (insn, CCNOmode)
8967 && ix86_binary_operator_ok (IOR, DImode, operands)"
8968 "or{q}\t{%2, %0|%0, %2}"
8969 [(set_attr "type" "alu")
8970 (set_attr "mode" "DI")])
8973 (define_expand "iorsi3"
8974 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8975 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
8976 (match_operand:SI 2 "general_operand" "")))]
8978 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
8980 (define_insn "*iorsi_1"
8981 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8982 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
8983 (match_operand:SI 2 "general_operand" "ri,g")))
8984 (clobber (reg:CC FLAGS_REG))]
8985 "ix86_binary_operator_ok (IOR, SImode, operands)"
8986 "or{l}\t{%2, %0|%0, %2}"
8987 [(set_attr "type" "alu")
8988 (set_attr "mode" "SI")])
8990 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8991 (define_insn "*iorsi_1_zext"
8992 [(set (match_operand:DI 0 "register_operand" "=r")
8994 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8995 (match_operand:SI 2 "general_operand" "g"))))
8996 (clobber (reg:CC FLAGS_REG))]
8997 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
8998 "or{l}\t{%2, %k0|%k0, %2}"
8999 [(set_attr "type" "alu")
9000 (set_attr "mode" "SI")])
9002 (define_insn "*iorsi_1_zext_imm"
9003 [(set (match_operand:DI 0 "register_operand" "=r")
9004 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9005 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9006 (clobber (reg:CC FLAGS_REG))]
9008 "or{l}\t{%2, %k0|%k0, %2}"
9009 [(set_attr "type" "alu")
9010 (set_attr "mode" "SI")])
9012 (define_insn "*iorsi_2"
9013 [(set (reg FLAGS_REG)
9014 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9015 (match_operand:SI 2 "general_operand" "g,ri"))
9017 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9018 (ior:SI (match_dup 1) (match_dup 2)))]
9019 "ix86_match_ccmode (insn, CCNOmode)
9020 && ix86_binary_operator_ok (IOR, SImode, operands)"
9021 "or{l}\t{%2, %0|%0, %2}"
9022 [(set_attr "type" "alu")
9023 (set_attr "mode" "SI")])
9025 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9026 ;; ??? Special case for immediate operand is missing - it is tricky.
9027 (define_insn "*iorsi_2_zext"
9028 [(set (reg FLAGS_REG)
9029 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9030 (match_operand:SI 2 "general_operand" "g"))
9032 (set (match_operand:DI 0 "register_operand" "=r")
9033 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
9034 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9035 && ix86_binary_operator_ok (IOR, SImode, operands)"
9036 "or{l}\t{%2, %k0|%k0, %2}"
9037 [(set_attr "type" "alu")
9038 (set_attr "mode" "SI")])
9040 (define_insn "*iorsi_2_zext_imm"
9041 [(set (reg FLAGS_REG)
9042 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9043 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9045 (set (match_operand:DI 0 "register_operand" "=r")
9046 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9047 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9048 && ix86_binary_operator_ok (IOR, SImode, operands)"
9049 "or{l}\t{%2, %k0|%k0, %2}"
9050 [(set_attr "type" "alu")
9051 (set_attr "mode" "SI")])
9053 (define_insn "*iorsi_3"
9054 [(set (reg FLAGS_REG)
9055 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9056 (match_operand:SI 2 "general_operand" "g"))
9058 (clobber (match_scratch:SI 0 "=r"))]
9059 "ix86_match_ccmode (insn, CCNOmode)
9060 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9061 "or{l}\t{%2, %0|%0, %2}"
9062 [(set_attr "type" "alu")
9063 (set_attr "mode" "SI")])
9065 (define_expand "iorhi3"
9066 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9067 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
9068 (match_operand:HI 2 "general_operand" "")))]
9069 "TARGET_HIMODE_MATH"
9070 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
9072 (define_insn "*iorhi_1"
9073 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9074 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9075 (match_operand:HI 2 "general_operand" "rmn,rn")))
9076 (clobber (reg:CC FLAGS_REG))]
9077 "ix86_binary_operator_ok (IOR, HImode, operands)"
9078 "or{w}\t{%2, %0|%0, %2}"
9079 [(set_attr "type" "alu")
9080 (set_attr "mode" "HI")])
9082 (define_insn "*iorhi_2"
9083 [(set (reg FLAGS_REG)
9084 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9085 (match_operand:HI 2 "general_operand" "rmn,rn"))
9087 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9088 (ior:HI (match_dup 1) (match_dup 2)))]
9089 "ix86_match_ccmode (insn, CCNOmode)
9090 && ix86_binary_operator_ok (IOR, HImode, operands)"
9091 "or{w}\t{%2, %0|%0, %2}"
9092 [(set_attr "type" "alu")
9093 (set_attr "mode" "HI")])
9095 (define_insn "*iorhi_3"
9096 [(set (reg FLAGS_REG)
9097 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9098 (match_operand:HI 2 "general_operand" "rmn"))
9100 (clobber (match_scratch:HI 0 "=r"))]
9101 "ix86_match_ccmode (insn, CCNOmode)
9102 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9103 "or{w}\t{%2, %0|%0, %2}"
9104 [(set_attr "type" "alu")
9105 (set_attr "mode" "HI")])
9107 (define_expand "iorqi3"
9108 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9109 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
9110 (match_operand:QI 2 "general_operand" "")))]
9111 "TARGET_QIMODE_MATH"
9112 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
9114 ;; %%% Potential partial reg stall on alternative 2. What to do?
9115 (define_insn "*iorqi_1"
9116 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9117 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9118 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9119 (clobber (reg:CC FLAGS_REG))]
9120 "ix86_binary_operator_ok (IOR, QImode, operands)"
9122 or{b}\t{%2, %0|%0, %2}
9123 or{b}\t{%2, %0|%0, %2}
9124 or{l}\t{%k2, %k0|%k0, %k2}"
9125 [(set_attr "type" "alu")
9126 (set_attr "mode" "QI,QI,SI")])
9128 (define_insn "*iorqi_1_slp"
9129 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
9130 (ior:QI (match_dup 0)
9131 (match_operand:QI 1 "general_operand" "qmn,qn")))
9132 (clobber (reg:CC FLAGS_REG))]
9133 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9134 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9135 "or{b}\t{%1, %0|%0, %1}"
9136 [(set_attr "type" "alu1")
9137 (set_attr "mode" "QI")])
9139 (define_insn "*iorqi_2"
9140 [(set (reg FLAGS_REG)
9141 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9142 (match_operand:QI 2 "general_operand" "qmn,qn"))
9144 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9145 (ior:QI (match_dup 1) (match_dup 2)))]
9146 "ix86_match_ccmode (insn, CCNOmode)
9147 && ix86_binary_operator_ok (IOR, QImode, operands)"
9148 "or{b}\t{%2, %0|%0, %2}"
9149 [(set_attr "type" "alu")
9150 (set_attr "mode" "QI")])
9152 (define_insn "*iorqi_2_slp"
9153 [(set (reg FLAGS_REG)
9154 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9155 (match_operand:QI 1 "general_operand" "qmn,qn"))
9157 (set (strict_low_part (match_dup 0))
9158 (ior:QI (match_dup 0) (match_dup 1)))]
9159 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9160 && ix86_match_ccmode (insn, CCNOmode)
9161 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9162 "or{b}\t{%1, %0|%0, %1}"
9163 [(set_attr "type" "alu1")
9164 (set_attr "mode" "QI")])
9166 (define_insn "*iorqi_3"
9167 [(set (reg FLAGS_REG)
9168 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9169 (match_operand:QI 2 "general_operand" "qmn"))
9171 (clobber (match_scratch:QI 0 "=q"))]
9172 "ix86_match_ccmode (insn, CCNOmode)
9173 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9174 "or{b}\t{%2, %0|%0, %2}"
9175 [(set_attr "type" "alu")
9176 (set_attr "mode" "QI")])
9178 (define_insn "*iorqi_ext_0"
9179 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9184 (match_operand 1 "ext_register_operand" "0")
9187 (match_operand 2 "const_int_operand" "n")))
9188 (clobber (reg:CC FLAGS_REG))]
9189 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9190 "or{b}\t{%2, %h0|%h0, %2}"
9191 [(set_attr "type" "alu")
9192 (set_attr "length_immediate" "1")
9193 (set_attr "modrm" "1")
9194 (set_attr "mode" "QI")])
9196 (define_insn "*iorqi_ext_1"
9197 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9202 (match_operand 1 "ext_register_operand" "0")
9206 (match_operand:QI 2 "general_operand" "Qm"))))
9207 (clobber (reg:CC FLAGS_REG))]
9209 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9210 "or{b}\t{%2, %h0|%h0, %2}"
9211 [(set_attr "type" "alu")
9212 (set_attr "length_immediate" "0")
9213 (set_attr "mode" "QI")])
9215 (define_insn "*iorqi_ext_1_rex64"
9216 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9221 (match_operand 1 "ext_register_operand" "0")
9225 (match_operand 2 "ext_register_operand" "Q"))))
9226 (clobber (reg:CC FLAGS_REG))]
9228 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9229 "or{b}\t{%2, %h0|%h0, %2}"
9230 [(set_attr "type" "alu")
9231 (set_attr "length_immediate" "0")
9232 (set_attr "mode" "QI")])
9234 (define_insn "*iorqi_ext_2"
9235 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9239 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9242 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9245 (clobber (reg:CC FLAGS_REG))]
9246 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9247 "ior{b}\t{%h2, %h0|%h0, %h2}"
9248 [(set_attr "type" "alu")
9249 (set_attr "length_immediate" "0")
9250 (set_attr "mode" "QI")])
9253 [(set (match_operand 0 "register_operand" "")
9254 (ior (match_operand 1 "register_operand" "")
9255 (match_operand 2 "const_int_operand" "")))
9256 (clobber (reg:CC FLAGS_REG))]
9258 && QI_REG_P (operands[0])
9259 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9260 && !(INTVAL (operands[2]) & ~(255 << 8))
9261 && GET_MODE (operands[0]) != QImode"
9262 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9263 (ior:SI (zero_extract:SI (match_dup 1)
9264 (const_int 8) (const_int 8))
9266 (clobber (reg:CC FLAGS_REG))])]
9267 "operands[0] = gen_lowpart (SImode, operands[0]);
9268 operands[1] = gen_lowpart (SImode, operands[1]);
9269 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9271 ;; Since OR can be encoded with sign extended immediate, this is only
9272 ;; profitable when 7th bit is set.
9274 [(set (match_operand 0 "register_operand" "")
9275 (ior (match_operand 1 "general_operand" "")
9276 (match_operand 2 "const_int_operand" "")))
9277 (clobber (reg:CC FLAGS_REG))]
9279 && ANY_QI_REG_P (operands[0])
9280 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9281 && !(INTVAL (operands[2]) & ~255)
9282 && (INTVAL (operands[2]) & 128)
9283 && GET_MODE (operands[0]) != QImode"
9284 [(parallel [(set (strict_low_part (match_dup 0))
9285 (ior:QI (match_dup 1)
9287 (clobber (reg:CC FLAGS_REG))])]
9288 "operands[0] = gen_lowpart (QImode, operands[0]);
9289 operands[1] = gen_lowpart (QImode, operands[1]);
9290 operands[2] = gen_lowpart (QImode, operands[2]);")
9292 ;; Logical XOR instructions
9294 ;; %%% This used to optimize known byte-wide and operations to memory.
9295 ;; If this is considered useful, it should be done with splitters.
9297 (define_expand "xordi3"
9298 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9299 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
9300 (match_operand:DI 2 "x86_64_general_operand" "")))]
9302 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
9304 (define_insn "*xordi_1_rex64"
9305 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9306 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9307 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
9308 (clobber (reg:CC FLAGS_REG))]
9310 && ix86_binary_operator_ok (XOR, DImode, operands)"
9311 "xor{q}\t{%2, %0|%0, %2}"
9312 [(set_attr "type" "alu")
9313 (set_attr "mode" "DI")])
9315 (define_insn "*xordi_2_rex64"
9316 [(set (reg FLAGS_REG)
9317 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
9318 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
9320 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
9321 (xor:DI (match_dup 1) (match_dup 2)))]
9323 && ix86_match_ccmode (insn, CCNOmode)
9324 && ix86_binary_operator_ok (XOR, DImode, operands)"
9325 "xor{q}\t{%2, %0|%0, %2}"
9326 [(set_attr "type" "alu")
9327 (set_attr "mode" "DI")])
9329 (define_insn "*xordi_3_rex64"
9330 [(set (reg FLAGS_REG)
9331 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
9332 (match_operand:DI 2 "x86_64_general_operand" "rem"))
9334 (clobber (match_scratch:DI 0 "=r"))]
9336 && ix86_match_ccmode (insn, CCNOmode)
9337 && ix86_binary_operator_ok (XOR, DImode, operands)"
9338 "xor{q}\t{%2, %0|%0, %2}"
9339 [(set_attr "type" "alu")
9340 (set_attr "mode" "DI")])
9342 (define_expand "xorsi3"
9343 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9344 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
9345 (match_operand:SI 2 "general_operand" "")))]
9347 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
9349 (define_insn "*xorsi_1"
9350 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9351 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9352 (match_operand:SI 2 "general_operand" "ri,rm")))
9353 (clobber (reg:CC FLAGS_REG))]
9354 "ix86_binary_operator_ok (XOR, SImode, operands)"
9355 "xor{l}\t{%2, %0|%0, %2}"
9356 [(set_attr "type" "alu")
9357 (set_attr "mode" "SI")])
9359 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9360 ;; Add speccase for immediates
9361 (define_insn "*xorsi_1_zext"
9362 [(set (match_operand:DI 0 "register_operand" "=r")
9364 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9365 (match_operand:SI 2 "general_operand" "g"))))
9366 (clobber (reg:CC FLAGS_REG))]
9367 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9368 "xor{l}\t{%2, %k0|%k0, %2}"
9369 [(set_attr "type" "alu")
9370 (set_attr "mode" "SI")])
9372 (define_insn "*xorsi_1_zext_imm"
9373 [(set (match_operand:DI 0 "register_operand" "=r")
9374 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
9375 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
9376 (clobber (reg:CC FLAGS_REG))]
9377 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
9378 "xor{l}\t{%2, %k0|%k0, %2}"
9379 [(set_attr "type" "alu")
9380 (set_attr "mode" "SI")])
9382 (define_insn "*xorsi_2"
9383 [(set (reg FLAGS_REG)
9384 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9385 (match_operand:SI 2 "general_operand" "g,ri"))
9387 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9388 (xor:SI (match_dup 1) (match_dup 2)))]
9389 "ix86_match_ccmode (insn, CCNOmode)
9390 && ix86_binary_operator_ok (XOR, SImode, operands)"
9391 "xor{l}\t{%2, %0|%0, %2}"
9392 [(set_attr "type" "alu")
9393 (set_attr "mode" "SI")])
9395 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9396 ;; ??? Special case for immediate operand is missing - it is tricky.
9397 (define_insn "*xorsi_2_zext"
9398 [(set (reg FLAGS_REG)
9399 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9400 (match_operand:SI 2 "general_operand" "g"))
9402 (set (match_operand:DI 0 "register_operand" "=r")
9403 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
9404 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9405 && ix86_binary_operator_ok (XOR, SImode, operands)"
9406 "xor{l}\t{%2, %k0|%k0, %2}"
9407 [(set_attr "type" "alu")
9408 (set_attr "mode" "SI")])
9410 (define_insn "*xorsi_2_zext_imm"
9411 [(set (reg FLAGS_REG)
9412 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9413 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
9415 (set (match_operand:DI 0 "register_operand" "=r")
9416 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
9417 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9418 && ix86_binary_operator_ok (XOR, SImode, operands)"
9419 "xor{l}\t{%2, %k0|%k0, %2}"
9420 [(set_attr "type" "alu")
9421 (set_attr "mode" "SI")])
9423 (define_insn "*xorsi_3"
9424 [(set (reg FLAGS_REG)
9425 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9426 (match_operand:SI 2 "general_operand" "g"))
9428 (clobber (match_scratch:SI 0 "=r"))]
9429 "ix86_match_ccmode (insn, CCNOmode)
9430 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9431 "xor{l}\t{%2, %0|%0, %2}"
9432 [(set_attr "type" "alu")
9433 (set_attr "mode" "SI")])
9435 (define_expand "xorhi3"
9436 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9437 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
9438 (match_operand:HI 2 "general_operand" "")))]
9439 "TARGET_HIMODE_MATH"
9440 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
9442 (define_insn "*xorhi_1"
9443 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
9444 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9445 (match_operand:HI 2 "general_operand" "rmn,rn")))
9446 (clobber (reg:CC FLAGS_REG))]
9447 "ix86_binary_operator_ok (XOR, HImode, operands)"
9448 "xor{w}\t{%2, %0|%0, %2}"
9449 [(set_attr "type" "alu")
9450 (set_attr "mode" "HI")])
9452 (define_insn "*xorhi_2"
9453 [(set (reg FLAGS_REG)
9454 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9455 (match_operand:HI 2 "general_operand" "rmn,rn"))
9457 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9458 (xor:HI (match_dup 1) (match_dup 2)))]
9459 "ix86_match_ccmode (insn, CCNOmode)
9460 && ix86_binary_operator_ok (XOR, HImode, operands)"
9461 "xor{w}\t{%2, %0|%0, %2}"
9462 [(set_attr "type" "alu")
9463 (set_attr "mode" "HI")])
9465 (define_insn "*xorhi_3"
9466 [(set (reg FLAGS_REG)
9467 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
9468 (match_operand:HI 2 "general_operand" "rmn"))
9470 (clobber (match_scratch:HI 0 "=r"))]
9471 "ix86_match_ccmode (insn, CCNOmode)
9472 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9473 "xor{w}\t{%2, %0|%0, %2}"
9474 [(set_attr "type" "alu")
9475 (set_attr "mode" "HI")])
9477 (define_expand "xorqi3"
9478 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9479 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
9480 (match_operand:QI 2 "general_operand" "")))]
9481 "TARGET_QIMODE_MATH"
9482 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
9484 ;; %%% Potential partial reg stall on alternative 2. What to do?
9485 (define_insn "*xorqi_1"
9486 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
9487 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9488 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
9489 (clobber (reg:CC FLAGS_REG))]
9490 "ix86_binary_operator_ok (XOR, QImode, operands)"
9492 xor{b}\t{%2, %0|%0, %2}
9493 xor{b}\t{%2, %0|%0, %2}
9494 xor{l}\t{%k2, %k0|%k0, %k2}"
9495 [(set_attr "type" "alu")
9496 (set_attr "mode" "QI,QI,SI")])
9498 (define_insn "*xorqi_1_slp"
9499 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9500 (xor:QI (match_dup 0)
9501 (match_operand:QI 1 "general_operand" "qn,qmn")))
9502 (clobber (reg:CC FLAGS_REG))]
9503 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9504 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9505 "xor{b}\t{%1, %0|%0, %1}"
9506 [(set_attr "type" "alu1")
9507 (set_attr "mode" "QI")])
9509 (define_insn "*xorqi_ext_0"
9510 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9515 (match_operand 1 "ext_register_operand" "0")
9518 (match_operand 2 "const_int_operand" "n")))
9519 (clobber (reg:CC FLAGS_REG))]
9520 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9521 "xor{b}\t{%2, %h0|%h0, %2}"
9522 [(set_attr "type" "alu")
9523 (set_attr "length_immediate" "1")
9524 (set_attr "modrm" "1")
9525 (set_attr "mode" "QI")])
9527 (define_insn "*xorqi_ext_1"
9528 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9533 (match_operand 1 "ext_register_operand" "0")
9537 (match_operand:QI 2 "general_operand" "Qm"))))
9538 (clobber (reg:CC FLAGS_REG))]
9540 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9541 "xor{b}\t{%2, %h0|%h0, %2}"
9542 [(set_attr "type" "alu")
9543 (set_attr "length_immediate" "0")
9544 (set_attr "mode" "QI")])
9546 (define_insn "*xorqi_ext_1_rex64"
9547 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9552 (match_operand 1 "ext_register_operand" "0")
9556 (match_operand 2 "ext_register_operand" "Q"))))
9557 (clobber (reg:CC FLAGS_REG))]
9559 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9560 "xor{b}\t{%2, %h0|%h0, %2}"
9561 [(set_attr "type" "alu")
9562 (set_attr "length_immediate" "0")
9563 (set_attr "mode" "QI")])
9565 (define_insn "*xorqi_ext_2"
9566 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9570 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
9573 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
9576 (clobber (reg:CC FLAGS_REG))]
9577 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
9578 "xor{b}\t{%h2, %h0|%h0, %h2}"
9579 [(set_attr "type" "alu")
9580 (set_attr "length_immediate" "0")
9581 (set_attr "mode" "QI")])
9583 (define_insn "*xorqi_cc_1"
9584 [(set (reg FLAGS_REG)
9586 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9587 (match_operand:QI 2 "general_operand" "qmn,qn"))
9589 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9590 (xor:QI (match_dup 1) (match_dup 2)))]
9591 "ix86_match_ccmode (insn, CCNOmode)
9592 && ix86_binary_operator_ok (XOR, QImode, operands)"
9593 "xor{b}\t{%2, %0|%0, %2}"
9594 [(set_attr "type" "alu")
9595 (set_attr "mode" "QI")])
9597 (define_insn "*xorqi_2_slp"
9598 [(set (reg FLAGS_REG)
9599 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9600 (match_operand:QI 1 "general_operand" "qmn,qn"))
9602 (set (strict_low_part (match_dup 0))
9603 (xor:QI (match_dup 0) (match_dup 1)))]
9604 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9605 && ix86_match_ccmode (insn, CCNOmode)
9606 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9607 "xor{b}\t{%1, %0|%0, %1}"
9608 [(set_attr "type" "alu1")
9609 (set_attr "mode" "QI")])
9611 (define_insn "*xorqi_cc_2"
9612 [(set (reg FLAGS_REG)
9614 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
9615 (match_operand:QI 2 "general_operand" "qmn"))
9617 (clobber (match_scratch:QI 0 "=q"))]
9618 "ix86_match_ccmode (insn, CCNOmode)
9619 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
9620 "xor{b}\t{%2, %0|%0, %2}"
9621 [(set_attr "type" "alu")
9622 (set_attr "mode" "QI")])
9624 (define_insn "*xorqi_cc_ext_1"
9625 [(set (reg FLAGS_REG)
9629 (match_operand 1 "ext_register_operand" "0")
9632 (match_operand:QI 2 "general_operand" "qmn"))
9634 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9638 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9640 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9641 "xor{b}\t{%2, %h0|%h0, %2}"
9642 [(set_attr "type" "alu")
9643 (set_attr "modrm" "1")
9644 (set_attr "mode" "QI")])
9646 (define_insn "*xorqi_cc_ext_1_rex64"
9647 [(set (reg FLAGS_REG)
9651 (match_operand 1 "ext_register_operand" "0")
9654 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9656 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9660 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9662 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9663 "xor{b}\t{%2, %h0|%h0, %2}"
9664 [(set_attr "type" "alu")
9665 (set_attr "modrm" "1")
9666 (set_attr "mode" "QI")])
9668 (define_expand "xorqi_cc_ext_1"
9670 (set (reg:CCNO FLAGS_REG)
9674 (match_operand 1 "ext_register_operand" "")
9677 (match_operand:QI 2 "general_operand" ""))
9679 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
9683 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
9689 [(set (match_operand 0 "register_operand" "")
9690 (xor (match_operand 1 "register_operand" "")
9691 (match_operand 2 "const_int_operand" "")))
9692 (clobber (reg:CC FLAGS_REG))]
9694 && QI_REG_P (operands[0])
9695 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9696 && !(INTVAL (operands[2]) & ~(255 << 8))
9697 && GET_MODE (operands[0]) != QImode"
9698 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
9699 (xor:SI (zero_extract:SI (match_dup 1)
9700 (const_int 8) (const_int 8))
9702 (clobber (reg:CC FLAGS_REG))])]
9703 "operands[0] = gen_lowpart (SImode, operands[0]);
9704 operands[1] = gen_lowpart (SImode, operands[1]);
9705 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
9707 ;; Since XOR can be encoded with sign extended immediate, this is only
9708 ;; profitable when 7th bit is set.
9710 [(set (match_operand 0 "register_operand" "")
9711 (xor (match_operand 1 "general_operand" "")
9712 (match_operand 2 "const_int_operand" "")))
9713 (clobber (reg:CC FLAGS_REG))]
9715 && ANY_QI_REG_P (operands[0])
9716 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9717 && !(INTVAL (operands[2]) & ~255)
9718 && (INTVAL (operands[2]) & 128)
9719 && GET_MODE (operands[0]) != QImode"
9720 [(parallel [(set (strict_low_part (match_dup 0))
9721 (xor:QI (match_dup 1)
9723 (clobber (reg:CC FLAGS_REG))])]
9724 "operands[0] = gen_lowpart (QImode, operands[0]);
9725 operands[1] = gen_lowpart (QImode, operands[1]);
9726 operands[2] = gen_lowpart (QImode, operands[2]);")
9728 ;; Negation instructions
9730 (define_expand "neg<mode>2"
9731 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9732 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9734 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9736 (define_insn_and_split "*neg<dwi>2_doubleword"
9737 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9738 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9739 (clobber (reg:CC FLAGS_REG))]
9740 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9744 [(set (reg:CCZ FLAGS_REG)
9745 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9746 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9749 (plus:DWIH (match_dup 3)
9750 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9752 (clobber (reg:CC FLAGS_REG))])
9755 (neg:DWIH (match_dup 2)))
9756 (clobber (reg:CC FLAGS_REG))])]
9757 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9759 (define_insn "*neg<mode>2_1"
9760 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9761 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9762 (clobber (reg:CC FLAGS_REG))]
9763 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9764 "neg{<imodesuffix>}\t%0"
9765 [(set_attr "type" "negnot")
9766 (set_attr "mode" "<MODE>")])
9768 ;; Combine is quite creative about this pattern.
9769 (define_insn "*negsi2_1_zext"
9770 [(set (match_operand:DI 0 "register_operand" "=r")
9772 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9775 (clobber (reg:CC FLAGS_REG))]
9776 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9778 [(set_attr "type" "negnot")
9779 (set_attr "mode" "SI")])
9781 ;; The problem with neg is that it does not perform (compare x 0),
9782 ;; it really performs (compare 0 x), which leaves us with the zero
9783 ;; flag being the only useful item.
9785 (define_insn "*neg<mode>2_cmpz"
9786 [(set (reg:CCZ FLAGS_REG)
9788 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9790 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9791 (neg:SWI (match_dup 1)))]
9792 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9793 "neg{<imodesuffix>}\t%0"
9794 [(set_attr "type" "negnot")
9795 (set_attr "mode" "<MODE>")])
9797 (define_insn "*negsi2_cmpz_zext"
9798 [(set (reg:CCZ FLAGS_REG)
9802 (match_operand:DI 1 "register_operand" "0")
9806 (set (match_operand:DI 0 "register_operand" "=r")
9807 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9810 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9812 [(set_attr "type" "negnot")
9813 (set_attr "mode" "SI")])
9815 ;; Changing of sign for FP values is doable using integer unit too.
9817 (define_expand "<code><mode>2"
9818 [(set (match_operand:X87MODEF 0 "register_operand" "")
9819 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9820 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9821 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9823 (define_insn "*absneg<mode>2_mixed"
9824 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9825 (match_operator:MODEF 3 "absneg_operator"
9826 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9827 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9828 (clobber (reg:CC FLAGS_REG))]
9829 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9832 (define_insn "*absneg<mode>2_sse"
9833 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9834 (match_operator:MODEF 3 "absneg_operator"
9835 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9836 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9837 (clobber (reg:CC FLAGS_REG))]
9838 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9841 (define_insn "*absneg<mode>2_i387"
9842 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9843 (match_operator:X87MODEF 3 "absneg_operator"
9844 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9845 (use (match_operand 2 "" ""))
9846 (clobber (reg:CC FLAGS_REG))]
9847 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9850 (define_expand "<code>tf2"
9851 [(set (match_operand:TF 0 "register_operand" "")
9852 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9854 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9856 (define_insn "*absnegtf2_sse"
9857 [(set (match_operand:TF 0 "register_operand" "=x,x")
9858 (match_operator:TF 3 "absneg_operator"
9859 [(match_operand:TF 1 "register_operand" "0,x")]))
9860 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9861 (clobber (reg:CC FLAGS_REG))]
9865 ;; Splitters for fp abs and neg.
9868 [(set (match_operand 0 "fp_register_operand" "")
9869 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9870 (use (match_operand 2 "" ""))
9871 (clobber (reg:CC FLAGS_REG))]
9873 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9876 [(set (match_operand 0 "register_operand" "")
9877 (match_operator 3 "absneg_operator"
9878 [(match_operand 1 "register_operand" "")]))
9879 (use (match_operand 2 "nonimmediate_operand" ""))
9880 (clobber (reg:CC FLAGS_REG))]
9881 "reload_completed && SSE_REG_P (operands[0])"
9882 [(set (match_dup 0) (match_dup 3))]
9884 enum machine_mode mode = GET_MODE (operands[0]);
9885 enum machine_mode vmode = GET_MODE (operands[2]);
9888 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9889 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9890 if (operands_match_p (operands[0], operands[2]))
9893 operands[1] = operands[2];
9896 if (GET_CODE (operands[3]) == ABS)
9897 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9899 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9904 [(set (match_operand:SF 0 "register_operand" "")
9905 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9906 (use (match_operand:V4SF 2 "" ""))
9907 (clobber (reg:CC FLAGS_REG))]
9909 [(parallel [(set (match_dup 0) (match_dup 1))
9910 (clobber (reg:CC FLAGS_REG))])]
9913 operands[0] = gen_lowpart (SImode, operands[0]);
9914 if (GET_CODE (operands[1]) == ABS)
9916 tmp = gen_int_mode (0x7fffffff, SImode);
9917 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9921 tmp = gen_int_mode (0x80000000, SImode);
9922 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9928 [(set (match_operand:DF 0 "register_operand" "")
9929 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9930 (use (match_operand 2 "" ""))
9931 (clobber (reg:CC FLAGS_REG))]
9933 [(parallel [(set (match_dup 0) (match_dup 1))
9934 (clobber (reg:CC FLAGS_REG))])]
9939 tmp = gen_lowpart (DImode, operands[0]);
9940 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9943 if (GET_CODE (operands[1]) == ABS)
9946 tmp = gen_rtx_NOT (DImode, tmp);
9950 operands[0] = gen_highpart (SImode, operands[0]);
9951 if (GET_CODE (operands[1]) == ABS)
9953 tmp = gen_int_mode (0x7fffffff, SImode);
9954 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9958 tmp = gen_int_mode (0x80000000, SImode);
9959 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9966 [(set (match_operand:XF 0 "register_operand" "")
9967 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9968 (use (match_operand 2 "" ""))
9969 (clobber (reg:CC FLAGS_REG))]
9971 [(parallel [(set (match_dup 0) (match_dup 1))
9972 (clobber (reg:CC FLAGS_REG))])]
9975 operands[0] = gen_rtx_REG (SImode,
9976 true_regnum (operands[0])
9977 + (TARGET_64BIT ? 1 : 2));
9978 if (GET_CODE (operands[1]) == ABS)
9980 tmp = GEN_INT (0x7fff);
9981 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9985 tmp = GEN_INT (0x8000);
9986 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9991 ;; Conditionalize these after reload. If they match before reload, we
9992 ;; lose the clobber and ability to use integer instructions.
9994 (define_insn "*<code><mode>2_1"
9995 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9996 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9998 && (reload_completed
9999 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
10001 [(set_attr "type" "fsgn")
10002 (set_attr "mode" "<MODE>")])
10004 (define_insn "*<code>extendsfdf2"
10005 [(set (match_operand:DF 0 "register_operand" "=f")
10006 (absneg:DF (float_extend:DF
10007 (match_operand:SF 1 "register_operand" "0"))))]
10008 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
10010 [(set_attr "type" "fsgn")
10011 (set_attr "mode" "DF")])
10013 (define_insn "*<code>extendsfxf2"
10014 [(set (match_operand:XF 0 "register_operand" "=f")
10015 (absneg:XF (float_extend:XF
10016 (match_operand:SF 1 "register_operand" "0"))))]
10019 [(set_attr "type" "fsgn")
10020 (set_attr "mode" "XF")])
10022 (define_insn "*<code>extenddfxf2"
10023 [(set (match_operand:XF 0 "register_operand" "=f")
10024 (absneg:XF (float_extend:XF
10025 (match_operand:DF 1 "register_operand" "0"))))]
10028 [(set_attr "type" "fsgn")
10029 (set_attr "mode" "XF")])
10031 ;; Copysign instructions
10033 (define_mode_iterator CSGNMODE [SF DF TF])
10034 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
10036 (define_expand "copysign<mode>3"
10037 [(match_operand:CSGNMODE 0 "register_operand" "")
10038 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
10039 (match_operand:CSGNMODE 2 "register_operand" "")]
10040 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10041 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10043 ix86_expand_copysign (operands);
10047 (define_insn_and_split "copysign<mode>3_const"
10048 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
10050 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
10051 (match_operand:CSGNMODE 2 "register_operand" "0")
10052 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
10054 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10055 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10057 "&& reload_completed"
10060 ix86_split_copysign_const (operands);
10064 (define_insn "copysign<mode>3_var"
10065 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
10067 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
10068 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
10069 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
10070 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
10072 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
10073 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10074 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
10078 [(set (match_operand:CSGNMODE 0 "register_operand" "")
10080 [(match_operand:CSGNMODE 2 "register_operand" "")
10081 (match_operand:CSGNMODE 3 "register_operand" "")
10082 (match_operand:<CSGNVMODE> 4 "" "")
10083 (match_operand:<CSGNVMODE> 5 "" "")]
10085 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
10086 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
10087 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
10088 && reload_completed"
10091 ix86_split_copysign_var (operands);
10095 ;; One complement instructions
10097 (define_expand "one_cmpl<mode>2"
10098 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
10099 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
10101 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
10103 (define_insn "*one_cmpl<mode>2_1"
10104 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
10105 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
10106 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10107 "not{<imodesuffix>}\t%0"
10108 [(set_attr "type" "negnot")
10109 (set_attr "mode" "<MODE>")])
10111 ;; %%% Potential partial reg stall on alternative 1. What to do?
10112 (define_insn "*one_cmplqi2_1"
10113 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10114 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
10115 "ix86_unary_operator_ok (NOT, QImode, operands)"
10119 [(set_attr "type" "negnot")
10120 (set_attr "mode" "QI,SI")])
10122 ;; ??? Currently never generated - xor is used instead.
10123 (define_insn "*one_cmplsi2_1_zext"
10124 [(set (match_operand:DI 0 "register_operand" "=r")
10126 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
10127 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
10129 [(set_attr "type" "negnot")
10130 (set_attr "mode" "SI")])
10132 (define_insn "*one_cmpl<mode>2_2"
10133 [(set (reg FLAGS_REG)
10134 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
10136 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
10137 (not:SWI (match_dup 1)))]
10138 "ix86_match_ccmode (insn, CCNOmode)
10139 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
10141 [(set_attr "type" "alu1")
10142 (set_attr "mode" "<MODE>")])
10145 [(set (match_operand 0 "flags_reg_operand" "")
10146 (match_operator 2 "compare_operator"
10147 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
10149 (set (match_operand:SWI 1 "nonimmediate_operand" "")
10150 (not:SWI (match_dup 3)))]
10151 "ix86_match_ccmode (insn, CCNOmode)"
10152 [(parallel [(set (match_dup 0)
10153 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
10156 (xor:SWI (match_dup 3) (const_int -1)))])]
10159 ;; ??? Currently never generated - xor is used instead.
10160 (define_insn "*one_cmplsi2_2_zext"
10161 [(set (reg FLAGS_REG)
10162 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
10164 (set (match_operand:DI 0 "register_operand" "=r")
10165 (zero_extend:DI (not:SI (match_dup 1))))]
10166 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10167 && ix86_unary_operator_ok (NOT, SImode, operands)"
10169 [(set_attr "type" "alu1")
10170 (set_attr "mode" "SI")])
10173 [(set (match_operand 0 "flags_reg_operand" "")
10174 (match_operator 2 "compare_operator"
10175 [(not:SI (match_operand:SI 3 "register_operand" ""))
10177 (set (match_operand:DI 1 "register_operand" "")
10178 (zero_extend:DI (not:SI (match_dup 3))))]
10179 "ix86_match_ccmode (insn, CCNOmode)"
10180 [(parallel [(set (match_dup 0)
10181 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
10184 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
10187 ;; Arithmetic shift instructions
10189 ;; DImode shifts are implemented using the i386 "shift double" opcode,
10190 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
10191 ;; is variable, then the count is in %cl and the "imm" operand is dropped
10192 ;; from the assembler input.
10194 ;; This instruction shifts the target reg/mem as usual, but instead of
10195 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
10196 ;; is a left shift double, bits are taken from the high order bits of
10197 ;; reg, else if the insn is a shift right double, bits are taken from the
10198 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
10199 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
10201 ;; Since sh[lr]d does not change the `reg' operand, that is done
10202 ;; separately, making all shifts emit pairs of shift double and normal
10203 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
10204 ;; support a 63 bit shift, each shift where the count is in a reg expands
10205 ;; to a pair of shifts, a branch, a shift by 32 and a label.
10207 ;; If the shift count is a constant, we need never emit more than one
10208 ;; shift pair, instead using moves and sign extension for counts greater
10211 (define_expand "ashlti3"
10212 [(set (match_operand:TI 0 "register_operand" "")
10213 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
10214 (match_operand:QI 2 "nonmemory_operand" "")))]
10216 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
10218 ;; This pattern must be defined before *ashlti3_1 to prevent
10219 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
10221 (define_insn "*avx_ashlti3"
10222 [(set (match_operand:TI 0 "register_operand" "=x")
10223 (ashift:TI (match_operand:TI 1 "register_operand" "x")
10224 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10227 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10228 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
10230 [(set_attr "type" "sseishft")
10231 (set_attr "prefix" "vex")
10232 (set_attr "length_immediate" "1")
10233 (set_attr "mode" "TI")])
10235 (define_insn "sse2_ashlti3"
10236 [(set (match_operand:TI 0 "register_operand" "=x")
10237 (ashift:TI (match_operand:TI 1 "register_operand" "0")
10238 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
10241 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
10242 return "pslldq\t{%2, %0|%0, %2}";
10244 [(set_attr "type" "sseishft")
10245 (set_attr "prefix_data16" "1")
10246 (set_attr "length_immediate" "1")
10247 (set_attr "mode" "TI")])
10249 (define_insn "*ashlti3_1"
10250 [(set (match_operand:TI 0 "register_operand" "=&r,r")
10251 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
10252 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
10253 (clobber (reg:CC FLAGS_REG))]
10256 [(set_attr "type" "multi")])
10259 [(match_scratch:DI 3 "r")
10260 (parallel [(set (match_operand:TI 0 "register_operand" "")
10261 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10262 (match_operand:QI 2 "nonmemory_operand" "")))
10263 (clobber (reg:CC FLAGS_REG))])
10267 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
10270 [(set (match_operand:TI 0 "register_operand" "")
10271 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
10272 (match_operand:QI 2 "nonmemory_operand" "")))
10273 (clobber (reg:CC FLAGS_REG))]
10274 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10275 ? epilogue_completed : reload_completed)"
10277 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
10279 (define_insn "x86_64_shld"
10280 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10281 (ior:DI (ashift:DI (match_dup 0)
10282 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10283 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
10284 (minus:QI (const_int 64) (match_dup 2)))))
10285 (clobber (reg:CC FLAGS_REG))]
10287 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
10288 [(set_attr "type" "ishift")
10289 (set_attr "prefix_0f" "1")
10290 (set_attr "mode" "DI")
10291 (set_attr "athlon_decode" "vector")
10292 (set_attr "amdfam10_decode" "vector")])
10294 (define_expand "x86_64_shift_adj_1"
10295 [(set (reg:CCZ FLAGS_REG)
10296 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10299 (set (match_operand:DI 0 "register_operand" "")
10300 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10301 (match_operand:DI 1 "register_operand" "")
10304 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10305 (match_operand:DI 3 "register_operand" "r")
10310 (define_expand "x86_64_shift_adj_2"
10311 [(use (match_operand:DI 0 "register_operand" ""))
10312 (use (match_operand:DI 1 "register_operand" ""))
10313 (use (match_operand:QI 2 "register_operand" ""))]
10316 rtx label = gen_label_rtx ();
10319 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10321 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10322 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10323 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10324 gen_rtx_LABEL_REF (VOIDmode, label),
10326 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10327 JUMP_LABEL (tmp) = label;
10329 emit_move_insn (operands[0], operands[1]);
10330 ix86_expand_clear (operands[1]);
10332 emit_label (label);
10333 LABEL_NUSES (label) = 1;
10338 (define_expand "ashldi3"
10339 [(set (match_operand:DI 0 "shiftdi_operand" "")
10340 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
10341 (match_operand:QI 2 "nonmemory_operand" "")))]
10343 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
10345 (define_insn "*ashldi3_1_rex64"
10346 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10347 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
10348 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
10349 (clobber (reg:CC FLAGS_REG))]
10350 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10352 switch (get_attr_type (insn))
10355 gcc_assert (operands[2] == const1_rtx);
10356 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10357 return "add{q}\t%0, %0";
10360 gcc_assert (CONST_INT_P (operands[2]));
10361 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
10362 operands[1] = gen_rtx_MULT (DImode, operands[1],
10363 GEN_INT (1 << INTVAL (operands[2])));
10364 return "lea{q}\t{%a1, %0|%0, %a1}";
10367 if (REG_P (operands[2]))
10368 return "sal{q}\t{%b2, %0|%0, %b2}";
10369 else if (operands[2] == const1_rtx
10370 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10371 return "sal{q}\t%0";
10373 return "sal{q}\t{%2, %0|%0, %2}";
10376 [(set (attr "type")
10377 (cond [(eq_attr "alternative" "1")
10378 (const_string "lea")
10379 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10381 (match_operand 0 "register_operand" ""))
10382 (match_operand 2 "const1_operand" ""))
10383 (const_string "alu")
10385 (const_string "ishift")))
10386 (set (attr "length_immediate")
10388 (ior (eq_attr "type" "alu")
10389 (and (eq_attr "type" "ishift")
10390 (and (match_operand 2 "const1_operand" "")
10391 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10394 (const_string "*")))
10395 (set_attr "mode" "DI")])
10397 ;; Convert lea to the lea pattern to avoid flags dependency.
10399 [(set (match_operand:DI 0 "register_operand" "")
10400 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
10401 (match_operand:QI 2 "immediate_operand" "")))
10402 (clobber (reg:CC FLAGS_REG))]
10403 "TARGET_64BIT && reload_completed
10404 && true_regnum (operands[0]) != true_regnum (operands[1])"
10405 [(set (match_dup 0)
10406 (mult:DI (match_dup 1)
10408 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
10410 ;; This pattern can't accept a variable shift count, since shifts by
10411 ;; zero don't affect the flags. We assume that shifts by constant
10412 ;; zero are optimized away.
10413 (define_insn "*ashldi3_cmp_rex64"
10414 [(set (reg FLAGS_REG)
10416 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10417 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10419 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10420 (ashift:DI (match_dup 1) (match_dup 2)))]
10422 && (optimize_function_for_size_p (cfun)
10423 || !TARGET_PARTIAL_FLAG_REG_STALL
10424 || (operands[2] == const1_rtx
10426 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10427 && ix86_match_ccmode (insn, CCGOCmode)
10428 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10430 switch (get_attr_type (insn))
10433 gcc_assert (operands[2] == const1_rtx);
10434 return "add{q}\t%0, %0";
10437 if (REG_P (operands[2]))
10438 return "sal{q}\t{%b2, %0|%0, %b2}";
10439 else if (operands[2] == const1_rtx
10440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10441 return "sal{q}\t%0";
10443 return "sal{q}\t{%2, %0|%0, %2}";
10446 [(set (attr "type")
10447 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10449 (match_operand 0 "register_operand" ""))
10450 (match_operand 2 "const1_operand" ""))
10451 (const_string "alu")
10453 (const_string "ishift")))
10454 (set (attr "length_immediate")
10456 (ior (eq_attr "type" "alu")
10457 (and (eq_attr "type" "ishift")
10458 (and (match_operand 2 "const1_operand" "")
10459 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10462 (const_string "*")))
10463 (set_attr "mode" "DI")])
10465 (define_insn "*ashldi3_cconly_rex64"
10466 [(set (reg FLAGS_REG)
10468 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10469 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10471 (clobber (match_scratch:DI 0 "=r"))]
10473 && (optimize_function_for_size_p (cfun)
10474 || !TARGET_PARTIAL_FLAG_REG_STALL
10475 || (operands[2] == const1_rtx
10477 || TARGET_DOUBLE_WITH_ADD)))
10478 && ix86_match_ccmode (insn, CCGOCmode)
10479 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
10481 switch (get_attr_type (insn))
10484 gcc_assert (operands[2] == const1_rtx);
10485 return "add{q}\t%0, %0";
10488 if (REG_P (operands[2]))
10489 return "sal{q}\t{%b2, %0|%0, %b2}";
10490 else if (operands[2] == const1_rtx
10491 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10492 return "sal{q}\t%0";
10494 return "sal{q}\t{%2, %0|%0, %2}";
10497 [(set (attr "type")
10498 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10500 (match_operand 0 "register_operand" ""))
10501 (match_operand 2 "const1_operand" ""))
10502 (const_string "alu")
10504 (const_string "ishift")))
10505 (set (attr "length_immediate")
10507 (ior (eq_attr "type" "alu")
10508 (and (eq_attr "type" "ishift")
10509 (and (match_operand 2 "const1_operand" "")
10510 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10513 (const_string "*")))
10514 (set_attr "mode" "DI")])
10516 (define_insn "*ashldi3_1"
10517 [(set (match_operand:DI 0 "register_operand" "=&r,r")
10518 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
10519 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
10520 (clobber (reg:CC FLAGS_REG))]
10523 [(set_attr "type" "multi")])
10525 ;; By default we don't ask for a scratch register, because when DImode
10526 ;; values are manipulated, registers are already at a premium. But if
10527 ;; we have one handy, we won't turn it away.
10529 [(match_scratch:SI 3 "r")
10530 (parallel [(set (match_operand:DI 0 "register_operand" "")
10531 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10532 (match_operand:QI 2 "nonmemory_operand" "")))
10533 (clobber (reg:CC FLAGS_REG))])
10535 "!TARGET_64BIT && TARGET_CMOVE"
10537 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
10540 [(set (match_operand:DI 0 "register_operand" "")
10541 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
10542 (match_operand:QI 2 "nonmemory_operand" "")))
10543 (clobber (reg:CC FLAGS_REG))]
10544 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10545 ? epilogue_completed : reload_completed)"
10547 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
10549 (define_insn "x86_shld"
10550 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10551 (ior:SI (ashift:SI (match_dup 0)
10552 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10553 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
10554 (minus:QI (const_int 32) (match_dup 2)))))
10555 (clobber (reg:CC FLAGS_REG))]
10557 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
10558 [(set_attr "type" "ishift")
10559 (set_attr "prefix_0f" "1")
10560 (set_attr "mode" "SI")
10561 (set_attr "pent_pair" "np")
10562 (set_attr "athlon_decode" "vector")
10563 (set_attr "amdfam10_decode" "vector")])
10565 (define_expand "x86_shift_adj_1"
10566 [(set (reg:CCZ FLAGS_REG)
10567 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
10570 (set (match_operand:SI 0 "register_operand" "")
10571 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10572 (match_operand:SI 1 "register_operand" "")
10575 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
10576 (match_operand:SI 3 "register_operand" "r")
10581 (define_expand "x86_shift_adj_2"
10582 [(use (match_operand:SI 0 "register_operand" ""))
10583 (use (match_operand:SI 1 "register_operand" ""))
10584 (use (match_operand:QI 2 "register_operand" ""))]
10587 rtx label = gen_label_rtx ();
10590 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10592 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10593 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10594 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10595 gen_rtx_LABEL_REF (VOIDmode, label),
10597 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10598 JUMP_LABEL (tmp) = label;
10600 emit_move_insn (operands[0], operands[1]);
10601 ix86_expand_clear (operands[1]);
10603 emit_label (label);
10604 LABEL_NUSES (label) = 1;
10609 (define_expand "ashlsi3"
10610 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10611 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
10612 (match_operand:QI 2 "nonmemory_operand" "")))]
10614 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
10616 (define_insn "*ashlsi3_1"
10617 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10618 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
10619 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10620 (clobber (reg:CC FLAGS_REG))]
10621 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10623 switch (get_attr_type (insn))
10626 gcc_assert (operands[2] == const1_rtx);
10627 gcc_assert (rtx_equal_p (operands[0], operands[1]));
10628 return "add{l}\t%0, %0";
10634 if (REG_P (operands[2]))
10635 return "sal{l}\t{%b2, %0|%0, %b2}";
10636 else if (operands[2] == const1_rtx
10637 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10638 return "sal{l}\t%0";
10640 return "sal{l}\t{%2, %0|%0, %2}";
10643 [(set (attr "type")
10644 (cond [(eq_attr "alternative" "1")
10645 (const_string "lea")
10646 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10648 (match_operand 0 "register_operand" ""))
10649 (match_operand 2 "const1_operand" ""))
10650 (const_string "alu")
10652 (const_string "ishift")))
10653 (set (attr "length_immediate")
10655 (ior (eq_attr "type" "alu")
10656 (and (eq_attr "type" "ishift")
10657 (and (match_operand 2 "const1_operand" "")
10658 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10661 (const_string "*")))
10662 (set_attr "mode" "SI")])
10664 ;; Convert lea to the lea pattern to avoid flags dependency.
10666 [(set (match_operand 0 "register_operand" "")
10667 (ashift (match_operand 1 "index_register_operand" "")
10668 (match_operand:QI 2 "const_int_operand" "")))
10669 (clobber (reg:CC FLAGS_REG))]
10671 && true_regnum (operands[0]) != true_regnum (operands[1])
10672 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
10676 enum machine_mode mode = GET_MODE (operands[0]);
10678 if (GET_MODE_SIZE (mode) < 4)
10679 operands[0] = gen_lowpart (SImode, operands[0]);
10681 operands[1] = gen_lowpart (Pmode, operands[1]);
10682 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10684 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
10685 if (Pmode != SImode)
10686 pat = gen_rtx_SUBREG (SImode, pat, 0);
10687 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
10691 ;; Rare case of shifting RSP is handled by generating move and shift
10693 [(set (match_operand 0 "register_operand" "")
10694 (ashift (match_operand 1 "register_operand" "")
10695 (match_operand:QI 2 "const_int_operand" "")))
10696 (clobber (reg:CC FLAGS_REG))]
10698 && true_regnum (operands[0]) != true_regnum (operands[1])"
10702 emit_move_insn (operands[0], operands[1]);
10703 pat = gen_rtx_SET (VOIDmode, operands[0],
10704 gen_rtx_ASHIFT (GET_MODE (operands[0]),
10705 operands[0], operands[2]));
10706 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
10707 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
10711 (define_insn "*ashlsi3_1_zext"
10712 [(set (match_operand:DI 0 "register_operand" "=r,r")
10713 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
10714 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
10715 (clobber (reg:CC FLAGS_REG))]
10716 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10718 switch (get_attr_type (insn))
10721 gcc_assert (operands[2] == const1_rtx);
10722 return "add{l}\t%k0, %k0";
10728 if (REG_P (operands[2]))
10729 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10730 else if (operands[2] == const1_rtx
10731 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10732 return "sal{l}\t%k0";
10734 return "sal{l}\t{%2, %k0|%k0, %2}";
10737 [(set (attr "type")
10738 (cond [(eq_attr "alternative" "1")
10739 (const_string "lea")
10740 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10742 (match_operand 2 "const1_operand" ""))
10743 (const_string "alu")
10745 (const_string "ishift")))
10746 (set (attr "length_immediate")
10748 (ior (eq_attr "type" "alu")
10749 (and (eq_attr "type" "ishift")
10750 (and (match_operand 2 "const1_operand" "")
10751 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10754 (const_string "*")))
10755 (set_attr "mode" "SI")])
10757 ;; Convert lea to the lea pattern to avoid flags dependency.
10759 [(set (match_operand:DI 0 "register_operand" "")
10760 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10761 (match_operand:QI 2 "const_int_operand" ""))))
10762 (clobber (reg:CC FLAGS_REG))]
10763 "TARGET_64BIT && reload_completed
10764 && true_regnum (operands[0]) != true_regnum (operands[1])"
10765 [(set (match_dup 0) (zero_extend:DI
10766 (subreg:SI (mult:SI (match_dup 1)
10767 (match_dup 2)) 0)))]
10769 operands[1] = gen_lowpart (Pmode, operands[1]);
10770 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10773 ;; This pattern can't accept a variable shift count, since shifts by
10774 ;; zero don't affect the flags. We assume that shifts by constant
10775 ;; zero are optimized away.
10776 (define_insn "*ashlsi3_cmp"
10777 [(set (reg FLAGS_REG)
10779 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10780 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10782 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10783 (ashift:SI (match_dup 1) (match_dup 2)))]
10784 "(optimize_function_for_size_p (cfun)
10785 || !TARGET_PARTIAL_FLAG_REG_STALL
10786 || (operands[2] == const1_rtx
10788 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10789 && ix86_match_ccmode (insn, CCGOCmode)
10790 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10792 switch (get_attr_type (insn))
10795 gcc_assert (operands[2] == const1_rtx);
10796 return "add{l}\t%0, %0";
10799 if (REG_P (operands[2]))
10800 return "sal{l}\t{%b2, %0|%0, %b2}";
10801 else if (operands[2] == const1_rtx
10802 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10803 return "sal{l}\t%0";
10805 return "sal{l}\t{%2, %0|%0, %2}";
10808 [(set (attr "type")
10809 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10811 (match_operand 0 "register_operand" ""))
10812 (match_operand 2 "const1_operand" ""))
10813 (const_string "alu")
10815 (const_string "ishift")))
10816 (set (attr "length_immediate")
10818 (ior (eq_attr "type" "alu")
10819 (and (eq_attr "type" "ishift")
10820 (and (match_operand 2 "const1_operand" "")
10821 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10824 (const_string "*")))
10825 (set_attr "mode" "SI")])
10827 (define_insn "*ashlsi3_cconly"
10828 [(set (reg FLAGS_REG)
10830 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10831 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10833 (clobber (match_scratch:SI 0 "=r"))]
10834 "(optimize_function_for_size_p (cfun)
10835 || !TARGET_PARTIAL_FLAG_REG_STALL
10836 || (operands[2] == const1_rtx
10838 || TARGET_DOUBLE_WITH_ADD)))
10839 && ix86_match_ccmode (insn, CCGOCmode)
10840 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10842 switch (get_attr_type (insn))
10845 gcc_assert (operands[2] == const1_rtx);
10846 return "add{l}\t%0, %0";
10849 if (REG_P (operands[2]))
10850 return "sal{l}\t{%b2, %0|%0, %b2}";
10851 else if (operands[2] == const1_rtx
10852 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10853 return "sal{l}\t%0";
10855 return "sal{l}\t{%2, %0|%0, %2}";
10858 [(set (attr "type")
10859 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10861 (match_operand 0 "register_operand" ""))
10862 (match_operand 2 "const1_operand" ""))
10863 (const_string "alu")
10865 (const_string "ishift")))
10866 (set (attr "length_immediate")
10868 (ior (eq_attr "type" "alu")
10869 (and (eq_attr "type" "ishift")
10870 (and (match_operand 2 "const1_operand" "")
10871 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10874 (const_string "*")))
10875 (set_attr "mode" "SI")])
10877 (define_insn "*ashlsi3_cmp_zext"
10878 [(set (reg FLAGS_REG)
10880 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10881 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10883 (set (match_operand:DI 0 "register_operand" "=r")
10884 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10886 && (optimize_function_for_size_p (cfun)
10887 || !TARGET_PARTIAL_FLAG_REG_STALL
10888 || (operands[2] == const1_rtx
10890 || TARGET_DOUBLE_WITH_ADD)))
10891 && ix86_match_ccmode (insn, CCGOCmode)
10892 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10894 switch (get_attr_type (insn))
10897 gcc_assert (operands[2] == const1_rtx);
10898 return "add{l}\t%k0, %k0";
10901 if (REG_P (operands[2]))
10902 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10903 else if (operands[2] == const1_rtx
10904 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10905 return "sal{l}\t%k0";
10907 return "sal{l}\t{%2, %k0|%k0, %2}";
10910 [(set (attr "type")
10911 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10913 (match_operand 2 "const1_operand" ""))
10914 (const_string "alu")
10916 (const_string "ishift")))
10917 (set (attr "length_immediate")
10919 (ior (eq_attr "type" "alu")
10920 (and (eq_attr "type" "ishift")
10921 (and (match_operand 2 "const1_operand" "")
10922 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10925 (const_string "*")))
10926 (set_attr "mode" "SI")])
10928 (define_expand "ashlhi3"
10929 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10930 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10931 (match_operand:QI 2 "nonmemory_operand" "")))]
10932 "TARGET_HIMODE_MATH"
10933 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10935 (define_insn "*ashlhi3_1_lea"
10936 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10937 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10938 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10939 (clobber (reg:CC FLAGS_REG))]
10940 "!TARGET_PARTIAL_REG_STALL
10941 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10943 switch (get_attr_type (insn))
10948 gcc_assert (operands[2] == const1_rtx);
10949 return "add{w}\t%0, %0";
10952 if (REG_P (operands[2]))
10953 return "sal{w}\t{%b2, %0|%0, %b2}";
10954 else if (operands[2] == const1_rtx
10955 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10956 return "sal{w}\t%0";
10958 return "sal{w}\t{%2, %0|%0, %2}";
10961 [(set (attr "type")
10962 (cond [(eq_attr "alternative" "1")
10963 (const_string "lea")
10964 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10966 (match_operand 0 "register_operand" ""))
10967 (match_operand 2 "const1_operand" ""))
10968 (const_string "alu")
10970 (const_string "ishift")))
10971 (set (attr "length_immediate")
10973 (ior (eq_attr "type" "alu")
10974 (and (eq_attr "type" "ishift")
10975 (and (match_operand 2 "const1_operand" "")
10976 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10979 (const_string "*")))
10980 (set_attr "mode" "HI,SI")])
10982 (define_insn "*ashlhi3_1"
10983 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10984 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10985 (match_operand:QI 2 "nonmemory_operand" "cI")))
10986 (clobber (reg:CC FLAGS_REG))]
10987 "TARGET_PARTIAL_REG_STALL
10988 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10990 switch (get_attr_type (insn))
10993 gcc_assert (operands[2] == const1_rtx);
10994 return "add{w}\t%0, %0";
10997 if (REG_P (operands[2]))
10998 return "sal{w}\t{%b2, %0|%0, %b2}";
10999 else if (operands[2] == const1_rtx
11000 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11001 return "sal{w}\t%0";
11003 return "sal{w}\t{%2, %0|%0, %2}";
11006 [(set (attr "type")
11007 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11009 (match_operand 0 "register_operand" ""))
11010 (match_operand 2 "const1_operand" ""))
11011 (const_string "alu")
11013 (const_string "ishift")))
11014 (set (attr "length_immediate")
11016 (ior (eq_attr "type" "alu")
11017 (and (eq_attr "type" "ishift")
11018 (and (match_operand 2 "const1_operand" "")
11019 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11022 (const_string "*")))
11023 (set_attr "mode" "HI")])
11025 ;; This pattern can't accept a variable shift count, since shifts by
11026 ;; zero don't affect the flags. We assume that shifts by constant
11027 ;; zero are optimized away.
11028 (define_insn "*ashlhi3_cmp"
11029 [(set (reg FLAGS_REG)
11031 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11032 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11034 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11035 (ashift:HI (match_dup 1) (match_dup 2)))]
11036 "(optimize_function_for_size_p (cfun)
11037 || !TARGET_PARTIAL_FLAG_REG_STALL
11038 || (operands[2] == const1_rtx
11040 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11041 && ix86_match_ccmode (insn, CCGOCmode)
11042 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11044 switch (get_attr_type (insn))
11047 gcc_assert (operands[2] == const1_rtx);
11048 return "add{w}\t%0, %0";
11051 if (REG_P (operands[2]))
11052 return "sal{w}\t{%b2, %0|%0, %b2}";
11053 else if (operands[2] == const1_rtx
11054 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11055 return "sal{w}\t%0";
11057 return "sal{w}\t{%2, %0|%0, %2}";
11060 [(set (attr "type")
11061 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11063 (match_operand 0 "register_operand" ""))
11064 (match_operand 2 "const1_operand" ""))
11065 (const_string "alu")
11067 (const_string "ishift")))
11068 (set (attr "length_immediate")
11070 (ior (eq_attr "type" "alu")
11071 (and (eq_attr "type" "ishift")
11072 (and (match_operand 2 "const1_operand" "")
11073 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11076 (const_string "*")))
11077 (set_attr "mode" "HI")])
11079 (define_insn "*ashlhi3_cconly"
11080 [(set (reg FLAGS_REG)
11082 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11083 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11085 (clobber (match_scratch:HI 0 "=r"))]
11086 "(optimize_function_for_size_p (cfun)
11087 || !TARGET_PARTIAL_FLAG_REG_STALL
11088 || (operands[2] == const1_rtx
11090 || TARGET_DOUBLE_WITH_ADD)))
11091 && ix86_match_ccmode (insn, CCGOCmode)
11092 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
11094 switch (get_attr_type (insn))
11097 gcc_assert (operands[2] == const1_rtx);
11098 return "add{w}\t%0, %0";
11101 if (REG_P (operands[2]))
11102 return "sal{w}\t{%b2, %0|%0, %b2}";
11103 else if (operands[2] == const1_rtx
11104 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11105 return "sal{w}\t%0";
11107 return "sal{w}\t{%2, %0|%0, %2}";
11110 [(set (attr "type")
11111 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11113 (match_operand 0 "register_operand" ""))
11114 (match_operand 2 "const1_operand" ""))
11115 (const_string "alu")
11117 (const_string "ishift")))
11118 (set (attr "length_immediate")
11120 (ior (eq_attr "type" "alu")
11121 (and (eq_attr "type" "ishift")
11122 (and (match_operand 2 "const1_operand" "")
11123 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11126 (const_string "*")))
11127 (set_attr "mode" "HI")])
11129 (define_expand "ashlqi3"
11130 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11131 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
11132 (match_operand:QI 2 "nonmemory_operand" "")))]
11133 "TARGET_QIMODE_MATH"
11134 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
11136 ;; %%% Potential partial reg stall on alternative 2. What to do?
11138 (define_insn "*ashlqi3_1_lea"
11139 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
11140 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
11141 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
11142 (clobber (reg:CC FLAGS_REG))]
11143 "!TARGET_PARTIAL_REG_STALL
11144 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11146 switch (get_attr_type (insn))
11151 gcc_assert (operands[2] == const1_rtx);
11152 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11153 return "add{l}\t%k0, %k0";
11155 return "add{b}\t%0, %0";
11158 if (REG_P (operands[2]))
11160 if (get_attr_mode (insn) == MODE_SI)
11161 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11163 return "sal{b}\t{%b2, %0|%0, %b2}";
11165 else if (operands[2] == const1_rtx
11166 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11168 if (get_attr_mode (insn) == MODE_SI)
11169 return "sal{l}\t%0";
11171 return "sal{b}\t%0";
11175 if (get_attr_mode (insn) == MODE_SI)
11176 return "sal{l}\t{%2, %k0|%k0, %2}";
11178 return "sal{b}\t{%2, %0|%0, %2}";
11182 [(set (attr "type")
11183 (cond [(eq_attr "alternative" "2")
11184 (const_string "lea")
11185 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11187 (match_operand 0 "register_operand" ""))
11188 (match_operand 2 "const1_operand" ""))
11189 (const_string "alu")
11191 (const_string "ishift")))
11192 (set (attr "length_immediate")
11194 (ior (eq_attr "type" "alu")
11195 (and (eq_attr "type" "ishift")
11196 (and (match_operand 2 "const1_operand" "")
11197 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11200 (const_string "*")))
11201 (set_attr "mode" "QI,SI,SI")])
11203 (define_insn "*ashlqi3_1"
11204 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11205 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11206 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
11207 (clobber (reg:CC FLAGS_REG))]
11208 "TARGET_PARTIAL_REG_STALL
11209 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11211 switch (get_attr_type (insn))
11214 gcc_assert (operands[2] == const1_rtx);
11215 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
11216 return "add{l}\t%k0, %k0";
11218 return "add{b}\t%0, %0";
11221 if (REG_P (operands[2]))
11223 if (get_attr_mode (insn) == MODE_SI)
11224 return "sal{l}\t{%b2, %k0|%k0, %b2}";
11226 return "sal{b}\t{%b2, %0|%0, %b2}";
11228 else if (operands[2] == const1_rtx
11229 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11231 if (get_attr_mode (insn) == MODE_SI)
11232 return "sal{l}\t%0";
11234 return "sal{b}\t%0";
11238 if (get_attr_mode (insn) == MODE_SI)
11239 return "sal{l}\t{%2, %k0|%k0, %2}";
11241 return "sal{b}\t{%2, %0|%0, %2}";
11245 [(set (attr "type")
11246 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11248 (match_operand 0 "register_operand" ""))
11249 (match_operand 2 "const1_operand" ""))
11250 (const_string "alu")
11252 (const_string "ishift")))
11253 (set (attr "length_immediate")
11255 (ior (eq_attr "type" "alu")
11256 (and (eq_attr "type" "ishift")
11257 (and (match_operand 2 "const1_operand" "")
11258 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11261 (const_string "*")))
11262 (set_attr "mode" "QI,SI")])
11264 ;; This pattern can't accept a variable shift count, since shifts by
11265 ;; zero don't affect the flags. We assume that shifts by constant
11266 ;; zero are optimized away.
11267 (define_insn "*ashlqi3_cmp"
11268 [(set (reg FLAGS_REG)
11270 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11271 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11273 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11274 (ashift:QI (match_dup 1) (match_dup 2)))]
11275 "(optimize_function_for_size_p (cfun)
11276 || !TARGET_PARTIAL_FLAG_REG_STALL
11277 || (operands[2] == const1_rtx
11279 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11280 && ix86_match_ccmode (insn, CCGOCmode)
11281 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11283 switch (get_attr_type (insn))
11286 gcc_assert (operands[2] == const1_rtx);
11287 return "add{b}\t%0, %0";
11290 if (REG_P (operands[2]))
11291 return "sal{b}\t{%b2, %0|%0, %b2}";
11292 else if (operands[2] == const1_rtx
11293 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11294 return "sal{b}\t%0";
11296 return "sal{b}\t{%2, %0|%0, %2}";
11299 [(set (attr "type")
11300 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11302 (match_operand 0 "register_operand" ""))
11303 (match_operand 2 "const1_operand" ""))
11304 (const_string "alu")
11306 (const_string "ishift")))
11307 (set (attr "length_immediate")
11309 (ior (eq_attr "type" "alu")
11310 (and (eq_attr "type" "ishift")
11311 (and (match_operand 2 "const1_operand" "")
11312 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11315 (const_string "*")))
11316 (set_attr "mode" "QI")])
11318 (define_insn "*ashlqi3_cconly"
11319 [(set (reg FLAGS_REG)
11321 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11322 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11324 (clobber (match_scratch:QI 0 "=q"))]
11325 "(optimize_function_for_size_p (cfun)
11326 || !TARGET_PARTIAL_FLAG_REG_STALL
11327 || (operands[2] == const1_rtx
11329 || TARGET_DOUBLE_WITH_ADD)))
11330 && ix86_match_ccmode (insn, CCGOCmode)
11331 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
11333 switch (get_attr_type (insn))
11336 gcc_assert (operands[2] == const1_rtx);
11337 return "add{b}\t%0, %0";
11340 if (REG_P (operands[2]))
11341 return "sal{b}\t{%b2, %0|%0, %b2}";
11342 else if (operands[2] == const1_rtx
11343 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11344 return "sal{b}\t%0";
11346 return "sal{b}\t{%2, %0|%0, %2}";
11349 [(set (attr "type")
11350 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11352 (match_operand 0 "register_operand" ""))
11353 (match_operand 2 "const1_operand" ""))
11354 (const_string "alu")
11356 (const_string "ishift")))
11357 (set (attr "length_immediate")
11359 (ior (eq_attr "type" "alu")
11360 (and (eq_attr "type" "ishift")
11361 (and (match_operand 2 "const1_operand" "")
11362 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11365 (const_string "*")))
11366 (set_attr "mode" "QI")])
11368 ;; See comment above `ashldi3' about how this works.
11370 (define_expand "ashrti3"
11371 [(set (match_operand:TI 0 "register_operand" "")
11372 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11373 (match_operand:QI 2 "nonmemory_operand" "")))]
11375 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
11377 (define_insn "*ashrti3_1"
11378 [(set (match_operand:TI 0 "register_operand" "=r")
11379 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
11380 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11381 (clobber (reg:CC FLAGS_REG))]
11384 [(set_attr "type" "multi")])
11387 [(match_scratch:DI 3 "r")
11388 (parallel [(set (match_operand:TI 0 "register_operand" "")
11389 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11390 (match_operand:QI 2 "nonmemory_operand" "")))
11391 (clobber (reg:CC FLAGS_REG))])
11395 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
11398 [(set (match_operand:TI 0 "register_operand" "")
11399 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
11400 (match_operand:QI 2 "nonmemory_operand" "")))
11401 (clobber (reg:CC FLAGS_REG))]
11402 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11403 ? epilogue_completed : reload_completed)"
11405 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
11407 (define_insn "x86_64_shrd"
11408 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11409 (ior:DI (ashiftrt:DI (match_dup 0)
11410 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11411 (ashift:DI (match_operand:DI 1 "register_operand" "r")
11412 (minus:QI (const_int 64) (match_dup 2)))))
11413 (clobber (reg:CC FLAGS_REG))]
11415 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
11416 [(set_attr "type" "ishift")
11417 (set_attr "prefix_0f" "1")
11418 (set_attr "mode" "DI")
11419 (set_attr "athlon_decode" "vector")
11420 (set_attr "amdfam10_decode" "vector")])
11422 (define_expand "ashrdi3"
11423 [(set (match_operand:DI 0 "shiftdi_operand" "")
11424 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11425 (match_operand:QI 2 "nonmemory_operand" "")))]
11427 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
11429 (define_expand "x86_64_shift_adj_3"
11430 [(use (match_operand:DI 0 "register_operand" ""))
11431 (use (match_operand:DI 1 "register_operand" ""))
11432 (use (match_operand:QI 2 "register_operand" ""))]
11435 rtx label = gen_label_rtx ();
11438 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11440 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11441 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11442 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11443 gen_rtx_LABEL_REF (VOIDmode, label),
11445 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11446 JUMP_LABEL (tmp) = label;
11448 emit_move_insn (operands[0], operands[1]);
11449 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
11451 emit_label (label);
11452 LABEL_NUSES (label) = 1;
11457 (define_insn "ashrdi3_63_rex64"
11458 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
11459 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
11460 (match_operand:DI 2 "const_int_operand" "i,i")))
11461 (clobber (reg:CC FLAGS_REG))]
11462 "TARGET_64BIT && INTVAL (operands[2]) == 63
11463 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11464 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11467 sar{q}\t{%2, %0|%0, %2}"
11468 [(set_attr "type" "imovx,ishift")
11469 (set_attr "prefix_0f" "0,*")
11470 (set_attr "length_immediate" "0,*")
11471 (set_attr "modrm" "0,1")
11472 (set_attr "mode" "DI")])
11474 (define_insn "*ashrdi3_1_one_bit_rex64"
11475 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11476 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11477 (match_operand:QI 2 "const1_operand" "")))
11478 (clobber (reg:CC FLAGS_REG))]
11480 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11481 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11483 [(set_attr "type" "ishift")
11484 (set_attr "length_immediate" "0")
11485 (set_attr "mode" "DI")])
11487 (define_insn "*ashrdi3_1_rex64"
11488 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11489 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11490 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11491 (clobber (reg:CC FLAGS_REG))]
11492 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11494 sar{q}\t{%2, %0|%0, %2}
11495 sar{q}\t{%b2, %0|%0, %b2}"
11496 [(set_attr "type" "ishift")
11497 (set_attr "mode" "DI")])
11499 ;; This pattern can't accept a variable shift count, since shifts by
11500 ;; zero don't affect the flags. We assume that shifts by constant
11501 ;; zero are optimized away.
11502 (define_insn "*ashrdi3_one_bit_cmp_rex64"
11503 [(set (reg FLAGS_REG)
11505 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11506 (match_operand:QI 2 "const1_operand" ""))
11508 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11509 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11511 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11512 && ix86_match_ccmode (insn, CCGOCmode)
11513 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11515 [(set_attr "type" "ishift")
11516 (set_attr "length_immediate" "0")
11517 (set_attr "mode" "DI")])
11519 (define_insn "*ashrdi3_one_bit_cconly_rex64"
11520 [(set (reg FLAGS_REG)
11522 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11523 (match_operand:QI 2 "const1_operand" ""))
11525 (clobber (match_scratch:DI 0 "=r"))]
11527 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11528 && ix86_match_ccmode (insn, CCGOCmode)
11529 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11531 [(set_attr "type" "ishift")
11532 (set_attr "length_immediate" "0")
11533 (set_attr "mode" "DI")])
11535 ;; This pattern can't accept a variable shift count, since shifts by
11536 ;; zero don't affect the flags. We assume that shifts by constant
11537 ;; zero are optimized away.
11538 (define_insn "*ashrdi3_cmp_rex64"
11539 [(set (reg FLAGS_REG)
11541 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11542 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11544 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11545 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
11547 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11548 && ix86_match_ccmode (insn, CCGOCmode)
11549 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11550 "sar{q}\t{%2, %0|%0, %2}"
11551 [(set_attr "type" "ishift")
11552 (set_attr "mode" "DI")])
11554 (define_insn "*ashrdi3_cconly_rex64"
11555 [(set (reg FLAGS_REG)
11557 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11558 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11560 (clobber (match_scratch:DI 0 "=r"))]
11562 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11563 && ix86_match_ccmode (insn, CCGOCmode)
11564 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
11565 "sar{q}\t{%2, %0|%0, %2}"
11566 [(set_attr "type" "ishift")
11567 (set_attr "mode" "DI")])
11569 (define_insn "*ashrdi3_1"
11570 [(set (match_operand:DI 0 "register_operand" "=r")
11571 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
11572 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11573 (clobber (reg:CC FLAGS_REG))]
11576 [(set_attr "type" "multi")])
11578 ;; By default we don't ask for a scratch register, because when DImode
11579 ;; values are manipulated, registers are already at a premium. But if
11580 ;; we have one handy, we won't turn it away.
11582 [(match_scratch:SI 3 "r")
11583 (parallel [(set (match_operand:DI 0 "register_operand" "")
11584 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11585 (match_operand:QI 2 "nonmemory_operand" "")))
11586 (clobber (reg:CC FLAGS_REG))])
11588 "!TARGET_64BIT && TARGET_CMOVE"
11590 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
11593 [(set (match_operand:DI 0 "register_operand" "")
11594 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
11595 (match_operand:QI 2 "nonmemory_operand" "")))
11596 (clobber (reg:CC FLAGS_REG))]
11597 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11598 ? epilogue_completed : reload_completed)"
11600 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
11602 (define_insn "x86_shrd"
11603 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11604 (ior:SI (ashiftrt:SI (match_dup 0)
11605 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11606 (ashift:SI (match_operand:SI 1 "register_operand" "r")
11607 (minus:QI (const_int 32) (match_dup 2)))))
11608 (clobber (reg:CC FLAGS_REG))]
11610 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
11611 [(set_attr "type" "ishift")
11612 (set_attr "prefix_0f" "1")
11613 (set_attr "pent_pair" "np")
11614 (set_attr "mode" "SI")])
11616 (define_expand "x86_shift_adj_3"
11617 [(use (match_operand:SI 0 "register_operand" ""))
11618 (use (match_operand:SI 1 "register_operand" ""))
11619 (use (match_operand:QI 2 "register_operand" ""))]
11622 rtx label = gen_label_rtx ();
11625 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11627 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11628 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11629 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11630 gen_rtx_LABEL_REF (VOIDmode, label),
11632 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11633 JUMP_LABEL (tmp) = label;
11635 emit_move_insn (operands[0], operands[1]);
11636 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
11638 emit_label (label);
11639 LABEL_NUSES (label) = 1;
11644 (define_expand "ashrsi3_31"
11645 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11646 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11647 (match_operand:SI 2 "const_int_operand" "i,i")))
11648 (clobber (reg:CC FLAGS_REG))])]
11651 (define_insn "*ashrsi3_31"
11652 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
11653 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
11654 (match_operand:SI 2 "const_int_operand" "i,i")))
11655 (clobber (reg:CC FLAGS_REG))]
11656 "INTVAL (operands[2]) == 31
11657 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11658 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11661 sar{l}\t{%2, %0|%0, %2}"
11662 [(set_attr "type" "imovx,ishift")
11663 (set_attr "prefix_0f" "0,*")
11664 (set_attr "length_immediate" "0,*")
11665 (set_attr "modrm" "0,1")
11666 (set_attr "mode" "SI")])
11668 (define_insn "*ashrsi3_31_zext"
11669 [(set (match_operand:DI 0 "register_operand" "=*d,r")
11670 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
11671 (match_operand:SI 2 "const_int_operand" "i,i"))))
11672 (clobber (reg:CC FLAGS_REG))]
11673 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
11674 && INTVAL (operands[2]) == 31
11675 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11678 sar{l}\t{%2, %k0|%k0, %2}"
11679 [(set_attr "type" "imovx,ishift")
11680 (set_attr "prefix_0f" "0,*")
11681 (set_attr "length_immediate" "0,*")
11682 (set_attr "modrm" "0,1")
11683 (set_attr "mode" "SI")])
11685 (define_expand "ashrsi3"
11686 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11687 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11688 (match_operand:QI 2 "nonmemory_operand" "")))]
11690 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
11692 (define_insn "*ashrsi3_1_one_bit"
11693 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11694 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11695 (match_operand:QI 2 "const1_operand" "")))
11696 (clobber (reg:CC FLAGS_REG))]
11697 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11698 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11700 [(set_attr "type" "ishift")
11701 (set_attr "length_immediate" "0")
11702 (set_attr "mode" "SI")])
11704 (define_insn "*ashrsi3_1_one_bit_zext"
11705 [(set (match_operand:DI 0 "register_operand" "=r")
11706 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11707 (match_operand:QI 2 "const1_operand" ""))))
11708 (clobber (reg:CC FLAGS_REG))]
11710 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11711 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11713 [(set_attr "type" "ishift")
11714 (set_attr "length_immediate" "0")
11715 (set_attr "mode" "SI")])
11717 (define_insn "*ashrsi3_1"
11718 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11719 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11720 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11721 (clobber (reg:CC FLAGS_REG))]
11722 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11724 sar{l}\t{%2, %0|%0, %2}
11725 sar{l}\t{%b2, %0|%0, %b2}"
11726 [(set_attr "type" "ishift")
11727 (set_attr "mode" "SI")])
11729 (define_insn "*ashrsi3_1_zext"
11730 [(set (match_operand:DI 0 "register_operand" "=r,r")
11731 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11732 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11733 (clobber (reg:CC FLAGS_REG))]
11734 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11736 sar{l}\t{%2, %k0|%k0, %2}
11737 sar{l}\t{%b2, %k0|%k0, %b2}"
11738 [(set_attr "type" "ishift")
11739 (set_attr "mode" "SI")])
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 "*ashrsi3_one_bit_cmp"
11745 [(set (reg FLAGS_REG)
11747 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11748 (match_operand:QI 2 "const1_operand" ""))
11750 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11751 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11752 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11753 && ix86_match_ccmode (insn, CCGOCmode)
11754 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11756 [(set_attr "type" "ishift")
11757 (set_attr "length_immediate" "0")
11758 (set_attr "mode" "SI")])
11760 (define_insn "*ashrsi3_one_bit_cconly"
11761 [(set (reg FLAGS_REG)
11763 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11764 (match_operand:QI 2 "const1_operand" ""))
11766 (clobber (match_scratch:SI 0 "=r"))]
11767 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11768 && ix86_match_ccmode (insn, CCGOCmode)
11769 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11771 [(set_attr "type" "ishift")
11772 (set_attr "length_immediate" "0")
11773 (set_attr "mode" "SI")])
11775 (define_insn "*ashrsi3_one_bit_cmp_zext"
11776 [(set (reg FLAGS_REG)
11778 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11779 (match_operand:QI 2 "const1_operand" ""))
11781 (set (match_operand:DI 0 "register_operand" "=r")
11782 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11784 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11785 && ix86_match_ccmode (insn, CCmode)
11786 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11788 [(set_attr "type" "ishift")
11789 (set_attr "length_immediate" "0")
11790 (set_attr "mode" "SI")])
11792 ;; This pattern can't accept a variable shift count, since shifts by
11793 ;; zero don't affect the flags. We assume that shifts by constant
11794 ;; zero are optimized away.
11795 (define_insn "*ashrsi3_cmp"
11796 [(set (reg FLAGS_REG)
11798 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11799 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11801 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11802 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11803 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11804 && ix86_match_ccmode (insn, CCGOCmode)
11805 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11806 "sar{l}\t{%2, %0|%0, %2}"
11807 [(set_attr "type" "ishift")
11808 (set_attr "mode" "SI")])
11810 (define_insn "*ashrsi3_cconly"
11811 [(set (reg FLAGS_REG)
11813 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11814 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11816 (clobber (match_scratch:SI 0 "=r"))]
11817 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11818 && ix86_match_ccmode (insn, CCGOCmode)
11819 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11820 "sar{l}\t{%2, %0|%0, %2}"
11821 [(set_attr "type" "ishift")
11822 (set_attr "mode" "SI")])
11824 (define_insn "*ashrsi3_cmp_zext"
11825 [(set (reg FLAGS_REG)
11827 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11828 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11830 (set (match_operand:DI 0 "register_operand" "=r")
11831 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11833 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11834 && ix86_match_ccmode (insn, CCGOCmode)
11835 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11836 "sar{l}\t{%2, %k0|%k0, %2}"
11837 [(set_attr "type" "ishift")
11838 (set_attr "mode" "SI")])
11840 (define_expand "ashrhi3"
11841 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11842 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11843 (match_operand:QI 2 "nonmemory_operand" "")))]
11844 "TARGET_HIMODE_MATH"
11845 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11847 (define_insn "*ashrhi3_1_one_bit"
11848 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11849 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11850 (match_operand:QI 2 "const1_operand" "")))
11851 (clobber (reg:CC FLAGS_REG))]
11852 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11853 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11855 [(set_attr "type" "ishift")
11856 (set_attr "length_immediate" "0")
11857 (set_attr "mode" "HI")])
11859 (define_insn "*ashrhi3_1"
11860 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11861 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11862 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11863 (clobber (reg:CC FLAGS_REG))]
11864 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11866 sar{w}\t{%2, %0|%0, %2}
11867 sar{w}\t{%b2, %0|%0, %b2}"
11868 [(set_attr "type" "ishift")
11869 (set_attr "mode" "HI")])
11871 ;; This pattern can't accept a variable shift count, since shifts by
11872 ;; zero don't affect the flags. We assume that shifts by constant
11873 ;; zero are optimized away.
11874 (define_insn "*ashrhi3_one_bit_cmp"
11875 [(set (reg FLAGS_REG)
11877 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11878 (match_operand:QI 2 "const1_operand" ""))
11880 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11881 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11882 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11883 && ix86_match_ccmode (insn, CCGOCmode)
11884 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11886 [(set_attr "type" "ishift")
11887 (set_attr "length_immediate" "0")
11888 (set_attr "mode" "HI")])
11890 (define_insn "*ashrhi3_one_bit_cconly"
11891 [(set (reg FLAGS_REG)
11893 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11894 (match_operand:QI 2 "const1_operand" ""))
11896 (clobber (match_scratch:HI 0 "=r"))]
11897 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11898 && ix86_match_ccmode (insn, CCGOCmode)
11899 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11901 [(set_attr "type" "ishift")
11902 (set_attr "length_immediate" "0")
11903 (set_attr "mode" "HI")])
11905 ;; This pattern can't accept a variable shift count, since shifts by
11906 ;; zero don't affect the flags. We assume that shifts by constant
11907 ;; zero are optimized away.
11908 (define_insn "*ashrhi3_cmp"
11909 [(set (reg FLAGS_REG)
11911 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11912 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11914 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11915 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11916 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11917 && ix86_match_ccmode (insn, CCGOCmode)
11918 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11919 "sar{w}\t{%2, %0|%0, %2}"
11920 [(set_attr "type" "ishift")
11921 (set_attr "mode" "HI")])
11923 (define_insn "*ashrhi3_cconly"
11924 [(set (reg FLAGS_REG)
11926 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11927 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11929 (clobber (match_scratch:HI 0 "=r"))]
11930 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11931 && ix86_match_ccmode (insn, CCGOCmode)
11932 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11933 "sar{w}\t{%2, %0|%0, %2}"
11934 [(set_attr "type" "ishift")
11935 (set_attr "mode" "HI")])
11937 (define_expand "ashrqi3"
11938 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11939 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11940 (match_operand:QI 2 "nonmemory_operand" "")))]
11941 "TARGET_QIMODE_MATH"
11942 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11944 (define_insn "*ashrqi3_1_one_bit"
11945 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11946 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11947 (match_operand:QI 2 "const1_operand" "")))
11948 (clobber (reg:CC FLAGS_REG))]
11949 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11950 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11952 [(set_attr "type" "ishift")
11953 (set_attr "length_immediate" "0")
11954 (set_attr "mode" "QI")])
11956 (define_insn "*ashrqi3_1_one_bit_slp"
11957 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11958 (ashiftrt:QI (match_dup 0)
11959 (match_operand:QI 1 "const1_operand" "")))
11960 (clobber (reg:CC FLAGS_REG))]
11961 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11962 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11963 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11965 [(set_attr "type" "ishift1")
11966 (set_attr "length_immediate" "0")
11967 (set_attr "mode" "QI")])
11969 (define_insn "*ashrqi3_1"
11970 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11971 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11972 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11973 (clobber (reg:CC FLAGS_REG))]
11974 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11976 sar{b}\t{%2, %0|%0, %2}
11977 sar{b}\t{%b2, %0|%0, %b2}"
11978 [(set_attr "type" "ishift")
11979 (set_attr "mode" "QI")])
11981 (define_insn "*ashrqi3_1_slp"
11982 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11983 (ashiftrt:QI (match_dup 0)
11984 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11985 (clobber (reg:CC FLAGS_REG))]
11986 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11987 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11989 sar{b}\t{%1, %0|%0, %1}
11990 sar{b}\t{%b1, %0|%0, %b1}"
11991 [(set_attr "type" "ishift1")
11992 (set_attr "mode" "QI")])
11994 ;; This pattern can't accept a variable shift count, since shifts by
11995 ;; zero don't affect the flags. We assume that shifts by constant
11996 ;; zero are optimized away.
11997 (define_insn "*ashrqi3_one_bit_cmp"
11998 [(set (reg FLAGS_REG)
12000 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12001 (match_operand:QI 2 "const1_operand" "I"))
12003 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12004 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12005 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12006 && ix86_match_ccmode (insn, CCGOCmode)
12007 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12009 [(set_attr "type" "ishift")
12010 (set_attr "length_immediate" "0")
12011 (set_attr "mode" "QI")])
12013 (define_insn "*ashrqi3_one_bit_cconly"
12014 [(set (reg FLAGS_REG)
12016 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12017 (match_operand:QI 2 "const1_operand" ""))
12019 (clobber (match_scratch:QI 0 "=q"))]
12020 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12021 && ix86_match_ccmode (insn, CCGOCmode)
12022 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12024 [(set_attr "type" "ishift")
12025 (set_attr "length_immediate" "0")
12026 (set_attr "mode" "QI")])
12028 ;; This pattern can't accept a variable shift count, since shifts by
12029 ;; zero don't affect the flags. We assume that shifts by constant
12030 ;; zero are optimized away.
12031 (define_insn "*ashrqi3_cmp"
12032 [(set (reg FLAGS_REG)
12034 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12035 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12037 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12038 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
12039 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12040 && ix86_match_ccmode (insn, CCGOCmode)
12041 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12042 "sar{b}\t{%2, %0|%0, %2}"
12043 [(set_attr "type" "ishift")
12044 (set_attr "mode" "QI")])
12046 (define_insn "*ashrqi3_cconly"
12047 [(set (reg FLAGS_REG)
12049 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12050 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12052 (clobber (match_scratch:QI 0 "=q"))]
12053 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12054 && ix86_match_ccmode (insn, CCGOCmode)
12055 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
12056 "sar{b}\t{%2, %0|%0, %2}"
12057 [(set_attr "type" "ishift")
12058 (set_attr "mode" "QI")])
12061 ;; Logical shift instructions
12063 ;; See comment above `ashldi3' about how this works.
12065 (define_expand "lshrti3"
12066 [(set (match_operand:TI 0 "register_operand" "")
12067 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12068 (match_operand:QI 2 "nonmemory_operand" "")))]
12070 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
12072 ;; This pattern must be defined before *lshrti3_1 to prevent
12073 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
12075 (define_insn "*avx_lshrti3"
12076 [(set (match_operand:TI 0 "register_operand" "=x")
12077 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
12078 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12081 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12082 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
12084 [(set_attr "type" "sseishft")
12085 (set_attr "prefix" "vex")
12086 (set_attr "length_immediate" "1")
12087 (set_attr "mode" "TI")])
12089 (define_insn "sse2_lshrti3"
12090 [(set (match_operand:TI 0 "register_operand" "=x")
12091 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12092 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
12095 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
12096 return "psrldq\t{%2, %0|%0, %2}";
12098 [(set_attr "type" "sseishft")
12099 (set_attr "prefix_data16" "1")
12100 (set_attr "length_immediate" "1")
12101 (set_attr "mode" "TI")])
12103 (define_insn "*lshrti3_1"
12104 [(set (match_operand:TI 0 "register_operand" "=r")
12105 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
12106 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12107 (clobber (reg:CC FLAGS_REG))]
12110 [(set_attr "type" "multi")])
12113 [(match_scratch:DI 3 "r")
12114 (parallel [(set (match_operand:TI 0 "register_operand" "")
12115 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12116 (match_operand:QI 2 "nonmemory_operand" "")))
12117 (clobber (reg:CC FLAGS_REG))])
12121 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
12124 [(set (match_operand:TI 0 "register_operand" "")
12125 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
12126 (match_operand:QI 2 "nonmemory_operand" "")))
12127 (clobber (reg:CC FLAGS_REG))]
12128 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12129 ? epilogue_completed : reload_completed)"
12131 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
12133 (define_expand "lshrdi3"
12134 [(set (match_operand:DI 0 "shiftdi_operand" "")
12135 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12136 (match_operand:QI 2 "nonmemory_operand" "")))]
12138 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
12140 (define_insn "*lshrdi3_1_one_bit_rex64"
12141 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12142 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12143 (match_operand:QI 2 "const1_operand" "")))
12144 (clobber (reg:CC FLAGS_REG))]
12146 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12147 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12149 [(set_attr "type" "ishift")
12150 (set_attr "length_immediate" "0")
12151 (set_attr "mode" "DI")])
12153 (define_insn "*lshrdi3_1_rex64"
12154 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12155 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12156 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12157 (clobber (reg:CC FLAGS_REG))]
12158 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12160 shr{q}\t{%2, %0|%0, %2}
12161 shr{q}\t{%b2, %0|%0, %b2}"
12162 [(set_attr "type" "ishift")
12163 (set_attr "mode" "DI")])
12165 ;; This pattern can't accept a variable shift count, since shifts by
12166 ;; zero don't affect the flags. We assume that shifts by constant
12167 ;; zero are optimized away.
12168 (define_insn "*lshrdi3_cmp_one_bit_rex64"
12169 [(set (reg FLAGS_REG)
12171 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12172 (match_operand:QI 2 "const1_operand" ""))
12174 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12175 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
12177 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12178 && ix86_match_ccmode (insn, CCGOCmode)
12179 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12181 [(set_attr "type" "ishift")
12182 (set_attr "length_immediate" "0")
12183 (set_attr "mode" "DI")])
12185 (define_insn "*lshrdi3_cconly_one_bit_rex64"
12186 [(set (reg FLAGS_REG)
12188 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12189 (match_operand:QI 2 "const1_operand" ""))
12191 (clobber (match_scratch:DI 0 "=r"))]
12193 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12194 && ix86_match_ccmode (insn, CCGOCmode)
12195 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12197 [(set_attr "type" "ishift")
12198 (set_attr "length_immediate" "0")
12199 (set_attr "mode" "DI")])
12201 ;; This pattern can't accept a variable shift count, since shifts by
12202 ;; zero don't affect the flags. We assume that shifts by constant
12203 ;; zero are optimized away.
12204 (define_insn "*lshrdi3_cmp_rex64"
12205 [(set (reg FLAGS_REG)
12207 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12208 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12210 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12211 (lshiftrt:DI (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{q}\t{%2, %0|%0, %2}"
12217 [(set_attr "type" "ishift")
12218 (set_attr "mode" "DI")])
12220 (define_insn "*lshrdi3_cconly_rex64"
12221 [(set (reg FLAGS_REG)
12223 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12224 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12226 (clobber (match_scratch:DI 0 "=r"))]
12228 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12229 && ix86_match_ccmode (insn, CCGOCmode)
12230 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12231 "shr{q}\t{%2, %0|%0, %2}"
12232 [(set_attr "type" "ishift")
12233 (set_attr "mode" "DI")])
12235 (define_insn "*lshrdi3_1"
12236 [(set (match_operand:DI 0 "register_operand" "=r")
12237 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
12238 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12239 (clobber (reg:CC FLAGS_REG))]
12242 [(set_attr "type" "multi")])
12244 ;; By default we don't ask for a scratch register, because when DImode
12245 ;; values are manipulated, registers are already at a premium. But if
12246 ;; we have one handy, we won't turn it away.
12248 [(match_scratch:SI 3 "r")
12249 (parallel [(set (match_operand:DI 0 "register_operand" "")
12250 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12251 (match_operand:QI 2 "nonmemory_operand" "")))
12252 (clobber (reg:CC FLAGS_REG))])
12254 "!TARGET_64BIT && TARGET_CMOVE"
12256 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
12259 [(set (match_operand:DI 0 "register_operand" "")
12260 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
12261 (match_operand:QI 2 "nonmemory_operand" "")))
12262 (clobber (reg:CC FLAGS_REG))]
12263 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12264 ? epilogue_completed : reload_completed)"
12266 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
12268 (define_expand "lshrsi3"
12269 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12270 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
12271 (match_operand:QI 2 "nonmemory_operand" "")))]
12273 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
12275 (define_insn "*lshrsi3_1_one_bit"
12276 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12277 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12278 (match_operand:QI 2 "const1_operand" "")))
12279 (clobber (reg:CC FLAGS_REG))]
12280 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12281 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12283 [(set_attr "type" "ishift")
12284 (set_attr "length_immediate" "0")
12285 (set_attr "mode" "SI")])
12287 (define_insn "*lshrsi3_1_one_bit_zext"
12288 [(set (match_operand:DI 0 "register_operand" "=r")
12289 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
12290 (match_operand:QI 2 "const1_operand" "")))
12291 (clobber (reg:CC FLAGS_REG))]
12293 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12294 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12296 [(set_attr "type" "ishift")
12297 (set_attr "length_immediate" "0")
12298 (set_attr "mode" "SI")])
12300 (define_insn "*lshrsi3_1"
12301 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12302 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12303 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12304 (clobber (reg:CC FLAGS_REG))]
12305 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12307 shr{l}\t{%2, %0|%0, %2}
12308 shr{l}\t{%b2, %0|%0, %b2}"
12309 [(set_attr "type" "ishift")
12310 (set_attr "mode" "SI")])
12312 (define_insn "*lshrsi3_1_zext"
12313 [(set (match_operand:DI 0 "register_operand" "=r,r")
12315 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12316 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12317 (clobber (reg:CC FLAGS_REG))]
12318 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12320 shr{l}\t{%2, %k0|%k0, %2}
12321 shr{l}\t{%b2, %k0|%k0, %b2}"
12322 [(set_attr "type" "ishift")
12323 (set_attr "mode" "SI")])
12325 ;; This pattern can't accept a variable shift count, since shifts by
12326 ;; zero don't affect the flags. We assume that shifts by constant
12327 ;; zero are optimized away.
12328 (define_insn "*lshrsi3_one_bit_cmp"
12329 [(set (reg FLAGS_REG)
12331 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12332 (match_operand:QI 2 "const1_operand" ""))
12334 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12335 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12336 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12337 && ix86_match_ccmode (insn, CCGOCmode)
12338 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12340 [(set_attr "type" "ishift")
12341 (set_attr "length_immediate" "0")
12342 (set_attr "mode" "SI")])
12344 (define_insn "*lshrsi3_one_bit_cconly"
12345 [(set (reg FLAGS_REG)
12347 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12348 (match_operand:QI 2 "const1_operand" ""))
12350 (clobber (match_scratch:SI 0 "=r"))]
12351 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12352 && ix86_match_ccmode (insn, CCGOCmode)
12353 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12355 [(set_attr "type" "ishift")
12356 (set_attr "length_immediate" "0")
12357 (set_attr "mode" "SI")])
12359 (define_insn "*lshrsi3_cmp_one_bit_zext"
12360 [(set (reg FLAGS_REG)
12362 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12363 (match_operand:QI 2 "const1_operand" ""))
12365 (set (match_operand:DI 0 "register_operand" "=r")
12366 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12368 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12369 && ix86_match_ccmode (insn, CCGOCmode)
12370 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12372 [(set_attr "type" "ishift")
12373 (set_attr "length_immediate" "0")
12374 (set_attr "mode" "SI")])
12376 ;; This pattern can't accept a variable shift count, since shifts by
12377 ;; zero don't affect the flags. We assume that shifts by constant
12378 ;; zero are optimized away.
12379 (define_insn "*lshrsi3_cmp"
12380 [(set (reg FLAGS_REG)
12382 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12383 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12385 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12386 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
12387 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12388 && ix86_match_ccmode (insn, CCGOCmode)
12389 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12390 "shr{l}\t{%2, %0|%0, %2}"
12391 [(set_attr "type" "ishift")
12392 (set_attr "mode" "SI")])
12394 (define_insn "*lshrsi3_cconly"
12395 [(set (reg FLAGS_REG)
12397 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12398 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12400 (clobber (match_scratch:SI 0 "=r"))]
12401 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12402 && ix86_match_ccmode (insn, CCGOCmode)
12403 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12404 "shr{l}\t{%2, %0|%0, %2}"
12405 [(set_attr "type" "ishift")
12406 (set_attr "mode" "SI")])
12408 (define_insn "*lshrsi3_cmp_zext"
12409 [(set (reg FLAGS_REG)
12411 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
12412 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12414 (set (match_operand:DI 0 "register_operand" "=r")
12415 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
12417 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12418 && ix86_match_ccmode (insn, CCGOCmode)
12419 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12420 "shr{l}\t{%2, %k0|%k0, %2}"
12421 [(set_attr "type" "ishift")
12422 (set_attr "mode" "SI")])
12424 (define_expand "lshrhi3"
12425 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12426 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
12427 (match_operand:QI 2 "nonmemory_operand" "")))]
12428 "TARGET_HIMODE_MATH"
12429 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
12431 (define_insn "*lshrhi3_1_one_bit"
12432 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12433 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12434 (match_operand:QI 2 "const1_operand" "")))
12435 (clobber (reg:CC FLAGS_REG))]
12436 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12437 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12439 [(set_attr "type" "ishift")
12440 (set_attr "length_immediate" "0")
12441 (set_attr "mode" "HI")])
12443 (define_insn "*lshrhi3_1"
12444 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12445 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12446 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12447 (clobber (reg:CC FLAGS_REG))]
12448 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12450 shr{w}\t{%2, %0|%0, %2}
12451 shr{w}\t{%b2, %0|%0, %b2}"
12452 [(set_attr "type" "ishift")
12453 (set_attr "mode" "HI")])
12455 ;; This pattern can't accept a variable shift count, since shifts by
12456 ;; zero don't affect the flags. We assume that shifts by constant
12457 ;; zero are optimized away.
12458 (define_insn "*lshrhi3_one_bit_cmp"
12459 [(set (reg FLAGS_REG)
12461 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12462 (match_operand:QI 2 "const1_operand" ""))
12464 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12465 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12466 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12467 && ix86_match_ccmode (insn, CCGOCmode)
12468 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12470 [(set_attr "type" "ishift")
12471 (set_attr "length_immediate" "0")
12472 (set_attr "mode" "HI")])
12474 (define_insn "*lshrhi3_one_bit_cconly"
12475 [(set (reg FLAGS_REG)
12477 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12478 (match_operand:QI 2 "const1_operand" ""))
12480 (clobber (match_scratch:HI 0 "=r"))]
12481 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12482 && ix86_match_ccmode (insn, CCGOCmode)
12483 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12485 [(set_attr "type" "ishift")
12486 (set_attr "length_immediate" "0")
12487 (set_attr "mode" "HI")])
12489 ;; This pattern can't accept a variable shift count, since shifts by
12490 ;; zero don't affect the flags. We assume that shifts by constant
12491 ;; zero are optimized away.
12492 (define_insn "*lshrhi3_cmp"
12493 [(set (reg FLAGS_REG)
12495 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12496 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12498 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12499 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
12500 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12501 && ix86_match_ccmode (insn, CCGOCmode)
12502 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12503 "shr{w}\t{%2, %0|%0, %2}"
12504 [(set_attr "type" "ishift")
12505 (set_attr "mode" "HI")])
12507 (define_insn "*lshrhi3_cconly"
12508 [(set (reg FLAGS_REG)
12510 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12511 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12513 (clobber (match_scratch:HI 0 "=r"))]
12514 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12515 && ix86_match_ccmode (insn, CCGOCmode)
12516 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
12517 "shr{w}\t{%2, %0|%0, %2}"
12518 [(set_attr "type" "ishift")
12519 (set_attr "mode" "HI")])
12521 (define_expand "lshrqi3"
12522 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12523 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
12524 (match_operand:QI 2 "nonmemory_operand" "")))]
12525 "TARGET_QIMODE_MATH"
12526 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
12528 (define_insn "*lshrqi3_1_one_bit"
12529 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12530 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12531 (match_operand:QI 2 "const1_operand" "")))
12532 (clobber (reg:CC FLAGS_REG))]
12533 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12534 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12536 [(set_attr "type" "ishift")
12537 (set_attr "length_immediate" "0")
12538 (set_attr "mode" "QI")])
12540 (define_insn "*lshrqi3_1_one_bit_slp"
12541 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12542 (lshiftrt:QI (match_dup 0)
12543 (match_operand:QI 1 "const1_operand" "")))
12544 (clobber (reg:CC FLAGS_REG))]
12545 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12546 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12548 [(set_attr "type" "ishift1")
12549 (set_attr "length_immediate" "0")
12550 (set_attr "mode" "QI")])
12552 (define_insn "*lshrqi3_1"
12553 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12554 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12555 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12556 (clobber (reg:CC FLAGS_REG))]
12557 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12559 shr{b}\t{%2, %0|%0, %2}
12560 shr{b}\t{%b2, %0|%0, %b2}"
12561 [(set_attr "type" "ishift")
12562 (set_attr "mode" "QI")])
12564 (define_insn "*lshrqi3_1_slp"
12565 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12566 (lshiftrt:QI (match_dup 0)
12567 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12568 (clobber (reg:CC FLAGS_REG))]
12569 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12570 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12572 shr{b}\t{%1, %0|%0, %1}
12573 shr{b}\t{%b1, %0|%0, %b1}"
12574 [(set_attr "type" "ishift1")
12575 (set_attr "mode" "QI")])
12577 ;; This pattern can't accept a variable shift count, since shifts by
12578 ;; zero don't affect the flags. We assume that shifts by constant
12579 ;; zero are optimized away.
12580 (define_insn "*lshrqi2_one_bit_cmp"
12581 [(set (reg FLAGS_REG)
12583 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12584 (match_operand:QI 2 "const1_operand" ""))
12586 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12587 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12588 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12589 && ix86_match_ccmode (insn, CCGOCmode)
12590 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12592 [(set_attr "type" "ishift")
12593 (set_attr "length_immediate" "0")
12594 (set_attr "mode" "QI")])
12596 (define_insn "*lshrqi2_one_bit_cconly"
12597 [(set (reg FLAGS_REG)
12599 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12600 (match_operand:QI 2 "const1_operand" ""))
12602 (clobber (match_scratch:QI 0 "=q"))]
12603 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12604 && ix86_match_ccmode (insn, CCGOCmode)
12605 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12607 [(set_attr "type" "ishift")
12608 (set_attr "length_immediate" "0")
12609 (set_attr "mode" "QI")])
12611 ;; This pattern can't accept a variable shift count, since shifts by
12612 ;; zero don't affect the flags. We assume that shifts by constant
12613 ;; zero are optimized away.
12614 (define_insn "*lshrqi2_cmp"
12615 [(set (reg FLAGS_REG)
12617 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12618 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12620 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12621 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
12622 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12623 && ix86_match_ccmode (insn, CCGOCmode)
12624 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12625 "shr{b}\t{%2, %0|%0, %2}"
12626 [(set_attr "type" "ishift")
12627 (set_attr "mode" "QI")])
12629 (define_insn "*lshrqi2_cconly"
12630 [(set (reg FLAGS_REG)
12632 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12633 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12635 (clobber (match_scratch:QI 0 "=q"))]
12636 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12637 && ix86_match_ccmode (insn, CCGOCmode)
12638 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
12639 "shr{b}\t{%2, %0|%0, %2}"
12640 [(set_attr "type" "ishift")
12641 (set_attr "mode" "QI")])
12643 ;; Rotate instructions
12645 (define_expand "rotldi3"
12646 [(set (match_operand:DI 0 "shiftdi_operand" "")
12647 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12648 (match_operand:QI 2 "nonmemory_operand" "")))]
12653 ix86_expand_binary_operator (ROTATE, DImode, operands);
12656 if (!const_1_to_31_operand (operands[2], VOIDmode))
12658 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
12662 ;; Implement rotation using two double-precision shift instructions
12663 ;; and a scratch register.
12664 (define_insn_and_split "ix86_rotldi3"
12665 [(set (match_operand:DI 0 "register_operand" "=r")
12666 (rotate:DI (match_operand:DI 1 "register_operand" "0")
12667 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12668 (clobber (reg:CC FLAGS_REG))
12669 (clobber (match_scratch:SI 3 "=&r"))]
12672 "&& reload_completed"
12673 [(set (match_dup 3) (match_dup 4))
12675 [(set (match_dup 4)
12676 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
12677 (lshiftrt:SI (match_dup 5)
12678 (minus:QI (const_int 32) (match_dup 2)))))
12679 (clobber (reg:CC FLAGS_REG))])
12681 [(set (match_dup 5)
12682 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
12683 (lshiftrt:SI (match_dup 3)
12684 (minus:QI (const_int 32) (match_dup 2)))))
12685 (clobber (reg:CC FLAGS_REG))])]
12686 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12688 (define_insn "*rotlsi3_1_one_bit_rex64"
12689 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12690 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12691 (match_operand:QI 2 "const1_operand" "")))
12692 (clobber (reg:CC FLAGS_REG))]
12694 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12695 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12697 [(set_attr "type" "rotate")
12698 (set_attr "length_immediate" "0")
12699 (set_attr "mode" "DI")])
12701 (define_insn "*rotldi3_1_rex64"
12702 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12703 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12704 (match_operand:QI 2 "nonmemory_operand" "e,c")))
12705 (clobber (reg:CC FLAGS_REG))]
12706 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
12708 rol{q}\t{%2, %0|%0, %2}
12709 rol{q}\t{%b2, %0|%0, %b2}"
12710 [(set_attr "type" "rotate")
12711 (set_attr "mode" "DI")])
12713 (define_expand "rotlsi3"
12714 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12715 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
12716 (match_operand:QI 2 "nonmemory_operand" "")))]
12718 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
12720 (define_insn "*rotlsi3_1_one_bit"
12721 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12722 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12723 (match_operand:QI 2 "const1_operand" "")))
12724 (clobber (reg:CC FLAGS_REG))]
12725 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12726 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12728 [(set_attr "type" "rotate")
12729 (set_attr "length_immediate" "0")
12730 (set_attr "mode" "SI")])
12732 (define_insn "*rotlsi3_1_one_bit_zext"
12733 [(set (match_operand:DI 0 "register_operand" "=r")
12735 (rotate:SI (match_operand:SI 1 "register_operand" "0")
12736 (match_operand:QI 2 "const1_operand" ""))))
12737 (clobber (reg:CC FLAGS_REG))]
12739 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12740 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12742 [(set_attr "type" "rotate")
12743 (set_attr "length_immediate" "0")
12744 (set_attr "mode" "SI")])
12746 (define_insn "*rotlsi3_1"
12747 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12748 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12749 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12750 (clobber (reg:CC FLAGS_REG))]
12751 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12753 rol{l}\t{%2, %0|%0, %2}
12754 rol{l}\t{%b2, %0|%0, %b2}"
12755 [(set_attr "type" "rotate")
12756 (set_attr "mode" "SI")])
12758 (define_insn "*rotlsi3_1_zext"
12759 [(set (match_operand:DI 0 "register_operand" "=r,r")
12761 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12762 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12763 (clobber (reg:CC FLAGS_REG))]
12764 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12766 rol{l}\t{%2, %k0|%k0, %2}
12767 rol{l}\t{%b2, %k0|%k0, %b2}"
12768 [(set_attr "type" "rotate")
12769 (set_attr "mode" "SI")])
12771 (define_expand "rotlhi3"
12772 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12773 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12774 (match_operand:QI 2 "nonmemory_operand" "")))]
12775 "TARGET_HIMODE_MATH"
12776 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12778 (define_insn "*rotlhi3_1_one_bit"
12779 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12780 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12781 (match_operand:QI 2 "const1_operand" "")))
12782 (clobber (reg:CC FLAGS_REG))]
12783 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12784 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12786 [(set_attr "type" "rotate")
12787 (set_attr "length_immediate" "0")
12788 (set_attr "mode" "HI")])
12790 (define_insn "*rotlhi3_1"
12791 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12792 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12793 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12794 (clobber (reg:CC FLAGS_REG))]
12795 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12797 rol{w}\t{%2, %0|%0, %2}
12798 rol{w}\t{%b2, %0|%0, %b2}"
12799 [(set_attr "type" "rotate")
12800 (set_attr "mode" "HI")])
12803 [(set (match_operand:HI 0 "register_operand" "")
12804 (rotate:HI (match_dup 0) (const_int 8)))
12805 (clobber (reg:CC FLAGS_REG))]
12807 [(parallel [(set (strict_low_part (match_dup 0))
12808 (bswap:HI (match_dup 0)))
12809 (clobber (reg:CC FLAGS_REG))])]
12812 (define_expand "rotlqi3"
12813 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12814 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12815 (match_operand:QI 2 "nonmemory_operand" "")))]
12816 "TARGET_QIMODE_MATH"
12817 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12819 (define_insn "*rotlqi3_1_one_bit_slp"
12820 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12821 (rotate:QI (match_dup 0)
12822 (match_operand:QI 1 "const1_operand" "")))
12823 (clobber (reg:CC FLAGS_REG))]
12824 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12825 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12827 [(set_attr "type" "rotate1")
12828 (set_attr "length_immediate" "0")
12829 (set_attr "mode" "QI")])
12831 (define_insn "*rotlqi3_1_one_bit"
12832 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12833 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12834 (match_operand:QI 2 "const1_operand" "")))
12835 (clobber (reg:CC FLAGS_REG))]
12836 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12837 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12839 [(set_attr "type" "rotate")
12840 (set_attr "length_immediate" "0")
12841 (set_attr "mode" "QI")])
12843 (define_insn "*rotlqi3_1_slp"
12844 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12845 (rotate:QI (match_dup 0)
12846 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12847 (clobber (reg:CC FLAGS_REG))]
12848 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12849 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12851 rol{b}\t{%1, %0|%0, %1}
12852 rol{b}\t{%b1, %0|%0, %b1}"
12853 [(set_attr "type" "rotate1")
12854 (set_attr "mode" "QI")])
12856 (define_insn "*rotlqi3_1"
12857 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12858 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12859 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12860 (clobber (reg:CC FLAGS_REG))]
12861 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12863 rol{b}\t{%2, %0|%0, %2}
12864 rol{b}\t{%b2, %0|%0, %b2}"
12865 [(set_attr "type" "rotate")
12866 (set_attr "mode" "QI")])
12868 (define_expand "rotrdi3"
12869 [(set (match_operand:DI 0 "shiftdi_operand" "")
12870 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12871 (match_operand:QI 2 "nonmemory_operand" "")))]
12876 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12879 if (!const_1_to_31_operand (operands[2], VOIDmode))
12881 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12885 ;; Implement rotation using two double-precision shift instructions
12886 ;; and a scratch register.
12887 (define_insn_and_split "ix86_rotrdi3"
12888 [(set (match_operand:DI 0 "register_operand" "=r")
12889 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12890 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12891 (clobber (reg:CC FLAGS_REG))
12892 (clobber (match_scratch:SI 3 "=&r"))]
12895 "&& reload_completed"
12896 [(set (match_dup 3) (match_dup 4))
12898 [(set (match_dup 4)
12899 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12900 (ashift:SI (match_dup 5)
12901 (minus:QI (const_int 32) (match_dup 2)))))
12902 (clobber (reg:CC FLAGS_REG))])
12904 [(set (match_dup 5)
12905 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12906 (ashift:SI (match_dup 3)
12907 (minus:QI (const_int 32) (match_dup 2)))))
12908 (clobber (reg:CC FLAGS_REG))])]
12909 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12911 (define_insn "*rotrdi3_1_one_bit_rex64"
12912 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12913 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12914 (match_operand:QI 2 "const1_operand" "")))
12915 (clobber (reg:CC FLAGS_REG))]
12917 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12918 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12920 [(set_attr "type" "rotate")
12921 (set_attr "length_immediate" "0")
12922 (set_attr "mode" "DI")])
12924 (define_insn "*rotrdi3_1_rex64"
12925 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12926 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12927 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12928 (clobber (reg:CC FLAGS_REG))]
12929 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12931 ror{q}\t{%2, %0|%0, %2}
12932 ror{q}\t{%b2, %0|%0, %b2}"
12933 [(set_attr "type" "rotate")
12934 (set_attr "mode" "DI")])
12936 (define_expand "rotrsi3"
12937 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12938 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12939 (match_operand:QI 2 "nonmemory_operand" "")))]
12941 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12943 (define_insn "*rotrsi3_1_one_bit"
12944 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12945 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12946 (match_operand:QI 2 "const1_operand" "")))
12947 (clobber (reg:CC FLAGS_REG))]
12948 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12949 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12951 [(set_attr "type" "rotate")
12952 (set_attr "length_immediate" "0")
12953 (set_attr "mode" "SI")])
12955 (define_insn "*rotrsi3_1_one_bit_zext"
12956 [(set (match_operand:DI 0 "register_operand" "=r")
12958 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12959 (match_operand:QI 2 "const1_operand" ""))))
12960 (clobber (reg:CC FLAGS_REG))]
12962 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12963 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12965 [(set_attr "type" "rotate")
12966 (set_attr "length_immediate" "0")
12967 (set_attr "mode" "SI")])
12969 (define_insn "*rotrsi3_1"
12970 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12971 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12972 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12973 (clobber (reg:CC FLAGS_REG))]
12974 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12976 ror{l}\t{%2, %0|%0, %2}
12977 ror{l}\t{%b2, %0|%0, %b2}"
12978 [(set_attr "type" "rotate")
12979 (set_attr "mode" "SI")])
12981 (define_insn "*rotrsi3_1_zext"
12982 [(set (match_operand:DI 0 "register_operand" "=r,r")
12984 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12985 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12986 (clobber (reg:CC FLAGS_REG))]
12987 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12989 ror{l}\t{%2, %k0|%k0, %2}
12990 ror{l}\t{%b2, %k0|%k0, %b2}"
12991 [(set_attr "type" "rotate")
12992 (set_attr "mode" "SI")])
12994 (define_expand "rotrhi3"
12995 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12996 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12997 (match_operand:QI 2 "nonmemory_operand" "")))]
12998 "TARGET_HIMODE_MATH"
12999 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
13001 (define_insn "*rotrhi3_one_bit"
13002 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13003 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13004 (match_operand:QI 2 "const1_operand" "")))
13005 (clobber (reg:CC FLAGS_REG))]
13006 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13007 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13009 [(set_attr "type" "rotate")
13010 (set_attr "length_immediate" "0")
13011 (set_attr "mode" "HI")])
13013 (define_insn "*rotrhi3_1"
13014 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13015 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13016 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13017 (clobber (reg:CC FLAGS_REG))]
13018 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
13020 ror{w}\t{%2, %0|%0, %2}
13021 ror{w}\t{%b2, %0|%0, %b2}"
13022 [(set_attr "type" "rotate")
13023 (set_attr "mode" "HI")])
13026 [(set (match_operand:HI 0 "register_operand" "")
13027 (rotatert:HI (match_dup 0) (const_int 8)))
13028 (clobber (reg:CC FLAGS_REG))]
13030 [(parallel [(set (strict_low_part (match_dup 0))
13031 (bswap:HI (match_dup 0)))
13032 (clobber (reg:CC FLAGS_REG))])]
13035 (define_expand "rotrqi3"
13036 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13037 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
13038 (match_operand:QI 2 "nonmemory_operand" "")))]
13039 "TARGET_QIMODE_MATH"
13040 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
13042 (define_insn "*rotrqi3_1_one_bit"
13043 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13044 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13045 (match_operand:QI 2 "const1_operand" "")))
13046 (clobber (reg:CC FLAGS_REG))]
13047 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13048 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13050 [(set_attr "type" "rotate")
13051 (set_attr "length_immediate" "0")
13052 (set_attr "mode" "QI")])
13054 (define_insn "*rotrqi3_1_one_bit_slp"
13055 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13056 (rotatert:QI (match_dup 0)
13057 (match_operand:QI 1 "const1_operand" "")))
13058 (clobber (reg:CC FLAGS_REG))]
13059 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13060 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13062 [(set_attr "type" "rotate1")
13063 (set_attr "length_immediate" "0")
13064 (set_attr "mode" "QI")])
13066 (define_insn "*rotrqi3_1"
13067 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13068 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13069 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13070 (clobber (reg:CC FLAGS_REG))]
13071 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
13073 ror{b}\t{%2, %0|%0, %2}
13074 ror{b}\t{%b2, %0|%0, %b2}"
13075 [(set_attr "type" "rotate")
13076 (set_attr "mode" "QI")])
13078 (define_insn "*rotrqi3_1_slp"
13079 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13080 (rotatert:QI (match_dup 0)
13081 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13082 (clobber (reg:CC FLAGS_REG))]
13083 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13084 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13086 ror{b}\t{%1, %0|%0, %1}
13087 ror{b}\t{%b1, %0|%0, %b1}"
13088 [(set_attr "type" "rotate1")
13089 (set_attr "mode" "QI")])
13091 ;; Bit set / bit test instructions
13093 (define_expand "extv"
13094 [(set (match_operand:SI 0 "register_operand" "")
13095 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
13096 (match_operand:SI 2 "const8_operand" "")
13097 (match_operand:SI 3 "const8_operand" "")))]
13100 /* Handle extractions from %ah et al. */
13101 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13104 /* From mips.md: extract_bit_field doesn't verify that our source
13105 matches the predicate, so check it again here. */
13106 if (! ext_register_operand (operands[1], VOIDmode))
13110 (define_expand "extzv"
13111 [(set (match_operand:SI 0 "register_operand" "")
13112 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
13113 (match_operand:SI 2 "const8_operand" "")
13114 (match_operand:SI 3 "const8_operand" "")))]
13117 /* Handle extractions from %ah et al. */
13118 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
13121 /* From mips.md: extract_bit_field doesn't verify that our source
13122 matches the predicate, so check it again here. */
13123 if (! ext_register_operand (operands[1], VOIDmode))
13127 (define_expand "insv"
13128 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
13129 (match_operand 1 "const8_operand" "")
13130 (match_operand 2 "const8_operand" ""))
13131 (match_operand 3 "register_operand" ""))]
13134 /* Handle insertions to %ah et al. */
13135 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
13138 /* From mips.md: insert_bit_field doesn't verify that our source
13139 matches the predicate, so check it again here. */
13140 if (! ext_register_operand (operands[0], VOIDmode))
13144 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
13146 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
13151 ;; %%% bts, btr, btc, bt.
13152 ;; In general these instructions are *slow* when applied to memory,
13153 ;; since they enforce atomic operation. When applied to registers,
13154 ;; it depends on the cpu implementation. They're never faster than
13155 ;; the corresponding and/ior/xor operations, so with 32-bit there's
13156 ;; no point. But in 64-bit, we can't hold the relevant immediates
13157 ;; within the instruction itself, so operating on bits in the high
13158 ;; 32-bits of a register becomes easier.
13160 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
13161 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
13162 ;; negdf respectively, so they can never be disabled entirely.
13164 (define_insn "*btsq"
13165 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13167 (match_operand:DI 1 "const_0_to_63_operand" ""))
13169 (clobber (reg:CC FLAGS_REG))]
13170 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13171 "bts{q}\t{%1, %0|%0, %1}"
13172 [(set_attr "type" "alu1")
13173 (set_attr "prefix_0f" "1")
13174 (set_attr "mode" "DI")])
13176 (define_insn "*btrq"
13177 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13179 (match_operand:DI 1 "const_0_to_63_operand" ""))
13181 (clobber (reg:CC FLAGS_REG))]
13182 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13183 "btr{q}\t{%1, %0|%0, %1}"
13184 [(set_attr "type" "alu1")
13185 (set_attr "prefix_0f" "1")
13186 (set_attr "mode" "DI")])
13188 (define_insn "*btcq"
13189 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
13191 (match_operand:DI 1 "const_0_to_63_operand" ""))
13192 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
13193 (clobber (reg:CC FLAGS_REG))]
13194 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
13195 "btc{q}\t{%1, %0|%0, %1}"
13196 [(set_attr "type" "alu1")
13197 (set_attr "prefix_0f" "1")
13198 (set_attr "mode" "DI")])
13200 ;; Allow Nocona to avoid these instructions if a register is available.
13203 [(match_scratch:DI 2 "r")
13204 (parallel [(set (zero_extract:DI
13205 (match_operand:DI 0 "register_operand" "")
13207 (match_operand:DI 1 "const_0_to_63_operand" ""))
13209 (clobber (reg:CC FLAGS_REG))])]
13210 "TARGET_64BIT && !TARGET_USE_BT"
13213 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13216 if (HOST_BITS_PER_WIDE_INT >= 64)
13217 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13218 else if (i < HOST_BITS_PER_WIDE_INT)
13219 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13221 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13223 op1 = immed_double_const (lo, hi, DImode);
13226 emit_move_insn (operands[2], op1);
13230 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
13235 [(match_scratch:DI 2 "r")
13236 (parallel [(set (zero_extract:DI
13237 (match_operand:DI 0 "register_operand" "")
13239 (match_operand:DI 1 "const_0_to_63_operand" ""))
13241 (clobber (reg:CC FLAGS_REG))])]
13242 "TARGET_64BIT && !TARGET_USE_BT"
13245 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13248 if (HOST_BITS_PER_WIDE_INT >= 64)
13249 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13250 else if (i < HOST_BITS_PER_WIDE_INT)
13251 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13253 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13255 op1 = immed_double_const (~lo, ~hi, DImode);
13258 emit_move_insn (operands[2], op1);
13262 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
13267 [(match_scratch:DI 2 "r")
13268 (parallel [(set (zero_extract:DI
13269 (match_operand:DI 0 "register_operand" "")
13271 (match_operand:DI 1 "const_0_to_63_operand" ""))
13272 (not:DI (zero_extract:DI
13273 (match_dup 0) (const_int 1) (match_dup 1))))
13274 (clobber (reg:CC FLAGS_REG))])]
13275 "TARGET_64BIT && !TARGET_USE_BT"
13278 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
13281 if (HOST_BITS_PER_WIDE_INT >= 64)
13282 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13283 else if (i < HOST_BITS_PER_WIDE_INT)
13284 lo = (HOST_WIDE_INT)1 << i, hi = 0;
13286 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
13288 op1 = immed_double_const (lo, hi, DImode);
13291 emit_move_insn (operands[2], op1);
13295 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
13299 (define_insn "*btdi_rex64"
13300 [(set (reg:CCC FLAGS_REG)
13303 (match_operand:DI 0 "register_operand" "r")
13305 (match_operand:DI 1 "nonmemory_operand" "rN"))
13307 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13308 "bt{q}\t{%1, %0|%0, %1}"
13309 [(set_attr "type" "alu1")
13310 (set_attr "prefix_0f" "1")
13311 (set_attr "mode" "DI")])
13313 (define_insn "*btsi"
13314 [(set (reg:CCC FLAGS_REG)
13317 (match_operand:SI 0 "register_operand" "r")
13319 (match_operand:SI 1 "nonmemory_operand" "rN"))
13321 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13322 "bt{l}\t{%1, %0|%0, %1}"
13323 [(set_attr "type" "alu1")
13324 (set_attr "prefix_0f" "1")
13325 (set_attr "mode" "SI")])
13327 ;; Store-flag instructions.
13329 ;; For all sCOND expanders, also expand the compare or test insn that
13330 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
13332 (define_insn_and_split "*setcc_di_1"
13333 [(set (match_operand:DI 0 "register_operand" "=q")
13334 (match_operator:DI 1 "ix86_comparison_operator"
13335 [(reg FLAGS_REG) (const_int 0)]))]
13336 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
13338 "&& reload_completed"
13339 [(set (match_dup 2) (match_dup 1))
13340 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
13342 PUT_MODE (operands[1], QImode);
13343 operands[2] = gen_lowpart (QImode, operands[0]);
13346 (define_insn_and_split "*setcc_si_1_and"
13347 [(set (match_operand:SI 0 "register_operand" "=q")
13348 (match_operator:SI 1 "ix86_comparison_operator"
13349 [(reg FLAGS_REG) (const_int 0)]))
13350 (clobber (reg:CC FLAGS_REG))]
13351 "!TARGET_PARTIAL_REG_STALL
13352 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
13354 "&& reload_completed"
13355 [(set (match_dup 2) (match_dup 1))
13356 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
13357 (clobber (reg:CC FLAGS_REG))])]
13359 PUT_MODE (operands[1], QImode);
13360 operands[2] = gen_lowpart (QImode, operands[0]);
13363 (define_insn_and_split "*setcc_si_1_movzbl"
13364 [(set (match_operand:SI 0 "register_operand" "=q")
13365 (match_operator:SI 1 "ix86_comparison_operator"
13366 [(reg FLAGS_REG) (const_int 0)]))]
13367 "!TARGET_PARTIAL_REG_STALL
13368 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
13370 "&& reload_completed"
13371 [(set (match_dup 2) (match_dup 1))
13372 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
13374 PUT_MODE (operands[1], QImode);
13375 operands[2] = gen_lowpart (QImode, operands[0]);
13378 (define_insn "*setcc_qi"
13379 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13380 (match_operator:QI 1 "ix86_comparison_operator"
13381 [(reg FLAGS_REG) (const_int 0)]))]
13384 [(set_attr "type" "setcc")
13385 (set_attr "mode" "QI")])
13387 (define_insn "*setcc_qi_slp"
13388 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13389 (match_operator:QI 1 "ix86_comparison_operator"
13390 [(reg FLAGS_REG) (const_int 0)]))]
13393 [(set_attr "type" "setcc")
13394 (set_attr "mode" "QI")])
13396 ;; In general it is not safe to assume too much about CCmode registers,
13397 ;; so simplify-rtx stops when it sees a second one. Under certain
13398 ;; conditions this is safe on x86, so help combine not create
13405 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13406 (ne:QI (match_operator 1 "ix86_comparison_operator"
13407 [(reg FLAGS_REG) (const_int 0)])
13410 [(set (match_dup 0) (match_dup 1))]
13412 PUT_MODE (operands[1], QImode);
13416 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13417 (ne:QI (match_operator 1 "ix86_comparison_operator"
13418 [(reg FLAGS_REG) (const_int 0)])
13421 [(set (match_dup 0) (match_dup 1))]
13423 PUT_MODE (operands[1], QImode);
13427 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13428 (eq:QI (match_operator 1 "ix86_comparison_operator"
13429 [(reg FLAGS_REG) (const_int 0)])
13432 [(set (match_dup 0) (match_dup 1))]
13434 rtx new_op1 = copy_rtx (operands[1]);
13435 operands[1] = new_op1;
13436 PUT_MODE (new_op1, QImode);
13437 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13438 GET_MODE (XEXP (new_op1, 0))));
13440 /* Make sure that (a) the CCmode we have for the flags is strong
13441 enough for the reversed compare or (b) we have a valid FP compare. */
13442 if (! ix86_comparison_operator (new_op1, VOIDmode))
13447 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
13448 (eq:QI (match_operator 1 "ix86_comparison_operator"
13449 [(reg FLAGS_REG) (const_int 0)])
13452 [(set (match_dup 0) (match_dup 1))]
13454 rtx new_op1 = copy_rtx (operands[1]);
13455 operands[1] = new_op1;
13456 PUT_MODE (new_op1, QImode);
13457 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
13458 GET_MODE (XEXP (new_op1, 0))));
13460 /* Make sure that (a) the CCmode we have for the flags is strong
13461 enough for the reversed compare or (b) we have a valid FP compare. */
13462 if (! ix86_comparison_operator (new_op1, VOIDmode))
13466 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
13467 ;; subsequent logical operations are used to imitate conditional moves.
13468 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
13471 (define_insn "*avx_setcc<mode>"
13472 [(set (match_operand:MODEF 0 "register_operand" "=x")
13473 (match_operator:MODEF 1 "avx_comparison_float_operator"
13474 [(match_operand:MODEF 2 "register_operand" "x")
13475 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13477 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
13478 [(set_attr "type" "ssecmp")
13479 (set_attr "prefix" "vex")
13480 (set_attr "length_immediate" "1")
13481 (set_attr "mode" "<MODE>")])
13483 (define_insn "*sse_setcc<mode>"
13484 [(set (match_operand:MODEF 0 "register_operand" "=x")
13485 (match_operator:MODEF 1 "sse_comparison_operator"
13486 [(match_operand:MODEF 2 "register_operand" "0")
13487 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
13488 "SSE_FLOAT_MODE_P (<MODE>mode)"
13489 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
13490 [(set_attr "type" "ssecmp")
13491 (set_attr "length_immediate" "1")
13492 (set_attr "mode" "<MODE>")])
13494 ;; Basic conditional jump instructions.
13495 ;; We ignore the overflow flag for signed branch instructions.
13497 (define_insn "*jcc_1"
13499 (if_then_else (match_operator 1 "ix86_comparison_operator"
13500 [(reg FLAGS_REG) (const_int 0)])
13501 (label_ref (match_operand 0 "" ""))
13505 [(set_attr "type" "ibr")
13506 (set_attr "modrm" "0")
13507 (set (attr "length")
13508 (if_then_else (and (ge (minus (match_dup 0) (pc))
13510 (lt (minus (match_dup 0) (pc))
13515 (define_insn "*jcc_2"
13517 (if_then_else (match_operator 1 "ix86_comparison_operator"
13518 [(reg FLAGS_REG) (const_int 0)])
13520 (label_ref (match_operand 0 "" ""))))]
13523 [(set_attr "type" "ibr")
13524 (set_attr "modrm" "0")
13525 (set (attr "length")
13526 (if_then_else (and (ge (minus (match_dup 0) (pc))
13528 (lt (minus (match_dup 0) (pc))
13533 ;; In general it is not safe to assume too much about CCmode registers,
13534 ;; so simplify-rtx stops when it sees a second one. Under certain
13535 ;; conditions this is safe on x86, so help combine not create
13543 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
13544 [(reg FLAGS_REG) (const_int 0)])
13546 (label_ref (match_operand 1 "" ""))
13550 (if_then_else (match_dup 0)
13551 (label_ref (match_dup 1))
13554 PUT_MODE (operands[0], VOIDmode);
13559 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
13560 [(reg FLAGS_REG) (const_int 0)])
13562 (label_ref (match_operand 1 "" ""))
13566 (if_then_else (match_dup 0)
13567 (label_ref (match_dup 1))
13570 rtx new_op0 = copy_rtx (operands[0]);
13571 operands[0] = new_op0;
13572 PUT_MODE (new_op0, VOIDmode);
13573 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
13574 GET_MODE (XEXP (new_op0, 0))));
13576 /* Make sure that (a) the CCmode we have for the flags is strong
13577 enough for the reversed compare or (b) we have a valid FP compare. */
13578 if (! ix86_comparison_operator (new_op0, VOIDmode))
13582 ;; zero_extend in SImode is correct, since this is what combine pass
13583 ;; generates from shift insn with QImode operand. Actually, the mode of
13584 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
13585 ;; appropriate modulo of the bit offset value.
13587 (define_insn_and_split "*jcc_btdi_rex64"
13589 (if_then_else (match_operator 0 "bt_comparison_operator"
13591 (match_operand:DI 1 "register_operand" "r")
13594 (match_operand:QI 2 "register_operand" "r")))
13596 (label_ref (match_operand 3 "" ""))
13598 (clobber (reg:CC FLAGS_REG))]
13599 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
13602 [(set (reg:CCC FLAGS_REG)
13610 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13611 (label_ref (match_dup 3))
13614 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
13616 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13619 ;; avoid useless masking of bit offset operand
13620 (define_insn_and_split "*jcc_btdi_mask_rex64"
13622 (if_then_else (match_operator 0 "bt_comparison_operator"
13624 (match_operand:DI 1 "register_operand" "r")
13627 (match_operand:SI 2 "register_operand" "r")
13628 (match_operand:SI 3 "const_int_operand" "n")))])
13629 (label_ref (match_operand 4 "" ""))
13631 (clobber (reg:CC FLAGS_REG))]
13632 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
13633 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
13636 [(set (reg:CCC FLAGS_REG)
13644 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13645 (label_ref (match_dup 4))
13648 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
13650 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13653 (define_insn_and_split "*jcc_btsi"
13655 (if_then_else (match_operator 0 "bt_comparison_operator"
13657 (match_operand:SI 1 "register_operand" "r")
13660 (match_operand:QI 2 "register_operand" "r")))
13662 (label_ref (match_operand 3 "" ""))
13664 (clobber (reg:CC FLAGS_REG))]
13665 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13668 [(set (reg:CCC FLAGS_REG)
13676 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13677 (label_ref (match_dup 3))
13680 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13682 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13685 ;; avoid useless masking of bit offset operand
13686 (define_insn_and_split "*jcc_btsi_mask"
13688 (if_then_else (match_operator 0 "bt_comparison_operator"
13690 (match_operand:SI 1 "register_operand" "r")
13693 (match_operand:SI 2 "register_operand" "r")
13694 (match_operand:SI 3 "const_int_operand" "n")))])
13695 (label_ref (match_operand 4 "" ""))
13697 (clobber (reg:CC FLAGS_REG))]
13698 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13699 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13702 [(set (reg:CCC FLAGS_REG)
13710 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13711 (label_ref (match_dup 4))
13713 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13715 (define_insn_and_split "*jcc_btsi_1"
13717 (if_then_else (match_operator 0 "bt_comparison_operator"
13720 (match_operand:SI 1 "register_operand" "r")
13721 (match_operand:QI 2 "register_operand" "r"))
13724 (label_ref (match_operand 3 "" ""))
13726 (clobber (reg:CC FLAGS_REG))]
13727 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
13730 [(set (reg:CCC FLAGS_REG)
13738 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13739 (label_ref (match_dup 3))
13742 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
13744 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13747 ;; avoid useless masking of bit offset operand
13748 (define_insn_and_split "*jcc_btsi_mask_1"
13751 (match_operator 0 "bt_comparison_operator"
13754 (match_operand:SI 1 "register_operand" "r")
13757 (match_operand:SI 2 "register_operand" "r")
13758 (match_operand:SI 3 "const_int_operand" "n")) 0))
13761 (label_ref (match_operand 4 "" ""))
13763 (clobber (reg:CC FLAGS_REG))]
13764 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13765 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13768 [(set (reg:CCC FLAGS_REG)
13776 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13777 (label_ref (match_dup 4))
13779 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13781 ;; Define combination compare-and-branch fp compare instructions to help
13784 (define_insn "*fp_jcc_3_387"
13786 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13787 [(match_operand 1 "register_operand" "f")
13788 (match_operand 2 "nonimmediate_operand" "fm")])
13789 (label_ref (match_operand 3 "" ""))
13791 (clobber (reg:CCFP FPSR_REG))
13792 (clobber (reg:CCFP FLAGS_REG))
13793 (clobber (match_scratch:HI 4 "=a"))]
13795 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13796 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13797 && SELECT_CC_MODE (GET_CODE (operands[0]),
13798 operands[1], operands[2]) == CCFPmode
13802 (define_insn "*fp_jcc_4_387"
13804 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13805 [(match_operand 1 "register_operand" "f")
13806 (match_operand 2 "nonimmediate_operand" "fm")])
13808 (label_ref (match_operand 3 "" ""))))
13809 (clobber (reg:CCFP FPSR_REG))
13810 (clobber (reg:CCFP FLAGS_REG))
13811 (clobber (match_scratch:HI 4 "=a"))]
13813 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13814 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13815 && SELECT_CC_MODE (GET_CODE (operands[0]),
13816 operands[1], operands[2]) == CCFPmode
13820 (define_insn "*fp_jcc_5_387"
13822 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13823 [(match_operand 1 "register_operand" "f")
13824 (match_operand 2 "register_operand" "f")])
13825 (label_ref (match_operand 3 "" ""))
13827 (clobber (reg:CCFP FPSR_REG))
13828 (clobber (reg:CCFP FLAGS_REG))
13829 (clobber (match_scratch:HI 4 "=a"))]
13830 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13831 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13835 (define_insn "*fp_jcc_6_387"
13837 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13838 [(match_operand 1 "register_operand" "f")
13839 (match_operand 2 "register_operand" "f")])
13841 (label_ref (match_operand 3 "" ""))))
13842 (clobber (reg:CCFP FPSR_REG))
13843 (clobber (reg:CCFP FLAGS_REG))
13844 (clobber (match_scratch:HI 4 "=a"))]
13845 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13846 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13850 (define_insn "*fp_jcc_7_387"
13852 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13853 [(match_operand 1 "register_operand" "f")
13854 (match_operand 2 "const0_operand" "")])
13855 (label_ref (match_operand 3 "" ""))
13857 (clobber (reg:CCFP FPSR_REG))
13858 (clobber (reg:CCFP FLAGS_REG))
13859 (clobber (match_scratch:HI 4 "=a"))]
13860 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13861 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13862 && SELECT_CC_MODE (GET_CODE (operands[0]),
13863 operands[1], operands[2]) == CCFPmode
13867 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13868 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13869 ;; with a precedence over other operators and is always put in the first
13870 ;; place. Swap condition and operands to match ficom instruction.
13872 (define_insn "*fp_jcc_8<mode>_387"
13874 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13875 [(match_operator 1 "float_operator"
13876 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13877 (match_operand 3 "register_operand" "f,f")])
13878 (label_ref (match_operand 4 "" ""))
13880 (clobber (reg:CCFP FPSR_REG))
13881 (clobber (reg:CCFP FLAGS_REG))
13882 (clobber (match_scratch:HI 5 "=a,a"))]
13883 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13884 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13885 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13886 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13892 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13893 [(match_operand 1 "register_operand" "")
13894 (match_operand 2 "nonimmediate_operand" "")])
13895 (match_operand 3 "" "")
13896 (match_operand 4 "" "")))
13897 (clobber (reg:CCFP FPSR_REG))
13898 (clobber (reg:CCFP FLAGS_REG))]
13902 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13903 operands[3], operands[4], NULL_RTX, NULL_RTX);
13909 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13910 [(match_operand 1 "register_operand" "")
13911 (match_operand 2 "general_operand" "")])
13912 (match_operand 3 "" "")
13913 (match_operand 4 "" "")))
13914 (clobber (reg:CCFP FPSR_REG))
13915 (clobber (reg:CCFP FLAGS_REG))
13916 (clobber (match_scratch:HI 5 "=a"))]
13920 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13921 operands[3], operands[4], operands[5], NULL_RTX);
13927 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13928 [(match_operator 1 "float_operator"
13929 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13930 (match_operand 3 "register_operand" "")])
13931 (match_operand 4 "" "")
13932 (match_operand 5 "" "")))
13933 (clobber (reg:CCFP FPSR_REG))
13934 (clobber (reg:CCFP FLAGS_REG))
13935 (clobber (match_scratch:HI 6 "=a"))]
13939 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13940 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13941 operands[3], operands[7],
13942 operands[4], operands[5], operands[6], NULL_RTX);
13946 ;; %%% Kill this when reload knows how to do it.
13949 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13950 [(match_operator 1 "float_operator"
13951 [(match_operand:X87MODEI12 2 "register_operand" "")])
13952 (match_operand 3 "register_operand" "")])
13953 (match_operand 4 "" "")
13954 (match_operand 5 "" "")))
13955 (clobber (reg:CCFP FPSR_REG))
13956 (clobber (reg:CCFP FLAGS_REG))
13957 (clobber (match_scratch:HI 6 "=a"))]
13961 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13962 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13963 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13964 operands[3], operands[7],
13965 operands[4], operands[5], operands[6], operands[2]);
13969 ;; Unconditional and other jump instructions
13971 (define_insn "jump"
13973 (label_ref (match_operand 0 "" "")))]
13976 [(set_attr "type" "ibr")
13977 (set (attr "length")
13978 (if_then_else (and (ge (minus (match_dup 0) (pc))
13980 (lt (minus (match_dup 0) (pc))
13984 (set_attr "modrm" "0")])
13986 (define_expand "indirect_jump"
13987 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13991 (define_insn "*indirect_jump"
13992 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13995 [(set_attr "type" "ibr")
13996 (set_attr "length_immediate" "0")])
13998 (define_expand "tablejump"
13999 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
14000 (use (label_ref (match_operand 1 "" "")))])]
14003 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
14004 relative. Convert the relative address to an absolute address. */
14008 enum rtx_code code;
14010 /* We can't use @GOTOFF for text labels on VxWorks;
14011 see gotoff_operand. */
14012 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
14016 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
14018 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
14022 op1 = pic_offset_table_rtx;
14027 op0 = pic_offset_table_rtx;
14031 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
14036 (define_insn "*tablejump_1"
14037 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
14038 (use (label_ref (match_operand 1 "" "")))]
14041 [(set_attr "type" "ibr")
14042 (set_attr "length_immediate" "0")])
14044 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
14047 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14048 (set (match_operand:QI 1 "register_operand" "")
14049 (match_operator:QI 2 "ix86_comparison_operator"
14050 [(reg FLAGS_REG) (const_int 0)]))
14051 (set (match_operand 3 "q_regs_operand" "")
14052 (zero_extend (match_dup 1)))]
14053 "(peep2_reg_dead_p (3, operands[1])
14054 || operands_match_p (operands[1], operands[3]))
14055 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14056 [(set (match_dup 4) (match_dup 0))
14057 (set (strict_low_part (match_dup 5))
14060 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14061 operands[5] = gen_lowpart (QImode, operands[3]);
14062 ix86_expand_clear (operands[3]);
14065 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
14068 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
14069 (set (match_operand:QI 1 "register_operand" "")
14070 (match_operator:QI 2 "ix86_comparison_operator"
14071 [(reg FLAGS_REG) (const_int 0)]))
14072 (parallel [(set (match_operand 3 "q_regs_operand" "")
14073 (zero_extend (match_dup 1)))
14074 (clobber (reg:CC FLAGS_REG))])]
14075 "(peep2_reg_dead_p (3, operands[1])
14076 || operands_match_p (operands[1], operands[3]))
14077 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
14078 [(set (match_dup 4) (match_dup 0))
14079 (set (strict_low_part (match_dup 5))
14082 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
14083 operands[5] = gen_lowpart (QImode, operands[3]);
14084 ix86_expand_clear (operands[3]);
14087 ;; Call instructions.
14089 ;; The predicates normally associated with named expanders are not properly
14090 ;; checked for calls. This is a bug in the generic code, but it isn't that
14091 ;; easy to fix. Ignore it for now and be prepared to fix things up.
14093 ;; P6 processors will jump to the address after the decrement when %esp
14094 ;; is used as a call operand, so they will execute return address as a code.
14095 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
14097 ;; Call subroutine returning no value.
14099 (define_expand "call_pop"
14100 [(parallel [(call (match_operand:QI 0 "" "")
14101 (match_operand:SI 1 "" ""))
14102 (set (reg:SI SP_REG)
14103 (plus:SI (reg:SI SP_REG)
14104 (match_operand:SI 3 "" "")))])]
14107 ix86_expand_call (NULL, operands[0], operands[1],
14108 operands[2], operands[3], 0);
14112 (define_insn "*call_pop_0"
14113 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
14114 (match_operand:SI 1 "" ""))
14115 (set (reg:SI SP_REG)
14116 (plus:SI (reg:SI SP_REG)
14117 (match_operand:SI 2 "immediate_operand" "")))]
14120 if (SIBLING_CALL_P (insn))
14123 return "call\t%P0";
14125 [(set_attr "type" "call")])
14127 (define_insn "*call_pop_1"
14128 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14129 (match_operand:SI 1 "" ""))
14130 (set (reg:SI SP_REG)
14131 (plus:SI (reg:SI SP_REG)
14132 (match_operand:SI 2 "immediate_operand" "i")))]
14133 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14135 if (constant_call_address_operand (operands[0], Pmode))
14136 return "call\t%P0";
14137 return "call\t%A0";
14139 [(set_attr "type" "call")])
14141 (define_insn "*sibcall_pop_1"
14142 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14143 (match_operand:SI 1 "" ""))
14144 (set (reg:SI SP_REG)
14145 (plus:SI (reg:SI SP_REG)
14146 (match_operand:SI 2 "immediate_operand" "i,i")))]
14147 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14151 [(set_attr "type" "call")])
14153 (define_expand "call"
14154 [(call (match_operand:QI 0 "" "")
14155 (match_operand 1 "" ""))
14156 (use (match_operand 2 "" ""))]
14159 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
14163 (define_expand "sibcall"
14164 [(call (match_operand:QI 0 "" "")
14165 (match_operand 1 "" ""))
14166 (use (match_operand 2 "" ""))]
14169 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
14173 (define_insn "*call_0"
14174 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
14175 (match_operand 1 "" ""))]
14178 if (SIBLING_CALL_P (insn))
14181 return "call\t%P0";
14183 [(set_attr "type" "call")])
14185 (define_insn "*call_1"
14186 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
14187 (match_operand 1 "" ""))]
14188 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
14190 if (constant_call_address_operand (operands[0], Pmode))
14191 return "call\t%P0";
14192 return "call\t%A0";
14194 [(set_attr "type" "call")])
14196 (define_insn "*sibcall_1"
14197 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
14198 (match_operand 1 "" ""))]
14199 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
14203 [(set_attr "type" "call")])
14205 (define_insn "*call_1_rex64"
14206 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14207 (match_operand 1 "" ""))]
14208 "TARGET_64BIT && !SIBLING_CALL_P (insn)
14209 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
14211 if (constant_call_address_operand (operands[0], Pmode))
14212 return "call\t%P0";
14213 return "call\t%A0";
14215 [(set_attr "type" "call")])
14217 (define_insn "*call_1_rex64_ms_sysv"
14218 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
14219 (match_operand 1 "" ""))
14220 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
14221 (clobber (reg:TI XMM6_REG))
14222 (clobber (reg:TI XMM7_REG))
14223 (clobber (reg:TI XMM8_REG))
14224 (clobber (reg:TI XMM9_REG))
14225 (clobber (reg:TI XMM10_REG))
14226 (clobber (reg:TI XMM11_REG))
14227 (clobber (reg:TI XMM12_REG))
14228 (clobber (reg:TI XMM13_REG))
14229 (clobber (reg:TI XMM14_REG))
14230 (clobber (reg:TI XMM15_REG))
14231 (clobber (reg:DI SI_REG))
14232 (clobber (reg:DI DI_REG))]
14233 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14235 if (constant_call_address_operand (operands[0], Pmode))
14236 return "call\t%P0";
14237 return "call\t%A0";
14239 [(set_attr "type" "call")])
14241 (define_insn "*call_1_rex64_large"
14242 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
14243 (match_operand 1 "" ""))]
14244 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
14246 [(set_attr "type" "call")])
14248 (define_insn "*sibcall_1_rex64"
14249 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
14250 (match_operand 1 "" ""))]
14251 "TARGET_64BIT && SIBLING_CALL_P (insn)"
14255 [(set_attr "type" "call")])
14257 ;; Call subroutine, returning value in operand 0
14258 (define_expand "call_value_pop"
14259 [(parallel [(set (match_operand 0 "" "")
14260 (call (match_operand:QI 1 "" "")
14261 (match_operand:SI 2 "" "")))
14262 (set (reg:SI SP_REG)
14263 (plus:SI (reg:SI SP_REG)
14264 (match_operand:SI 4 "" "")))])]
14267 ix86_expand_call (operands[0], operands[1], operands[2],
14268 operands[3], operands[4], 0);
14272 (define_expand "call_value"
14273 [(set (match_operand 0 "" "")
14274 (call (match_operand:QI 1 "" "")
14275 (match_operand:SI 2 "" "")))
14276 (use (match_operand:SI 3 "" ""))]
14277 ;; Operand 3 is not used on the i386.
14280 ix86_expand_call (operands[0], operands[1], operands[2],
14281 operands[3], NULL, 0);
14285 (define_expand "sibcall_value"
14286 [(set (match_operand 0 "" "")
14287 (call (match_operand:QI 1 "" "")
14288 (match_operand:SI 2 "" "")))
14289 (use (match_operand:SI 3 "" ""))]
14290 ;; Operand 3 is not used on the i386.
14293 ix86_expand_call (operands[0], operands[1], operands[2],
14294 operands[3], NULL, 1);
14298 ;; Call subroutine returning any type.
14300 (define_expand "untyped_call"
14301 [(parallel [(call (match_operand 0 "" "")
14303 (match_operand 1 "" "")
14304 (match_operand 2 "" "")])]
14309 /* In order to give reg-stack an easier job in validating two
14310 coprocessor registers as containing a possible return value,
14311 simply pretend the untyped call returns a complex long double
14314 We can't use SSE_REGPARM_MAX here since callee is unprototyped
14315 and should have the default ABI. */
14317 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
14318 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
14319 operands[0], const0_rtx,
14320 GEN_INT ((TARGET_64BIT
14321 ? (ix86_abi == SYSV_ABI
14322 ? X86_64_SSE_REGPARM_MAX
14323 : X86_64_MS_SSE_REGPARM_MAX)
14324 : X86_32_SSE_REGPARM_MAX)
14328 for (i = 0; i < XVECLEN (operands[2], 0); i++)
14330 rtx set = XVECEXP (operands[2], 0, i);
14331 emit_move_insn (SET_DEST (set), SET_SRC (set));
14334 /* The optimizer does not know that the call sets the function value
14335 registers we stored in the result block. We avoid problems by
14336 claiming that all hard registers are used and clobbered at this
14338 emit_insn (gen_blockage ());
14343 ;; Prologue and epilogue instructions
14345 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
14346 ;; all of memory. This blocks insns from being moved across this point.
14348 (define_insn "blockage"
14349 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
14352 [(set_attr "length" "0")])
14354 ;; Do not schedule instructions accessing memory across this point.
14356 (define_expand "memory_blockage"
14357 [(set (match_dup 0)
14358 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14361 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
14362 MEM_VOLATILE_P (operands[0]) = 1;
14365 (define_insn "*memory_blockage"
14366 [(set (match_operand:BLK 0 "" "")
14367 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
14370 [(set_attr "length" "0")])
14372 ;; As USE insns aren't meaningful after reload, this is used instead
14373 ;; to prevent deleting instructions setting registers for PIC code
14374 (define_insn "prologue_use"
14375 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
14378 [(set_attr "length" "0")])
14380 ;; Insn emitted into the body of a function to return from a function.
14381 ;; This is only done if the function's epilogue is known to be simple.
14382 ;; See comments for ix86_can_use_return_insn_p in i386.c.
14384 (define_expand "return"
14386 "ix86_can_use_return_insn_p ()"
14388 if (crtl->args.pops_args)
14390 rtx popc = GEN_INT (crtl->args.pops_args);
14391 emit_jump_insn (gen_return_pop_internal (popc));
14396 (define_insn "return_internal"
14400 [(set_attr "length" "1")
14401 (set_attr "atom_unit" "jeu")
14402 (set_attr "length_immediate" "0")
14403 (set_attr "modrm" "0")])
14405 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
14406 ;; instruction Athlon and K8 have.
14408 (define_insn "return_internal_long"
14410 (unspec [(const_int 0)] UNSPEC_REP)]
14413 [(set_attr "length" "2")
14414 (set_attr "atom_unit" "jeu")
14415 (set_attr "length_immediate" "0")
14416 (set_attr "prefix_rep" "1")
14417 (set_attr "modrm" "0")])
14419 (define_insn "return_pop_internal"
14421 (use (match_operand:SI 0 "const_int_operand" ""))]
14424 [(set_attr "length" "3")
14425 (set_attr "atom_unit" "jeu")
14426 (set_attr "length_immediate" "2")
14427 (set_attr "modrm" "0")])
14429 (define_insn "return_indirect_internal"
14431 (use (match_operand:SI 0 "register_operand" "r"))]
14434 [(set_attr "type" "ibr")
14435 (set_attr "length_immediate" "0")])
14441 [(set_attr "length" "1")
14442 (set_attr "length_immediate" "0")
14443 (set_attr "modrm" "0")])
14445 (define_insn "vswapmov"
14446 [(set (match_operand:SI 0 "register_operand" "=r")
14447 (match_operand:SI 1 "register_operand" "r"))
14448 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
14450 "movl.s\t{%1, %0|%0, %1}"
14451 [(set_attr "length" "2")
14452 (set_attr "length_immediate" "0")
14453 (set_attr "modrm" "0")])
14455 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
14456 ;; branch prediction penalty for the third jump in a 16-byte
14460 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
14463 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
14464 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
14466 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
14467 The align insn is used to avoid 3 jump instructions in the row to improve
14468 branch prediction and the benefits hardly outweigh the cost of extra 8
14469 nops on the average inserted by full alignment pseudo operation. */
14473 [(set_attr "length" "16")])
14475 (define_expand "prologue"
14478 "ix86_expand_prologue (); DONE;")
14480 (define_insn "set_got"
14481 [(set (match_operand:SI 0 "register_operand" "=r")
14482 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
14483 (clobber (reg:CC FLAGS_REG))]
14485 { return output_set_got (operands[0], NULL_RTX); }
14486 [(set_attr "type" "multi")
14487 (set_attr "length" "12")])
14489 (define_insn "set_got_labelled"
14490 [(set (match_operand:SI 0 "register_operand" "=r")
14491 (unspec:SI [(label_ref (match_operand 1 "" ""))]
14493 (clobber (reg:CC FLAGS_REG))]
14495 { return output_set_got (operands[0], operands[1]); }
14496 [(set_attr "type" "multi")
14497 (set_attr "length" "12")])
14499 (define_insn "set_got_rex64"
14500 [(set (match_operand:DI 0 "register_operand" "=r")
14501 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
14503 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
14504 [(set_attr "type" "lea")
14505 (set_attr "length_address" "4")
14506 (set_attr "mode" "DI")])
14508 (define_insn "set_rip_rex64"
14509 [(set (match_operand:DI 0 "register_operand" "=r")
14510 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
14512 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
14513 [(set_attr "type" "lea")
14514 (set_attr "length_address" "4")
14515 (set_attr "mode" "DI")])
14517 (define_insn "set_got_offset_rex64"
14518 [(set (match_operand:DI 0 "register_operand" "=r")
14520 [(label_ref (match_operand 1 "" ""))]
14521 UNSPEC_SET_GOT_OFFSET))]
14523 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
14524 [(set_attr "type" "imov")
14525 (set_attr "length_immediate" "0")
14526 (set_attr "length_address" "8")
14527 (set_attr "mode" "DI")])
14529 (define_expand "epilogue"
14532 "ix86_expand_epilogue (1); DONE;")
14534 (define_expand "sibcall_epilogue"
14537 "ix86_expand_epilogue (0); DONE;")
14539 (define_expand "eh_return"
14540 [(use (match_operand 0 "register_operand" ""))]
14543 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
14545 /* Tricky bit: we write the address of the handler to which we will
14546 be returning into someone else's stack frame, one word below the
14547 stack address we wish to restore. */
14548 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
14549 tmp = plus_constant (tmp, -UNITS_PER_WORD);
14550 tmp = gen_rtx_MEM (Pmode, tmp);
14551 emit_move_insn (tmp, ra);
14553 emit_jump_insn (gen_eh_return_internal ());
14558 (define_insn_and_split "eh_return_internal"
14562 "epilogue_completed"
14564 "ix86_expand_epilogue (2); DONE;")
14566 (define_insn "leave"
14567 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
14568 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
14569 (clobber (mem:BLK (scratch)))]
14572 [(set_attr "type" "leave")])
14574 (define_insn "leave_rex64"
14575 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
14576 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
14577 (clobber (mem:BLK (scratch)))]
14580 [(set_attr "type" "leave")])
14582 (define_expand "ffssi2"
14584 [(set (match_operand:SI 0 "register_operand" "")
14585 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
14586 (clobber (match_scratch:SI 2 ""))
14587 (clobber (reg:CC FLAGS_REG))])]
14592 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
14597 (define_expand "ffs_cmove"
14598 [(set (match_dup 2) (const_int -1))
14599 (parallel [(set (reg:CCZ FLAGS_REG)
14600 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
14602 (set (match_operand:SI 0 "register_operand" "")
14603 (ctz:SI (match_dup 1)))])
14604 (set (match_dup 0) (if_then_else:SI
14605 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14608 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14609 (clobber (reg:CC FLAGS_REG))])]
14611 "operands[2] = gen_reg_rtx (SImode);")
14613 (define_insn_and_split "*ffs_no_cmove"
14614 [(set (match_operand:SI 0 "register_operand" "=r")
14615 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14616 (clobber (match_scratch:SI 2 "=&q"))
14617 (clobber (reg:CC FLAGS_REG))]
14620 "&& reload_completed"
14621 [(parallel [(set (reg:CCZ FLAGS_REG)
14622 (compare:CCZ (match_dup 1) (const_int 0)))
14623 (set (match_dup 0) (ctz:SI (match_dup 1)))])
14624 (set (strict_low_part (match_dup 3))
14625 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
14626 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
14627 (clobber (reg:CC FLAGS_REG))])
14628 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
14629 (clobber (reg:CC FLAGS_REG))])
14630 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
14631 (clobber (reg:CC FLAGS_REG))])]
14633 operands[3] = gen_lowpart (QImode, operands[2]);
14634 ix86_expand_clear (operands[2]);
14637 (define_insn "*ffssi_1"
14638 [(set (reg:CCZ FLAGS_REG)
14639 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
14641 (set (match_operand:SI 0 "register_operand" "=r")
14642 (ctz:SI (match_dup 1)))]
14644 "bsf{l}\t{%1, %0|%0, %1}"
14645 [(set_attr "type" "alu1")
14646 (set_attr "prefix_0f" "1")
14647 (set_attr "mode" "SI")])
14649 (define_expand "ffsdi2"
14650 [(set (match_dup 2) (const_int -1))
14651 (parallel [(set (reg:CCZ FLAGS_REG)
14652 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
14654 (set (match_operand:DI 0 "register_operand" "")
14655 (ctz:DI (match_dup 1)))])
14656 (set (match_dup 0) (if_then_else:DI
14657 (eq (reg:CCZ FLAGS_REG) (const_int 0))
14660 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
14661 (clobber (reg:CC FLAGS_REG))])]
14663 "operands[2] = gen_reg_rtx (DImode);")
14665 (define_insn "*ffsdi_1"
14666 [(set (reg:CCZ FLAGS_REG)
14667 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
14669 (set (match_operand:DI 0 "register_operand" "=r")
14670 (ctz:DI (match_dup 1)))]
14672 "bsf{q}\t{%1, %0|%0, %1}"
14673 [(set_attr "type" "alu1")
14674 (set_attr "prefix_0f" "1")
14675 (set_attr "mode" "DI")])
14677 (define_insn "ctzsi2"
14678 [(set (match_operand:SI 0 "register_operand" "=r")
14679 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14680 (clobber (reg:CC FLAGS_REG))]
14682 "bsf{l}\t{%1, %0|%0, %1}"
14683 [(set_attr "type" "alu1")
14684 (set_attr "prefix_0f" "1")
14685 (set_attr "mode" "SI")])
14687 (define_insn "ctzdi2"
14688 [(set (match_operand:DI 0 "register_operand" "=r")
14689 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14690 (clobber (reg:CC FLAGS_REG))]
14692 "bsf{q}\t{%1, %0|%0, %1}"
14693 [(set_attr "type" "alu1")
14694 (set_attr "prefix_0f" "1")
14695 (set_attr "mode" "DI")])
14697 (define_expand "clzsi2"
14699 [(set (match_operand:SI 0 "register_operand" "")
14700 (minus:SI (const_int 31)
14701 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
14702 (clobber (reg:CC FLAGS_REG))])
14704 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
14705 (clobber (reg:CC FLAGS_REG))])]
14710 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
14715 (define_insn "clzsi2_abm"
14716 [(set (match_operand:SI 0 "register_operand" "=r")
14717 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
14718 (clobber (reg:CC FLAGS_REG))]
14720 "lzcnt{l}\t{%1, %0|%0, %1}"
14721 [(set_attr "prefix_rep" "1")
14722 (set_attr "type" "bitmanip")
14723 (set_attr "mode" "SI")])
14726 [(set (match_operand:SI 0 "register_operand" "=r")
14727 (minus:SI (const_int 31)
14728 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
14729 (clobber (reg:CC FLAGS_REG))]
14731 "bsr{l}\t{%1, %0|%0, %1}"
14732 [(set_attr "type" "alu1")
14733 (set_attr "prefix_0f" "1")
14734 (set_attr "mode" "SI")])
14736 (define_insn "popcount<mode>2"
14737 [(set (match_operand:SWI248 0 "register_operand" "=r")
14739 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
14740 (clobber (reg:CC FLAGS_REG))]
14744 return "popcnt\t{%1, %0|%0, %1}";
14746 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14749 [(set_attr "prefix_rep" "1")
14750 (set_attr "type" "bitmanip")
14751 (set_attr "mode" "<MODE>")])
14753 (define_insn "*popcount<mode>2_cmp"
14754 [(set (reg FLAGS_REG)
14757 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14759 (set (match_operand:SWI248 0 "register_operand" "=r")
14760 (popcount:SWI248 (match_dup 1)))]
14761 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14764 return "popcnt\t{%1, %0|%0, %1}";
14766 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14769 [(set_attr "prefix_rep" "1")
14770 (set_attr "type" "bitmanip")
14771 (set_attr "mode" "<MODE>")])
14773 (define_insn "*popcountsi2_cmp_zext"
14774 [(set (reg FLAGS_REG)
14776 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14778 (set (match_operand:DI 0 "register_operand" "=r")
14779 (zero_extend:DI(popcount:SI (match_dup 1))))]
14780 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14783 return "popcnt\t{%1, %0|%0, %1}";
14785 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14788 [(set_attr "prefix_rep" "1")
14789 (set_attr "type" "bitmanip")
14790 (set_attr "mode" "SI")])
14792 (define_expand "bswapsi2"
14793 [(set (match_operand:SI 0 "register_operand" "")
14794 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14797 if (!(TARGET_BSWAP || TARGET_MOVBE))
14799 rtx x = operands[0];
14801 emit_move_insn (x, operands[1]);
14802 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14803 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14804 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14809 (define_insn "*bswapsi_movbe"
14810 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14811 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14812 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14815 movbe\t{%1, %0|%0, %1}
14816 movbe\t{%1, %0|%0, %1}"
14817 [(set_attr "type" "*,imov,imov")
14818 (set_attr "modrm" "*,1,1")
14819 (set_attr "prefix_0f" "1")
14820 (set_attr "prefix_extra" "*,1,1")
14821 (set_attr "length" "2,*,*")
14822 (set_attr "mode" "SI")])
14824 (define_insn "*bswapsi_1"
14825 [(set (match_operand:SI 0 "register_operand" "=r")
14826 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14829 [(set_attr "prefix_0f" "1")
14830 (set_attr "length" "2")])
14832 (define_insn "*bswaphi_lowpart_1"
14833 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14834 (bswap:HI (match_dup 0)))
14835 (clobber (reg:CC FLAGS_REG))]
14836 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14838 xchg{b}\t{%h0, %b0|%b0, %h0}
14839 rol{w}\t{$8, %0|%0, 8}"
14840 [(set_attr "length" "2,4")
14841 (set_attr "mode" "QI,HI")])
14843 (define_insn "bswaphi_lowpart"
14844 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14845 (bswap:HI (match_dup 0)))
14846 (clobber (reg:CC FLAGS_REG))]
14848 "rol{w}\t{$8, %0|%0, 8}"
14849 [(set_attr "length" "4")
14850 (set_attr "mode" "HI")])
14852 (define_expand "bswapdi2"
14853 [(set (match_operand:DI 0 "register_operand" "")
14854 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14858 (define_insn "*bswapdi_movbe"
14859 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14860 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14861 "TARGET_64BIT && TARGET_MOVBE
14862 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14865 movbe\t{%1, %0|%0, %1}
14866 movbe\t{%1, %0|%0, %1}"
14867 [(set_attr "type" "*,imov,imov")
14868 (set_attr "modrm" "*,1,1")
14869 (set_attr "prefix_0f" "1")
14870 (set_attr "prefix_extra" "*,1,1")
14871 (set_attr "length" "3,*,*")
14872 (set_attr "mode" "DI")])
14874 (define_insn "*bswapdi_1"
14875 [(set (match_operand:DI 0 "register_operand" "=r")
14876 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14879 [(set_attr "prefix_0f" "1")
14880 (set_attr "length" "3")])
14882 (define_expand "clzdi2"
14884 [(set (match_operand:DI 0 "register_operand" "")
14885 (minus:DI (const_int 63)
14886 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14887 (clobber (reg:CC FLAGS_REG))])
14889 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14890 (clobber (reg:CC FLAGS_REG))])]
14895 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14900 (define_insn "clzdi2_abm"
14901 [(set (match_operand:DI 0 "register_operand" "=r")
14902 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14903 (clobber (reg:CC FLAGS_REG))]
14904 "TARGET_64BIT && TARGET_ABM"
14905 "lzcnt{q}\t{%1, %0|%0, %1}"
14906 [(set_attr "prefix_rep" "1")
14907 (set_attr "type" "bitmanip")
14908 (set_attr "mode" "DI")])
14910 (define_insn "bsr_rex64"
14911 [(set (match_operand:DI 0 "register_operand" "=r")
14912 (minus:DI (const_int 63)
14913 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14914 (clobber (reg:CC FLAGS_REG))]
14916 "bsr{q}\t{%1, %0|%0, %1}"
14917 [(set_attr "type" "alu1")
14918 (set_attr "prefix_0f" "1")
14919 (set_attr "mode" "DI")])
14921 (define_expand "clzhi2"
14923 [(set (match_operand:HI 0 "register_operand" "")
14924 (minus:HI (const_int 15)
14925 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14926 (clobber (reg:CC FLAGS_REG))])
14928 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14929 (clobber (reg:CC FLAGS_REG))])]
14934 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14939 (define_insn "clzhi2_abm"
14940 [(set (match_operand:HI 0 "register_operand" "=r")
14941 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14942 (clobber (reg:CC FLAGS_REG))]
14944 "lzcnt{w}\t{%1, %0|%0, %1}"
14945 [(set_attr "prefix_rep" "1")
14946 (set_attr "type" "bitmanip")
14947 (set_attr "mode" "HI")])
14949 (define_insn "*bsrhi"
14950 [(set (match_operand:HI 0 "register_operand" "=r")
14951 (minus:HI (const_int 15)
14952 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14953 (clobber (reg:CC FLAGS_REG))]
14955 "bsr{w}\t{%1, %0|%0, %1}"
14956 [(set_attr "type" "alu1")
14957 (set_attr "prefix_0f" "1")
14958 (set_attr "mode" "HI")])
14960 (define_expand "paritydi2"
14961 [(set (match_operand:DI 0 "register_operand" "")
14962 (parity:DI (match_operand:DI 1 "register_operand" "")))]
14965 rtx scratch = gen_reg_rtx (QImode);
14968 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14969 NULL_RTX, operands[1]));
14971 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14972 gen_rtx_REG (CCmode, FLAGS_REG),
14974 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14977 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14980 rtx tmp = gen_reg_rtx (SImode);
14982 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14983 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14988 (define_insn_and_split "paritydi2_cmp"
14989 [(set (reg:CC FLAGS_REG)
14990 (parity:CC (match_operand:DI 3 "register_operand" "0")))
14991 (clobber (match_scratch:DI 0 "=r"))
14992 (clobber (match_scratch:SI 1 "=&r"))
14993 (clobber (match_scratch:HI 2 "=Q"))]
14996 "&& reload_completed"
14998 [(set (match_dup 1)
14999 (xor:SI (match_dup 1) (match_dup 4)))
15000 (clobber (reg:CC FLAGS_REG))])
15002 [(set (reg:CC FLAGS_REG)
15003 (parity:CC (match_dup 1)))
15004 (clobber (match_dup 1))
15005 (clobber (match_dup 2))])]
15007 operands[4] = gen_lowpart (SImode, operands[3]);
15011 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
15012 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
15015 operands[1] = gen_highpart (SImode, operands[3]);
15018 (define_expand "paritysi2"
15019 [(set (match_operand:SI 0 "register_operand" "")
15020 (parity:SI (match_operand:SI 1 "register_operand" "")))]
15023 rtx scratch = gen_reg_rtx (QImode);
15026 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
15028 cond = gen_rtx_fmt_ee (ORDERED, QImode,
15029 gen_rtx_REG (CCmode, FLAGS_REG),
15031 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
15033 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
15037 (define_insn_and_split "paritysi2_cmp"
15038 [(set (reg:CC FLAGS_REG)
15039 (parity:CC (match_operand:SI 2 "register_operand" "0")))
15040 (clobber (match_scratch:SI 0 "=r"))
15041 (clobber (match_scratch:HI 1 "=&Q"))]
15044 "&& reload_completed"
15046 [(set (match_dup 1)
15047 (xor:HI (match_dup 1) (match_dup 3)))
15048 (clobber (reg:CC FLAGS_REG))])
15050 [(set (reg:CC FLAGS_REG)
15051 (parity:CC (match_dup 1)))
15052 (clobber (match_dup 1))])]
15054 operands[3] = gen_lowpart (HImode, operands[2]);
15056 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
15057 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
15060 (define_insn "*parityhi2_cmp"
15061 [(set (reg:CC FLAGS_REG)
15062 (parity:CC (match_operand:HI 1 "register_operand" "0")))
15063 (clobber (match_scratch:HI 0 "=Q"))]
15065 "xor{b}\t{%h0, %b0|%b0, %h0}"
15066 [(set_attr "length" "2")
15067 (set_attr "mode" "HI")])
15069 (define_insn "*parityqi2_cmp"
15070 [(set (reg:CC FLAGS_REG)
15071 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
15074 [(set_attr "length" "2")
15075 (set_attr "mode" "QI")])
15077 ;; Thread-local storage patterns for ELF.
15079 ;; Note that these code sequences must appear exactly as shown
15080 ;; in order to allow linker relaxation.
15082 (define_insn "*tls_global_dynamic_32_gnu"
15083 [(set (match_operand:SI 0 "register_operand" "=a")
15084 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15085 (match_operand:SI 2 "tls_symbolic_operand" "")
15086 (match_operand:SI 3 "call_insn_operand" "")]
15088 (clobber (match_scratch:SI 4 "=d"))
15089 (clobber (match_scratch:SI 5 "=c"))
15090 (clobber (reg:CC FLAGS_REG))]
15091 "!TARGET_64BIT && TARGET_GNU_TLS"
15092 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
15093 [(set_attr "type" "multi")
15094 (set_attr "length" "12")])
15096 (define_insn "*tls_global_dynamic_32_sun"
15097 [(set (match_operand:SI 0 "register_operand" "=a")
15098 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15099 (match_operand:SI 2 "tls_symbolic_operand" "")
15100 (match_operand:SI 3 "call_insn_operand" "")]
15102 (clobber (match_scratch:SI 4 "=d"))
15103 (clobber (match_scratch:SI 5 "=c"))
15104 (clobber (reg:CC FLAGS_REG))]
15105 "!TARGET_64BIT && TARGET_SUN_TLS"
15106 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
15107 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
15108 [(set_attr "type" "multi")
15109 (set_attr "length" "14")])
15111 (define_expand "tls_global_dynamic_32"
15112 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15115 (match_operand:SI 1 "tls_symbolic_operand" "")
15118 (clobber (match_scratch:SI 4 ""))
15119 (clobber (match_scratch:SI 5 ""))
15120 (clobber (reg:CC FLAGS_REG))])]
15124 operands[2] = pic_offset_table_rtx;
15127 operands[2] = gen_reg_rtx (Pmode);
15128 emit_insn (gen_set_got (operands[2]));
15130 if (TARGET_GNU2_TLS)
15132 emit_insn (gen_tls_dynamic_gnu2_32
15133 (operands[0], operands[1], operands[2]));
15136 operands[3] = ix86_tls_get_addr ();
15139 (define_insn "*tls_global_dynamic_64"
15140 [(set (match_operand:DI 0 "register_operand" "=a")
15141 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
15142 (match_operand:DI 3 "" "")))
15143 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15146 { 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"; }
15147 [(set_attr "type" "multi")
15148 (set_attr "length" "16")])
15150 (define_expand "tls_global_dynamic_64"
15151 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15152 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
15153 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15157 if (TARGET_GNU2_TLS)
15159 emit_insn (gen_tls_dynamic_gnu2_64
15160 (operands[0], operands[1]));
15163 operands[2] = ix86_tls_get_addr ();
15166 (define_insn "*tls_local_dynamic_base_32_gnu"
15167 [(set (match_operand:SI 0 "register_operand" "=a")
15168 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15169 (match_operand:SI 2 "call_insn_operand" "")]
15170 UNSPEC_TLS_LD_BASE))
15171 (clobber (match_scratch:SI 3 "=d"))
15172 (clobber (match_scratch:SI 4 "=c"))
15173 (clobber (reg:CC FLAGS_REG))]
15174 "!TARGET_64BIT && TARGET_GNU_TLS"
15175 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
15176 [(set_attr "type" "multi")
15177 (set_attr "length" "11")])
15179 (define_insn "*tls_local_dynamic_base_32_sun"
15180 [(set (match_operand:SI 0 "register_operand" "=a")
15181 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15182 (match_operand:SI 2 "call_insn_operand" "")]
15183 UNSPEC_TLS_LD_BASE))
15184 (clobber (match_scratch:SI 3 "=d"))
15185 (clobber (match_scratch:SI 4 "=c"))
15186 (clobber (reg:CC FLAGS_REG))]
15187 "!TARGET_64BIT && TARGET_SUN_TLS"
15188 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
15189 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
15190 [(set_attr "type" "multi")
15191 (set_attr "length" "13")])
15193 (define_expand "tls_local_dynamic_base_32"
15194 [(parallel [(set (match_operand:SI 0 "register_operand" "")
15195 (unspec:SI [(match_dup 1) (match_dup 2)]
15196 UNSPEC_TLS_LD_BASE))
15197 (clobber (match_scratch:SI 3 ""))
15198 (clobber (match_scratch:SI 4 ""))
15199 (clobber (reg:CC FLAGS_REG))])]
15203 operands[1] = pic_offset_table_rtx;
15206 operands[1] = gen_reg_rtx (Pmode);
15207 emit_insn (gen_set_got (operands[1]));
15209 if (TARGET_GNU2_TLS)
15211 emit_insn (gen_tls_dynamic_gnu2_32
15212 (operands[0], ix86_tls_module_base (), operands[1]));
15215 operands[2] = ix86_tls_get_addr ();
15218 (define_insn "*tls_local_dynamic_base_64"
15219 [(set (match_operand:DI 0 "register_operand" "=a")
15220 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
15221 (match_operand:DI 2 "" "")))
15222 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
15224 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
15225 [(set_attr "type" "multi")
15226 (set_attr "length" "12")])
15228 (define_expand "tls_local_dynamic_base_64"
15229 [(parallel [(set (match_operand:DI 0 "register_operand" "")
15230 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
15231 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
15234 if (TARGET_GNU2_TLS)
15236 emit_insn (gen_tls_dynamic_gnu2_64
15237 (operands[0], ix86_tls_module_base ()));
15240 operands[1] = ix86_tls_get_addr ();
15243 ;; Local dynamic of a single variable is a lose. Show combine how
15244 ;; to convert that back to global dynamic.
15246 (define_insn_and_split "*tls_local_dynamic_32_once"
15247 [(set (match_operand:SI 0 "register_operand" "=a")
15248 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
15249 (match_operand:SI 2 "call_insn_operand" "")]
15250 UNSPEC_TLS_LD_BASE)
15251 (const:SI (unspec:SI
15252 [(match_operand:SI 3 "tls_symbolic_operand" "")]
15254 (clobber (match_scratch:SI 4 "=d"))
15255 (clobber (match_scratch:SI 5 "=c"))
15256 (clobber (reg:CC FLAGS_REG))]
15260 [(parallel [(set (match_dup 0)
15261 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
15263 (clobber (match_dup 4))
15264 (clobber (match_dup 5))
15265 (clobber (reg:CC FLAGS_REG))])]
15268 ;; Load and add the thread base pointer from %gs:0.
15270 (define_insn "*load_tp_si"
15271 [(set (match_operand:SI 0 "register_operand" "=r")
15272 (unspec:SI [(const_int 0)] UNSPEC_TP))]
15274 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15275 [(set_attr "type" "imov")
15276 (set_attr "modrm" "0")
15277 (set_attr "length" "7")
15278 (set_attr "memory" "load")
15279 (set_attr "imm_disp" "false")])
15281 (define_insn "*add_tp_si"
15282 [(set (match_operand:SI 0 "register_operand" "=r")
15283 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
15284 (match_operand:SI 1 "register_operand" "0")))
15285 (clobber (reg:CC FLAGS_REG))]
15287 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
15288 [(set_attr "type" "alu")
15289 (set_attr "modrm" "0")
15290 (set_attr "length" "7")
15291 (set_attr "memory" "load")
15292 (set_attr "imm_disp" "false")])
15294 (define_insn "*load_tp_di"
15295 [(set (match_operand:DI 0 "register_operand" "=r")
15296 (unspec:DI [(const_int 0)] UNSPEC_TP))]
15298 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15299 [(set_attr "type" "imov")
15300 (set_attr "modrm" "0")
15301 (set_attr "length" "7")
15302 (set_attr "memory" "load")
15303 (set_attr "imm_disp" "false")])
15305 (define_insn "*add_tp_di"
15306 [(set (match_operand:DI 0 "register_operand" "=r")
15307 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
15308 (match_operand:DI 1 "register_operand" "0")))
15309 (clobber (reg:CC FLAGS_REG))]
15311 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
15312 [(set_attr "type" "alu")
15313 (set_attr "modrm" "0")
15314 (set_attr "length" "7")
15315 (set_attr "memory" "load")
15316 (set_attr "imm_disp" "false")])
15318 ;; GNU2 TLS patterns can be split.
15320 (define_expand "tls_dynamic_gnu2_32"
15321 [(set (match_dup 3)
15322 (plus:SI (match_operand:SI 2 "register_operand" "")
15324 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
15327 [(set (match_operand:SI 0 "register_operand" "")
15328 (unspec:SI [(match_dup 1) (match_dup 3)
15329 (match_dup 2) (reg:SI SP_REG)]
15331 (clobber (reg:CC FLAGS_REG))])]
15332 "!TARGET_64BIT && TARGET_GNU2_TLS"
15334 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15335 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15338 (define_insn "*tls_dynamic_lea_32"
15339 [(set (match_operand:SI 0 "register_operand" "=r")
15340 (plus:SI (match_operand:SI 1 "register_operand" "b")
15342 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
15343 UNSPEC_TLSDESC))))]
15344 "!TARGET_64BIT && TARGET_GNU2_TLS"
15345 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
15346 [(set_attr "type" "lea")
15347 (set_attr "mode" "SI")
15348 (set_attr "length" "6")
15349 (set_attr "length_address" "4")])
15351 (define_insn "*tls_dynamic_call_32"
15352 [(set (match_operand:SI 0 "register_operand" "=a")
15353 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
15354 (match_operand:SI 2 "register_operand" "0")
15355 ;; we have to make sure %ebx still points to the GOT
15356 (match_operand:SI 3 "register_operand" "b")
15359 (clobber (reg:CC FLAGS_REG))]
15360 "!TARGET_64BIT && TARGET_GNU2_TLS"
15361 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
15362 [(set_attr "type" "call")
15363 (set_attr "length" "2")
15364 (set_attr "length_address" "0")])
15366 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
15367 [(set (match_operand:SI 0 "register_operand" "=&a")
15369 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
15370 (match_operand:SI 4 "" "")
15371 (match_operand:SI 2 "register_operand" "b")
15374 (const:SI (unspec:SI
15375 [(match_operand:SI 1 "tls_symbolic_operand" "")]
15377 (clobber (reg:CC FLAGS_REG))]
15378 "!TARGET_64BIT && TARGET_GNU2_TLS"
15381 [(set (match_dup 0) (match_dup 5))]
15383 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15384 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
15387 (define_expand "tls_dynamic_gnu2_64"
15388 [(set (match_dup 2)
15389 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15392 [(set (match_operand:DI 0 "register_operand" "")
15393 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
15395 (clobber (reg:CC FLAGS_REG))])]
15396 "TARGET_64BIT && TARGET_GNU2_TLS"
15398 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15399 ix86_tls_descriptor_calls_expanded_in_cfun = true;
15402 (define_insn "*tls_dynamic_lea_64"
15403 [(set (match_operand:DI 0 "register_operand" "=r")
15404 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
15406 "TARGET_64BIT && TARGET_GNU2_TLS"
15407 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
15408 [(set_attr "type" "lea")
15409 (set_attr "mode" "DI")
15410 (set_attr "length" "7")
15411 (set_attr "length_address" "4")])
15413 (define_insn "*tls_dynamic_call_64"
15414 [(set (match_operand:DI 0 "register_operand" "=a")
15415 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
15416 (match_operand:DI 2 "register_operand" "0")
15419 (clobber (reg:CC FLAGS_REG))]
15420 "TARGET_64BIT && TARGET_GNU2_TLS"
15421 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
15422 [(set_attr "type" "call")
15423 (set_attr "length" "2")
15424 (set_attr "length_address" "0")])
15426 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
15427 [(set (match_operand:DI 0 "register_operand" "=&a")
15429 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
15430 (match_operand:DI 3 "" "")
15433 (const:DI (unspec:DI
15434 [(match_operand:DI 1 "tls_symbolic_operand" "")]
15436 (clobber (reg:CC FLAGS_REG))]
15437 "TARGET_64BIT && TARGET_GNU2_TLS"
15440 [(set (match_dup 0) (match_dup 4))]
15442 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
15443 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
15448 ;; These patterns match the binary 387 instructions for addM3, subM3,
15449 ;; mulM3 and divM3. There are three patterns for each of DFmode and
15450 ;; SFmode. The first is the normal insn, the second the same insn but
15451 ;; with one operand a conversion, and the third the same insn but with
15452 ;; the other operand a conversion. The conversion may be SFmode or
15453 ;; SImode if the target mode DFmode, but only SImode if the target mode
15456 ;; Gcc is slightly more smart about handling normal two address instructions
15457 ;; so use special patterns for add and mull.
15459 (define_insn "*fop_<mode>_comm_mixed_avx"
15460 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15461 (match_operator:MODEF 3 "binary_fp_operator"
15462 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
15463 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15464 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15465 && COMMUTATIVE_ARITH_P (operands[3])
15466 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15467 "* return output_387_binary_op (insn, operands);"
15468 [(set (attr "type")
15469 (if_then_else (eq_attr "alternative" "1")
15470 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15471 (const_string "ssemul")
15472 (const_string "sseadd"))
15473 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15474 (const_string "fmul")
15475 (const_string "fop"))))
15476 (set_attr "prefix" "orig,maybe_vex")
15477 (set_attr "mode" "<MODE>")])
15479 (define_insn "*fop_<mode>_comm_mixed"
15480 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
15481 (match_operator:MODEF 3 "binary_fp_operator"
15482 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
15483 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
15484 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15485 && COMMUTATIVE_ARITH_P (operands[3])
15486 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15487 "* return output_387_binary_op (insn, operands);"
15488 [(set (attr "type")
15489 (if_then_else (eq_attr "alternative" "1")
15490 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15491 (const_string "ssemul")
15492 (const_string "sseadd"))
15493 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15494 (const_string "fmul")
15495 (const_string "fop"))))
15496 (set_attr "mode" "<MODE>")])
15498 (define_insn "*fop_<mode>_comm_avx"
15499 [(set (match_operand:MODEF 0 "register_operand" "=x")
15500 (match_operator:MODEF 3 "binary_fp_operator"
15501 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
15502 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15503 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15504 && COMMUTATIVE_ARITH_P (operands[3])
15505 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15506 "* return output_387_binary_op (insn, operands);"
15507 [(set (attr "type")
15508 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15509 (const_string "ssemul")
15510 (const_string "sseadd")))
15511 (set_attr "prefix" "vex")
15512 (set_attr "mode" "<MODE>")])
15514 (define_insn "*fop_<mode>_comm_sse"
15515 [(set (match_operand:MODEF 0 "register_operand" "=x")
15516 (match_operator:MODEF 3 "binary_fp_operator"
15517 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15518 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15519 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15520 && COMMUTATIVE_ARITH_P (operands[3])
15521 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15522 "* return output_387_binary_op (insn, operands);"
15523 [(set (attr "type")
15524 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15525 (const_string "ssemul")
15526 (const_string "sseadd")))
15527 (set_attr "mode" "<MODE>")])
15529 (define_insn "*fop_<mode>_comm_i387"
15530 [(set (match_operand:MODEF 0 "register_operand" "=f")
15531 (match_operator:MODEF 3 "binary_fp_operator"
15532 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
15533 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
15534 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15535 && COMMUTATIVE_ARITH_P (operands[3])
15536 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15537 "* return output_387_binary_op (insn, operands);"
15538 [(set (attr "type")
15539 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
15540 (const_string "fmul")
15541 (const_string "fop")))
15542 (set_attr "mode" "<MODE>")])
15544 (define_insn "*fop_<mode>_1_mixed_avx"
15545 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15546 (match_operator:MODEF 3 "binary_fp_operator"
15547 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
15548 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15549 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15550 && !COMMUTATIVE_ARITH_P (operands[3])
15551 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15552 "* return output_387_binary_op (insn, operands);"
15553 [(set (attr "type")
15554 (cond [(and (eq_attr "alternative" "2")
15555 (match_operand:MODEF 3 "mult_operator" ""))
15556 (const_string "ssemul")
15557 (and (eq_attr "alternative" "2")
15558 (match_operand:MODEF 3 "div_operator" ""))
15559 (const_string "ssediv")
15560 (eq_attr "alternative" "2")
15561 (const_string "sseadd")
15562 (match_operand:MODEF 3 "mult_operator" "")
15563 (const_string "fmul")
15564 (match_operand:MODEF 3 "div_operator" "")
15565 (const_string "fdiv")
15567 (const_string "fop")))
15568 (set_attr "prefix" "orig,orig,maybe_vex")
15569 (set_attr "mode" "<MODE>")])
15571 (define_insn "*fop_<mode>_1_mixed"
15572 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
15573 (match_operator:MODEF 3 "binary_fp_operator"
15574 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
15575 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
15576 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
15577 && !COMMUTATIVE_ARITH_P (operands[3])
15578 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15579 "* return output_387_binary_op (insn, operands);"
15580 [(set (attr "type")
15581 (cond [(and (eq_attr "alternative" "2")
15582 (match_operand:MODEF 3 "mult_operator" ""))
15583 (const_string "ssemul")
15584 (and (eq_attr "alternative" "2")
15585 (match_operand:MODEF 3 "div_operator" ""))
15586 (const_string "ssediv")
15587 (eq_attr "alternative" "2")
15588 (const_string "sseadd")
15589 (match_operand:MODEF 3 "mult_operator" "")
15590 (const_string "fmul")
15591 (match_operand:MODEF 3 "div_operator" "")
15592 (const_string "fdiv")
15594 (const_string "fop")))
15595 (set_attr "mode" "<MODE>")])
15597 (define_insn "*rcpsf2_sse"
15598 [(set (match_operand:SF 0 "register_operand" "=x")
15599 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15602 "%vrcpss\t{%1, %d0|%d0, %1}"
15603 [(set_attr "type" "sse")
15604 (set_attr "atom_sse_attr" "rcp")
15605 (set_attr "prefix" "maybe_vex")
15606 (set_attr "mode" "SF")])
15608 (define_insn "*fop_<mode>_1_avx"
15609 [(set (match_operand:MODEF 0 "register_operand" "=x")
15610 (match_operator:MODEF 3 "binary_fp_operator"
15611 [(match_operand:MODEF 1 "register_operand" "x")
15612 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15613 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15614 && !COMMUTATIVE_ARITH_P (operands[3])"
15615 "* return output_387_binary_op (insn, operands);"
15616 [(set (attr "type")
15617 (cond [(match_operand:MODEF 3 "mult_operator" "")
15618 (const_string "ssemul")
15619 (match_operand:MODEF 3 "div_operator" "")
15620 (const_string "ssediv")
15622 (const_string "sseadd")))
15623 (set_attr "prefix" "vex")
15624 (set_attr "mode" "<MODE>")])
15626 (define_insn "*fop_<mode>_1_sse"
15627 [(set (match_operand:MODEF 0 "register_operand" "=x")
15628 (match_operator:MODEF 3 "binary_fp_operator"
15629 [(match_operand:MODEF 1 "register_operand" "0")
15630 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
15631 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15632 && !COMMUTATIVE_ARITH_P (operands[3])"
15633 "* return output_387_binary_op (insn, operands);"
15634 [(set (attr "type")
15635 (cond [(match_operand:MODEF 3 "mult_operator" "")
15636 (const_string "ssemul")
15637 (match_operand:MODEF 3 "div_operator" "")
15638 (const_string "ssediv")
15640 (const_string "sseadd")))
15641 (set_attr "mode" "<MODE>")])
15643 ;; This pattern is not fully shadowed by the pattern above.
15644 (define_insn "*fop_<mode>_1_i387"
15645 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15646 (match_operator:MODEF 3 "binary_fp_operator"
15647 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
15648 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
15649 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
15650 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15651 && !COMMUTATIVE_ARITH_P (operands[3])
15652 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15653 "* return output_387_binary_op (insn, operands);"
15654 [(set (attr "type")
15655 (cond [(match_operand:MODEF 3 "mult_operator" "")
15656 (const_string "fmul")
15657 (match_operand:MODEF 3 "div_operator" "")
15658 (const_string "fdiv")
15660 (const_string "fop")))
15661 (set_attr "mode" "<MODE>")])
15663 ;; ??? Add SSE splitters for these!
15664 (define_insn "*fop_<MODEF:mode>_2_i387"
15665 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15666 (match_operator:MODEF 3 "binary_fp_operator"
15668 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15669 (match_operand:MODEF 2 "register_operand" "0,0")]))]
15670 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15671 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15672 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15673 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15674 [(set (attr "type")
15675 (cond [(match_operand:MODEF 3 "mult_operator" "")
15676 (const_string "fmul")
15677 (match_operand:MODEF 3 "div_operator" "")
15678 (const_string "fdiv")
15680 (const_string "fop")))
15681 (set_attr "fp_int_src" "true")
15682 (set_attr "mode" "<X87MODEI12:MODE>")])
15684 (define_insn "*fop_<MODEF:mode>_3_i387"
15685 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
15686 (match_operator:MODEF 3 "binary_fp_operator"
15687 [(match_operand:MODEF 1 "register_operand" "0,0")
15689 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15690 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
15691 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
15692 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15693 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15694 [(set (attr "type")
15695 (cond [(match_operand:MODEF 3 "mult_operator" "")
15696 (const_string "fmul")
15697 (match_operand:MODEF 3 "div_operator" "")
15698 (const_string "fdiv")
15700 (const_string "fop")))
15701 (set_attr "fp_int_src" "true")
15702 (set_attr "mode" "<MODE>")])
15704 (define_insn "*fop_df_4_i387"
15705 [(set (match_operand:DF 0 "register_operand" "=f,f")
15706 (match_operator:DF 3 "binary_fp_operator"
15708 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
15709 (match_operand:DF 2 "register_operand" "0,f")]))]
15710 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15711 && !(TARGET_SSE2 && TARGET_SSE_MATH)
15712 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
15713 "* return output_387_binary_op (insn, operands);"
15714 [(set (attr "type")
15715 (cond [(match_operand:DF 3 "mult_operator" "")
15716 (const_string "fmul")
15717 (match_operand:DF 3 "div_operator" "")
15718 (const_string "fdiv")
15720 (const_string "fop")))
15721 (set_attr "mode" "SF")])
15723 (define_insn "*fop_df_5_i387"
15724 [(set (match_operand:DF 0 "register_operand" "=f,f")
15725 (match_operator:DF 3 "binary_fp_operator"
15726 [(match_operand:DF 1 "register_operand" "0,f")
15728 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15729 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15730 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15731 "* return output_387_binary_op (insn, operands);"
15732 [(set (attr "type")
15733 (cond [(match_operand:DF 3 "mult_operator" "")
15734 (const_string "fmul")
15735 (match_operand:DF 3 "div_operator" "")
15736 (const_string "fdiv")
15738 (const_string "fop")))
15739 (set_attr "mode" "SF")])
15741 (define_insn "*fop_df_6_i387"
15742 [(set (match_operand:DF 0 "register_operand" "=f,f")
15743 (match_operator:DF 3 "binary_fp_operator"
15745 (match_operand:SF 1 "register_operand" "0,f"))
15747 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
15748 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
15749 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
15750 "* return output_387_binary_op (insn, operands);"
15751 [(set (attr "type")
15752 (cond [(match_operand:DF 3 "mult_operator" "")
15753 (const_string "fmul")
15754 (match_operand:DF 3 "div_operator" "")
15755 (const_string "fdiv")
15757 (const_string "fop")))
15758 (set_attr "mode" "SF")])
15760 (define_insn "*fop_xf_comm_i387"
15761 [(set (match_operand:XF 0 "register_operand" "=f")
15762 (match_operator:XF 3 "binary_fp_operator"
15763 [(match_operand:XF 1 "register_operand" "%0")
15764 (match_operand:XF 2 "register_operand" "f")]))]
15766 && COMMUTATIVE_ARITH_P (operands[3])"
15767 "* return output_387_binary_op (insn, operands);"
15768 [(set (attr "type")
15769 (if_then_else (match_operand:XF 3 "mult_operator" "")
15770 (const_string "fmul")
15771 (const_string "fop")))
15772 (set_attr "mode" "XF")])
15774 (define_insn "*fop_xf_1_i387"
15775 [(set (match_operand:XF 0 "register_operand" "=f,f")
15776 (match_operator:XF 3 "binary_fp_operator"
15777 [(match_operand:XF 1 "register_operand" "0,f")
15778 (match_operand:XF 2 "register_operand" "f,0")]))]
15780 && !COMMUTATIVE_ARITH_P (operands[3])"
15781 "* return output_387_binary_op (insn, operands);"
15782 [(set (attr "type")
15783 (cond [(match_operand:XF 3 "mult_operator" "")
15784 (const_string "fmul")
15785 (match_operand:XF 3 "div_operator" "")
15786 (const_string "fdiv")
15788 (const_string "fop")))
15789 (set_attr "mode" "XF")])
15791 (define_insn "*fop_xf_2_i387"
15792 [(set (match_operand:XF 0 "register_operand" "=f,f")
15793 (match_operator:XF 3 "binary_fp_operator"
15795 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15796 (match_operand:XF 2 "register_operand" "0,0")]))]
15797 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15798 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15799 [(set (attr "type")
15800 (cond [(match_operand:XF 3 "mult_operator" "")
15801 (const_string "fmul")
15802 (match_operand:XF 3 "div_operator" "")
15803 (const_string "fdiv")
15805 (const_string "fop")))
15806 (set_attr "fp_int_src" "true")
15807 (set_attr "mode" "<MODE>")])
15809 (define_insn "*fop_xf_3_i387"
15810 [(set (match_operand:XF 0 "register_operand" "=f,f")
15811 (match_operator:XF 3 "binary_fp_operator"
15812 [(match_operand:XF 1 "register_operand" "0,0")
15814 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15815 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15816 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15817 [(set (attr "type")
15818 (cond [(match_operand:XF 3 "mult_operator" "")
15819 (const_string "fmul")
15820 (match_operand:XF 3 "div_operator" "")
15821 (const_string "fdiv")
15823 (const_string "fop")))
15824 (set_attr "fp_int_src" "true")
15825 (set_attr "mode" "<MODE>")])
15827 (define_insn "*fop_xf_4_i387"
15828 [(set (match_operand:XF 0 "register_operand" "=f,f")
15829 (match_operator:XF 3 "binary_fp_operator"
15831 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15832 (match_operand:XF 2 "register_operand" "0,f")]))]
15834 "* return output_387_binary_op (insn, operands);"
15835 [(set (attr "type")
15836 (cond [(match_operand:XF 3 "mult_operator" "")
15837 (const_string "fmul")
15838 (match_operand:XF 3 "div_operator" "")
15839 (const_string "fdiv")
15841 (const_string "fop")))
15842 (set_attr "mode" "<MODE>")])
15844 (define_insn "*fop_xf_5_i387"
15845 [(set (match_operand:XF 0 "register_operand" "=f,f")
15846 (match_operator:XF 3 "binary_fp_operator"
15847 [(match_operand:XF 1 "register_operand" "0,f")
15849 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15851 "* return output_387_binary_op (insn, operands);"
15852 [(set (attr "type")
15853 (cond [(match_operand:XF 3 "mult_operator" "")
15854 (const_string "fmul")
15855 (match_operand:XF 3 "div_operator" "")
15856 (const_string "fdiv")
15858 (const_string "fop")))
15859 (set_attr "mode" "<MODE>")])
15861 (define_insn "*fop_xf_6_i387"
15862 [(set (match_operand:XF 0 "register_operand" "=f,f")
15863 (match_operator:XF 3 "binary_fp_operator"
15865 (match_operand:MODEF 1 "register_operand" "0,f"))
15867 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15869 "* return output_387_binary_op (insn, operands);"
15870 [(set (attr "type")
15871 (cond [(match_operand:XF 3 "mult_operator" "")
15872 (const_string "fmul")
15873 (match_operand:XF 3 "div_operator" "")
15874 (const_string "fdiv")
15876 (const_string "fop")))
15877 (set_attr "mode" "<MODE>")])
15880 [(set (match_operand 0 "register_operand" "")
15881 (match_operator 3 "binary_fp_operator"
15882 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15883 (match_operand 2 "register_operand" "")]))]
15885 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15886 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15889 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15890 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15891 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15892 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15893 GET_MODE (operands[3]),
15896 ix86_free_from_memory (GET_MODE (operands[1]));
15901 [(set (match_operand 0 "register_operand" "")
15902 (match_operator 3 "binary_fp_operator"
15903 [(match_operand 1 "register_operand" "")
15904 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15906 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15907 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15910 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15911 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15912 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15913 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15914 GET_MODE (operands[3]),
15917 ix86_free_from_memory (GET_MODE (operands[2]));
15921 ;; FPU special functions.
15923 ;; This pattern implements a no-op XFmode truncation for
15924 ;; all fancy i386 XFmode math functions.
15926 (define_insn "truncxf<mode>2_i387_noop_unspec"
15927 [(set (match_operand:MODEF 0 "register_operand" "=f")
15928 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15929 UNSPEC_TRUNC_NOOP))]
15930 "TARGET_USE_FANCY_MATH_387"
15931 "* return output_387_reg_move (insn, operands);"
15932 [(set_attr "type" "fmov")
15933 (set_attr "mode" "<MODE>")])
15935 (define_insn "sqrtxf2"
15936 [(set (match_operand:XF 0 "register_operand" "=f")
15937 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15938 "TARGET_USE_FANCY_MATH_387"
15940 [(set_attr "type" "fpspc")
15941 (set_attr "mode" "XF")
15942 (set_attr "athlon_decode" "direct")
15943 (set_attr "amdfam10_decode" "direct")])
15945 (define_insn "sqrt_extend<mode>xf2_i387"
15946 [(set (match_operand:XF 0 "register_operand" "=f")
15949 (match_operand:MODEF 1 "register_operand" "0"))))]
15950 "TARGET_USE_FANCY_MATH_387"
15952 [(set_attr "type" "fpspc")
15953 (set_attr "mode" "XF")
15954 (set_attr "athlon_decode" "direct")
15955 (set_attr "amdfam10_decode" "direct")])
15957 (define_insn "*rsqrtsf2_sse"
15958 [(set (match_operand:SF 0 "register_operand" "=x")
15959 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15962 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15963 [(set_attr "type" "sse")
15964 (set_attr "atom_sse_attr" "rcp")
15965 (set_attr "prefix" "maybe_vex")
15966 (set_attr "mode" "SF")])
15968 (define_expand "rsqrtsf2"
15969 [(set (match_operand:SF 0 "register_operand" "")
15970 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15974 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15978 (define_insn "*sqrt<mode>2_sse"
15979 [(set (match_operand:MODEF 0 "register_operand" "=x")
15981 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15982 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15983 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15984 [(set_attr "type" "sse")
15985 (set_attr "atom_sse_attr" "sqrt")
15986 (set_attr "prefix" "maybe_vex")
15987 (set_attr "mode" "<MODE>")
15988 (set_attr "athlon_decode" "*")
15989 (set_attr "amdfam10_decode" "*")])
15991 (define_expand "sqrt<mode>2"
15992 [(set (match_operand:MODEF 0 "register_operand" "")
15994 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15995 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15996 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15998 if (<MODE>mode == SFmode
15999 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
16000 && flag_finite_math_only && !flag_trapping_math
16001 && flag_unsafe_math_optimizations)
16003 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
16007 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
16009 rtx op0 = gen_reg_rtx (XFmode);
16010 rtx op1 = force_reg (<MODE>mode, operands[1]);
16012 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
16013 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
16018 (define_insn "fpremxf4_i387"
16019 [(set (match_operand:XF 0 "register_operand" "=f")
16020 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16021 (match_operand:XF 3 "register_operand" "1")]
16023 (set (match_operand:XF 1 "register_operand" "=u")
16024 (unspec:XF [(match_dup 2) (match_dup 3)]
16026 (set (reg:CCFP FPSR_REG)
16027 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16029 "TARGET_USE_FANCY_MATH_387"
16031 [(set_attr "type" "fpspc")
16032 (set_attr "mode" "XF")])
16034 (define_expand "fmodxf3"
16035 [(use (match_operand:XF 0 "register_operand" ""))
16036 (use (match_operand:XF 1 "general_operand" ""))
16037 (use (match_operand:XF 2 "general_operand" ""))]
16038 "TARGET_USE_FANCY_MATH_387"
16040 rtx label = gen_label_rtx ();
16042 rtx op1 = gen_reg_rtx (XFmode);
16043 rtx op2 = gen_reg_rtx (XFmode);
16045 emit_move_insn (op2, operands[2]);
16046 emit_move_insn (op1, operands[1]);
16048 emit_label (label);
16049 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16050 ix86_emit_fp_unordered_jump (label);
16051 LABEL_NUSES (label) = 1;
16053 emit_move_insn (operands[0], op1);
16057 (define_expand "fmod<mode>3"
16058 [(use (match_operand:MODEF 0 "register_operand" ""))
16059 (use (match_operand:MODEF 1 "general_operand" ""))
16060 (use (match_operand:MODEF 2 "general_operand" ""))]
16061 "TARGET_USE_FANCY_MATH_387"
16063 rtx label = gen_label_rtx ();
16065 rtx op1 = gen_reg_rtx (XFmode);
16066 rtx op2 = gen_reg_rtx (XFmode);
16068 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16069 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16071 emit_label (label);
16072 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
16073 ix86_emit_fp_unordered_jump (label);
16074 LABEL_NUSES (label) = 1;
16076 /* Truncate the result properly for strict SSE math. */
16077 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16078 && !TARGET_MIX_SSE_I387)
16079 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16081 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16086 (define_insn "fprem1xf4_i387"
16087 [(set (match_operand:XF 0 "register_operand" "=f")
16088 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16089 (match_operand:XF 3 "register_operand" "1")]
16091 (set (match_operand:XF 1 "register_operand" "=u")
16092 (unspec:XF [(match_dup 2) (match_dup 3)]
16094 (set (reg:CCFP FPSR_REG)
16095 (unspec:CCFP [(match_dup 2) (match_dup 3)]
16097 "TARGET_USE_FANCY_MATH_387"
16099 [(set_attr "type" "fpspc")
16100 (set_attr "mode" "XF")])
16102 (define_expand "remainderxf3"
16103 [(use (match_operand:XF 0 "register_operand" ""))
16104 (use (match_operand:XF 1 "general_operand" ""))
16105 (use (match_operand:XF 2 "general_operand" ""))]
16106 "TARGET_USE_FANCY_MATH_387"
16108 rtx label = gen_label_rtx ();
16110 rtx op1 = gen_reg_rtx (XFmode);
16111 rtx op2 = gen_reg_rtx (XFmode);
16113 emit_move_insn (op2, operands[2]);
16114 emit_move_insn (op1, operands[1]);
16116 emit_label (label);
16117 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16118 ix86_emit_fp_unordered_jump (label);
16119 LABEL_NUSES (label) = 1;
16121 emit_move_insn (operands[0], op1);
16125 (define_expand "remainder<mode>3"
16126 [(use (match_operand:MODEF 0 "register_operand" ""))
16127 (use (match_operand:MODEF 1 "general_operand" ""))
16128 (use (match_operand:MODEF 2 "general_operand" ""))]
16129 "TARGET_USE_FANCY_MATH_387"
16131 rtx label = gen_label_rtx ();
16133 rtx op1 = gen_reg_rtx (XFmode);
16134 rtx op2 = gen_reg_rtx (XFmode);
16136 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16137 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16139 emit_label (label);
16141 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
16142 ix86_emit_fp_unordered_jump (label);
16143 LABEL_NUSES (label) = 1;
16145 /* Truncate the result properly for strict SSE math. */
16146 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16147 && !TARGET_MIX_SSE_I387)
16148 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
16150 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
16155 (define_insn "*sinxf2_i387"
16156 [(set (match_operand:XF 0 "register_operand" "=f")
16157 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
16158 "TARGET_USE_FANCY_MATH_387
16159 && flag_unsafe_math_optimizations"
16161 [(set_attr "type" "fpspc")
16162 (set_attr "mode" "XF")])
16164 (define_insn "*sin_extend<mode>xf2_i387"
16165 [(set (match_operand:XF 0 "register_operand" "=f")
16166 (unspec:XF [(float_extend:XF
16167 (match_operand:MODEF 1 "register_operand" "0"))]
16169 "TARGET_USE_FANCY_MATH_387
16170 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16171 || TARGET_MIX_SSE_I387)
16172 && flag_unsafe_math_optimizations"
16174 [(set_attr "type" "fpspc")
16175 (set_attr "mode" "XF")])
16177 (define_insn "*cosxf2_i387"
16178 [(set (match_operand:XF 0 "register_operand" "=f")
16179 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
16180 "TARGET_USE_FANCY_MATH_387
16181 && flag_unsafe_math_optimizations"
16183 [(set_attr "type" "fpspc")
16184 (set_attr "mode" "XF")])
16186 (define_insn "*cos_extend<mode>xf2_i387"
16187 [(set (match_operand:XF 0 "register_operand" "=f")
16188 (unspec:XF [(float_extend:XF
16189 (match_operand:MODEF 1 "register_operand" "0"))]
16191 "TARGET_USE_FANCY_MATH_387
16192 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16193 || TARGET_MIX_SSE_I387)
16194 && flag_unsafe_math_optimizations"
16196 [(set_attr "type" "fpspc")
16197 (set_attr "mode" "XF")])
16199 ;; When sincos pattern is defined, sin and cos builtin functions will be
16200 ;; expanded to sincos pattern with one of its outputs left unused.
16201 ;; CSE pass will figure out if two sincos patterns can be combined,
16202 ;; otherwise sincos pattern will be split back to sin or cos pattern,
16203 ;; depending on the unused output.
16205 (define_insn "sincosxf3"
16206 [(set (match_operand:XF 0 "register_operand" "=f")
16207 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16208 UNSPEC_SINCOS_COS))
16209 (set (match_operand:XF 1 "register_operand" "=u")
16210 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16211 "TARGET_USE_FANCY_MATH_387
16212 && flag_unsafe_math_optimizations"
16214 [(set_attr "type" "fpspc")
16215 (set_attr "mode" "XF")])
16218 [(set (match_operand:XF 0 "register_operand" "")
16219 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16220 UNSPEC_SINCOS_COS))
16221 (set (match_operand:XF 1 "register_operand" "")
16222 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16223 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16224 && !(reload_completed || reload_in_progress)"
16225 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
16229 [(set (match_operand:XF 0 "register_operand" "")
16230 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
16231 UNSPEC_SINCOS_COS))
16232 (set (match_operand:XF 1 "register_operand" "")
16233 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
16234 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16235 && !(reload_completed || reload_in_progress)"
16236 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
16239 (define_insn "sincos_extend<mode>xf3_i387"
16240 [(set (match_operand:XF 0 "register_operand" "=f")
16241 (unspec:XF [(float_extend:XF
16242 (match_operand:MODEF 2 "register_operand" "0"))]
16243 UNSPEC_SINCOS_COS))
16244 (set (match_operand:XF 1 "register_operand" "=u")
16245 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16246 "TARGET_USE_FANCY_MATH_387
16247 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16248 || TARGET_MIX_SSE_I387)
16249 && flag_unsafe_math_optimizations"
16251 [(set_attr "type" "fpspc")
16252 (set_attr "mode" "XF")])
16255 [(set (match_operand:XF 0 "register_operand" "")
16256 (unspec:XF [(float_extend:XF
16257 (match_operand:MODEF 2 "register_operand" ""))]
16258 UNSPEC_SINCOS_COS))
16259 (set (match_operand:XF 1 "register_operand" "")
16260 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16261 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
16262 && !(reload_completed || reload_in_progress)"
16263 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
16267 [(set (match_operand:XF 0 "register_operand" "")
16268 (unspec:XF [(float_extend:XF
16269 (match_operand:MODEF 2 "register_operand" ""))]
16270 UNSPEC_SINCOS_COS))
16271 (set (match_operand:XF 1 "register_operand" "")
16272 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
16273 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
16274 && !(reload_completed || reload_in_progress)"
16275 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
16278 (define_expand "sincos<mode>3"
16279 [(use (match_operand:MODEF 0 "register_operand" ""))
16280 (use (match_operand:MODEF 1 "register_operand" ""))
16281 (use (match_operand:MODEF 2 "register_operand" ""))]
16282 "TARGET_USE_FANCY_MATH_387
16283 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16284 || TARGET_MIX_SSE_I387)
16285 && flag_unsafe_math_optimizations"
16287 rtx op0 = gen_reg_rtx (XFmode);
16288 rtx op1 = gen_reg_rtx (XFmode);
16290 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
16291 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16292 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
16296 (define_insn "fptanxf4_i387"
16297 [(set (match_operand:XF 0 "register_operand" "=f")
16298 (match_operand:XF 3 "const_double_operand" "F"))
16299 (set (match_operand:XF 1 "register_operand" "=u")
16300 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16302 "TARGET_USE_FANCY_MATH_387
16303 && flag_unsafe_math_optimizations
16304 && standard_80387_constant_p (operands[3]) == 2"
16306 [(set_attr "type" "fpspc")
16307 (set_attr "mode" "XF")])
16309 (define_insn "fptan_extend<mode>xf4_i387"
16310 [(set (match_operand:MODEF 0 "register_operand" "=f")
16311 (match_operand:MODEF 3 "const_double_operand" "F"))
16312 (set (match_operand:XF 1 "register_operand" "=u")
16313 (unspec:XF [(float_extend:XF
16314 (match_operand:MODEF 2 "register_operand" "0"))]
16316 "TARGET_USE_FANCY_MATH_387
16317 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16318 || TARGET_MIX_SSE_I387)
16319 && flag_unsafe_math_optimizations
16320 && standard_80387_constant_p (operands[3]) == 2"
16322 [(set_attr "type" "fpspc")
16323 (set_attr "mode" "XF")])
16325 (define_expand "tanxf2"
16326 [(use (match_operand:XF 0 "register_operand" ""))
16327 (use (match_operand:XF 1 "register_operand" ""))]
16328 "TARGET_USE_FANCY_MATH_387
16329 && flag_unsafe_math_optimizations"
16331 rtx one = gen_reg_rtx (XFmode);
16332 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
16334 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
16338 (define_expand "tan<mode>2"
16339 [(use (match_operand:MODEF 0 "register_operand" ""))
16340 (use (match_operand:MODEF 1 "register_operand" ""))]
16341 "TARGET_USE_FANCY_MATH_387
16342 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16343 || TARGET_MIX_SSE_I387)
16344 && flag_unsafe_math_optimizations"
16346 rtx op0 = gen_reg_rtx (XFmode);
16348 rtx one = gen_reg_rtx (<MODE>mode);
16349 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
16351 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
16352 operands[1], op2));
16353 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16357 (define_insn "*fpatanxf3_i387"
16358 [(set (match_operand:XF 0 "register_operand" "=f")
16359 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16360 (match_operand:XF 2 "register_operand" "u")]
16362 (clobber (match_scratch:XF 3 "=2"))]
16363 "TARGET_USE_FANCY_MATH_387
16364 && flag_unsafe_math_optimizations"
16366 [(set_attr "type" "fpspc")
16367 (set_attr "mode" "XF")])
16369 (define_insn "fpatan_extend<mode>xf3_i387"
16370 [(set (match_operand:XF 0 "register_operand" "=f")
16371 (unspec:XF [(float_extend:XF
16372 (match_operand:MODEF 1 "register_operand" "0"))
16374 (match_operand:MODEF 2 "register_operand" "u"))]
16376 (clobber (match_scratch:XF 3 "=2"))]
16377 "TARGET_USE_FANCY_MATH_387
16378 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16379 || TARGET_MIX_SSE_I387)
16380 && flag_unsafe_math_optimizations"
16382 [(set_attr "type" "fpspc")
16383 (set_attr "mode" "XF")])
16385 (define_expand "atan2xf3"
16386 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16387 (unspec:XF [(match_operand:XF 2 "register_operand" "")
16388 (match_operand:XF 1 "register_operand" "")]
16390 (clobber (match_scratch:XF 3 ""))])]
16391 "TARGET_USE_FANCY_MATH_387
16392 && flag_unsafe_math_optimizations"
16395 (define_expand "atan2<mode>3"
16396 [(use (match_operand:MODEF 0 "register_operand" ""))
16397 (use (match_operand:MODEF 1 "register_operand" ""))
16398 (use (match_operand:MODEF 2 "register_operand" ""))]
16399 "TARGET_USE_FANCY_MATH_387
16400 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16401 || TARGET_MIX_SSE_I387)
16402 && flag_unsafe_math_optimizations"
16404 rtx op0 = gen_reg_rtx (XFmode);
16406 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
16407 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16411 (define_expand "atanxf2"
16412 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16413 (unspec:XF [(match_dup 2)
16414 (match_operand:XF 1 "register_operand" "")]
16416 (clobber (match_scratch:XF 3 ""))])]
16417 "TARGET_USE_FANCY_MATH_387
16418 && flag_unsafe_math_optimizations"
16420 operands[2] = gen_reg_rtx (XFmode);
16421 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16424 (define_expand "atan<mode>2"
16425 [(use (match_operand:MODEF 0 "register_operand" ""))
16426 (use (match_operand:MODEF 1 "register_operand" ""))]
16427 "TARGET_USE_FANCY_MATH_387
16428 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16429 || TARGET_MIX_SSE_I387)
16430 && flag_unsafe_math_optimizations"
16432 rtx op0 = gen_reg_rtx (XFmode);
16434 rtx op2 = gen_reg_rtx (<MODE>mode);
16435 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
16437 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
16438 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16442 (define_expand "asinxf2"
16443 [(set (match_dup 2)
16444 (mult:XF (match_operand:XF 1 "register_operand" "")
16446 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16447 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16448 (parallel [(set (match_operand:XF 0 "register_operand" "")
16449 (unspec:XF [(match_dup 5) (match_dup 1)]
16451 (clobber (match_scratch:XF 6 ""))])]
16452 "TARGET_USE_FANCY_MATH_387
16453 && flag_unsafe_math_optimizations"
16457 if (optimize_insn_for_size_p ())
16460 for (i = 2; i < 6; i++)
16461 operands[i] = gen_reg_rtx (XFmode);
16463 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16466 (define_expand "asin<mode>2"
16467 [(use (match_operand:MODEF 0 "register_operand" ""))
16468 (use (match_operand:MODEF 1 "general_operand" ""))]
16469 "TARGET_USE_FANCY_MATH_387
16470 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16471 || TARGET_MIX_SSE_I387)
16472 && flag_unsafe_math_optimizations"
16474 rtx op0 = gen_reg_rtx (XFmode);
16475 rtx op1 = gen_reg_rtx (XFmode);
16477 if (optimize_insn_for_size_p ())
16480 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16481 emit_insn (gen_asinxf2 (op0, op1));
16482 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16486 (define_expand "acosxf2"
16487 [(set (match_dup 2)
16488 (mult:XF (match_operand:XF 1 "register_operand" "")
16490 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
16491 (set (match_dup 5) (sqrt:XF (match_dup 4)))
16492 (parallel [(set (match_operand:XF 0 "register_operand" "")
16493 (unspec:XF [(match_dup 1) (match_dup 5)]
16495 (clobber (match_scratch:XF 6 ""))])]
16496 "TARGET_USE_FANCY_MATH_387
16497 && flag_unsafe_math_optimizations"
16501 if (optimize_insn_for_size_p ())
16504 for (i = 2; i < 6; i++)
16505 operands[i] = gen_reg_rtx (XFmode);
16507 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
16510 (define_expand "acos<mode>2"
16511 [(use (match_operand:MODEF 0 "register_operand" ""))
16512 (use (match_operand:MODEF 1 "general_operand" ""))]
16513 "TARGET_USE_FANCY_MATH_387
16514 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16515 || TARGET_MIX_SSE_I387)
16516 && flag_unsafe_math_optimizations"
16518 rtx op0 = gen_reg_rtx (XFmode);
16519 rtx op1 = gen_reg_rtx (XFmode);
16521 if (optimize_insn_for_size_p ())
16524 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16525 emit_insn (gen_acosxf2 (op0, op1));
16526 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16530 (define_insn "fyl2xxf3_i387"
16531 [(set (match_operand:XF 0 "register_operand" "=f")
16532 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16533 (match_operand:XF 2 "register_operand" "u")]
16535 (clobber (match_scratch:XF 3 "=2"))]
16536 "TARGET_USE_FANCY_MATH_387
16537 && flag_unsafe_math_optimizations"
16539 [(set_attr "type" "fpspc")
16540 (set_attr "mode" "XF")])
16542 (define_insn "fyl2x_extend<mode>xf3_i387"
16543 [(set (match_operand:XF 0 "register_operand" "=f")
16544 (unspec:XF [(float_extend:XF
16545 (match_operand:MODEF 1 "register_operand" "0"))
16546 (match_operand:XF 2 "register_operand" "u")]
16548 (clobber (match_scratch:XF 3 "=2"))]
16549 "TARGET_USE_FANCY_MATH_387
16550 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16551 || TARGET_MIX_SSE_I387)
16552 && flag_unsafe_math_optimizations"
16554 [(set_attr "type" "fpspc")
16555 (set_attr "mode" "XF")])
16557 (define_expand "logxf2"
16558 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16559 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16560 (match_dup 2)] UNSPEC_FYL2X))
16561 (clobber (match_scratch:XF 3 ""))])]
16562 "TARGET_USE_FANCY_MATH_387
16563 && flag_unsafe_math_optimizations"
16565 operands[2] = gen_reg_rtx (XFmode);
16566 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
16569 (define_expand "log<mode>2"
16570 [(use (match_operand:MODEF 0 "register_operand" ""))
16571 (use (match_operand:MODEF 1 "register_operand" ""))]
16572 "TARGET_USE_FANCY_MATH_387
16573 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16574 || TARGET_MIX_SSE_I387)
16575 && flag_unsafe_math_optimizations"
16577 rtx op0 = gen_reg_rtx (XFmode);
16579 rtx op2 = gen_reg_rtx (XFmode);
16580 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
16582 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16583 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16587 (define_expand "log10xf2"
16588 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16589 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16590 (match_dup 2)] UNSPEC_FYL2X))
16591 (clobber (match_scratch:XF 3 ""))])]
16592 "TARGET_USE_FANCY_MATH_387
16593 && flag_unsafe_math_optimizations"
16595 operands[2] = gen_reg_rtx (XFmode);
16596 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
16599 (define_expand "log10<mode>2"
16600 [(use (match_operand:MODEF 0 "register_operand" ""))
16601 (use (match_operand:MODEF 1 "register_operand" ""))]
16602 "TARGET_USE_FANCY_MATH_387
16603 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16604 || TARGET_MIX_SSE_I387)
16605 && flag_unsafe_math_optimizations"
16607 rtx op0 = gen_reg_rtx (XFmode);
16609 rtx op2 = gen_reg_rtx (XFmode);
16610 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
16612 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16613 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16617 (define_expand "log2xf2"
16618 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16619 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16620 (match_dup 2)] UNSPEC_FYL2X))
16621 (clobber (match_scratch:XF 3 ""))])]
16622 "TARGET_USE_FANCY_MATH_387
16623 && flag_unsafe_math_optimizations"
16625 operands[2] = gen_reg_rtx (XFmode);
16626 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
16629 (define_expand "log2<mode>2"
16630 [(use (match_operand:MODEF 0 "register_operand" ""))
16631 (use (match_operand:MODEF 1 "register_operand" ""))]
16632 "TARGET_USE_FANCY_MATH_387
16633 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16634 || TARGET_MIX_SSE_I387)
16635 && flag_unsafe_math_optimizations"
16637 rtx op0 = gen_reg_rtx (XFmode);
16639 rtx op2 = gen_reg_rtx (XFmode);
16640 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16642 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
16643 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16647 (define_insn "fyl2xp1xf3_i387"
16648 [(set (match_operand:XF 0 "register_operand" "=f")
16649 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
16650 (match_operand:XF 2 "register_operand" "u")]
16652 (clobber (match_scratch:XF 3 "=2"))]
16653 "TARGET_USE_FANCY_MATH_387
16654 && flag_unsafe_math_optimizations"
16656 [(set_attr "type" "fpspc")
16657 (set_attr "mode" "XF")])
16659 (define_insn "fyl2xp1_extend<mode>xf3_i387"
16660 [(set (match_operand:XF 0 "register_operand" "=f")
16661 (unspec:XF [(float_extend:XF
16662 (match_operand:MODEF 1 "register_operand" "0"))
16663 (match_operand:XF 2 "register_operand" "u")]
16665 (clobber (match_scratch:XF 3 "=2"))]
16666 "TARGET_USE_FANCY_MATH_387
16667 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16668 || TARGET_MIX_SSE_I387)
16669 && flag_unsafe_math_optimizations"
16671 [(set_attr "type" "fpspc")
16672 (set_attr "mode" "XF")])
16674 (define_expand "log1pxf2"
16675 [(use (match_operand:XF 0 "register_operand" ""))
16676 (use (match_operand:XF 1 "register_operand" ""))]
16677 "TARGET_USE_FANCY_MATH_387
16678 && flag_unsafe_math_optimizations"
16680 if (optimize_insn_for_size_p ())
16683 ix86_emit_i387_log1p (operands[0], operands[1]);
16687 (define_expand "log1p<mode>2"
16688 [(use (match_operand:MODEF 0 "register_operand" ""))
16689 (use (match_operand:MODEF 1 "register_operand" ""))]
16690 "TARGET_USE_FANCY_MATH_387
16691 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16692 || TARGET_MIX_SSE_I387)
16693 && flag_unsafe_math_optimizations"
16697 if (optimize_insn_for_size_p ())
16700 op0 = gen_reg_rtx (XFmode);
16702 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
16704 ix86_emit_i387_log1p (op0, operands[1]);
16705 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16709 (define_insn "fxtractxf3_i387"
16710 [(set (match_operand:XF 0 "register_operand" "=f")
16711 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
16712 UNSPEC_XTRACT_FRACT))
16713 (set (match_operand:XF 1 "register_operand" "=u")
16714 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
16715 "TARGET_USE_FANCY_MATH_387
16716 && flag_unsafe_math_optimizations"
16718 [(set_attr "type" "fpspc")
16719 (set_attr "mode" "XF")])
16721 (define_insn "fxtract_extend<mode>xf3_i387"
16722 [(set (match_operand:XF 0 "register_operand" "=f")
16723 (unspec:XF [(float_extend:XF
16724 (match_operand:MODEF 2 "register_operand" "0"))]
16725 UNSPEC_XTRACT_FRACT))
16726 (set (match_operand:XF 1 "register_operand" "=u")
16727 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
16728 "TARGET_USE_FANCY_MATH_387
16729 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16730 || TARGET_MIX_SSE_I387)
16731 && flag_unsafe_math_optimizations"
16733 [(set_attr "type" "fpspc")
16734 (set_attr "mode" "XF")])
16736 (define_expand "logbxf2"
16737 [(parallel [(set (match_dup 2)
16738 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16739 UNSPEC_XTRACT_FRACT))
16740 (set (match_operand:XF 0 "register_operand" "")
16741 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16742 "TARGET_USE_FANCY_MATH_387
16743 && flag_unsafe_math_optimizations"
16745 operands[2] = gen_reg_rtx (XFmode);
16748 (define_expand "logb<mode>2"
16749 [(use (match_operand:MODEF 0 "register_operand" ""))
16750 (use (match_operand:MODEF 1 "register_operand" ""))]
16751 "TARGET_USE_FANCY_MATH_387
16752 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16753 || TARGET_MIX_SSE_I387)
16754 && flag_unsafe_math_optimizations"
16756 rtx op0 = gen_reg_rtx (XFmode);
16757 rtx op1 = gen_reg_rtx (XFmode);
16759 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16760 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
16764 (define_expand "ilogbxf2"
16765 [(use (match_operand:SI 0 "register_operand" ""))
16766 (use (match_operand:XF 1 "register_operand" ""))]
16767 "TARGET_USE_FANCY_MATH_387
16768 && flag_unsafe_math_optimizations"
16772 if (optimize_insn_for_size_p ())
16775 op0 = gen_reg_rtx (XFmode);
16776 op1 = gen_reg_rtx (XFmode);
16778 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16779 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16783 (define_expand "ilogb<mode>2"
16784 [(use (match_operand:SI 0 "register_operand" ""))
16785 (use (match_operand:MODEF 1 "register_operand" ""))]
16786 "TARGET_USE_FANCY_MATH_387
16787 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16788 || TARGET_MIX_SSE_I387)
16789 && flag_unsafe_math_optimizations"
16793 if (optimize_insn_for_size_p ())
16796 op0 = gen_reg_rtx (XFmode);
16797 op1 = gen_reg_rtx (XFmode);
16799 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16800 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16804 (define_insn "*f2xm1xf2_i387"
16805 [(set (match_operand:XF 0 "register_operand" "=f")
16806 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16808 "TARGET_USE_FANCY_MATH_387
16809 && flag_unsafe_math_optimizations"
16811 [(set_attr "type" "fpspc")
16812 (set_attr "mode" "XF")])
16814 (define_insn "*fscalexf4_i387"
16815 [(set (match_operand:XF 0 "register_operand" "=f")
16816 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16817 (match_operand:XF 3 "register_operand" "1")]
16818 UNSPEC_FSCALE_FRACT))
16819 (set (match_operand:XF 1 "register_operand" "=u")
16820 (unspec:XF [(match_dup 2) (match_dup 3)]
16821 UNSPEC_FSCALE_EXP))]
16822 "TARGET_USE_FANCY_MATH_387
16823 && flag_unsafe_math_optimizations"
16825 [(set_attr "type" "fpspc")
16826 (set_attr "mode" "XF")])
16828 (define_expand "expNcorexf3"
16829 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16830 (match_operand:XF 2 "register_operand" "")))
16831 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16832 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16833 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16834 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16835 (parallel [(set (match_operand:XF 0 "register_operand" "")
16836 (unspec:XF [(match_dup 8) (match_dup 4)]
16837 UNSPEC_FSCALE_FRACT))
16839 (unspec:XF [(match_dup 8) (match_dup 4)]
16840 UNSPEC_FSCALE_EXP))])]
16841 "TARGET_USE_FANCY_MATH_387
16842 && flag_unsafe_math_optimizations"
16846 if (optimize_insn_for_size_p ())
16849 for (i = 3; i < 10; i++)
16850 operands[i] = gen_reg_rtx (XFmode);
16852 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16855 (define_expand "expxf2"
16856 [(use (match_operand:XF 0 "register_operand" ""))
16857 (use (match_operand:XF 1 "register_operand" ""))]
16858 "TARGET_USE_FANCY_MATH_387
16859 && flag_unsafe_math_optimizations"
16863 if (optimize_insn_for_size_p ())
16866 op2 = gen_reg_rtx (XFmode);
16867 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16869 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16873 (define_expand "exp<mode>2"
16874 [(use (match_operand:MODEF 0 "register_operand" ""))
16875 (use (match_operand:MODEF 1 "general_operand" ""))]
16876 "TARGET_USE_FANCY_MATH_387
16877 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16878 || TARGET_MIX_SSE_I387)
16879 && flag_unsafe_math_optimizations"
16883 if (optimize_insn_for_size_p ())
16886 op0 = gen_reg_rtx (XFmode);
16887 op1 = gen_reg_rtx (XFmode);
16889 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16890 emit_insn (gen_expxf2 (op0, op1));
16891 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16895 (define_expand "exp10xf2"
16896 [(use (match_operand:XF 0 "register_operand" ""))
16897 (use (match_operand:XF 1 "register_operand" ""))]
16898 "TARGET_USE_FANCY_MATH_387
16899 && flag_unsafe_math_optimizations"
16903 if (optimize_insn_for_size_p ())
16906 op2 = gen_reg_rtx (XFmode);
16907 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16909 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16913 (define_expand "exp10<mode>2"
16914 [(use (match_operand:MODEF 0 "register_operand" ""))
16915 (use (match_operand:MODEF 1 "general_operand" ""))]
16916 "TARGET_USE_FANCY_MATH_387
16917 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16918 || TARGET_MIX_SSE_I387)
16919 && flag_unsafe_math_optimizations"
16923 if (optimize_insn_for_size_p ())
16926 op0 = gen_reg_rtx (XFmode);
16927 op1 = gen_reg_rtx (XFmode);
16929 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16930 emit_insn (gen_exp10xf2 (op0, op1));
16931 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16935 (define_expand "exp2xf2"
16936 [(use (match_operand:XF 0 "register_operand" ""))
16937 (use (match_operand:XF 1 "register_operand" ""))]
16938 "TARGET_USE_FANCY_MATH_387
16939 && flag_unsafe_math_optimizations"
16943 if (optimize_insn_for_size_p ())
16946 op2 = gen_reg_rtx (XFmode);
16947 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16949 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16953 (define_expand "exp2<mode>2"
16954 [(use (match_operand:MODEF 0 "register_operand" ""))
16955 (use (match_operand:MODEF 1 "general_operand" ""))]
16956 "TARGET_USE_FANCY_MATH_387
16957 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16958 || TARGET_MIX_SSE_I387)
16959 && flag_unsafe_math_optimizations"
16963 if (optimize_insn_for_size_p ())
16966 op0 = gen_reg_rtx (XFmode);
16967 op1 = gen_reg_rtx (XFmode);
16969 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16970 emit_insn (gen_exp2xf2 (op0, op1));
16971 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16975 (define_expand "expm1xf2"
16976 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16978 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16979 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16980 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16981 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16982 (parallel [(set (match_dup 7)
16983 (unspec:XF [(match_dup 6) (match_dup 4)]
16984 UNSPEC_FSCALE_FRACT))
16986 (unspec:XF [(match_dup 6) (match_dup 4)]
16987 UNSPEC_FSCALE_EXP))])
16988 (parallel [(set (match_dup 10)
16989 (unspec:XF [(match_dup 9) (match_dup 8)]
16990 UNSPEC_FSCALE_FRACT))
16991 (set (match_dup 11)
16992 (unspec:XF [(match_dup 9) (match_dup 8)]
16993 UNSPEC_FSCALE_EXP))])
16994 (set (match_dup 12) (minus:XF (match_dup 10)
16995 (float_extend:XF (match_dup 13))))
16996 (set (match_operand:XF 0 "register_operand" "")
16997 (plus:XF (match_dup 12) (match_dup 7)))]
16998 "TARGET_USE_FANCY_MATH_387
16999 && flag_unsafe_math_optimizations"
17003 if (optimize_insn_for_size_p ())
17006 for (i = 2; i < 13; i++)
17007 operands[i] = gen_reg_rtx (XFmode);
17010 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
17012 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
17015 (define_expand "expm1<mode>2"
17016 [(use (match_operand:MODEF 0 "register_operand" ""))
17017 (use (match_operand:MODEF 1 "general_operand" ""))]
17018 "TARGET_USE_FANCY_MATH_387
17019 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17020 || TARGET_MIX_SSE_I387)
17021 && flag_unsafe_math_optimizations"
17025 if (optimize_insn_for_size_p ())
17028 op0 = gen_reg_rtx (XFmode);
17029 op1 = gen_reg_rtx (XFmode);
17031 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17032 emit_insn (gen_expm1xf2 (op0, op1));
17033 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17037 (define_expand "ldexpxf3"
17038 [(set (match_dup 3)
17039 (float:XF (match_operand:SI 2 "register_operand" "")))
17040 (parallel [(set (match_operand:XF 0 " register_operand" "")
17041 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17043 UNSPEC_FSCALE_FRACT))
17045 (unspec:XF [(match_dup 1) (match_dup 3)]
17046 UNSPEC_FSCALE_EXP))])]
17047 "TARGET_USE_FANCY_MATH_387
17048 && flag_unsafe_math_optimizations"
17050 if (optimize_insn_for_size_p ())
17053 operands[3] = gen_reg_rtx (XFmode);
17054 operands[4] = gen_reg_rtx (XFmode);
17057 (define_expand "ldexp<mode>3"
17058 [(use (match_operand:MODEF 0 "register_operand" ""))
17059 (use (match_operand:MODEF 1 "general_operand" ""))
17060 (use (match_operand:SI 2 "register_operand" ""))]
17061 "TARGET_USE_FANCY_MATH_387
17062 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17063 || TARGET_MIX_SSE_I387)
17064 && flag_unsafe_math_optimizations"
17068 if (optimize_insn_for_size_p ())
17071 op0 = gen_reg_rtx (XFmode);
17072 op1 = gen_reg_rtx (XFmode);
17074 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17075 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
17076 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17080 (define_expand "scalbxf3"
17081 [(parallel [(set (match_operand:XF 0 " register_operand" "")
17082 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17083 (match_operand:XF 2 "register_operand" "")]
17084 UNSPEC_FSCALE_FRACT))
17086 (unspec:XF [(match_dup 1) (match_dup 2)]
17087 UNSPEC_FSCALE_EXP))])]
17088 "TARGET_USE_FANCY_MATH_387
17089 && flag_unsafe_math_optimizations"
17091 if (optimize_insn_for_size_p ())
17094 operands[3] = gen_reg_rtx (XFmode);
17097 (define_expand "scalb<mode>3"
17098 [(use (match_operand:MODEF 0 "register_operand" ""))
17099 (use (match_operand:MODEF 1 "general_operand" ""))
17100 (use (match_operand:MODEF 2 "general_operand" ""))]
17101 "TARGET_USE_FANCY_MATH_387
17102 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17103 || TARGET_MIX_SSE_I387)
17104 && flag_unsafe_math_optimizations"
17108 if (optimize_insn_for_size_p ())
17111 op0 = gen_reg_rtx (XFmode);
17112 op1 = gen_reg_rtx (XFmode);
17113 op2 = gen_reg_rtx (XFmode);
17115 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17116 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17117 emit_insn (gen_scalbxf3 (op0, op1, op2));
17118 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17122 (define_expand "significandxf2"
17123 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17124 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17125 UNSPEC_XTRACT_FRACT))
17127 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
17128 "TARGET_USE_FANCY_MATH_387
17129 && flag_unsafe_math_optimizations"
17131 operands[2] = gen_reg_rtx (XFmode);
17134 (define_expand "significand<mode>2"
17135 [(use (match_operand:MODEF 0 "register_operand" ""))
17136 (use (match_operand:MODEF 1 "register_operand" ""))]
17137 "TARGET_USE_FANCY_MATH_387
17138 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17139 || TARGET_MIX_SSE_I387)
17140 && flag_unsafe_math_optimizations"
17142 rtx op0 = gen_reg_rtx (XFmode);
17143 rtx op1 = gen_reg_rtx (XFmode);
17145 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
17146 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17151 (define_insn "sse4_1_round<mode>2"
17152 [(set (match_operand:MODEF 0 "register_operand" "=x")
17153 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
17154 (match_operand:SI 2 "const_0_to_15_operand" "n")]
17157 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
17158 [(set_attr "type" "ssecvt")
17159 (set_attr "prefix_extra" "1")
17160 (set_attr "prefix" "maybe_vex")
17161 (set_attr "mode" "<MODE>")])
17163 (define_insn "rintxf2"
17164 [(set (match_operand:XF 0 "register_operand" "=f")
17165 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17167 "TARGET_USE_FANCY_MATH_387
17168 && flag_unsafe_math_optimizations"
17170 [(set_attr "type" "fpspc")
17171 (set_attr "mode" "XF")])
17173 (define_expand "rint<mode>2"
17174 [(use (match_operand:MODEF 0 "register_operand" ""))
17175 (use (match_operand:MODEF 1 "register_operand" ""))]
17176 "(TARGET_USE_FANCY_MATH_387
17177 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17178 || TARGET_MIX_SSE_I387)
17179 && flag_unsafe_math_optimizations)
17180 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17181 && !flag_trapping_math)"
17183 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17184 && !flag_trapping_math)
17186 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17189 emit_insn (gen_sse4_1_round<mode>2
17190 (operands[0], operands[1], GEN_INT (0x04)));
17192 ix86_expand_rint (operand0, operand1);
17196 rtx op0 = gen_reg_rtx (XFmode);
17197 rtx op1 = gen_reg_rtx (XFmode);
17199 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17200 emit_insn (gen_rintxf2 (op0, op1));
17202 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17207 (define_expand "round<mode>2"
17208 [(match_operand:MODEF 0 "register_operand" "")
17209 (match_operand:MODEF 1 "nonimmediate_operand" "")]
17210 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17211 && !flag_trapping_math && !flag_rounding_math"
17213 if (optimize_insn_for_size_p ())
17215 if (TARGET_64BIT || (<MODE>mode != DFmode))
17216 ix86_expand_round (operand0, operand1);
17218 ix86_expand_rounddf_32 (operand0, operand1);
17222 (define_insn_and_split "*fistdi2_1"
17223 [(set (match_operand:DI 0 "nonimmediate_operand" "")
17224 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17226 "TARGET_USE_FANCY_MATH_387
17227 && can_create_pseudo_p ()"
17232 if (memory_operand (operands[0], VOIDmode))
17233 emit_insn (gen_fistdi2 (operands[0], operands[1]));
17236 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
17237 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
17242 [(set_attr "type" "fpspc")
17243 (set_attr "mode" "DI")])
17245 (define_insn "fistdi2"
17246 [(set (match_operand:DI 0 "memory_operand" "=m")
17247 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17249 (clobber (match_scratch:XF 2 "=&1f"))]
17250 "TARGET_USE_FANCY_MATH_387"
17251 "* return output_fix_trunc (insn, operands, 0);"
17252 [(set_attr "type" "fpspc")
17253 (set_attr "mode" "DI")])
17255 (define_insn "fistdi2_with_temp"
17256 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17257 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17259 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
17260 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
17261 "TARGET_USE_FANCY_MATH_387"
17263 [(set_attr "type" "fpspc")
17264 (set_attr "mode" "DI")])
17267 [(set (match_operand:DI 0 "register_operand" "")
17268 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17270 (clobber (match_operand:DI 2 "memory_operand" ""))
17271 (clobber (match_scratch 3 ""))]
17273 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17274 (clobber (match_dup 3))])
17275 (set (match_dup 0) (match_dup 2))]
17279 [(set (match_operand:DI 0 "memory_operand" "")
17280 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17282 (clobber (match_operand:DI 2 "memory_operand" ""))
17283 (clobber (match_scratch 3 ""))]
17285 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
17286 (clobber (match_dup 3))])]
17289 (define_insn_and_split "*fist<mode>2_1"
17290 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17291 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17293 "TARGET_USE_FANCY_MATH_387
17294 && can_create_pseudo_p ()"
17299 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17300 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
17304 [(set_attr "type" "fpspc")
17305 (set_attr "mode" "<MODE>")])
17307 (define_insn "fist<mode>2"
17308 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17309 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17311 "TARGET_USE_FANCY_MATH_387"
17312 "* return output_fix_trunc (insn, operands, 0);"
17313 [(set_attr "type" "fpspc")
17314 (set_attr "mode" "<MODE>")])
17316 (define_insn "fist<mode>2_with_temp"
17317 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
17318 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17320 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
17321 "TARGET_USE_FANCY_MATH_387"
17323 [(set_attr "type" "fpspc")
17324 (set_attr "mode" "<MODE>")])
17327 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17328 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17330 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17332 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
17333 (set (match_dup 0) (match_dup 2))]
17337 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17338 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17340 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
17342 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
17345 (define_expand "lrintxf<mode>2"
17346 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17347 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17349 "TARGET_USE_FANCY_MATH_387"
17352 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
17353 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17354 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
17355 UNSPEC_FIX_NOTRUNC))]
17356 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17357 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
17360 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
17361 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
17362 (match_operand:MODEF 1 "register_operand" "")]
17363 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17364 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
17365 && !flag_trapping_math && !flag_rounding_math"
17367 if (optimize_insn_for_size_p ())
17369 ix86_expand_lround (operand0, operand1);
17373 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17374 (define_insn_and_split "frndintxf2_floor"
17375 [(set (match_operand:XF 0 "register_operand" "")
17376 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17377 UNSPEC_FRNDINT_FLOOR))
17378 (clobber (reg:CC FLAGS_REG))]
17379 "TARGET_USE_FANCY_MATH_387
17380 && flag_unsafe_math_optimizations
17381 && can_create_pseudo_p ()"
17386 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17388 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17389 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17391 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
17392 operands[2], operands[3]));
17395 [(set_attr "type" "frndint")
17396 (set_attr "i387_cw" "floor")
17397 (set_attr "mode" "XF")])
17399 (define_insn "frndintxf2_floor_i387"
17400 [(set (match_operand:XF 0 "register_operand" "=f")
17401 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17402 UNSPEC_FRNDINT_FLOOR))
17403 (use (match_operand:HI 2 "memory_operand" "m"))
17404 (use (match_operand:HI 3 "memory_operand" "m"))]
17405 "TARGET_USE_FANCY_MATH_387
17406 && flag_unsafe_math_optimizations"
17407 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17408 [(set_attr "type" "frndint")
17409 (set_attr "i387_cw" "floor")
17410 (set_attr "mode" "XF")])
17412 (define_expand "floorxf2"
17413 [(use (match_operand:XF 0 "register_operand" ""))
17414 (use (match_operand:XF 1 "register_operand" ""))]
17415 "TARGET_USE_FANCY_MATH_387
17416 && flag_unsafe_math_optimizations"
17418 if (optimize_insn_for_size_p ())
17420 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
17424 (define_expand "floor<mode>2"
17425 [(use (match_operand:MODEF 0 "register_operand" ""))
17426 (use (match_operand:MODEF 1 "register_operand" ""))]
17427 "(TARGET_USE_FANCY_MATH_387
17428 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17429 || TARGET_MIX_SSE_I387)
17430 && flag_unsafe_math_optimizations)
17431 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17432 && !flag_trapping_math)"
17434 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17435 && !flag_trapping_math
17436 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17438 if (!TARGET_ROUND && optimize_insn_for_size_p ())
17441 emit_insn (gen_sse4_1_round<mode>2
17442 (operands[0], operands[1], GEN_INT (0x01)));
17443 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17444 ix86_expand_floorceil (operand0, operand1, true);
17446 ix86_expand_floorceildf_32 (operand0, operand1, true);
17452 if (optimize_insn_for_size_p ())
17455 op0 = gen_reg_rtx (XFmode);
17456 op1 = gen_reg_rtx (XFmode);
17457 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17458 emit_insn (gen_frndintxf2_floor (op0, op1));
17460 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17465 (define_insn_and_split "*fist<mode>2_floor_1"
17466 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17467 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17468 UNSPEC_FIST_FLOOR))
17469 (clobber (reg:CC FLAGS_REG))]
17470 "TARGET_USE_FANCY_MATH_387
17471 && flag_unsafe_math_optimizations
17472 && can_create_pseudo_p ()"
17477 ix86_optimize_mode_switching[I387_FLOOR] = 1;
17479 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17480 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
17481 if (memory_operand (operands[0], VOIDmode))
17482 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
17483 operands[2], operands[3]));
17486 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17487 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
17488 operands[2], operands[3],
17493 [(set_attr "type" "fistp")
17494 (set_attr "i387_cw" "floor")
17495 (set_attr "mode" "<MODE>")])
17497 (define_insn "fistdi2_floor"
17498 [(set (match_operand:DI 0 "memory_operand" "=m")
17499 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17500 UNSPEC_FIST_FLOOR))
17501 (use (match_operand:HI 2 "memory_operand" "m"))
17502 (use (match_operand:HI 3 "memory_operand" "m"))
17503 (clobber (match_scratch:XF 4 "=&1f"))]
17504 "TARGET_USE_FANCY_MATH_387
17505 && flag_unsafe_math_optimizations"
17506 "* return output_fix_trunc (insn, operands, 0);"
17507 [(set_attr "type" "fistp")
17508 (set_attr "i387_cw" "floor")
17509 (set_attr "mode" "DI")])
17511 (define_insn "fistdi2_floor_with_temp"
17512 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17513 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17514 UNSPEC_FIST_FLOOR))
17515 (use (match_operand:HI 2 "memory_operand" "m,m"))
17516 (use (match_operand:HI 3 "memory_operand" "m,m"))
17517 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17518 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17519 "TARGET_USE_FANCY_MATH_387
17520 && flag_unsafe_math_optimizations"
17522 [(set_attr "type" "fistp")
17523 (set_attr "i387_cw" "floor")
17524 (set_attr "mode" "DI")])
17527 [(set (match_operand:DI 0 "register_operand" "")
17528 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17529 UNSPEC_FIST_FLOOR))
17530 (use (match_operand:HI 2 "memory_operand" ""))
17531 (use (match_operand:HI 3 "memory_operand" ""))
17532 (clobber (match_operand:DI 4 "memory_operand" ""))
17533 (clobber (match_scratch 5 ""))]
17535 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17536 (use (match_dup 2))
17537 (use (match_dup 3))
17538 (clobber (match_dup 5))])
17539 (set (match_dup 0) (match_dup 4))]
17543 [(set (match_operand:DI 0 "memory_operand" "")
17544 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17545 UNSPEC_FIST_FLOOR))
17546 (use (match_operand:HI 2 "memory_operand" ""))
17547 (use (match_operand:HI 3 "memory_operand" ""))
17548 (clobber (match_operand:DI 4 "memory_operand" ""))
17549 (clobber (match_scratch 5 ""))]
17551 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
17552 (use (match_dup 2))
17553 (use (match_dup 3))
17554 (clobber (match_dup 5))])]
17557 (define_insn "fist<mode>2_floor"
17558 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17559 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17560 UNSPEC_FIST_FLOOR))
17561 (use (match_operand:HI 2 "memory_operand" "m"))
17562 (use (match_operand:HI 3 "memory_operand" "m"))]
17563 "TARGET_USE_FANCY_MATH_387
17564 && flag_unsafe_math_optimizations"
17565 "* return output_fix_trunc (insn, operands, 0);"
17566 [(set_attr "type" "fistp")
17567 (set_attr "i387_cw" "floor")
17568 (set_attr "mode" "<MODE>")])
17570 (define_insn "fist<mode>2_floor_with_temp"
17571 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17572 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17573 UNSPEC_FIST_FLOOR))
17574 (use (match_operand:HI 2 "memory_operand" "m,m"))
17575 (use (match_operand:HI 3 "memory_operand" "m,m"))
17576 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17577 "TARGET_USE_FANCY_MATH_387
17578 && flag_unsafe_math_optimizations"
17580 [(set_attr "type" "fistp")
17581 (set_attr "i387_cw" "floor")
17582 (set_attr "mode" "<MODE>")])
17585 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17586 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17587 UNSPEC_FIST_FLOOR))
17588 (use (match_operand:HI 2 "memory_operand" ""))
17589 (use (match_operand:HI 3 "memory_operand" ""))
17590 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17592 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17593 UNSPEC_FIST_FLOOR))
17594 (use (match_dup 2))
17595 (use (match_dup 3))])
17596 (set (match_dup 0) (match_dup 4))]
17600 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17601 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17602 UNSPEC_FIST_FLOOR))
17603 (use (match_operand:HI 2 "memory_operand" ""))
17604 (use (match_operand:HI 3 "memory_operand" ""))
17605 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17607 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17608 UNSPEC_FIST_FLOOR))
17609 (use (match_dup 2))
17610 (use (match_dup 3))])]
17613 (define_expand "lfloorxf<mode>2"
17614 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17615 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17616 UNSPEC_FIST_FLOOR))
17617 (clobber (reg:CC FLAGS_REG))])]
17618 "TARGET_USE_FANCY_MATH_387
17619 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17620 && flag_unsafe_math_optimizations"
17623 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
17624 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17625 (match_operand:MODEF 1 "register_operand" "")]
17626 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17627 && !flag_trapping_math"
17629 if (TARGET_64BIT && optimize_insn_for_size_p ())
17631 ix86_expand_lfloorceil (operand0, operand1, true);
17635 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17636 (define_insn_and_split "frndintxf2_ceil"
17637 [(set (match_operand:XF 0 "register_operand" "")
17638 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17639 UNSPEC_FRNDINT_CEIL))
17640 (clobber (reg:CC FLAGS_REG))]
17641 "TARGET_USE_FANCY_MATH_387
17642 && flag_unsafe_math_optimizations
17643 && can_create_pseudo_p ()"
17648 ix86_optimize_mode_switching[I387_CEIL] = 1;
17650 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17651 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17653 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
17654 operands[2], operands[3]));
17657 [(set_attr "type" "frndint")
17658 (set_attr "i387_cw" "ceil")
17659 (set_attr "mode" "XF")])
17661 (define_insn "frndintxf2_ceil_i387"
17662 [(set (match_operand:XF 0 "register_operand" "=f")
17663 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17664 UNSPEC_FRNDINT_CEIL))
17665 (use (match_operand:HI 2 "memory_operand" "m"))
17666 (use (match_operand:HI 3 "memory_operand" "m"))]
17667 "TARGET_USE_FANCY_MATH_387
17668 && flag_unsafe_math_optimizations"
17669 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17670 [(set_attr "type" "frndint")
17671 (set_attr "i387_cw" "ceil")
17672 (set_attr "mode" "XF")])
17674 (define_expand "ceilxf2"
17675 [(use (match_operand:XF 0 "register_operand" ""))
17676 (use (match_operand:XF 1 "register_operand" ""))]
17677 "TARGET_USE_FANCY_MATH_387
17678 && flag_unsafe_math_optimizations"
17680 if (optimize_insn_for_size_p ())
17682 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
17686 (define_expand "ceil<mode>2"
17687 [(use (match_operand:MODEF 0 "register_operand" ""))
17688 (use (match_operand:MODEF 1 "register_operand" ""))]
17689 "(TARGET_USE_FANCY_MATH_387
17690 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17691 || TARGET_MIX_SSE_I387)
17692 && flag_unsafe_math_optimizations)
17693 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17694 && !flag_trapping_math)"
17696 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17697 && !flag_trapping_math
17698 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17701 emit_insn (gen_sse4_1_round<mode>2
17702 (operands[0], operands[1], GEN_INT (0x02)));
17703 else if (optimize_insn_for_size_p ())
17705 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17706 ix86_expand_floorceil (operand0, operand1, false);
17708 ix86_expand_floorceildf_32 (operand0, operand1, false);
17714 if (optimize_insn_for_size_p ())
17717 op0 = gen_reg_rtx (XFmode);
17718 op1 = gen_reg_rtx (XFmode);
17719 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17720 emit_insn (gen_frndintxf2_ceil (op0, op1));
17722 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17727 (define_insn_and_split "*fist<mode>2_ceil_1"
17728 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17729 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17731 (clobber (reg:CC FLAGS_REG))]
17732 "TARGET_USE_FANCY_MATH_387
17733 && flag_unsafe_math_optimizations
17734 && can_create_pseudo_p ()"
17739 ix86_optimize_mode_switching[I387_CEIL] = 1;
17741 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17742 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
17743 if (memory_operand (operands[0], VOIDmode))
17744 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
17745 operands[2], operands[3]));
17748 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
17749 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
17750 operands[2], operands[3],
17755 [(set_attr "type" "fistp")
17756 (set_attr "i387_cw" "ceil")
17757 (set_attr "mode" "<MODE>")])
17759 (define_insn "fistdi2_ceil"
17760 [(set (match_operand:DI 0 "memory_operand" "=m")
17761 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
17763 (use (match_operand:HI 2 "memory_operand" "m"))
17764 (use (match_operand:HI 3 "memory_operand" "m"))
17765 (clobber (match_scratch:XF 4 "=&1f"))]
17766 "TARGET_USE_FANCY_MATH_387
17767 && flag_unsafe_math_optimizations"
17768 "* return output_fix_trunc (insn, operands, 0);"
17769 [(set_attr "type" "fistp")
17770 (set_attr "i387_cw" "ceil")
17771 (set_attr "mode" "DI")])
17773 (define_insn "fistdi2_ceil_with_temp"
17774 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
17775 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17777 (use (match_operand:HI 2 "memory_operand" "m,m"))
17778 (use (match_operand:HI 3 "memory_operand" "m,m"))
17779 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17780 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17781 "TARGET_USE_FANCY_MATH_387
17782 && flag_unsafe_math_optimizations"
17784 [(set_attr "type" "fistp")
17785 (set_attr "i387_cw" "ceil")
17786 (set_attr "mode" "DI")])
17789 [(set (match_operand:DI 0 "register_operand" "")
17790 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17792 (use (match_operand:HI 2 "memory_operand" ""))
17793 (use (match_operand:HI 3 "memory_operand" ""))
17794 (clobber (match_operand:DI 4 "memory_operand" ""))
17795 (clobber (match_scratch 5 ""))]
17797 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17798 (use (match_dup 2))
17799 (use (match_dup 3))
17800 (clobber (match_dup 5))])
17801 (set (match_dup 0) (match_dup 4))]
17805 [(set (match_operand:DI 0 "memory_operand" "")
17806 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17808 (use (match_operand:HI 2 "memory_operand" ""))
17809 (use (match_operand:HI 3 "memory_operand" ""))
17810 (clobber (match_operand:DI 4 "memory_operand" ""))
17811 (clobber (match_scratch 5 ""))]
17813 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17814 (use (match_dup 2))
17815 (use (match_dup 3))
17816 (clobber (match_dup 5))])]
17819 (define_insn "fist<mode>2_ceil"
17820 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17821 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17823 (use (match_operand:HI 2 "memory_operand" "m"))
17824 (use (match_operand:HI 3 "memory_operand" "m"))]
17825 "TARGET_USE_FANCY_MATH_387
17826 && flag_unsafe_math_optimizations"
17827 "* return output_fix_trunc (insn, operands, 0);"
17828 [(set_attr "type" "fistp")
17829 (set_attr "i387_cw" "ceil")
17830 (set_attr "mode" "<MODE>")])
17832 (define_insn "fist<mode>2_ceil_with_temp"
17833 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17834 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17836 (use (match_operand:HI 2 "memory_operand" "m,m"))
17837 (use (match_operand:HI 3 "memory_operand" "m,m"))
17838 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17839 "TARGET_USE_FANCY_MATH_387
17840 && flag_unsafe_math_optimizations"
17842 [(set_attr "type" "fistp")
17843 (set_attr "i387_cw" "ceil")
17844 (set_attr "mode" "<MODE>")])
17847 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17848 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17850 (use (match_operand:HI 2 "memory_operand" ""))
17851 (use (match_operand:HI 3 "memory_operand" ""))
17852 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17854 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17856 (use (match_dup 2))
17857 (use (match_dup 3))])
17858 (set (match_dup 0) (match_dup 4))]
17862 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17863 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17865 (use (match_operand:HI 2 "memory_operand" ""))
17866 (use (match_operand:HI 3 "memory_operand" ""))
17867 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17869 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17871 (use (match_dup 2))
17872 (use (match_dup 3))])]
17875 (define_expand "lceilxf<mode>2"
17876 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17877 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17879 (clobber (reg:CC FLAGS_REG))])]
17880 "TARGET_USE_FANCY_MATH_387
17881 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17882 && flag_unsafe_math_optimizations"
17885 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17886 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17887 (match_operand:MODEF 1 "register_operand" "")]
17888 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17889 && !flag_trapping_math"
17891 ix86_expand_lfloorceil (operand0, operand1, false);
17895 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17896 (define_insn_and_split "frndintxf2_trunc"
17897 [(set (match_operand:XF 0 "register_operand" "")
17898 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17899 UNSPEC_FRNDINT_TRUNC))
17900 (clobber (reg:CC FLAGS_REG))]
17901 "TARGET_USE_FANCY_MATH_387
17902 && flag_unsafe_math_optimizations
17903 && can_create_pseudo_p ()"
17908 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17910 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17911 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17913 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17914 operands[2], operands[3]));
17917 [(set_attr "type" "frndint")
17918 (set_attr "i387_cw" "trunc")
17919 (set_attr "mode" "XF")])
17921 (define_insn "frndintxf2_trunc_i387"
17922 [(set (match_operand:XF 0 "register_operand" "=f")
17923 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17924 UNSPEC_FRNDINT_TRUNC))
17925 (use (match_operand:HI 2 "memory_operand" "m"))
17926 (use (match_operand:HI 3 "memory_operand" "m"))]
17927 "TARGET_USE_FANCY_MATH_387
17928 && flag_unsafe_math_optimizations"
17929 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17930 [(set_attr "type" "frndint")
17931 (set_attr "i387_cw" "trunc")
17932 (set_attr "mode" "XF")])
17934 (define_expand "btruncxf2"
17935 [(use (match_operand:XF 0 "register_operand" ""))
17936 (use (match_operand:XF 1 "register_operand" ""))]
17937 "TARGET_USE_FANCY_MATH_387
17938 && flag_unsafe_math_optimizations"
17940 if (optimize_insn_for_size_p ())
17942 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17946 (define_expand "btrunc<mode>2"
17947 [(use (match_operand:MODEF 0 "register_operand" ""))
17948 (use (match_operand:MODEF 1 "register_operand" ""))]
17949 "(TARGET_USE_FANCY_MATH_387
17950 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17951 || TARGET_MIX_SSE_I387)
17952 && flag_unsafe_math_optimizations)
17953 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17954 && !flag_trapping_math)"
17956 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17957 && !flag_trapping_math
17958 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17961 emit_insn (gen_sse4_1_round<mode>2
17962 (operands[0], operands[1], GEN_INT (0x03)));
17963 else if (optimize_insn_for_size_p ())
17965 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17966 ix86_expand_trunc (operand0, operand1);
17968 ix86_expand_truncdf_32 (operand0, operand1);
17974 if (optimize_insn_for_size_p ())
17977 op0 = gen_reg_rtx (XFmode);
17978 op1 = gen_reg_rtx (XFmode);
17979 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17980 emit_insn (gen_frndintxf2_trunc (op0, op1));
17982 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17987 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17988 (define_insn_and_split "frndintxf2_mask_pm"
17989 [(set (match_operand:XF 0 "register_operand" "")
17990 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17991 UNSPEC_FRNDINT_MASK_PM))
17992 (clobber (reg:CC FLAGS_REG))]
17993 "TARGET_USE_FANCY_MATH_387
17994 && flag_unsafe_math_optimizations
17995 && can_create_pseudo_p ()"
18000 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
18002 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18003 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
18005 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
18006 operands[2], operands[3]));
18009 [(set_attr "type" "frndint")
18010 (set_attr "i387_cw" "mask_pm")
18011 (set_attr "mode" "XF")])
18013 (define_insn "frndintxf2_mask_pm_i387"
18014 [(set (match_operand:XF 0 "register_operand" "=f")
18015 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18016 UNSPEC_FRNDINT_MASK_PM))
18017 (use (match_operand:HI 2 "memory_operand" "m"))
18018 (use (match_operand:HI 3 "memory_operand" "m"))]
18019 "TARGET_USE_FANCY_MATH_387
18020 && flag_unsafe_math_optimizations"
18021 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
18022 [(set_attr "type" "frndint")
18023 (set_attr "i387_cw" "mask_pm")
18024 (set_attr "mode" "XF")])
18026 (define_expand "nearbyintxf2"
18027 [(use (match_operand:XF 0 "register_operand" ""))
18028 (use (match_operand:XF 1 "register_operand" ""))]
18029 "TARGET_USE_FANCY_MATH_387
18030 && flag_unsafe_math_optimizations"
18032 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
18037 (define_expand "nearbyint<mode>2"
18038 [(use (match_operand:MODEF 0 "register_operand" ""))
18039 (use (match_operand:MODEF 1 "register_operand" ""))]
18040 "TARGET_USE_FANCY_MATH_387
18041 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18042 || TARGET_MIX_SSE_I387)
18043 && flag_unsafe_math_optimizations"
18045 rtx op0 = gen_reg_rtx (XFmode);
18046 rtx op1 = gen_reg_rtx (XFmode);
18048 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18049 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
18051 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18055 (define_insn "fxam<mode>2_i387"
18056 [(set (match_operand:HI 0 "register_operand" "=a")
18058 [(match_operand:X87MODEF 1 "register_operand" "f")]
18060 "TARGET_USE_FANCY_MATH_387"
18061 "fxam\n\tfnstsw\t%0"
18062 [(set_attr "type" "multi")
18063 (set_attr "length" "4")
18064 (set_attr "unit" "i387")
18065 (set_attr "mode" "<MODE>")])
18067 (define_insn_and_split "fxam<mode>2_i387_with_temp"
18068 [(set (match_operand:HI 0 "register_operand" "")
18070 [(match_operand:MODEF 1 "memory_operand" "")]
18072 "TARGET_USE_FANCY_MATH_387
18073 && can_create_pseudo_p ()"
18076 [(set (match_dup 2)(match_dup 1))
18078 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
18080 operands[2] = gen_reg_rtx (<MODE>mode);
18082 MEM_VOLATILE_P (operands[1]) = 1;
18084 [(set_attr "type" "multi")
18085 (set_attr "unit" "i387")
18086 (set_attr "mode" "<MODE>")])
18088 (define_expand "isinfxf2"
18089 [(use (match_operand:SI 0 "register_operand" ""))
18090 (use (match_operand:XF 1 "register_operand" ""))]
18091 "TARGET_USE_FANCY_MATH_387
18092 && TARGET_C99_FUNCTIONS"
18094 rtx mask = GEN_INT (0x45);
18095 rtx val = GEN_INT (0x05);
18099 rtx scratch = gen_reg_rtx (HImode);
18100 rtx res = gen_reg_rtx (QImode);
18102 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
18104 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18105 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18106 cond = gen_rtx_fmt_ee (EQ, QImode,
18107 gen_rtx_REG (CCmode, FLAGS_REG),
18109 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18110 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18114 (define_expand "isinf<mode>2"
18115 [(use (match_operand:SI 0 "register_operand" ""))
18116 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
18117 "TARGET_USE_FANCY_MATH_387
18118 && TARGET_C99_FUNCTIONS
18119 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18121 rtx mask = GEN_INT (0x45);
18122 rtx val = GEN_INT (0x05);
18126 rtx scratch = gen_reg_rtx (HImode);
18127 rtx res = gen_reg_rtx (QImode);
18129 /* Remove excess precision by forcing value through memory. */
18130 if (memory_operand (operands[1], VOIDmode))
18131 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
18134 enum ix86_stack_slot slot = (virtuals_instantiated
18137 rtx temp = assign_386_stack_local (<MODE>mode, slot);
18139 emit_move_insn (temp, operands[1]);
18140 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
18143 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
18144 emit_insn (gen_cmpqi_ext_3 (scratch, val));
18145 cond = gen_rtx_fmt_ee (EQ, QImode,
18146 gen_rtx_REG (CCmode, FLAGS_REG),
18148 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
18149 emit_insn (gen_zero_extendqisi2 (operands[0], res));
18153 (define_expand "signbit<mode>2"
18154 [(use (match_operand:SI 0 "register_operand" ""))
18155 (use (match_operand:X87MODEF 1 "register_operand" ""))]
18156 "TARGET_USE_FANCY_MATH_387
18157 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18159 rtx mask = GEN_INT (0x0200);
18161 rtx scratch = gen_reg_rtx (HImode);
18163 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
18164 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
18168 ;; Block operation instructions
18171 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
18174 [(set_attr "length" "1")
18175 (set_attr "length_immediate" "0")
18176 (set_attr "modrm" "0")])
18178 (define_expand "movmemsi"
18179 [(use (match_operand:BLK 0 "memory_operand" ""))
18180 (use (match_operand:BLK 1 "memory_operand" ""))
18181 (use (match_operand:SI 2 "nonmemory_operand" ""))
18182 (use (match_operand:SI 3 "const_int_operand" ""))
18183 (use (match_operand:SI 4 "const_int_operand" ""))
18184 (use (match_operand:SI 5 "const_int_operand" ""))]
18187 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18188 operands[4], operands[5]))
18194 (define_expand "movmemdi"
18195 [(use (match_operand:BLK 0 "memory_operand" ""))
18196 (use (match_operand:BLK 1 "memory_operand" ""))
18197 (use (match_operand:DI 2 "nonmemory_operand" ""))
18198 (use (match_operand:DI 3 "const_int_operand" ""))
18199 (use (match_operand:SI 4 "const_int_operand" ""))
18200 (use (match_operand:SI 5 "const_int_operand" ""))]
18203 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
18204 operands[4], operands[5]))
18210 ;; Most CPUs don't like single string operations
18211 ;; Handle this case here to simplify previous expander.
18213 (define_expand "strmov"
18214 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
18215 (set (match_operand 1 "memory_operand" "") (match_dup 4))
18216 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
18217 (clobber (reg:CC FLAGS_REG))])
18218 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
18219 (clobber (reg:CC FLAGS_REG))])]
18222 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
18224 /* If .md ever supports :P for Pmode, these can be directly
18225 in the pattern above. */
18226 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
18227 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
18229 /* Can't use this if the user has appropriated esi or edi. */
18230 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18231 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
18233 emit_insn (gen_strmov_singleop (operands[0], operands[1],
18234 operands[2], operands[3],
18235 operands[5], operands[6]));
18239 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
18242 (define_expand "strmov_singleop"
18243 [(parallel [(set (match_operand 1 "memory_operand" "")
18244 (match_operand 3 "memory_operand" ""))
18245 (set (match_operand 0 "register_operand" "")
18246 (match_operand 4 "" ""))
18247 (set (match_operand 2 "register_operand" "")
18248 (match_operand 5 "" ""))])]
18250 "ix86_current_function_needs_cld = 1;")
18252 (define_insn "*strmovdi_rex_1"
18253 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
18254 (mem:DI (match_operand:DI 3 "register_operand" "1")))
18255 (set (match_operand:DI 0 "register_operand" "=D")
18256 (plus:DI (match_dup 2)
18258 (set (match_operand:DI 1 "register_operand" "=S")
18259 (plus:DI (match_dup 3)
18263 [(set_attr "type" "str")
18264 (set_attr "mode" "DI")
18265 (set_attr "memory" "both")])
18267 (define_insn "*strmovsi_1"
18268 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
18269 (mem:SI (match_operand:SI 3 "register_operand" "1")))
18270 (set (match_operand:SI 0 "register_operand" "=D")
18271 (plus:SI (match_dup 2)
18273 (set (match_operand:SI 1 "register_operand" "=S")
18274 (plus:SI (match_dup 3)
18278 [(set_attr "type" "str")
18279 (set_attr "mode" "SI")
18280 (set_attr "memory" "both")])
18282 (define_insn "*strmovsi_rex_1"
18283 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
18284 (mem:SI (match_operand:DI 3 "register_operand" "1")))
18285 (set (match_operand:DI 0 "register_operand" "=D")
18286 (plus:DI (match_dup 2)
18288 (set (match_operand:DI 1 "register_operand" "=S")
18289 (plus:DI (match_dup 3)
18293 [(set_attr "type" "str")
18294 (set_attr "mode" "SI")
18295 (set_attr "memory" "both")])
18297 (define_insn "*strmovhi_1"
18298 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
18299 (mem:HI (match_operand:SI 3 "register_operand" "1")))
18300 (set (match_operand:SI 0 "register_operand" "=D")
18301 (plus:SI (match_dup 2)
18303 (set (match_operand:SI 1 "register_operand" "=S")
18304 (plus:SI (match_dup 3)
18308 [(set_attr "type" "str")
18309 (set_attr "memory" "both")
18310 (set_attr "mode" "HI")])
18312 (define_insn "*strmovhi_rex_1"
18313 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
18314 (mem:HI (match_operand:DI 3 "register_operand" "1")))
18315 (set (match_operand:DI 0 "register_operand" "=D")
18316 (plus:DI (match_dup 2)
18318 (set (match_operand:DI 1 "register_operand" "=S")
18319 (plus:DI (match_dup 3)
18323 [(set_attr "type" "str")
18324 (set_attr "memory" "both")
18325 (set_attr "mode" "HI")])
18327 (define_insn "*strmovqi_1"
18328 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
18329 (mem:QI (match_operand:SI 3 "register_operand" "1")))
18330 (set (match_operand:SI 0 "register_operand" "=D")
18331 (plus:SI (match_dup 2)
18333 (set (match_operand:SI 1 "register_operand" "=S")
18334 (plus:SI (match_dup 3)
18338 [(set_attr "type" "str")
18339 (set_attr "memory" "both")
18340 (set_attr "mode" "QI")])
18342 (define_insn "*strmovqi_rex_1"
18343 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
18344 (mem:QI (match_operand:DI 3 "register_operand" "1")))
18345 (set (match_operand:DI 0 "register_operand" "=D")
18346 (plus:DI (match_dup 2)
18348 (set (match_operand:DI 1 "register_operand" "=S")
18349 (plus:DI (match_dup 3)
18353 [(set_attr "type" "str")
18354 (set_attr "memory" "both")
18355 (set_attr "prefix_rex" "0")
18356 (set_attr "mode" "QI")])
18358 (define_expand "rep_mov"
18359 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
18360 (set (match_operand 0 "register_operand" "")
18361 (match_operand 5 "" ""))
18362 (set (match_operand 2 "register_operand" "")
18363 (match_operand 6 "" ""))
18364 (set (match_operand 1 "memory_operand" "")
18365 (match_operand 3 "memory_operand" ""))
18366 (use (match_dup 4))])]
18368 "ix86_current_function_needs_cld = 1;")
18370 (define_insn "*rep_movdi_rex64"
18371 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18372 (set (match_operand:DI 0 "register_operand" "=D")
18373 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18375 (match_operand:DI 3 "register_operand" "0")))
18376 (set (match_operand:DI 1 "register_operand" "=S")
18377 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
18378 (match_operand:DI 4 "register_operand" "1")))
18379 (set (mem:BLK (match_dup 3))
18380 (mem:BLK (match_dup 4)))
18381 (use (match_dup 5))]
18384 [(set_attr "type" "str")
18385 (set_attr "prefix_rep" "1")
18386 (set_attr "memory" "both")
18387 (set_attr "mode" "DI")])
18389 (define_insn "*rep_movsi"
18390 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18391 (set (match_operand:SI 0 "register_operand" "=D")
18392 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
18394 (match_operand:SI 3 "register_operand" "0")))
18395 (set (match_operand:SI 1 "register_operand" "=S")
18396 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
18397 (match_operand:SI 4 "register_operand" "1")))
18398 (set (mem:BLK (match_dup 3))
18399 (mem:BLK (match_dup 4)))
18400 (use (match_dup 5))]
18403 [(set_attr "type" "str")
18404 (set_attr "prefix_rep" "1")
18405 (set_attr "memory" "both")
18406 (set_attr "mode" "SI")])
18408 (define_insn "*rep_movsi_rex64"
18409 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18410 (set (match_operand:DI 0 "register_operand" "=D")
18411 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
18413 (match_operand:DI 3 "register_operand" "0")))
18414 (set (match_operand:DI 1 "register_operand" "=S")
18415 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
18416 (match_operand:DI 4 "register_operand" "1")))
18417 (set (mem:BLK (match_dup 3))
18418 (mem:BLK (match_dup 4)))
18419 (use (match_dup 5))]
18422 [(set_attr "type" "str")
18423 (set_attr "prefix_rep" "1")
18424 (set_attr "memory" "both")
18425 (set_attr "mode" "SI")])
18427 (define_insn "*rep_movqi"
18428 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
18429 (set (match_operand:SI 0 "register_operand" "=D")
18430 (plus:SI (match_operand:SI 3 "register_operand" "0")
18431 (match_operand:SI 5 "register_operand" "2")))
18432 (set (match_operand:SI 1 "register_operand" "=S")
18433 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
18434 (set (mem:BLK (match_dup 3))
18435 (mem:BLK (match_dup 4)))
18436 (use (match_dup 5))]
18439 [(set_attr "type" "str")
18440 (set_attr "prefix_rep" "1")
18441 (set_attr "memory" "both")
18442 (set_attr "mode" "SI")])
18444 (define_insn "*rep_movqi_rex64"
18445 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
18446 (set (match_operand:DI 0 "register_operand" "=D")
18447 (plus:DI (match_operand:DI 3 "register_operand" "0")
18448 (match_operand:DI 5 "register_operand" "2")))
18449 (set (match_operand:DI 1 "register_operand" "=S")
18450 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
18451 (set (mem:BLK (match_dup 3))
18452 (mem:BLK (match_dup 4)))
18453 (use (match_dup 5))]
18456 [(set_attr "type" "str")
18457 (set_attr "prefix_rep" "1")
18458 (set_attr "memory" "both")
18459 (set_attr "mode" "SI")])
18461 (define_expand "setmemsi"
18462 [(use (match_operand:BLK 0 "memory_operand" ""))
18463 (use (match_operand:SI 1 "nonmemory_operand" ""))
18464 (use (match_operand 2 "const_int_operand" ""))
18465 (use (match_operand 3 "const_int_operand" ""))
18466 (use (match_operand:SI 4 "const_int_operand" ""))
18467 (use (match_operand:SI 5 "const_int_operand" ""))]
18470 if (ix86_expand_setmem (operands[0], operands[1],
18471 operands[2], operands[3],
18472 operands[4], operands[5]))
18478 (define_expand "setmemdi"
18479 [(use (match_operand:BLK 0 "memory_operand" ""))
18480 (use (match_operand:DI 1 "nonmemory_operand" ""))
18481 (use (match_operand 2 "const_int_operand" ""))
18482 (use (match_operand 3 "const_int_operand" ""))
18483 (use (match_operand 4 "const_int_operand" ""))
18484 (use (match_operand 5 "const_int_operand" ""))]
18487 if (ix86_expand_setmem (operands[0], operands[1],
18488 operands[2], operands[3],
18489 operands[4], operands[5]))
18495 ;; Most CPUs don't like single string operations
18496 ;; Handle this case here to simplify previous expander.
18498 (define_expand "strset"
18499 [(set (match_operand 1 "memory_operand" "")
18500 (match_operand 2 "register_operand" ""))
18501 (parallel [(set (match_operand 0 "register_operand" "")
18503 (clobber (reg:CC FLAGS_REG))])]
18506 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
18507 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
18509 /* If .md ever supports :P for Pmode, this can be directly
18510 in the pattern above. */
18511 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
18512 GEN_INT (GET_MODE_SIZE (GET_MODE
18514 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
18516 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
18522 (define_expand "strset_singleop"
18523 [(parallel [(set (match_operand 1 "memory_operand" "")
18524 (match_operand 2 "register_operand" ""))
18525 (set (match_operand 0 "register_operand" "")
18526 (match_operand 3 "" ""))])]
18528 "ix86_current_function_needs_cld = 1;")
18530 (define_insn "*strsetdi_rex_1"
18531 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
18532 (match_operand:DI 2 "register_operand" "a"))
18533 (set (match_operand:DI 0 "register_operand" "=D")
18534 (plus:DI (match_dup 1)
18538 [(set_attr "type" "str")
18539 (set_attr "memory" "store")
18540 (set_attr "mode" "DI")])
18542 (define_insn "*strsetsi_1"
18543 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
18544 (match_operand:SI 2 "register_operand" "a"))
18545 (set (match_operand:SI 0 "register_operand" "=D")
18546 (plus:SI (match_dup 1)
18550 [(set_attr "type" "str")
18551 (set_attr "memory" "store")
18552 (set_attr "mode" "SI")])
18554 (define_insn "*strsetsi_rex_1"
18555 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
18556 (match_operand:SI 2 "register_operand" "a"))
18557 (set (match_operand:DI 0 "register_operand" "=D")
18558 (plus:DI (match_dup 1)
18562 [(set_attr "type" "str")
18563 (set_attr "memory" "store")
18564 (set_attr "mode" "SI")])
18566 (define_insn "*strsethi_1"
18567 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
18568 (match_operand:HI 2 "register_operand" "a"))
18569 (set (match_operand:SI 0 "register_operand" "=D")
18570 (plus:SI (match_dup 1)
18574 [(set_attr "type" "str")
18575 (set_attr "memory" "store")
18576 (set_attr "mode" "HI")])
18578 (define_insn "*strsethi_rex_1"
18579 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
18580 (match_operand:HI 2 "register_operand" "a"))
18581 (set (match_operand:DI 0 "register_operand" "=D")
18582 (plus:DI (match_dup 1)
18586 [(set_attr "type" "str")
18587 (set_attr "memory" "store")
18588 (set_attr "mode" "HI")])
18590 (define_insn "*strsetqi_1"
18591 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
18592 (match_operand:QI 2 "register_operand" "a"))
18593 (set (match_operand:SI 0 "register_operand" "=D")
18594 (plus:SI (match_dup 1)
18598 [(set_attr "type" "str")
18599 (set_attr "memory" "store")
18600 (set_attr "mode" "QI")])
18602 (define_insn "*strsetqi_rex_1"
18603 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
18604 (match_operand:QI 2 "register_operand" "a"))
18605 (set (match_operand:DI 0 "register_operand" "=D")
18606 (plus:DI (match_dup 1)
18610 [(set_attr "type" "str")
18611 (set_attr "memory" "store")
18612 (set_attr "prefix_rex" "0")
18613 (set_attr "mode" "QI")])
18615 (define_expand "rep_stos"
18616 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
18617 (set (match_operand 0 "register_operand" "")
18618 (match_operand 4 "" ""))
18619 (set (match_operand 2 "memory_operand" "") (const_int 0))
18620 (use (match_operand 3 "register_operand" ""))
18621 (use (match_dup 1))])]
18623 "ix86_current_function_needs_cld = 1;")
18625 (define_insn "*rep_stosdi_rex64"
18626 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18627 (set (match_operand:DI 0 "register_operand" "=D")
18628 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18630 (match_operand:DI 3 "register_operand" "0")))
18631 (set (mem:BLK (match_dup 3))
18633 (use (match_operand:DI 2 "register_operand" "a"))
18634 (use (match_dup 4))]
18637 [(set_attr "type" "str")
18638 (set_attr "prefix_rep" "1")
18639 (set_attr "memory" "store")
18640 (set_attr "mode" "DI")])
18642 (define_insn "*rep_stossi"
18643 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18644 (set (match_operand:SI 0 "register_operand" "=D")
18645 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
18647 (match_operand:SI 3 "register_operand" "0")))
18648 (set (mem:BLK (match_dup 3))
18650 (use (match_operand:SI 2 "register_operand" "a"))
18651 (use (match_dup 4))]
18654 [(set_attr "type" "str")
18655 (set_attr "prefix_rep" "1")
18656 (set_attr "memory" "store")
18657 (set_attr "mode" "SI")])
18659 (define_insn "*rep_stossi_rex64"
18660 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18661 (set (match_operand:DI 0 "register_operand" "=D")
18662 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
18664 (match_operand:DI 3 "register_operand" "0")))
18665 (set (mem:BLK (match_dup 3))
18667 (use (match_operand:SI 2 "register_operand" "a"))
18668 (use (match_dup 4))]
18671 [(set_attr "type" "str")
18672 (set_attr "prefix_rep" "1")
18673 (set_attr "memory" "store")
18674 (set_attr "mode" "SI")])
18676 (define_insn "*rep_stosqi"
18677 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
18678 (set (match_operand:SI 0 "register_operand" "=D")
18679 (plus:SI (match_operand:SI 3 "register_operand" "0")
18680 (match_operand:SI 4 "register_operand" "1")))
18681 (set (mem:BLK (match_dup 3))
18683 (use (match_operand:QI 2 "register_operand" "a"))
18684 (use (match_dup 4))]
18687 [(set_attr "type" "str")
18688 (set_attr "prefix_rep" "1")
18689 (set_attr "memory" "store")
18690 (set_attr "mode" "QI")])
18692 (define_insn "*rep_stosqi_rex64"
18693 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
18694 (set (match_operand:DI 0 "register_operand" "=D")
18695 (plus:DI (match_operand:DI 3 "register_operand" "0")
18696 (match_operand:DI 4 "register_operand" "1")))
18697 (set (mem:BLK (match_dup 3))
18699 (use (match_operand:QI 2 "register_operand" "a"))
18700 (use (match_dup 4))]
18703 [(set_attr "type" "str")
18704 (set_attr "prefix_rep" "1")
18705 (set_attr "memory" "store")
18706 (set_attr "prefix_rex" "0")
18707 (set_attr "mode" "QI")])
18709 (define_expand "cmpstrnsi"
18710 [(set (match_operand:SI 0 "register_operand" "")
18711 (compare:SI (match_operand:BLK 1 "general_operand" "")
18712 (match_operand:BLK 2 "general_operand" "")))
18713 (use (match_operand 3 "general_operand" ""))
18714 (use (match_operand 4 "immediate_operand" ""))]
18717 rtx addr1, addr2, out, outlow, count, countreg, align;
18719 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
18722 /* Can't use this if the user has appropriated esi or edi. */
18723 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
18728 out = gen_reg_rtx (SImode);
18730 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
18731 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
18732 if (addr1 != XEXP (operands[1], 0))
18733 operands[1] = replace_equiv_address_nv (operands[1], addr1);
18734 if (addr2 != XEXP (operands[2], 0))
18735 operands[2] = replace_equiv_address_nv (operands[2], addr2);
18737 count = operands[3];
18738 countreg = ix86_zero_extend_to_Pmode (count);
18740 /* %%% Iff we are testing strict equality, we can use known alignment
18741 to good advantage. This may be possible with combine, particularly
18742 once cc0 is dead. */
18743 align = operands[4];
18745 if (CONST_INT_P (count))
18747 if (INTVAL (count) == 0)
18749 emit_move_insn (operands[0], const0_rtx);
18752 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
18753 operands[1], operands[2]));
18757 rtx (*cmp_insn)(rtx, rtx);
18760 cmp_insn = gen_cmpdi_1;
18762 cmp_insn = gen_cmpsi_1;
18763 emit_insn (cmp_insn (countreg, countreg));
18764 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
18765 operands[1], operands[2]));
18768 outlow = gen_lowpart (QImode, out);
18769 emit_insn (gen_cmpintqi (outlow));
18770 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
18772 if (operands[0] != out)
18773 emit_move_insn (operands[0], out);
18778 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18780 (define_expand "cmpintqi"
18781 [(set (match_dup 1)
18782 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18784 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18785 (parallel [(set (match_operand:QI 0 "register_operand" "")
18786 (minus:QI (match_dup 1)
18788 (clobber (reg:CC FLAGS_REG))])]
18790 "operands[1] = gen_reg_rtx (QImode);
18791 operands[2] = gen_reg_rtx (QImode);")
18793 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18794 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18796 (define_expand "cmpstrnqi_nz_1"
18797 [(parallel [(set (reg:CC FLAGS_REG)
18798 (compare:CC (match_operand 4 "memory_operand" "")
18799 (match_operand 5 "memory_operand" "")))
18800 (use (match_operand 2 "register_operand" ""))
18801 (use (match_operand:SI 3 "immediate_operand" ""))
18802 (clobber (match_operand 0 "register_operand" ""))
18803 (clobber (match_operand 1 "register_operand" ""))
18804 (clobber (match_dup 2))])]
18806 "ix86_current_function_needs_cld = 1;")
18808 (define_insn "*cmpstrnqi_nz_1"
18809 [(set (reg:CC FLAGS_REG)
18810 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18811 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18812 (use (match_operand:SI 6 "register_operand" "2"))
18813 (use (match_operand:SI 3 "immediate_operand" "i"))
18814 (clobber (match_operand:SI 0 "register_operand" "=S"))
18815 (clobber (match_operand:SI 1 "register_operand" "=D"))
18816 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18819 [(set_attr "type" "str")
18820 (set_attr "mode" "QI")
18821 (set_attr "prefix_rep" "1")])
18823 (define_insn "*cmpstrnqi_nz_rex_1"
18824 [(set (reg:CC FLAGS_REG)
18825 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18826 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18827 (use (match_operand:DI 6 "register_operand" "2"))
18828 (use (match_operand:SI 3 "immediate_operand" "i"))
18829 (clobber (match_operand:DI 0 "register_operand" "=S"))
18830 (clobber (match_operand:DI 1 "register_operand" "=D"))
18831 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18834 [(set_attr "type" "str")
18835 (set_attr "mode" "QI")
18836 (set_attr "prefix_rex" "0")
18837 (set_attr "prefix_rep" "1")])
18839 ;; The same, but the count is not known to not be zero.
18841 (define_expand "cmpstrnqi_1"
18842 [(parallel [(set (reg:CC FLAGS_REG)
18843 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18845 (compare:CC (match_operand 4 "memory_operand" "")
18846 (match_operand 5 "memory_operand" ""))
18848 (use (match_operand:SI 3 "immediate_operand" ""))
18849 (use (reg:CC FLAGS_REG))
18850 (clobber (match_operand 0 "register_operand" ""))
18851 (clobber (match_operand 1 "register_operand" ""))
18852 (clobber (match_dup 2))])]
18854 "ix86_current_function_needs_cld = 1;")
18856 (define_insn "*cmpstrnqi_1"
18857 [(set (reg:CC FLAGS_REG)
18858 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18860 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18861 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18863 (use (match_operand:SI 3 "immediate_operand" "i"))
18864 (use (reg:CC FLAGS_REG))
18865 (clobber (match_operand:SI 0 "register_operand" "=S"))
18866 (clobber (match_operand:SI 1 "register_operand" "=D"))
18867 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18870 [(set_attr "type" "str")
18871 (set_attr "mode" "QI")
18872 (set_attr "prefix_rep" "1")])
18874 (define_insn "*cmpstrnqi_rex_1"
18875 [(set (reg:CC FLAGS_REG)
18876 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18878 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18879 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18881 (use (match_operand:SI 3 "immediate_operand" "i"))
18882 (use (reg:CC FLAGS_REG))
18883 (clobber (match_operand:DI 0 "register_operand" "=S"))
18884 (clobber (match_operand:DI 1 "register_operand" "=D"))
18885 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18888 [(set_attr "type" "str")
18889 (set_attr "mode" "QI")
18890 (set_attr "prefix_rex" "0")
18891 (set_attr "prefix_rep" "1")])
18893 (define_expand "strlensi"
18894 [(set (match_operand:SI 0 "register_operand" "")
18895 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18896 (match_operand:QI 2 "immediate_operand" "")
18897 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18900 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18906 (define_expand "strlendi"
18907 [(set (match_operand:DI 0 "register_operand" "")
18908 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18909 (match_operand:QI 2 "immediate_operand" "")
18910 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18913 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18919 (define_expand "strlenqi_1"
18920 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18921 (clobber (match_operand 1 "register_operand" ""))
18922 (clobber (reg:CC FLAGS_REG))])]
18924 "ix86_current_function_needs_cld = 1;")
18926 (define_insn "*strlenqi_1"
18927 [(set (match_operand:SI 0 "register_operand" "=&c")
18928 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18929 (match_operand:QI 2 "register_operand" "a")
18930 (match_operand:SI 3 "immediate_operand" "i")
18931 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18932 (clobber (match_operand:SI 1 "register_operand" "=D"))
18933 (clobber (reg:CC FLAGS_REG))]
18936 [(set_attr "type" "str")
18937 (set_attr "mode" "QI")
18938 (set_attr "prefix_rep" "1")])
18940 (define_insn "*strlenqi_rex_1"
18941 [(set (match_operand:DI 0 "register_operand" "=&c")
18942 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18943 (match_operand:QI 2 "register_operand" "a")
18944 (match_operand:DI 3 "immediate_operand" "i")
18945 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18946 (clobber (match_operand:DI 1 "register_operand" "=D"))
18947 (clobber (reg:CC FLAGS_REG))]
18950 [(set_attr "type" "str")
18951 (set_attr "mode" "QI")
18952 (set_attr "prefix_rex" "0")
18953 (set_attr "prefix_rep" "1")])
18955 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18956 ;; handled in combine, but it is not currently up to the task.
18957 ;; When used for their truth value, the cmpstrn* expanders generate
18966 ;; The intermediate three instructions are unnecessary.
18968 ;; This one handles cmpstrn*_nz_1...
18971 (set (reg:CC FLAGS_REG)
18972 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18973 (mem:BLK (match_operand 5 "register_operand" ""))))
18974 (use (match_operand 6 "register_operand" ""))
18975 (use (match_operand:SI 3 "immediate_operand" ""))
18976 (clobber (match_operand 0 "register_operand" ""))
18977 (clobber (match_operand 1 "register_operand" ""))
18978 (clobber (match_operand 2 "register_operand" ""))])
18979 (set (match_operand:QI 7 "register_operand" "")
18980 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18981 (set (match_operand:QI 8 "register_operand" "")
18982 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18983 (set (reg FLAGS_REG)
18984 (compare (match_dup 7) (match_dup 8)))
18986 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18988 (set (reg:CC FLAGS_REG)
18989 (compare:CC (mem:BLK (match_dup 4))
18990 (mem:BLK (match_dup 5))))
18991 (use (match_dup 6))
18992 (use (match_dup 3))
18993 (clobber (match_dup 0))
18994 (clobber (match_dup 1))
18995 (clobber (match_dup 2))])]
18998 ;; ...and this one handles cmpstrn*_1.
19001 (set (reg:CC FLAGS_REG)
19002 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
19004 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
19005 (mem:BLK (match_operand 5 "register_operand" "")))
19007 (use (match_operand:SI 3 "immediate_operand" ""))
19008 (use (reg:CC FLAGS_REG))
19009 (clobber (match_operand 0 "register_operand" ""))
19010 (clobber (match_operand 1 "register_operand" ""))
19011 (clobber (match_operand 2 "register_operand" ""))])
19012 (set (match_operand:QI 7 "register_operand" "")
19013 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
19014 (set (match_operand:QI 8 "register_operand" "")
19015 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
19016 (set (reg FLAGS_REG)
19017 (compare (match_dup 7) (match_dup 8)))
19019 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
19021 (set (reg:CC FLAGS_REG)
19022 (if_then_else:CC (ne (match_dup 6)
19024 (compare:CC (mem:BLK (match_dup 4))
19025 (mem:BLK (match_dup 5)))
19027 (use (match_dup 3))
19028 (use (reg:CC FLAGS_REG))
19029 (clobber (match_dup 0))
19030 (clobber (match_dup 1))
19031 (clobber (match_dup 2))])]
19036 ;; Conditional move instructions.
19038 (define_expand "mov<mode>cc"
19039 [(set (match_operand:SWIM 0 "register_operand" "")
19040 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
19041 (match_operand:SWIM 2 "general_operand" "")
19042 (match_operand:SWIM 3 "general_operand" "")))]
19044 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
19046 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
19047 ;; the register first winds up with `sbbl $0,reg', which is also weird.
19048 ;; So just document what we're doing explicitly.
19050 (define_expand "x86_mov<mode>cc_0_m1"
19052 [(set (match_operand:SWI48 0 "register_operand" "")
19053 (if_then_else:SWI48
19054 (match_operator:SWI48 2 "ix86_carry_flag_operator"
19055 [(match_operand 1 "flags_reg_operand" "")
19059 (clobber (reg:CC FLAGS_REG))])]
19063 (define_insn "*x86_mov<mode>cc_0_m1"
19064 [(set (match_operand:SWI48 0 "register_operand" "=r")
19065 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19066 [(reg FLAGS_REG) (const_int 0)])
19069 (clobber (reg:CC FLAGS_REG))]
19071 "sbb{<imodesuffix>}\t%0, %0"
19072 ; Since we don't have the proper number of operands for an alu insn,
19073 ; fill in all the blanks.
19074 [(set_attr "type" "alu")
19075 (set_attr "use_carry" "1")
19076 (set_attr "pent_pair" "pu")
19077 (set_attr "memory" "none")
19078 (set_attr "imm_disp" "false")
19079 (set_attr "mode" "<MODE>")
19080 (set_attr "length_immediate" "0")])
19082 (define_insn "*x86_mov<mode>cc_0_m1_se"
19083 [(set (match_operand:SWI48 0 "register_operand" "=r")
19084 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19085 [(reg FLAGS_REG) (const_int 0)])
19088 (clobber (reg:CC FLAGS_REG))]
19090 "sbb{<imodesuffix>}\t%0, %0"
19091 [(set_attr "type" "alu")
19092 (set_attr "use_carry" "1")
19093 (set_attr "pent_pair" "pu")
19094 (set_attr "memory" "none")
19095 (set_attr "imm_disp" "false")
19096 (set_attr "mode" "<MODE>")
19097 (set_attr "length_immediate" "0")])
19099 (define_insn "*x86_mov<mode>cc_0_m1_neg"
19100 [(set (match_operand:SWI48 0 "register_operand" "=r")
19101 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
19102 [(reg FLAGS_REG) (const_int 0)])))]
19104 "sbb{<imodesuffix>}\t%0, %0"
19105 [(set_attr "type" "alu")
19106 (set_attr "use_carry" "1")
19107 (set_attr "pent_pair" "pu")
19108 (set_attr "memory" "none")
19109 (set_attr "imm_disp" "false")
19110 (set_attr "mode" "<MODE>")
19111 (set_attr "length_immediate" "0")])
19113 (define_insn "*mov<mode>cc_noc"
19114 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
19115 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
19116 [(reg FLAGS_REG) (const_int 0)])
19117 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
19118 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
19119 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19121 cmov%O2%C1\t{%2, %0|%0, %2}
19122 cmov%O2%c1\t{%3, %0|%0, %3}"
19123 [(set_attr "type" "icmov")
19124 (set_attr "mode" "<MODE>")])
19126 (define_insn_and_split "*movqicc_noc"
19127 [(set (match_operand:QI 0 "register_operand" "=r,r")
19128 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
19129 [(match_operand 4 "flags_reg_operand" "")
19131 (match_operand:QI 2 "register_operand" "r,0")
19132 (match_operand:QI 3 "register_operand" "0,r")))]
19133 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
19135 "&& reload_completed"
19136 [(set (match_dup 0)
19137 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19140 "operands[0] = gen_lowpart (SImode, operands[0]);
19141 operands[2] = gen_lowpart (SImode, operands[2]);
19142 operands[3] = gen_lowpart (SImode, operands[3]);"
19143 [(set_attr "type" "icmov")
19144 (set_attr "mode" "SI")])
19146 (define_expand "mov<mode>cc"
19147 [(set (match_operand:X87MODEF 0 "register_operand" "")
19148 (if_then_else:X87MODEF
19149 (match_operand 1 "ix86_fp_comparison_operator" "")
19150 (match_operand:X87MODEF 2 "register_operand" "")
19151 (match_operand:X87MODEF 3 "register_operand" "")))]
19152 "(TARGET_80387 && TARGET_CMOVE)
19153 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19154 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
19156 (define_insn "*movsfcc_1_387"
19157 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
19158 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
19159 [(reg FLAGS_REG) (const_int 0)])
19160 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
19161 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
19162 "TARGET_80387 && TARGET_CMOVE
19163 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19165 fcmov%F1\t{%2, %0|%0, %2}
19166 fcmov%f1\t{%3, %0|%0, %3}
19167 cmov%O2%C1\t{%2, %0|%0, %2}
19168 cmov%O2%c1\t{%3, %0|%0, %3}"
19169 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19170 (set_attr "mode" "SF,SF,SI,SI")])
19172 (define_insn "*movdfcc_1"
19173 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
19174 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19175 [(reg FLAGS_REG) (const_int 0)])
19176 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19177 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19178 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19179 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19181 fcmov%F1\t{%2, %0|%0, %2}
19182 fcmov%f1\t{%3, %0|%0, %3}
19185 [(set_attr "type" "fcmov,fcmov,multi,multi")
19186 (set_attr "mode" "DF")])
19188 (define_insn "*movdfcc_1_rex64"
19189 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
19190 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19191 [(reg FLAGS_REG) (const_int 0)])
19192 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
19193 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
19194 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
19195 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
19197 fcmov%F1\t{%2, %0|%0, %2}
19198 fcmov%f1\t{%3, %0|%0, %3}
19199 cmov%O2%C1\t{%2, %0|%0, %2}
19200 cmov%O2%c1\t{%3, %0|%0, %3}"
19201 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
19202 (set_attr "mode" "DF")])
19205 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
19206 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
19207 [(match_operand 4 "flags_reg_operand" "")
19209 (match_operand:DF 2 "nonimmediate_operand" "")
19210 (match_operand:DF 3 "nonimmediate_operand" "")))]
19211 "!TARGET_64BIT && reload_completed"
19212 [(set (match_dup 2)
19213 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19217 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
19220 "split_di (&operands[2], 2, &operands[5], &operands[7]);
19221 split_di (&operands[0], 1, &operands[2], &operands[3]);")
19223 (define_insn "*movxfcc_1"
19224 [(set (match_operand:XF 0 "register_operand" "=f,f")
19225 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
19226 [(reg FLAGS_REG) (const_int 0)])
19227 (match_operand:XF 2 "register_operand" "f,0")
19228 (match_operand:XF 3 "register_operand" "0,f")))]
19229 "TARGET_80387 && TARGET_CMOVE"
19231 fcmov%F1\t{%2, %0|%0, %2}
19232 fcmov%f1\t{%3, %0|%0, %3}"
19233 [(set_attr "type" "fcmov")
19234 (set_attr "mode" "XF")])
19236 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
19237 ;; the scalar versions to have only XMM registers as operands.
19239 ;; XOP conditional move
19240 (define_insn "*xop_pcmov_<mode>"
19241 [(set (match_operand:MODEF 0 "register_operand" "=x")
19242 (if_then_else:MODEF
19243 (match_operand:MODEF 1 "register_operand" "x")
19244 (match_operand:MODEF 2 "register_operand" "x")
19245 (match_operand:MODEF 3 "register_operand" "x")))]
19246 "TARGET_XOP && ix86_fma4_valid_op_p (operands, insn, 4, true, 1, false)"
19247 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
19248 [(set_attr "type" "sse4arg")])
19250 ;; These versions of the min/max patterns are intentionally ignorant of
19251 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
19252 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
19253 ;; are undefined in this condition, we're certain this is correct.
19255 (define_insn "*avx_<code><mode>3"
19256 [(set (match_operand:MODEF 0 "register_operand" "=x")
19258 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
19259 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19260 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19261 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19262 [(set_attr "type" "sseadd")
19263 (set_attr "prefix" "vex")
19264 (set_attr "mode" "<MODE>")])
19266 (define_insn "<code><mode>3"
19267 [(set (match_operand:MODEF 0 "register_operand" "=x")
19269 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
19270 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
19271 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19272 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
19273 [(set_attr "type" "sseadd")
19274 (set_attr "mode" "<MODE>")])
19276 ;; These versions of the min/max patterns implement exactly the operations
19277 ;; min = (op1 < op2 ? op1 : op2)
19278 ;; max = (!(op1 < op2) ? op1 : op2)
19279 ;; Their operands are not commutative, and thus they may be used in the
19280 ;; presence of -0.0 and NaN.
19282 (define_insn "*avx_ieee_smin<mode>3"
19283 [(set (match_operand:MODEF 0 "register_operand" "=x")
19285 [(match_operand:MODEF 1 "register_operand" "x")
19286 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19288 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19289 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19290 [(set_attr "type" "sseadd")
19291 (set_attr "prefix" "vex")
19292 (set_attr "mode" "<MODE>")])
19294 (define_insn "*ieee_smin<mode>3"
19295 [(set (match_operand:MODEF 0 "register_operand" "=x")
19297 [(match_operand:MODEF 1 "register_operand" "0")
19298 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19300 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19301 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
19302 [(set_attr "type" "sseadd")
19303 (set_attr "mode" "<MODE>")])
19305 (define_insn "*avx_ieee_smax<mode>3"
19306 [(set (match_operand:MODEF 0 "register_operand" "=x")
19308 [(match_operand:MODEF 1 "register_operand" "0")
19309 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19311 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19312 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
19313 [(set_attr "type" "sseadd")
19314 (set_attr "prefix" "vex")
19315 (set_attr "mode" "<MODE>")])
19317 (define_insn "*ieee_smax<mode>3"
19318 [(set (match_operand:MODEF 0 "register_operand" "=x")
19320 [(match_operand:MODEF 1 "register_operand" "0")
19321 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
19323 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
19324 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
19325 [(set_attr "type" "sseadd")
19326 (set_attr "mode" "<MODE>")])
19328 ;; Make two stack loads independent:
19330 ;; fld %st(0) -> fld bb
19331 ;; fmul bb fmul %st(1), %st
19333 ;; Actually we only match the last two instructions for simplicity.
19335 [(set (match_operand 0 "fp_register_operand" "")
19336 (match_operand 1 "fp_register_operand" ""))
19338 (match_operator 2 "binary_fp_operator"
19340 (match_operand 3 "memory_operand" "")]))]
19341 "REGNO (operands[0]) != REGNO (operands[1])"
19342 [(set (match_dup 0) (match_dup 3))
19343 (set (match_dup 0) (match_dup 4))]
19345 ;; The % modifier is not operational anymore in peephole2's, so we have to
19346 ;; swap the operands manually in the case of addition and multiplication.
19347 "if (COMMUTATIVE_ARITH_P (operands[2]))
19348 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19349 operands[0], operands[1]);
19351 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
19352 operands[1], operands[0]);")
19354 ;; Conditional addition patterns
19355 (define_expand "add<mode>cc"
19356 [(match_operand:SWI 0 "register_operand" "")
19357 (match_operand 1 "comparison_operator" "")
19358 (match_operand:SWI 2 "register_operand" "")
19359 (match_operand:SWI 3 "const_int_operand" "")]
19361 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
19364 ;; Misc patterns (?)
19366 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
19367 ;; Otherwise there will be nothing to keep
19369 ;; [(set (reg ebp) (reg esp))]
19370 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
19371 ;; (clobber (eflags)]
19372 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
19374 ;; in proper program order.
19375 (define_insn "pro_epilogue_adjust_stack_1"
19376 [(set (match_operand:SI 0 "register_operand" "=r,r")
19377 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
19378 (match_operand:SI 2 "immediate_operand" "i,i")))
19379 (clobber (reg:CC FLAGS_REG))
19380 (clobber (mem:BLK (scratch)))]
19383 switch (get_attr_type (insn))
19386 return "mov{l}\t{%1, %0|%0, %1}";
19389 if (CONST_INT_P (operands[2])
19390 && (INTVAL (operands[2]) == 128
19391 || (INTVAL (operands[2]) < 0
19392 && INTVAL (operands[2]) != -128)))
19394 operands[2] = GEN_INT (-INTVAL (operands[2]));
19395 return "sub{l}\t{%2, %0|%0, %2}";
19397 return "add{l}\t{%2, %0|%0, %2}";
19400 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19401 return "lea{l}\t{%a2, %0|%0, %a2}";
19404 gcc_unreachable ();
19407 [(set (attr "type")
19408 (cond [(and (eq_attr "alternative" "0")
19409 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19410 (const_string "alu")
19411 (match_operand:SI 2 "const0_operand" "")
19412 (const_string "imov")
19414 (const_string "lea")))
19415 (set (attr "length_immediate")
19416 (cond [(eq_attr "type" "imov")
19418 (and (eq_attr "type" "alu")
19419 (match_operand 2 "const128_operand" ""))
19422 (const_string "*")))
19423 (set_attr "mode" "SI")])
19425 (define_insn "pro_epilogue_adjust_stack_rex64"
19426 [(set (match_operand:DI 0 "register_operand" "=r,r")
19427 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19428 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
19429 (clobber (reg:CC FLAGS_REG))
19430 (clobber (mem:BLK (scratch)))]
19433 switch (get_attr_type (insn))
19436 return "mov{q}\t{%1, %0|%0, %1}";
19439 if (CONST_INT_P (operands[2])
19440 /* Avoid overflows. */
19441 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
19442 && (INTVAL (operands[2]) == 128
19443 || (INTVAL (operands[2]) < 0
19444 && INTVAL (operands[2]) != -128)))
19446 operands[2] = GEN_INT (-INTVAL (operands[2]));
19447 return "sub{q}\t{%2, %0|%0, %2}";
19449 return "add{q}\t{%2, %0|%0, %2}";
19452 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
19453 return "lea{q}\t{%a2, %0|%0, %a2}";
19456 gcc_unreachable ();
19459 [(set (attr "type")
19460 (cond [(and (eq_attr "alternative" "0")
19461 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
19462 (const_string "alu")
19463 (match_operand:DI 2 "const0_operand" "")
19464 (const_string "imov")
19466 (const_string "lea")))
19467 (set (attr "length_immediate")
19468 (cond [(eq_attr "type" "imov")
19470 (and (eq_attr "type" "alu")
19471 (match_operand 2 "const128_operand" ""))
19474 (const_string "*")))
19475 (set_attr "mode" "DI")])
19477 (define_insn "pro_epilogue_adjust_stack_rex64_2"
19478 [(set (match_operand:DI 0 "register_operand" "=r,r")
19479 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
19480 (match_operand:DI 3 "immediate_operand" "i,i")))
19481 (use (match_operand:DI 2 "register_operand" "r,r"))
19482 (clobber (reg:CC FLAGS_REG))
19483 (clobber (mem:BLK (scratch)))]
19486 switch (get_attr_type (insn))
19489 return "add{q}\t{%2, %0|%0, %2}";
19492 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
19493 return "lea{q}\t{%a2, %0|%0, %a2}";
19496 gcc_unreachable ();
19499 [(set_attr "type" "alu,lea")
19500 (set_attr "mode" "DI")])
19502 (define_insn "allocate_stack_worker_32"
19503 [(set (match_operand:SI 0 "register_operand" "=a")
19504 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
19505 UNSPECV_STACK_PROBE))
19506 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
19507 (clobber (reg:CC FLAGS_REG))]
19508 "!TARGET_64BIT && TARGET_STACK_PROBE"
19510 [(set_attr "type" "multi")
19511 (set_attr "length" "5")])
19513 (define_insn "allocate_stack_worker_64"
19514 [(set (match_operand:DI 0 "register_operand" "=a")
19515 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
19516 UNSPECV_STACK_PROBE))
19517 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
19518 (clobber (reg:DI R10_REG))
19519 (clobber (reg:DI R11_REG))
19520 (clobber (reg:CC FLAGS_REG))]
19521 "TARGET_64BIT && TARGET_STACK_PROBE"
19523 [(set_attr "type" "multi")
19524 (set_attr "length" "5")])
19526 (define_expand "allocate_stack"
19527 [(match_operand 0 "register_operand" "")
19528 (match_operand 1 "general_operand" "")]
19529 "TARGET_STACK_PROBE"
19533 #ifndef CHECK_STACK_LIMIT
19534 #define CHECK_STACK_LIMIT 0
19537 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
19538 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
19540 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
19541 stack_pointer_rtx, 0, OPTAB_DIRECT);
19542 if (x != stack_pointer_rtx)
19543 emit_move_insn (stack_pointer_rtx, x);
19547 x = copy_to_mode_reg (Pmode, operands[1]);
19549 x = gen_allocate_stack_worker_64 (x, x);
19551 x = gen_allocate_stack_worker_32 (x, x);
19555 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
19559 ;; Use IOR for stack probes, this is shorter.
19560 (define_expand "probe_stack"
19561 [(match_operand 0 "memory_operand" "")]
19564 if (GET_MODE (operands[0]) == DImode)
19565 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
19567 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
19571 (define_expand "builtin_setjmp_receiver"
19572 [(label_ref (match_operand 0 "" ""))]
19573 "!TARGET_64BIT && flag_pic"
19579 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
19580 rtx label_rtx = gen_label_rtx ();
19581 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
19582 xops[0] = xops[1] = picreg;
19583 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
19584 ix86_expand_binary_operator (MINUS, SImode, xops);
19588 emit_insn (gen_set_got (pic_offset_table_rtx));
19592 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
19595 [(set (match_operand 0 "register_operand" "")
19596 (match_operator 3 "promotable_binary_operator"
19597 [(match_operand 1 "register_operand" "")
19598 (match_operand 2 "aligned_operand" "")]))
19599 (clobber (reg:CC FLAGS_REG))]
19600 "! TARGET_PARTIAL_REG_STALL && reload_completed
19601 && ((GET_MODE (operands[0]) == HImode
19602 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
19603 /* ??? next two lines just !satisfies_constraint_K (...) */
19604 || !CONST_INT_P (operands[2])
19605 || satisfies_constraint_K (operands[2])))
19606 || (GET_MODE (operands[0]) == QImode
19607 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
19608 [(parallel [(set (match_dup 0)
19609 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19610 (clobber (reg:CC FLAGS_REG))])]
19611 "operands[0] = gen_lowpart (SImode, operands[0]);
19612 operands[1] = gen_lowpart (SImode, operands[1]);
19613 if (GET_CODE (operands[3]) != ASHIFT)
19614 operands[2] = gen_lowpart (SImode, operands[2]);
19615 PUT_MODE (operands[3], SImode);")
19617 ; Promote the QImode tests, as i386 has encoding of the AND
19618 ; instruction with 32-bit sign-extended immediate and thus the
19619 ; instruction size is unchanged, except in the %eax case for
19620 ; which it is increased by one byte, hence the ! optimize_size.
19622 [(set (match_operand 0 "flags_reg_operand" "")
19623 (match_operator 2 "compare_operator"
19624 [(and (match_operand 3 "aligned_operand" "")
19625 (match_operand 4 "const_int_operand" ""))
19627 (set (match_operand 1 "register_operand" "")
19628 (and (match_dup 3) (match_dup 4)))]
19629 "! TARGET_PARTIAL_REG_STALL && reload_completed
19630 && optimize_insn_for_speed_p ()
19631 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
19632 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
19633 /* Ensure that the operand will remain sign-extended immediate. */
19634 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
19635 [(parallel [(set (match_dup 0)
19636 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
19639 (and:SI (match_dup 3) (match_dup 4)))])]
19642 = gen_int_mode (INTVAL (operands[4])
19643 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
19644 operands[1] = gen_lowpart (SImode, operands[1]);
19645 operands[3] = gen_lowpart (SImode, operands[3]);
19648 ; Don't promote the QImode tests, as i386 doesn't have encoding of
19649 ; the TEST instruction with 32-bit sign-extended immediate and thus
19650 ; the instruction size would at least double, which is not what we
19651 ; want even with ! optimize_size.
19653 [(set (match_operand 0 "flags_reg_operand" "")
19654 (match_operator 1 "compare_operator"
19655 [(and (match_operand:HI 2 "aligned_operand" "")
19656 (match_operand:HI 3 "const_int_operand" ""))
19658 "! TARGET_PARTIAL_REG_STALL && reload_completed
19659 && ! TARGET_FAST_PREFIX
19660 && optimize_insn_for_speed_p ()
19661 /* Ensure that the operand will remain sign-extended immediate. */
19662 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
19663 [(set (match_dup 0)
19664 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19668 = gen_int_mode (INTVAL (operands[3])
19669 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
19670 operands[2] = gen_lowpart (SImode, operands[2]);
19674 [(set (match_operand 0 "register_operand" "")
19675 (neg (match_operand 1 "register_operand" "")))
19676 (clobber (reg:CC FLAGS_REG))]
19677 "! TARGET_PARTIAL_REG_STALL && reload_completed
19678 && (GET_MODE (operands[0]) == HImode
19679 || (GET_MODE (operands[0]) == QImode
19680 && (TARGET_PROMOTE_QImode
19681 || optimize_insn_for_size_p ())))"
19682 [(parallel [(set (match_dup 0)
19683 (neg:SI (match_dup 1)))
19684 (clobber (reg:CC FLAGS_REG))])]
19685 "operands[0] = gen_lowpart (SImode, operands[0]);
19686 operands[1] = gen_lowpart (SImode, operands[1]);")
19689 [(set (match_operand 0 "register_operand" "")
19690 (not (match_operand 1 "register_operand" "")))]
19691 "! TARGET_PARTIAL_REG_STALL && reload_completed
19692 && (GET_MODE (operands[0]) == HImode
19693 || (GET_MODE (operands[0]) == QImode
19694 && (TARGET_PROMOTE_QImode
19695 || optimize_insn_for_size_p ())))"
19696 [(set (match_dup 0)
19697 (not:SI (match_dup 1)))]
19698 "operands[0] = gen_lowpart (SImode, operands[0]);
19699 operands[1] = gen_lowpart (SImode, operands[1]);")
19702 [(set (match_operand 0 "register_operand" "")
19703 (if_then_else (match_operator 1 "comparison_operator"
19704 [(reg FLAGS_REG) (const_int 0)])
19705 (match_operand 2 "register_operand" "")
19706 (match_operand 3 "register_operand" "")))]
19707 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
19708 && (GET_MODE (operands[0]) == HImode
19709 || (GET_MODE (operands[0]) == QImode
19710 && (TARGET_PROMOTE_QImode
19711 || optimize_insn_for_size_p ())))"
19712 [(set (match_dup 0)
19713 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
19714 "operands[0] = gen_lowpart (SImode, operands[0]);
19715 operands[2] = gen_lowpart (SImode, operands[2]);
19716 operands[3] = gen_lowpart (SImode, operands[3]);")
19719 ;; RTL Peephole optimizations, run before sched2. These primarily look to
19720 ;; transform a complex memory operation into two memory to register operations.
19722 ;; Don't push memory operands
19724 [(set (match_operand:SI 0 "push_operand" "")
19725 (match_operand:SI 1 "memory_operand" ""))
19726 (match_scratch:SI 2 "r")]
19727 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19728 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19729 [(set (match_dup 2) (match_dup 1))
19730 (set (match_dup 0) (match_dup 2))]
19734 [(set (match_operand:DI 0 "push_operand" "")
19735 (match_operand:DI 1 "memory_operand" ""))
19736 (match_scratch:DI 2 "r")]
19737 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19738 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19739 [(set (match_dup 2) (match_dup 1))
19740 (set (match_dup 0) (match_dup 2))]
19743 ;; We need to handle SFmode only, because DFmode and XFmode is split to
19746 [(set (match_operand:SF 0 "push_operand" "")
19747 (match_operand:SF 1 "memory_operand" ""))
19748 (match_scratch:SF 2 "r")]
19749 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19750 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19751 [(set (match_dup 2) (match_dup 1))
19752 (set (match_dup 0) (match_dup 2))]
19756 [(set (match_operand:HI 0 "push_operand" "")
19757 (match_operand:HI 1 "memory_operand" ""))
19758 (match_scratch:HI 2 "r")]
19759 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19760 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19761 [(set (match_dup 2) (match_dup 1))
19762 (set (match_dup 0) (match_dup 2))]
19766 [(set (match_operand:QI 0 "push_operand" "")
19767 (match_operand:QI 1 "memory_operand" ""))
19768 (match_scratch:QI 2 "q")]
19769 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
19770 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
19771 [(set (match_dup 2) (match_dup 1))
19772 (set (match_dup 0) (match_dup 2))]
19775 ;; Don't move an immediate directly to memory when the instruction
19778 [(match_scratch:SI 1 "r")
19779 (set (match_operand:SI 0 "memory_operand" "")
19781 "optimize_insn_for_speed_p ()
19782 && ! TARGET_USE_MOV0
19783 && TARGET_SPLIT_LONG_MOVES
19784 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19785 && peep2_regno_dead_p (0, FLAGS_REG)"
19786 [(parallel [(set (match_dup 1) (const_int 0))
19787 (clobber (reg:CC FLAGS_REG))])
19788 (set (match_dup 0) (match_dup 1))]
19792 [(match_scratch:HI 1 "r")
19793 (set (match_operand:HI 0 "memory_operand" "")
19795 "optimize_insn_for_speed_p ()
19796 && ! TARGET_USE_MOV0
19797 && TARGET_SPLIT_LONG_MOVES
19798 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19799 && peep2_regno_dead_p (0, FLAGS_REG)"
19800 [(parallel [(set (match_dup 2) (const_int 0))
19801 (clobber (reg:CC FLAGS_REG))])
19802 (set (match_dup 0) (match_dup 1))]
19803 "operands[2] = gen_lowpart (SImode, operands[1]);")
19806 [(match_scratch:QI 1 "q")
19807 (set (match_operand:QI 0 "memory_operand" "")
19809 "optimize_insn_for_speed_p ()
19810 && ! TARGET_USE_MOV0
19811 && TARGET_SPLIT_LONG_MOVES
19812 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19813 && peep2_regno_dead_p (0, FLAGS_REG)"
19814 [(parallel [(set (match_dup 2) (const_int 0))
19815 (clobber (reg:CC FLAGS_REG))])
19816 (set (match_dup 0) (match_dup 1))]
19817 "operands[2] = gen_lowpart (SImode, operands[1]);")
19820 [(match_scratch:SI 2 "r")
19821 (set (match_operand:SI 0 "memory_operand" "")
19822 (match_operand:SI 1 "immediate_operand" ""))]
19823 "optimize_insn_for_speed_p ()
19824 && TARGET_SPLIT_LONG_MOVES
19825 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19826 [(set (match_dup 2) (match_dup 1))
19827 (set (match_dup 0) (match_dup 2))]
19831 [(match_scratch:HI 2 "r")
19832 (set (match_operand:HI 0 "memory_operand" "")
19833 (match_operand:HI 1 "immediate_operand" ""))]
19834 "optimize_insn_for_speed_p ()
19835 && TARGET_SPLIT_LONG_MOVES
19836 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19837 [(set (match_dup 2) (match_dup 1))
19838 (set (match_dup 0) (match_dup 2))]
19842 [(match_scratch:QI 2 "q")
19843 (set (match_operand:QI 0 "memory_operand" "")
19844 (match_operand:QI 1 "immediate_operand" ""))]
19845 "optimize_insn_for_speed_p ()
19846 && TARGET_SPLIT_LONG_MOVES
19847 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19848 [(set (match_dup 2) (match_dup 1))
19849 (set (match_dup 0) (match_dup 2))]
19852 ;; Don't compare memory with zero, load and use a test instead.
19854 [(set (match_operand 0 "flags_reg_operand" "")
19855 (match_operator 1 "compare_operator"
19856 [(match_operand:SI 2 "memory_operand" "")
19858 (match_scratch:SI 3 "r")]
19859 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19860 [(set (match_dup 3) (match_dup 2))
19861 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19864 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19865 ;; Don't split NOTs with a displacement operand, because resulting XOR
19866 ;; will not be pairable anyway.
19868 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19869 ;; represented using a modRM byte. The XOR replacement is long decoded,
19870 ;; so this split helps here as well.
19872 ;; Note: Can't do this as a regular split because we can't get proper
19873 ;; lifetime information then.
19876 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19877 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19878 "optimize_insn_for_speed_p ()
19879 && ((TARGET_NOT_UNPAIRABLE
19880 && (!MEM_P (operands[0])
19881 || !memory_displacement_operand (operands[0], SImode)))
19882 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19883 && peep2_regno_dead_p (0, FLAGS_REG)"
19884 [(parallel [(set (match_dup 0)
19885 (xor:SI (match_dup 1) (const_int -1)))
19886 (clobber (reg:CC FLAGS_REG))])]
19890 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19891 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19892 "optimize_insn_for_speed_p ()
19893 && ((TARGET_NOT_UNPAIRABLE
19894 && (!MEM_P (operands[0])
19895 || !memory_displacement_operand (operands[0], HImode)))
19896 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19897 && peep2_regno_dead_p (0, FLAGS_REG)"
19898 [(parallel [(set (match_dup 0)
19899 (xor:HI (match_dup 1) (const_int -1)))
19900 (clobber (reg:CC FLAGS_REG))])]
19904 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19905 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19906 "optimize_insn_for_speed_p ()
19907 && ((TARGET_NOT_UNPAIRABLE
19908 && (!MEM_P (operands[0])
19909 || !memory_displacement_operand (operands[0], QImode)))
19910 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19911 && peep2_regno_dead_p (0, FLAGS_REG)"
19912 [(parallel [(set (match_dup 0)
19913 (xor:QI (match_dup 1) (const_int -1)))
19914 (clobber (reg:CC FLAGS_REG))])]
19917 ;; Non pairable "test imm, reg" instructions can be translated to
19918 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19919 ;; byte opcode instead of two, have a short form for byte operands),
19920 ;; so do it for other CPUs as well. Given that the value was dead,
19921 ;; this should not create any new dependencies. Pass on the sub-word
19922 ;; versions if we're concerned about partial register stalls.
19925 [(set (match_operand 0 "flags_reg_operand" "")
19926 (match_operator 1 "compare_operator"
19927 [(and:SI (match_operand:SI 2 "register_operand" "")
19928 (match_operand:SI 3 "immediate_operand" ""))
19930 "ix86_match_ccmode (insn, CCNOmode)
19931 && (true_regnum (operands[2]) != AX_REG
19932 || satisfies_constraint_K (operands[3]))
19933 && peep2_reg_dead_p (1, operands[2])"
19935 [(set (match_dup 0)
19936 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19939 (and:SI (match_dup 2) (match_dup 3)))])]
19942 ;; We don't need to handle HImode case, because it will be promoted to SImode
19943 ;; on ! TARGET_PARTIAL_REG_STALL
19946 [(set (match_operand 0 "flags_reg_operand" "")
19947 (match_operator 1 "compare_operator"
19948 [(and:QI (match_operand:QI 2 "register_operand" "")
19949 (match_operand:QI 3 "immediate_operand" ""))
19951 "! TARGET_PARTIAL_REG_STALL
19952 && ix86_match_ccmode (insn, CCNOmode)
19953 && true_regnum (operands[2]) != AX_REG
19954 && peep2_reg_dead_p (1, operands[2])"
19956 [(set (match_dup 0)
19957 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19960 (and:QI (match_dup 2) (match_dup 3)))])]
19964 [(set (match_operand 0 "flags_reg_operand" "")
19965 (match_operator 1 "compare_operator"
19968 (match_operand 2 "ext_register_operand" "")
19971 (match_operand 3 "const_int_operand" ""))
19973 "! TARGET_PARTIAL_REG_STALL
19974 && ix86_match_ccmode (insn, CCNOmode)
19975 && true_regnum (operands[2]) != AX_REG
19976 && peep2_reg_dead_p (1, operands[2])"
19977 [(parallel [(set (match_dup 0)
19986 (set (zero_extract:SI (match_dup 2)
19997 ;; Don't do logical operations with memory inputs.
19999 [(match_scratch:SI 2 "r")
20000 (parallel [(set (match_operand:SI 0 "register_operand" "")
20001 (match_operator:SI 3 "arith_or_logical_operator"
20003 (match_operand:SI 1 "memory_operand" "")]))
20004 (clobber (reg:CC FLAGS_REG))])]
20005 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20006 [(set (match_dup 2) (match_dup 1))
20007 (parallel [(set (match_dup 0)
20008 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
20009 (clobber (reg:CC FLAGS_REG))])]
20013 [(match_scratch:SI 2 "r")
20014 (parallel [(set (match_operand:SI 0 "register_operand" "")
20015 (match_operator:SI 3 "arith_or_logical_operator"
20016 [(match_operand:SI 1 "memory_operand" "")
20018 (clobber (reg:CC FLAGS_REG))])]
20019 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
20020 [(set (match_dup 2) (match_dup 1))
20021 (parallel [(set (match_dup 0)
20022 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
20023 (clobber (reg:CC FLAGS_REG))])]
20026 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
20027 ;; refers to the destination of the load!
20030 [(set (match_operand:SI 0 "register_operand" "")
20031 (match_operand:SI 1 "register_operand" ""))
20032 (parallel [(set (match_dup 0)
20033 (match_operator:SI 3 "commutative_operator"
20035 (match_operand:SI 2 "memory_operand" "")]))
20036 (clobber (reg:CC FLAGS_REG))])]
20037 "REGNO (operands[0]) != REGNO (operands[1])
20038 && GENERAL_REGNO_P (REGNO (operands[0]))
20039 && GENERAL_REGNO_P (REGNO (operands[1]))"
20040 [(set (match_dup 0) (match_dup 4))
20041 (parallel [(set (match_dup 0)
20042 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
20043 (clobber (reg:CC FLAGS_REG))])]
20044 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
20047 [(set (match_operand 0 "register_operand" "")
20048 (match_operand 1 "register_operand" ""))
20050 (match_operator 3 "commutative_operator"
20052 (match_operand 2 "memory_operand" "")]))]
20053 "REGNO (operands[0]) != REGNO (operands[1])
20054 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
20055 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
20056 [(set (match_dup 0) (match_dup 2))
20058 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
20061 ; Don't do logical operations with memory outputs
20063 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
20064 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
20065 ; the same decoder scheduling characteristics as the original.
20068 [(match_scratch:SI 2 "r")
20069 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20070 (match_operator:SI 3 "arith_or_logical_operator"
20072 (match_operand:SI 1 "nonmemory_operand" "")]))
20073 (clobber (reg:CC FLAGS_REG))])]
20074 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20075 /* Do not split stack checking probes. */
20076 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20077 [(set (match_dup 2) (match_dup 0))
20078 (parallel [(set (match_dup 2)
20079 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
20080 (clobber (reg:CC FLAGS_REG))])
20081 (set (match_dup 0) (match_dup 2))]
20085 [(match_scratch:SI 2 "r")
20086 (parallel [(set (match_operand:SI 0 "memory_operand" "")
20087 (match_operator:SI 3 "arith_or_logical_operator"
20088 [(match_operand:SI 1 "nonmemory_operand" "")
20090 (clobber (reg:CC FLAGS_REG))])]
20091 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
20092 /* Do not split stack checking probes. */
20093 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
20094 [(set (match_dup 2) (match_dup 0))
20095 (parallel [(set (match_dup 2)
20096 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
20097 (clobber (reg:CC FLAGS_REG))])
20098 (set (match_dup 0) (match_dup 2))]
20101 ;; Attempt to always use XOR for zeroing registers.
20103 [(set (match_operand 0 "register_operand" "")
20104 (match_operand 1 "const0_operand" ""))]
20105 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
20106 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20107 && GENERAL_REG_P (operands[0])
20108 && peep2_regno_dead_p (0, FLAGS_REG)"
20109 [(parallel [(set (match_dup 0) (const_int 0))
20110 (clobber (reg:CC FLAGS_REG))])]
20112 operands[0] = gen_lowpart (word_mode, operands[0]);
20116 [(set (strict_low_part (match_operand 0 "register_operand" ""))
20118 "(GET_MODE (operands[0]) == QImode
20119 || GET_MODE (operands[0]) == HImode)
20120 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
20121 && peep2_regno_dead_p (0, FLAGS_REG)"
20122 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
20123 (clobber (reg:CC FLAGS_REG))])])
20125 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
20127 [(set (match_operand 0 "register_operand" "")
20129 "(GET_MODE (operands[0]) == HImode
20130 || GET_MODE (operands[0]) == SImode
20131 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
20132 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
20133 && peep2_regno_dead_p (0, FLAGS_REG)"
20134 [(parallel [(set (match_dup 0) (const_int -1))
20135 (clobber (reg:CC FLAGS_REG))])]
20136 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
20139 ;; Attempt to convert simple leas to adds. These can be created by
20142 [(set (match_operand:SI 0 "register_operand" "")
20143 (plus:SI (match_dup 0)
20144 (match_operand:SI 1 "nonmemory_operand" "")))]
20145 "peep2_regno_dead_p (0, FLAGS_REG)"
20146 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
20147 (clobber (reg:CC FLAGS_REG))])]
20151 [(set (match_operand:SI 0 "register_operand" "")
20152 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
20153 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
20154 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
20155 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
20156 (clobber (reg:CC FLAGS_REG))])]
20157 "operands[2] = gen_lowpart (SImode, operands[2]);")
20160 [(set (match_operand:DI 0 "register_operand" "")
20161 (plus:DI (match_dup 0)
20162 (match_operand:DI 1 "x86_64_general_operand" "")))]
20163 "peep2_regno_dead_p (0, FLAGS_REG)"
20164 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
20165 (clobber (reg:CC FLAGS_REG))])]
20169 [(set (match_operand:SI 0 "register_operand" "")
20170 (mult:SI (match_dup 0)
20171 (match_operand:SI 1 "const_int_operand" "")))]
20172 "exact_log2 (INTVAL (operands[1])) >= 0
20173 && peep2_regno_dead_p (0, FLAGS_REG)"
20174 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20175 (clobber (reg:CC FLAGS_REG))])]
20176 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20179 [(set (match_operand:DI 0 "register_operand" "")
20180 (mult:DI (match_dup 0)
20181 (match_operand:DI 1 "const_int_operand" "")))]
20182 "exact_log2 (INTVAL (operands[1])) >= 0
20183 && peep2_regno_dead_p (0, FLAGS_REG)"
20184 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
20185 (clobber (reg:CC FLAGS_REG))])]
20186 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
20189 [(set (match_operand:SI 0 "register_operand" "")
20190 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
20191 (match_operand:DI 2 "const_int_operand" "")) 0))]
20192 "exact_log2 (INTVAL (operands[2])) >= 0
20193 && REGNO (operands[0]) == REGNO (operands[1])
20194 && peep2_regno_dead_p (0, FLAGS_REG)"
20195 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
20196 (clobber (reg:CC FLAGS_REG))])]
20197 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
20199 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
20200 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
20201 ;; many CPUs it is also faster, since special hardware to avoid esp
20202 ;; dependencies is present.
20204 ;; While some of these conversions may be done using splitters, we use peepholes
20205 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
20207 ;; Convert prologue esp subtractions to push.
20208 ;; We need register to push. In order to keep verify_flow_info happy we have
20210 ;; - use scratch and clobber it in order to avoid dependencies
20211 ;; - use already live register
20212 ;; We can't use the second way right now, since there is no reliable way how to
20213 ;; verify that given register is live. First choice will also most likely in
20214 ;; fewer dependencies. On the place of esp adjustments it is very likely that
20215 ;; call clobbered registers are dead. We may want to use base pointer as an
20216 ;; alternative when no register is available later.
20219 [(match_scratch:SI 0 "r")
20220 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20221 (clobber (reg:CC FLAGS_REG))
20222 (clobber (mem:BLK (scratch)))])]
20223 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20224 [(clobber (match_dup 0))
20225 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20226 (clobber (mem:BLK (scratch)))])])
20229 [(match_scratch:SI 0 "r")
20230 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20231 (clobber (reg:CC FLAGS_REG))
20232 (clobber (mem:BLK (scratch)))])]
20233 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20234 [(clobber (match_dup 0))
20235 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20236 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20237 (clobber (mem:BLK (scratch)))])])
20239 ;; Convert esp subtractions to push.
20241 [(match_scratch:SI 0 "r")
20242 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
20243 (clobber (reg:CC FLAGS_REG))])]
20244 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20245 [(clobber (match_dup 0))
20246 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20249 [(match_scratch:SI 0 "r")
20250 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
20251 (clobber (reg:CC FLAGS_REG))])]
20252 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20253 [(clobber (match_dup 0))
20254 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
20255 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
20257 ;; Convert epilogue deallocator to pop.
20259 [(match_scratch:SI 0 "r")
20260 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20261 (clobber (reg:CC FLAGS_REG))
20262 (clobber (mem:BLK (scratch)))])]
20263 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20264 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20265 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20266 (clobber (mem:BLK (scratch)))])]
20269 ;; Two pops case is tricky, since pop causes dependency on destination register.
20270 ;; We use two registers if available.
20272 [(match_scratch:SI 0 "r")
20273 (match_scratch:SI 1 "r")
20274 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20275 (clobber (reg:CC FLAGS_REG))
20276 (clobber (mem:BLK (scratch)))])]
20277 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20278 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20279 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20280 (clobber (mem:BLK (scratch)))])
20281 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20282 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20286 [(match_scratch:SI 0 "r")
20287 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20288 (clobber (reg:CC FLAGS_REG))
20289 (clobber (mem:BLK (scratch)))])]
20290 "optimize_insn_for_size_p ()"
20291 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20292 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20293 (clobber (mem:BLK (scratch)))])
20294 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20295 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20298 ;; Convert esp additions to pop.
20300 [(match_scratch:SI 0 "r")
20301 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
20302 (clobber (reg:CC FLAGS_REG))])]
20304 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20305 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20308 ;; Two pops case is tricky, since pop causes dependency on destination register.
20309 ;; We use two registers if available.
20311 [(match_scratch:SI 0 "r")
20312 (match_scratch:SI 1 "r")
20313 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20314 (clobber (reg:CC FLAGS_REG))])]
20316 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20317 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20318 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
20319 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20323 [(match_scratch:SI 0 "r")
20324 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
20325 (clobber (reg:CC FLAGS_REG))])]
20326 "optimize_insn_for_size_p ()"
20327 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20328 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
20329 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
20330 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
20333 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
20334 ;; required and register dies. Similarly for 128 to -128.
20336 [(set (match_operand 0 "flags_reg_operand" "")
20337 (match_operator 1 "compare_operator"
20338 [(match_operand 2 "register_operand" "")
20339 (match_operand 3 "const_int_operand" "")]))]
20340 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
20341 && incdec_operand (operands[3], GET_MODE (operands[3])))
20342 || (!TARGET_FUSE_CMP_AND_BRANCH
20343 && INTVAL (operands[3]) == 128))
20344 && ix86_match_ccmode (insn, CCGCmode)
20345 && peep2_reg_dead_p (1, operands[2])"
20346 [(parallel [(set (match_dup 0)
20347 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
20348 (clobber (match_dup 2))])]
20352 [(match_scratch:DI 0 "r")
20353 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20354 (clobber (reg:CC FLAGS_REG))
20355 (clobber (mem:BLK (scratch)))])]
20356 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20357 [(clobber (match_dup 0))
20358 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20359 (clobber (mem:BLK (scratch)))])])
20362 [(match_scratch:DI 0 "r")
20363 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20364 (clobber (reg:CC FLAGS_REG))
20365 (clobber (mem:BLK (scratch)))])]
20366 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20367 [(clobber (match_dup 0))
20368 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20369 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20370 (clobber (mem:BLK (scratch)))])])
20372 ;; Convert esp subtractions to push.
20374 [(match_scratch:DI 0 "r")
20375 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
20376 (clobber (reg:CC FLAGS_REG))])]
20377 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
20378 [(clobber (match_dup 0))
20379 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20382 [(match_scratch:DI 0 "r")
20383 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
20384 (clobber (reg:CC FLAGS_REG))])]
20385 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
20386 [(clobber (match_dup 0))
20387 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
20388 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
20390 ;; Convert epilogue deallocator to pop.
20392 [(match_scratch:DI 0 "r")
20393 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20394 (clobber (reg:CC FLAGS_REG))
20395 (clobber (mem:BLK (scratch)))])]
20396 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
20397 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20398 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20399 (clobber (mem:BLK (scratch)))])]
20402 ;; Two pops case is tricky, since pop causes dependency on destination register.
20403 ;; We use two registers if available.
20405 [(match_scratch:DI 0 "r")
20406 (match_scratch:DI 1 "r")
20407 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20408 (clobber (reg:CC FLAGS_REG))
20409 (clobber (mem:BLK (scratch)))])]
20410 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
20411 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20412 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20413 (clobber (mem:BLK (scratch)))])
20414 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20415 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20419 [(match_scratch:DI 0 "r")
20420 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20421 (clobber (reg:CC FLAGS_REG))
20422 (clobber (mem:BLK (scratch)))])]
20423 "optimize_insn_for_size_p ()"
20424 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20425 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20426 (clobber (mem:BLK (scratch)))])
20427 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20428 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20431 ;; Convert esp additions to pop.
20433 [(match_scratch:DI 0 "r")
20434 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
20435 (clobber (reg:CC FLAGS_REG))])]
20437 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20438 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20441 ;; Two pops case is tricky, since pop causes dependency on destination register.
20442 ;; We use two registers if available.
20444 [(match_scratch:DI 0 "r")
20445 (match_scratch:DI 1 "r")
20446 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20447 (clobber (reg:CC FLAGS_REG))])]
20449 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20450 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20451 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
20452 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20456 [(match_scratch:DI 0 "r")
20457 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
20458 (clobber (reg:CC FLAGS_REG))])]
20459 "optimize_insn_for_size_p ()"
20460 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20461 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
20462 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
20463 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
20466 ;; Convert imul by three, five and nine into lea
20469 [(set (match_operand:SI 0 "register_operand" "")
20470 (mult:SI (match_operand:SI 1 "register_operand" "")
20471 (match_operand:SI 2 "const_int_operand" "")))
20472 (clobber (reg:CC FLAGS_REG))])]
20473 "INTVAL (operands[2]) == 3
20474 || INTVAL (operands[2]) == 5
20475 || INTVAL (operands[2]) == 9"
20476 [(set (match_dup 0)
20477 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
20479 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20483 [(set (match_operand:SI 0 "register_operand" "")
20484 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20485 (match_operand:SI 2 "const_int_operand" "")))
20486 (clobber (reg:CC FLAGS_REG))])]
20487 "optimize_insn_for_speed_p ()
20488 && (INTVAL (operands[2]) == 3
20489 || INTVAL (operands[2]) == 5
20490 || INTVAL (operands[2]) == 9)"
20491 [(set (match_dup 0) (match_dup 1))
20493 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
20495 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20499 [(set (match_operand:DI 0 "register_operand" "")
20500 (mult:DI (match_operand:DI 1 "register_operand" "")
20501 (match_operand:DI 2 "const_int_operand" "")))
20502 (clobber (reg:CC FLAGS_REG))])]
20504 && (INTVAL (operands[2]) == 3
20505 || INTVAL (operands[2]) == 5
20506 || INTVAL (operands[2]) == 9)"
20507 [(set (match_dup 0)
20508 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
20510 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20514 [(set (match_operand:DI 0 "register_operand" "")
20515 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20516 (match_operand:DI 2 "const_int_operand" "")))
20517 (clobber (reg:CC FLAGS_REG))])]
20519 && optimize_insn_for_speed_p ()
20520 && (INTVAL (operands[2]) == 3
20521 || INTVAL (operands[2]) == 5
20522 || INTVAL (operands[2]) == 9)"
20523 [(set (match_dup 0) (match_dup 1))
20525 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
20527 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
20529 ;; Imul $32bit_imm, mem, reg is vector decoded, while
20530 ;; imul $32bit_imm, reg, reg is direct decoded.
20532 [(match_scratch:DI 3 "r")
20533 (parallel [(set (match_operand:DI 0 "register_operand" "")
20534 (mult:DI (match_operand:DI 1 "memory_operand" "")
20535 (match_operand:DI 2 "immediate_operand" "")))
20536 (clobber (reg:CC FLAGS_REG))])]
20537 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20538 && !satisfies_constraint_K (operands[2])"
20539 [(set (match_dup 3) (match_dup 1))
20540 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
20541 (clobber (reg:CC FLAGS_REG))])]
20545 [(match_scratch:SI 3 "r")
20546 (parallel [(set (match_operand:SI 0 "register_operand" "")
20547 (mult:SI (match_operand:SI 1 "memory_operand" "")
20548 (match_operand:SI 2 "immediate_operand" "")))
20549 (clobber (reg:CC FLAGS_REG))])]
20550 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20551 && !satisfies_constraint_K (operands[2])"
20552 [(set (match_dup 3) (match_dup 1))
20553 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
20554 (clobber (reg:CC FLAGS_REG))])]
20558 [(match_scratch:SI 3 "r")
20559 (parallel [(set (match_operand:DI 0 "register_operand" "")
20561 (mult:SI (match_operand:SI 1 "memory_operand" "")
20562 (match_operand:SI 2 "immediate_operand" ""))))
20563 (clobber (reg:CC FLAGS_REG))])]
20564 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
20565 && !satisfies_constraint_K (operands[2])"
20566 [(set (match_dup 3) (match_dup 1))
20567 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
20568 (clobber (reg:CC FLAGS_REG))])]
20571 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
20572 ;; Convert it into imul reg, reg
20573 ;; It would be better to force assembler to encode instruction using long
20574 ;; immediate, but there is apparently no way to do so.
20576 [(parallel [(set (match_operand:DI 0 "register_operand" "")
20577 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
20578 (match_operand:DI 2 "const_int_operand" "")))
20579 (clobber (reg:CC FLAGS_REG))])
20580 (match_scratch:DI 3 "r")]
20581 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20582 && satisfies_constraint_K (operands[2])"
20583 [(set (match_dup 3) (match_dup 2))
20584 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
20585 (clobber (reg:CC FLAGS_REG))])]
20587 if (!rtx_equal_p (operands[0], operands[1]))
20588 emit_move_insn (operands[0], operands[1]);
20592 [(parallel [(set (match_operand:SI 0 "register_operand" "")
20593 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
20594 (match_operand:SI 2 "const_int_operand" "")))
20595 (clobber (reg:CC FLAGS_REG))])
20596 (match_scratch:SI 3 "r")]
20597 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
20598 && satisfies_constraint_K (operands[2])"
20599 [(set (match_dup 3) (match_dup 2))
20600 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
20601 (clobber (reg:CC FLAGS_REG))])]
20603 if (!rtx_equal_p (operands[0], operands[1]))
20604 emit_move_insn (operands[0], operands[1]);
20608 [(parallel [(set (match_operand:HI 0 "register_operand" "")
20609 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
20610 (match_operand:HI 2 "immediate_operand" "")))
20611 (clobber (reg:CC FLAGS_REG))])
20612 (match_scratch:HI 3 "r")]
20613 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
20614 [(set (match_dup 3) (match_dup 2))
20615 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
20616 (clobber (reg:CC FLAGS_REG))])]
20618 if (!rtx_equal_p (operands[0], operands[1]))
20619 emit_move_insn (operands[0], operands[1]);
20622 ;; After splitting up read-modify operations, array accesses with memory
20623 ;; operands might end up in form:
20625 ;; movl 4(%esp), %edx
20627 ;; instead of pre-splitting:
20629 ;; addl 4(%esp), %eax
20631 ;; movl 4(%esp), %edx
20632 ;; leal (%edx,%eax,4), %eax
20635 [(parallel [(set (match_operand 0 "register_operand" "")
20636 (ashift (match_operand 1 "register_operand" "")
20637 (match_operand 2 "const_int_operand" "")))
20638 (clobber (reg:CC FLAGS_REG))])
20639 (set (match_operand 3 "register_operand")
20640 (match_operand 4 "x86_64_general_operand" ""))
20641 (parallel [(set (match_operand 5 "register_operand" "")
20642 (plus (match_operand 6 "register_operand" "")
20643 (match_operand 7 "register_operand" "")))
20644 (clobber (reg:CC FLAGS_REG))])]
20645 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
20646 /* Validate MODE for lea. */
20647 && ((!TARGET_PARTIAL_REG_STALL
20648 && (GET_MODE (operands[0]) == QImode
20649 || GET_MODE (operands[0]) == HImode))
20650 || GET_MODE (operands[0]) == SImode
20651 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
20652 /* We reorder load and the shift. */
20653 && !rtx_equal_p (operands[1], operands[3])
20654 && !reg_overlap_mentioned_p (operands[0], operands[4])
20655 /* Last PLUS must consist of operand 0 and 3. */
20656 && !rtx_equal_p (operands[0], operands[3])
20657 && (rtx_equal_p (operands[3], operands[6])
20658 || rtx_equal_p (operands[3], operands[7]))
20659 && (rtx_equal_p (operands[0], operands[6])
20660 || rtx_equal_p (operands[0], operands[7]))
20661 /* The intermediate operand 0 must die or be same as output. */
20662 && (rtx_equal_p (operands[0], operands[5])
20663 || peep2_reg_dead_p (3, operands[0]))"
20664 [(set (match_dup 3) (match_dup 4))
20665 (set (match_dup 0) (match_dup 1))]
20667 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
20668 int scale = 1 << INTVAL (operands[2]);
20669 rtx index = gen_lowpart (Pmode, operands[1]);
20670 rtx base = gen_lowpart (Pmode, operands[3]);
20671 rtx dest = gen_lowpart (mode, operands[5]);
20673 operands[1] = gen_rtx_PLUS (Pmode, base,
20674 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
20676 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
20677 operands[0] = dest;
20680 ;; Call-value patterns last so that the wildcard operand does not
20681 ;; disrupt insn-recog's switch tables.
20683 (define_insn "*call_value_pop_0"
20684 [(set (match_operand 0 "" "")
20685 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20686 (match_operand:SI 2 "" "")))
20687 (set (reg:SI SP_REG)
20688 (plus:SI (reg:SI SP_REG)
20689 (match_operand:SI 3 "immediate_operand" "")))]
20692 if (SIBLING_CALL_P (insn))
20695 return "call\t%P1";
20697 [(set_attr "type" "callv")])
20699 (define_insn "*call_value_pop_1"
20700 [(set (match_operand 0 "" "")
20701 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20702 (match_operand:SI 2 "" "")))
20703 (set (reg:SI SP_REG)
20704 (plus:SI (reg:SI SP_REG)
20705 (match_operand:SI 3 "immediate_operand" "i")))]
20706 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20708 if (constant_call_address_operand (operands[1], Pmode))
20709 return "call\t%P1";
20710 return "call\t%A1";
20712 [(set_attr "type" "callv")])
20714 (define_insn "*sibcall_value_pop_1"
20715 [(set (match_operand 0 "" "")
20716 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20717 (match_operand:SI 2 "" "")))
20718 (set (reg:SI SP_REG)
20719 (plus:SI (reg:SI SP_REG)
20720 (match_operand:SI 3 "immediate_operand" "i,i")))]
20721 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20725 [(set_attr "type" "callv")])
20727 (define_insn "*call_value_0"
20728 [(set (match_operand 0 "" "")
20729 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
20730 (match_operand:SI 2 "" "")))]
20733 if (SIBLING_CALL_P (insn))
20736 return "call\t%P1";
20738 [(set_attr "type" "callv")])
20740 (define_insn "*call_value_0_rex64"
20741 [(set (match_operand 0 "" "")
20742 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20743 (match_operand:DI 2 "const_int_operand" "")))]
20746 if (SIBLING_CALL_P (insn))
20749 return "call\t%P1";
20751 [(set_attr "type" "callv")])
20753 (define_insn "*call_value_0_rex64_ms_sysv"
20754 [(set (match_operand 0 "" "")
20755 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
20756 (match_operand:DI 2 "const_int_operand" "")))
20757 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20758 (clobber (reg:TI XMM6_REG))
20759 (clobber (reg:TI XMM7_REG))
20760 (clobber (reg:TI XMM8_REG))
20761 (clobber (reg:TI XMM9_REG))
20762 (clobber (reg:TI XMM10_REG))
20763 (clobber (reg:TI XMM11_REG))
20764 (clobber (reg:TI XMM12_REG))
20765 (clobber (reg:TI XMM13_REG))
20766 (clobber (reg:TI XMM14_REG))
20767 (clobber (reg:TI XMM15_REG))
20768 (clobber (reg:DI SI_REG))
20769 (clobber (reg:DI DI_REG))]
20770 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20772 if (SIBLING_CALL_P (insn))
20775 return "call\t%P1";
20777 [(set_attr "type" "callv")])
20779 (define_insn "*call_value_1"
20780 [(set (match_operand 0 "" "")
20781 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20782 (match_operand:SI 2 "" "")))]
20783 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20785 if (constant_call_address_operand (operands[1], Pmode))
20786 return "call\t%P1";
20787 return "call\t%A1";
20789 [(set_attr "type" "callv")])
20791 (define_insn "*sibcall_value_1"
20792 [(set (match_operand 0 "" "")
20793 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20794 (match_operand:SI 2 "" "")))]
20795 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20799 [(set_attr "type" "callv")])
20801 (define_insn "*call_value_1_rex64"
20802 [(set (match_operand 0 "" "")
20803 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20804 (match_operand:DI 2 "" "")))]
20805 "TARGET_64BIT && !SIBLING_CALL_P (insn)
20806 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20808 if (constant_call_address_operand (operands[1], Pmode))
20809 return "call\t%P1";
20810 return "call\t%A1";
20812 [(set_attr "type" "callv")])
20814 (define_insn "*call_value_1_rex64_ms_sysv"
20815 [(set (match_operand 0 "" "")
20816 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20817 (match_operand:DI 2 "" "")))
20818 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20819 (clobber (reg:TI XMM6_REG))
20820 (clobber (reg:TI XMM7_REG))
20821 (clobber (reg:TI XMM8_REG))
20822 (clobber (reg:TI XMM9_REG))
20823 (clobber (reg:TI XMM10_REG))
20824 (clobber (reg:TI XMM11_REG))
20825 (clobber (reg:TI XMM12_REG))
20826 (clobber (reg:TI XMM13_REG))
20827 (clobber (reg:TI XMM14_REG))
20828 (clobber (reg:TI XMM15_REG))
20829 (clobber (reg:DI SI_REG))
20830 (clobber (reg:DI DI_REG))]
20831 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20833 if (constant_call_address_operand (operands[1], Pmode))
20834 return "call\t%P1";
20835 return "call\t%A1";
20837 [(set_attr "type" "callv")])
20839 (define_insn "*call_value_1_rex64_large"
20840 [(set (match_operand 0 "" "")
20841 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20842 (match_operand:DI 2 "" "")))]
20843 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20845 [(set_attr "type" "callv")])
20847 (define_insn "*sibcall_value_1_rex64"
20848 [(set (match_operand 0 "" "")
20849 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20850 (match_operand:DI 2 "" "")))]
20851 "TARGET_64BIT && SIBLING_CALL_P (insn)"
20855 [(set_attr "type" "callv")])
20857 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20858 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20859 ;; caught for use by garbage collectors and the like. Using an insn that
20860 ;; maps to SIGILL makes it more likely the program will rightfully die.
20861 ;; Keeping with tradition, "6" is in honor of #UD.
20862 (define_insn "trap"
20863 [(trap_if (const_int 1) (const_int 6))]
20865 { return ASM_SHORT "0x0b0f"; }
20866 [(set_attr "length" "2")])
20868 (define_expand "sse_prologue_save"
20869 [(parallel [(set (match_operand:BLK 0 "" "")
20870 (unspec:BLK [(reg:DI XMM0_REG)
20877 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20878 (use (match_operand:DI 1 "register_operand" ""))
20879 (use (match_operand:DI 2 "immediate_operand" ""))
20880 (use (label_ref:DI (match_operand 3 "" "")))])]
20884 (define_insn "*sse_prologue_save_insn"
20885 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20886 (match_operand:DI 4 "const_int_operand" "n")))
20887 (unspec:BLK [(reg:DI XMM0_REG)
20894 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20895 (use (match_operand:DI 1 "register_operand" "r"))
20896 (use (match_operand:DI 2 "const_int_operand" "i"))
20897 (use (label_ref:DI (match_operand 3 "" "X")))]
20899 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20900 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20903 operands[0] = gen_rtx_MEM (Pmode,
20904 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20905 /* VEX instruction with a REX prefix will #UD. */
20906 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20907 gcc_unreachable ();
20909 output_asm_insn ("jmp\t%A1", operands);
20910 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20912 operands[4] = adjust_address (operands[0], DImode, i*16);
20913 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20914 PUT_MODE (operands[4], TImode);
20915 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20916 output_asm_insn ("rex", operands);
20917 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20919 (*targetm.asm_out.internal_label) (asm_out_file, "L",
20920 CODE_LABEL_NUMBER (operands[3]));
20923 [(set_attr "type" "other")
20924 (set_attr "length_immediate" "0")
20925 (set_attr "length_address" "0")
20926 (set (attr "length")
20928 (eq (symbol_ref "TARGET_AVX") (const_int 0))
20929 (const_string "34")
20930 (const_string "42")))
20931 (set_attr "memory" "store")
20932 (set_attr "modrm" "0")
20933 (set_attr "prefix" "maybe_vex")
20934 (set_attr "mode" "DI")])
20936 (define_expand "prefetch"
20937 [(prefetch (match_operand 0 "address_operand" "")
20938 (match_operand:SI 1 "const_int_operand" "")
20939 (match_operand:SI 2 "const_int_operand" ""))]
20940 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20942 int rw = INTVAL (operands[1]);
20943 int locality = INTVAL (operands[2]);
20945 gcc_assert (rw == 0 || rw == 1);
20946 gcc_assert (locality >= 0 && locality <= 3);
20947 gcc_assert (GET_MODE (operands[0]) == Pmode
20948 || GET_MODE (operands[0]) == VOIDmode);
20950 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20951 supported by SSE counterpart or the SSE prefetch is not available
20952 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20954 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20955 operands[2] = GEN_INT (3);
20957 operands[1] = const0_rtx;
20960 (define_insn "*prefetch_sse"
20961 [(prefetch (match_operand:SI 0 "address_operand" "p")
20963 (match_operand:SI 1 "const_int_operand" ""))]
20964 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20966 static const char * const patterns[4] = {
20967 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20970 int locality = INTVAL (operands[1]);
20971 gcc_assert (locality >= 0 && locality <= 3);
20973 return patterns[locality];
20975 [(set_attr "type" "sse")
20976 (set_attr "atom_sse_attr" "prefetch")
20977 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20978 (set_attr "memory" "none")])
20980 (define_insn "*prefetch_sse_rex"
20981 [(prefetch (match_operand:DI 0 "address_operand" "p")
20983 (match_operand:SI 1 "const_int_operand" ""))]
20984 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20986 static const char * const patterns[4] = {
20987 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20990 int locality = INTVAL (operands[1]);
20991 gcc_assert (locality >= 0 && locality <= 3);
20993 return patterns[locality];
20995 [(set_attr "type" "sse")
20996 (set_attr "atom_sse_attr" "prefetch")
20997 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20998 (set_attr "memory" "none")])
21000 (define_insn "*prefetch_3dnow"
21001 [(prefetch (match_operand:SI 0 "address_operand" "p")
21002 (match_operand:SI 1 "const_int_operand" "n")
21004 "TARGET_3DNOW && !TARGET_64BIT"
21006 if (INTVAL (operands[1]) == 0)
21007 return "prefetch\t%a0";
21009 return "prefetchw\t%a0";
21011 [(set_attr "type" "mmx")
21012 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21013 (set_attr "memory" "none")])
21015 (define_insn "*prefetch_3dnow_rex"
21016 [(prefetch (match_operand:DI 0 "address_operand" "p")
21017 (match_operand:SI 1 "const_int_operand" "n")
21019 "TARGET_3DNOW && TARGET_64BIT"
21021 if (INTVAL (operands[1]) == 0)
21022 return "prefetch\t%a0";
21024 return "prefetchw\t%a0";
21026 [(set_attr "type" "mmx")
21027 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
21028 (set_attr "memory" "none")])
21030 (define_expand "stack_protect_set"
21031 [(match_operand 0 "memory_operand" "")
21032 (match_operand 1 "memory_operand" "")]
21035 #ifdef TARGET_THREAD_SSP_OFFSET
21037 emit_insn (gen_stack_tls_protect_set_di (operands[0],
21038 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21040 emit_insn (gen_stack_tls_protect_set_si (operands[0],
21041 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21044 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
21046 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
21051 (define_insn "stack_protect_set_si"
21052 [(set (match_operand:SI 0 "memory_operand" "=m")
21053 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21054 (set (match_scratch:SI 2 "=&r") (const_int 0))
21055 (clobber (reg:CC FLAGS_REG))]
21057 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21058 [(set_attr "type" "multi")])
21060 (define_insn "stack_protect_set_di"
21061 [(set (match_operand:DI 0 "memory_operand" "=m")
21062 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
21063 (set (match_scratch:DI 2 "=&r") (const_int 0))
21064 (clobber (reg:CC FLAGS_REG))]
21066 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
21067 [(set_attr "type" "multi")])
21069 (define_insn "stack_tls_protect_set_si"
21070 [(set (match_operand:SI 0 "memory_operand" "=m")
21071 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21072 (set (match_scratch:SI 2 "=&r") (const_int 0))
21073 (clobber (reg:CC FLAGS_REG))]
21075 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
21076 [(set_attr "type" "multi")])
21078 (define_insn "stack_tls_protect_set_di"
21079 [(set (match_operand:DI 0 "memory_operand" "=m")
21080 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
21081 (set (match_scratch:DI 2 "=&r") (const_int 0))
21082 (clobber (reg:CC FLAGS_REG))]
21085 /* The kernel uses a different segment register for performance reasons; a
21086 system call would not have to trash the userspace segment register,
21087 which would be expensive */
21088 if (ix86_cmodel != CM_KERNEL)
21089 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21091 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
21093 [(set_attr "type" "multi")])
21095 (define_expand "stack_protect_test"
21096 [(match_operand 0 "memory_operand" "")
21097 (match_operand 1 "memory_operand" "")
21098 (match_operand 2 "" "")]
21101 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
21103 #ifdef TARGET_THREAD_SSP_OFFSET
21105 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
21106 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21108 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
21109 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
21112 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
21114 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
21117 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
21118 flags, const0_rtx, operands[2]));
21122 (define_insn "stack_protect_test_si"
21123 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21124 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21125 (match_operand:SI 2 "memory_operand" "m")]
21127 (clobber (match_scratch:SI 3 "=&r"))]
21129 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
21130 [(set_attr "type" "multi")])
21132 (define_insn "stack_protect_test_di"
21133 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21134 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21135 (match_operand:DI 2 "memory_operand" "m")]
21137 (clobber (match_scratch:DI 3 "=&r"))]
21139 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
21140 [(set_attr "type" "multi")])
21142 (define_insn "stack_tls_protect_test_si"
21143 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21144 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
21145 (match_operand:SI 2 "const_int_operand" "i")]
21146 UNSPEC_SP_TLS_TEST))
21147 (clobber (match_scratch:SI 3 "=r"))]
21149 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
21150 [(set_attr "type" "multi")])
21152 (define_insn "stack_tls_protect_test_di"
21153 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
21154 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
21155 (match_operand:DI 2 "const_int_operand" "i")]
21156 UNSPEC_SP_TLS_TEST))
21157 (clobber (match_scratch:DI 3 "=r"))]
21160 /* The kernel uses a different segment register for performance reasons; a
21161 system call would not have to trash the userspace segment register,
21162 which would be expensive */
21163 if (ix86_cmodel != CM_KERNEL)
21164 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
21166 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
21168 [(set_attr "type" "multi")])
21170 (define_mode_iterator CRC32MODE [QI HI SI])
21171 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
21172 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
21174 (define_insn "sse4_2_crc32<mode>"
21175 [(set (match_operand:SI 0 "register_operand" "=r")
21177 [(match_operand:SI 1 "register_operand" "0")
21178 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
21180 "TARGET_SSE4_2 || TARGET_CRC32"
21181 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
21182 [(set_attr "type" "sselog1")
21183 (set_attr "prefix_rep" "1")
21184 (set_attr "prefix_extra" "1")
21185 (set (attr "prefix_data16")
21186 (if_then_else (match_operand:HI 2 "" "")
21188 (const_string "*")))
21189 (set (attr "prefix_rex")
21190 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
21192 (const_string "*")))
21193 (set_attr "mode" "SI")])
21195 (define_insn "sse4_2_crc32di"
21196 [(set (match_operand:DI 0 "register_operand" "=r")
21198 [(match_operand:DI 1 "register_operand" "0")
21199 (match_operand:DI 2 "nonimmediate_operand" "rm")]
21201 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
21202 "crc32q\t{%2, %0|%0, %2}"
21203 [(set_attr "type" "sselog1")
21204 (set_attr "prefix_rep" "1")
21205 (set_attr "prefix_extra" "1")
21206 (set_attr "mode" "DI")])
21208 (define_expand "rdpmc"
21209 [(match_operand:DI 0 "register_operand" "")
21210 (match_operand:SI 1 "register_operand" "")]
21213 rtx reg = gen_reg_rtx (DImode);
21216 /* Force operand 1 into ECX. */
21217 rtx ecx = gen_rtx_REG (SImode, CX_REG);
21218 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
21219 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
21224 rtvec vec = rtvec_alloc (2);
21225 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21226 rtx upper = gen_reg_rtx (DImode);
21227 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21228 gen_rtvec (1, const0_rtx),
21230 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
21231 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21233 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21234 NULL, 1, OPTAB_DIRECT);
21235 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21239 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
21240 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21244 (define_insn "*rdpmc"
21245 [(set (match_operand:DI 0 "register_operand" "=A")
21246 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
21250 [(set_attr "type" "other")
21251 (set_attr "length" "2")])
21253 (define_insn "*rdpmc_rex64"
21254 [(set (match_operand:DI 0 "register_operand" "=a")
21255 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
21257 (set (match_operand:DI 1 "register_operand" "=d")
21258 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
21261 [(set_attr "type" "other")
21262 (set_attr "length" "2")])
21264 (define_expand "rdtsc"
21265 [(set (match_operand:DI 0 "register_operand" "")
21266 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21271 rtvec vec = rtvec_alloc (2);
21272 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21273 rtx upper = gen_reg_rtx (DImode);
21274 rtx lower = gen_reg_rtx (DImode);
21275 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
21276 gen_rtvec (1, const0_rtx),
21278 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
21279 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
21281 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21282 NULL, 1, OPTAB_DIRECT);
21283 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
21285 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
21290 (define_insn "*rdtsc"
21291 [(set (match_operand:DI 0 "register_operand" "=A")
21292 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21295 [(set_attr "type" "other")
21296 (set_attr "length" "2")])
21298 (define_insn "*rdtsc_rex64"
21299 [(set (match_operand:DI 0 "register_operand" "=a")
21300 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
21301 (set (match_operand:DI 1 "register_operand" "=d")
21302 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
21305 [(set_attr "type" "other")
21306 (set_attr "length" "2")])
21308 (define_expand "rdtscp"
21309 [(match_operand:DI 0 "register_operand" "")
21310 (match_operand:SI 1 "memory_operand" "")]
21313 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
21314 gen_rtvec (1, const0_rtx),
21316 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
21317 gen_rtvec (1, const0_rtx),
21319 rtx reg = gen_reg_rtx (DImode);
21320 rtx tmp = gen_reg_rtx (SImode);
21324 rtvec vec = rtvec_alloc (3);
21325 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21326 rtx upper = gen_reg_rtx (DImode);
21327 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21328 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
21329 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
21331 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
21332 NULL, 1, OPTAB_DIRECT);
21333 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
21338 rtvec vec = rtvec_alloc (2);
21339 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
21340 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
21341 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
21344 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
21345 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
21349 (define_insn "*rdtscp"
21350 [(set (match_operand:DI 0 "register_operand" "=A")
21351 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21352 (set (match_operand:SI 1 "register_operand" "=c")
21353 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21356 [(set_attr "type" "other")
21357 (set_attr "length" "3")])
21359 (define_insn "*rdtscp_rex64"
21360 [(set (match_operand:DI 0 "register_operand" "=a")
21361 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21362 (set (match_operand:DI 1 "register_operand" "=d")
21363 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
21364 (set (match_operand:SI 2 "register_operand" "=c")
21365 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
21368 [(set_attr "type" "other")
21369 (set_attr "length" "3")])
21371 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21373 ;; LWP instructions
21375 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
21377 (define_insn "lwp_llwpcbhi1"
21378 [(unspec [(match_operand:HI 0 "register_operand" "r")]
21379 UNSPEC_LLWP_INTRINSIC)]
21382 [(set_attr "type" "lwp")
21383 (set_attr "mode" "HI")])
21385 (define_insn "lwp_llwpcbsi1"
21386 [(unspec [(match_operand:SI 0 "register_operand" "r")]
21387 UNSPEC_LLWP_INTRINSIC)]
21390 [(set_attr "type" "lwp")
21391 (set_attr "mode" "SI")])
21393 (define_insn "lwp_llwpcbdi1"
21394 [(unspec [(match_operand:DI 0 "register_operand" "r")]
21395 UNSPEC_LLWP_INTRINSIC)]
21398 [(set_attr "type" "lwp")
21399 (set_attr "mode" "DI")])
21401 (define_insn "lwp_slwpcbhi1"
21402 [(unspec [(match_operand:HI 0 "register_operand" "r")]
21403 UNSPEC_SLWP_INTRINSIC)]
21406 [(set_attr "type" "lwp")
21407 (set_attr "mode" "HI")])
21409 (define_insn "lwp_slwpcbsi1"
21410 [(unspec [(match_operand:SI 0 "register_operand" "r")]
21411 UNSPEC_SLWP_INTRINSIC)]
21414 [(set_attr "type" "lwp")
21415 (set_attr "mode" "SI")])
21417 (define_insn "lwp_slwpcbdi1"
21418 [(unspec [(match_operand:DI 0 "register_operand" "r")]
21419 UNSPEC_SLWP_INTRINSIC)]
21422 [(set_attr "type" "lwp")
21423 (set_attr "mode" "DI")])
21425 (define_insn "lwp_lwpvalhi3"
21426 [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21427 (match_operand:SI 1 "nonimmediate_operand" "rm")
21428 (match_operand:HI 2 "const_int_operand" "")]
21429 UNSPECV_LWPVAL_INTRINSIC)]
21431 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21432 [(set_attr "type" "lwp")
21433 (set_attr "mode" "HI")])
21435 (define_insn "lwp_lwpvalsi3"
21436 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21437 (match_operand:SI 1 "nonimmediate_operand" "rm")
21438 (match_operand:SI 2 "const_int_operand" "")]
21439 UNSPECV_LWPVAL_INTRINSIC)]
21441 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21442 [(set_attr "type" "lwp")
21443 (set_attr "mode" "SI")])
21445 (define_insn "lwp_lwpvaldi3"
21446 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21447 (match_operand:SI 1 "nonimmediate_operand" "rm")
21448 (match_operand:SI 2 "const_int_operand" "")]
21449 UNSPECV_LWPVAL_INTRINSIC)]
21451 "lwpval\t{%2, %1, %0|%0, %1, %2}"
21452 [(set_attr "type" "lwp")
21453 (set_attr "mode" "DI")])
21455 (define_insn "lwp_lwpinshi3"
21456 [(unspec_volatile [(match_operand:HI 0 "register_operand" "r")
21457 (match_operand:SI 1 "nonimmediate_operand" "rm")
21458 (match_operand:HI 2 "const_int_operand" "")]
21459 UNSPECV_LWPINS_INTRINSIC)]
21461 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21462 [(set_attr "type" "lwp")
21463 (set_attr "mode" "HI")])
21465 (define_insn "lwp_lwpinssi3"
21466 [(unspec_volatile [(match_operand:SI 0 "register_operand" "r")
21467 (match_operand:SI 1 "nonimmediate_operand" "rm")
21468 (match_operand:SI 2 "const_int_operand" "")]
21469 UNSPECV_LWPINS_INTRINSIC)]
21471 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21472 [(set_attr "type" "lwp")
21473 (set_attr "mode" "SI")])
21475 (define_insn "lwp_lwpinsdi3"
21476 [(unspec_volatile [(match_operand:DI 0 "register_operand" "r")
21477 (match_operand:SI 1 "nonimmediate_operand" "rm")
21478 (match_operand:SI 2 "const_int_operand" "")]
21479 UNSPECV_LWPINS_INTRINSIC)]
21481 "lwpins\t{%2, %1, %0|%0, %1, %2}"
21482 [(set_attr "type" "lwp")
21483 (set_attr "mode" "DI")])
21487 (include "sync.md")