1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; F,f -- likewise, but for floating-point.
34 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
36 ;; R -- print the prefix for register names.
37 ;; z -- print the opcode suffix for the size of the current operand.
38 ;; Z -- likewise, with special suffixes for x87 instructions.
39 ;; * -- print a star (in certain assembler syntax)
40 ;; A -- print an absolute memory reference.
41 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
42 ;; s -- print a shift double count, followed by the assemblers argument
44 ;; b -- print the QImode name of the register for the indicated operand.
45 ;; %b0 would print %al if operands[0] is reg 0.
46 ;; w -- likewise, print the HImode name of the register.
47 ;; k -- likewise, print the SImode name of the register.
48 ;; q -- likewise, print the DImode name of the register.
49 ;; x -- likewise, print the V4SFmode name of the register.
50 ;; t -- likewise, print the V8SFmode name of the register.
51 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
52 ;; y -- print "st(0)" instead of "st" as a register.
53 ;; d -- print duplicated register operand for AVX instruction.
54 ;; D -- print condition for SSE cmp instruction.
55 ;; P -- if PIC, print an @PLT suffix.
56 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
57 ;; & -- print some in-use local-dynamic symbol name.
58 ;; H -- print a memory address offset by 8; used for sse high-parts
59 ;; Y -- print condition for XOP pcom* instruction.
60 ;; + -- print a branch hint as 'cs' or 'ds' prefix
61 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
66 [; Relocation specifiers
77 (UNSPEC_MACHOPIC_OFFSET 10)
80 (UNSPEC_STACK_ALLOC 11)
82 (UNSPEC_SSE_PROLOGUE_SAVE 13)
86 (UNSPEC_SET_GOT_OFFSET 17)
87 (UNSPEC_MEMORY_BLOCKAGE 18)
92 (UNSPEC_TLS_LD_BASE 22)
95 ; Other random patterns
100 (UNSPEC_ADD_CARRY 34)
103 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
104 (UNSPEC_TRUNC_NOOP 39)
106 ; For SSE/MMX support:
107 (UNSPEC_FIX_NOTRUNC 40)
124 (UNSPEC_MS_TO_SYSV_CALL 48)
126 ; Generic math support
128 (UNSPEC_IEEE_MIN 51) ; not commutative
129 (UNSPEC_IEEE_MAX 52) ; not commutative
144 (UNSPEC_FRNDINT_FLOOR 70)
145 (UNSPEC_FRNDINT_CEIL 71)
146 (UNSPEC_FRNDINT_TRUNC 72)
147 (UNSPEC_FRNDINT_MASK_PM 73)
148 (UNSPEC_FIST_FLOOR 74)
149 (UNSPEC_FIST_CEIL 75)
151 ; x87 Double output FP
152 (UNSPEC_SINCOS_COS 80)
153 (UNSPEC_SINCOS_SIN 81)
154 (UNSPEC_XTRACT_FRACT 84)
155 (UNSPEC_XTRACT_EXP 85)
156 (UNSPEC_FSCALE_FRACT 86)
157 (UNSPEC_FSCALE_EXP 87)
169 (UNSPEC_SP_TLS_SET 102)
170 (UNSPEC_SP_TLS_TEST 103)
180 (UNSPEC_INSERTQI 132)
185 (UNSPEC_INSERTPS 135)
187 (UNSPEC_MOVNTDQA 137)
189 (UNSPEC_PHMINPOSUW 139)
195 (UNSPEC_PCMPESTR 144)
196 (UNSPEC_PCMPISTR 145)
199 (UNSPEC_FMA4_INTRINSIC 150)
200 (UNSPEC_FMA4_FMADDSUB 151)
201 (UNSPEC_FMA4_FMSUBADD 152)
202 (UNSPEC_XOP_UNSIGNED_CMP 151)
203 (UNSPEC_XOP_TRUEFALSE 152)
204 (UNSPEC_XOP_PERMUTE 153)
209 (UNSPEC_AESENCLAST 160)
211 (UNSPEC_AESDECLAST 162)
213 (UNSPEC_AESKEYGENASSIST 164)
221 (UNSPEC_VPERMIL2 168)
222 (UNSPEC_VPERMIL2F128 169)
223 (UNSPEC_MASKLOAD 170)
224 (UNSPEC_MASKSTORE 171)
230 [(UNSPECV_BLOCKAGE 0)
231 (UNSPECV_STACK_PROBE 1)
243 (UNSPECV_PROLOGUE_USE 14)
245 (UNSPECV_VZEROALL 16)
246 (UNSPECV_VZEROUPPER 17)
250 (UNSPECV_VSWAPMOV 21)
251 (UNSPECV_LLWP_INTRINSIC 22)
252 (UNSPECV_SLWP_INTRINSIC 23)
253 (UNSPECV_LWPVAL_INTRINSIC 24)
254 (UNSPECV_LWPINS_INTRINSIC 25)
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,lwp")
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 logic operators
721 (define_code_iterator any_logic [and ior xor])
722 (define_code_iterator any_or [ior xor])
724 ;; Base name for insn mnemonic.
725 (define_code_attr logicprefix [(and "and") (ior "or") (xor "xor")])
727 ;; Mapping of abs neg operators
728 (define_code_iterator absneg [abs neg])
730 ;; Base name for x87 insn mnemonic.
731 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
733 ;; Used in signed and unsigned widening multiplications.
734 (define_code_iterator any_extend [sign_extend zero_extend])
736 ;; Various insn prefixes for signed and unsigned operations.
737 (define_code_attr u [(sign_extend "") (zero_extend "u")
738 (div "") (udiv "u")])
739 (define_code_attr s [(sign_extend "s") (zero_extend "u")])
741 ;; Used in signed and unsigned divisions.
742 (define_code_iterator any_div [div udiv])
744 ;; Instruction prefix for signed and unsigned operations.
745 (define_code_attr sgnprefix [(sign_extend "i") (zero_extend "")
746 (div "i") (udiv "")])
748 ;; All single word integer modes.
749 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
751 ;; Single word integer modes without DImode.
752 (define_mode_iterator SWI124 [QI HI SI])
754 ;; Single word integer modes without QImode.
755 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
757 ;; Single word integer modes without QImode and HImode.
758 (define_mode_iterator SWI48 [SI (DI "TARGET_64BIT")])
760 ;; All math-dependant single and double word integer modes.
761 (define_mode_iterator SDWIM [(QI "TARGET_QIMODE_MATH")
762 (HI "TARGET_HIMODE_MATH")
763 SI DI (TI "TARGET_64BIT")])
765 ;; Math-dependant single word integer modes.
766 (define_mode_iterator SWIM [(QI "TARGET_QIMODE_MATH")
767 (HI "TARGET_HIMODE_MATH")
768 SI (DI "TARGET_64BIT")])
770 ;; Math-dependant single word integer modes without QImode.
771 (define_mode_iterator SWIM248 [(HI "TARGET_HIMODE_MATH")
772 SI (DI "TARGET_64BIT")])
774 ;; Half mode for double word integer modes.
775 (define_mode_iterator DWIH [(SI "!TARGET_64BIT")
776 (DI "TARGET_64BIT")])
778 ;; Double word integer modes.
779 (define_mode_attr DWI [(SI "DI") (DI "TI")])
780 (define_mode_attr dwi [(SI "di") (DI "ti")])
782 ;; Instruction suffix for integer modes.
783 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
785 ;; Register class for integer modes.
786 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
788 ;; Immediate operand constraint for integer modes.
789 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
791 ;; General operand constraint for word modes.
792 (define_mode_attr g [(QI "qmn") (HI "rmn") (SI "g") (DI "rme")])
794 ;; Immediate operand constraint for double integer modes.
795 (define_mode_attr di [(SI "iF") (DI "e")])
797 ;; General operand predicate for integer modes.
798 (define_mode_attr general_operand
799 [(QI "general_operand")
800 (HI "general_operand")
801 (SI "general_operand")
802 (DI "x86_64_general_operand")
803 (TI "x86_64_general_operand")])
805 ;; General sign/zero extend operand predicate for integer modes.
806 (define_mode_attr general_szext_operand
807 [(QI "general_operand")
808 (HI "general_operand")
809 (SI "general_operand")
810 (DI "x86_64_szext_general_operand")])
812 ;; SSE and x87 SFmode and DFmode floating point modes
813 (define_mode_iterator MODEF [SF DF])
815 ;; All x87 floating point modes
816 (define_mode_iterator X87MODEF [SF DF XF])
818 ;; All integer modes handled by x87 fisttp operator.
819 (define_mode_iterator X87MODEI [HI SI DI])
821 ;; All integer modes handled by integer x87 operators.
822 (define_mode_iterator X87MODEI12 [HI SI])
824 ;; All integer modes handled by SSE cvtts?2si* operators.
825 (define_mode_iterator SSEMODEI24 [SI DI])
827 ;; SSE asm suffix for floating point modes
828 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
830 ;; SSE vector mode corresponding to a scalar mode
831 (define_mode_attr ssevecmode
832 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
834 ;; Instruction suffix for REX 64bit operators.
835 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
837 ;; This mode iterator allows :P to be used for patterns that operate on
838 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
839 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
841 ;; Scheduling descriptions
843 (include "pentium.md")
846 (include "athlon.md")
851 ;; Operand and operator predicates and constraints
853 (include "predicates.md")
854 (include "constraints.md")
857 ;; Compare and branch/compare and store instructions.
859 (define_expand "cbranch<mode>4"
860 [(set (reg:CC FLAGS_REG)
861 (compare:CC (match_operand:SDWIM 1 "nonimmediate_operand" "")
862 (match_operand:SDWIM 2 "<general_operand>" "")))
863 (set (pc) (if_then_else
864 (match_operator 0 "comparison_operator"
865 [(reg:CC FLAGS_REG) (const_int 0)])
866 (label_ref (match_operand 3 "" ""))
870 if (MEM_P (operands[1]) && MEM_P (operands[2]))
871 operands[1] = force_reg (<MODE>mode, operands[1]);
872 ix86_compare_op0 = operands[1];
873 ix86_compare_op1 = operands[2];
874 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
878 (define_expand "cstore<mode>4"
879 [(set (reg:CC FLAGS_REG)
880 (compare:CC (match_operand:SWIM 2 "nonimmediate_operand" "")
881 (match_operand:SWIM 3 "<general_operand>" "")))
882 (set (match_operand:QI 0 "register_operand" "")
883 (match_operator 1 "comparison_operator"
884 [(reg:CC FLAGS_REG) (const_int 0)]))]
887 if (MEM_P (operands[2]) && MEM_P (operands[3]))
888 operands[2] = force_reg (<MODE>mode, operands[2]);
889 ix86_compare_op0 = operands[2];
890 ix86_compare_op1 = operands[3];
891 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
895 (define_expand "cmp<mode>_1"
896 [(set (reg:CC FLAGS_REG)
897 (compare:CC (match_operand:SWI48 0 "nonimmediate_operand" "")
898 (match_operand:SWI48 1 "<general_operand>" "")))]
902 (define_insn "*cmp<mode>_ccno_1"
903 [(set (reg FLAGS_REG)
904 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>,?m<r>")
905 (match_operand:SWI 1 "const0_operand" "")))]
906 "ix86_match_ccmode (insn, CCNOmode)"
908 test{<imodesuffix>}\t%0, %0
909 cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
910 [(set_attr "type" "test,icmp")
911 (set_attr "length_immediate" "0,1")
912 (set_attr "mode" "<MODE>")])
914 (define_insn "*cmp<mode>_1"
915 [(set (reg FLAGS_REG)
916 (compare (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
917 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m")))]
918 "ix86_match_ccmode (insn, CCmode)"
919 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
920 [(set_attr "type" "icmp")
921 (set_attr "mode" "<MODE>")])
923 (define_insn "*cmp<mode>_minus_1"
924 [(set (reg FLAGS_REG)
926 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
927 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
929 "ix86_match_ccmode (insn, CCGOCmode)"
930 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
931 [(set_attr "type" "icmp")
932 (set_attr "mode" "<MODE>")])
934 (define_insn "*cmpqi_ext_1"
935 [(set (reg FLAGS_REG)
937 (match_operand:QI 0 "general_operand" "Qm")
940 (match_operand 1 "ext_register_operand" "Q")
943 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
944 "cmp{b}\t{%h1, %0|%0, %h1}"
945 [(set_attr "type" "icmp")
946 (set_attr "mode" "QI")])
948 (define_insn "*cmpqi_ext_1_rex64"
949 [(set (reg FLAGS_REG)
951 (match_operand:QI 0 "register_operand" "Q")
954 (match_operand 1 "ext_register_operand" "Q")
957 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
958 "cmp{b}\t{%h1, %0|%0, %h1}"
959 [(set_attr "type" "icmp")
960 (set_attr "mode" "QI")])
962 (define_insn "*cmpqi_ext_2"
963 [(set (reg FLAGS_REG)
967 (match_operand 0 "ext_register_operand" "Q")
970 (match_operand:QI 1 "const0_operand" "")))]
971 "ix86_match_ccmode (insn, CCNOmode)"
973 [(set_attr "type" "test")
974 (set_attr "length_immediate" "0")
975 (set_attr "mode" "QI")])
977 (define_expand "cmpqi_ext_3"
978 [(set (reg:CC FLAGS_REG)
982 (match_operand 0 "ext_register_operand" "")
985 (match_operand:QI 1 "immediate_operand" "")))]
989 (define_insn "*cmpqi_ext_3_insn"
990 [(set (reg FLAGS_REG)
994 (match_operand 0 "ext_register_operand" "Q")
997 (match_operand:QI 1 "general_operand" "Qmn")))]
998 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
999 "cmp{b}\t{%1, %h0|%h0, %1}"
1000 [(set_attr "type" "icmp")
1001 (set_attr "modrm" "1")
1002 (set_attr "mode" "QI")])
1004 (define_insn "*cmpqi_ext_3_insn_rex64"
1005 [(set (reg FLAGS_REG)
1009 (match_operand 0 "ext_register_operand" "Q")
1012 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1013 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1014 "cmp{b}\t{%1, %h0|%h0, %1}"
1015 [(set_attr "type" "icmp")
1016 (set_attr "modrm" "1")
1017 (set_attr "mode" "QI")])
1019 (define_insn "*cmpqi_ext_4"
1020 [(set (reg FLAGS_REG)
1024 (match_operand 0 "ext_register_operand" "Q")
1029 (match_operand 1 "ext_register_operand" "Q")
1031 (const_int 8)) 0)))]
1032 "ix86_match_ccmode (insn, CCmode)"
1033 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1034 [(set_attr "type" "icmp")
1035 (set_attr "mode" "QI")])
1037 ;; These implement float point compares.
1038 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1039 ;; which would allow mix and match FP modes on the compares. Which is what
1040 ;; the old patterns did, but with many more of them.
1042 (define_expand "cbranchxf4"
1043 [(set (reg:CC FLAGS_REG)
1044 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1045 (match_operand:XF 2 "nonmemory_operand" "")))
1046 (set (pc) (if_then_else
1047 (match_operator 0 "ix86_fp_comparison_operator"
1050 (label_ref (match_operand 3 "" ""))
1054 ix86_compare_op0 = operands[1];
1055 ix86_compare_op1 = operands[2];
1056 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1060 (define_expand "cstorexf4"
1061 [(set (reg:CC FLAGS_REG)
1062 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1063 (match_operand:XF 3 "nonmemory_operand" "")))
1064 (set (match_operand:QI 0 "register_operand" "")
1065 (match_operator 1 "ix86_fp_comparison_operator"
1070 ix86_compare_op0 = operands[2];
1071 ix86_compare_op1 = operands[3];
1072 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1076 (define_expand "cbranch<mode>4"
1077 [(set (reg:CC FLAGS_REG)
1078 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1079 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1080 (set (pc) (if_then_else
1081 (match_operator 0 "ix86_fp_comparison_operator"
1084 (label_ref (match_operand 3 "" ""))
1086 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1088 ix86_compare_op0 = operands[1];
1089 ix86_compare_op1 = operands[2];
1090 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1094 (define_expand "cstore<mode>4"
1095 [(set (reg:CC FLAGS_REG)
1096 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1097 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1098 (set (match_operand:QI 0 "register_operand" "")
1099 (match_operator 1 "ix86_fp_comparison_operator"
1102 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1104 ix86_compare_op0 = operands[2];
1105 ix86_compare_op1 = operands[3];
1106 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1110 (define_expand "cbranchcc4"
1111 [(set (pc) (if_then_else
1112 (match_operator 0 "comparison_operator"
1113 [(match_operand 1 "flags_reg_operand" "")
1114 (match_operand 2 "const0_operand" "")])
1115 (label_ref (match_operand 3 "" ""))
1119 ix86_compare_op0 = operands[1];
1120 ix86_compare_op1 = operands[2];
1121 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1125 (define_expand "cstorecc4"
1126 [(set (match_operand:QI 0 "register_operand" "")
1127 (match_operator 1 "comparison_operator"
1128 [(match_operand 2 "flags_reg_operand" "")
1129 (match_operand 3 "const0_operand" "")]))]
1132 ix86_compare_op0 = operands[2];
1133 ix86_compare_op1 = operands[3];
1134 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1139 ;; FP compares, step 1:
1140 ;; Set the FP condition codes.
1142 ;; CCFPmode compare with exceptions
1143 ;; CCFPUmode compare with no exceptions
1145 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1146 ;; used to manage the reg stack popping would not be preserved.
1148 (define_insn "*cmpfp_0"
1149 [(set (match_operand:HI 0 "register_operand" "=a")
1152 (match_operand 1 "register_operand" "f")
1153 (match_operand 2 "const0_operand" ""))]
1155 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1156 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1157 "* return output_fp_compare (insn, operands, 0, 0);"
1158 [(set_attr "type" "multi")
1159 (set_attr "unit" "i387")
1161 (cond [(match_operand:SF 1 "" "")
1163 (match_operand:DF 1 "" "")
1166 (const_string "XF")))])
1168 (define_insn_and_split "*cmpfp_0_cc"
1169 [(set (reg:CCFP FLAGS_REG)
1171 (match_operand 1 "register_operand" "f")
1172 (match_operand 2 "const0_operand" "")))
1173 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1174 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1175 && TARGET_SAHF && !TARGET_CMOVE
1176 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1178 "&& reload_completed"
1181 [(compare:CCFP (match_dup 1)(match_dup 2))]
1183 (set (reg:CC FLAGS_REG)
1184 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1186 [(set_attr "type" "multi")
1187 (set_attr "unit" "i387")
1189 (cond [(match_operand:SF 1 "" "")
1191 (match_operand:DF 1 "" "")
1194 (const_string "XF")))])
1196 (define_insn "*cmpfp_xf"
1197 [(set (match_operand:HI 0 "register_operand" "=a")
1200 (match_operand:XF 1 "register_operand" "f")
1201 (match_operand:XF 2 "register_operand" "f"))]
1204 "* return output_fp_compare (insn, operands, 0, 0);"
1205 [(set_attr "type" "multi")
1206 (set_attr "unit" "i387")
1207 (set_attr "mode" "XF")])
1209 (define_insn_and_split "*cmpfp_xf_cc"
1210 [(set (reg:CCFP FLAGS_REG)
1212 (match_operand:XF 1 "register_operand" "f")
1213 (match_operand:XF 2 "register_operand" "f")))
1214 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1216 && TARGET_SAHF && !TARGET_CMOVE"
1218 "&& reload_completed"
1221 [(compare:CCFP (match_dup 1)(match_dup 2))]
1223 (set (reg:CC FLAGS_REG)
1224 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1226 [(set_attr "type" "multi")
1227 (set_attr "unit" "i387")
1228 (set_attr "mode" "XF")])
1230 (define_insn "*cmpfp_<mode>"
1231 [(set (match_operand:HI 0 "register_operand" "=a")
1234 (match_operand:MODEF 1 "register_operand" "f")
1235 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1238 "* return output_fp_compare (insn, operands, 0, 0);"
1239 [(set_attr "type" "multi")
1240 (set_attr "unit" "i387")
1241 (set_attr "mode" "<MODE>")])
1243 (define_insn_and_split "*cmpfp_<mode>_cc"
1244 [(set (reg:CCFP FLAGS_REG)
1246 (match_operand:MODEF 1 "register_operand" "f")
1247 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1248 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1250 && TARGET_SAHF && !TARGET_CMOVE"
1252 "&& reload_completed"
1255 [(compare:CCFP (match_dup 1)(match_dup 2))]
1257 (set (reg:CC FLAGS_REG)
1258 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1260 [(set_attr "type" "multi")
1261 (set_attr "unit" "i387")
1262 (set_attr "mode" "<MODE>")])
1264 (define_insn "*cmpfp_u"
1265 [(set (match_operand:HI 0 "register_operand" "=a")
1268 (match_operand 1 "register_operand" "f")
1269 (match_operand 2 "register_operand" "f"))]
1271 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1272 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1273 "* return output_fp_compare (insn, operands, 0, 1);"
1274 [(set_attr "type" "multi")
1275 (set_attr "unit" "i387")
1277 (cond [(match_operand:SF 1 "" "")
1279 (match_operand:DF 1 "" "")
1282 (const_string "XF")))])
1284 (define_insn_and_split "*cmpfp_u_cc"
1285 [(set (reg:CCFPU FLAGS_REG)
1287 (match_operand 1 "register_operand" "f")
1288 (match_operand 2 "register_operand" "f")))
1289 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1290 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1291 && TARGET_SAHF && !TARGET_CMOVE
1292 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1294 "&& reload_completed"
1297 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1299 (set (reg:CC FLAGS_REG)
1300 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1302 [(set_attr "type" "multi")
1303 (set_attr "unit" "i387")
1305 (cond [(match_operand:SF 1 "" "")
1307 (match_operand:DF 1 "" "")
1310 (const_string "XF")))])
1312 (define_insn "*cmpfp_<mode>"
1313 [(set (match_operand:HI 0 "register_operand" "=a")
1316 (match_operand 1 "register_operand" "f")
1317 (match_operator 3 "float_operator"
1318 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1320 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1321 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1322 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1323 "* return output_fp_compare (insn, operands, 0, 0);"
1324 [(set_attr "type" "multi")
1325 (set_attr "unit" "i387")
1326 (set_attr "fp_int_src" "true")
1327 (set_attr "mode" "<MODE>")])
1329 (define_insn_and_split "*cmpfp_<mode>_cc"
1330 [(set (reg:CCFP FLAGS_REG)
1332 (match_operand 1 "register_operand" "f")
1333 (match_operator 3 "float_operator"
1334 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1335 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1336 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1337 && TARGET_SAHF && !TARGET_CMOVE
1338 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1339 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1341 "&& reload_completed"
1346 (match_op_dup 3 [(match_dup 2)]))]
1348 (set (reg:CC FLAGS_REG)
1349 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1351 [(set_attr "type" "multi")
1352 (set_attr "unit" "i387")
1353 (set_attr "fp_int_src" "true")
1354 (set_attr "mode" "<MODE>")])
1356 ;; FP compares, step 2
1357 ;; Move the fpsw to ax.
1359 (define_insn "x86_fnstsw_1"
1360 [(set (match_operand:HI 0 "register_operand" "=a")
1361 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1364 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1365 (set_attr "mode" "SI")
1366 (set_attr "unit" "i387")])
1368 ;; FP compares, step 3
1369 ;; Get ax into flags, general case.
1371 (define_insn "x86_sahf_1"
1372 [(set (reg:CC FLAGS_REG)
1373 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1377 #ifdef HAVE_AS_IX86_SAHF
1380 return ASM_BYTE "0x9e";
1383 [(set_attr "length" "1")
1384 (set_attr "athlon_decode" "vector")
1385 (set_attr "amdfam10_decode" "direct")
1386 (set_attr "mode" "SI")])
1388 ;; Pentium Pro can do steps 1 through 3 in one go.
1389 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1390 (define_insn "*cmpfp_i_mixed"
1391 [(set (reg:CCFP FLAGS_REG)
1392 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1393 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1394 "TARGET_MIX_SSE_I387
1395 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1396 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1397 "* return output_fp_compare (insn, operands, 1, 0);"
1398 [(set_attr "type" "fcmp,ssecomi")
1399 (set_attr "prefix" "orig,maybe_vex")
1401 (if_then_else (match_operand:SF 1 "" "")
1403 (const_string "DF")))
1404 (set (attr "prefix_rep")
1405 (if_then_else (eq_attr "type" "ssecomi")
1407 (const_string "*")))
1408 (set (attr "prefix_data16")
1409 (cond [(eq_attr "type" "fcmp")
1411 (eq_attr "mode" "DF")
1414 (const_string "0")))
1415 (set_attr "athlon_decode" "vector")
1416 (set_attr "amdfam10_decode" "direct")])
1418 (define_insn "*cmpfp_i_sse"
1419 [(set (reg:CCFP FLAGS_REG)
1420 (compare:CCFP (match_operand 0 "register_operand" "x")
1421 (match_operand 1 "nonimmediate_operand" "xm")))]
1423 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1424 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1425 "* return output_fp_compare (insn, operands, 1, 0);"
1426 [(set_attr "type" "ssecomi")
1427 (set_attr "prefix" "maybe_vex")
1429 (if_then_else (match_operand:SF 1 "" "")
1431 (const_string "DF")))
1432 (set_attr "prefix_rep" "0")
1433 (set (attr "prefix_data16")
1434 (if_then_else (eq_attr "mode" "DF")
1436 (const_string "0")))
1437 (set_attr "athlon_decode" "vector")
1438 (set_attr "amdfam10_decode" "direct")])
1440 (define_insn "*cmpfp_i_i387"
1441 [(set (reg:CCFP FLAGS_REG)
1442 (compare:CCFP (match_operand 0 "register_operand" "f")
1443 (match_operand 1 "register_operand" "f")))]
1444 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1446 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1447 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1448 "* return output_fp_compare (insn, operands, 1, 0);"
1449 [(set_attr "type" "fcmp")
1451 (cond [(match_operand:SF 1 "" "")
1453 (match_operand:DF 1 "" "")
1456 (const_string "XF")))
1457 (set_attr "athlon_decode" "vector")
1458 (set_attr "amdfam10_decode" "direct")])
1460 (define_insn "*cmpfp_iu_mixed"
1461 [(set (reg:CCFPU FLAGS_REG)
1462 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1463 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1464 "TARGET_MIX_SSE_I387
1465 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1466 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1467 "* return output_fp_compare (insn, operands, 1, 1);"
1468 [(set_attr "type" "fcmp,ssecomi")
1469 (set_attr "prefix" "orig,maybe_vex")
1471 (if_then_else (match_operand:SF 1 "" "")
1473 (const_string "DF")))
1474 (set (attr "prefix_rep")
1475 (if_then_else (eq_attr "type" "ssecomi")
1477 (const_string "*")))
1478 (set (attr "prefix_data16")
1479 (cond [(eq_attr "type" "fcmp")
1481 (eq_attr "mode" "DF")
1484 (const_string "0")))
1485 (set_attr "athlon_decode" "vector")
1486 (set_attr "amdfam10_decode" "direct")])
1488 (define_insn "*cmpfp_iu_sse"
1489 [(set (reg:CCFPU FLAGS_REG)
1490 (compare:CCFPU (match_operand 0 "register_operand" "x")
1491 (match_operand 1 "nonimmediate_operand" "xm")))]
1493 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1494 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1495 "* return output_fp_compare (insn, operands, 1, 1);"
1496 [(set_attr "type" "ssecomi")
1497 (set_attr "prefix" "maybe_vex")
1499 (if_then_else (match_operand:SF 1 "" "")
1501 (const_string "DF")))
1502 (set_attr "prefix_rep" "0")
1503 (set (attr "prefix_data16")
1504 (if_then_else (eq_attr "mode" "DF")
1506 (const_string "0")))
1507 (set_attr "athlon_decode" "vector")
1508 (set_attr "amdfam10_decode" "direct")])
1510 (define_insn "*cmpfp_iu_387"
1511 [(set (reg:CCFPU FLAGS_REG)
1512 (compare:CCFPU (match_operand 0 "register_operand" "f")
1513 (match_operand 1 "register_operand" "f")))]
1514 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1516 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1517 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1518 "* return output_fp_compare (insn, operands, 1, 1);"
1519 [(set_attr "type" "fcmp")
1521 (cond [(match_operand:SF 1 "" "")
1523 (match_operand:DF 1 "" "")
1526 (const_string "XF")))
1527 (set_attr "athlon_decode" "vector")
1528 (set_attr "amdfam10_decode" "direct")])
1530 ;; Move instructions.
1532 ;; General case of fullword move.
1534 (define_expand "movsi"
1535 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1536 (match_operand:SI 1 "general_operand" ""))]
1538 "ix86_expand_move (SImode, operands); DONE;")
1540 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1543 ;; %%% We don't use a post-inc memory reference because x86 is not a
1544 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1545 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1546 ;; targets without our curiosities, and it is just as easy to represent
1547 ;; this differently.
1549 (define_insn "*pushsi2"
1550 [(set (match_operand:SI 0 "push_operand" "=<")
1551 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1554 [(set_attr "type" "push")
1555 (set_attr "mode" "SI")])
1557 ;; For 64BIT abi we always round up to 8 bytes.
1558 (define_insn "*pushsi2_rex64"
1559 [(set (match_operand:SI 0 "push_operand" "=X")
1560 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1563 [(set_attr "type" "push")
1564 (set_attr "mode" "SI")])
1566 (define_insn "*pushsi2_prologue"
1567 [(set (match_operand:SI 0 "push_operand" "=<")
1568 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1569 (clobber (mem:BLK (scratch)))]
1572 [(set_attr "type" "push")
1573 (set_attr "mode" "SI")])
1575 (define_insn "*popsi1_epilogue"
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)))
1580 (clobber (mem:BLK (scratch)))]
1583 [(set_attr "type" "pop")
1584 (set_attr "mode" "SI")])
1586 (define_insn "popsi1"
1587 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1588 (mem:SI (reg:SI SP_REG)))
1589 (set (reg:SI SP_REG)
1590 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1593 [(set_attr "type" "pop")
1594 (set_attr "mode" "SI")])
1596 (define_insn "*movsi_xor"
1597 [(set (match_operand:SI 0 "register_operand" "=r")
1598 (match_operand:SI 1 "const0_operand" ""))
1599 (clobber (reg:CC FLAGS_REG))]
1602 [(set_attr "type" "alu1")
1603 (set_attr "mode" "SI")
1604 (set_attr "length_immediate" "0")])
1606 (define_insn "*movsi_or"
1607 [(set (match_operand:SI 0 "register_operand" "=r")
1608 (match_operand:SI 1 "immediate_operand" "i"))
1609 (clobber (reg:CC FLAGS_REG))]
1611 && operands[1] == constm1_rtx"
1613 operands[1] = constm1_rtx;
1614 return "or{l}\t{%1, %0|%0, %1}";
1616 [(set_attr "type" "alu1")
1617 (set_attr "mode" "SI")
1618 (set_attr "length_immediate" "1")])
1620 (define_insn "*movsi_1"
1621 [(set (match_operand:SI 0 "nonimmediate_operand"
1622 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1623 (match_operand:SI 1 "general_operand"
1624 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1625 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1627 switch (get_attr_type (insn))
1630 if (get_attr_mode (insn) == MODE_TI)
1631 return "%vpxor\t%0, %d0";
1632 return "%vxorps\t%0, %d0";
1635 switch (get_attr_mode (insn))
1638 return "%vmovdqa\t{%1, %0|%0, %1}";
1640 return "%vmovaps\t{%1, %0|%0, %1}";
1642 return "%vmovd\t{%1, %0|%0, %1}";
1644 return "%vmovss\t{%1, %0|%0, %1}";
1650 return "pxor\t%0, %0";
1653 if (get_attr_mode (insn) == MODE_DI)
1654 return "movq\t{%1, %0|%0, %1}";
1655 return "movd\t{%1, %0|%0, %1}";
1658 return "lea{l}\t{%1, %0|%0, %1}";
1661 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1662 return "mov{l}\t{%1, %0|%0, %1}";
1666 (cond [(eq_attr "alternative" "2")
1667 (const_string "mmx")
1668 (eq_attr "alternative" "3,4,5")
1669 (const_string "mmxmov")
1670 (eq_attr "alternative" "6")
1671 (const_string "sselog1")
1672 (eq_attr "alternative" "7,8,9,10,11")
1673 (const_string "ssemov")
1674 (match_operand:DI 1 "pic_32bit_operand" "")
1675 (const_string "lea")
1677 (const_string "imov")))
1678 (set (attr "prefix")
1679 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1680 (const_string "orig")
1681 (const_string "maybe_vex")))
1682 (set (attr "prefix_data16")
1683 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1685 (const_string "*")))
1687 (cond [(eq_attr "alternative" "2,3")
1689 (eq_attr "alternative" "6,7")
1691 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1692 (const_string "V4SF")
1693 (const_string "TI"))
1694 (and (eq_attr "alternative" "8,9,10,11")
1695 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1698 (const_string "SI")))])
1700 ;; Stores and loads of ax to arbitrary constant address.
1701 ;; We fake an second form of instruction to force reload to load address
1702 ;; into register when rax is not available
1703 (define_insn "*movabssi_1_rex64"
1704 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1705 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1706 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1708 movabs{l}\t{%1, %P0|%P0, %1}
1709 mov{l}\t{%1, %a0|%a0, %1}"
1710 [(set_attr "type" "imov")
1711 (set_attr "modrm" "0,*")
1712 (set_attr "length_address" "8,0")
1713 (set_attr "length_immediate" "0,*")
1714 (set_attr "memory" "store")
1715 (set_attr "mode" "SI")])
1717 (define_insn "*movabssi_2_rex64"
1718 [(set (match_operand:SI 0 "register_operand" "=a,r")
1719 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1720 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1722 movabs{l}\t{%P1, %0|%0, %P1}
1723 mov{l}\t{%a1, %0|%0, %a1}"
1724 [(set_attr "type" "imov")
1725 (set_attr "modrm" "0,*")
1726 (set_attr "length_address" "8,0")
1727 (set_attr "length_immediate" "0")
1728 (set_attr "memory" "load")
1729 (set_attr "mode" "SI")])
1731 (define_insn "*swapsi"
1732 [(set (match_operand:SI 0 "register_operand" "+r")
1733 (match_operand:SI 1 "register_operand" "+r"))
1738 [(set_attr "type" "imov")
1739 (set_attr "mode" "SI")
1740 (set_attr "pent_pair" "np")
1741 (set_attr "athlon_decode" "vector")
1742 (set_attr "amdfam10_decode" "double")])
1744 (define_expand "movhi"
1745 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1746 (match_operand:HI 1 "general_operand" ""))]
1748 "ix86_expand_move (HImode, operands); DONE;")
1750 (define_insn "*pushhi2"
1751 [(set (match_operand:HI 0 "push_operand" "=X")
1752 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1755 [(set_attr "type" "push")
1756 (set_attr "mode" "SI")])
1758 ;; For 64BIT abi we always round up to 8 bytes.
1759 (define_insn "*pushhi2_rex64"
1760 [(set (match_operand:HI 0 "push_operand" "=X")
1761 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1764 [(set_attr "type" "push")
1765 (set_attr "mode" "DI")])
1767 (define_insn "*movhi_1"
1768 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1769 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1770 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1772 switch (get_attr_type (insn))
1775 /* movzwl is faster than movw on p2 due to partial word stalls,
1776 though not as fast as an aligned movl. */
1777 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
1779 if (get_attr_mode (insn) == MODE_SI)
1780 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1782 return "mov{w}\t{%1, %0|%0, %1}";
1786 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1787 (const_string "imov")
1788 (and (eq_attr "alternative" "0")
1789 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1791 (eq (symbol_ref "TARGET_HIMODE_MATH")
1793 (const_string "imov")
1794 (and (eq_attr "alternative" "1,2")
1795 (match_operand:HI 1 "aligned_operand" ""))
1796 (const_string "imov")
1797 (and (ne (symbol_ref "TARGET_MOVX")
1799 (eq_attr "alternative" "0,2"))
1800 (const_string "imovx")
1802 (const_string "imov")))
1804 (cond [(eq_attr "type" "imovx")
1806 (and (eq_attr "alternative" "1,2")
1807 (match_operand:HI 1 "aligned_operand" ""))
1809 (and (eq_attr "alternative" "0")
1810 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1812 (eq (symbol_ref "TARGET_HIMODE_MATH")
1816 (const_string "HI")))])
1818 ;; Stores and loads of ax to arbitrary constant address.
1819 ;; We fake an second form of instruction to force reload to load address
1820 ;; into register when rax is not available
1821 (define_insn "*movabshi_1_rex64"
1822 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1823 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1824 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1826 movabs{w}\t{%1, %P0|%P0, %1}
1827 mov{w}\t{%1, %a0|%a0, %1}"
1828 [(set_attr "type" "imov")
1829 (set_attr "modrm" "0,*")
1830 (set_attr "length_address" "8,0")
1831 (set_attr "length_immediate" "0,*")
1832 (set_attr "memory" "store")
1833 (set_attr "mode" "HI")])
1835 (define_insn "*movabshi_2_rex64"
1836 [(set (match_operand:HI 0 "register_operand" "=a,r")
1837 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1838 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1840 movabs{w}\t{%P1, %0|%0, %P1}
1841 mov{w}\t{%a1, %0|%0, %a1}"
1842 [(set_attr "type" "imov")
1843 (set_attr "modrm" "0,*")
1844 (set_attr "length_address" "8,0")
1845 (set_attr "length_immediate" "0")
1846 (set_attr "memory" "load")
1847 (set_attr "mode" "HI")])
1849 (define_insn "*swaphi_1"
1850 [(set (match_operand:HI 0 "register_operand" "+r")
1851 (match_operand:HI 1 "register_operand" "+r"))
1854 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
1856 [(set_attr "type" "imov")
1857 (set_attr "mode" "SI")
1858 (set_attr "pent_pair" "np")
1859 (set_attr "athlon_decode" "vector")
1860 (set_attr "amdfam10_decode" "double")])
1862 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
1863 (define_insn "*swaphi_2"
1864 [(set (match_operand:HI 0 "register_operand" "+r")
1865 (match_operand:HI 1 "register_operand" "+r"))
1868 "TARGET_PARTIAL_REG_STALL"
1870 [(set_attr "type" "imov")
1871 (set_attr "mode" "HI")
1872 (set_attr "pent_pair" "np")
1873 (set_attr "athlon_decode" "vector")])
1875 (define_expand "movstricthi"
1876 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
1877 (match_operand:HI 1 "general_operand" ""))]
1880 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
1882 /* Don't generate memory->memory moves, go through a register */
1883 if (MEM_P (operands[0]) && MEM_P (operands[1]))
1884 operands[1] = force_reg (HImode, operands[1]);
1887 (define_insn "*movstricthi_1"
1888 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
1889 (match_operand:HI 1 "general_operand" "rn,m"))]
1890 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
1891 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
1892 "mov{w}\t{%1, %0|%0, %1}"
1893 [(set_attr "type" "imov")
1894 (set_attr "mode" "HI")])
1896 (define_insn "*movstricthi_xor"
1897 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
1898 (match_operand:HI 1 "const0_operand" ""))
1899 (clobber (reg:CC FLAGS_REG))]
1902 [(set_attr "type" "alu1")
1903 (set_attr "mode" "HI")
1904 (set_attr "length_immediate" "0")])
1906 (define_expand "movqi"
1907 [(set (match_operand:QI 0 "nonimmediate_operand" "")
1908 (match_operand:QI 1 "general_operand" ""))]
1910 "ix86_expand_move (QImode, operands); DONE;")
1912 ;; emit_push_insn when it calls move_by_pieces requires an insn to
1913 ;; "push a byte". But actually we use pushl, which has the effect
1914 ;; of rounding the amount pushed up to a word.
1916 (define_insn "*pushqi2"
1917 [(set (match_operand:QI 0 "push_operand" "=X")
1918 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
1921 [(set_attr "type" "push")
1922 (set_attr "mode" "SI")])
1924 ;; For 64BIT abi we always round up to 8 bytes.
1925 (define_insn "*pushqi2_rex64"
1926 [(set (match_operand:QI 0 "push_operand" "=X")
1927 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
1930 [(set_attr "type" "push")
1931 (set_attr "mode" "DI")])
1933 ;; Situation is quite tricky about when to choose full sized (SImode) move
1934 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
1935 ;; partial register dependency machines (such as AMD Athlon), where QImode
1936 ;; moves issue extra dependency and for partial register stalls machines
1937 ;; that don't use QImode patterns (and QImode move cause stall on the next
1940 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
1941 ;; register stall machines with, where we use QImode instructions, since
1942 ;; partial register stall can be caused there. Then we use movzx.
1943 (define_insn "*movqi_1"
1944 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
1945 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
1946 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1948 switch (get_attr_type (insn))
1951 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
1952 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
1954 if (get_attr_mode (insn) == MODE_SI)
1955 return "mov{l}\t{%k1, %k0|%k0, %k1}";
1957 return "mov{b}\t{%1, %0|%0, %1}";
1961 (cond [(and (eq_attr "alternative" "5")
1962 (not (match_operand:QI 1 "aligned_operand" "")))
1963 (const_string "imovx")
1964 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1965 (const_string "imov")
1966 (and (eq_attr "alternative" "3")
1967 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1969 (eq (symbol_ref "TARGET_QIMODE_MATH")
1971 (const_string "imov")
1972 (eq_attr "alternative" "3,5")
1973 (const_string "imovx")
1974 (and (ne (symbol_ref "TARGET_MOVX")
1976 (eq_attr "alternative" "2"))
1977 (const_string "imovx")
1979 (const_string "imov")))
1981 (cond [(eq_attr "alternative" "3,4,5")
1983 (eq_attr "alternative" "6")
1985 (eq_attr "type" "imovx")
1987 (and (eq_attr "type" "imov")
1988 (and (eq_attr "alternative" "0,1")
1989 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
1991 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
1993 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1996 ;; Avoid partial register stalls when not using QImode arithmetic
1997 (and (eq_attr "type" "imov")
1998 (and (eq_attr "alternative" "0,1")
1999 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2001 (eq (symbol_ref "TARGET_QIMODE_MATH")
2005 (const_string "QI")))])
2007 (define_insn "*swapqi_1"
2008 [(set (match_operand:QI 0 "register_operand" "+r")
2009 (match_operand:QI 1 "register_operand" "+r"))
2012 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2014 [(set_attr "type" "imov")
2015 (set_attr "mode" "SI")
2016 (set_attr "pent_pair" "np")
2017 (set_attr "athlon_decode" "vector")
2018 (set_attr "amdfam10_decode" "vector")])
2020 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2021 (define_insn "*swapqi_2"
2022 [(set (match_operand:QI 0 "register_operand" "+q")
2023 (match_operand:QI 1 "register_operand" "+q"))
2026 "TARGET_PARTIAL_REG_STALL"
2028 [(set_attr "type" "imov")
2029 (set_attr "mode" "QI")
2030 (set_attr "pent_pair" "np")
2031 (set_attr "athlon_decode" "vector")])
2033 (define_expand "movstrictqi"
2034 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2035 (match_operand:QI 1 "general_operand" ""))]
2038 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2040 /* Don't generate memory->memory moves, go through a register. */
2041 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2042 operands[1] = force_reg (QImode, operands[1]);
2045 (define_insn "*movstrictqi_1"
2046 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2047 (match_operand:QI 1 "general_operand" "*qn,m"))]
2048 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2049 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2050 "mov{b}\t{%1, %0|%0, %1}"
2051 [(set_attr "type" "imov")
2052 (set_attr "mode" "QI")])
2054 (define_insn "*movstrictqi_xor"
2055 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2056 (match_operand:QI 1 "const0_operand" ""))
2057 (clobber (reg:CC FLAGS_REG))]
2060 [(set_attr "type" "alu1")
2061 (set_attr "mode" "QI")
2062 (set_attr "length_immediate" "0")])
2064 (define_insn "*movsi_extv_1"
2065 [(set (match_operand:SI 0 "register_operand" "=R")
2066 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2070 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2071 [(set_attr "type" "imovx")
2072 (set_attr "mode" "SI")])
2074 (define_insn "*movhi_extv_1"
2075 [(set (match_operand:HI 0 "register_operand" "=R")
2076 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2080 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2081 [(set_attr "type" "imovx")
2082 (set_attr "mode" "SI")])
2084 (define_insn "*movqi_extv_1"
2085 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2086 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2091 switch (get_attr_type (insn))
2094 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2096 return "mov{b}\t{%h1, %0|%0, %h1}";
2100 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2101 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2102 (ne (symbol_ref "TARGET_MOVX")
2104 (const_string "imovx")
2105 (const_string "imov")))
2107 (if_then_else (eq_attr "type" "imovx")
2109 (const_string "QI")))])
2111 (define_insn "*movqi_extv_1_rex64"
2112 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2113 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2118 switch (get_attr_type (insn))
2121 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2123 return "mov{b}\t{%h1, %0|%0, %h1}";
2127 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2128 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2129 (ne (symbol_ref "TARGET_MOVX")
2131 (const_string "imovx")
2132 (const_string "imov")))
2134 (if_then_else (eq_attr "type" "imovx")
2136 (const_string "QI")))])
2138 ;; Stores and loads of ax to arbitrary constant address.
2139 ;; We fake an second form of instruction to force reload to load address
2140 ;; into register when rax is not available
2141 (define_insn "*movabsqi_1_rex64"
2142 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2143 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2144 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2146 movabs{b}\t{%1, %P0|%P0, %1}
2147 mov{b}\t{%1, %a0|%a0, %1}"
2148 [(set_attr "type" "imov")
2149 (set_attr "modrm" "0,*")
2150 (set_attr "length_address" "8,0")
2151 (set_attr "length_immediate" "0,*")
2152 (set_attr "memory" "store")
2153 (set_attr "mode" "QI")])
2155 (define_insn "*movabsqi_2_rex64"
2156 [(set (match_operand:QI 0 "register_operand" "=a,r")
2157 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2158 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2160 movabs{b}\t{%P1, %0|%0, %P1}
2161 mov{b}\t{%a1, %0|%0, %a1}"
2162 [(set_attr "type" "imov")
2163 (set_attr "modrm" "0,*")
2164 (set_attr "length_address" "8,0")
2165 (set_attr "length_immediate" "0")
2166 (set_attr "memory" "load")
2167 (set_attr "mode" "QI")])
2169 (define_insn "*movdi_extzv_1"
2170 [(set (match_operand:DI 0 "register_operand" "=R")
2171 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2175 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2176 [(set_attr "type" "imovx")
2177 (set_attr "mode" "SI")])
2179 (define_insn "*movsi_extzv_1"
2180 [(set (match_operand:SI 0 "register_operand" "=R")
2181 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2185 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2186 [(set_attr "type" "imovx")
2187 (set_attr "mode" "SI")])
2189 (define_insn "*movqi_extzv_2"
2190 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2191 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2196 switch (get_attr_type (insn))
2199 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2201 return "mov{b}\t{%h1, %0|%0, %h1}";
2205 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2206 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2207 (ne (symbol_ref "TARGET_MOVX")
2209 (const_string "imovx")
2210 (const_string "imov")))
2212 (if_then_else (eq_attr "type" "imovx")
2214 (const_string "QI")))])
2216 (define_insn "*movqi_extzv_2_rex64"
2217 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2218 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2223 switch (get_attr_type (insn))
2226 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2228 return "mov{b}\t{%h1, %0|%0, %h1}";
2232 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2233 (ne (symbol_ref "TARGET_MOVX")
2235 (const_string "imovx")
2236 (const_string "imov")))
2238 (if_then_else (eq_attr "type" "imovx")
2240 (const_string "QI")))])
2242 (define_insn "movsi_insv_1"
2243 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2246 (match_operand:SI 1 "general_operand" "Qmn"))]
2248 "mov{b}\t{%b1, %h0|%h0, %b1}"
2249 [(set_attr "type" "imov")
2250 (set_attr "mode" "QI")])
2252 (define_insn "*movsi_insv_1_rex64"
2253 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2256 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2258 "mov{b}\t{%b1, %h0|%h0, %b1}"
2259 [(set_attr "type" "imov")
2260 (set_attr "mode" "QI")])
2262 (define_insn "movdi_insv_1_rex64"
2263 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2266 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2268 "mov{b}\t{%b1, %h0|%h0, %b1}"
2269 [(set_attr "type" "imov")
2270 (set_attr "mode" "QI")])
2272 (define_insn "*movqi_insv_2"
2273 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2276 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2279 "mov{b}\t{%h1, %h0|%h0, %h1}"
2280 [(set_attr "type" "imov")
2281 (set_attr "mode" "QI")])
2283 (define_expand "movdi"
2284 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2285 (match_operand:DI 1 "general_operand" ""))]
2287 "ix86_expand_move (DImode, operands); DONE;")
2289 (define_insn "*pushdi"
2290 [(set (match_operand:DI 0 "push_operand" "=<")
2291 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2295 (define_insn "*pushdi2_rex64"
2296 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2297 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2302 [(set_attr "type" "push,multi")
2303 (set_attr "mode" "DI")])
2305 ;; Convert impossible pushes of immediate to existing instructions.
2306 ;; First try to get scratch register and go through it. In case this
2307 ;; fails, push sign extended lower part first and then overwrite
2308 ;; upper part by 32bit move.
2310 [(match_scratch:DI 2 "r")
2311 (set (match_operand:DI 0 "push_operand" "")
2312 (match_operand:DI 1 "immediate_operand" ""))]
2313 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2314 && !x86_64_immediate_operand (operands[1], DImode)"
2315 [(set (match_dup 2) (match_dup 1))
2316 (set (match_dup 0) (match_dup 2))]
2319 ;; We need to define this as both peepholer and splitter for case
2320 ;; peephole2 pass is not run.
2321 ;; "&& 1" is needed to keep it from matching the previous pattern.
2323 [(set (match_operand:DI 0 "push_operand" "")
2324 (match_operand:DI 1 "immediate_operand" ""))]
2325 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2326 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2327 [(set (match_dup 0) (match_dup 1))
2328 (set (match_dup 2) (match_dup 3))]
2329 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2330 operands[1] = gen_lowpart (DImode, operands[2]);
2331 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2336 [(set (match_operand:DI 0 "push_operand" "")
2337 (match_operand:DI 1 "immediate_operand" ""))]
2338 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2339 ? epilogue_completed : reload_completed)
2340 && !symbolic_operand (operands[1], DImode)
2341 && !x86_64_immediate_operand (operands[1], DImode)"
2342 [(set (match_dup 0) (match_dup 1))
2343 (set (match_dup 2) (match_dup 3))]
2344 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2345 operands[1] = gen_lowpart (DImode, operands[2]);
2346 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2350 (define_insn "*pushdi2_prologue_rex64"
2351 [(set (match_operand:DI 0 "push_operand" "=<")
2352 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2353 (clobber (mem:BLK (scratch)))]
2356 [(set_attr "type" "push")
2357 (set_attr "mode" "DI")])
2359 (define_insn "*popdi1_epilogue_rex64"
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)))
2364 (clobber (mem:BLK (scratch)))]
2367 [(set_attr "type" "pop")
2368 (set_attr "mode" "DI")])
2370 (define_insn "popdi1"
2371 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2372 (mem:DI (reg:DI SP_REG)))
2373 (set (reg:DI SP_REG)
2374 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2377 [(set_attr "type" "pop")
2378 (set_attr "mode" "DI")])
2380 (define_insn "*movdi_xor_rex64"
2381 [(set (match_operand:DI 0 "register_operand" "=r")
2382 (match_operand:DI 1 "const0_operand" ""))
2383 (clobber (reg:CC FLAGS_REG))]
2385 && reload_completed"
2387 [(set_attr "type" "alu1")
2388 (set_attr "mode" "SI")
2389 (set_attr "length_immediate" "0")])
2391 (define_insn "*movdi_or_rex64"
2392 [(set (match_operand:DI 0 "register_operand" "=r")
2393 (match_operand:DI 1 "const_int_operand" "i"))
2394 (clobber (reg:CC FLAGS_REG))]
2397 && operands[1] == constm1_rtx"
2399 operands[1] = constm1_rtx;
2400 return "or{q}\t{%1, %0|%0, %1}";
2402 [(set_attr "type" "alu1")
2403 (set_attr "mode" "DI")
2404 (set_attr "length_immediate" "1")])
2406 (define_insn "*movdi_2"
2407 [(set (match_operand:DI 0 "nonimmediate_operand"
2408 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2409 (match_operand:DI 1 "general_operand"
2410 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2411 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2416 movq\t{%1, %0|%0, %1}
2417 movq\t{%1, %0|%0, %1}
2419 %vmovq\t{%1, %0|%0, %1}
2420 %vmovdqa\t{%1, %0|%0, %1}
2421 %vmovq\t{%1, %0|%0, %1}
2423 movlps\t{%1, %0|%0, %1}
2424 movaps\t{%1, %0|%0, %1}
2425 movlps\t{%1, %0|%0, %1}"
2426 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2427 (set (attr "prefix")
2428 (if_then_else (eq_attr "alternative" "5,6,7,8")
2429 (const_string "vex")
2430 (const_string "orig")))
2431 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2434 [(set (match_operand:DI 0 "push_operand" "")
2435 (match_operand:DI 1 "general_operand" ""))]
2436 "!TARGET_64BIT && reload_completed
2437 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2439 "ix86_split_long_move (operands); DONE;")
2441 ;; %%% This multiword shite has got to go.
2443 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2444 (match_operand:DI 1 "general_operand" ""))]
2445 "!TARGET_64BIT && reload_completed
2446 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2447 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2449 "ix86_split_long_move (operands); DONE;")
2451 (define_insn "*movdi_1_rex64"
2452 [(set (match_operand:DI 0 "nonimmediate_operand"
2453 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2454 (match_operand:DI 1 "general_operand"
2455 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2456 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2458 switch (get_attr_type (insn))
2461 if (SSE_REG_P (operands[0]))
2462 return "movq2dq\t{%1, %0|%0, %1}";
2464 return "movdq2q\t{%1, %0|%0, %1}";
2469 if (get_attr_mode (insn) == MODE_TI)
2470 return "vmovdqa\t{%1, %0|%0, %1}";
2472 return "vmovq\t{%1, %0|%0, %1}";
2475 if (get_attr_mode (insn) == MODE_TI)
2476 return "movdqa\t{%1, %0|%0, %1}";
2480 /* Moves from and into integer register is done using movd
2481 opcode with REX prefix. */
2482 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2483 return "movd\t{%1, %0|%0, %1}";
2484 return "movq\t{%1, %0|%0, %1}";
2487 return "%vpxor\t%0, %d0";
2490 return "pxor\t%0, %0";
2496 return "lea{q}\t{%a1, %0|%0, %a1}";
2499 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2500 if (get_attr_mode (insn) == MODE_SI)
2501 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2502 else if (which_alternative == 2)
2503 return "movabs{q}\t{%1, %0|%0, %1}";
2505 return "mov{q}\t{%1, %0|%0, %1}";
2509 (cond [(eq_attr "alternative" "5")
2510 (const_string "mmx")
2511 (eq_attr "alternative" "6,7,8,9,10")
2512 (const_string "mmxmov")
2513 (eq_attr "alternative" "11")
2514 (const_string "sselog1")
2515 (eq_attr "alternative" "12,13,14,15,16")
2516 (const_string "ssemov")
2517 (eq_attr "alternative" "17,18")
2518 (const_string "ssecvt")
2519 (eq_attr "alternative" "4")
2520 (const_string "multi")
2521 (match_operand:DI 1 "pic_32bit_operand" "")
2522 (const_string "lea")
2524 (const_string "imov")))
2527 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2529 (const_string "*")))
2530 (set (attr "length_immediate")
2532 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2534 (const_string "*")))
2535 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2536 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2537 (set (attr "prefix")
2538 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2539 (const_string "maybe_vex")
2540 (const_string "orig")))
2541 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2543 ;; Stores and loads of ax to arbitrary constant address.
2544 ;; We fake an second form of instruction to force reload to load address
2545 ;; into register when rax is not available
2546 (define_insn "*movabsdi_1_rex64"
2547 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2548 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2549 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2551 movabs{q}\t{%1, %P0|%P0, %1}
2552 mov{q}\t{%1, %a0|%a0, %1}"
2553 [(set_attr "type" "imov")
2554 (set_attr "modrm" "0,*")
2555 (set_attr "length_address" "8,0")
2556 (set_attr "length_immediate" "0,*")
2557 (set_attr "memory" "store")
2558 (set_attr "mode" "DI")])
2560 (define_insn "*movabsdi_2_rex64"
2561 [(set (match_operand:DI 0 "register_operand" "=a,r")
2562 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2563 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2565 movabs{q}\t{%P1, %0|%0, %P1}
2566 mov{q}\t{%a1, %0|%0, %a1}"
2567 [(set_attr "type" "imov")
2568 (set_attr "modrm" "0,*")
2569 (set_attr "length_address" "8,0")
2570 (set_attr "length_immediate" "0")
2571 (set_attr "memory" "load")
2572 (set_attr "mode" "DI")])
2574 ;; Convert impossible stores of immediate to existing instructions.
2575 ;; First try to get scratch register and go through it. In case this
2576 ;; fails, move by 32bit parts.
2578 [(match_scratch:DI 2 "r")
2579 (set (match_operand:DI 0 "memory_operand" "")
2580 (match_operand:DI 1 "immediate_operand" ""))]
2581 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2582 && !x86_64_immediate_operand (operands[1], DImode)"
2583 [(set (match_dup 2) (match_dup 1))
2584 (set (match_dup 0) (match_dup 2))]
2587 ;; We need to define this as both peepholer and splitter for case
2588 ;; peephole2 pass is not run.
2589 ;; "&& 1" is needed to keep it from matching the previous pattern.
2591 [(set (match_operand:DI 0 "memory_operand" "")
2592 (match_operand:DI 1 "immediate_operand" ""))]
2593 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2594 && !x86_64_immediate_operand (operands[1], DImode) && 1"
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]);")
2600 [(set (match_operand:DI 0 "memory_operand" "")
2601 (match_operand:DI 1 "immediate_operand" ""))]
2602 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2603 ? epilogue_completed : reload_completed)
2604 && !symbolic_operand (operands[1], DImode)
2605 && !x86_64_immediate_operand (operands[1], DImode)"
2606 [(set (match_dup 2) (match_dup 3))
2607 (set (match_dup 4) (match_dup 5))]
2608 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2610 (define_insn "*swapdi_rex64"
2611 [(set (match_operand:DI 0 "register_operand" "+r")
2612 (match_operand:DI 1 "register_operand" "+r"))
2617 [(set_attr "type" "imov")
2618 (set_attr "mode" "DI")
2619 (set_attr "pent_pair" "np")
2620 (set_attr "athlon_decode" "vector")
2621 (set_attr "amdfam10_decode" "double")])
2623 (define_expand "movoi"
2624 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2625 (match_operand:OI 1 "general_operand" ""))]
2627 "ix86_expand_move (OImode, operands); DONE;")
2629 (define_insn "*movoi_internal"
2630 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2631 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2633 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2635 switch (which_alternative)
2638 return "vxorps\t%0, %0, %0";
2641 if (misaligned_operand (operands[0], OImode)
2642 || misaligned_operand (operands[1], OImode))
2643 return "vmovdqu\t{%1, %0|%0, %1}";
2645 return "vmovdqa\t{%1, %0|%0, %1}";
2650 [(set_attr "type" "sselog1,ssemov,ssemov")
2651 (set_attr "prefix" "vex")
2652 (set_attr "mode" "OI")])
2654 (define_expand "movti"
2655 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2656 (match_operand:TI 1 "nonimmediate_operand" ""))]
2657 "TARGET_SSE || TARGET_64BIT"
2660 ix86_expand_move (TImode, operands);
2661 else if (push_operand (operands[0], TImode))
2662 ix86_expand_push (TImode, operands[1]);
2664 ix86_expand_vector_move (TImode, operands);
2668 (define_insn "*movti_internal"
2669 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2670 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2671 "TARGET_SSE && !TARGET_64BIT
2672 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2674 switch (which_alternative)
2677 if (get_attr_mode (insn) == MODE_V4SF)
2678 return "%vxorps\t%0, %d0";
2680 return "%vpxor\t%0, %d0";
2683 /* TDmode values are passed as TImode on the stack. Moving them
2684 to stack may result in unaligned memory access. */
2685 if (misaligned_operand (operands[0], TImode)
2686 || misaligned_operand (operands[1], TImode))
2688 if (get_attr_mode (insn) == MODE_V4SF)
2689 return "%vmovups\t{%1, %0|%0, %1}";
2691 return "%vmovdqu\t{%1, %0|%0, %1}";
2695 if (get_attr_mode (insn) == MODE_V4SF)
2696 return "%vmovaps\t{%1, %0|%0, %1}";
2698 return "%vmovdqa\t{%1, %0|%0, %1}";
2704 [(set_attr "type" "sselog1,ssemov,ssemov")
2705 (set_attr "prefix" "maybe_vex")
2707 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2708 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2709 (const_string "V4SF")
2710 (and (eq_attr "alternative" "2")
2711 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2713 (const_string "V4SF")]
2714 (const_string "TI")))])
2716 (define_insn "*movti_rex64"
2717 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2718 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2720 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2722 switch (which_alternative)
2728 if (get_attr_mode (insn) == MODE_V4SF)
2729 return "%vxorps\t%0, %d0";
2731 return "%vpxor\t%0, %d0";
2734 /* TDmode values are passed as TImode on the stack. Moving them
2735 to stack may result in unaligned memory access. */
2736 if (misaligned_operand (operands[0], TImode)
2737 || misaligned_operand (operands[1], TImode))
2739 if (get_attr_mode (insn) == MODE_V4SF)
2740 return "%vmovups\t{%1, %0|%0, %1}";
2742 return "%vmovdqu\t{%1, %0|%0, %1}";
2746 if (get_attr_mode (insn) == MODE_V4SF)
2747 return "%vmovaps\t{%1, %0|%0, %1}";
2749 return "%vmovdqa\t{%1, %0|%0, %1}";
2755 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2756 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2758 (cond [(eq_attr "alternative" "2,3")
2760 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2762 (const_string "V4SF")
2763 (const_string "TI"))
2764 (eq_attr "alternative" "4")
2766 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2768 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2770 (const_string "V4SF")
2771 (const_string "TI"))]
2772 (const_string "DI")))])
2775 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2776 (match_operand:TI 1 "general_operand" ""))]
2777 "reload_completed && !SSE_REG_P (operands[0])
2778 && !SSE_REG_P (operands[1])"
2780 "ix86_split_long_move (operands); DONE;")
2782 ;; This expands to what emit_move_complex would generate if we didn't
2783 ;; have a movti pattern. Having this avoids problems with reload on
2784 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2785 ;; to have around all the time.
2786 (define_expand "movcdi"
2787 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2788 (match_operand:CDI 1 "general_operand" ""))]
2791 if (push_operand (operands[0], CDImode))
2792 emit_move_complex_push (CDImode, operands[0], operands[1]);
2794 emit_move_complex_parts (operands[0], operands[1]);
2798 (define_expand "movsf"
2799 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2800 (match_operand:SF 1 "general_operand" ""))]
2802 "ix86_expand_move (SFmode, operands); DONE;")
2804 (define_insn "*pushsf"
2805 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2806 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2809 /* Anything else should be already split before reg-stack. */
2810 gcc_assert (which_alternative == 1);
2811 return "push{l}\t%1";
2813 [(set_attr "type" "multi,push,multi")
2814 (set_attr "unit" "i387,*,*")
2815 (set_attr "mode" "SF,SI,SF")])
2817 (define_insn "*pushsf_rex64"
2818 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2819 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2822 /* Anything else should be already split before reg-stack. */
2823 gcc_assert (which_alternative == 1);
2824 return "push{q}\t%q1";
2826 [(set_attr "type" "multi,push,multi")
2827 (set_attr "unit" "i387,*,*")
2828 (set_attr "mode" "SF,DI,SF")])
2831 [(set (match_operand:SF 0 "push_operand" "")
2832 (match_operand:SF 1 "memory_operand" ""))]
2834 && MEM_P (operands[1])
2835 && (operands[2] = find_constant_src (insn))"
2839 ;; %%% Kill this when call knows how to work this out.
2841 [(set (match_operand:SF 0 "push_operand" "")
2842 (match_operand:SF 1 "any_fp_register_operand" ""))]
2844 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
2845 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
2848 [(set (match_operand:SF 0 "push_operand" "")
2849 (match_operand:SF 1 "any_fp_register_operand" ""))]
2851 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
2852 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
2854 (define_insn "*movsf_1"
2855 [(set (match_operand:SF 0 "nonimmediate_operand"
2856 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
2857 (match_operand:SF 1 "general_operand"
2858 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
2859 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
2860 && (reload_in_progress || reload_completed
2861 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
2862 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
2863 && standard_80387_constant_p (operands[1]))
2864 || GET_CODE (operands[1]) != CONST_DOUBLE
2865 || memory_operand (operands[0], SFmode))"
2867 switch (which_alternative)
2871 return output_387_reg_move (insn, operands);
2874 return standard_80387_constant_opcode (operands[1]);
2878 return "mov{l}\t{%1, %0|%0, %1}";
2880 if (get_attr_mode (insn) == MODE_TI)
2881 return "%vpxor\t%0, %d0";
2883 return "%vxorps\t%0, %d0";
2885 if (get_attr_mode (insn) == MODE_V4SF)
2886 return "%vmovaps\t{%1, %0|%0, %1}";
2888 return "%vmovss\t{%1, %d0|%d0, %1}";
2891 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
2892 : "vmovss\t{%1, %0|%0, %1}";
2894 return "movss\t{%1, %0|%0, %1}";
2896 return "%vmovss\t{%1, %0|%0, %1}";
2898 case 9: case 10: case 14: case 15:
2899 return "movd\t{%1, %0|%0, %1}";
2901 return "%vmovd\t{%1, %0|%0, %1}";
2904 return "movq\t{%1, %0|%0, %1}";
2910 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
2911 (set (attr "prefix")
2912 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
2913 (const_string "maybe_vex")
2914 (const_string "orig")))
2916 (cond [(eq_attr "alternative" "3,4,9,10")
2918 (eq_attr "alternative" "5")
2920 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
2922 (ne (symbol_ref "TARGET_SSE2")
2924 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2927 (const_string "V4SF"))
2928 /* For architectures resolving dependencies on
2929 whole SSE registers use APS move to break dependency
2930 chains, otherwise use short move to avoid extra work.
2932 Do the same for architectures resolving dependencies on
2933 the parts. While in DF mode it is better to always handle
2934 just register parts, the SF mode is different due to lack
2935 of instructions to load just part of the register. It is
2936 better to maintain the whole registers in single format
2937 to avoid problems on using packed logical operations. */
2938 (eq_attr "alternative" "6")
2940 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
2942 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
2944 (const_string "V4SF")
2945 (const_string "SF"))
2946 (eq_attr "alternative" "11")
2947 (const_string "DI")]
2948 (const_string "SF")))])
2950 (define_insn "*swapsf"
2951 [(set (match_operand:SF 0 "fp_register_operand" "+f")
2952 (match_operand:SF 1 "fp_register_operand" "+f"))
2955 "reload_completed || TARGET_80387"
2957 if (STACK_TOP_P (operands[0]))
2962 [(set_attr "type" "fxch")
2963 (set_attr "mode" "SF")])
2965 (define_expand "movdf"
2966 [(set (match_operand:DF 0 "nonimmediate_operand" "")
2967 (match_operand:DF 1 "general_operand" ""))]
2969 "ix86_expand_move (DFmode, operands); DONE;")
2971 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
2972 ;; Size of pushdf using integer instructions is 2+2*memory operand size
2973 ;; On the average, pushdf using integers can be still shorter. Allow this
2974 ;; pattern for optimize_size too.
2976 (define_insn "*pushdf_nointeger"
2977 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
2978 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
2979 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
2981 /* This insn should be already split before reg-stack. */
2984 [(set_attr "type" "multi")
2985 (set_attr "unit" "i387,*,*,*")
2986 (set_attr "mode" "DF,SI,SI,DF")])
2988 (define_insn "*pushdf_integer"
2989 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
2990 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
2991 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
2993 /* This insn should be already split before reg-stack. */
2996 [(set_attr "type" "multi")
2997 (set_attr "unit" "i387,*,*")
2998 (set_attr "mode" "DF,SI,DF")])
3000 ;; %%% Kill this when call knows how to work this out.
3002 [(set (match_operand:DF 0 "push_operand" "")
3003 (match_operand:DF 1 "any_fp_register_operand" ""))]
3005 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3006 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3010 [(set (match_operand:DF 0 "push_operand" "")
3011 (match_operand:DF 1 "general_operand" ""))]
3014 "ix86_split_long_move (operands); DONE;")
3016 ;; Moving is usually shorter when only FP registers are used. This separate
3017 ;; movdf pattern avoids the use of integer registers for FP operations
3018 ;; when optimizing for size.
3020 (define_insn "*movdf_nointeger"
3021 [(set (match_operand:DF 0 "nonimmediate_operand"
3022 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3023 (match_operand:DF 1 "general_operand"
3024 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3025 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3026 && ((optimize_function_for_size_p (cfun)
3027 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3028 && (reload_in_progress || reload_completed
3029 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3030 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3031 && optimize_function_for_size_p (cfun)
3032 && !memory_operand (operands[0], DFmode)
3033 && standard_80387_constant_p (operands[1]))
3034 || GET_CODE (operands[1]) != CONST_DOUBLE
3035 || ((optimize_function_for_size_p (cfun)
3036 || !TARGET_MEMORY_MISMATCH_STALL
3037 || reload_in_progress || reload_completed)
3038 && memory_operand (operands[0], DFmode)))"
3040 switch (which_alternative)
3044 return output_387_reg_move (insn, operands);
3047 return standard_80387_constant_opcode (operands[1]);
3053 switch (get_attr_mode (insn))
3056 return "%vxorps\t%0, %d0";
3058 return "%vxorpd\t%0, %d0";
3060 return "%vpxor\t%0, %d0";
3067 switch (get_attr_mode (insn))
3070 return "%vmovaps\t{%1, %0|%0, %1}";
3072 return "%vmovapd\t{%1, %0|%0, %1}";
3074 return "%vmovdqa\t{%1, %0|%0, %1}";
3076 return "%vmovq\t{%1, %0|%0, %1}";
3080 if (REG_P (operands[0]) && REG_P (operands[1]))
3081 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3083 return "vmovsd\t{%1, %0|%0, %1}";
3086 return "movsd\t{%1, %0|%0, %1}";
3090 if (REG_P (operands[0]))
3091 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3093 return "vmovlpd\t{%1, %0|%0, %1}";
3096 return "movlpd\t{%1, %0|%0, %1}";
3100 if (REG_P (operands[0]))
3101 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3103 return "vmovlps\t{%1, %0|%0, %1}";
3106 return "movlps\t{%1, %0|%0, %1}";
3115 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3116 (set (attr "prefix")
3117 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3118 (const_string "orig")
3119 (const_string "maybe_vex")))
3120 (set (attr "prefix_data16")
3121 (if_then_else (eq_attr "mode" "V1DF")
3123 (const_string "*")))
3125 (cond [(eq_attr "alternative" "0,1,2")
3127 (eq_attr "alternative" "3,4")
3130 /* For SSE1, we have many fewer alternatives. */
3131 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3132 (cond [(eq_attr "alternative" "5,6")
3133 (const_string "V4SF")
3135 (const_string "V2SF"))
3137 /* xorps is one byte shorter. */
3138 (eq_attr "alternative" "5")
3139 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3141 (const_string "V4SF")
3142 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3146 (const_string "V2DF"))
3148 /* For architectures resolving dependencies on
3149 whole SSE registers use APD move to break dependency
3150 chains, otherwise use short move to avoid extra work.
3152 movaps encodes one byte shorter. */
3153 (eq_attr "alternative" "6")
3155 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3157 (const_string "V4SF")
3158 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3160 (const_string "V2DF")
3162 (const_string "DF"))
3163 /* For architectures resolving dependencies on register
3164 parts we may avoid extra work to zero out upper part
3166 (eq_attr "alternative" "7")
3168 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3170 (const_string "V1DF")
3171 (const_string "DF"))
3173 (const_string "DF")))])
3175 (define_insn "*movdf_integer_rex64"
3176 [(set (match_operand:DF 0 "nonimmediate_operand"
3177 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3178 (match_operand:DF 1 "general_operand"
3179 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3180 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3181 && (reload_in_progress || reload_completed
3182 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3183 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3184 && optimize_function_for_size_p (cfun)
3185 && standard_80387_constant_p (operands[1]))
3186 || GET_CODE (operands[1]) != CONST_DOUBLE
3187 || memory_operand (operands[0], DFmode))"
3189 switch (which_alternative)
3193 return output_387_reg_move (insn, operands);
3196 return standard_80387_constant_opcode (operands[1]);
3203 switch (get_attr_mode (insn))
3206 return "%vxorps\t%0, %d0";
3208 return "%vxorpd\t%0, %d0";
3210 return "%vpxor\t%0, %d0";
3217 switch (get_attr_mode (insn))
3220 return "%vmovaps\t{%1, %0|%0, %1}";
3222 return "%vmovapd\t{%1, %0|%0, %1}";
3224 return "%vmovdqa\t{%1, %0|%0, %1}";
3226 return "%vmovq\t{%1, %0|%0, %1}";
3230 if (REG_P (operands[0]) && REG_P (operands[1]))
3231 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3233 return "vmovsd\t{%1, %0|%0, %1}";
3236 return "movsd\t{%1, %0|%0, %1}";
3238 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3240 return "%vmovlps\t{%1, %d0|%d0, %1}";
3247 return "%vmovd\t{%1, %0|%0, %1}";
3253 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3254 (set (attr "prefix")
3255 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3256 (const_string "orig")
3257 (const_string "maybe_vex")))
3258 (set (attr "prefix_data16")
3259 (if_then_else (eq_attr "mode" "V1DF")
3261 (const_string "*")))
3263 (cond [(eq_attr "alternative" "0,1,2")
3265 (eq_attr "alternative" "3,4,9,10")
3268 /* For SSE1, we have many fewer alternatives. */
3269 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3270 (cond [(eq_attr "alternative" "5,6")
3271 (const_string "V4SF")
3273 (const_string "V2SF"))
3275 /* xorps is one byte shorter. */
3276 (eq_attr "alternative" "5")
3277 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3279 (const_string "V4SF")
3280 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3284 (const_string "V2DF"))
3286 /* For architectures resolving dependencies on
3287 whole SSE registers use APD move to break dependency
3288 chains, otherwise use short move to avoid extra work.
3290 movaps encodes one byte shorter. */
3291 (eq_attr "alternative" "6")
3293 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3295 (const_string "V4SF")
3296 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3298 (const_string "V2DF")
3300 (const_string "DF"))
3301 /* For architectures resolving dependencies on register
3302 parts we may avoid extra work to zero out upper part
3304 (eq_attr "alternative" "7")
3306 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3308 (const_string "V1DF")
3309 (const_string "DF"))
3311 (const_string "DF")))])
3313 (define_insn "*movdf_integer"
3314 [(set (match_operand:DF 0 "nonimmediate_operand"
3315 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3316 (match_operand:DF 1 "general_operand"
3317 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3318 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3319 && optimize_function_for_speed_p (cfun)
3320 && TARGET_INTEGER_DFMODE_MOVES
3321 && (reload_in_progress || reload_completed
3322 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3323 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3324 && optimize_function_for_size_p (cfun)
3325 && standard_80387_constant_p (operands[1]))
3326 || GET_CODE (operands[1]) != CONST_DOUBLE
3327 || memory_operand (operands[0], DFmode))"
3329 switch (which_alternative)
3333 return output_387_reg_move (insn, operands);
3336 return standard_80387_constant_opcode (operands[1]);
3343 switch (get_attr_mode (insn))
3346 return "xorps\t%0, %0";
3348 return "xorpd\t%0, %0";
3350 return "pxor\t%0, %0";
3357 switch (get_attr_mode (insn))
3360 return "movaps\t{%1, %0|%0, %1}";
3362 return "movapd\t{%1, %0|%0, %1}";
3364 return "movdqa\t{%1, %0|%0, %1}";
3366 return "movq\t{%1, %0|%0, %1}";
3368 return "movsd\t{%1, %0|%0, %1}";
3370 return "movlpd\t{%1, %0|%0, %1}";
3372 return "movlps\t{%1, %0|%0, %1}";
3381 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3382 (set (attr "prefix_data16")
3383 (if_then_else (eq_attr "mode" "V1DF")
3385 (const_string "*")))
3387 (cond [(eq_attr "alternative" "0,1,2")
3389 (eq_attr "alternative" "3,4")
3392 /* For SSE1, we have many fewer alternatives. */
3393 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3394 (cond [(eq_attr "alternative" "5,6")
3395 (const_string "V4SF")
3397 (const_string "V2SF"))
3399 /* xorps is one byte shorter. */
3400 (eq_attr "alternative" "5")
3401 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3403 (const_string "V4SF")
3404 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3408 (const_string "V2DF"))
3410 /* For architectures resolving dependencies on
3411 whole SSE registers use APD move to break dependency
3412 chains, otherwise use short move to avoid extra work.
3414 movaps encodes one byte shorter. */
3415 (eq_attr "alternative" "6")
3417 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3419 (const_string "V4SF")
3420 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3422 (const_string "V2DF")
3424 (const_string "DF"))
3425 /* For architectures resolving dependencies on register
3426 parts we may avoid extra work to zero out upper part
3428 (eq_attr "alternative" "7")
3430 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3432 (const_string "V1DF")
3433 (const_string "DF"))
3435 (const_string "DF")))])
3438 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3439 (match_operand:DF 1 "general_operand" ""))]
3441 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3442 && ! (ANY_FP_REG_P (operands[0]) ||
3443 (GET_CODE (operands[0]) == SUBREG
3444 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3445 && ! (ANY_FP_REG_P (operands[1]) ||
3446 (GET_CODE (operands[1]) == SUBREG
3447 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3449 "ix86_split_long_move (operands); DONE;")
3451 (define_insn "*swapdf"
3452 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3453 (match_operand:DF 1 "fp_register_operand" "+f"))
3456 "reload_completed || TARGET_80387"
3458 if (STACK_TOP_P (operands[0]))
3463 [(set_attr "type" "fxch")
3464 (set_attr "mode" "DF")])
3466 (define_expand "movxf"
3467 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3468 (match_operand:XF 1 "general_operand" ""))]
3470 "ix86_expand_move (XFmode, operands); DONE;")
3472 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3473 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3474 ;; Pushing using integer instructions is longer except for constants
3475 ;; and direct memory references.
3476 ;; (assuming that any given constant is pushed only once, but this ought to be
3477 ;; handled elsewhere).
3479 (define_insn "*pushxf_nointeger"
3480 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3481 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3482 "optimize_function_for_size_p (cfun)"
3484 /* This insn should be already split before reg-stack. */
3487 [(set_attr "type" "multi")
3488 (set_attr "unit" "i387,*,*")
3489 (set_attr "mode" "XF,SI,SI")])
3491 (define_insn "*pushxf_integer"
3492 [(set (match_operand:XF 0 "push_operand" "=<,<")
3493 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3494 "optimize_function_for_speed_p (cfun)"
3496 /* This insn should be already split before reg-stack. */
3499 [(set_attr "type" "multi")
3500 (set_attr "unit" "i387,*")
3501 (set_attr "mode" "XF,SI")])
3504 [(set (match_operand 0 "push_operand" "")
3505 (match_operand 1 "general_operand" ""))]
3507 && (GET_MODE (operands[0]) == XFmode
3508 || GET_MODE (operands[0]) == DFmode)
3509 && !ANY_FP_REG_P (operands[1])"
3511 "ix86_split_long_move (operands); DONE;")
3514 [(set (match_operand:XF 0 "push_operand" "")
3515 (match_operand:XF 1 "any_fp_register_operand" ""))]
3517 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3518 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3519 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3521 ;; Do not use integer registers when optimizing for size
3522 (define_insn "*movxf_nointeger"
3523 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3524 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3525 "optimize_function_for_size_p (cfun)
3526 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3527 && (reload_in_progress || reload_completed
3528 || standard_80387_constant_p (operands[1])
3529 || GET_CODE (operands[1]) != CONST_DOUBLE
3530 || memory_operand (operands[0], XFmode))"
3532 switch (which_alternative)
3536 return output_387_reg_move (insn, operands);
3539 return standard_80387_constant_opcode (operands[1]);
3547 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3548 (set_attr "mode" "XF,XF,XF,SI,SI")])
3550 (define_insn "*movxf_integer"
3551 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3552 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3553 "optimize_function_for_speed_p (cfun)
3554 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3555 && (reload_in_progress || reload_completed
3556 || GET_CODE (operands[1]) != CONST_DOUBLE
3557 || memory_operand (operands[0], XFmode))"
3559 switch (which_alternative)
3563 return output_387_reg_move (insn, operands);
3566 return standard_80387_constant_opcode (operands[1]);
3575 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3576 (set_attr "mode" "XF,XF,XF,SI,SI")])
3578 (define_expand "movtf"
3579 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3580 (match_operand:TF 1 "nonimmediate_operand" ""))]
3583 ix86_expand_move (TFmode, operands);
3587 (define_insn "*movtf_internal"
3588 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3589 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3591 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3593 switch (which_alternative)
3597 if (get_attr_mode (insn) == MODE_V4SF)
3598 return "%vmovaps\t{%1, %0|%0, %1}";
3600 return "%vmovdqa\t{%1, %0|%0, %1}";
3602 if (get_attr_mode (insn) == MODE_V4SF)
3603 return "%vxorps\t%0, %d0";
3605 return "%vpxor\t%0, %d0";
3613 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3614 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3616 (cond [(eq_attr "alternative" "0,2")
3618 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3620 (const_string "V4SF")
3621 (const_string "TI"))
3622 (eq_attr "alternative" "1")
3624 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3626 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3628 (const_string "V4SF")
3629 (const_string "TI"))]
3630 (const_string "DI")))])
3632 (define_insn "*pushtf_sse"
3633 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3634 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3637 /* This insn should be already split before reg-stack. */
3640 [(set_attr "type" "multi")
3641 (set_attr "unit" "sse,*,*")
3642 (set_attr "mode" "TF,SI,SI")])
3645 [(set (match_operand:TF 0 "push_operand" "")
3646 (match_operand:TF 1 "general_operand" ""))]
3647 "TARGET_SSE2 && reload_completed
3648 && !SSE_REG_P (operands[1])"
3650 "ix86_split_long_move (operands); DONE;")
3653 [(set (match_operand:TF 0 "push_operand" "")
3654 (match_operand:TF 1 "any_fp_register_operand" ""))]
3656 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3657 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3661 [(set (match_operand 0 "nonimmediate_operand" "")
3662 (match_operand 1 "general_operand" ""))]
3664 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3665 && GET_MODE (operands[0]) == XFmode
3666 && ! (ANY_FP_REG_P (operands[0]) ||
3667 (GET_CODE (operands[0]) == SUBREG
3668 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3669 && ! (ANY_FP_REG_P (operands[1]) ||
3670 (GET_CODE (operands[1]) == SUBREG
3671 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3673 "ix86_split_long_move (operands); DONE;")
3676 [(set (match_operand 0 "register_operand" "")
3677 (match_operand 1 "memory_operand" ""))]
3679 && MEM_P (operands[1])
3680 && (GET_MODE (operands[0]) == TFmode
3681 || GET_MODE (operands[0]) == XFmode
3682 || GET_MODE (operands[0]) == SFmode
3683 || GET_MODE (operands[0]) == DFmode)
3684 && (operands[2] = find_constant_src (insn))"
3685 [(set (match_dup 0) (match_dup 2))]
3687 rtx c = operands[2];
3688 rtx r = operands[0];
3690 if (GET_CODE (r) == SUBREG)
3695 if (!standard_sse_constant_p (c))
3698 else if (FP_REG_P (r))
3700 if (!standard_80387_constant_p (c))
3703 else if (MMX_REG_P (r))
3708 [(set (match_operand 0 "register_operand" "")
3709 (float_extend (match_operand 1 "memory_operand" "")))]
3711 && MEM_P (operands[1])
3712 && (GET_MODE (operands[0]) == TFmode
3713 || GET_MODE (operands[0]) == XFmode
3714 || GET_MODE (operands[0]) == SFmode
3715 || GET_MODE (operands[0]) == DFmode)
3716 && (operands[2] = find_constant_src (insn))"
3717 [(set (match_dup 0) (match_dup 2))]
3719 rtx c = operands[2];
3720 rtx r = operands[0];
3722 if (GET_CODE (r) == SUBREG)
3727 if (!standard_sse_constant_p (c))
3730 else if (FP_REG_P (r))
3732 if (!standard_80387_constant_p (c))
3735 else if (MMX_REG_P (r))
3739 (define_insn "swapxf"
3740 [(set (match_operand:XF 0 "register_operand" "+f")
3741 (match_operand:XF 1 "register_operand" "+f"))
3746 if (STACK_TOP_P (operands[0]))
3751 [(set_attr "type" "fxch")
3752 (set_attr "mode" "XF")])
3754 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3756 [(set (match_operand:X87MODEF 0 "register_operand" "")
3757 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3758 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3759 && (standard_80387_constant_p (operands[1]) == 8
3760 || standard_80387_constant_p (operands[1]) == 9)"
3761 [(set (match_dup 0)(match_dup 1))
3763 (neg:X87MODEF (match_dup 0)))]
3767 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3768 if (real_isnegzero (&r))
3769 operands[1] = CONST0_RTX (<MODE>mode);
3771 operands[1] = CONST1_RTX (<MODE>mode);
3775 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3776 (match_operand:TF 1 "general_operand" ""))]
3778 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3780 "ix86_split_long_move (operands); DONE;")
3782 ;; Zero extension instructions
3784 (define_expand "zero_extendhisi2"
3785 [(set (match_operand:SI 0 "register_operand" "")
3786 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3789 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3791 operands[1] = force_reg (HImode, operands[1]);
3792 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3797 (define_insn "zero_extendhisi2_and"
3798 [(set (match_operand:SI 0 "register_operand" "=r")
3799 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3800 (clobber (reg:CC FLAGS_REG))]
3801 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3803 [(set_attr "type" "alu1")
3804 (set_attr "mode" "SI")])
3807 [(set (match_operand:SI 0 "register_operand" "")
3808 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3809 (clobber (reg:CC FLAGS_REG))]
3810 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3811 && optimize_function_for_speed_p (cfun)"
3812 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3813 (clobber (reg:CC FLAGS_REG))])]
3816 (define_insn "*zero_extendhisi2_movzwl"
3817 [(set (match_operand:SI 0 "register_operand" "=r")
3818 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3819 "!TARGET_ZERO_EXTEND_WITH_AND
3820 || optimize_function_for_size_p (cfun)"
3821 "movz{wl|x}\t{%1, %0|%0, %1}"
3822 [(set_attr "type" "imovx")
3823 (set_attr "mode" "SI")])
3825 (define_expand "zero_extendqihi2"
3827 [(set (match_operand:HI 0 "register_operand" "")
3828 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3829 (clobber (reg:CC FLAGS_REG))])]
3833 (define_insn "*zero_extendqihi2_and"
3834 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
3835 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3836 (clobber (reg:CC FLAGS_REG))]
3837 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3839 [(set_attr "type" "alu1")
3840 (set_attr "mode" "HI")])
3842 (define_insn "*zero_extendqihi2_movzbw_and"
3843 [(set (match_operand:HI 0 "register_operand" "=r,r")
3844 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3845 (clobber (reg:CC FLAGS_REG))]
3846 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3848 [(set_attr "type" "imovx,alu1")
3849 (set_attr "mode" "HI")])
3851 ; zero extend to SImode here to avoid partial register stalls
3852 (define_insn "*zero_extendqihi2_movzbl"
3853 [(set (match_operand:HI 0 "register_operand" "=r")
3854 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3855 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3856 && reload_completed"
3857 "movz{bl|x}\t{%1, %k0|%k0, %1}"
3858 [(set_attr "type" "imovx")
3859 (set_attr "mode" "SI")])
3861 ;; For the movzbw case strip only the clobber
3863 [(set (match_operand:HI 0 "register_operand" "")
3864 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3865 (clobber (reg:CC FLAGS_REG))]
3867 && (!TARGET_ZERO_EXTEND_WITH_AND
3868 || optimize_function_for_size_p (cfun))
3869 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3870 [(set (match_operand:HI 0 "register_operand" "")
3871 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
3873 ;; When source and destination does not overlap, clear destination
3874 ;; first and then do the movb
3876 [(set (match_operand:HI 0 "register_operand" "")
3877 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
3878 (clobber (reg:CC FLAGS_REG))]
3880 && ANY_QI_REG_P (operands[0])
3881 && (TARGET_ZERO_EXTEND_WITH_AND
3882 && optimize_function_for_speed_p (cfun))
3883 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3884 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3886 operands[2] = gen_lowpart (QImode, operands[0]);
3887 ix86_expand_clear (operands[0]);
3890 ;; Rest is handled by single and.
3892 [(set (match_operand:HI 0 "register_operand" "")
3893 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
3894 (clobber (reg:CC FLAGS_REG))]
3896 && true_regnum (operands[0]) == true_regnum (operands[1])"
3897 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
3898 (clobber (reg:CC FLAGS_REG))])]
3901 (define_expand "zero_extendqisi2"
3903 [(set (match_operand:SI 0 "register_operand" "")
3904 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3905 (clobber (reg:CC FLAGS_REG))])]
3909 (define_insn "*zero_extendqisi2_and"
3910 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
3911 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
3912 (clobber (reg:CC FLAGS_REG))]
3913 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3915 [(set_attr "type" "alu1")
3916 (set_attr "mode" "SI")])
3918 (define_insn "*zero_extendqisi2_movzbl_and"
3919 [(set (match_operand:SI 0 "register_operand" "=r,r")
3920 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
3921 (clobber (reg:CC FLAGS_REG))]
3922 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
3924 [(set_attr "type" "imovx,alu1")
3925 (set_attr "mode" "SI")])
3927 (define_insn "*zero_extendqisi2_movzbl"
3928 [(set (match_operand:SI 0 "register_operand" "=r")
3929 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
3930 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3931 && reload_completed"
3932 "movz{bl|x}\t{%1, %0|%0, %1}"
3933 [(set_attr "type" "imovx")
3934 (set_attr "mode" "SI")])
3936 ;; For the movzbl case strip only the clobber
3938 [(set (match_operand:SI 0 "register_operand" "")
3939 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3940 (clobber (reg:CC FLAGS_REG))]
3942 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
3943 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
3945 (zero_extend:SI (match_dup 1)))])
3947 ;; When source and destination does not overlap, clear destination
3948 ;; first and then do the movb
3950 [(set (match_operand:SI 0 "register_operand" "")
3951 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
3952 (clobber (reg:CC FLAGS_REG))]
3954 && ANY_QI_REG_P (operands[0])
3955 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
3956 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3957 && !reg_overlap_mentioned_p (operands[0], operands[1])"
3958 [(set (strict_low_part (match_dup 2)) (match_dup 1))]
3960 operands[2] = gen_lowpart (QImode, operands[0]);
3961 ix86_expand_clear (operands[0]);
3964 ;; Rest is handled by single and.
3966 [(set (match_operand:SI 0 "register_operand" "")
3967 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
3968 (clobber (reg:CC FLAGS_REG))]
3970 && true_regnum (operands[0]) == true_regnum (operands[1])"
3971 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
3972 (clobber (reg:CC FLAGS_REG))])]
3975 ;; %%% Kill me once multi-word ops are sane.
3976 (define_expand "zero_extendsidi2"
3977 [(set (match_operand:DI 0 "register_operand" "")
3978 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
3983 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
3988 (define_insn "zero_extendsidi2_32"
3989 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
3991 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
3992 (clobber (reg:CC FLAGS_REG))]
3998 movd\t{%1, %0|%0, %1}
3999 movd\t{%1, %0|%0, %1}
4000 %vmovd\t{%1, %0|%0, %1}
4001 %vmovd\t{%1, %0|%0, %1}"
4002 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4003 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4004 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4006 (define_insn "zero_extendsidi2_rex64"
4007 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4009 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4012 mov\t{%k1, %k0|%k0, %k1}
4014 movd\t{%1, %0|%0, %1}
4015 movd\t{%1, %0|%0, %1}
4016 %vmovd\t{%1, %0|%0, %1}
4017 %vmovd\t{%1, %0|%0, %1}"
4018 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4019 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4020 (set_attr "prefix_0f" "0,*,*,*,*,*")
4021 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4024 [(set (match_operand:DI 0 "memory_operand" "")
4025 (zero_extend:DI (match_dup 0)))]
4027 [(set (match_dup 4) (const_int 0))]
4028 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4031 [(set (match_operand:DI 0 "register_operand" "")
4032 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4033 (clobber (reg:CC FLAGS_REG))]
4034 "!TARGET_64BIT && reload_completed
4035 && true_regnum (operands[0]) == true_regnum (operands[1])"
4036 [(set (match_dup 4) (const_int 0))]
4037 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4040 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4041 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4042 (clobber (reg:CC FLAGS_REG))]
4043 "!TARGET_64BIT && reload_completed
4044 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4045 [(set (match_dup 3) (match_dup 1))
4046 (set (match_dup 4) (const_int 0))]
4047 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4049 (define_insn "zero_extendhidi2"
4050 [(set (match_operand:DI 0 "register_operand" "=r")
4051 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4053 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4054 [(set_attr "type" "imovx")
4055 (set_attr "mode" "SI")])
4057 (define_insn "zero_extendqidi2"
4058 [(set (match_operand:DI 0 "register_operand" "=r")
4059 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4061 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4062 [(set_attr "type" "imovx")
4063 (set_attr "mode" "SI")])
4065 ;; Sign extension instructions
4067 (define_expand "extendsidi2"
4068 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4069 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4070 (clobber (reg:CC FLAGS_REG))
4071 (clobber (match_scratch:SI 2 ""))])]
4076 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4081 (define_insn "*extendsidi2_1"
4082 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4083 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4084 (clobber (reg:CC FLAGS_REG))
4085 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4089 (define_insn "extendsidi2_rex64"
4090 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4091 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4095 movs{lq|x}\t{%1, %0|%0, %1}"
4096 [(set_attr "type" "imovx")
4097 (set_attr "mode" "DI")
4098 (set_attr "prefix_0f" "0")
4099 (set_attr "modrm" "0,1")])
4101 (define_insn "extendhidi2"
4102 [(set (match_operand:DI 0 "register_operand" "=r")
4103 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4105 "movs{wq|x}\t{%1, %0|%0, %1}"
4106 [(set_attr "type" "imovx")
4107 (set_attr "mode" "DI")])
4109 (define_insn "extendqidi2"
4110 [(set (match_operand:DI 0 "register_operand" "=r")
4111 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4113 "movs{bq|x}\t{%1, %0|%0, %1}"
4114 [(set_attr "type" "imovx")
4115 (set_attr "mode" "DI")])
4117 ;; Extend to memory case when source register does die.
4119 [(set (match_operand:DI 0 "memory_operand" "")
4120 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4121 (clobber (reg:CC FLAGS_REG))
4122 (clobber (match_operand:SI 2 "register_operand" ""))]
4124 && dead_or_set_p (insn, operands[1])
4125 && !reg_mentioned_p (operands[1], operands[0]))"
4126 [(set (match_dup 3) (match_dup 1))
4127 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4128 (clobber (reg:CC FLAGS_REG))])
4129 (set (match_dup 4) (match_dup 1))]
4130 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4132 ;; Extend to memory case when source register does not die.
4134 [(set (match_operand:DI 0 "memory_operand" "")
4135 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4136 (clobber (reg:CC FLAGS_REG))
4137 (clobber (match_operand:SI 2 "register_operand" ""))]
4141 split_di (&operands[0], 1, &operands[3], &operands[4]);
4143 emit_move_insn (operands[3], operands[1]);
4145 /* Generate a cltd if possible and doing so it profitable. */
4146 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4147 && true_regnum (operands[1]) == AX_REG
4148 && true_regnum (operands[2]) == DX_REG)
4150 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4154 emit_move_insn (operands[2], operands[1]);
4155 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4157 emit_move_insn (operands[4], operands[2]);
4161 ;; Extend to register case. Optimize case where source and destination
4162 ;; registers match and cases where we can use cltd.
4164 [(set (match_operand:DI 0 "register_operand" "")
4165 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4166 (clobber (reg:CC FLAGS_REG))
4167 (clobber (match_scratch:SI 2 ""))]
4171 split_di (&operands[0], 1, &operands[3], &operands[4]);
4173 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4174 emit_move_insn (operands[3], operands[1]);
4176 /* Generate a cltd if possible and doing so it profitable. */
4177 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4178 && true_regnum (operands[3]) == AX_REG)
4180 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4184 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4185 emit_move_insn (operands[4], operands[1]);
4187 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4191 (define_insn "extendhisi2"
4192 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4193 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4196 switch (get_attr_prefix_0f (insn))
4199 return "{cwtl|cwde}";
4201 return "movs{wl|x}\t{%1, %0|%0, %1}";
4204 [(set_attr "type" "imovx")
4205 (set_attr "mode" "SI")
4206 (set (attr "prefix_0f")
4207 ;; movsx is short decodable while cwtl is vector decoded.
4208 (if_then_else (and (eq_attr "cpu" "!k6")
4209 (eq_attr "alternative" "0"))
4211 (const_string "1")))
4213 (if_then_else (eq_attr "prefix_0f" "0")
4215 (const_string "1")))])
4217 (define_insn "*extendhisi2_zext"
4218 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4220 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4223 switch (get_attr_prefix_0f (insn))
4226 return "{cwtl|cwde}";
4228 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4231 [(set_attr "type" "imovx")
4232 (set_attr "mode" "SI")
4233 (set (attr "prefix_0f")
4234 ;; movsx is short decodable while cwtl is vector decoded.
4235 (if_then_else (and (eq_attr "cpu" "!k6")
4236 (eq_attr "alternative" "0"))
4238 (const_string "1")))
4240 (if_then_else (eq_attr "prefix_0f" "0")
4242 (const_string "1")))])
4244 (define_insn "extendqihi2"
4245 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4246 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4249 switch (get_attr_prefix_0f (insn))
4252 return "{cbtw|cbw}";
4254 return "movs{bw|x}\t{%1, %0|%0, %1}";
4257 [(set_attr "type" "imovx")
4258 (set_attr "mode" "HI")
4259 (set (attr "prefix_0f")
4260 ;; movsx is short decodable while cwtl is vector decoded.
4261 (if_then_else (and (eq_attr "cpu" "!k6")
4262 (eq_attr "alternative" "0"))
4264 (const_string "1")))
4266 (if_then_else (eq_attr "prefix_0f" "0")
4268 (const_string "1")))])
4270 (define_insn "extendqisi2"
4271 [(set (match_operand:SI 0 "register_operand" "=r")
4272 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4274 "movs{bl|x}\t{%1, %0|%0, %1}"
4275 [(set_attr "type" "imovx")
4276 (set_attr "mode" "SI")])
4278 (define_insn "*extendqisi2_zext"
4279 [(set (match_operand:DI 0 "register_operand" "=r")
4281 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4283 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4284 [(set_attr "type" "imovx")
4285 (set_attr "mode" "SI")])
4287 ;; Conversions between float and double.
4289 ;; These are all no-ops in the model used for the 80387. So just
4292 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4293 (define_insn "*dummy_extendsfdf2"
4294 [(set (match_operand:DF 0 "push_operand" "=<")
4295 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4300 [(set (match_operand:DF 0 "push_operand" "")
4301 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4303 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4304 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4306 (define_insn "*dummy_extendsfxf2"
4307 [(set (match_operand:XF 0 "push_operand" "=<")
4308 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4313 [(set (match_operand:XF 0 "push_operand" "")
4314 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4316 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4317 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4318 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4321 [(set (match_operand:XF 0 "push_operand" "")
4322 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4324 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4325 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4326 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4328 (define_expand "extendsfdf2"
4329 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4330 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4331 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4333 /* ??? Needed for compress_float_constant since all fp constants
4334 are LEGITIMATE_CONSTANT_P. */
4335 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4337 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4338 && standard_80387_constant_p (operands[1]) > 0)
4340 operands[1] = simplify_const_unary_operation
4341 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4342 emit_move_insn_1 (operands[0], operands[1]);
4345 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4349 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4351 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4353 We do the conversion post reload to avoid producing of 128bit spills
4354 that might lead to ICE on 32bit target. The sequence unlikely combine
4357 [(set (match_operand:DF 0 "register_operand" "")
4359 (match_operand:SF 1 "nonimmediate_operand" "")))]
4360 "TARGET_USE_VECTOR_FP_CONVERTS
4361 && optimize_insn_for_speed_p ()
4362 && reload_completed && SSE_REG_P (operands[0])"
4367 (parallel [(const_int 0) (const_int 1)]))))]
4369 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4370 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4371 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4372 Try to avoid move when unpacking can be done in source. */
4373 if (REG_P (operands[1]))
4375 /* If it is unsafe to overwrite upper half of source, we need
4376 to move to destination and unpack there. */
4377 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4378 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4379 && true_regnum (operands[0]) != true_regnum (operands[1]))
4381 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4382 emit_move_insn (tmp, operands[1]);
4385 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4386 emit_insn (gen_vec_interleave_lowv4sf (operands[3], operands[3],
4390 emit_insn (gen_vec_setv4sf_0 (operands[3],
4391 CONST0_RTX (V4SFmode), operands[1]));
4394 (define_insn "*extendsfdf2_mixed"
4395 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4397 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4398 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4400 switch (which_alternative)
4404 return output_387_reg_move (insn, operands);
4407 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4413 [(set_attr "type" "fmov,fmov,ssecvt")
4414 (set_attr "prefix" "orig,orig,maybe_vex")
4415 (set_attr "mode" "SF,XF,DF")])
4417 (define_insn "*extendsfdf2_sse"
4418 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4419 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4420 "TARGET_SSE2 && TARGET_SSE_MATH"
4421 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4422 [(set_attr "type" "ssecvt")
4423 (set_attr "prefix" "maybe_vex")
4424 (set_attr "mode" "DF")])
4426 (define_insn "*extendsfdf2_i387"
4427 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4428 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4430 "* return output_387_reg_move (insn, operands);"
4431 [(set_attr "type" "fmov")
4432 (set_attr "mode" "SF,XF")])
4434 (define_expand "extend<mode>xf2"
4435 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4436 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4439 /* ??? Needed for compress_float_constant since all fp constants
4440 are LEGITIMATE_CONSTANT_P. */
4441 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4443 if (standard_80387_constant_p (operands[1]) > 0)
4445 operands[1] = simplify_const_unary_operation
4446 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4447 emit_move_insn_1 (operands[0], operands[1]);
4450 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4454 (define_insn "*extend<mode>xf2_i387"
4455 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4457 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4459 "* return output_387_reg_move (insn, operands);"
4460 [(set_attr "type" "fmov")
4461 (set_attr "mode" "<MODE>,XF")])
4463 ;; %%% This seems bad bad news.
4464 ;; This cannot output into an f-reg because there is no way to be sure
4465 ;; of truncating in that case. Otherwise this is just like a simple move
4466 ;; insn. So we pretend we can output to a reg in order to get better
4467 ;; register preferencing, but we really use a stack slot.
4469 ;; Conversion from DFmode to SFmode.
4471 (define_expand "truncdfsf2"
4472 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4474 (match_operand:DF 1 "nonimmediate_operand" "")))]
4475 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4477 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4479 else if (flag_unsafe_math_optimizations)
4483 enum ix86_stack_slot slot = (virtuals_instantiated
4486 rtx temp = assign_386_stack_local (SFmode, slot);
4487 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4492 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4494 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4496 We do the conversion post reload to avoid producing of 128bit spills
4497 that might lead to ICE on 32bit target. The sequence unlikely combine
4500 [(set (match_operand:SF 0 "register_operand" "")
4502 (match_operand:DF 1 "nonimmediate_operand" "")))]
4503 "TARGET_USE_VECTOR_FP_CONVERTS
4504 && optimize_insn_for_speed_p ()
4505 && reload_completed && SSE_REG_P (operands[0])"
4508 (float_truncate:V2SF
4512 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4513 operands[3] = CONST0_RTX (V2SFmode);
4514 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4515 /* Use movsd for loading from memory, unpcklpd for registers.
4516 Try to avoid move when unpacking can be done in source, or SSE3
4517 movddup is available. */
4518 if (REG_P (operands[1]))
4521 && true_regnum (operands[0]) != true_regnum (operands[1])
4522 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4523 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4525 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4526 emit_move_insn (tmp, operands[1]);
4529 else if (!TARGET_SSE3)
4530 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4531 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4534 emit_insn (gen_sse2_loadlpd (operands[4],
4535 CONST0_RTX (V2DFmode), operands[1]));
4538 (define_expand "truncdfsf2_with_temp"
4539 [(parallel [(set (match_operand:SF 0 "" "")
4540 (float_truncate:SF (match_operand:DF 1 "" "")))
4541 (clobber (match_operand:SF 2 "" ""))])]
4544 (define_insn "*truncdfsf_fast_mixed"
4545 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4547 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4548 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4550 switch (which_alternative)
4553 return output_387_reg_move (insn, operands);
4555 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4560 [(set_attr "type" "fmov,ssecvt")
4561 (set_attr "prefix" "orig,maybe_vex")
4562 (set_attr "mode" "SF")])
4564 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4565 ;; because nothing we do here is unsafe.
4566 (define_insn "*truncdfsf_fast_sse"
4567 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4569 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4570 "TARGET_SSE2 && TARGET_SSE_MATH"
4571 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4572 [(set_attr "type" "ssecvt")
4573 (set_attr "prefix" "maybe_vex")
4574 (set_attr "mode" "SF")])
4576 (define_insn "*truncdfsf_fast_i387"
4577 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4579 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4580 "TARGET_80387 && flag_unsafe_math_optimizations"
4581 "* return output_387_reg_move (insn, operands);"
4582 [(set_attr "type" "fmov")
4583 (set_attr "mode" "SF")])
4585 (define_insn "*truncdfsf_mixed"
4586 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4588 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4589 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4590 "TARGET_MIX_SSE_I387"
4592 switch (which_alternative)
4595 return output_387_reg_move (insn, operands);
4597 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4603 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4604 (set_attr "unit" "*,*,i387,i387,i387")
4605 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4606 (set_attr "mode" "SF")])
4608 (define_insn "*truncdfsf_i387"
4609 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4611 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4612 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4615 switch (which_alternative)
4618 return output_387_reg_move (insn, operands);
4624 [(set_attr "type" "fmov,multi,multi,multi")
4625 (set_attr "unit" "*,i387,i387,i387")
4626 (set_attr "mode" "SF")])
4628 (define_insn "*truncdfsf2_i387_1"
4629 [(set (match_operand:SF 0 "memory_operand" "=m")
4631 (match_operand:DF 1 "register_operand" "f")))]
4633 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4634 && !TARGET_MIX_SSE_I387"
4635 "* return output_387_reg_move (insn, operands);"
4636 [(set_attr "type" "fmov")
4637 (set_attr "mode" "SF")])
4640 [(set (match_operand:SF 0 "register_operand" "")
4642 (match_operand:DF 1 "fp_register_operand" "")))
4643 (clobber (match_operand 2 "" ""))]
4645 [(set (match_dup 2) (match_dup 1))
4646 (set (match_dup 0) (match_dup 2))]
4648 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4651 ;; Conversion from XFmode to {SF,DF}mode
4653 (define_expand "truncxf<mode>2"
4654 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4655 (float_truncate:MODEF
4656 (match_operand:XF 1 "register_operand" "")))
4657 (clobber (match_dup 2))])]
4660 if (flag_unsafe_math_optimizations)
4662 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4663 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4664 if (reg != operands[0])
4665 emit_move_insn (operands[0], reg);
4670 enum ix86_stack_slot slot = (virtuals_instantiated
4673 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4677 (define_insn "*truncxfsf2_mixed"
4678 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4680 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4681 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4684 gcc_assert (!which_alternative);
4685 return output_387_reg_move (insn, operands);
4687 [(set_attr "type" "fmov,multi,multi,multi")
4688 (set_attr "unit" "*,i387,i387,i387")
4689 (set_attr "mode" "SF")])
4691 (define_insn "*truncxfdf2_mixed"
4692 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4694 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4695 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4698 gcc_assert (!which_alternative);
4699 return output_387_reg_move (insn, operands);
4701 [(set_attr "type" "fmov,multi,multi,multi")
4702 (set_attr "unit" "*,i387,i387,i387")
4703 (set_attr "mode" "DF")])
4705 (define_insn "truncxf<mode>2_i387_noop"
4706 [(set (match_operand:MODEF 0 "register_operand" "=f")
4707 (float_truncate:MODEF
4708 (match_operand:XF 1 "register_operand" "f")))]
4709 "TARGET_80387 && flag_unsafe_math_optimizations"
4710 "* return output_387_reg_move (insn, operands);"
4711 [(set_attr "type" "fmov")
4712 (set_attr "mode" "<MODE>")])
4714 (define_insn "*truncxf<mode>2_i387"
4715 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4716 (float_truncate:MODEF
4717 (match_operand:XF 1 "register_operand" "f")))]
4719 "* return output_387_reg_move (insn, operands);"
4720 [(set_attr "type" "fmov")
4721 (set_attr "mode" "<MODE>")])
4724 [(set (match_operand:MODEF 0 "register_operand" "")
4725 (float_truncate:MODEF
4726 (match_operand:XF 1 "register_operand" "")))
4727 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4728 "TARGET_80387 && reload_completed"
4729 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4730 (set (match_dup 0) (match_dup 2))]
4734 [(set (match_operand:MODEF 0 "memory_operand" "")
4735 (float_truncate:MODEF
4736 (match_operand:XF 1 "register_operand" "")))
4737 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4739 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4742 ;; Signed conversion to DImode.
4744 (define_expand "fix_truncxfdi2"
4745 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4746 (fix:DI (match_operand:XF 1 "register_operand" "")))
4747 (clobber (reg:CC FLAGS_REG))])]
4752 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4757 (define_expand "fix_trunc<mode>di2"
4758 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4759 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4760 (clobber (reg:CC FLAGS_REG))])]
4761 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4764 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4766 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4769 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4771 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4772 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4773 if (out != operands[0])
4774 emit_move_insn (operands[0], out);
4779 ;; Signed conversion to SImode.
4781 (define_expand "fix_truncxfsi2"
4782 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4783 (fix:SI (match_operand:XF 1 "register_operand" "")))
4784 (clobber (reg:CC FLAGS_REG))])]
4789 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4794 (define_expand "fix_trunc<mode>si2"
4795 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4796 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4797 (clobber (reg:CC FLAGS_REG))])]
4798 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4801 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4803 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4806 if (SSE_FLOAT_MODE_P (<MODE>mode))
4808 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4809 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4810 if (out != operands[0])
4811 emit_move_insn (operands[0], out);
4816 ;; Signed conversion to HImode.
4818 (define_expand "fix_trunc<mode>hi2"
4819 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4820 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4821 (clobber (reg:CC FLAGS_REG))])]
4823 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4827 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
4832 ;; Unsigned conversion to SImode.
4834 (define_expand "fixuns_trunc<mode>si2"
4836 [(set (match_operand:SI 0 "register_operand" "")
4838 (match_operand:MODEF 1 "nonimmediate_operand" "")))
4840 (clobber (match_scratch:<ssevecmode> 3 ""))
4841 (clobber (match_scratch:<ssevecmode> 4 ""))])]
4842 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
4844 enum machine_mode mode = <MODE>mode;
4845 enum machine_mode vecmode = <ssevecmode>mode;
4846 REAL_VALUE_TYPE TWO31r;
4849 if (optimize_insn_for_size_p ())
4852 real_ldexp (&TWO31r, &dconst1, 31);
4853 two31 = const_double_from_real_value (TWO31r, mode);
4854 two31 = ix86_build_const_vector (mode, true, two31);
4855 operands[2] = force_reg (vecmode, two31);
4858 (define_insn_and_split "*fixuns_trunc<mode>_1"
4859 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
4861 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
4862 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
4863 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
4864 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
4865 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
4866 && optimize_function_for_speed_p (cfun)"
4868 "&& reload_completed"
4871 ix86_split_convert_uns_si_sse (operands);
4875 ;; Unsigned conversion to HImode.
4876 ;; Without these patterns, we'll try the unsigned SI conversion which
4877 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
4879 (define_expand "fixuns_trunc<mode>hi2"
4881 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
4882 (set (match_operand:HI 0 "nonimmediate_operand" "")
4883 (subreg:HI (match_dup 2) 0))]
4884 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
4885 "operands[2] = gen_reg_rtx (SImode);")
4887 ;; When SSE is available, it is always faster to use it!
4888 (define_insn "fix_trunc<mode>di_sse"
4889 [(set (match_operand:DI 0 "register_operand" "=r,r")
4890 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4891 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
4892 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4893 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
4894 [(set_attr "type" "sseicvt")
4895 (set_attr "prefix" "maybe_vex")
4896 (set_attr "prefix_rex" "1")
4897 (set_attr "mode" "<MODE>")
4898 (set_attr "athlon_decode" "double,vector")
4899 (set_attr "amdfam10_decode" "double,double")])
4901 (define_insn "fix_trunc<mode>si_sse"
4902 [(set (match_operand:SI 0 "register_operand" "=r,r")
4903 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
4904 "SSE_FLOAT_MODE_P (<MODE>mode)
4905 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
4906 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
4907 [(set_attr "type" "sseicvt")
4908 (set_attr "prefix" "maybe_vex")
4909 (set_attr "mode" "<MODE>")
4910 (set_attr "athlon_decode" "double,vector")
4911 (set_attr "amdfam10_decode" "double,double")])
4913 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
4915 [(set (match_operand:MODEF 0 "register_operand" "")
4916 (match_operand:MODEF 1 "memory_operand" ""))
4917 (set (match_operand:SSEMODEI24 2 "register_operand" "")
4918 (fix:SSEMODEI24 (match_dup 0)))]
4919 "TARGET_SHORTEN_X87_SSE
4920 && peep2_reg_dead_p (2, operands[0])"
4921 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
4924 ;; Avoid vector decoded forms of the instruction.
4926 [(match_scratch:DF 2 "Y2")
4927 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4928 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
4929 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4930 [(set (match_dup 2) (match_dup 1))
4931 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4935 [(match_scratch:SF 2 "x")
4936 (set (match_operand:SSEMODEI24 0 "register_operand" "")
4937 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
4938 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
4939 [(set (match_dup 2) (match_dup 1))
4940 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
4943 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
4944 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
4945 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
4946 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4948 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4949 && (TARGET_64BIT || <MODE>mode != DImode))
4951 && can_create_pseudo_p ()"
4956 if (memory_operand (operands[0], VOIDmode))
4957 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
4960 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
4961 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
4967 [(set_attr "type" "fisttp")
4968 (set_attr "mode" "<MODE>")])
4970 (define_insn "fix_trunc<mode>_i387_fisttp"
4971 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
4972 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
4973 (clobber (match_scratch:XF 2 "=&1f"))]
4974 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4976 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4977 && (TARGET_64BIT || <MODE>mode != DImode))
4978 && TARGET_SSE_MATH)"
4979 "* return output_fix_trunc (insn, operands, 1);"
4980 [(set_attr "type" "fisttp")
4981 (set_attr "mode" "<MODE>")])
4983 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
4984 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
4985 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
4986 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
4987 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
4988 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
4990 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
4991 && (TARGET_64BIT || <MODE>mode != DImode))
4992 && TARGET_SSE_MATH)"
4994 [(set_attr "type" "fisttp")
4995 (set_attr "mode" "<MODE>")])
4998 [(set (match_operand:X87MODEI 0 "register_operand" "")
4999 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5000 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5001 (clobber (match_scratch 3 ""))]
5003 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5004 (clobber (match_dup 3))])
5005 (set (match_dup 0) (match_dup 2))]
5009 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5010 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5011 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5012 (clobber (match_scratch 3 ""))]
5014 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5015 (clobber (match_dup 3))])]
5018 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5019 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5020 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5021 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5022 ;; function in i386.c.
5023 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5024 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5025 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5026 (clobber (reg:CC FLAGS_REG))]
5027 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5029 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5030 && (TARGET_64BIT || <MODE>mode != DImode))
5031 && can_create_pseudo_p ()"
5036 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5038 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5039 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5040 if (memory_operand (operands[0], VOIDmode))
5041 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5042 operands[2], operands[3]));
5045 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5046 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5047 operands[2], operands[3],
5052 [(set_attr "type" "fistp")
5053 (set_attr "i387_cw" "trunc")
5054 (set_attr "mode" "<MODE>")])
5056 (define_insn "fix_truncdi_i387"
5057 [(set (match_operand:DI 0 "memory_operand" "=m")
5058 (fix:DI (match_operand 1 "register_operand" "f")))
5059 (use (match_operand:HI 2 "memory_operand" "m"))
5060 (use (match_operand:HI 3 "memory_operand" "m"))
5061 (clobber (match_scratch:XF 4 "=&1f"))]
5062 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5064 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5065 "* return output_fix_trunc (insn, operands, 0);"
5066 [(set_attr "type" "fistp")
5067 (set_attr "i387_cw" "trunc")
5068 (set_attr "mode" "DI")])
5070 (define_insn "fix_truncdi_i387_with_temp"
5071 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5072 (fix:DI (match_operand 1 "register_operand" "f,f")))
5073 (use (match_operand:HI 2 "memory_operand" "m,m"))
5074 (use (match_operand:HI 3 "memory_operand" "m,m"))
5075 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5076 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5077 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5079 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5081 [(set_attr "type" "fistp")
5082 (set_attr "i387_cw" "trunc")
5083 (set_attr "mode" "DI")])
5086 [(set (match_operand:DI 0 "register_operand" "")
5087 (fix:DI (match_operand 1 "register_operand" "")))
5088 (use (match_operand:HI 2 "memory_operand" ""))
5089 (use (match_operand:HI 3 "memory_operand" ""))
5090 (clobber (match_operand:DI 4 "memory_operand" ""))
5091 (clobber (match_scratch 5 ""))]
5093 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5096 (clobber (match_dup 5))])
5097 (set (match_dup 0) (match_dup 4))]
5101 [(set (match_operand:DI 0 "memory_operand" "")
5102 (fix:DI (match_operand 1 "register_operand" "")))
5103 (use (match_operand:HI 2 "memory_operand" ""))
5104 (use (match_operand:HI 3 "memory_operand" ""))
5105 (clobber (match_operand:DI 4 "memory_operand" ""))
5106 (clobber (match_scratch 5 ""))]
5108 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5111 (clobber (match_dup 5))])]
5114 (define_insn "fix_trunc<mode>_i387"
5115 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5116 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5117 (use (match_operand:HI 2 "memory_operand" "m"))
5118 (use (match_operand:HI 3 "memory_operand" "m"))]
5119 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5121 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5122 "* return output_fix_trunc (insn, operands, 0);"
5123 [(set_attr "type" "fistp")
5124 (set_attr "i387_cw" "trunc")
5125 (set_attr "mode" "<MODE>")])
5127 (define_insn "fix_trunc<mode>_i387_with_temp"
5128 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5129 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5130 (use (match_operand:HI 2 "memory_operand" "m,m"))
5131 (use (match_operand:HI 3 "memory_operand" "m,m"))
5132 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5133 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5135 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5137 [(set_attr "type" "fistp")
5138 (set_attr "i387_cw" "trunc")
5139 (set_attr "mode" "<MODE>")])
5142 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5143 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5144 (use (match_operand:HI 2 "memory_operand" ""))
5145 (use (match_operand:HI 3 "memory_operand" ""))
5146 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5148 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5150 (use (match_dup 3))])
5151 (set (match_dup 0) (match_dup 4))]
5155 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5156 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5157 (use (match_operand:HI 2 "memory_operand" ""))
5158 (use (match_operand:HI 3 "memory_operand" ""))
5159 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5161 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5163 (use (match_dup 3))])]
5166 (define_insn "x86_fnstcw_1"
5167 [(set (match_operand:HI 0 "memory_operand" "=m")
5168 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5171 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5172 (set_attr "mode" "HI")
5173 (set_attr "unit" "i387")])
5175 (define_insn "x86_fldcw_1"
5176 [(set (reg:HI FPCR_REG)
5177 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5180 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5181 (set_attr "mode" "HI")
5182 (set_attr "unit" "i387")
5183 (set_attr "athlon_decode" "vector")
5184 (set_attr "amdfam10_decode" "vector")])
5186 ;; Conversion between fixed point and floating point.
5188 ;; Even though we only accept memory inputs, the backend _really_
5189 ;; wants to be able to do this between registers.
5191 (define_expand "floathi<mode>2"
5192 [(set (match_operand:X87MODEF 0 "register_operand" "")
5193 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5195 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5196 || TARGET_MIX_SSE_I387)"
5199 ;; Pre-reload splitter to add memory clobber to the pattern.
5200 (define_insn_and_split "*floathi<mode>2_1"
5201 [(set (match_operand:X87MODEF 0 "register_operand" "")
5202 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5204 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5205 || TARGET_MIX_SSE_I387)
5206 && can_create_pseudo_p ()"
5209 [(parallel [(set (match_dup 0)
5210 (float:X87MODEF (match_dup 1)))
5211 (clobber (match_dup 2))])]
5212 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5214 (define_insn "*floathi<mode>2_i387_with_temp"
5215 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5216 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5217 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5219 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5220 || TARGET_MIX_SSE_I387)"
5222 [(set_attr "type" "fmov,multi")
5223 (set_attr "mode" "<MODE>")
5224 (set_attr "unit" "*,i387")
5225 (set_attr "fp_int_src" "true")])
5227 (define_insn "*floathi<mode>2_i387"
5228 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5229 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5231 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5232 || TARGET_MIX_SSE_I387)"
5234 [(set_attr "type" "fmov")
5235 (set_attr "mode" "<MODE>")
5236 (set_attr "fp_int_src" "true")])
5239 [(set (match_operand:X87MODEF 0 "register_operand" "")
5240 (float:X87MODEF (match_operand:HI 1 "register_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 2) (match_dup 1))
5247 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5251 [(set (match_operand:X87MODEF 0 "register_operand" "")
5252 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5253 (clobber (match_operand:HI 2 "memory_operand" ""))]
5255 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5256 || TARGET_MIX_SSE_I387)
5257 && reload_completed"
5258 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5261 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5262 [(set (match_operand:X87MODEF 0 "register_operand" "")
5264 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5266 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5267 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5269 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5270 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5271 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5273 rtx reg = gen_reg_rtx (XFmode);
5276 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5278 if (<X87MODEF:MODE>mode == SFmode)
5279 insn = gen_truncxfsf2 (operands[0], reg);
5280 else if (<X87MODEF:MODE>mode == DFmode)
5281 insn = gen_truncxfdf2 (operands[0], reg);
5290 ;; Pre-reload splitter to add memory clobber to the pattern.
5291 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5292 [(set (match_operand:X87MODEF 0 "register_operand" "")
5293 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5295 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5296 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5297 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5298 || TARGET_MIX_SSE_I387))
5299 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5300 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5301 && ((<SSEMODEI24:MODE>mode == SImode
5302 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5303 && optimize_function_for_speed_p (cfun)
5304 && flag_trapping_math)
5305 || !(TARGET_INTER_UNIT_CONVERSIONS
5306 || optimize_function_for_size_p (cfun)))))
5307 && can_create_pseudo_p ()"
5310 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5311 (clobber (match_dup 2))])]
5313 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5315 /* Avoid store forwarding (partial memory) stall penalty
5316 by passing DImode value through XMM registers. */
5317 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5318 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5319 && optimize_function_for_speed_p (cfun))
5321 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5328 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5329 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5331 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5332 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5333 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5334 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5336 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5337 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5338 (set_attr "unit" "*,i387,*,*,*")
5339 (set_attr "athlon_decode" "*,*,double,direct,double")
5340 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5341 (set_attr "fp_int_src" "true")])
5343 (define_insn "*floatsi<mode>2_vector_mixed"
5344 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5345 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5346 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5347 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5351 [(set_attr "type" "fmov,sseicvt")
5352 (set_attr "mode" "<MODE>,<ssevecmode>")
5353 (set_attr "unit" "i387,*")
5354 (set_attr "athlon_decode" "*,direct")
5355 (set_attr "amdfam10_decode" "*,double")
5356 (set_attr "fp_int_src" "true")])
5358 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5359 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5361 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5362 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5363 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5364 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5366 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5367 (set_attr "mode" "<MODEF:MODE>")
5368 (set_attr "unit" "*,i387,*,*")
5369 (set_attr "athlon_decode" "*,*,double,direct")
5370 (set_attr "amdfam10_decode" "*,*,vector,double")
5371 (set_attr "fp_int_src" "true")])
5374 [(set (match_operand:MODEF 0 "register_operand" "")
5375 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5376 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5377 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5378 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5379 && TARGET_INTER_UNIT_CONVERSIONS
5381 && (SSE_REG_P (operands[0])
5382 || (GET_CODE (operands[0]) == SUBREG
5383 && SSE_REG_P (operands[0])))"
5384 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5388 [(set (match_operand:MODEF 0 "register_operand" "")
5389 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5390 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5391 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5392 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5393 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5395 && (SSE_REG_P (operands[0])
5396 || (GET_CODE (operands[0]) == SUBREG
5397 && SSE_REG_P (operands[0])))"
5398 [(set (match_dup 2) (match_dup 1))
5399 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5402 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5403 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5405 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5406 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5407 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5408 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5411 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5412 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5413 [(set_attr "type" "fmov,sseicvt,sseicvt")
5414 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5415 (set_attr "mode" "<MODEF:MODE>")
5416 (set (attr "prefix_rex")
5418 (and (eq_attr "prefix" "maybe_vex")
5419 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5421 (const_string "*")))
5422 (set_attr "unit" "i387,*,*")
5423 (set_attr "athlon_decode" "*,double,direct")
5424 (set_attr "amdfam10_decode" "*,vector,double")
5425 (set_attr "fp_int_src" "true")])
5427 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5428 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5430 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5431 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5432 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5433 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5436 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5437 [(set_attr "type" "fmov,sseicvt")
5438 (set_attr "prefix" "orig,maybe_vex")
5439 (set_attr "mode" "<MODEF:MODE>")
5440 (set (attr "prefix_rex")
5442 (and (eq_attr "prefix" "maybe_vex")
5443 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5445 (const_string "*")))
5446 (set_attr "athlon_decode" "*,direct")
5447 (set_attr "amdfam10_decode" "*,double")
5448 (set_attr "fp_int_src" "true")])
5450 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5451 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5453 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5454 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5455 "TARGET_SSE2 && TARGET_SSE_MATH
5456 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5458 [(set_attr "type" "sseicvt")
5459 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5460 (set_attr "athlon_decode" "double,direct,double")
5461 (set_attr "amdfam10_decode" "vector,double,double")
5462 (set_attr "fp_int_src" "true")])
5464 (define_insn "*floatsi<mode>2_vector_sse"
5465 [(set (match_operand:MODEF 0 "register_operand" "=x")
5466 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5467 "TARGET_SSE2 && TARGET_SSE_MATH
5468 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5470 [(set_attr "type" "sseicvt")
5471 (set_attr "mode" "<MODE>")
5472 (set_attr "athlon_decode" "direct")
5473 (set_attr "amdfam10_decode" "double")
5474 (set_attr "fp_int_src" "true")])
5477 [(set (match_operand:MODEF 0 "register_operand" "")
5478 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5479 (clobber (match_operand:SI 2 "memory_operand" ""))]
5480 "TARGET_SSE2 && TARGET_SSE_MATH
5481 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5483 && (SSE_REG_P (operands[0])
5484 || (GET_CODE (operands[0]) == SUBREG
5485 && SSE_REG_P (operands[0])))"
5488 rtx op1 = operands[1];
5490 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5492 if (GET_CODE (op1) == SUBREG)
5493 op1 = SUBREG_REG (op1);
5495 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5497 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5498 emit_insn (gen_sse2_loadld (operands[4],
5499 CONST0_RTX (V4SImode), operands[1]));
5501 /* We can ignore possible trapping value in the
5502 high part of SSE register for non-trapping math. */
5503 else if (SSE_REG_P (op1) && !flag_trapping_math)
5504 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5507 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5508 emit_move_insn (operands[2], operands[1]);
5509 emit_insn (gen_sse2_loadld (operands[4],
5510 CONST0_RTX (V4SImode), operands[2]));
5513 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5518 [(set (match_operand:MODEF 0 "register_operand" "")
5519 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5520 (clobber (match_operand:SI 2 "memory_operand" ""))]
5521 "TARGET_SSE2 && TARGET_SSE_MATH
5522 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5524 && (SSE_REG_P (operands[0])
5525 || (GET_CODE (operands[0]) == SUBREG
5526 && SSE_REG_P (operands[0])))"
5529 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5531 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5533 emit_insn (gen_sse2_loadld (operands[4],
5534 CONST0_RTX (V4SImode), operands[1]));
5536 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5541 [(set (match_operand:MODEF 0 "register_operand" "")
5542 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5543 "TARGET_SSE2 && TARGET_SSE_MATH
5544 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5546 && (SSE_REG_P (operands[0])
5547 || (GET_CODE (operands[0]) == SUBREG
5548 && SSE_REG_P (operands[0])))"
5551 rtx op1 = operands[1];
5553 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5555 if (GET_CODE (op1) == SUBREG)
5556 op1 = SUBREG_REG (op1);
5558 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5560 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5561 emit_insn (gen_sse2_loadld (operands[4],
5562 CONST0_RTX (V4SImode), operands[1]));
5564 /* We can ignore possible trapping value in the
5565 high part of SSE register for non-trapping math. */
5566 else if (SSE_REG_P (op1) && !flag_trapping_math)
5567 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5571 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5576 [(set (match_operand:MODEF 0 "register_operand" "")
5577 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5578 "TARGET_SSE2 && TARGET_SSE_MATH
5579 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5581 && (SSE_REG_P (operands[0])
5582 || (GET_CODE (operands[0]) == SUBREG
5583 && SSE_REG_P (operands[0])))"
5586 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5588 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5590 emit_insn (gen_sse2_loadld (operands[4],
5591 CONST0_RTX (V4SImode), operands[1]));
5593 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5597 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5598 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5600 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5601 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5602 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5603 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5605 [(set_attr "type" "sseicvt")
5606 (set_attr "mode" "<MODEF:MODE>")
5607 (set_attr "athlon_decode" "double,direct")
5608 (set_attr "amdfam10_decode" "vector,double")
5609 (set_attr "fp_int_src" "true")])
5611 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5612 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5614 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5615 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5616 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5617 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5618 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5619 [(set_attr "type" "sseicvt")
5620 (set_attr "prefix" "maybe_vex")
5621 (set_attr "mode" "<MODEF:MODE>")
5622 (set (attr "prefix_rex")
5624 (and (eq_attr "prefix" "maybe_vex")
5625 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5627 (const_string "*")))
5628 (set_attr "athlon_decode" "double,direct")
5629 (set_attr "amdfam10_decode" "vector,double")
5630 (set_attr "fp_int_src" "true")])
5633 [(set (match_operand:MODEF 0 "register_operand" "")
5634 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5635 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5636 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5637 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5638 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5640 && (SSE_REG_P (operands[0])
5641 || (GET_CODE (operands[0]) == SUBREG
5642 && SSE_REG_P (operands[0])))"
5643 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5646 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5647 [(set (match_operand:MODEF 0 "register_operand" "=x")
5649 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5650 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5651 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5652 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5653 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5654 [(set_attr "type" "sseicvt")
5655 (set_attr "prefix" "maybe_vex")
5656 (set_attr "mode" "<MODEF:MODE>")
5657 (set (attr "prefix_rex")
5659 (and (eq_attr "prefix" "maybe_vex")
5660 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5662 (const_string "*")))
5663 (set_attr "athlon_decode" "direct")
5664 (set_attr "amdfam10_decode" "double")
5665 (set_attr "fp_int_src" "true")])
5668 [(set (match_operand:MODEF 0 "register_operand" "")
5669 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5670 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5671 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5672 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5673 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5675 && (SSE_REG_P (operands[0])
5676 || (GET_CODE (operands[0]) == SUBREG
5677 && SSE_REG_P (operands[0])))"
5678 [(set (match_dup 2) (match_dup 1))
5679 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5683 [(set (match_operand:MODEF 0 "register_operand" "")
5684 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5685 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5686 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5687 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5689 && (SSE_REG_P (operands[0])
5690 || (GET_CODE (operands[0]) == SUBREG
5691 && SSE_REG_P (operands[0])))"
5692 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5695 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5696 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5698 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5699 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5701 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5705 [(set_attr "type" "fmov,multi")
5706 (set_attr "mode" "<X87MODEF:MODE>")
5707 (set_attr "unit" "*,i387")
5708 (set_attr "fp_int_src" "true")])
5710 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5711 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5713 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5715 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5717 [(set_attr "type" "fmov")
5718 (set_attr "mode" "<X87MODEF:MODE>")
5719 (set_attr "fp_int_src" "true")])
5722 [(set (match_operand:X87MODEF 0 "register_operand" "")
5723 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5724 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5726 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5728 && FP_REG_P (operands[0])"
5729 [(set (match_dup 2) (match_dup 1))
5730 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5734 [(set (match_operand:X87MODEF 0 "register_operand" "")
5735 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5736 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5738 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5740 && FP_REG_P (operands[0])"
5741 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5744 ;; Avoid store forwarding (partial memory) stall penalty
5745 ;; by passing DImode value through XMM registers. */
5747 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5748 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5750 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5751 (clobber (match_scratch:V4SI 3 "=X,x"))
5752 (clobber (match_scratch:V4SI 4 "=X,x"))
5753 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5754 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5755 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5756 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5758 [(set_attr "type" "multi")
5759 (set_attr "mode" "<X87MODEF:MODE>")
5760 (set_attr "unit" "i387")
5761 (set_attr "fp_int_src" "true")])
5764 [(set (match_operand:X87MODEF 0 "register_operand" "")
5765 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5766 (clobber (match_scratch:V4SI 3 ""))
5767 (clobber (match_scratch:V4SI 4 ""))
5768 (clobber (match_operand:DI 2 "memory_operand" ""))]
5769 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5770 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5771 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5773 && FP_REG_P (operands[0])"
5774 [(set (match_dup 2) (match_dup 3))
5775 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5777 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5778 Assemble the 64-bit DImode value in an xmm register. */
5779 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5780 gen_rtx_SUBREG (SImode, operands[1], 0)));
5781 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5782 gen_rtx_SUBREG (SImode, operands[1], 4)));
5783 emit_insn (gen_vec_interleave_lowv4si (operands[3], operands[3],
5786 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5790 [(set (match_operand:X87MODEF 0 "register_operand" "")
5791 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5792 (clobber (match_scratch:V4SI 3 ""))
5793 (clobber (match_scratch:V4SI 4 ""))
5794 (clobber (match_operand:DI 2 "memory_operand" ""))]
5795 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5796 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5797 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5799 && FP_REG_P (operands[0])"
5800 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5803 ;; Avoid store forwarding (partial memory) stall penalty by extending
5804 ;; SImode value to DImode through XMM register instead of pushing two
5805 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5806 ;; targets benefit from this optimization. Also note that fild
5807 ;; loads from memory only.
5809 (define_insn "*floatunssi<mode>2_1"
5810 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5811 (unsigned_float:X87MODEF
5812 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5813 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5814 (clobber (match_scratch:SI 3 "=X,x"))]
5816 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5819 [(set_attr "type" "multi")
5820 (set_attr "mode" "<MODE>")])
5823 [(set (match_operand:X87MODEF 0 "register_operand" "")
5824 (unsigned_float:X87MODEF
5825 (match_operand:SI 1 "register_operand" "")))
5826 (clobber (match_operand:DI 2 "memory_operand" ""))
5827 (clobber (match_scratch:SI 3 ""))]
5829 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5831 && reload_completed"
5832 [(set (match_dup 2) (match_dup 1))
5834 (float:X87MODEF (match_dup 2)))]
5835 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
5838 [(set (match_operand:X87MODEF 0 "register_operand" "")
5839 (unsigned_float:X87MODEF
5840 (match_operand:SI 1 "memory_operand" "")))
5841 (clobber (match_operand:DI 2 "memory_operand" ""))
5842 (clobber (match_scratch:SI 3 ""))]
5844 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5846 && reload_completed"
5847 [(set (match_dup 2) (match_dup 3))
5849 (float:X87MODEF (match_dup 2)))]
5851 emit_move_insn (operands[3], operands[1]);
5852 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
5855 (define_expand "floatunssi<mode>2"
5857 [(set (match_operand:X87MODEF 0 "register_operand" "")
5858 (unsigned_float:X87MODEF
5859 (match_operand:SI 1 "nonimmediate_operand" "")))
5860 (clobber (match_dup 2))
5861 (clobber (match_scratch:SI 3 ""))])]
5863 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5865 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
5867 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5869 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
5874 enum ix86_stack_slot slot = (virtuals_instantiated
5877 operands[2] = assign_386_stack_local (DImode, slot);
5881 (define_expand "floatunsdisf2"
5882 [(use (match_operand:SF 0 "register_operand" ""))
5883 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5884 "TARGET_64BIT && TARGET_SSE_MATH"
5885 "x86_emit_floatuns (operands); DONE;")
5887 (define_expand "floatunsdidf2"
5888 [(use (match_operand:DF 0 "register_operand" ""))
5889 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
5890 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
5891 && TARGET_SSE2 && TARGET_SSE_MATH"
5894 x86_emit_floatuns (operands);
5896 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
5902 (define_expand "add<mode>3"
5903 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
5904 (plus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
5905 (match_operand:SDWIM 2 "<general_operand>" "")))]
5907 "ix86_expand_binary_operator (PLUS, <MODE>mode, operands); DONE;")
5909 (define_insn_and_split "*add<dwi>3_doubleword"
5910 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
5912 (match_operand:<DWI> 1 "nonimmediate_operand" "%0,0")
5913 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
5914 (clobber (reg:CC FLAGS_REG))]
5915 "ix86_binary_operator_ok (PLUS, <DWI>mode, operands)"
5918 [(parallel [(set (reg:CC FLAGS_REG)
5919 (unspec:CC [(match_dup 1) (match_dup 2)]
5922 (plus:DWIH (match_dup 1) (match_dup 2)))])
5923 (parallel [(set (match_dup 3)
5927 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
5929 (clobber (reg:CC FLAGS_REG))])]
5930 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
5932 (define_insn "*add<mode>3_cc"
5933 [(set (reg:CC FLAGS_REG)
5935 [(match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
5936 (match_operand:SWI48 2 "<general_operand>" "r<i>,rm")]
5938 (set (match_operand:SWI48 0 "nonimmediate_operand" "=rm,r")
5939 (plus:SWI48 (match_dup 1) (match_dup 2)))]
5940 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5941 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
5942 [(set_attr "type" "alu")
5943 (set_attr "mode" "<MODE>")])
5945 (define_insn "addqi3_cc"
5946 [(set (reg:CC FLAGS_REG)
5948 [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
5949 (match_operand:QI 2 "general_operand" "qn,qm")]
5951 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
5952 (plus:QI (match_dup 1) (match_dup 2)))]
5953 "ix86_binary_operator_ok (PLUS, QImode, operands)"
5954 "add{b}\t{%2, %0|%0, %2}"
5955 [(set_attr "type" "alu")
5956 (set_attr "mode" "QI")])
5958 (define_insn "*lea_1"
5959 [(set (match_operand:DWIH 0 "register_operand" "=r")
5960 (match_operand:DWIH 1 "no_seg_address_operand" "p"))]
5962 "lea{<imodesuffix>}\t{%a1, %0|%0, %a1}"
5963 [(set_attr "type" "lea")
5964 (set_attr "mode" "<MODE>")])
5966 (define_insn "*lea_2"
5967 [(set (match_operand:SI 0 "register_operand" "=r")
5968 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
5970 "lea{l}\t{%a1, %0|%0, %a1}"
5971 [(set_attr "type" "lea")
5972 (set_attr "mode" "SI")])
5974 (define_insn "*lea_2_zext"
5975 [(set (match_operand:DI 0 "register_operand" "=r")
5977 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
5979 "lea{l}\t{%a1, %k0|%k0, %a1}"
5980 [(set_attr "type" "lea")
5981 (set_attr "mode" "SI")])
5983 (define_insn "*add<mode>_1"
5984 [(set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm,r,r")
5986 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0,r,r")
5987 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>,0,l<i>")))
5988 (clobber (reg:CC FLAGS_REG))]
5989 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
5991 switch (get_attr_type (insn))
5994 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
5995 return "lea{<imodesuffix>}\t{%a2, %0|%0, %a2}";
5998 gcc_assert (rtx_equal_p (operands[0], operands[1]));
5999 if (operands[2] == const1_rtx)
6000 return "inc{<imodesuffix>}\t%0";
6003 gcc_assert (operands[2] == constm1_rtx);
6004 return "dec{<imodesuffix>}\t%0";
6008 /* Use add as much as possible to replace lea for AGU optimization. */
6009 if (which_alternative == 2 && TARGET_OPT_AGU)
6010 return "add{<imodesuffix>}\t{%1, %0|%0, %1}";
6012 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6013 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6014 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6016 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6020 (cond [(and (eq_attr "alternative" "2")
6021 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6022 (const_string "lea")
6023 (eq_attr "alternative" "3")
6024 (const_string "lea")
6025 ; Current assemblers are broken and do not allow @GOTOFF in
6026 ; ought but a memory context.
6027 (match_operand:SWI48 2 "pic_symbolic_operand" "")
6028 (const_string "lea")
6029 (match_operand:SWI48 2 "incdec_operand" "")
6030 (const_string "incdec")
6032 (const_string "alu")))
6033 (set (attr "length_immediate")
6035 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6037 (const_string "*")))
6038 (set_attr "mode" "<MODE>")])
6040 ;; It may seem that nonimmediate operand is proper one for operand 1.
6041 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6042 ;; we take care in ix86_binary_operator_ok to not allow two memory
6043 ;; operands so proper swapping will be done in reload. This allow
6044 ;; patterns constructed from addsi_1 to match.
6046 (define_insn "*addsi_1_zext"
6047 [(set (match_operand:DI 0 "register_operand" "=r,r")
6049 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6050 (match_operand:SI 2 "general_operand" "g,li"))))
6051 (clobber (reg:CC FLAGS_REG))]
6052 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6054 switch (get_attr_type (insn))
6057 operands[2] = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
6058 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6061 if (operands[2] == const1_rtx)
6062 return "inc{l}\t%k0";
6065 gcc_assert (operands[2] == constm1_rtx);
6066 return "dec{l}\t%k0";
6070 if (x86_maybe_negate_const_int (&operands[2], SImode))
6071 return "sub{l}\t{%2, %k0|%k0, %2}";
6073 return "add{l}\t{%2, %k0|%k0, %2}";
6077 (cond [(eq_attr "alternative" "1")
6078 (const_string "lea")
6079 ; Current assemblers are broken and do not allow @GOTOFF in
6080 ; ought but a memory context.
6081 (match_operand:SI 2 "pic_symbolic_operand" "")
6082 (const_string "lea")
6083 (match_operand:SI 2 "incdec_operand" "")
6084 (const_string "incdec")
6086 (const_string "alu")))
6087 (set (attr "length_immediate")
6089 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6091 (const_string "*")))
6092 (set_attr "mode" "SI")])
6094 (define_insn "*addhi_1"
6095 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6096 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6097 (match_operand:HI 2 "general_operand" "rn,rm")))
6098 (clobber (reg:CC FLAGS_REG))]
6099 "TARGET_PARTIAL_REG_STALL
6100 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6102 switch (get_attr_type (insn))
6105 if (operands[2] == const1_rtx)
6106 return "inc{w}\t%0";
6109 gcc_assert (operands[2] == constm1_rtx);
6110 return "dec{w}\t%0";
6114 if (x86_maybe_negate_const_int (&operands[2], HImode))
6115 return "sub{w}\t{%2, %0|%0, %2}";
6117 return "add{w}\t{%2, %0|%0, %2}";
6121 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6122 (const_string "incdec")
6123 (const_string "alu")))
6124 (set (attr "length_immediate")
6126 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6128 (const_string "*")))
6129 (set_attr "mode" "HI")])
6131 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
6132 ;; type optimizations enabled by define-splits. This is not important
6133 ;; for PII, and in fact harmful because of partial register stalls.
6135 (define_insn "*addhi_1_lea"
6136 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
6137 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
6138 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
6139 (clobber (reg:CC FLAGS_REG))]
6140 "!TARGET_PARTIAL_REG_STALL
6141 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6143 switch (get_attr_type (insn))
6148 if (operands[2] == const1_rtx)
6149 return "inc{w}\t%0";
6152 gcc_assert (operands[2] == constm1_rtx);
6153 return "dec{w}\t%0";
6157 if (x86_maybe_negate_const_int (&operands[2], HImode))
6158 return "sub{w}\t{%2, %0|%0, %2}";
6160 return "add{w}\t{%2, %0|%0, %2}";
6164 (if_then_else (eq_attr "alternative" "2")
6165 (const_string "lea")
6166 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6167 (const_string "incdec")
6168 (const_string "alu"))))
6169 (set (attr "length_immediate")
6171 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6173 (const_string "*")))
6174 (set_attr "mode" "HI,HI,SI")])
6176 (define_insn "*addqi_1"
6177 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
6178 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
6179 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
6180 (clobber (reg:CC FLAGS_REG))]
6181 "TARGET_PARTIAL_REG_STALL
6182 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6184 int widen = (which_alternative == 2);
6185 switch (get_attr_type (insn))
6188 if (operands[2] == const1_rtx)
6189 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6192 gcc_assert (operands[2] == constm1_rtx);
6193 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6197 if (x86_maybe_negate_const_int (&operands[2], QImode))
6200 return "sub{l}\t{%2, %k0|%k0, %2}";
6202 return "sub{b}\t{%2, %0|%0, %2}";
6205 return "add{l}\t{%k2, %k0|%k0, %k2}";
6207 return "add{b}\t{%2, %0|%0, %2}";
6211 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6212 (const_string "incdec")
6213 (const_string "alu")))
6214 (set (attr "length_immediate")
6216 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6218 (const_string "*")))
6219 (set_attr "mode" "QI,QI,SI")])
6221 ;; %%% Potential partial reg stall on alternative 2. What to do?
6222 (define_insn "*addqi_1_lea"
6223 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
6224 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
6225 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
6226 (clobber (reg:CC FLAGS_REG))]
6227 "!TARGET_PARTIAL_REG_STALL
6228 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6230 int widen = (which_alternative == 2);
6231 switch (get_attr_type (insn))
6236 if (operands[2] == const1_rtx)
6237 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
6240 gcc_assert (operands[2] == constm1_rtx);
6241 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
6245 if (x86_maybe_negate_const_int (&operands[2], QImode))
6248 return "sub{l}\t{%2, %k0|%k0, %2}";
6250 return "sub{b}\t{%2, %0|%0, %2}";
6253 return "add{l}\t{%k2, %k0|%k0, %k2}";
6255 return "add{b}\t{%2, %0|%0, %2}";
6259 (if_then_else (eq_attr "alternative" "3")
6260 (const_string "lea")
6261 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6262 (const_string "incdec")
6263 (const_string "alu"))))
6264 (set (attr "length_immediate")
6266 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6268 (const_string "*")))
6269 (set_attr "mode" "QI,QI,SI,SI")])
6271 (define_insn "*addqi_1_slp"
6272 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
6273 (plus:QI (match_dup 0)
6274 (match_operand:QI 1 "general_operand" "qn,qnm")))
6275 (clobber (reg:CC FLAGS_REG))]
6276 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6277 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
6279 switch (get_attr_type (insn))
6282 if (operands[1] == const1_rtx)
6283 return "inc{b}\t%0";
6286 gcc_assert (operands[1] == constm1_rtx);
6287 return "dec{b}\t%0";
6291 if (x86_maybe_negate_const_int (&operands[1], QImode))
6292 return "sub{b}\t{%1, %0|%0, %1}";
6294 return "add{b}\t{%1, %0|%0, %1}";
6298 (if_then_else (match_operand:QI 1 "incdec_operand" "")
6299 (const_string "incdec")
6300 (const_string "alu1")))
6301 (set (attr "memory")
6302 (if_then_else (match_operand 1 "memory_operand" "")
6303 (const_string "load")
6304 (const_string "none")))
6305 (set_attr "mode" "QI")])
6307 (define_insn "*add<mode>_2"
6308 [(set (reg FLAGS_REG)
6311 (match_operand:SWI48 1 "nonimmediate_operand" "%0,0")
6312 (match_operand:SWI48 2 "<general_operand>" "<g>,r<i>"))
6314 (set (match_operand:SWI48 0 "nonimmediate_operand" "=r,rm")
6315 (plus:SWI48 (match_dup 1) (match_dup 2)))]
6316 "ix86_match_ccmode (insn, CCGOCmode)
6317 && ix86_binary_operator_ok (PLUS, <MODE>mode, operands)
6318 /* Current assemblers are broken and do not allow @GOTOFF in
6319 ought but a memory context. */
6320 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6322 switch (get_attr_type (insn))
6325 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6326 if (operands[2] == const1_rtx)
6327 return "inc{<imodesuffix>}\t%0";
6330 gcc_assert (operands[2] == constm1_rtx);
6331 return "dec{<imodesuffix>}\t%0";
6335 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6336 /* ???? In DImode, we ought to handle there the 32bit case too
6337 - do we need new constraint? */
6338 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6339 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6341 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6345 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6346 (const_string "incdec")
6347 (const_string "alu")))
6348 (set (attr "length_immediate")
6350 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6352 (const_string "*")))
6353 (set_attr "mode" "<MODE>")])
6355 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6356 (define_insn "*addsi_2_zext"
6357 [(set (reg FLAGS_REG)
6359 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
6360 (match_operand:SI 2 "general_operand" "g"))
6362 (set (match_operand:DI 0 "register_operand" "=r")
6363 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6364 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6365 && ix86_binary_operator_ok (PLUS, SImode, operands)
6366 /* Current assemblers are broken and do not allow @GOTOFF in
6367 ought but a memory context. */
6368 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6370 switch (get_attr_type (insn))
6373 if (operands[2] == const1_rtx)
6374 return "inc{l}\t%k0";
6377 gcc_assert (operands[2] == constm1_rtx);
6378 return "dec{l}\t%k0";
6382 if (x86_maybe_negate_const_int (&operands[2], SImode))
6383 return "sub{l}\t{%2, %k0|%k0, %2}";
6385 return "add{l}\t{%2, %k0|%k0, %2}";
6389 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6390 (const_string "incdec")
6391 (const_string "alu")))
6392 (set (attr "length_immediate")
6394 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6396 (const_string "*")))
6397 (set_attr "mode" "SI")])
6399 (define_insn "*addhi_2"
6400 [(set (reg FLAGS_REG)
6402 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
6403 (match_operand:HI 2 "general_operand" "rmn,rn"))
6405 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
6406 (plus:HI (match_dup 1) (match_dup 2)))]
6407 "ix86_match_ccmode (insn, CCGOCmode)
6408 && ix86_binary_operator_ok (PLUS, HImode, operands)"
6410 switch (get_attr_type (insn))
6413 if (operands[2] == const1_rtx)
6414 return "inc{w}\t%0";
6417 gcc_assert (operands[2] == constm1_rtx);
6418 return "dec{w}\t%0";
6422 if (x86_maybe_negate_const_int (&operands[2], HImode))
6423 return "sub{w}\t{%2, %0|%0, %2}";
6425 return "add{w}\t{%2, %0|%0, %2}";
6429 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6430 (const_string "incdec")
6431 (const_string "alu")))
6432 (set (attr "length_immediate")
6434 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6436 (const_string "*")))
6437 (set_attr "mode" "HI")])
6439 (define_insn "*addqi_2"
6440 [(set (reg FLAGS_REG)
6442 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
6443 (match_operand:QI 2 "general_operand" "qmn,qn"))
6445 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
6446 (plus:QI (match_dup 1) (match_dup 2)))]
6447 "ix86_match_ccmode (insn, CCGOCmode)
6448 && ix86_binary_operator_ok (PLUS, QImode, operands)"
6450 switch (get_attr_type (insn))
6453 if (operands[2] == const1_rtx)
6454 return "inc{b}\t%0";
6457 gcc_assert (operands[2] == constm1_rtx
6458 || (CONST_INT_P (operands[2])
6459 && INTVAL (operands[2]) == 255));
6460 return "dec{b}\t%0";
6464 if (x86_maybe_negate_const_int (&operands[2], QImode))
6465 return "sub{b}\t{%2, %0|%0, %2}";
6467 return "add{b}\t{%2, %0|%0, %2}";
6471 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6472 (const_string "incdec")
6473 (const_string "alu")))
6474 (set_attr "mode" "QI")])
6476 (define_insn "*add<mode>_3"
6477 [(set (reg FLAGS_REG)
6479 (neg:SWI48 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6480 (match_operand:SWI48 1 "nonimmediate_operand" "%0")))
6481 (clobber (match_scratch:SWI48 0 "=r"))]
6482 "ix86_match_ccmode (insn, CCZmode)
6483 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6484 /* Current assemblers are broken and do not allow @GOTOFF in
6485 ought but a memory context. */
6486 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6488 switch (get_attr_type (insn))
6491 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6492 if (operands[2] == const1_rtx)
6493 return "inc{<imodesuffix>}\t%0";
6496 gcc_assert (operands[2] == constm1_rtx);
6497 return "dec{<imodesuffix>}\t%0";
6501 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6502 /* ???? In DImode, we ought to handle there the 32bit case too
6503 - do we need new constraint? */
6504 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6505 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6507 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6511 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6512 (const_string "incdec")
6513 (const_string "alu")))
6514 (set (attr "length_immediate")
6516 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6518 (const_string "*")))
6519 (set_attr "mode" "<MODE>")])
6521 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
6522 (define_insn "*addsi_3_zext"
6523 [(set (reg FLAGS_REG)
6525 (neg:SI (match_operand:SI 2 "general_operand" "g"))
6526 (match_operand:SI 1 "nonimmediate_operand" "%0")))
6527 (set (match_operand:DI 0 "register_operand" "=r")
6528 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
6529 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
6530 && ix86_binary_operator_ok (PLUS, SImode, operands)
6531 /* Current assemblers are broken and do not allow @GOTOFF in
6532 ought but a memory context. */
6533 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6535 switch (get_attr_type (insn))
6538 if (operands[2] == const1_rtx)
6539 return "inc{l}\t%k0";
6542 gcc_assert (operands[2] == constm1_rtx);
6543 return "dec{l}\t%k0";
6547 if (x86_maybe_negate_const_int (&operands[2], SImode))
6548 return "sub{l}\t{%2, %k0|%k0, %2}";
6550 return "add{l}\t{%2, %k0|%k0, %2}";
6554 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6555 (const_string "incdec")
6556 (const_string "alu")))
6557 (set (attr "length_immediate")
6559 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6561 (const_string "*")))
6562 (set_attr "mode" "SI")])
6564 (define_insn "*addhi_3"
6565 [(set (reg FLAGS_REG)
6567 (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
6568 (match_operand:HI 1 "nonimmediate_operand" "%0")))
6569 (clobber (match_scratch:HI 0 "=r"))]
6570 "ix86_match_ccmode (insn, CCZmode)
6571 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6573 switch (get_attr_type (insn))
6576 if (operands[2] == const1_rtx)
6577 return "inc{w}\t%0";
6580 gcc_assert (operands[2] == constm1_rtx);
6581 return "dec{w}\t%0";
6585 if (x86_maybe_negate_const_int (&operands[2], HImode))
6586 return "sub{w}\t{%2, %0|%0, %2}";
6588 return "add{w}\t{%2, %0|%0, %2}";
6592 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6593 (const_string "incdec")
6594 (const_string "alu")))
6595 (set (attr "length_immediate")
6597 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6599 (const_string "*")))
6600 (set_attr "mode" "HI")])
6602 (define_insn "*addqi_3"
6603 [(set (reg FLAGS_REG)
6605 (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
6606 (match_operand:QI 1 "nonimmediate_operand" "%0")))
6607 (clobber (match_scratch:QI 0 "=q"))]
6608 "ix86_match_ccmode (insn, CCZmode)
6609 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6611 switch (get_attr_type (insn))
6614 if (operands[2] == const1_rtx)
6615 return "inc{b}\t%0";
6618 gcc_assert (operands[2] == constm1_rtx
6619 || (CONST_INT_P (operands[2])
6620 && INTVAL (operands[2]) == 255));
6621 return "dec{b}\t%0";
6625 if (x86_maybe_negate_const_int (&operands[2], QImode))
6626 return "sub{b}\t{%2, %0|%0, %2}";
6628 return "add{b}\t{%2, %0|%0, %2}";
6632 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6633 (const_string "incdec")
6634 (const_string "alu")))
6635 (set_attr "mode" "QI")])
6637 ; For comparisons against 1, -1 and 128, we may generate better code
6638 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6639 ; is matched then. We can't accept general immediate, because for
6640 ; case of overflows, the result is messed up.
6641 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6642 ; only for comparisons not depending on it.
6644 (define_insn "*adddi_4"
6645 [(set (reg FLAGS_REG)
6647 (match_operand:DI 1 "nonimmediate_operand" "0")
6648 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6649 (clobber (match_scratch:DI 0 "=rm"))]
6651 && ix86_match_ccmode (insn, CCGCmode)"
6653 switch (get_attr_type (insn))
6656 if (operands[2] == constm1_rtx)
6657 return "inc{q}\t%0";
6660 gcc_assert (operands[2] == const1_rtx);
6661 return "dec{q}\t%0";
6665 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6666 if (x86_maybe_negate_const_int (&operands[2], DImode))
6667 return "add{q}\t{%2, %0|%0, %2}";
6669 return "sub{q}\t{%2, %0|%0, %2}";
6673 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6674 (const_string "incdec")
6675 (const_string "alu")))
6676 (set (attr "length_immediate")
6678 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6680 (const_string "*")))
6681 (set_attr "mode" "DI")])
6683 ; For comparisons against 1, -1 and 128, we may generate better code
6684 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6685 ; is matched then. We can't accept general immediate, because for
6686 ; case of overflows, the result is messed up.
6687 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6688 ; only for comparisons not depending on it.
6690 (define_insn "*addsi_4"
6691 [(set (reg FLAGS_REG)
6693 (match_operand:SI 1 "nonimmediate_operand" "0")
6694 (match_operand:SI 2 "const_int_operand" "n")))
6695 (clobber (match_scratch:SI 0 "=rm"))]
6696 "ix86_match_ccmode (insn, CCGCmode)"
6698 switch (get_attr_type (insn))
6701 if (operands[2] == constm1_rtx)
6702 return "inc{l}\t%0";
6705 gcc_assert (operands[2] == const1_rtx);
6706 return "dec{l}\t%0";
6710 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6711 if (x86_maybe_negate_const_int (&operands[2], SImode))
6712 return "add{l}\t{%2, %0|%0, %2}";
6714 return "sub{l}\t{%2, %0|%0, %2}";
6718 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6719 (const_string "incdec")
6720 (const_string "alu")))
6721 (set (attr "length_immediate")
6723 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6725 (const_string "*")))
6726 (set_attr "mode" "SI")])
6728 ; See comments above addsi_4 for details.
6730 (define_insn "*addhi_4"
6731 [(set (reg FLAGS_REG)
6733 (match_operand:HI 1 "nonimmediate_operand" "0")
6734 (match_operand:HI 2 "const_int_operand" "n")))
6735 (clobber (match_scratch:HI 0 "=rm"))]
6736 "ix86_match_ccmode (insn, CCGCmode)"
6738 switch (get_attr_type (insn))
6741 if (operands[2] == constm1_rtx)
6742 return "inc{w}\t%0";
6745 gcc_assert (operands[2] == const1_rtx);
6746 return "dec{w}\t%0";
6750 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6751 if (x86_maybe_negate_const_int (&operands[2], HImode))
6752 return "add{w}\t{%2, %0|%0, %2}";
6754 return "sub{w}\t{%2, %0|%0, %2}";
6758 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6759 (const_string "incdec")
6760 (const_string "alu")))
6761 (set (attr "length_immediate")
6763 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6765 (const_string "*")))
6766 (set_attr "mode" "HI")])
6768 ; See comments above addsi_4 for details.
6770 (define_insn "*addqi_4"
6771 [(set (reg FLAGS_REG)
6773 (match_operand:QI 1 "nonimmediate_operand" "0")
6774 (match_operand:QI 2 "const_int_operand" "n")))
6775 (clobber (match_scratch:QI 0 "=qm"))]
6776 "ix86_match_ccmode (insn, CCGCmode)"
6778 switch (get_attr_type (insn))
6781 if (operands[2] == constm1_rtx
6782 || (CONST_INT_P (operands[2])
6783 && INTVAL (operands[2]) == 255))
6784 return "inc{b}\t%0";
6787 gcc_assert (operands[2] == const1_rtx);
6788 return "dec{b}\t%0";
6792 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6793 if (x86_maybe_negate_const_int (&operands[2], QImode))
6794 return "add{b}\t{%2, %0|%0, %2}";
6796 return "sub{b}\t{%2, %0|%0, %2}";
6800 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6801 (const_string "incdec")
6802 (const_string "alu")))
6803 (set_attr "mode" "QI")])
6805 (define_insn "*add<mode>_5"
6806 [(set (reg FLAGS_REG)
6809 (match_operand:SWI48 1 "nonimmediate_operand" "%0")
6810 (match_operand:SWI48 2 "<general_operand>" "<g>"))
6812 (clobber (match_scratch:SWI48 0 "=r"))]
6813 "ix86_match_ccmode (insn, CCGOCmode)
6814 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6815 /* Current assemblers are broken and do not allow @GOTOFF in
6816 ought but a memory context. */
6817 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6819 switch (get_attr_type (insn))
6822 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6823 if (operands[2] == const1_rtx)
6824 return "inc{<imodesuffix>}\t%0";
6827 gcc_assert (operands[2] == constm1_rtx);
6828 return "dec{<imodesuffix>}\t%0";
6832 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6833 if (x86_maybe_negate_const_int (&operands[2], <MODE>mode))
6834 return "sub{<imodesuffix>}\t{%2, %0|%0, %2}";
6836 return "add{<imodesuffix>}\t{%2, %0|%0, %2}";
6840 (if_then_else (match_operand:SWI48 2 "incdec_operand" "")
6841 (const_string "incdec")
6842 (const_string "alu")))
6843 (set (attr "length_immediate")
6845 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6847 (const_string "*")))
6848 (set_attr "mode" "<MODE>")])
6850 (define_insn "*addhi_5"
6851 [(set (reg FLAGS_REG)
6853 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
6854 (match_operand:HI 2 "general_operand" "rmn"))
6856 (clobber (match_scratch:HI 0 "=r"))]
6857 "ix86_match_ccmode (insn, CCGOCmode)
6858 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6860 switch (get_attr_type (insn))
6863 if (operands[2] == const1_rtx)
6864 return "inc{w}\t%0";
6867 gcc_assert (operands[2] == constm1_rtx);
6868 return "dec{w}\t%0";
6872 if (x86_maybe_negate_const_int (&operands[2], HImode))
6873 return "sub{w}\t{%2, %0|%0, %2}";
6875 return "add{w}\t{%2, %0|%0, %2}";
6879 (if_then_else (match_operand:HI 2 "incdec_operand" "")
6880 (const_string "incdec")
6881 (const_string "alu")))
6882 (set (attr "length_immediate")
6884 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6886 (const_string "*")))
6887 (set_attr "mode" "HI")])
6889 (define_insn "*addqi_5"
6890 [(set (reg FLAGS_REG)
6892 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
6893 (match_operand:QI 2 "general_operand" "qmn"))
6895 (clobber (match_scratch:QI 0 "=q"))]
6896 "ix86_match_ccmode (insn, CCGOCmode)
6897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
6899 switch (get_attr_type (insn))
6902 if (operands[2] == const1_rtx)
6903 return "inc{b}\t%0";
6906 gcc_assert (operands[2] == constm1_rtx
6907 || (CONST_INT_P (operands[2])
6908 && INTVAL (operands[2]) == 255));
6909 return "dec{b}\t%0";
6913 if (x86_maybe_negate_const_int (&operands[2], QImode))
6914 return "sub{b}\t{%2, %0|%0, %2}";
6916 return "add{b}\t{%2, %0|%0, %2}";
6920 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6921 (const_string "incdec")
6922 (const_string "alu")))
6923 (set_attr "mode" "QI")])
6925 (define_insn "*addqi_ext_1_rex64"
6926 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6931 (match_operand 1 "ext_register_operand" "0")
6934 (match_operand:QI 2 "nonmemory_operand" "Qn")))
6935 (clobber (reg:CC FLAGS_REG))]
6938 switch (get_attr_type (insn))
6941 if (operands[2] == const1_rtx)
6942 return "inc{b}\t%h0";
6945 gcc_assert (operands[2] == constm1_rtx
6946 || (CONST_INT_P (operands[2])
6947 && INTVAL (operands[2]) == 255));
6948 return "dec{b}\t%h0";
6952 return "add{b}\t{%2, %h0|%h0, %2}";
6956 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6957 (const_string "incdec")
6958 (const_string "alu")))
6959 (set_attr "modrm" "1")
6960 (set_attr "mode" "QI")])
6962 (define_insn "addqi_ext_1"
6963 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
6968 (match_operand 1 "ext_register_operand" "0")
6971 (match_operand:QI 2 "general_operand" "Qmn")))
6972 (clobber (reg:CC FLAGS_REG))]
6975 switch (get_attr_type (insn))
6978 if (operands[2] == const1_rtx)
6979 return "inc{b}\t%h0";
6982 gcc_assert (operands[2] == constm1_rtx
6983 || (CONST_INT_P (operands[2])
6984 && INTVAL (operands[2]) == 255));
6985 return "dec{b}\t%h0";
6989 return "add{b}\t{%2, %h0|%h0, %2}";
6993 (if_then_else (match_operand:QI 2 "incdec_operand" "")
6994 (const_string "incdec")
6995 (const_string "alu")))
6996 (set_attr "modrm" "1")
6997 (set_attr "mode" "QI")])
6999 (define_insn "*addqi_ext_2"
7000 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7005 (match_operand 1 "ext_register_operand" "%0")
7009 (match_operand 2 "ext_register_operand" "Q")
7012 (clobber (reg:CC FLAGS_REG))]
7014 "add{b}\t{%h2, %h0|%h0, %h2}"
7015 [(set_attr "type" "alu")
7016 (set_attr "mode" "QI")])
7018 ;; The lea patterns for non-Pmodes needs to be matched by
7019 ;; several insns converted to real lea by splitters.
7021 (define_insn_and_split "*lea_general_1"
7022 [(set (match_operand 0 "register_operand" "=r")
7023 (plus (plus (match_operand 1 "index_register_operand" "l")
7024 (match_operand 2 "register_operand" "r"))
7025 (match_operand 3 "immediate_operand" "i")))]
7026 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7027 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7028 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7029 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7030 && GET_MODE (operands[0]) == GET_MODE (operands[2])
7031 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7032 || GET_MODE (operands[3]) == VOIDmode)"
7034 "&& reload_completed"
7038 operands[0] = gen_lowpart (SImode, operands[0]);
7039 operands[1] = gen_lowpart (Pmode, operands[1]);
7040 operands[2] = gen_lowpart (Pmode, operands[2]);
7041 operands[3] = gen_lowpart (Pmode, operands[3]);
7042 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
7044 if (Pmode != SImode)
7045 pat = gen_rtx_SUBREG (SImode, pat, 0);
7046 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7049 [(set_attr "type" "lea")
7050 (set_attr "mode" "SI")])
7052 (define_insn_and_split "*lea_general_1_zext"
7053 [(set (match_operand:DI 0 "register_operand" "=r")
7056 (match_operand:SI 1 "index_register_operand" "l")
7057 (match_operand:SI 2 "register_operand" "r"))
7058 (match_operand:SI 3 "immediate_operand" "i"))))]
7061 "&& reload_completed"
7063 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
7065 (match_dup 3)) 0)))]
7067 operands[1] = gen_lowpart (Pmode, operands[1]);
7068 operands[2] = gen_lowpart (Pmode, operands[2]);
7069 operands[3] = gen_lowpart (Pmode, operands[3]);
7071 [(set_attr "type" "lea")
7072 (set_attr "mode" "SI")])
7074 (define_insn_and_split "*lea_general_2"
7075 [(set (match_operand 0 "register_operand" "=r")
7076 (plus (mult (match_operand 1 "index_register_operand" "l")
7077 (match_operand 2 "const248_operand" "i"))
7078 (match_operand 3 "nonmemory_operand" "ri")))]
7079 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7080 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7081 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7082 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7083 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
7084 || GET_MODE (operands[3]) == VOIDmode)"
7086 "&& reload_completed"
7090 operands[0] = gen_lowpart (SImode, operands[0]);
7091 operands[1] = gen_lowpart (Pmode, operands[1]);
7092 operands[3] = gen_lowpart (Pmode, operands[3]);
7093 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
7095 if (Pmode != SImode)
7096 pat = gen_rtx_SUBREG (SImode, pat, 0);
7097 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7100 [(set_attr "type" "lea")
7101 (set_attr "mode" "SI")])
7103 (define_insn_and_split "*lea_general_2_zext"
7104 [(set (match_operand:DI 0 "register_operand" "=r")
7107 (match_operand:SI 1 "index_register_operand" "l")
7108 (match_operand:SI 2 "const248_operand" "n"))
7109 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
7112 "&& reload_completed"
7114 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
7116 (match_dup 3)) 0)))]
7118 operands[1] = gen_lowpart (Pmode, operands[1]);
7119 operands[3] = gen_lowpart (Pmode, operands[3]);
7121 [(set_attr "type" "lea")
7122 (set_attr "mode" "SI")])
7124 (define_insn_and_split "*lea_general_3"
7125 [(set (match_operand 0 "register_operand" "=r")
7126 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
7127 (match_operand 2 "const248_operand" "i"))
7128 (match_operand 3 "register_operand" "r"))
7129 (match_operand 4 "immediate_operand" "i")))]
7130 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
7131 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
7132 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7133 && GET_MODE (operands[0]) == GET_MODE (operands[1])
7134 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
7136 "&& reload_completed"
7140 operands[0] = gen_lowpart (SImode, operands[0]);
7141 operands[1] = gen_lowpart (Pmode, operands[1]);
7142 operands[3] = gen_lowpart (Pmode, operands[3]);
7143 operands[4] = gen_lowpart (Pmode, operands[4]);
7144 pat = gen_rtx_PLUS (Pmode,
7145 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
7149 if (Pmode != SImode)
7150 pat = gen_rtx_SUBREG (SImode, pat, 0);
7151 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7154 [(set_attr "type" "lea")
7155 (set_attr "mode" "SI")])
7157 (define_insn_and_split "*lea_general_3_zext"
7158 [(set (match_operand:DI 0 "register_operand" "=r")
7162 (match_operand:SI 1 "index_register_operand" "l")
7163 (match_operand:SI 2 "const248_operand" "n"))
7164 (match_operand:SI 3 "register_operand" "r"))
7165 (match_operand:SI 4 "immediate_operand" "i"))))]
7168 "&& reload_completed"
7170 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
7173 (match_dup 4)) 0)))]
7175 operands[1] = gen_lowpart (Pmode, operands[1]);
7176 operands[3] = gen_lowpart (Pmode, operands[3]);
7177 operands[4] = gen_lowpart (Pmode, operands[4]);
7179 [(set_attr "type" "lea")
7180 (set_attr "mode" "SI")])
7182 ;; Convert lea to the lea pattern to avoid flags dependency.
7184 [(set (match_operand:DI 0 "register_operand" "")
7185 (plus:DI (match_operand:DI 1 "register_operand" "")
7186 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
7187 (clobber (reg:CC FLAGS_REG))]
7188 "TARGET_64BIT && reload_completed
7189 && ix86_lea_for_add_ok (PLUS, insn, operands)"
7191 (plus:DI (match_dup 1)
7195 ;; Convert lea to the lea pattern to avoid flags dependency.
7197 [(set (match_operand 0 "register_operand" "")
7198 (plus (match_operand 1 "register_operand" "")
7199 (match_operand 2 "nonmemory_operand" "")))
7200 (clobber (reg:CC FLAGS_REG))]
7201 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
7205 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
7206 may confuse gen_lowpart. */
7207 if (GET_MODE (operands[0]) != Pmode)
7209 operands[1] = gen_lowpart (Pmode, operands[1]);
7210 operands[2] = gen_lowpart (Pmode, operands[2]);
7212 operands[0] = gen_lowpart (SImode, operands[0]);
7213 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
7214 if (Pmode != SImode)
7215 pat = gen_rtx_SUBREG (SImode, pat, 0);
7216 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
7220 ;; Convert lea to the lea pattern to avoid flags dependency.
7222 [(set (match_operand:DI 0 "register_operand" "")
7224 (plus:SI (match_operand:SI 1 "register_operand" "")
7225 (match_operand:SI 2 "nonmemory_operand" ""))))
7226 (clobber (reg:CC FLAGS_REG))]
7227 "TARGET_64BIT && reload_completed
7228 && true_regnum (operands[0]) != true_regnum (operands[1])"
7230 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
7232 operands[1] = gen_lowpart (Pmode, operands[1]);
7233 operands[2] = gen_lowpart (Pmode, operands[2]);
7236 ;; Subtract instructions
7238 (define_expand "sub<mode>3"
7239 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
7240 (minus:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")
7241 (match_operand:SDWIM 2 "<general_operand>" "")))]
7243 "ix86_expand_binary_operator (MINUS, <MODE>mode, operands); DONE;")
7245 (define_insn_and_split "*sub<dwi>3_doubleword"
7246 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=r,o")
7248 (match_operand:<DWI> 1 "nonimmediate_operand" "0,0")
7249 (match_operand:<DWI> 2 "<general_operand>" "ro<di>,r<di>")))
7250 (clobber (reg:CC FLAGS_REG))]
7251 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7254 [(parallel [(set (reg:CC FLAGS_REG)
7255 (compare:CC (match_dup 1) (match_dup 2)))
7257 (minus:DWIH (match_dup 1) (match_dup 2)))])
7258 (parallel [(set (match_dup 3)
7262 (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
7264 (clobber (reg:CC FLAGS_REG))])]
7265 "split_<dwi> (&operands[0], 3, &operands[0], &operands[3]);")
7267 (define_insn "*sub<mode>_1"
7268 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7270 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7271 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7272 (clobber (reg:CC FLAGS_REG))]
7273 "ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7274 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7275 [(set_attr "type" "alu")
7276 (set_attr "mode" "<MODE>")])
7278 (define_insn "*subsi_1_zext"
7279 [(set (match_operand:DI 0 "register_operand" "=r")
7281 (minus:SI (match_operand:SI 1 "register_operand" "0")
7282 (match_operand:SI 2 "general_operand" "g"))))
7283 (clobber (reg:CC FLAGS_REG))]
7284 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7285 "sub{l}\t{%2, %k0|%k0, %2}"
7286 [(set_attr "type" "alu")
7287 (set_attr "mode" "SI")])
7289 (define_insn "*subqi_1_slp"
7290 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7291 (minus:QI (match_dup 0)
7292 (match_operand:QI 1 "general_operand" "qn,qm")))
7293 (clobber (reg:CC FLAGS_REG))]
7294 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7295 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7296 "sub{b}\t{%1, %0|%0, %1}"
7297 [(set_attr "type" "alu1")
7298 (set_attr "mode" "QI")])
7300 (define_insn "*sub<mode>_2"
7301 [(set (reg FLAGS_REG)
7304 (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7305 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7307 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7308 (minus:SWI (match_dup 1) (match_dup 2)))]
7309 "ix86_match_ccmode (insn, CCGOCmode)
7310 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7311 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7312 [(set_attr "type" "alu")
7313 (set_attr "mode" "<MODE>")])
7315 (define_insn "*subsi_2_zext"
7316 [(set (reg FLAGS_REG)
7318 (minus:SI (match_operand:SI 1 "register_operand" "0")
7319 (match_operand:SI 2 "general_operand" "g"))
7321 (set (match_operand:DI 0 "register_operand" "=r")
7323 (minus:SI (match_dup 1)
7325 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7326 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7327 "sub{l}\t{%2, %k0|%k0, %2}"
7328 [(set_attr "type" "alu")
7329 (set_attr "mode" "SI")])
7331 (define_insn "*sub<mode>_3"
7332 [(set (reg FLAGS_REG)
7333 (compare (match_operand:SWI 1 "nonimmediate_operand" "0,0")
7334 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m")))
7335 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7336 (minus:SWI (match_dup 1) (match_dup 2)))]
7337 "ix86_match_ccmode (insn, CCmode)
7338 && ix86_binary_operator_ok (MINUS, <MODE>mode, operands)"
7339 "sub{<imodesuffix>}\t{%2, %0|%0, %2}"
7340 [(set_attr "type" "alu")
7341 (set_attr "mode" "<MODE>")])
7343 (define_insn "*subsi_3_zext"
7344 [(set (reg FLAGS_REG)
7345 (compare (match_operand:SI 1 "register_operand" "0")
7346 (match_operand:SI 2 "general_operand" "g")))
7347 (set (match_operand:DI 0 "register_operand" "=r")
7349 (minus:SI (match_dup 1)
7351 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
7352 && ix86_binary_operator_ok (MINUS, SImode, operands)"
7353 "sub{l}\t{%2, %1|%1, %2}"
7354 [(set_attr "type" "alu")
7355 (set_attr "mode" "SI")])
7357 ;; Add with carry and subtract with borrow
7359 (define_expand "<plusminus_insn><mode>3_carry"
7361 [(set (match_operand:SWI 0 "nonimmediate_operand" "")
7363 (match_operand:SWI 1 "nonimmediate_operand" "")
7364 (plus:SWI (match_operator:SWI 4 "ix86_carry_flag_operator"
7365 [(match_operand 3 "flags_reg_operand" "")
7367 (match_operand:SWI 2 "<general_operand>" ""))))
7368 (clobber (reg:CC FLAGS_REG))])]
7369 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7372 (define_insn "*<plusminus_insn><mode>3_carry"
7373 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7375 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7377 (match_operator 3 "ix86_carry_flag_operator"
7378 [(reg FLAGS_REG) (const_int 0)])
7379 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))))
7380 (clobber (reg:CC FLAGS_REG))]
7381 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7382 "<plusminus_carry_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7383 [(set_attr "type" "alu")
7384 (set_attr "use_carry" "1")
7385 (set_attr "pent_pair" "pu")
7386 (set_attr "mode" "<MODE>")])
7388 (define_insn "*addsi3_carry_zext"
7389 [(set (match_operand:DI 0 "register_operand" "=r")
7391 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7392 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7393 [(reg FLAGS_REG) (const_int 0)])
7394 (match_operand:SI 2 "general_operand" "g")))))
7395 (clobber (reg:CC FLAGS_REG))]
7396 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
7397 "adc{l}\t{%2, %k0|%k0, %2}"
7398 [(set_attr "type" "alu")
7399 (set_attr "use_carry" "1")
7400 (set_attr "pent_pair" "pu")
7401 (set_attr "mode" "SI")])
7403 (define_insn "*subsi3_carry_zext"
7404 [(set (match_operand:DI 0 "register_operand" "=r")
7406 (minus:SI (match_operand:SI 1 "register_operand" "0")
7407 (plus:SI (match_operator 3 "ix86_carry_flag_operator"
7408 [(reg FLAGS_REG) (const_int 0)])
7409 (match_operand:SI 2 "general_operand" "g")))))
7410 (clobber (reg:CC FLAGS_REG))]
7411 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
7412 "sbb{l}\t{%2, %k0|%k0, %2}"
7413 [(set_attr "type" "alu")
7414 (set_attr "pent_pair" "pu")
7415 (set_attr "mode" "SI")])
7417 ;; Overflow setting add and subtract instructions
7419 (define_insn "*add<mode>3_cconly_overflow"
7420 [(set (reg:CCC FLAGS_REG)
7423 (match_operand:SWI 1 "nonimmediate_operand" "%0")
7424 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
7426 (clobber (match_scratch:SWI 0 "=<r>"))]
7427 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
7428 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
7429 [(set_attr "type" "alu")
7430 (set_attr "mode" "<MODE>")])
7432 (define_insn "*sub<mode>3_cconly_overflow"
7433 [(set (reg:CCC FLAGS_REG)
7436 (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
7437 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
7440 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
7441 [(set_attr "type" "icmp")
7442 (set_attr "mode" "<MODE>")])
7444 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
7445 [(set (reg:CCC FLAGS_REG)
7448 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
7449 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
7451 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
7452 (plusminus:SWI (match_dup 1) (match_dup 2)))]
7453 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
7454 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
7455 [(set_attr "type" "alu")
7456 (set_attr "mode" "<MODE>")])
7458 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
7459 [(set (reg:CCC FLAGS_REG)
7462 (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
7463 (match_operand:SI 2 "general_operand" "g"))
7465 (set (match_operand:DI 0 "register_operand" "=r")
7466 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
7467 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
7468 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
7469 [(set_attr "type" "alu")
7470 (set_attr "mode" "SI")])
7472 ;; The patterns that match these are at the end of this file.
7474 (define_expand "<plusminus_insn>xf3"
7475 [(set (match_operand:XF 0 "register_operand" "")
7477 (match_operand:XF 1 "register_operand" "")
7478 (match_operand:XF 2 "register_operand" "")))]
7482 (define_expand "<plusminus_insn><mode>3"
7483 [(set (match_operand:MODEF 0 "register_operand" "")
7485 (match_operand:MODEF 1 "register_operand" "")
7486 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7487 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7488 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7491 ;; Multiply instructions
7493 (define_expand "mul<mode>3"
7494 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7496 (match_operand:SWIM248 1 "register_operand" "")
7497 (match_operand:SWIM248 2 "<general_operand>" "")))
7498 (clobber (reg:CC FLAGS_REG))])]
7502 (define_expand "mulqi3"
7503 [(parallel [(set (match_operand:QI 0 "register_operand" "")
7505 (match_operand:QI 1 "register_operand" "")
7506 (match_operand:QI 2 "nonimmediate_operand" "")))
7507 (clobber (reg:CC FLAGS_REG))])]
7508 "TARGET_QIMODE_MATH"
7512 ;; IMUL reg32/64, reg32/64, imm8 Direct
7513 ;; IMUL reg32/64, mem32/64, imm8 VectorPath
7514 ;; IMUL reg32/64, reg32/64, imm32 Direct
7515 ;; IMUL reg32/64, mem32/64, imm32 VectorPath
7516 ;; IMUL reg32/64, reg32/64 Direct
7517 ;; IMUL reg32/64, mem32/64 Direct
7519 (define_insn "*mul<mode>3_1"
7520 [(set (match_operand:SWI48 0 "register_operand" "=r,r,r")
7522 (match_operand:SWI48 1 "nonimmediate_operand" "%rm,rm,0")
7523 (match_operand:SWI48 2 "<general_operand>" "K,<i>,mr")))
7524 (clobber (reg:CC FLAGS_REG))]
7525 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7527 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7528 imul{<imodesuffix>}\t{%2, %1, %0|%0, %1, %2}
7529 imul{<imodesuffix>}\t{%2, %0|%0, %2}"
7530 [(set_attr "type" "imul")
7531 (set_attr "prefix_0f" "0,0,1")
7532 (set (attr "athlon_decode")
7533 (cond [(eq_attr "cpu" "athlon")
7534 (const_string "vector")
7535 (eq_attr "alternative" "1")
7536 (const_string "vector")
7537 (and (eq_attr "alternative" "2")
7538 (match_operand 1 "memory_operand" ""))
7539 (const_string "vector")]
7540 (const_string "direct")))
7541 (set (attr "amdfam10_decode")
7542 (cond [(and (eq_attr "alternative" "0,1")
7543 (match_operand 1 "memory_operand" ""))
7544 (const_string "vector")]
7545 (const_string "direct")))
7546 (set_attr "mode" "<MODE>")])
7548 (define_insn "*mulsi3_1_zext"
7549 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
7551 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
7552 (match_operand:SI 2 "general_operand" "K,i,mr"))))
7553 (clobber (reg:CC FLAGS_REG))]
7555 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7557 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7558 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
7559 imul{l}\t{%2, %k0|%k0, %2}"
7560 [(set_attr "type" "imul")
7561 (set_attr "prefix_0f" "0,0,1")
7562 (set (attr "athlon_decode")
7563 (cond [(eq_attr "cpu" "athlon")
7564 (const_string "vector")
7565 (eq_attr "alternative" "1")
7566 (const_string "vector")
7567 (and (eq_attr "alternative" "2")
7568 (match_operand 1 "memory_operand" ""))
7569 (const_string "vector")]
7570 (const_string "direct")))
7571 (set (attr "amdfam10_decode")
7572 (cond [(and (eq_attr "alternative" "0,1")
7573 (match_operand 1 "memory_operand" ""))
7574 (const_string "vector")]
7575 (const_string "direct")))
7576 (set_attr "mode" "SI")])
7579 ;; IMUL reg16, reg16, imm8 VectorPath
7580 ;; IMUL reg16, mem16, imm8 VectorPath
7581 ;; IMUL reg16, reg16, imm16 VectorPath
7582 ;; IMUL reg16, mem16, imm16 VectorPath
7583 ;; IMUL reg16, reg16 Direct
7584 ;; IMUL reg16, mem16 Direct
7586 (define_insn "*mulhi3_1"
7587 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
7588 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
7589 (match_operand:HI 2 "general_operand" "K,n,mr")))
7590 (clobber (reg:CC FLAGS_REG))]
7592 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7594 imul{w}\t{%2, %1, %0|%0, %1, %2}
7595 imul{w}\t{%2, %1, %0|%0, %1, %2}
7596 imul{w}\t{%2, %0|%0, %2}"
7597 [(set_attr "type" "imul")
7598 (set_attr "prefix_0f" "0,0,1")
7599 (set (attr "athlon_decode")
7600 (cond [(eq_attr "cpu" "athlon")
7601 (const_string "vector")
7602 (eq_attr "alternative" "1,2")
7603 (const_string "vector")]
7604 (const_string "direct")))
7605 (set (attr "amdfam10_decode")
7606 (cond [(eq_attr "alternative" "0,1")
7607 (const_string "vector")]
7608 (const_string "direct")))
7609 (set_attr "mode" "HI")])
7615 (define_insn "*mulqi3_1"
7616 [(set (match_operand:QI 0 "register_operand" "=a")
7617 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7618 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7619 (clobber (reg:CC FLAGS_REG))]
7621 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7623 [(set_attr "type" "imul")
7624 (set_attr "length_immediate" "0")
7625 (set (attr "athlon_decode")
7626 (if_then_else (eq_attr "cpu" "athlon")
7627 (const_string "vector")
7628 (const_string "direct")))
7629 (set_attr "amdfam10_decode" "direct")
7630 (set_attr "mode" "QI")])
7632 (define_expand "<u>mul<mode><dwi>3"
7633 [(parallel [(set (match_operand:<DWI> 0 "register_operand" "")
7636 (match_operand:DWIH 1 "nonimmediate_operand" ""))
7638 (match_operand:DWIH 2 "register_operand" ""))))
7639 (clobber (reg:CC FLAGS_REG))])]
7643 (define_expand "<u>mulqihi3"
7644 [(parallel [(set (match_operand:HI 0 "register_operand" "")
7647 (match_operand:QI 1 "nonimmediate_operand" ""))
7649 (match_operand:QI 2 "register_operand" ""))))
7650 (clobber (reg:CC FLAGS_REG))])]
7651 "TARGET_QIMODE_MATH"
7654 (define_insn "*<u>mul<mode><dwi>3_1"
7655 [(set (match_operand:<DWI> 0 "register_operand" "=A")
7658 (match_operand:DWIH 1 "nonimmediate_operand" "%0"))
7660 (match_operand:DWIH 2 "nonimmediate_operand" "rm"))))
7661 (clobber (reg:CC FLAGS_REG))]
7662 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7663 "<sgnprefix>mul{<imodesuffix>}\t%2"
7664 [(set_attr "type" "imul")
7665 (set_attr "length_immediate" "0")
7666 (set (attr "athlon_decode")
7667 (if_then_else (eq_attr "cpu" "athlon")
7668 (const_string "vector")
7669 (const_string "double")))
7670 (set_attr "amdfam10_decode" "double")
7671 (set_attr "mode" "<MODE>")])
7673 (define_insn "*<u>mulqihi3_1"
7674 [(set (match_operand:HI 0 "register_operand" "=a")
7677 (match_operand:QI 1 "nonimmediate_operand" "%0"))
7679 (match_operand:QI 2 "nonimmediate_operand" "qm"))))
7680 (clobber (reg:CC FLAGS_REG))]
7682 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7683 "<sgnprefix>mul{b}\t%2"
7684 [(set_attr "type" "imul")
7685 (set_attr "length_immediate" "0")
7686 (set (attr "athlon_decode")
7687 (if_then_else (eq_attr "cpu" "athlon")
7688 (const_string "vector")
7689 (const_string "direct")))
7690 (set_attr "amdfam10_decode" "direct")
7691 (set_attr "mode" "QI")])
7693 (define_expand "<s>mul<mode>3_highpart"
7694 [(parallel [(set (match_operand:SWI48 0 "register_operand" "")
7699 (match_operand:SWI48 1 "nonimmediate_operand" ""))
7701 (match_operand:SWI48 2 "register_operand" "")))
7703 (clobber (match_scratch:SWI48 3 ""))
7704 (clobber (reg:CC FLAGS_REG))])]
7706 "operands[4] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode));")
7708 (define_insn "*<s>muldi3_highpart_1"
7709 [(set (match_operand:DI 0 "register_operand" "=d")
7714 (match_operand:DI 1 "nonimmediate_operand" "%a"))
7716 (match_operand:DI 2 "nonimmediate_operand" "rm")))
7718 (clobber (match_scratch:DI 3 "=1"))
7719 (clobber (reg:CC FLAGS_REG))]
7721 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7722 "<sgnprefix>mul{q}\t%2"
7723 [(set_attr "type" "imul")
7724 (set_attr "length_immediate" "0")
7725 (set (attr "athlon_decode")
7726 (if_then_else (eq_attr "cpu" "athlon")
7727 (const_string "vector")
7728 (const_string "double")))
7729 (set_attr "amdfam10_decode" "double")
7730 (set_attr "mode" "DI")])
7732 (define_insn "*<s>mulsi3_highpart_1"
7733 [(set (match_operand:SI 0 "register_operand" "=d")
7738 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7740 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7742 (clobber (match_scratch:SI 3 "=1"))
7743 (clobber (reg:CC FLAGS_REG))]
7744 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
7745 "<sgnprefix>mul{l}\t%2"
7746 [(set_attr "type" "imul")
7747 (set_attr "length_immediate" "0")
7748 (set (attr "athlon_decode")
7749 (if_then_else (eq_attr "cpu" "athlon")
7750 (const_string "vector")
7751 (const_string "double")))
7752 (set_attr "amdfam10_decode" "double")
7753 (set_attr "mode" "SI")])
7755 (define_insn "*<s>mulsi3_highpart_zext"
7756 [(set (match_operand:DI 0 "register_operand" "=d")
7757 (zero_extend:DI (truncate:SI
7759 (mult:DI (any_extend:DI
7760 (match_operand:SI 1 "nonimmediate_operand" "%a"))
7762 (match_operand:SI 2 "nonimmediate_operand" "rm")))
7764 (clobber (match_scratch:SI 3 "=1"))
7765 (clobber (reg:CC FLAGS_REG))]
7767 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7768 "<sgnprefix>mul{l}\t%2"
7769 [(set_attr "type" "imul")
7770 (set_attr "length_immediate" "0")
7771 (set (attr "athlon_decode")
7772 (if_then_else (eq_attr "cpu" "athlon")
7773 (const_string "vector")
7774 (const_string "double")))
7775 (set_attr "amdfam10_decode" "double")
7776 (set_attr "mode" "SI")])
7778 ;; The patterns that match these are at the end of this file.
7780 (define_expand "mulxf3"
7781 [(set (match_operand:XF 0 "register_operand" "")
7782 (mult:XF (match_operand:XF 1 "register_operand" "")
7783 (match_operand:XF 2 "register_operand" "")))]
7787 (define_expand "mul<mode>3"
7788 [(set (match_operand:MODEF 0 "register_operand" "")
7789 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
7790 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7791 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7792 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7795 ;; Divide instructions
7797 (define_insn "<u>divqi3"
7798 [(set (match_operand:QI 0 "register_operand" "=a")
7800 (match_operand:HI 1 "register_operand" "0")
7801 (match_operand:QI 2 "nonimmediate_operand" "qm")))
7802 (clobber (reg:CC FLAGS_REG))]
7803 "TARGET_QIMODE_MATH"
7804 "<sgnprefix>div{b}\t%2"
7805 [(set_attr "type" "idiv")
7806 (set_attr "mode" "QI")])
7808 ;; The patterns that match these are at the end of this file.
7810 (define_expand "divxf3"
7811 [(set (match_operand:XF 0 "register_operand" "")
7812 (div:XF (match_operand:XF 1 "register_operand" "")
7813 (match_operand:XF 2 "register_operand" "")))]
7817 (define_expand "divdf3"
7818 [(set (match_operand:DF 0 "register_operand" "")
7819 (div:DF (match_operand:DF 1 "register_operand" "")
7820 (match_operand:DF 2 "nonimmediate_operand" "")))]
7821 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
7822 || (TARGET_SSE2 && TARGET_SSE_MATH)"
7825 (define_expand "divsf3"
7826 [(set (match_operand:SF 0 "register_operand" "")
7827 (div:SF (match_operand:SF 1 "register_operand" "")
7828 (match_operand:SF 2 "nonimmediate_operand" "")))]
7829 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
7832 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
7833 && flag_finite_math_only && !flag_trapping_math
7834 && flag_unsafe_math_optimizations)
7836 ix86_emit_swdivsf (operands[0], operands[1],
7837 operands[2], SFmode);
7842 ;; Divmod instructions.
7844 (define_expand "divmod<mode>4"
7845 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7847 (match_operand:SWIM248 1 "register_operand" "")
7848 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7849 (set (match_operand:SWIM248 3 "register_operand" "")
7850 (mod:SWIM248 (match_dup 1) (match_dup 2)))
7851 (clobber (reg:CC FLAGS_REG))])]
7855 (define_insn_and_split "*divmod<mode>4"
7856 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7857 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7858 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7859 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7860 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7861 (clobber (reg:CC FLAGS_REG))]
7864 "&& reload_completed"
7865 [(parallel [(set (match_dup 1)
7866 (ashiftrt:SWIM248 (match_dup 4) (match_dup 5)))
7867 (clobber (reg:CC FLAGS_REG))])
7868 (parallel [(set (match_dup 0)
7869 (div:SWIM248 (match_dup 2) (match_dup 3)))
7871 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7873 (clobber (reg:CC FLAGS_REG))])]
7875 operands[5] = GEN_INT (GET_MODE_BITSIZE (<MODE>mode) - 1);
7877 if (<MODE>mode != HImode
7878 && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD))
7879 operands[4] = operands[2];
7882 /* Avoid use of cltd in favor of a mov+shift. */
7883 emit_move_insn (operands[1], operands[2]);
7884 operands[4] = operands[1];
7887 [(set_attr "type" "multi")
7888 (set_attr "mode" "<MODE>")])
7890 (define_insn "*divmod<mode>4_noext"
7891 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7892 (div:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7893 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7894 (set (match_operand:SWIM248 1 "register_operand" "=d")
7895 (mod:SWIM248 (match_dup 2) (match_dup 3)))
7896 (use (match_operand:SWIM248 4 "register_operand" "1"))
7897 (clobber (reg:CC FLAGS_REG))]
7899 "idiv{<imodesuffix>}\t%3"
7900 [(set_attr "type" "idiv")
7901 (set_attr "mode" "<MODE>")])
7903 (define_expand "udivmod<mode>4"
7904 [(parallel [(set (match_operand:SWIM248 0 "register_operand" "")
7906 (match_operand:SWIM248 1 "register_operand" "")
7907 (match_operand:SWIM248 2 "nonimmediate_operand" "")))
7908 (set (match_operand:SWIM248 3 "register_operand" "")
7909 (umod:SWIM248 (match_dup 1) (match_dup 2)))
7910 (clobber (reg:CC FLAGS_REG))])]
7914 (define_insn_and_split "*udivmod<mode>4"
7915 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7916 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7917 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7918 (set (match_operand:SWIM248 1 "register_operand" "=&d")
7919 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7920 (clobber (reg:CC FLAGS_REG))]
7923 "&& reload_completed"
7924 [(set (match_dup 1) (const_int 0))
7925 (parallel [(set (match_dup 0)
7926 (udiv:SWIM248 (match_dup 2) (match_dup 3)))
7928 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7930 (clobber (reg:CC FLAGS_REG))])]
7932 [(set_attr "type" "multi")
7933 (set_attr "mode" "<MODE>")])
7935 (define_insn "*udivmod<mode>4_noext"
7936 [(set (match_operand:SWIM248 0 "register_operand" "=a")
7937 (udiv:SWIM248 (match_operand:SWIM248 2 "register_operand" "0")
7938 (match_operand:SWIM248 3 "nonimmediate_operand" "rm")))
7939 (set (match_operand:SWIM248 1 "register_operand" "=d")
7940 (umod:SWIM248 (match_dup 2) (match_dup 3)))
7941 (use (match_operand:SWIM248 4 "register_operand" "1"))
7942 (clobber (reg:CC FLAGS_REG))]
7944 "div{<imodesuffix>}\t%3"
7945 [(set_attr "type" "idiv")
7946 (set_attr "mode" "<MODE>")])
7948 ;; We cannot use div/idiv for double division, because it causes
7949 ;; "division by zero" on the overflow and that's not what we expect
7950 ;; from truncate. Because true (non truncating) double division is
7951 ;; never generated, we can't create this insn anyway.
7954 ; [(set (match_operand:SI 0 "register_operand" "=a")
7956 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
7958 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
7959 ; (set (match_operand:SI 3 "register_operand" "=d")
7961 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
7962 ; (clobber (reg:CC FLAGS_REG))]
7964 ; "div{l}\t{%2, %0|%0, %2}"
7965 ; [(set_attr "type" "idiv")])
7967 ;;- Logical AND instructions
7969 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
7970 ;; Note that this excludes ah.
7972 (define_expand "testsi_ccno_1"
7973 [(set (reg:CCNO FLAGS_REG)
7975 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
7976 (match_operand:SI 1 "nonmemory_operand" ""))
7981 (define_expand "testqi_ccz_1"
7982 [(set (reg:CCZ FLAGS_REG)
7983 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
7984 (match_operand:QI 1 "nonmemory_operand" ""))
7989 (define_insn "*testdi_1"
7990 [(set (reg FLAGS_REG)
7993 (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
7994 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
7996 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
7997 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7999 test{l}\t{%k1, %k0|%k0, %k1}
8000 test{l}\t{%k1, %k0|%k0, %k1}
8001 test{q}\t{%1, %0|%0, %1}
8002 test{q}\t{%1, %0|%0, %1}
8003 test{q}\t{%1, %0|%0, %1}"
8004 [(set_attr "type" "test")
8005 (set_attr "modrm" "0,1,0,1,1")
8006 (set_attr "mode" "SI,SI,DI,DI,DI")])
8008 (define_insn "*testqi_1_maybe_si"
8009 [(set (reg FLAGS_REG)
8012 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
8013 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
8015 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
8016 && ix86_match_ccmode (insn,
8017 CONST_INT_P (operands[1])
8018 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
8020 if (which_alternative == 3)
8022 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
8023 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
8024 return "test{l}\t{%1, %k0|%k0, %1}";
8026 return "test{b}\t{%1, %0|%0, %1}";
8028 [(set_attr "type" "test")
8029 (set_attr "modrm" "0,1,1,1")
8030 (set_attr "mode" "QI,QI,QI,SI")
8031 (set_attr "pent_pair" "uv,np,uv,np")])
8033 (define_insn "*test<mode>_1"
8034 [(set (reg FLAGS_REG)
8037 (match_operand:SWI124 0 "nonimmediate_operand" "%!*a,<r>,<r>m")
8038 (match_operand:SWI124 1 "general_operand" "<i>,<i>,<r><i>"))
8040 "ix86_match_ccmode (insn, CCNOmode)
8041 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8042 "test{<imodesuffix>}\t{%1, %0|%0, %1}"
8043 [(set_attr "type" "test")
8044 (set_attr "modrm" "0,1,1")
8045 (set_attr "mode" "<MODE>")
8046 (set_attr "pent_pair" "uv,np,uv")])
8048 (define_expand "testqi_ext_ccno_0"
8049 [(set (reg:CCNO FLAGS_REG)
8053 (match_operand 0 "ext_register_operand" "")
8056 (match_operand 1 "const_int_operand" ""))
8061 (define_insn "*testqi_ext_0"
8062 [(set (reg FLAGS_REG)
8066 (match_operand 0 "ext_register_operand" "Q")
8069 (match_operand 1 "const_int_operand" "n"))
8071 "ix86_match_ccmode (insn, CCNOmode)"
8072 "test{b}\t{%1, %h0|%h0, %1}"
8073 [(set_attr "type" "test")
8074 (set_attr "mode" "QI")
8075 (set_attr "length_immediate" "1")
8076 (set_attr "modrm" "1")
8077 (set_attr "pent_pair" "np")])
8079 (define_insn "*testqi_ext_1_rex64"
8080 [(set (reg FLAGS_REG)
8084 (match_operand 0 "ext_register_operand" "Q")
8088 (match_operand:QI 1 "register_operand" "Q")))
8090 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8091 "test{b}\t{%1, %h0|%h0, %1}"
8092 [(set_attr "type" "test")
8093 (set_attr "mode" "QI")])
8095 (define_insn "*testqi_ext_1"
8096 [(set (reg FLAGS_REG)
8100 (match_operand 0 "ext_register_operand" "Q")
8104 (match_operand:QI 1 "general_operand" "Qm")))
8106 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
8107 "test{b}\t{%1, %h0|%h0, %1}"
8108 [(set_attr "type" "test")
8109 (set_attr "mode" "QI")])
8111 (define_insn "*testqi_ext_2"
8112 [(set (reg FLAGS_REG)
8116 (match_operand 0 "ext_register_operand" "Q")
8120 (match_operand 1 "ext_register_operand" "Q")
8124 "ix86_match_ccmode (insn, CCNOmode)"
8125 "test{b}\t{%h1, %h0|%h0, %h1}"
8126 [(set_attr "type" "test")
8127 (set_attr "mode" "QI")])
8129 (define_insn "*testqi_ext_3_rex64"
8130 [(set (reg FLAGS_REG)
8131 (compare (zero_extract:DI
8132 (match_operand 0 "nonimmediate_operand" "rm")
8133 (match_operand:DI 1 "const_int_operand" "")
8134 (match_operand:DI 2 "const_int_operand" ""))
8137 && ix86_match_ccmode (insn, CCNOmode)
8138 && INTVAL (operands[1]) > 0
8139 && INTVAL (operands[2]) >= 0
8140 /* Ensure that resulting mask is zero or sign extended operand. */
8141 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8142 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
8143 && INTVAL (operands[1]) > 32))
8144 && (GET_MODE (operands[0]) == SImode
8145 || GET_MODE (operands[0]) == DImode
8146 || GET_MODE (operands[0]) == HImode
8147 || GET_MODE (operands[0]) == QImode)"
8150 ;; Combine likes to form bit extractions for some tests. Humor it.
8151 (define_insn "*testqi_ext_3"
8152 [(set (reg FLAGS_REG)
8153 (compare (zero_extract:SI
8154 (match_operand 0 "nonimmediate_operand" "rm")
8155 (match_operand:SI 1 "const_int_operand" "")
8156 (match_operand:SI 2 "const_int_operand" ""))
8158 "ix86_match_ccmode (insn, CCNOmode)
8159 && INTVAL (operands[1]) > 0
8160 && INTVAL (operands[2]) >= 0
8161 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
8162 && (GET_MODE (operands[0]) == SImode
8163 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
8164 || GET_MODE (operands[0]) == HImode
8165 || GET_MODE (operands[0]) == QImode)"
8169 [(set (match_operand 0 "flags_reg_operand" "")
8170 (match_operator 1 "compare_operator"
8172 (match_operand 2 "nonimmediate_operand" "")
8173 (match_operand 3 "const_int_operand" "")
8174 (match_operand 4 "const_int_operand" ""))
8176 "ix86_match_ccmode (insn, CCNOmode)"
8177 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
8179 rtx val = operands[2];
8180 HOST_WIDE_INT len = INTVAL (operands[3]);
8181 HOST_WIDE_INT pos = INTVAL (operands[4]);
8183 enum machine_mode mode, submode;
8185 mode = GET_MODE (val);
8188 /* ??? Combine likes to put non-volatile mem extractions in QImode
8189 no matter the size of the test. So find a mode that works. */
8190 if (! MEM_VOLATILE_P (val))
8192 mode = smallest_mode_for_size (pos + len, MODE_INT);
8193 val = adjust_address (val, mode, 0);
8196 else if (GET_CODE (val) == SUBREG
8197 && (submode = GET_MODE (SUBREG_REG (val)),
8198 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
8199 && pos + len <= GET_MODE_BITSIZE (submode)
8200 && GET_MODE_CLASS (submode) == MODE_INT)
8202 /* Narrow a paradoxical subreg to prevent partial register stalls. */
8204 val = SUBREG_REG (val);
8206 else if (mode == HImode && pos + len <= 8)
8208 /* Small HImode tests can be converted to QImode. */
8210 val = gen_lowpart (QImode, val);
8213 if (len == HOST_BITS_PER_WIDE_INT)
8216 mask = ((HOST_WIDE_INT)1 << len) - 1;
8219 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
8222 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
8223 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
8224 ;; this is relatively important trick.
8225 ;; Do the conversion only post-reload to avoid limiting of the register class
8228 [(set (match_operand 0 "flags_reg_operand" "")
8229 (match_operator 1 "compare_operator"
8230 [(and (match_operand 2 "register_operand" "")
8231 (match_operand 3 "const_int_operand" ""))
8234 && QI_REG_P (operands[2])
8235 && GET_MODE (operands[2]) != QImode
8236 && ((ix86_match_ccmode (insn, CCZmode)
8237 && !(INTVAL (operands[3]) & ~(255 << 8)))
8238 || (ix86_match_ccmode (insn, CCNOmode)
8239 && !(INTVAL (operands[3]) & ~(127 << 8))))"
8242 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
8245 "operands[2] = gen_lowpart (SImode, operands[2]);
8246 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
8249 [(set (match_operand 0 "flags_reg_operand" "")
8250 (match_operator 1 "compare_operator"
8251 [(and (match_operand 2 "nonimmediate_operand" "")
8252 (match_operand 3 "const_int_operand" ""))
8255 && GET_MODE (operands[2]) != QImode
8256 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
8257 && ((ix86_match_ccmode (insn, CCZmode)
8258 && !(INTVAL (operands[3]) & ~255))
8259 || (ix86_match_ccmode (insn, CCNOmode)
8260 && !(INTVAL (operands[3]) & ~127)))"
8262 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
8264 "operands[2] = gen_lowpart (QImode, operands[2]);
8265 operands[3] = gen_lowpart (QImode, operands[3]);")
8267 ;; %%% This used to optimize known byte-wide and operations to memory,
8268 ;; and sometimes to QImode registers. If this is considered useful,
8269 ;; it should be done with splitters.
8271 (define_expand "and<mode>3"
8272 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8273 (and:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8274 (match_operand:SWIM 2 "<general_szext_operand>" "")))]
8276 "ix86_expand_binary_operator (AND, <MODE>mode, operands); DONE;")
8278 (define_insn "*anddi_1"
8279 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
8281 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
8282 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
8283 (clobber (reg:CC FLAGS_REG))]
8284 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
8286 switch (get_attr_type (insn))
8290 enum machine_mode mode;
8292 gcc_assert (CONST_INT_P (operands[2]));
8293 if (INTVAL (operands[2]) == 0xff)
8297 gcc_assert (INTVAL (operands[2]) == 0xffff);
8301 operands[1] = gen_lowpart (mode, operands[1]);
8303 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
8305 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
8309 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8310 if (get_attr_mode (insn) == MODE_SI)
8311 return "and{l}\t{%k2, %k0|%k0, %k2}";
8313 return "and{q}\t{%2, %0|%0, %2}";
8316 [(set_attr "type" "alu,alu,alu,imovx")
8317 (set_attr "length_immediate" "*,*,*,0")
8318 (set (attr "prefix_rex")
8320 (and (eq_attr "type" "imovx")
8321 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8322 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8324 (const_string "*")))
8325 (set_attr "mode" "SI,DI,DI,SI")])
8327 (define_insn "*andsi_1"
8328 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
8329 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
8330 (match_operand:SI 2 "general_operand" "ri,rm,L")))
8331 (clobber (reg:CC FLAGS_REG))]
8332 "ix86_binary_operator_ok (AND, SImode, operands)"
8334 switch (get_attr_type (insn))
8338 enum machine_mode mode;
8340 gcc_assert (CONST_INT_P (operands[2]));
8341 if (INTVAL (operands[2]) == 0xff)
8345 gcc_assert (INTVAL (operands[2]) == 0xffff);
8349 operands[1] = gen_lowpart (mode, operands[1]);
8351 return "movz{bl|x}\t{%1, %0|%0, %1}";
8353 return "movz{wl|x}\t{%1, %0|%0, %1}";
8357 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8358 return "and{l}\t{%2, %0|%0, %2}";
8361 [(set_attr "type" "alu,alu,imovx")
8362 (set (attr "prefix_rex")
8364 (and (eq_attr "type" "imovx")
8365 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
8366 (match_operand 1 "ext_QIreg_nomode_operand" "")))
8368 (const_string "*")))
8369 (set_attr "length_immediate" "*,*,0")
8370 (set_attr "mode" "SI")])
8372 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8373 (define_insn "*andsi_1_zext"
8374 [(set (match_operand:DI 0 "register_operand" "=r")
8376 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8377 (match_operand:SI 2 "general_operand" "g"))))
8378 (clobber (reg:CC FLAGS_REG))]
8379 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
8380 "and{l}\t{%2, %k0|%k0, %2}"
8381 [(set_attr "type" "alu")
8382 (set_attr "mode" "SI")])
8384 (define_insn "*andhi_1"
8385 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
8386 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
8387 (match_operand:HI 2 "general_operand" "rn,rm,L")))
8388 (clobber (reg:CC FLAGS_REG))]
8389 "ix86_binary_operator_ok (AND, HImode, operands)"
8391 switch (get_attr_type (insn))
8394 gcc_assert (CONST_INT_P (operands[2]));
8395 gcc_assert (INTVAL (operands[2]) == 0xff);
8396 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
8399 gcc_assert (rtx_equal_p (operands[0], operands[1]));
8401 return "and{w}\t{%2, %0|%0, %2}";
8404 [(set_attr "type" "alu,alu,imovx")
8405 (set_attr "length_immediate" "*,*,0")
8406 (set (attr "prefix_rex")
8408 (and (eq_attr "type" "imovx")
8409 (match_operand 1 "ext_QIreg_nomode_operand" ""))
8411 (const_string "*")))
8412 (set_attr "mode" "HI,HI,SI")])
8414 ;; %%% Potential partial reg stall on alternative 2. What to do?
8415 (define_insn "*andqi_1"
8416 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
8417 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8418 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
8419 (clobber (reg:CC FLAGS_REG))]
8420 "ix86_binary_operator_ok (AND, QImode, operands)"
8422 and{b}\t{%2, %0|%0, %2}
8423 and{b}\t{%2, %0|%0, %2}
8424 and{l}\t{%k2, %k0|%k0, %k2}"
8425 [(set_attr "type" "alu")
8426 (set_attr "mode" "QI,QI,SI")])
8428 (define_insn "*andqi_1_slp"
8429 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8430 (and:QI (match_dup 0)
8431 (match_operand:QI 1 "general_operand" "qn,qmn")))
8432 (clobber (reg:CC FLAGS_REG))]
8433 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8434 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8435 "and{b}\t{%1, %0|%0, %1}"
8436 [(set_attr "type" "alu1")
8437 (set_attr "mode" "QI")])
8440 [(set (match_operand 0 "register_operand" "")
8442 (const_int -65536)))
8443 (clobber (reg:CC FLAGS_REG))]
8444 "(TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)
8445 || optimize_function_for_size_p (cfun)"
8446 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8447 "operands[1] = gen_lowpart (HImode, operands[0]);")
8450 [(set (match_operand 0 "ext_register_operand" "")
8453 (clobber (reg:CC FLAGS_REG))]
8454 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8455 && reload_completed"
8456 [(set (strict_low_part (match_dup 1)) (const_int 0))]
8457 "operands[1] = gen_lowpart (QImode, operands[0]);")
8460 [(set (match_operand 0 "ext_register_operand" "")
8462 (const_int -65281)))
8463 (clobber (reg:CC FLAGS_REG))]
8464 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8465 && reload_completed"
8466 [(parallel [(set (zero_extract:SI (match_dup 0)
8470 (zero_extract:SI (match_dup 0)
8473 (zero_extract:SI (match_dup 0)
8476 (clobber (reg:CC FLAGS_REG))])]
8477 "operands[0] = gen_lowpart (SImode, operands[0]);")
8479 (define_insn "*anddi_2"
8480 [(set (reg FLAGS_REG)
8483 (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
8484 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
8486 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
8487 (and:DI (match_dup 1) (match_dup 2)))]
8488 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8489 && ix86_binary_operator_ok (AND, DImode, operands)"
8491 and{l}\t{%k2, %k0|%k0, %k2}
8492 and{q}\t{%2, %0|%0, %2}
8493 and{q}\t{%2, %0|%0, %2}"
8494 [(set_attr "type" "alu")
8495 (set_attr "mode" "SI,DI,DI")])
8497 (define_insn "*andqi_2_maybe_si"
8498 [(set (reg FLAGS_REG)
8500 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8501 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
8503 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
8504 (and:QI (match_dup 1) (match_dup 2)))]
8505 "ix86_binary_operator_ok (AND, QImode, operands)
8506 && ix86_match_ccmode (insn,
8507 CONST_INT_P (operands[2])
8508 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
8510 if (which_alternative == 2)
8512 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
8513 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
8514 return "and{l}\t{%2, %k0|%k0, %2}";
8516 return "and{b}\t{%2, %0|%0, %2}";
8518 [(set_attr "type" "alu")
8519 (set_attr "mode" "QI,QI,SI")])
8521 (define_insn "*and<mode>_2"
8522 [(set (reg FLAGS_REG)
8523 (compare (and:SWI124
8524 (match_operand:SWI124 1 "nonimmediate_operand" "%0,0")
8525 (match_operand:SWI124 2 "general_operand" "<g>,<r><i>"))
8527 (set (match_operand:SWI124 0 "nonimmediate_operand" "=<r>,<r>m")
8528 (and:SWI124 (match_dup 1) (match_dup 2)))]
8529 "ix86_match_ccmode (insn, CCNOmode)
8530 && ix86_binary_operator_ok (AND, <MODE>mode, operands)"
8531 "and{<imodesuffix>}\t{%2, %0|%0, %2}"
8532 [(set_attr "type" "alu")
8533 (set_attr "mode" "<MODE>")])
8535 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8536 (define_insn "*andsi_2_zext"
8537 [(set (reg FLAGS_REG)
8539 (match_operand:SI 1 "nonimmediate_operand" "%0")
8540 (match_operand:SI 2 "general_operand" "g"))
8542 (set (match_operand:DI 0 "register_operand" "=r")
8543 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
8544 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8545 && ix86_binary_operator_ok (AND, SImode, operands)"
8546 "and{l}\t{%2, %k0|%k0, %2}"
8547 [(set_attr "type" "alu")
8548 (set_attr "mode" "SI")])
8550 (define_insn "*andqi_2_slp"
8551 [(set (reg FLAGS_REG)
8553 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8554 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
8556 (set (strict_low_part (match_dup 0))
8557 (and:QI (match_dup 0) (match_dup 1)))]
8558 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8559 && ix86_match_ccmode (insn, CCNOmode)
8560 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8561 "and{b}\t{%1, %0|%0, %1}"
8562 [(set_attr "type" "alu1")
8563 (set_attr "mode" "QI")])
8565 ;; ??? A bug in recog prevents it from recognizing a const_int as an
8566 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
8567 ;; for a QImode operand, which of course failed.
8568 (define_insn "andqi_ext_0"
8569 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8574 (match_operand 1 "ext_register_operand" "0")
8577 (match_operand 2 "const_int_operand" "n")))
8578 (clobber (reg:CC FLAGS_REG))]
8580 "and{b}\t{%2, %h0|%h0, %2}"
8581 [(set_attr "type" "alu")
8582 (set_attr "length_immediate" "1")
8583 (set_attr "modrm" "1")
8584 (set_attr "mode" "QI")])
8586 ;; Generated by peephole translating test to and. This shows up
8587 ;; often in fp comparisons.
8588 (define_insn "*andqi_ext_0_cc"
8589 [(set (reg FLAGS_REG)
8593 (match_operand 1 "ext_register_operand" "0")
8596 (match_operand 2 "const_int_operand" "n"))
8598 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8607 "ix86_match_ccmode (insn, CCNOmode)"
8608 "and{b}\t{%2, %h0|%h0, %2}"
8609 [(set_attr "type" "alu")
8610 (set_attr "length_immediate" "1")
8611 (set_attr "modrm" "1")
8612 (set_attr "mode" "QI")])
8614 (define_insn "*andqi_ext_1_rex64"
8615 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8620 (match_operand 1 "ext_register_operand" "0")
8624 (match_operand 2 "ext_register_operand" "Q"))))
8625 (clobber (reg:CC FLAGS_REG))]
8627 "and{b}\t{%2, %h0|%h0, %2}"
8628 [(set_attr "type" "alu")
8629 (set_attr "length_immediate" "0")
8630 (set_attr "mode" "QI")])
8632 (define_insn "*andqi_ext_1"
8633 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8638 (match_operand 1 "ext_register_operand" "0")
8642 (match_operand:QI 2 "general_operand" "Qm"))))
8643 (clobber (reg:CC FLAGS_REG))]
8645 "and{b}\t{%2, %h0|%h0, %2}"
8646 [(set_attr "type" "alu")
8647 (set_attr "length_immediate" "0")
8648 (set_attr "mode" "QI")])
8650 (define_insn "*andqi_ext_2"
8651 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8656 (match_operand 1 "ext_register_operand" "%0")
8660 (match_operand 2 "ext_register_operand" "Q")
8663 (clobber (reg:CC FLAGS_REG))]
8665 "and{b}\t{%h2, %h0|%h0, %h2}"
8666 [(set_attr "type" "alu")
8667 (set_attr "length_immediate" "0")
8668 (set_attr "mode" "QI")])
8670 ;; Convert wide AND instructions with immediate operand to shorter QImode
8671 ;; equivalents when possible.
8672 ;; Don't do the splitting with memory operands, since it introduces risk
8673 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
8674 ;; for size, but that can (should?) be handled by generic code instead.
8676 [(set (match_operand 0 "register_operand" "")
8677 (and (match_operand 1 "register_operand" "")
8678 (match_operand 2 "const_int_operand" "")))
8679 (clobber (reg:CC FLAGS_REG))]
8681 && QI_REG_P (operands[0])
8682 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8683 && !(~INTVAL (operands[2]) & ~(255 << 8))
8684 && GET_MODE (operands[0]) != QImode"
8685 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8686 (and:SI (zero_extract:SI (match_dup 1)
8687 (const_int 8) (const_int 8))
8689 (clobber (reg:CC FLAGS_REG))])]
8690 "operands[0] = gen_lowpart (SImode, operands[0]);
8691 operands[1] = gen_lowpart (SImode, operands[1]);
8692 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8694 ;; Since AND can be encoded with sign extended immediate, this is only
8695 ;; profitable when 7th bit is not set.
8697 [(set (match_operand 0 "register_operand" "")
8698 (and (match_operand 1 "general_operand" "")
8699 (match_operand 2 "const_int_operand" "")))
8700 (clobber (reg:CC FLAGS_REG))]
8702 && ANY_QI_REG_P (operands[0])
8703 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8704 && !(~INTVAL (operands[2]) & ~255)
8705 && !(INTVAL (operands[2]) & 128)
8706 && GET_MODE (operands[0]) != QImode"
8707 [(parallel [(set (strict_low_part (match_dup 0))
8708 (and:QI (match_dup 1)
8710 (clobber (reg:CC FLAGS_REG))])]
8711 "operands[0] = gen_lowpart (QImode, operands[0]);
8712 operands[1] = gen_lowpart (QImode, operands[1]);
8713 operands[2] = gen_lowpart (QImode, operands[2]);")
8715 ;; Logical inclusive and exclusive OR instructions
8717 ;; %%% This used to optimize known byte-wide and operations to memory.
8718 ;; If this is considered useful, it should be done with splitters.
8720 (define_expand "<code><mode>3"
8721 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
8722 (any_or:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")
8723 (match_operand:SWIM 2 "<general_operand>" "")))]
8725 "ix86_expand_binary_operator (<CODE>, <MODE>mode, operands); DONE;")
8727 (define_insn "*<code><mode>_1"
8728 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=r,rm")
8730 (match_operand:SWI248 1 "nonimmediate_operand" "%0,0")
8731 (match_operand:SWI248 2 "<general_operand>" "<g>,r<i>")))
8732 (clobber (reg:CC FLAGS_REG))]
8733 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8734 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8735 [(set_attr "type" "alu")
8736 (set_attr "mode" "<MODE>")])
8738 ;; %%% Potential partial reg stall on alternative 2. What to do?
8739 (define_insn "*<code>qi_1"
8740 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
8741 (any_or:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
8742 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
8743 (clobber (reg:CC FLAGS_REG))]
8744 "ix86_binary_operator_ok (<CODE>, QImode, operands)"
8746 <logicprefix>{b}\t{%2, %0|%0, %2}
8747 <logicprefix>{b}\t{%2, %0|%0, %2}
8748 <logicprefix>{l}\t{%k2, %k0|%k0, %k2}"
8749 [(set_attr "type" "alu")
8750 (set_attr "mode" "QI,QI,SI")])
8752 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8753 (define_insn "*<code>si_1_zext"
8754 [(set (match_operand:DI 0 "register_operand" "=r")
8756 (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8757 (match_operand:SI 2 "general_operand" "g"))))
8758 (clobber (reg:CC FLAGS_REG))]
8759 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8760 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8761 [(set_attr "type" "alu")
8762 (set_attr "mode" "SI")])
8764 (define_insn "*<code>si_1_zext_imm"
8765 [(set (match_operand:DI 0 "register_operand" "=r")
8767 (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
8768 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
8769 (clobber (reg:CC FLAGS_REG))]
8770 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8771 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8772 [(set_attr "type" "alu")
8773 (set_attr "mode" "SI")])
8775 (define_insn "*<code>qi_1_slp"
8776 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
8777 (any_or:QI (match_dup 0)
8778 (match_operand:QI 1 "general_operand" "qmn,qn")))
8779 (clobber (reg:CC FLAGS_REG))]
8780 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8781 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8782 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8783 [(set_attr "type" "alu1")
8784 (set_attr "mode" "QI")])
8786 (define_insn "*<code><mode>_2"
8787 [(set (reg FLAGS_REG)
8788 (compare (any_or:SWI
8789 (match_operand:SWI 1 "nonimmediate_operand" "%0,0")
8790 (match_operand:SWI 2 "<general_operand>" "<g>,<r><i>"))
8792 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>,<r>m")
8793 (any_or:SWI (match_dup 1) (match_dup 2)))]
8794 "ix86_match_ccmode (insn, CCNOmode)
8795 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8796 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8797 [(set_attr "type" "alu")
8798 (set_attr "mode" "<MODE>")])
8800 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
8801 ;; ??? Special case for immediate operand is missing - it is tricky.
8802 (define_insn "*<code>si_2_zext"
8803 [(set (reg FLAGS_REG)
8804 (compare (any_or:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
8805 (match_operand:SI 2 "general_operand" "g"))
8807 (set (match_operand:DI 0 "register_operand" "=r")
8808 (zero_extend:DI (any_or:SI (match_dup 1) (match_dup 2))))]
8809 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8810 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8811 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8812 [(set_attr "type" "alu")
8813 (set_attr "mode" "SI")])
8815 (define_insn "*<code>si_2_zext_imm"
8816 [(set (reg FLAGS_REG)
8818 (match_operand:SI 1 "nonimmediate_operand" "%0")
8819 (match_operand:SI 2 "x86_64_zext_immediate_operand" "Z"))
8821 (set (match_operand:DI 0 "register_operand" "=r")
8822 (any_or:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
8823 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
8824 && ix86_binary_operator_ok (<CODE>, SImode, operands)"
8825 "<logicprefix>{l}\t{%2, %k0|%k0, %2}"
8826 [(set_attr "type" "alu")
8827 (set_attr "mode" "SI")])
8829 (define_insn "*<code>qi_2_slp"
8830 [(set (reg FLAGS_REG)
8831 (compare (any_or:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
8832 (match_operand:QI 1 "general_operand" "qmn,qn"))
8834 (set (strict_low_part (match_dup 0))
8835 (any_or:QI (match_dup 0) (match_dup 1)))]
8836 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8837 && ix86_match_ccmode (insn, CCNOmode)
8838 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8839 "<logicprefix>{b}\t{%1, %0|%0, %1}"
8840 [(set_attr "type" "alu1")
8841 (set_attr "mode" "QI")])
8843 (define_insn "*<code><mode>_3"
8844 [(set (reg FLAGS_REG)
8845 (compare (any_or:SWI
8846 (match_operand:SWI 1 "nonimmediate_operand" "%0")
8847 (match_operand:SWI 2 "<general_operand>" "<g>"))
8849 (clobber (match_scratch:SWI 0 "=<r>"))]
8850 "ix86_match_ccmode (insn, CCNOmode)
8851 && ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
8852 "<logicprefix>{<imodesuffix>}\t{%2, %0|%0, %2}"
8853 [(set_attr "type" "alu")
8854 (set_attr "mode" "<MODE>")])
8856 (define_insn "*<code>qi_ext_0"
8857 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8862 (match_operand 1 "ext_register_operand" "0")
8865 (match_operand 2 "const_int_operand" "n")))
8866 (clobber (reg:CC FLAGS_REG))]
8867 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8868 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8869 [(set_attr "type" "alu")
8870 (set_attr "length_immediate" "1")
8871 (set_attr "modrm" "1")
8872 (set_attr "mode" "QI")])
8874 (define_insn "*<code>qi_ext_1_rex64"
8875 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8880 (match_operand 1 "ext_register_operand" "0")
8884 (match_operand 2 "ext_register_operand" "Q"))))
8885 (clobber (reg:CC FLAGS_REG))]
8887 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8888 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8889 [(set_attr "type" "alu")
8890 (set_attr "length_immediate" "0")
8891 (set_attr "mode" "QI")])
8893 (define_insn "*<code>qi_ext_1"
8894 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8899 (match_operand 1 "ext_register_operand" "0")
8903 (match_operand:QI 2 "general_operand" "Qm"))))
8904 (clobber (reg:CC FLAGS_REG))]
8906 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
8907 "<logicprefix>{b}\t{%2, %h0|%h0, %2}"
8908 [(set_attr "type" "alu")
8909 (set_attr "length_immediate" "0")
8910 (set_attr "mode" "QI")])
8912 (define_insn "*<code>qi_ext_2"
8913 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
8917 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
8920 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
8923 (clobber (reg:CC FLAGS_REG))]
8924 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
8925 "<logicprefix>{b}\t{%h2, %h0|%h0, %h2}"
8926 [(set_attr "type" "alu")
8927 (set_attr "length_immediate" "0")
8928 (set_attr "mode" "QI")])
8931 [(set (match_operand 0 "register_operand" "")
8932 (any_or (match_operand 1 "register_operand" "")
8933 (match_operand 2 "const_int_operand" "")))
8934 (clobber (reg:CC FLAGS_REG))]
8936 && QI_REG_P (operands[0])
8937 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8938 && !(INTVAL (operands[2]) & ~(255 << 8))
8939 && GET_MODE (operands[0]) != QImode"
8940 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
8941 (any_or:SI (zero_extract:SI (match_dup 1)
8942 (const_int 8) (const_int 8))
8944 (clobber (reg:CC FLAGS_REG))])]
8945 "operands[0] = gen_lowpart (SImode, operands[0]);
8946 operands[1] = gen_lowpart (SImode, operands[1]);
8947 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
8949 ;; Since OR can be encoded with sign extended immediate, this is only
8950 ;; profitable when 7th bit is set.
8952 [(set (match_operand 0 "register_operand" "")
8953 (any_or (match_operand 1 "general_operand" "")
8954 (match_operand 2 "const_int_operand" "")))
8955 (clobber (reg:CC FLAGS_REG))]
8957 && ANY_QI_REG_P (operands[0])
8958 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8959 && !(INTVAL (operands[2]) & ~255)
8960 && (INTVAL (operands[2]) & 128)
8961 && GET_MODE (operands[0]) != QImode"
8962 [(parallel [(set (strict_low_part (match_dup 0))
8963 (any_or:QI (match_dup 1)
8965 (clobber (reg:CC FLAGS_REG))])]
8966 "operands[0] = gen_lowpart (QImode, operands[0]);
8967 operands[1] = gen_lowpart (QImode, operands[1]);
8968 operands[2] = gen_lowpart (QImode, operands[2]);")
8970 (define_expand "xorqi_cc_ext_1"
8972 (set (reg:CCNO FLAGS_REG)
8976 (match_operand 1 "ext_register_operand" "")
8979 (match_operand:QI 2 "general_operand" ""))
8981 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
8993 (define_insn "*xorqi_cc_ext_1_rex64"
8994 [(set (reg FLAGS_REG)
8998 (match_operand 1 "ext_register_operand" "0")
9001 (match_operand:QI 2 "nonmemory_operand" "Qn"))
9003 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9012 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9013 "xor{b}\t{%2, %h0|%h0, %2}"
9014 [(set_attr "type" "alu")
9015 (set_attr "modrm" "1")
9016 (set_attr "mode" "QI")])
9018 (define_insn "*xorqi_cc_ext_1"
9019 [(set (reg FLAGS_REG)
9023 (match_operand 1 "ext_register_operand" "0")
9026 (match_operand:QI 2 "general_operand" "qmn"))
9028 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
9037 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9038 "xor{b}\t{%2, %h0|%h0, %2}"
9039 [(set_attr "type" "alu")
9040 (set_attr "modrm" "1")
9041 (set_attr "mode" "QI")])
9043 ;; Negation instructions
9045 (define_expand "neg<mode>2"
9046 [(set (match_operand:SDWIM 0 "nonimmediate_operand" "")
9047 (neg:SDWIM (match_operand:SDWIM 1 "nonimmediate_operand" "")))]
9049 "ix86_expand_unary_operator (NEG, <MODE>mode, operands); DONE;")
9051 (define_insn_and_split "*neg<dwi>2_doubleword"
9052 [(set (match_operand:<DWI> 0 "nonimmediate_operand" "=ro")
9053 (neg:<DWI> (match_operand:<DWI> 1 "nonimmediate_operand" "0")))
9054 (clobber (reg:CC FLAGS_REG))]
9055 "ix86_unary_operator_ok (NEG, <DWI>mode, operands)"
9059 [(set (reg:CCZ FLAGS_REG)
9060 (compare:CCZ (neg:DWIH (match_dup 1)) (const_int 0)))
9061 (set (match_dup 0) (neg:DWIH (match_dup 1)))])
9064 (plus:DWIH (match_dup 3)
9065 (plus:DWIH (ltu:DWIH (reg:CC FLAGS_REG) (const_int 0))
9067 (clobber (reg:CC FLAGS_REG))])
9070 (neg:DWIH (match_dup 2)))
9071 (clobber (reg:CC FLAGS_REG))])]
9072 "split_<dwi> (&operands[0], 2, &operands[0], &operands[2]);")
9074 (define_insn "*neg<mode>2_1"
9075 [(set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9076 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0")))
9077 (clobber (reg:CC FLAGS_REG))]
9078 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9079 "neg{<imodesuffix>}\t%0"
9080 [(set_attr "type" "negnot")
9081 (set_attr "mode" "<MODE>")])
9083 ;; Combine is quite creative about this pattern.
9084 (define_insn "*negsi2_1_zext"
9085 [(set (match_operand:DI 0 "register_operand" "=r")
9087 (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
9090 (clobber (reg:CC FLAGS_REG))]
9091 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9093 [(set_attr "type" "negnot")
9094 (set_attr "mode" "SI")])
9096 ;; The problem with neg is that it does not perform (compare x 0),
9097 ;; it really performs (compare 0 x), which leaves us with the zero
9098 ;; flag being the only useful item.
9100 (define_insn "*neg<mode>2_cmpz"
9101 [(set (reg:CCZ FLAGS_REG)
9103 (neg:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9105 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9106 (neg:SWI (match_dup 1)))]
9107 "ix86_unary_operator_ok (NEG, <MODE>mode, operands)"
9108 "neg{<imodesuffix>}\t%0"
9109 [(set_attr "type" "negnot")
9110 (set_attr "mode" "<MODE>")])
9112 (define_insn "*negsi2_cmpz_zext"
9113 [(set (reg:CCZ FLAGS_REG)
9117 (match_operand:DI 1 "register_operand" "0")
9121 (set (match_operand:DI 0 "register_operand" "=r")
9122 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
9125 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
9127 [(set_attr "type" "negnot")
9128 (set_attr "mode" "SI")])
9130 ;; Changing of sign for FP values is doable using integer unit too.
9132 (define_expand "<code><mode>2"
9133 [(set (match_operand:X87MODEF 0 "register_operand" "")
9134 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
9135 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9136 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
9138 (define_insn "*absneg<mode>2_mixed"
9139 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
9140 (match_operator:MODEF 3 "absneg_operator"
9141 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
9142 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
9143 (clobber (reg:CC FLAGS_REG))]
9144 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
9147 (define_insn "*absneg<mode>2_sse"
9148 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
9149 (match_operator:MODEF 3 "absneg_operator"
9150 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
9151 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
9152 (clobber (reg:CC FLAGS_REG))]
9153 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
9156 (define_insn "*absneg<mode>2_i387"
9157 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
9158 (match_operator:X87MODEF 3 "absneg_operator"
9159 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
9160 (use (match_operand 2 "" ""))
9161 (clobber (reg:CC FLAGS_REG))]
9162 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
9165 (define_expand "<code>tf2"
9166 [(set (match_operand:TF 0 "register_operand" "")
9167 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
9169 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
9171 (define_insn "*absnegtf2_sse"
9172 [(set (match_operand:TF 0 "register_operand" "=x,x")
9173 (match_operator:TF 3 "absneg_operator"
9174 [(match_operand:TF 1 "register_operand" "0,x")]))
9175 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
9176 (clobber (reg:CC FLAGS_REG))]
9180 ;; Splitters for fp abs and neg.
9183 [(set (match_operand 0 "fp_register_operand" "")
9184 (match_operator 1 "absneg_operator" [(match_dup 0)]))
9185 (use (match_operand 2 "" ""))
9186 (clobber (reg:CC FLAGS_REG))]
9188 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
9191 [(set (match_operand 0 "register_operand" "")
9192 (match_operator 3 "absneg_operator"
9193 [(match_operand 1 "register_operand" "")]))
9194 (use (match_operand 2 "nonimmediate_operand" ""))
9195 (clobber (reg:CC FLAGS_REG))]
9196 "reload_completed && SSE_REG_P (operands[0])"
9197 [(set (match_dup 0) (match_dup 3))]
9199 enum machine_mode mode = GET_MODE (operands[0]);
9200 enum machine_mode vmode = GET_MODE (operands[2]);
9203 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
9204 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
9205 if (operands_match_p (operands[0], operands[2]))
9208 operands[1] = operands[2];
9211 if (GET_CODE (operands[3]) == ABS)
9212 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
9214 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
9219 [(set (match_operand:SF 0 "register_operand" "")
9220 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
9221 (use (match_operand:V4SF 2 "" ""))
9222 (clobber (reg:CC FLAGS_REG))]
9224 [(parallel [(set (match_dup 0) (match_dup 1))
9225 (clobber (reg:CC FLAGS_REG))])]
9228 operands[0] = gen_lowpart (SImode, operands[0]);
9229 if (GET_CODE (operands[1]) == ABS)
9231 tmp = gen_int_mode (0x7fffffff, SImode);
9232 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9236 tmp = gen_int_mode (0x80000000, SImode);
9237 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9243 [(set (match_operand:DF 0 "register_operand" "")
9244 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
9245 (use (match_operand 2 "" ""))
9246 (clobber (reg:CC FLAGS_REG))]
9248 [(parallel [(set (match_dup 0) (match_dup 1))
9249 (clobber (reg:CC FLAGS_REG))])]
9254 tmp = gen_lowpart (DImode, operands[0]);
9255 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
9258 if (GET_CODE (operands[1]) == ABS)
9261 tmp = gen_rtx_NOT (DImode, tmp);
9265 operands[0] = gen_highpart (SImode, operands[0]);
9266 if (GET_CODE (operands[1]) == ABS)
9268 tmp = gen_int_mode (0x7fffffff, SImode);
9269 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9273 tmp = gen_int_mode (0x80000000, SImode);
9274 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9281 [(set (match_operand:XF 0 "register_operand" "")
9282 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
9283 (use (match_operand 2 "" ""))
9284 (clobber (reg:CC FLAGS_REG))]
9286 [(parallel [(set (match_dup 0) (match_dup 1))
9287 (clobber (reg:CC FLAGS_REG))])]
9290 operands[0] = gen_rtx_REG (SImode,
9291 true_regnum (operands[0])
9292 + (TARGET_64BIT ? 1 : 2));
9293 if (GET_CODE (operands[1]) == ABS)
9295 tmp = GEN_INT (0x7fff);
9296 tmp = gen_rtx_AND (SImode, operands[0], tmp);
9300 tmp = GEN_INT (0x8000);
9301 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
9306 ;; Conditionalize these after reload. If they match before reload, we
9307 ;; lose the clobber and ability to use integer instructions.
9309 (define_insn "*<code><mode>2_1"
9310 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
9311 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
9313 && (reload_completed
9314 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
9316 [(set_attr "type" "fsgn")
9317 (set_attr "mode" "<MODE>")])
9319 (define_insn "*<code>extendsfdf2"
9320 [(set (match_operand:DF 0 "register_operand" "=f")
9321 (absneg:DF (float_extend:DF
9322 (match_operand:SF 1 "register_operand" "0"))))]
9323 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
9325 [(set_attr "type" "fsgn")
9326 (set_attr "mode" "DF")])
9328 (define_insn "*<code>extendsfxf2"
9329 [(set (match_operand:XF 0 "register_operand" "=f")
9330 (absneg:XF (float_extend:XF
9331 (match_operand:SF 1 "register_operand" "0"))))]
9334 [(set_attr "type" "fsgn")
9335 (set_attr "mode" "XF")])
9337 (define_insn "*<code>extenddfxf2"
9338 [(set (match_operand:XF 0 "register_operand" "=f")
9339 (absneg:XF (float_extend:XF
9340 (match_operand:DF 1 "register_operand" "0"))))]
9343 [(set_attr "type" "fsgn")
9344 (set_attr "mode" "XF")])
9346 ;; Copysign instructions
9348 (define_mode_iterator CSGNMODE [SF DF TF])
9349 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
9351 (define_expand "copysign<mode>3"
9352 [(match_operand:CSGNMODE 0 "register_operand" "")
9353 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
9354 (match_operand:CSGNMODE 2 "register_operand" "")]
9355 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9356 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9358 ix86_expand_copysign (operands);
9362 (define_insn_and_split "copysign<mode>3_const"
9363 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
9365 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
9366 (match_operand:CSGNMODE 2 "register_operand" "0")
9367 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
9369 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9370 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9372 "&& reload_completed"
9375 ix86_split_copysign_const (operands);
9379 (define_insn "copysign<mode>3_var"
9380 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
9382 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
9383 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
9384 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
9385 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
9387 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
9388 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9389 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
9393 [(set (match_operand:CSGNMODE 0 "register_operand" "")
9395 [(match_operand:CSGNMODE 2 "register_operand" "")
9396 (match_operand:CSGNMODE 3 "register_operand" "")
9397 (match_operand:<CSGNVMODE> 4 "" "")
9398 (match_operand:<CSGNVMODE> 5 "" "")]
9400 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
9401 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
9402 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
9403 && reload_completed"
9406 ix86_split_copysign_var (operands);
9410 ;; One complement instructions
9412 (define_expand "one_cmpl<mode>2"
9413 [(set (match_operand:SWIM 0 "nonimmediate_operand" "")
9414 (not:SWIM (match_operand:SWIM 1 "nonimmediate_operand" "")))]
9416 "ix86_expand_unary_operator (NOT, <MODE>mode, operands); DONE;")
9418 (define_insn "*one_cmpl<mode>2_1"
9419 [(set (match_operand:SWI248 0 "nonimmediate_operand" "=rm")
9420 (not:SWI248 (match_operand:SWI248 1 "nonimmediate_operand" "0")))]
9421 "ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9422 "not{<imodesuffix>}\t%0"
9423 [(set_attr "type" "negnot")
9424 (set_attr "mode" "<MODE>")])
9426 ;; %%% Potential partial reg stall on alternative 1. What to do?
9427 (define_insn "*one_cmplqi2_1"
9428 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
9429 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
9430 "ix86_unary_operator_ok (NOT, QImode, operands)"
9434 [(set_attr "type" "negnot")
9435 (set_attr "mode" "QI,SI")])
9437 ;; ??? Currently never generated - xor is used instead.
9438 (define_insn "*one_cmplsi2_1_zext"
9439 [(set (match_operand:DI 0 "register_operand" "=r")
9441 (not:SI (match_operand:SI 1 "register_operand" "0"))))]
9442 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
9444 [(set_attr "type" "negnot")
9445 (set_attr "mode" "SI")])
9447 (define_insn "*one_cmpl<mode>2_2"
9448 [(set (reg FLAGS_REG)
9449 (compare (not:SWI (match_operand:SWI 1 "nonimmediate_operand" "0"))
9451 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m")
9452 (not:SWI (match_dup 1)))]
9453 "ix86_match_ccmode (insn, CCNOmode)
9454 && ix86_unary_operator_ok (NOT, <MODE>mode, operands)"
9456 [(set_attr "type" "alu1")
9457 (set_attr "mode" "<MODE>")])
9460 [(set (match_operand 0 "flags_reg_operand" "")
9461 (match_operator 2 "compare_operator"
9462 [(not:SWI (match_operand:SWI 3 "nonimmediate_operand" ""))
9464 (set (match_operand:SWI 1 "nonimmediate_operand" "")
9465 (not:SWI (match_dup 3)))]
9466 "ix86_match_ccmode (insn, CCNOmode)"
9467 [(parallel [(set (match_dup 0)
9468 (match_op_dup 2 [(xor:SWI (match_dup 3) (const_int -1))
9471 (xor:SWI (match_dup 3) (const_int -1)))])]
9474 ;; ??? Currently never generated - xor is used instead.
9475 (define_insn "*one_cmplsi2_2_zext"
9476 [(set (reg FLAGS_REG)
9477 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
9479 (set (match_operand:DI 0 "register_operand" "=r")
9480 (zero_extend:DI (not:SI (match_dup 1))))]
9481 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9482 && ix86_unary_operator_ok (NOT, SImode, operands)"
9484 [(set_attr "type" "alu1")
9485 (set_attr "mode" "SI")])
9488 [(set (match_operand 0 "flags_reg_operand" "")
9489 (match_operator 2 "compare_operator"
9490 [(not:SI (match_operand:SI 3 "register_operand" ""))
9492 (set (match_operand:DI 1 "register_operand" "")
9493 (zero_extend:DI (not:SI (match_dup 3))))]
9494 "ix86_match_ccmode (insn, CCNOmode)"
9495 [(parallel [(set (match_dup 0)
9496 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
9499 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
9502 ;; Arithmetic shift instructions
9504 ;; DImode shifts are implemented using the i386 "shift double" opcode,
9505 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
9506 ;; is variable, then the count is in %cl and the "imm" operand is dropped
9507 ;; from the assembler input.
9509 ;; This instruction shifts the target reg/mem as usual, but instead of
9510 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
9511 ;; is a left shift double, bits are taken from the high order bits of
9512 ;; reg, else if the insn is a shift right double, bits are taken from the
9513 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
9514 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
9516 ;; Since sh[lr]d does not change the `reg' operand, that is done
9517 ;; separately, making all shifts emit pairs of shift double and normal
9518 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
9519 ;; support a 63 bit shift, each shift where the count is in a reg expands
9520 ;; to a pair of shifts, a branch, a shift by 32 and a label.
9522 ;; If the shift count is a constant, we need never emit more than one
9523 ;; shift pair, instead using moves and sign extension for counts greater
9526 (define_expand "ashlti3"
9527 [(set (match_operand:TI 0 "register_operand" "")
9528 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
9529 (match_operand:QI 2 "nonmemory_operand" "")))]
9531 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
9533 (define_insn "*ashlti3_1"
9534 [(set (match_operand:TI 0 "register_operand" "=&r,r")
9535 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
9536 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
9537 (clobber (reg:CC FLAGS_REG))]
9540 [(set_attr "type" "multi")])
9543 [(match_scratch:DI 3 "r")
9544 (parallel [(set (match_operand:TI 0 "register_operand" "")
9545 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9546 (match_operand:QI 2 "nonmemory_operand" "")))
9547 (clobber (reg:CC FLAGS_REG))])
9551 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
9554 [(set (match_operand:TI 0 "register_operand" "")
9555 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
9556 (match_operand:QI 2 "nonmemory_operand" "")))
9557 (clobber (reg:CC FLAGS_REG))]
9558 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9559 ? epilogue_completed : reload_completed)"
9561 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
9563 (define_insn "x86_64_shld"
9564 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
9565 (ior:DI (ashift:DI (match_dup 0)
9566 (match_operand:QI 2 "nonmemory_operand" "Jc"))
9567 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
9568 (minus:QI (const_int 64) (match_dup 2)))))
9569 (clobber (reg:CC FLAGS_REG))]
9571 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
9572 [(set_attr "type" "ishift")
9573 (set_attr "prefix_0f" "1")
9574 (set_attr "mode" "DI")
9575 (set_attr "athlon_decode" "vector")
9576 (set_attr "amdfam10_decode" "vector")])
9578 (define_expand "x86_64_shift_adj_1"
9579 [(set (reg:CCZ FLAGS_REG)
9580 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9583 (set (match_operand:DI 0 "register_operand" "")
9584 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9585 (match_operand:DI 1 "register_operand" "")
9588 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9589 (match_operand:DI 3 "register_operand" "r")
9594 (define_expand "x86_64_shift_adj_2"
9595 [(use (match_operand:DI 0 "register_operand" ""))
9596 (use (match_operand:DI 1 "register_operand" ""))
9597 (use (match_operand:QI 2 "register_operand" ""))]
9600 rtx label = gen_label_rtx ();
9603 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
9605 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9606 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9607 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9608 gen_rtx_LABEL_REF (VOIDmode, label),
9610 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9611 JUMP_LABEL (tmp) = label;
9613 emit_move_insn (operands[0], operands[1]);
9614 ix86_expand_clear (operands[1]);
9617 LABEL_NUSES (label) = 1;
9622 (define_expand "ashldi3"
9623 [(set (match_operand:DI 0 "shiftdi_operand" "")
9624 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
9625 (match_operand:QI 2 "nonmemory_operand" "")))]
9627 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
9629 (define_insn "*ashldi3_1_rex64"
9630 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
9631 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
9632 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
9633 (clobber (reg:CC FLAGS_REG))]
9634 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9636 switch (get_attr_type (insn))
9639 gcc_assert (operands[2] == const1_rtx);
9640 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9641 return "add{q}\t%0, %0";
9644 gcc_assert (CONST_INT_P (operands[2]));
9645 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
9646 operands[1] = gen_rtx_MULT (DImode, operands[1],
9647 GEN_INT (1 << INTVAL (operands[2])));
9648 return "lea{q}\t{%a1, %0|%0, %a1}";
9651 if (REG_P (operands[2]))
9652 return "sal{q}\t{%b2, %0|%0, %b2}";
9653 else if (operands[2] == const1_rtx
9654 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9655 return "sal{q}\t%0";
9657 return "sal{q}\t{%2, %0|%0, %2}";
9661 (cond [(eq_attr "alternative" "1")
9662 (const_string "lea")
9663 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9665 (match_operand 0 "register_operand" ""))
9666 (match_operand 2 "const1_operand" ""))
9667 (const_string "alu")
9669 (const_string "ishift")))
9670 (set (attr "length_immediate")
9672 (ior (eq_attr "type" "alu")
9673 (and (eq_attr "type" "ishift")
9674 (and (match_operand 2 "const1_operand" "")
9675 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9678 (const_string "*")))
9679 (set_attr "mode" "DI")])
9681 ;; Convert lea to the lea pattern to avoid flags dependency.
9683 [(set (match_operand:DI 0 "register_operand" "")
9684 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
9685 (match_operand:QI 2 "immediate_operand" "")))
9686 (clobber (reg:CC FLAGS_REG))]
9687 "TARGET_64BIT && reload_completed
9688 && true_regnum (operands[0]) != true_regnum (operands[1])"
9690 (mult:DI (match_dup 1)
9692 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
9694 ;; This pattern can't accept a variable shift count, since shifts by
9695 ;; zero don't affect the flags. We assume that shifts by constant
9696 ;; zero are optimized away.
9697 (define_insn "*ashldi3_cmp_rex64"
9698 [(set (reg FLAGS_REG)
9700 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9701 (match_operand:QI 2 "const_1_to_63_operand" "J"))
9703 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
9704 (ashift:DI (match_dup 1) (match_dup 2)))]
9706 && (optimize_function_for_size_p (cfun)
9707 || !TARGET_PARTIAL_FLAG_REG_STALL
9708 || (operands[2] == const1_rtx
9710 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
9711 && ix86_match_ccmode (insn, CCGOCmode)
9712 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9714 switch (get_attr_type (insn))
9717 gcc_assert (operands[2] == const1_rtx);
9718 return "add{q}\t%0, %0";
9721 if (REG_P (operands[2]))
9722 return "sal{q}\t{%b2, %0|%0, %b2}";
9723 else if (operands[2] == const1_rtx
9724 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9725 return "sal{q}\t%0";
9727 return "sal{q}\t{%2, %0|%0, %2}";
9731 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9733 (match_operand 0 "register_operand" ""))
9734 (match_operand 2 "const1_operand" ""))
9735 (const_string "alu")
9737 (const_string "ishift")))
9738 (set (attr "length_immediate")
9740 (ior (eq_attr "type" "alu")
9741 (and (eq_attr "type" "ishift")
9742 (and (match_operand 2 "const1_operand" "")
9743 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9746 (const_string "*")))
9747 (set_attr "mode" "DI")])
9749 (define_insn "*ashldi3_cconly_rex64"
9750 [(set (reg FLAGS_REG)
9752 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
9753 (match_operand:QI 2 "const_1_to_63_operand" "J"))
9755 (clobber (match_scratch:DI 0 "=r"))]
9757 && (optimize_function_for_size_p (cfun)
9758 || !TARGET_PARTIAL_FLAG_REG_STALL
9759 || (operands[2] == const1_rtx
9761 || TARGET_DOUBLE_WITH_ADD)))
9762 && ix86_match_ccmode (insn, CCGOCmode)
9763 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
9765 switch (get_attr_type (insn))
9768 gcc_assert (operands[2] == const1_rtx);
9769 return "add{q}\t%0, %0";
9772 if (REG_P (operands[2]))
9773 return "sal{q}\t{%b2, %0|%0, %b2}";
9774 else if (operands[2] == const1_rtx
9775 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9776 return "sal{q}\t%0";
9778 return "sal{q}\t{%2, %0|%0, %2}";
9782 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9784 (match_operand 0 "register_operand" ""))
9785 (match_operand 2 "const1_operand" ""))
9786 (const_string "alu")
9788 (const_string "ishift")))
9789 (set (attr "length_immediate")
9791 (ior (eq_attr "type" "alu")
9792 (and (eq_attr "type" "ishift")
9793 (and (match_operand 2 "const1_operand" "")
9794 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9797 (const_string "*")))
9798 (set_attr "mode" "DI")])
9800 (define_insn "*ashldi3_1"
9801 [(set (match_operand:DI 0 "register_operand" "=&r,r")
9802 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
9803 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
9804 (clobber (reg:CC FLAGS_REG))]
9807 [(set_attr "type" "multi")])
9809 ;; By default we don't ask for a scratch register, because when DImode
9810 ;; values are manipulated, registers are already at a premium. But if
9811 ;; we have one handy, we won't turn it away.
9813 [(match_scratch:SI 3 "r")
9814 (parallel [(set (match_operand:DI 0 "register_operand" "")
9815 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9816 (match_operand:QI 2 "nonmemory_operand" "")))
9817 (clobber (reg:CC FLAGS_REG))])
9819 "!TARGET_64BIT && TARGET_CMOVE"
9821 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
9824 [(set (match_operand:DI 0 "register_operand" "")
9825 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
9826 (match_operand:QI 2 "nonmemory_operand" "")))
9827 (clobber (reg:CC FLAGS_REG))]
9828 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
9829 ? epilogue_completed : reload_completed)"
9831 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
9833 (define_insn "x86_shld"
9834 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
9835 (ior:SI (ashift:SI (match_dup 0)
9836 (match_operand:QI 2 "nonmemory_operand" "Ic"))
9837 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
9838 (minus:QI (const_int 32) (match_dup 2)))))
9839 (clobber (reg:CC FLAGS_REG))]
9841 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
9842 [(set_attr "type" "ishift")
9843 (set_attr "prefix_0f" "1")
9844 (set_attr "mode" "SI")
9845 (set_attr "pent_pair" "np")
9846 (set_attr "athlon_decode" "vector")
9847 (set_attr "amdfam10_decode" "vector")])
9849 (define_expand "x86_shift_adj_1"
9850 [(set (reg:CCZ FLAGS_REG)
9851 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
9854 (set (match_operand:SI 0 "register_operand" "")
9855 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9856 (match_operand:SI 1 "register_operand" "")
9859 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
9860 (match_operand:SI 3 "register_operand" "r")
9865 (define_expand "x86_shift_adj_2"
9866 [(use (match_operand:SI 0 "register_operand" ""))
9867 (use (match_operand:SI 1 "register_operand" ""))
9868 (use (match_operand:QI 2 "register_operand" ""))]
9871 rtx label = gen_label_rtx ();
9874 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
9876 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
9877 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
9878 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
9879 gen_rtx_LABEL_REF (VOIDmode, label),
9881 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
9882 JUMP_LABEL (tmp) = label;
9884 emit_move_insn (operands[0], operands[1]);
9885 ix86_expand_clear (operands[1]);
9888 LABEL_NUSES (label) = 1;
9893 (define_expand "ashlsi3"
9894 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9895 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
9896 (match_operand:QI 2 "nonmemory_operand" "")))]
9898 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
9900 (define_insn "*ashlsi3_1"
9901 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
9902 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
9903 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
9904 (clobber (reg:CC FLAGS_REG))]
9905 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
9907 switch (get_attr_type (insn))
9910 gcc_assert (operands[2] == const1_rtx);
9911 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9912 return "add{l}\t%0, %0";
9918 if (REG_P (operands[2]))
9919 return "sal{l}\t{%b2, %0|%0, %b2}";
9920 else if (operands[2] == const1_rtx
9921 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
9922 return "sal{l}\t%0";
9924 return "sal{l}\t{%2, %0|%0, %2}";
9928 (cond [(eq_attr "alternative" "1")
9929 (const_string "lea")
9930 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
9932 (match_operand 0 "register_operand" ""))
9933 (match_operand 2 "const1_operand" ""))
9934 (const_string "alu")
9936 (const_string "ishift")))
9937 (set (attr "length_immediate")
9939 (ior (eq_attr "type" "alu")
9940 (and (eq_attr "type" "ishift")
9941 (and (match_operand 2 "const1_operand" "")
9942 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
9945 (const_string "*")))
9946 (set_attr "mode" "SI")])
9948 ;; Convert lea to the lea pattern to avoid flags dependency.
9950 [(set (match_operand 0 "register_operand" "")
9951 (ashift (match_operand 1 "index_register_operand" "")
9952 (match_operand:QI 2 "const_int_operand" "")))
9953 (clobber (reg:CC FLAGS_REG))]
9955 && true_regnum (operands[0]) != true_regnum (operands[1])
9956 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
9960 enum machine_mode mode = GET_MODE (operands[0]);
9962 if (GET_MODE_SIZE (mode) < 4)
9963 operands[0] = gen_lowpart (SImode, operands[0]);
9965 operands[1] = gen_lowpart (Pmode, operands[1]);
9966 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
9968 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
9969 if (Pmode != SImode)
9970 pat = gen_rtx_SUBREG (SImode, pat, 0);
9971 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
9975 ;; Rare case of shifting RSP is handled by generating move and shift
9977 [(set (match_operand 0 "register_operand" "")
9978 (ashift (match_operand 1 "register_operand" "")
9979 (match_operand:QI 2 "const_int_operand" "")))
9980 (clobber (reg:CC FLAGS_REG))]
9982 && true_regnum (operands[0]) != true_regnum (operands[1])"
9986 emit_move_insn (operands[0], operands[1]);
9987 pat = gen_rtx_SET (VOIDmode, operands[0],
9988 gen_rtx_ASHIFT (GET_MODE (operands[0]),
9989 operands[0], operands[2]));
9990 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
9991 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
9995 (define_insn "*ashlsi3_1_zext"
9996 [(set (match_operand:DI 0 "register_operand" "=r,r")
9997 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
9998 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
9999 (clobber (reg:CC FLAGS_REG))]
10000 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10002 switch (get_attr_type (insn))
10005 gcc_assert (operands[2] == const1_rtx);
10006 return "add{l}\t%k0, %k0";
10012 if (REG_P (operands[2]))
10013 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10014 else if (operands[2] == const1_rtx
10015 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10016 return "sal{l}\t%k0";
10018 return "sal{l}\t{%2, %k0|%k0, %2}";
10021 [(set (attr "type")
10022 (cond [(eq_attr "alternative" "1")
10023 (const_string "lea")
10024 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10026 (match_operand 2 "const1_operand" ""))
10027 (const_string "alu")
10029 (const_string "ishift")))
10030 (set (attr "length_immediate")
10032 (ior (eq_attr "type" "alu")
10033 (and (eq_attr "type" "ishift")
10034 (and (match_operand 2 "const1_operand" "")
10035 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10038 (const_string "*")))
10039 (set_attr "mode" "SI")])
10041 ;; Convert lea to the lea pattern to avoid flags dependency.
10043 [(set (match_operand:DI 0 "register_operand" "")
10044 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
10045 (match_operand:QI 2 "const_int_operand" ""))))
10046 (clobber (reg:CC FLAGS_REG))]
10047 "TARGET_64BIT && reload_completed
10048 && true_regnum (operands[0]) != true_regnum (operands[1])"
10049 [(set (match_dup 0) (zero_extend:DI
10050 (subreg:SI (mult:SI (match_dup 1)
10051 (match_dup 2)) 0)))]
10053 operands[1] = gen_lowpart (Pmode, operands[1]);
10054 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
10057 ;; This pattern can't accept a variable shift count, since shifts by
10058 ;; zero don't affect the flags. We assume that shifts by constant
10059 ;; zero are optimized away.
10060 (define_insn "*ashlsi3_cmp"
10061 [(set (reg FLAGS_REG)
10063 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10064 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10066 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10067 (ashift:SI (match_dup 1) (match_dup 2)))]
10068 "(optimize_function_for_size_p (cfun)
10069 || !TARGET_PARTIAL_FLAG_REG_STALL
10070 || (operands[2] == const1_rtx
10072 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10073 && ix86_match_ccmode (insn, CCGOCmode)
10074 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10076 switch (get_attr_type (insn))
10079 gcc_assert (operands[2] == const1_rtx);
10080 return "add{l}\t%0, %0";
10083 if (REG_P (operands[2]))
10084 return "sal{l}\t{%b2, %0|%0, %b2}";
10085 else if (operands[2] == const1_rtx
10086 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10087 return "sal{l}\t%0";
10089 return "sal{l}\t{%2, %0|%0, %2}";
10092 [(set (attr "type")
10093 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10095 (match_operand 0 "register_operand" ""))
10096 (match_operand 2 "const1_operand" ""))
10097 (const_string "alu")
10099 (const_string "ishift")))
10100 (set (attr "length_immediate")
10102 (ior (eq_attr "type" "alu")
10103 (and (eq_attr "type" "ishift")
10104 (and (match_operand 2 "const1_operand" "")
10105 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10108 (const_string "*")))
10109 (set_attr "mode" "SI")])
10111 (define_insn "*ashlsi3_cconly"
10112 [(set (reg FLAGS_REG)
10114 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10115 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10117 (clobber (match_scratch:SI 0 "=r"))]
10118 "(optimize_function_for_size_p (cfun)
10119 || !TARGET_PARTIAL_FLAG_REG_STALL
10120 || (operands[2] == const1_rtx
10122 || TARGET_DOUBLE_WITH_ADD)))
10123 && ix86_match_ccmode (insn, CCGOCmode)
10124 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10126 switch (get_attr_type (insn))
10129 gcc_assert (operands[2] == const1_rtx);
10130 return "add{l}\t%0, %0";
10133 if (REG_P (operands[2]))
10134 return "sal{l}\t{%b2, %0|%0, %b2}";
10135 else if (operands[2] == const1_rtx
10136 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10137 return "sal{l}\t%0";
10139 return "sal{l}\t{%2, %0|%0, %2}";
10142 [(set (attr "type")
10143 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10145 (match_operand 0 "register_operand" ""))
10146 (match_operand 2 "const1_operand" ""))
10147 (const_string "alu")
10149 (const_string "ishift")))
10150 (set (attr "length_immediate")
10152 (ior (eq_attr "type" "alu")
10153 (and (eq_attr "type" "ishift")
10154 (and (match_operand 2 "const1_operand" "")
10155 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10158 (const_string "*")))
10159 (set_attr "mode" "SI")])
10161 (define_insn "*ashlsi3_cmp_zext"
10162 [(set (reg FLAGS_REG)
10164 (ashift:SI (match_operand:SI 1 "register_operand" "0")
10165 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10167 (set (match_operand:DI 0 "register_operand" "=r")
10168 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
10170 && (optimize_function_for_size_p (cfun)
10171 || !TARGET_PARTIAL_FLAG_REG_STALL
10172 || (operands[2] == const1_rtx
10174 || TARGET_DOUBLE_WITH_ADD)))
10175 && ix86_match_ccmode (insn, CCGOCmode)
10176 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
10178 switch (get_attr_type (insn))
10181 gcc_assert (operands[2] == const1_rtx);
10182 return "add{l}\t%k0, %k0";
10185 if (REG_P (operands[2]))
10186 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10187 else if (operands[2] == const1_rtx
10188 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10189 return "sal{l}\t%k0";
10191 return "sal{l}\t{%2, %k0|%k0, %2}";
10194 [(set (attr "type")
10195 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10197 (match_operand 2 "const1_operand" ""))
10198 (const_string "alu")
10200 (const_string "ishift")))
10201 (set (attr "length_immediate")
10203 (ior (eq_attr "type" "alu")
10204 (and (eq_attr "type" "ishift")
10205 (and (match_operand 2 "const1_operand" "")
10206 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10209 (const_string "*")))
10210 (set_attr "mode" "SI")])
10212 (define_expand "ashlhi3"
10213 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10214 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
10215 (match_operand:QI 2 "nonmemory_operand" "")))]
10216 "TARGET_HIMODE_MATH"
10217 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
10219 (define_insn "*ashlhi3_1_lea"
10220 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
10221 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
10222 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
10223 (clobber (reg:CC FLAGS_REG))]
10224 "!TARGET_PARTIAL_REG_STALL
10225 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10227 switch (get_attr_type (insn))
10232 gcc_assert (operands[2] == const1_rtx);
10233 return "add{w}\t%0, %0";
10236 if (REG_P (operands[2]))
10237 return "sal{w}\t{%b2, %0|%0, %b2}";
10238 else if (operands[2] == const1_rtx
10239 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10240 return "sal{w}\t%0";
10242 return "sal{w}\t{%2, %0|%0, %2}";
10245 [(set (attr "type")
10246 (cond [(eq_attr "alternative" "1")
10247 (const_string "lea")
10248 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10250 (match_operand 0 "register_operand" ""))
10251 (match_operand 2 "const1_operand" ""))
10252 (const_string "alu")
10254 (const_string "ishift")))
10255 (set (attr "length_immediate")
10257 (ior (eq_attr "type" "alu")
10258 (and (eq_attr "type" "ishift")
10259 (and (match_operand 2 "const1_operand" "")
10260 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10263 (const_string "*")))
10264 (set_attr "mode" "HI,SI")])
10266 (define_insn "*ashlhi3_1"
10267 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10268 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10269 (match_operand:QI 2 "nonmemory_operand" "cI")))
10270 (clobber (reg:CC FLAGS_REG))]
10271 "TARGET_PARTIAL_REG_STALL
10272 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10274 switch (get_attr_type (insn))
10277 gcc_assert (operands[2] == const1_rtx);
10278 return "add{w}\t%0, %0";
10281 if (REG_P (operands[2]))
10282 return "sal{w}\t{%b2, %0|%0, %b2}";
10283 else if (operands[2] == const1_rtx
10284 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10285 return "sal{w}\t%0";
10287 return "sal{w}\t{%2, %0|%0, %2}";
10290 [(set (attr "type")
10291 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10293 (match_operand 0 "register_operand" ""))
10294 (match_operand 2 "const1_operand" ""))
10295 (const_string "alu")
10297 (const_string "ishift")))
10298 (set (attr "length_immediate")
10300 (ior (eq_attr "type" "alu")
10301 (and (eq_attr "type" "ishift")
10302 (and (match_operand 2 "const1_operand" "")
10303 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10306 (const_string "*")))
10307 (set_attr "mode" "HI")])
10309 ;; This pattern can't accept a variable shift count, since shifts by
10310 ;; zero don't affect the flags. We assume that shifts by constant
10311 ;; zero are optimized away.
10312 (define_insn "*ashlhi3_cmp"
10313 [(set (reg FLAGS_REG)
10315 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10316 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10318 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
10319 (ashift:HI (match_dup 1) (match_dup 2)))]
10320 "(optimize_function_for_size_p (cfun)
10321 || !TARGET_PARTIAL_FLAG_REG_STALL
10322 || (operands[2] == const1_rtx
10324 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10325 && ix86_match_ccmode (insn, CCGOCmode)
10326 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10328 switch (get_attr_type (insn))
10331 gcc_assert (operands[2] == const1_rtx);
10332 return "add{w}\t%0, %0";
10335 if (REG_P (operands[2]))
10336 return "sal{w}\t{%b2, %0|%0, %b2}";
10337 else if (operands[2] == const1_rtx
10338 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10339 return "sal{w}\t%0";
10341 return "sal{w}\t{%2, %0|%0, %2}";
10344 [(set (attr "type")
10345 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10347 (match_operand 0 "register_operand" ""))
10348 (match_operand 2 "const1_operand" ""))
10349 (const_string "alu")
10351 (const_string "ishift")))
10352 (set (attr "length_immediate")
10354 (ior (eq_attr "type" "alu")
10355 (and (eq_attr "type" "ishift")
10356 (and (match_operand 2 "const1_operand" "")
10357 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10360 (const_string "*")))
10361 (set_attr "mode" "HI")])
10363 (define_insn "*ashlhi3_cconly"
10364 [(set (reg FLAGS_REG)
10366 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
10367 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10369 (clobber (match_scratch:HI 0 "=r"))]
10370 "(optimize_function_for_size_p (cfun)
10371 || !TARGET_PARTIAL_FLAG_REG_STALL
10372 || (operands[2] == const1_rtx
10374 || TARGET_DOUBLE_WITH_ADD)))
10375 && ix86_match_ccmode (insn, CCGOCmode)
10376 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
10378 switch (get_attr_type (insn))
10381 gcc_assert (operands[2] == const1_rtx);
10382 return "add{w}\t%0, %0";
10385 if (REG_P (operands[2]))
10386 return "sal{w}\t{%b2, %0|%0, %b2}";
10387 else if (operands[2] == const1_rtx
10388 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10389 return "sal{w}\t%0";
10391 return "sal{w}\t{%2, %0|%0, %2}";
10394 [(set (attr "type")
10395 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10397 (match_operand 0 "register_operand" ""))
10398 (match_operand 2 "const1_operand" ""))
10399 (const_string "alu")
10401 (const_string "ishift")))
10402 (set (attr "length_immediate")
10404 (ior (eq_attr "type" "alu")
10405 (and (eq_attr "type" "ishift")
10406 (and (match_operand 2 "const1_operand" "")
10407 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10410 (const_string "*")))
10411 (set_attr "mode" "HI")])
10413 (define_expand "ashlqi3"
10414 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10415 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
10416 (match_operand:QI 2 "nonmemory_operand" "")))]
10417 "TARGET_QIMODE_MATH"
10418 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
10420 ;; %%% Potential partial reg stall on alternative 2. What to do?
10422 (define_insn "*ashlqi3_1_lea"
10423 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
10424 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
10425 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
10426 (clobber (reg:CC FLAGS_REG))]
10427 "!TARGET_PARTIAL_REG_STALL
10428 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10430 switch (get_attr_type (insn))
10435 gcc_assert (operands[2] == const1_rtx);
10436 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10437 return "add{l}\t%k0, %k0";
10439 return "add{b}\t%0, %0";
10442 if (REG_P (operands[2]))
10444 if (get_attr_mode (insn) == MODE_SI)
10445 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10447 return "sal{b}\t{%b2, %0|%0, %b2}";
10449 else if (operands[2] == const1_rtx
10450 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10452 if (get_attr_mode (insn) == MODE_SI)
10453 return "sal{l}\t%0";
10455 return "sal{b}\t%0";
10459 if (get_attr_mode (insn) == MODE_SI)
10460 return "sal{l}\t{%2, %k0|%k0, %2}";
10462 return "sal{b}\t{%2, %0|%0, %2}";
10466 [(set (attr "type")
10467 (cond [(eq_attr "alternative" "2")
10468 (const_string "lea")
10469 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10471 (match_operand 0 "register_operand" ""))
10472 (match_operand 2 "const1_operand" ""))
10473 (const_string "alu")
10475 (const_string "ishift")))
10476 (set (attr "length_immediate")
10478 (ior (eq_attr "type" "alu")
10479 (and (eq_attr "type" "ishift")
10480 (and (match_operand 2 "const1_operand" "")
10481 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10484 (const_string "*")))
10485 (set_attr "mode" "QI,SI,SI")])
10487 (define_insn "*ashlqi3_1"
10488 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
10489 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
10490 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
10491 (clobber (reg:CC FLAGS_REG))]
10492 "TARGET_PARTIAL_REG_STALL
10493 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10495 switch (get_attr_type (insn))
10498 gcc_assert (operands[2] == const1_rtx);
10499 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
10500 return "add{l}\t%k0, %k0";
10502 return "add{b}\t%0, %0";
10505 if (REG_P (operands[2]))
10507 if (get_attr_mode (insn) == MODE_SI)
10508 return "sal{l}\t{%b2, %k0|%k0, %b2}";
10510 return "sal{b}\t{%b2, %0|%0, %b2}";
10512 else if (operands[2] == const1_rtx
10513 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10515 if (get_attr_mode (insn) == MODE_SI)
10516 return "sal{l}\t%0";
10518 return "sal{b}\t%0";
10522 if (get_attr_mode (insn) == MODE_SI)
10523 return "sal{l}\t{%2, %k0|%k0, %2}";
10525 return "sal{b}\t{%2, %0|%0, %2}";
10529 [(set (attr "type")
10530 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10532 (match_operand 0 "register_operand" ""))
10533 (match_operand 2 "const1_operand" ""))
10534 (const_string "alu")
10536 (const_string "ishift")))
10537 (set (attr "length_immediate")
10539 (ior (eq_attr "type" "alu")
10540 (and (eq_attr "type" "ishift")
10541 (and (match_operand 2 "const1_operand" "")
10542 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10545 (const_string "*")))
10546 (set_attr "mode" "QI,SI")])
10548 ;; This pattern can't accept a variable shift count, since shifts by
10549 ;; zero don't affect the flags. We assume that shifts by constant
10550 ;; zero are optimized away.
10551 (define_insn "*ashlqi3_cmp"
10552 [(set (reg FLAGS_REG)
10554 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10555 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10557 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
10558 (ashift:QI (match_dup 1) (match_dup 2)))]
10559 "(optimize_function_for_size_p (cfun)
10560 || !TARGET_PARTIAL_FLAG_REG_STALL
10561 || (operands[2] == const1_rtx
10563 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
10564 && ix86_match_ccmode (insn, CCGOCmode)
10565 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10567 switch (get_attr_type (insn))
10570 gcc_assert (operands[2] == const1_rtx);
10571 return "add{b}\t%0, %0";
10574 if (REG_P (operands[2]))
10575 return "sal{b}\t{%b2, %0|%0, %b2}";
10576 else if (operands[2] == const1_rtx
10577 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10578 return "sal{b}\t%0";
10580 return "sal{b}\t{%2, %0|%0, %2}";
10583 [(set (attr "type")
10584 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10586 (match_operand 0 "register_operand" ""))
10587 (match_operand 2 "const1_operand" ""))
10588 (const_string "alu")
10590 (const_string "ishift")))
10591 (set (attr "length_immediate")
10593 (ior (eq_attr "type" "alu")
10594 (and (eq_attr "type" "ishift")
10595 (and (match_operand 2 "const1_operand" "")
10596 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10599 (const_string "*")))
10600 (set_attr "mode" "QI")])
10602 (define_insn "*ashlqi3_cconly"
10603 [(set (reg FLAGS_REG)
10605 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
10606 (match_operand:QI 2 "const_1_to_31_operand" "I"))
10608 (clobber (match_scratch:QI 0 "=q"))]
10609 "(optimize_function_for_size_p (cfun)
10610 || !TARGET_PARTIAL_FLAG_REG_STALL
10611 || (operands[2] == const1_rtx
10613 || TARGET_DOUBLE_WITH_ADD)))
10614 && ix86_match_ccmode (insn, CCGOCmode)
10615 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
10617 switch (get_attr_type (insn))
10620 gcc_assert (operands[2] == const1_rtx);
10621 return "add{b}\t%0, %0";
10624 if (REG_P (operands[2]))
10625 return "sal{b}\t{%b2, %0|%0, %b2}";
10626 else if (operands[2] == const1_rtx
10627 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
10628 return "sal{b}\t%0";
10630 return "sal{b}\t{%2, %0|%0, %2}";
10633 [(set (attr "type")
10634 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
10636 (match_operand 0 "register_operand" ""))
10637 (match_operand 2 "const1_operand" ""))
10638 (const_string "alu")
10640 (const_string "ishift")))
10641 (set (attr "length_immediate")
10643 (ior (eq_attr "type" "alu")
10644 (and (eq_attr "type" "ishift")
10645 (and (match_operand 2 "const1_operand" "")
10646 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
10649 (const_string "*")))
10650 (set_attr "mode" "QI")])
10652 ;; See comment above `ashldi3' about how this works.
10654 (define_expand "ashrti3"
10655 [(set (match_operand:TI 0 "register_operand" "")
10656 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10657 (match_operand:QI 2 "nonmemory_operand" "")))]
10659 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
10661 (define_insn "*ashrti3_1"
10662 [(set (match_operand:TI 0 "register_operand" "=r")
10663 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
10664 (match_operand:QI 2 "nonmemory_operand" "Oc")))
10665 (clobber (reg:CC FLAGS_REG))]
10668 [(set_attr "type" "multi")])
10671 [(match_scratch:DI 3 "r")
10672 (parallel [(set (match_operand:TI 0 "register_operand" "")
10673 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10674 (match_operand:QI 2 "nonmemory_operand" "")))
10675 (clobber (reg:CC FLAGS_REG))])
10679 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
10682 [(set (match_operand:TI 0 "register_operand" "")
10683 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
10684 (match_operand:QI 2 "nonmemory_operand" "")))
10685 (clobber (reg:CC FLAGS_REG))]
10686 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10687 ? epilogue_completed : reload_completed)"
10689 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
10691 (define_insn "x86_64_shrd"
10692 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
10693 (ior:DI (ashiftrt:DI (match_dup 0)
10694 (match_operand:QI 2 "nonmemory_operand" "Jc"))
10695 (ashift:DI (match_operand:DI 1 "register_operand" "r")
10696 (minus:QI (const_int 64) (match_dup 2)))))
10697 (clobber (reg:CC FLAGS_REG))]
10699 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
10700 [(set_attr "type" "ishift")
10701 (set_attr "prefix_0f" "1")
10702 (set_attr "mode" "DI")
10703 (set_attr "athlon_decode" "vector")
10704 (set_attr "amdfam10_decode" "vector")])
10706 (define_expand "ashrdi3"
10707 [(set (match_operand:DI 0 "shiftdi_operand" "")
10708 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
10709 (match_operand:QI 2 "nonmemory_operand" "")))]
10711 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
10713 (define_expand "x86_64_shift_adj_3"
10714 [(use (match_operand:DI 0 "register_operand" ""))
10715 (use (match_operand:DI 1 "register_operand" ""))
10716 (use (match_operand:QI 2 "register_operand" ""))]
10719 rtx label = gen_label_rtx ();
10722 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
10724 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10725 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10726 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10727 gen_rtx_LABEL_REF (VOIDmode, label),
10729 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10730 JUMP_LABEL (tmp) = label;
10732 emit_move_insn (operands[0], operands[1]);
10733 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
10735 emit_label (label);
10736 LABEL_NUSES (label) = 1;
10741 (define_insn "ashrdi3_63_rex64"
10742 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
10743 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
10744 (match_operand:DI 2 "const_int_operand" "i,i")))
10745 (clobber (reg:CC FLAGS_REG))]
10746 "TARGET_64BIT && INTVAL (operands[2]) == 63
10747 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10748 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10751 sar{q}\t{%2, %0|%0, %2}"
10752 [(set_attr "type" "imovx,ishift")
10753 (set_attr "prefix_0f" "0,*")
10754 (set_attr "length_immediate" "0,*")
10755 (set_attr "modrm" "0,1")
10756 (set_attr "mode" "DI")])
10758 (define_insn "*ashrdi3_1_one_bit_rex64"
10759 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10760 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10761 (match_operand:QI 2 "const1_operand" "")))
10762 (clobber (reg:CC FLAGS_REG))]
10764 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10765 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10767 [(set_attr "type" "ishift")
10768 (set_attr "length_immediate" "0")
10769 (set_attr "mode" "DI")])
10771 (define_insn "*ashrdi3_1_rex64"
10772 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
10773 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
10774 (match_operand:QI 2 "nonmemory_operand" "J,c")))
10775 (clobber (reg:CC FLAGS_REG))]
10776 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10778 sar{q}\t{%2, %0|%0, %2}
10779 sar{q}\t{%b2, %0|%0, %b2}"
10780 [(set_attr "type" "ishift")
10781 (set_attr "mode" "DI")])
10783 ;; This pattern can't accept a variable shift count, since shifts by
10784 ;; zero don't affect the flags. We assume that shifts by constant
10785 ;; zero are optimized away.
10786 (define_insn "*ashrdi3_one_bit_cmp_rex64"
10787 [(set (reg FLAGS_REG)
10789 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10790 (match_operand:QI 2 "const1_operand" ""))
10792 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10793 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10795 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10796 && ix86_match_ccmode (insn, CCGOCmode)
10797 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10799 [(set_attr "type" "ishift")
10800 (set_attr "length_immediate" "0")
10801 (set_attr "mode" "DI")])
10803 (define_insn "*ashrdi3_one_bit_cconly_rex64"
10804 [(set (reg FLAGS_REG)
10806 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10807 (match_operand:QI 2 "const1_operand" ""))
10809 (clobber (match_scratch:DI 0 "=r"))]
10811 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10812 && ix86_match_ccmode (insn, CCGOCmode)
10813 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10815 [(set_attr "type" "ishift")
10816 (set_attr "length_immediate" "0")
10817 (set_attr "mode" "DI")])
10819 ;; This pattern can't accept a variable shift count, since shifts by
10820 ;; zero don't affect the flags. We assume that shifts by constant
10821 ;; zero are optimized away.
10822 (define_insn "*ashrdi3_cmp_rex64"
10823 [(set (reg FLAGS_REG)
10825 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10826 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10828 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10829 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
10831 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10832 && ix86_match_ccmode (insn, CCGOCmode)
10833 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10834 "sar{q}\t{%2, %0|%0, %2}"
10835 [(set_attr "type" "ishift")
10836 (set_attr "mode" "DI")])
10838 (define_insn "*ashrdi3_cconly_rex64"
10839 [(set (reg FLAGS_REG)
10841 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
10842 (match_operand:QI 2 "const_1_to_63_operand" "J"))
10844 (clobber (match_scratch:DI 0 "=r"))]
10846 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
10847 && ix86_match_ccmode (insn, CCGOCmode)
10848 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
10849 "sar{q}\t{%2, %0|%0, %2}"
10850 [(set_attr "type" "ishift")
10851 (set_attr "mode" "DI")])
10853 (define_insn "*ashrdi3_1"
10854 [(set (match_operand:DI 0 "register_operand" "=r")
10855 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
10856 (match_operand:QI 2 "nonmemory_operand" "Jc")))
10857 (clobber (reg:CC FLAGS_REG))]
10860 [(set_attr "type" "multi")])
10862 ;; By default we don't ask for a scratch register, because when DImode
10863 ;; values are manipulated, registers are already at a premium. But if
10864 ;; we have one handy, we won't turn it away.
10866 [(match_scratch:SI 3 "r")
10867 (parallel [(set (match_operand:DI 0 "register_operand" "")
10868 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10869 (match_operand:QI 2 "nonmemory_operand" "")))
10870 (clobber (reg:CC FLAGS_REG))])
10872 "!TARGET_64BIT && TARGET_CMOVE"
10874 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
10877 [(set (match_operand:DI 0 "register_operand" "")
10878 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
10879 (match_operand:QI 2 "nonmemory_operand" "")))
10880 (clobber (reg:CC FLAGS_REG))]
10881 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
10882 ? epilogue_completed : reload_completed)"
10884 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
10886 (define_insn "x86_shrd"
10887 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
10888 (ior:SI (ashiftrt:SI (match_dup 0)
10889 (match_operand:QI 2 "nonmemory_operand" "Ic"))
10890 (ashift:SI (match_operand:SI 1 "register_operand" "r")
10891 (minus:QI (const_int 32) (match_dup 2)))))
10892 (clobber (reg:CC FLAGS_REG))]
10894 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
10895 [(set_attr "type" "ishift")
10896 (set_attr "prefix_0f" "1")
10897 (set_attr "pent_pair" "np")
10898 (set_attr "mode" "SI")])
10900 (define_expand "x86_shift_adj_3"
10901 [(use (match_operand:SI 0 "register_operand" ""))
10902 (use (match_operand:SI 1 "register_operand" ""))
10903 (use (match_operand:QI 2 "register_operand" ""))]
10906 rtx label = gen_label_rtx ();
10909 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
10911 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
10912 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
10913 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
10914 gen_rtx_LABEL_REF (VOIDmode, label),
10916 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
10917 JUMP_LABEL (tmp) = label;
10919 emit_move_insn (operands[0], operands[1]);
10920 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
10922 emit_label (label);
10923 LABEL_NUSES (label) = 1;
10928 (define_expand "ashrsi3_31"
10929 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10930 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10931 (match_operand:SI 2 "const_int_operand" "i,i")))
10932 (clobber (reg:CC FLAGS_REG))])]
10935 (define_insn "*ashrsi3_31"
10936 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
10937 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
10938 (match_operand:SI 2 "const_int_operand" "i,i")))
10939 (clobber (reg:CC FLAGS_REG))]
10940 "INTVAL (operands[2]) == 31
10941 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10942 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10945 sar{l}\t{%2, %0|%0, %2}"
10946 [(set_attr "type" "imovx,ishift")
10947 (set_attr "prefix_0f" "0,*")
10948 (set_attr "length_immediate" "0,*")
10949 (set_attr "modrm" "0,1")
10950 (set_attr "mode" "SI")])
10952 (define_insn "*ashrsi3_31_zext"
10953 [(set (match_operand:DI 0 "register_operand" "=*d,r")
10954 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
10955 (match_operand:SI 2 "const_int_operand" "i,i"))))
10956 (clobber (reg:CC FLAGS_REG))]
10957 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
10958 && INTVAL (operands[2]) == 31
10959 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10962 sar{l}\t{%2, %k0|%k0, %2}"
10963 [(set_attr "type" "imovx,ishift")
10964 (set_attr "prefix_0f" "0,*")
10965 (set_attr "length_immediate" "0,*")
10966 (set_attr "modrm" "0,1")
10967 (set_attr "mode" "SI")])
10969 (define_expand "ashrsi3"
10970 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10971 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
10972 (match_operand:QI 2 "nonmemory_operand" "")))]
10974 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
10976 (define_insn "*ashrsi3_1_one_bit"
10977 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10978 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
10979 (match_operand:QI 2 "const1_operand" "")))
10980 (clobber (reg:CC FLAGS_REG))]
10981 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10982 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10984 [(set_attr "type" "ishift")
10985 (set_attr "length_immediate" "0")
10986 (set_attr "mode" "SI")])
10988 (define_insn "*ashrsi3_1_one_bit_zext"
10989 [(set (match_operand:DI 0 "register_operand" "=r")
10990 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
10991 (match_operand:QI 2 "const1_operand" ""))))
10992 (clobber (reg:CC FLAGS_REG))]
10994 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
10995 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
10997 [(set_attr "type" "ishift")
10998 (set_attr "length_immediate" "0")
10999 (set_attr "mode" "SI")])
11001 (define_insn "*ashrsi3_1"
11002 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11003 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11004 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11005 (clobber (reg:CC FLAGS_REG))]
11006 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11008 sar{l}\t{%2, %0|%0, %2}
11009 sar{l}\t{%b2, %0|%0, %b2}"
11010 [(set_attr "type" "ishift")
11011 (set_attr "mode" "SI")])
11013 (define_insn "*ashrsi3_1_zext"
11014 [(set (match_operand:DI 0 "register_operand" "=r,r")
11015 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
11016 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11017 (clobber (reg:CC FLAGS_REG))]
11018 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11020 sar{l}\t{%2, %k0|%k0, %2}
11021 sar{l}\t{%b2, %k0|%k0, %b2}"
11022 [(set_attr "type" "ishift")
11023 (set_attr "mode" "SI")])
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 "*ashrsi3_one_bit_cmp"
11029 [(set (reg FLAGS_REG)
11031 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11032 (match_operand:QI 2 "const1_operand" ""))
11034 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11035 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11036 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11037 && ix86_match_ccmode (insn, CCGOCmode)
11038 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11040 [(set_attr "type" "ishift")
11041 (set_attr "length_immediate" "0")
11042 (set_attr "mode" "SI")])
11044 (define_insn "*ashrsi3_one_bit_cconly"
11045 [(set (reg FLAGS_REG)
11047 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11048 (match_operand:QI 2 "const1_operand" ""))
11050 (clobber (match_scratch:SI 0 "=r"))]
11051 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11052 && ix86_match_ccmode (insn, CCGOCmode)
11053 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11055 [(set_attr "type" "ishift")
11056 (set_attr "length_immediate" "0")
11057 (set_attr "mode" "SI")])
11059 (define_insn "*ashrsi3_one_bit_cmp_zext"
11060 [(set (reg FLAGS_REG)
11062 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11063 (match_operand:QI 2 "const1_operand" ""))
11065 (set (match_operand:DI 0 "register_operand" "=r")
11066 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11068 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11069 && ix86_match_ccmode (insn, CCmode)
11070 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11072 [(set_attr "type" "ishift")
11073 (set_attr "length_immediate" "0")
11074 (set_attr "mode" "SI")])
11076 ;; This pattern can't accept a variable shift count, since shifts by
11077 ;; zero don't affect the flags. We assume that shifts by constant
11078 ;; zero are optimized away.
11079 (define_insn "*ashrsi3_cmp"
11080 [(set (reg FLAGS_REG)
11082 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11083 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11085 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11086 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
11087 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11088 && ix86_match_ccmode (insn, CCGOCmode)
11089 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11090 "sar{l}\t{%2, %0|%0, %2}"
11091 [(set_attr "type" "ishift")
11092 (set_attr "mode" "SI")])
11094 (define_insn "*ashrsi3_cconly"
11095 [(set (reg FLAGS_REG)
11097 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11098 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11100 (clobber (match_scratch:SI 0 "=r"))]
11101 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11102 && ix86_match_ccmode (insn, CCGOCmode)
11103 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11104 "sar{l}\t{%2, %0|%0, %2}"
11105 [(set_attr "type" "ishift")
11106 (set_attr "mode" "SI")])
11108 (define_insn "*ashrsi3_cmp_zext"
11109 [(set (reg FLAGS_REG)
11111 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
11112 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11114 (set (match_operand:DI 0 "register_operand" "=r")
11115 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
11117 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11118 && ix86_match_ccmode (insn, CCGOCmode)
11119 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
11120 "sar{l}\t{%2, %k0|%k0, %2}"
11121 [(set_attr "type" "ishift")
11122 (set_attr "mode" "SI")])
11124 (define_expand "ashrhi3"
11125 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11126 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11127 (match_operand:QI 2 "nonmemory_operand" "")))]
11128 "TARGET_HIMODE_MATH"
11129 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
11131 (define_insn "*ashrhi3_1_one_bit"
11132 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11133 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11134 (match_operand:QI 2 "const1_operand" "")))
11135 (clobber (reg:CC FLAGS_REG))]
11136 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11137 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11139 [(set_attr "type" "ishift")
11140 (set_attr "length_immediate" "0")
11141 (set_attr "mode" "HI")])
11143 (define_insn "*ashrhi3_1"
11144 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11145 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11146 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11147 (clobber (reg:CC FLAGS_REG))]
11148 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11150 sar{w}\t{%2, %0|%0, %2}
11151 sar{w}\t{%b2, %0|%0, %b2}"
11152 [(set_attr "type" "ishift")
11153 (set_attr "mode" "HI")])
11155 ;; This pattern can't accept a variable shift count, since shifts by
11156 ;; zero don't affect the flags. We assume that shifts by constant
11157 ;; zero are optimized away.
11158 (define_insn "*ashrhi3_one_bit_cmp"
11159 [(set (reg FLAGS_REG)
11161 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11162 (match_operand:QI 2 "const1_operand" ""))
11164 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11165 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11166 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11167 && ix86_match_ccmode (insn, CCGOCmode)
11168 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11170 [(set_attr "type" "ishift")
11171 (set_attr "length_immediate" "0")
11172 (set_attr "mode" "HI")])
11174 (define_insn "*ashrhi3_one_bit_cconly"
11175 [(set (reg FLAGS_REG)
11177 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11178 (match_operand:QI 2 "const1_operand" ""))
11180 (clobber (match_scratch:HI 0 "=r"))]
11181 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11182 && ix86_match_ccmode (insn, CCGOCmode)
11183 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11185 [(set_attr "type" "ishift")
11186 (set_attr "length_immediate" "0")
11187 (set_attr "mode" "HI")])
11189 ;; This pattern can't accept a variable shift count, since shifts by
11190 ;; zero don't affect the flags. We assume that shifts by constant
11191 ;; zero are optimized away.
11192 (define_insn "*ashrhi3_cmp"
11193 [(set (reg FLAGS_REG)
11195 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11196 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11198 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11199 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
11200 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11201 && ix86_match_ccmode (insn, CCGOCmode)
11202 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11203 "sar{w}\t{%2, %0|%0, %2}"
11204 [(set_attr "type" "ishift")
11205 (set_attr "mode" "HI")])
11207 (define_insn "*ashrhi3_cconly"
11208 [(set (reg FLAGS_REG)
11210 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11211 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11213 (clobber (match_scratch:HI 0 "=r"))]
11214 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11215 && ix86_match_ccmode (insn, CCGOCmode)
11216 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
11217 "sar{w}\t{%2, %0|%0, %2}"
11218 [(set_attr "type" "ishift")
11219 (set_attr "mode" "HI")])
11221 (define_expand "ashrqi3"
11222 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11223 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11224 (match_operand:QI 2 "nonmemory_operand" "")))]
11225 "TARGET_QIMODE_MATH"
11226 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
11228 (define_insn "*ashrqi3_1_one_bit"
11229 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11230 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11231 (match_operand:QI 2 "const1_operand" "")))
11232 (clobber (reg:CC FLAGS_REG))]
11233 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11234 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11236 [(set_attr "type" "ishift")
11237 (set_attr "length_immediate" "0")
11238 (set_attr "mode" "QI")])
11240 (define_insn "*ashrqi3_1_one_bit_slp"
11241 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11242 (ashiftrt:QI (match_dup 0)
11243 (match_operand:QI 1 "const1_operand" "")))
11244 (clobber (reg:CC FLAGS_REG))]
11245 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11246 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11247 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11249 [(set_attr "type" "ishift1")
11250 (set_attr "length_immediate" "0")
11251 (set_attr "mode" "QI")])
11253 (define_insn "*ashrqi3_1"
11254 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11255 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11256 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11257 (clobber (reg:CC FLAGS_REG))]
11258 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11260 sar{b}\t{%2, %0|%0, %2}
11261 sar{b}\t{%b2, %0|%0, %b2}"
11262 [(set_attr "type" "ishift")
11263 (set_attr "mode" "QI")])
11265 (define_insn "*ashrqi3_1_slp"
11266 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11267 (ashiftrt:QI (match_dup 0)
11268 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11269 (clobber (reg:CC FLAGS_REG))]
11270 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11271 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11273 sar{b}\t{%1, %0|%0, %1}
11274 sar{b}\t{%b1, %0|%0, %b1}"
11275 [(set_attr "type" "ishift1")
11276 (set_attr "mode" "QI")])
11278 ;; This pattern can't accept a variable shift count, since shifts by
11279 ;; zero don't affect the flags. We assume that shifts by constant
11280 ;; zero are optimized away.
11281 (define_insn "*ashrqi3_one_bit_cmp"
11282 [(set (reg FLAGS_REG)
11284 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11285 (match_operand:QI 2 "const1_operand" "I"))
11287 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11288 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11289 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11290 && ix86_match_ccmode (insn, CCGOCmode)
11291 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11293 [(set_attr "type" "ishift")
11294 (set_attr "length_immediate" "0")
11295 (set_attr "mode" "QI")])
11297 (define_insn "*ashrqi3_one_bit_cconly"
11298 [(set (reg FLAGS_REG)
11300 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11301 (match_operand:QI 2 "const1_operand" ""))
11303 (clobber (match_scratch:QI 0 "=q"))]
11304 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11305 && ix86_match_ccmode (insn, CCGOCmode)
11306 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11308 [(set_attr "type" "ishift")
11309 (set_attr "length_immediate" "0")
11310 (set_attr "mode" "QI")])
11312 ;; This pattern can't accept a variable shift count, since shifts by
11313 ;; zero don't affect the flags. We assume that shifts by constant
11314 ;; zero are optimized away.
11315 (define_insn "*ashrqi3_cmp"
11316 [(set (reg FLAGS_REG)
11318 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11319 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11321 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11322 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
11323 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11324 && ix86_match_ccmode (insn, CCGOCmode)
11325 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11326 "sar{b}\t{%2, %0|%0, %2}"
11327 [(set_attr "type" "ishift")
11328 (set_attr "mode" "QI")])
11330 (define_insn "*ashrqi3_cconly"
11331 [(set (reg FLAGS_REG)
11333 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11334 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11336 (clobber (match_scratch:QI 0 "=q"))]
11337 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11338 && ix86_match_ccmode (insn, CCGOCmode)
11339 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
11340 "sar{b}\t{%2, %0|%0, %2}"
11341 [(set_attr "type" "ishift")
11342 (set_attr "mode" "QI")])
11345 ;; Logical shift instructions
11347 ;; See comment above `ashldi3' about how this works.
11349 (define_expand "lshrti3"
11350 [(set (match_operand:TI 0 "register_operand" "")
11351 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11352 (match_operand:QI 2 "nonmemory_operand" "")))]
11354 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
11356 (define_insn "*lshrti3_1"
11357 [(set (match_operand:TI 0 "register_operand" "=r")
11358 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
11359 (match_operand:QI 2 "nonmemory_operand" "Oc")))
11360 (clobber (reg:CC FLAGS_REG))]
11363 [(set_attr "type" "multi")])
11366 [(match_scratch:DI 3 "r")
11367 (parallel [(set (match_operand:TI 0 "register_operand" "")
11368 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11369 (match_operand:QI 2 "nonmemory_operand" "")))
11370 (clobber (reg:CC FLAGS_REG))])
11374 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
11377 [(set (match_operand:TI 0 "register_operand" "")
11378 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
11379 (match_operand:QI 2 "nonmemory_operand" "")))
11380 (clobber (reg:CC FLAGS_REG))]
11381 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11382 ? epilogue_completed : reload_completed)"
11384 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
11386 (define_expand "lshrdi3"
11387 [(set (match_operand:DI 0 "shiftdi_operand" "")
11388 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
11389 (match_operand:QI 2 "nonmemory_operand" "")))]
11391 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
11393 (define_insn "*lshrdi3_1_one_bit_rex64"
11394 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11395 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11396 (match_operand:QI 2 "const1_operand" "")))
11397 (clobber (reg:CC FLAGS_REG))]
11399 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11400 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11402 [(set_attr "type" "ishift")
11403 (set_attr "length_immediate" "0")
11404 (set_attr "mode" "DI")])
11406 (define_insn "*lshrdi3_1_rex64"
11407 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11408 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11409 (match_operand:QI 2 "nonmemory_operand" "J,c")))
11410 (clobber (reg:CC FLAGS_REG))]
11411 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11413 shr{q}\t{%2, %0|%0, %2}
11414 shr{q}\t{%b2, %0|%0, %b2}"
11415 [(set_attr "type" "ishift")
11416 (set_attr "mode" "DI")])
11418 ;; This pattern can't accept a variable shift count, since shifts by
11419 ;; zero don't affect the flags. We assume that shifts by constant
11420 ;; zero are optimized away.
11421 (define_insn "*lshrdi3_cmp_one_bit_rex64"
11422 [(set (reg FLAGS_REG)
11424 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11425 (match_operand:QI 2 "const1_operand" ""))
11427 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11428 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11430 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11431 && ix86_match_ccmode (insn, CCGOCmode)
11432 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11434 [(set_attr "type" "ishift")
11435 (set_attr "length_immediate" "0")
11436 (set_attr "mode" "DI")])
11438 (define_insn "*lshrdi3_cconly_one_bit_rex64"
11439 [(set (reg FLAGS_REG)
11441 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11442 (match_operand:QI 2 "const1_operand" ""))
11444 (clobber (match_scratch:DI 0 "=r"))]
11446 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11447 && ix86_match_ccmode (insn, CCGOCmode)
11448 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11450 [(set_attr "type" "ishift")
11451 (set_attr "length_immediate" "0")
11452 (set_attr "mode" "DI")])
11454 ;; This pattern can't accept a variable shift count, since shifts by
11455 ;; zero don't affect the flags. We assume that shifts by constant
11456 ;; zero are optimized away.
11457 (define_insn "*lshrdi3_cmp_rex64"
11458 [(set (reg FLAGS_REG)
11460 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11461 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11463 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11464 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
11466 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11467 && ix86_match_ccmode (insn, CCGOCmode)
11468 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11469 "shr{q}\t{%2, %0|%0, %2}"
11470 [(set_attr "type" "ishift")
11471 (set_attr "mode" "DI")])
11473 (define_insn "*lshrdi3_cconly_rex64"
11474 [(set (reg FLAGS_REG)
11476 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11477 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11479 (clobber (match_scratch:DI 0 "=r"))]
11481 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11482 && ix86_match_ccmode (insn, CCGOCmode)
11483 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11484 "shr{q}\t{%2, %0|%0, %2}"
11485 [(set_attr "type" "ishift")
11486 (set_attr "mode" "DI")])
11488 (define_insn "*lshrdi3_1"
11489 [(set (match_operand:DI 0 "register_operand" "=r")
11490 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
11491 (match_operand:QI 2 "nonmemory_operand" "Jc")))
11492 (clobber (reg:CC FLAGS_REG))]
11495 [(set_attr "type" "multi")])
11497 ;; By default we don't ask for a scratch register, because when DImode
11498 ;; values are manipulated, registers are already at a premium. But if
11499 ;; we have one handy, we won't turn it away.
11501 [(match_scratch:SI 3 "r")
11502 (parallel [(set (match_operand:DI 0 "register_operand" "")
11503 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11504 (match_operand:QI 2 "nonmemory_operand" "")))
11505 (clobber (reg:CC FLAGS_REG))])
11507 "!TARGET_64BIT && TARGET_CMOVE"
11509 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
11512 [(set (match_operand:DI 0 "register_operand" "")
11513 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
11514 (match_operand:QI 2 "nonmemory_operand" "")))
11515 (clobber (reg:CC FLAGS_REG))]
11516 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11517 ? epilogue_completed : reload_completed)"
11519 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
11521 (define_expand "lshrsi3"
11522 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11523 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
11524 (match_operand:QI 2 "nonmemory_operand" "")))]
11526 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
11528 (define_insn "*lshrsi3_1_one_bit"
11529 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11530 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11531 (match_operand:QI 2 "const1_operand" "")))
11532 (clobber (reg:CC FLAGS_REG))]
11533 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11534 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11536 [(set_attr "type" "ishift")
11537 (set_attr "length_immediate" "0")
11538 (set_attr "mode" "SI")])
11540 (define_insn "*lshrsi3_1_one_bit_zext"
11541 [(set (match_operand:DI 0 "register_operand" "=r")
11542 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
11543 (match_operand:QI 2 "const1_operand" "")))
11544 (clobber (reg:CC FLAGS_REG))]
11546 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11547 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11549 [(set_attr "type" "ishift")
11550 (set_attr "length_immediate" "0")
11551 (set_attr "mode" "SI")])
11553 (define_insn "*lshrsi3_1"
11554 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
11555 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11556 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11557 (clobber (reg:CC FLAGS_REG))]
11558 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11560 shr{l}\t{%2, %0|%0, %2}
11561 shr{l}\t{%b2, %0|%0, %b2}"
11562 [(set_attr "type" "ishift")
11563 (set_attr "mode" "SI")])
11565 (define_insn "*lshrsi3_1_zext"
11566 [(set (match_operand:DI 0 "register_operand" "=r,r")
11568 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
11569 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
11570 (clobber (reg:CC FLAGS_REG))]
11571 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11573 shr{l}\t{%2, %k0|%k0, %2}
11574 shr{l}\t{%b2, %k0|%k0, %b2}"
11575 [(set_attr "type" "ishift")
11576 (set_attr "mode" "SI")])
11578 ;; This pattern can't accept a variable shift count, since shifts by
11579 ;; zero don't affect the flags. We assume that shifts by constant
11580 ;; zero are optimized away.
11581 (define_insn "*lshrsi3_one_bit_cmp"
11582 [(set (reg FLAGS_REG)
11584 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11585 (match_operand:QI 2 "const1_operand" ""))
11587 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11588 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11589 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11590 && ix86_match_ccmode (insn, CCGOCmode)
11591 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11593 [(set_attr "type" "ishift")
11594 (set_attr "length_immediate" "0")
11595 (set_attr "mode" "SI")])
11597 (define_insn "*lshrsi3_one_bit_cconly"
11598 [(set (reg FLAGS_REG)
11600 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11601 (match_operand:QI 2 "const1_operand" ""))
11603 (clobber (match_scratch:SI 0 "=r"))]
11604 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11605 && ix86_match_ccmode (insn, CCGOCmode)
11606 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11608 [(set_attr "type" "ishift")
11609 (set_attr "length_immediate" "0")
11610 (set_attr "mode" "SI")])
11612 (define_insn "*lshrsi3_cmp_one_bit_zext"
11613 [(set (reg FLAGS_REG)
11615 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11616 (match_operand:QI 2 "const1_operand" ""))
11618 (set (match_operand:DI 0 "register_operand" "=r")
11619 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11621 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11622 && ix86_match_ccmode (insn, CCGOCmode)
11623 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11625 [(set_attr "type" "ishift")
11626 (set_attr "length_immediate" "0")
11627 (set_attr "mode" "SI")])
11629 ;; This pattern can't accept a variable shift count, since shifts by
11630 ;; zero don't affect the flags. We assume that shifts by constant
11631 ;; zero are optimized away.
11632 (define_insn "*lshrsi3_cmp"
11633 [(set (reg FLAGS_REG)
11635 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11636 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11638 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11639 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
11640 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11641 && ix86_match_ccmode (insn, CCGOCmode)
11642 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11643 "shr{l}\t{%2, %0|%0, %2}"
11644 [(set_attr "type" "ishift")
11645 (set_attr "mode" "SI")])
11647 (define_insn "*lshrsi3_cconly"
11648 [(set (reg FLAGS_REG)
11650 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11651 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11653 (clobber (match_scratch:SI 0 "=r"))]
11654 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11655 && ix86_match_ccmode (insn, CCGOCmode)
11656 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11657 "shr{l}\t{%2, %0|%0, %2}"
11658 [(set_attr "type" "ishift")
11659 (set_attr "mode" "SI")])
11661 (define_insn "*lshrsi3_cmp_zext"
11662 [(set (reg FLAGS_REG)
11664 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
11665 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11667 (set (match_operand:DI 0 "register_operand" "=r")
11668 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
11670 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11671 && ix86_match_ccmode (insn, CCGOCmode)
11672 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11673 "shr{l}\t{%2, %k0|%k0, %2}"
11674 [(set_attr "type" "ishift")
11675 (set_attr "mode" "SI")])
11677 (define_expand "lshrhi3"
11678 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11679 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
11680 (match_operand:QI 2 "nonmemory_operand" "")))]
11681 "TARGET_HIMODE_MATH"
11682 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
11684 (define_insn "*lshrhi3_1_one_bit"
11685 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11686 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11687 (match_operand:QI 2 "const1_operand" "")))
11688 (clobber (reg:CC FLAGS_REG))]
11689 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11690 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11692 [(set_attr "type" "ishift")
11693 (set_attr "length_immediate" "0")
11694 (set_attr "mode" "HI")])
11696 (define_insn "*lshrhi3_1"
11697 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
11698 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
11699 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11700 (clobber (reg:CC FLAGS_REG))]
11701 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11703 shr{w}\t{%2, %0|%0, %2}
11704 shr{w}\t{%b2, %0|%0, %b2}"
11705 [(set_attr "type" "ishift")
11706 (set_attr "mode" "HI")])
11708 ;; This pattern can't accept a variable shift count, since shifts by
11709 ;; zero don't affect the flags. We assume that shifts by constant
11710 ;; zero are optimized away.
11711 (define_insn "*lshrhi3_one_bit_cmp"
11712 [(set (reg FLAGS_REG)
11714 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11715 (match_operand:QI 2 "const1_operand" ""))
11717 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11718 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11719 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11720 && ix86_match_ccmode (insn, CCGOCmode)
11721 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11723 [(set_attr "type" "ishift")
11724 (set_attr "length_immediate" "0")
11725 (set_attr "mode" "HI")])
11727 (define_insn "*lshrhi3_one_bit_cconly"
11728 [(set (reg FLAGS_REG)
11730 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11731 (match_operand:QI 2 "const1_operand" ""))
11733 (clobber (match_scratch:HI 0 "=r"))]
11734 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11735 && ix86_match_ccmode (insn, CCGOCmode)
11736 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11738 [(set_attr "type" "ishift")
11739 (set_attr "length_immediate" "0")
11740 (set_attr "mode" "HI")])
11742 ;; This pattern can't accept a variable shift count, since shifts by
11743 ;; zero don't affect the flags. We assume that shifts by constant
11744 ;; zero are optimized away.
11745 (define_insn "*lshrhi3_cmp"
11746 [(set (reg FLAGS_REG)
11748 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11749 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11751 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11752 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
11753 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11754 && ix86_match_ccmode (insn, CCGOCmode)
11755 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11756 "shr{w}\t{%2, %0|%0, %2}"
11757 [(set_attr "type" "ishift")
11758 (set_attr "mode" "HI")])
11760 (define_insn "*lshrhi3_cconly"
11761 [(set (reg FLAGS_REG)
11763 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
11764 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11766 (clobber (match_scratch:HI 0 "=r"))]
11767 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11768 && ix86_match_ccmode (insn, CCGOCmode)
11769 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
11770 "shr{w}\t{%2, %0|%0, %2}"
11771 [(set_attr "type" "ishift")
11772 (set_attr "mode" "HI")])
11774 (define_expand "lshrqi3"
11775 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11776 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
11777 (match_operand:QI 2 "nonmemory_operand" "")))]
11778 "TARGET_QIMODE_MATH"
11779 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
11781 (define_insn "*lshrqi3_1_one_bit"
11782 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11783 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11784 (match_operand:QI 2 "const1_operand" "")))
11785 (clobber (reg:CC FLAGS_REG))]
11786 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11787 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11789 [(set_attr "type" "ishift")
11790 (set_attr "length_immediate" "0")
11791 (set_attr "mode" "QI")])
11793 (define_insn "*lshrqi3_1_one_bit_slp"
11794 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
11795 (lshiftrt:QI (match_dup 0)
11796 (match_operand:QI 1 "const1_operand" "")))
11797 (clobber (reg:CC FLAGS_REG))]
11798 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11799 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
11801 [(set_attr "type" "ishift1")
11802 (set_attr "length_immediate" "0")
11803 (set_attr "mode" "QI")])
11805 (define_insn "*lshrqi3_1"
11806 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
11807 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
11808 (match_operand:QI 2 "nonmemory_operand" "I,c")))
11809 (clobber (reg:CC FLAGS_REG))]
11810 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11812 shr{b}\t{%2, %0|%0, %2}
11813 shr{b}\t{%b2, %0|%0, %b2}"
11814 [(set_attr "type" "ishift")
11815 (set_attr "mode" "QI")])
11817 (define_insn "*lshrqi3_1_slp"
11818 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
11819 (lshiftrt:QI (match_dup 0)
11820 (match_operand:QI 1 "nonmemory_operand" "I,c")))
11821 (clobber (reg:CC FLAGS_REG))]
11822 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
11823 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
11825 shr{b}\t{%1, %0|%0, %1}
11826 shr{b}\t{%b1, %0|%0, %b1}"
11827 [(set_attr "type" "ishift1")
11828 (set_attr "mode" "QI")])
11830 ;; This pattern can't accept a variable shift count, since shifts by
11831 ;; zero don't affect the flags. We assume that shifts by constant
11832 ;; zero are optimized away.
11833 (define_insn "*lshrqi2_one_bit_cmp"
11834 [(set (reg FLAGS_REG)
11836 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11837 (match_operand:QI 2 "const1_operand" ""))
11839 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11840 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11841 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11842 && ix86_match_ccmode (insn, CCGOCmode)
11843 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11845 [(set_attr "type" "ishift")
11846 (set_attr "length_immediate" "0")
11847 (set_attr "mode" "QI")])
11849 (define_insn "*lshrqi2_one_bit_cconly"
11850 [(set (reg FLAGS_REG)
11852 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11853 (match_operand:QI 2 "const1_operand" ""))
11855 (clobber (match_scratch:QI 0 "=q"))]
11856 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11857 && ix86_match_ccmode (insn, CCGOCmode)
11858 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11860 [(set_attr "type" "ishift")
11861 (set_attr "length_immediate" "0")
11862 (set_attr "mode" "QI")])
11864 ;; This pattern can't accept a variable shift count, since shifts by
11865 ;; zero don't affect the flags. We assume that shifts by constant
11866 ;; zero are optimized away.
11867 (define_insn "*lshrqi2_cmp"
11868 [(set (reg FLAGS_REG)
11870 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11871 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11873 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11874 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
11875 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11876 && ix86_match_ccmode (insn, CCGOCmode)
11877 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11878 "shr{b}\t{%2, %0|%0, %2}"
11879 [(set_attr "type" "ishift")
11880 (set_attr "mode" "QI")])
11882 (define_insn "*lshrqi2_cconly"
11883 [(set (reg FLAGS_REG)
11885 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
11886 (match_operand:QI 2 "const_1_to_31_operand" "I"))
11888 (clobber (match_scratch:QI 0 "=q"))]
11889 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
11890 && ix86_match_ccmode (insn, CCGOCmode)
11891 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
11892 "shr{b}\t{%2, %0|%0, %2}"
11893 [(set_attr "type" "ishift")
11894 (set_attr "mode" "QI")])
11896 ;; Rotate instructions
11898 (define_expand "rotldi3"
11899 [(set (match_operand:DI 0 "shiftdi_operand" "")
11900 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
11901 (match_operand:QI 2 "nonmemory_operand" "")))]
11906 ix86_expand_binary_operator (ROTATE, DImode, operands);
11909 if (!const_1_to_31_operand (operands[2], VOIDmode))
11911 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
11915 ;; Implement rotation using two double-precision shift instructions
11916 ;; and a scratch register.
11917 (define_insn_and_split "ix86_rotldi3"
11918 [(set (match_operand:DI 0 "register_operand" "=r")
11919 (rotate:DI (match_operand:DI 1 "register_operand" "0")
11920 (match_operand:QI 2 "const_1_to_31_operand" "I")))
11921 (clobber (reg:CC FLAGS_REG))
11922 (clobber (match_scratch:SI 3 "=&r"))]
11925 "&& reload_completed"
11926 [(set (match_dup 3) (match_dup 4))
11928 [(set (match_dup 4)
11929 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
11930 (lshiftrt:SI (match_dup 5)
11931 (minus:QI (const_int 32) (match_dup 2)))))
11932 (clobber (reg:CC FLAGS_REG))])
11934 [(set (match_dup 5)
11935 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
11936 (lshiftrt:SI (match_dup 3)
11937 (minus:QI (const_int 32) (match_dup 2)))))
11938 (clobber (reg:CC FLAGS_REG))])]
11939 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
11941 (define_insn "*rotlsi3_1_one_bit_rex64"
11942 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11943 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11944 (match_operand:QI 2 "const1_operand" "")))
11945 (clobber (reg:CC FLAGS_REG))]
11947 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11948 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11950 [(set_attr "type" "rotate")
11951 (set_attr "length_immediate" "0")
11952 (set_attr "mode" "DI")])
11954 (define_insn "*rotldi3_1_rex64"
11955 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
11956 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
11957 (match_operand:QI 2 "nonmemory_operand" "e,c")))
11958 (clobber (reg:CC FLAGS_REG))]
11959 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
11961 rol{q}\t{%2, %0|%0, %2}
11962 rol{q}\t{%b2, %0|%0, %b2}"
11963 [(set_attr "type" "rotate")
11964 (set_attr "mode" "DI")])
11966 (define_expand "rotlsi3"
11967 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11968 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
11969 (match_operand:QI 2 "nonmemory_operand" "")))]
11971 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
11973 (define_insn "*rotlsi3_1_one_bit"
11974 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11975 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
11976 (match_operand:QI 2 "const1_operand" "")))
11977 (clobber (reg:CC FLAGS_REG))]
11978 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11979 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11981 [(set_attr "type" "rotate")
11982 (set_attr "length_immediate" "0")
11983 (set_attr "mode" "SI")])
11985 (define_insn "*rotlsi3_1_one_bit_zext"
11986 [(set (match_operand:DI 0 "register_operand" "=r")
11988 (rotate:SI (match_operand:SI 1 "register_operand" "0")
11989 (match_operand:QI 2 "const1_operand" ""))))
11990 (clobber (reg:CC FLAGS_REG))]
11992 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
11993 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
11995 [(set_attr "type" "rotate")
11996 (set_attr "length_immediate" "0")
11997 (set_attr "mode" "SI")])
11999 (define_insn "*rotlsi3_1"
12000 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12001 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12002 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12003 (clobber (reg:CC FLAGS_REG))]
12004 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
12006 rol{l}\t{%2, %0|%0, %2}
12007 rol{l}\t{%b2, %0|%0, %b2}"
12008 [(set_attr "type" "rotate")
12009 (set_attr "mode" "SI")])
12011 (define_insn "*rotlsi3_1_zext"
12012 [(set (match_operand:DI 0 "register_operand" "=r,r")
12014 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
12015 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12016 (clobber (reg:CC FLAGS_REG))]
12017 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
12019 rol{l}\t{%2, %k0|%k0, %2}
12020 rol{l}\t{%b2, %k0|%k0, %b2}"
12021 [(set_attr "type" "rotate")
12022 (set_attr "mode" "SI")])
12024 (define_expand "rotlhi3"
12025 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12026 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
12027 (match_operand:QI 2 "nonmemory_operand" "")))]
12028 "TARGET_HIMODE_MATH"
12029 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
12031 (define_insn "*rotlhi3_1_one_bit"
12032 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12033 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12034 (match_operand:QI 2 "const1_operand" "")))
12035 (clobber (reg:CC FLAGS_REG))]
12036 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12037 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
12039 [(set_attr "type" "rotate")
12040 (set_attr "length_immediate" "0")
12041 (set_attr "mode" "HI")])
12043 (define_insn "*rotlhi3_1"
12044 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12045 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12046 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12047 (clobber (reg:CC FLAGS_REG))]
12048 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
12050 rol{w}\t{%2, %0|%0, %2}
12051 rol{w}\t{%b2, %0|%0, %b2}"
12052 [(set_attr "type" "rotate")
12053 (set_attr "mode" "HI")])
12056 [(set (match_operand:HI 0 "register_operand" "")
12057 (rotate:HI (match_dup 0) (const_int 8)))
12058 (clobber (reg:CC FLAGS_REG))]
12060 [(parallel [(set (strict_low_part (match_dup 0))
12061 (bswap:HI (match_dup 0)))
12062 (clobber (reg:CC FLAGS_REG))])]
12065 (define_expand "rotlqi3"
12066 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12067 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
12068 (match_operand:QI 2 "nonmemory_operand" "")))]
12069 "TARGET_QIMODE_MATH"
12070 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
12072 (define_insn "*rotlqi3_1_one_bit_slp"
12073 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12074 (rotate:QI (match_dup 0)
12075 (match_operand:QI 1 "const1_operand" "")))
12076 (clobber (reg:CC FLAGS_REG))]
12077 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12078 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12080 [(set_attr "type" "rotate1")
12081 (set_attr "length_immediate" "0")
12082 (set_attr "mode" "QI")])
12084 (define_insn "*rotlqi3_1_one_bit"
12085 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12086 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12087 (match_operand:QI 2 "const1_operand" "")))
12088 (clobber (reg:CC FLAGS_REG))]
12089 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12090 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
12092 [(set_attr "type" "rotate")
12093 (set_attr "length_immediate" "0")
12094 (set_attr "mode" "QI")])
12096 (define_insn "*rotlqi3_1_slp"
12097 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12098 (rotate:QI (match_dup 0)
12099 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12100 (clobber (reg:CC FLAGS_REG))]
12101 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12102 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12104 rol{b}\t{%1, %0|%0, %1}
12105 rol{b}\t{%b1, %0|%0, %b1}"
12106 [(set_attr "type" "rotate1")
12107 (set_attr "mode" "QI")])
12109 (define_insn "*rotlqi3_1"
12110 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12111 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12112 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12113 (clobber (reg:CC FLAGS_REG))]
12114 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
12116 rol{b}\t{%2, %0|%0, %2}
12117 rol{b}\t{%b2, %0|%0, %b2}"
12118 [(set_attr "type" "rotate")
12119 (set_attr "mode" "QI")])
12121 (define_expand "rotrdi3"
12122 [(set (match_operand:DI 0 "shiftdi_operand" "")
12123 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
12124 (match_operand:QI 2 "nonmemory_operand" "")))]
12129 ix86_expand_binary_operator (ROTATERT, DImode, operands);
12132 if (!const_1_to_31_operand (operands[2], VOIDmode))
12134 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
12138 ;; Implement rotation using two double-precision shift instructions
12139 ;; and a scratch register.
12140 (define_insn_and_split "ix86_rotrdi3"
12141 [(set (match_operand:DI 0 "register_operand" "=r")
12142 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
12143 (match_operand:QI 2 "const_1_to_31_operand" "I")))
12144 (clobber (reg:CC FLAGS_REG))
12145 (clobber (match_scratch:SI 3 "=&r"))]
12148 "&& reload_completed"
12149 [(set (match_dup 3) (match_dup 4))
12151 [(set (match_dup 4)
12152 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
12153 (ashift:SI (match_dup 5)
12154 (minus:QI (const_int 32) (match_dup 2)))))
12155 (clobber (reg:CC FLAGS_REG))])
12157 [(set (match_dup 5)
12158 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
12159 (ashift:SI (match_dup 3)
12160 (minus:QI (const_int 32) (match_dup 2)))))
12161 (clobber (reg:CC FLAGS_REG))])]
12162 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
12164 (define_insn "*rotrdi3_1_one_bit_rex64"
12165 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12166 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12167 (match_operand:QI 2 "const1_operand" "")))
12168 (clobber (reg:CC FLAGS_REG))]
12170 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12171 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12173 [(set_attr "type" "rotate")
12174 (set_attr "length_immediate" "0")
12175 (set_attr "mode" "DI")])
12177 (define_insn "*rotrdi3_1_rex64"
12178 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12179 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12180 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12181 (clobber (reg:CC FLAGS_REG))]
12182 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
12184 ror{q}\t{%2, %0|%0, %2}
12185 ror{q}\t{%b2, %0|%0, %b2}"
12186 [(set_attr "type" "rotate")
12187 (set_attr "mode" "DI")])
12189 (define_expand "rotrsi3"
12190 [(set (match_operand:SI 0 "nonimmediate_operand" "")
12191 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
12192 (match_operand:QI 2 "nonmemory_operand" "")))]
12194 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
12196 (define_insn "*rotrsi3_1_one_bit"
12197 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12198 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12199 (match_operand:QI 2 "const1_operand" "")))
12200 (clobber (reg:CC FLAGS_REG))]
12201 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12202 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12204 [(set_attr "type" "rotate")
12205 (set_attr "length_immediate" "0")
12206 (set_attr "mode" "SI")])
12208 (define_insn "*rotrsi3_1_one_bit_zext"
12209 [(set (match_operand:DI 0 "register_operand" "=r")
12211 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
12212 (match_operand:QI 2 "const1_operand" ""))))
12213 (clobber (reg:CC FLAGS_REG))]
12215 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12216 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12218 [(set_attr "type" "rotate")
12219 (set_attr "length_immediate" "0")
12220 (set_attr "mode" "SI")])
12222 (define_insn "*rotrsi3_1"
12223 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
12224 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
12225 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12226 (clobber (reg:CC FLAGS_REG))]
12227 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12229 ror{l}\t{%2, %0|%0, %2}
12230 ror{l}\t{%b2, %0|%0, %b2}"
12231 [(set_attr "type" "rotate")
12232 (set_attr "mode" "SI")])
12234 (define_insn "*rotrsi3_1_zext"
12235 [(set (match_operand:DI 0 "register_operand" "=r,r")
12237 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
12238 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
12239 (clobber (reg:CC FLAGS_REG))]
12240 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
12242 ror{l}\t{%2, %k0|%k0, %2}
12243 ror{l}\t{%b2, %k0|%k0, %b2}"
12244 [(set_attr "type" "rotate")
12245 (set_attr "mode" "SI")])
12247 (define_expand "rotrhi3"
12248 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12249 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
12250 (match_operand:QI 2 "nonmemory_operand" "")))]
12251 "TARGET_HIMODE_MATH"
12252 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
12254 (define_insn "*rotrhi3_one_bit"
12255 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12256 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12257 (match_operand:QI 2 "const1_operand" "")))
12258 (clobber (reg:CC FLAGS_REG))]
12259 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12260 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12262 [(set_attr "type" "rotate")
12263 (set_attr "length_immediate" "0")
12264 (set_attr "mode" "HI")])
12266 (define_insn "*rotrhi3_1"
12267 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
12268 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
12269 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12270 (clobber (reg:CC FLAGS_REG))]
12271 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
12273 ror{w}\t{%2, %0|%0, %2}
12274 ror{w}\t{%b2, %0|%0, %b2}"
12275 [(set_attr "type" "rotate")
12276 (set_attr "mode" "HI")])
12279 [(set (match_operand:HI 0 "register_operand" "")
12280 (rotatert:HI (match_dup 0) (const_int 8)))
12281 (clobber (reg:CC FLAGS_REG))]
12283 [(parallel [(set (strict_low_part (match_dup 0))
12284 (bswap:HI (match_dup 0)))
12285 (clobber (reg:CC FLAGS_REG))])]
12288 (define_expand "rotrqi3"
12289 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12290 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
12291 (match_operand:QI 2 "nonmemory_operand" "")))]
12292 "TARGET_QIMODE_MATH"
12293 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
12295 (define_insn "*rotrqi3_1_one_bit"
12296 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12297 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12298 (match_operand:QI 2 "const1_operand" "")))
12299 (clobber (reg:CC FLAGS_REG))]
12300 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12301 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12303 [(set_attr "type" "rotate")
12304 (set_attr "length_immediate" "0")
12305 (set_attr "mode" "QI")])
12307 (define_insn "*rotrqi3_1_one_bit_slp"
12308 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12309 (rotatert:QI (match_dup 0)
12310 (match_operand:QI 1 "const1_operand" "")))
12311 (clobber (reg:CC FLAGS_REG))]
12312 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12313 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
12315 [(set_attr "type" "rotate1")
12316 (set_attr "length_immediate" "0")
12317 (set_attr "mode" "QI")])
12319 (define_insn "*rotrqi3_1"
12320 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
12321 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12322 (match_operand:QI 2 "nonmemory_operand" "I,c")))
12323 (clobber (reg:CC FLAGS_REG))]
12324 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
12326 ror{b}\t{%2, %0|%0, %2}
12327 ror{b}\t{%b2, %0|%0, %b2}"
12328 [(set_attr "type" "rotate")
12329 (set_attr "mode" "QI")])
12331 (define_insn "*rotrqi3_1_slp"
12332 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
12333 (rotatert:QI (match_dup 0)
12334 (match_operand:QI 1 "nonmemory_operand" "I,c")))
12335 (clobber (reg:CC FLAGS_REG))]
12336 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
12337 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
12339 ror{b}\t{%1, %0|%0, %1}
12340 ror{b}\t{%b1, %0|%0, %b1}"
12341 [(set_attr "type" "rotate1")
12342 (set_attr "mode" "QI")])
12344 ;; Bit set / bit test instructions
12346 (define_expand "extv"
12347 [(set (match_operand:SI 0 "register_operand" "")
12348 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
12349 (match_operand:SI 2 "const8_operand" "")
12350 (match_operand:SI 3 "const8_operand" "")))]
12353 /* Handle extractions from %ah et al. */
12354 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12357 /* From mips.md: extract_bit_field doesn't verify that our source
12358 matches the predicate, so check it again here. */
12359 if (! ext_register_operand (operands[1], VOIDmode))
12363 (define_expand "extzv"
12364 [(set (match_operand:SI 0 "register_operand" "")
12365 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
12366 (match_operand:SI 2 "const8_operand" "")
12367 (match_operand:SI 3 "const8_operand" "")))]
12370 /* Handle extractions from %ah et al. */
12371 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
12374 /* From mips.md: extract_bit_field doesn't verify that our source
12375 matches the predicate, so check it again here. */
12376 if (! ext_register_operand (operands[1], VOIDmode))
12380 (define_expand "insv"
12381 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
12382 (match_operand 1 "const8_operand" "")
12383 (match_operand 2 "const8_operand" ""))
12384 (match_operand 3 "register_operand" ""))]
12387 /* Handle insertions to %ah et al. */
12388 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
12391 /* From mips.md: insert_bit_field doesn't verify that our source
12392 matches the predicate, so check it again here. */
12393 if (! ext_register_operand (operands[0], VOIDmode))
12397 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
12399 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
12404 ;; %%% bts, btr, btc, bt.
12405 ;; In general these instructions are *slow* when applied to memory,
12406 ;; since they enforce atomic operation. When applied to registers,
12407 ;; it depends on the cpu implementation. They're never faster than
12408 ;; the corresponding and/ior/xor operations, so with 32-bit there's
12409 ;; no point. But in 64-bit, we can't hold the relevant immediates
12410 ;; within the instruction itself, so operating on bits in the high
12411 ;; 32-bits of a register becomes easier.
12413 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
12414 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
12415 ;; negdf respectively, so they can never be disabled entirely.
12417 (define_insn "*btsq"
12418 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12420 (match_operand:DI 1 "const_0_to_63_operand" ""))
12422 (clobber (reg:CC FLAGS_REG))]
12423 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12424 "bts{q}\t{%1, %0|%0, %1}"
12425 [(set_attr "type" "alu1")
12426 (set_attr "prefix_0f" "1")
12427 (set_attr "mode" "DI")])
12429 (define_insn "*btrq"
12430 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12432 (match_operand:DI 1 "const_0_to_63_operand" ""))
12434 (clobber (reg:CC FLAGS_REG))]
12435 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12436 "btr{q}\t{%1, %0|%0, %1}"
12437 [(set_attr "type" "alu1")
12438 (set_attr "prefix_0f" "1")
12439 (set_attr "mode" "DI")])
12441 (define_insn "*btcq"
12442 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
12444 (match_operand:DI 1 "const_0_to_63_operand" ""))
12445 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
12446 (clobber (reg:CC FLAGS_REG))]
12447 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
12448 "btc{q}\t{%1, %0|%0, %1}"
12449 [(set_attr "type" "alu1")
12450 (set_attr "prefix_0f" "1")
12451 (set_attr "mode" "DI")])
12453 ;; Allow Nocona to avoid these instructions if a register is available.
12456 [(match_scratch:DI 2 "r")
12457 (parallel [(set (zero_extract:DI
12458 (match_operand:DI 0 "register_operand" "")
12460 (match_operand:DI 1 "const_0_to_63_operand" ""))
12462 (clobber (reg:CC FLAGS_REG))])]
12463 "TARGET_64BIT && !TARGET_USE_BT"
12466 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12469 if (HOST_BITS_PER_WIDE_INT >= 64)
12470 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12471 else if (i < HOST_BITS_PER_WIDE_INT)
12472 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12474 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12476 op1 = immed_double_const (lo, hi, DImode);
12479 emit_move_insn (operands[2], op1);
12483 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
12488 [(match_scratch:DI 2 "r")
12489 (parallel [(set (zero_extract:DI
12490 (match_operand:DI 0 "register_operand" "")
12492 (match_operand:DI 1 "const_0_to_63_operand" ""))
12494 (clobber (reg:CC FLAGS_REG))])]
12495 "TARGET_64BIT && !TARGET_USE_BT"
12498 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12501 if (HOST_BITS_PER_WIDE_INT >= 64)
12502 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12503 else if (i < HOST_BITS_PER_WIDE_INT)
12504 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12506 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12508 op1 = immed_double_const (~lo, ~hi, DImode);
12511 emit_move_insn (operands[2], op1);
12515 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
12520 [(match_scratch:DI 2 "r")
12521 (parallel [(set (zero_extract:DI
12522 (match_operand:DI 0 "register_operand" "")
12524 (match_operand:DI 1 "const_0_to_63_operand" ""))
12525 (not:DI (zero_extract:DI
12526 (match_dup 0) (const_int 1) (match_dup 1))))
12527 (clobber (reg:CC FLAGS_REG))])]
12528 "TARGET_64BIT && !TARGET_USE_BT"
12531 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
12534 if (HOST_BITS_PER_WIDE_INT >= 64)
12535 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12536 else if (i < HOST_BITS_PER_WIDE_INT)
12537 lo = (HOST_WIDE_INT)1 << i, hi = 0;
12539 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
12541 op1 = immed_double_const (lo, hi, DImode);
12544 emit_move_insn (operands[2], op1);
12548 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
12552 (define_insn "*btdi_rex64"
12553 [(set (reg:CCC FLAGS_REG)
12556 (match_operand:DI 0 "register_operand" "r")
12558 (match_operand:DI 1 "nonmemory_operand" "rN"))
12560 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12561 "bt{q}\t{%1, %0|%0, %1}"
12562 [(set_attr "type" "alu1")
12563 (set_attr "prefix_0f" "1")
12564 (set_attr "mode" "DI")])
12566 (define_insn "*btsi"
12567 [(set (reg:CCC FLAGS_REG)
12570 (match_operand:SI 0 "register_operand" "r")
12572 (match_operand:SI 1 "nonmemory_operand" "rN"))
12574 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12575 "bt{l}\t{%1, %0|%0, %1}"
12576 [(set_attr "type" "alu1")
12577 (set_attr "prefix_0f" "1")
12578 (set_attr "mode" "SI")])
12580 ;; Store-flag instructions.
12582 ;; For all sCOND expanders, also expand the compare or test insn that
12583 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
12585 (define_insn_and_split "*setcc_di_1"
12586 [(set (match_operand:DI 0 "register_operand" "=q")
12587 (match_operator:DI 1 "ix86_comparison_operator"
12588 [(reg FLAGS_REG) (const_int 0)]))]
12589 "TARGET_64BIT && !TARGET_PARTIAL_REG_STALL"
12591 "&& reload_completed"
12592 [(set (match_dup 2) (match_dup 1))
12593 (set (match_dup 0) (zero_extend:DI (match_dup 2)))]
12595 PUT_MODE (operands[1], QImode);
12596 operands[2] = gen_lowpart (QImode, operands[0]);
12599 (define_insn_and_split "*setcc_si_1_and"
12600 [(set (match_operand:SI 0 "register_operand" "=q")
12601 (match_operator:SI 1 "ix86_comparison_operator"
12602 [(reg FLAGS_REG) (const_int 0)]))
12603 (clobber (reg:CC FLAGS_REG))]
12604 "!TARGET_PARTIAL_REG_STALL
12605 && TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
12607 "&& reload_completed"
12608 [(set (match_dup 2) (match_dup 1))
12609 (parallel [(set (match_dup 0) (zero_extend:SI (match_dup 2)))
12610 (clobber (reg:CC FLAGS_REG))])]
12612 PUT_MODE (operands[1], QImode);
12613 operands[2] = gen_lowpart (QImode, operands[0]);
12616 (define_insn_and_split "*setcc_si_1_movzbl"
12617 [(set (match_operand:SI 0 "register_operand" "=q")
12618 (match_operator:SI 1 "ix86_comparison_operator"
12619 [(reg FLAGS_REG) (const_int 0)]))]
12620 "!TARGET_PARTIAL_REG_STALL
12621 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))"
12623 "&& reload_completed"
12624 [(set (match_dup 2) (match_dup 1))
12625 (set (match_dup 0) (zero_extend:SI (match_dup 2)))]
12627 PUT_MODE (operands[1], QImode);
12628 operands[2] = gen_lowpart (QImode, operands[0]);
12631 (define_insn "*setcc_qi"
12632 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12633 (match_operator:QI 1 "ix86_comparison_operator"
12634 [(reg FLAGS_REG) (const_int 0)]))]
12637 [(set_attr "type" "setcc")
12638 (set_attr "mode" "QI")])
12640 (define_insn "*setcc_qi_slp"
12641 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
12642 (match_operator:QI 1 "ix86_comparison_operator"
12643 [(reg FLAGS_REG) (const_int 0)]))]
12646 [(set_attr "type" "setcc")
12647 (set_attr "mode" "QI")])
12649 ;; In general it is not safe to assume too much about CCmode registers,
12650 ;; so simplify-rtx stops when it sees a second one. Under certain
12651 ;; conditions this is safe on x86, so help combine not create
12658 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12659 (ne:QI (match_operator 1 "ix86_comparison_operator"
12660 [(reg FLAGS_REG) (const_int 0)])
12663 [(set (match_dup 0) (match_dup 1))]
12665 PUT_MODE (operands[1], QImode);
12669 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12670 (ne:QI (match_operator 1 "ix86_comparison_operator"
12671 [(reg FLAGS_REG) (const_int 0)])
12674 [(set (match_dup 0) (match_dup 1))]
12676 PUT_MODE (operands[1], QImode);
12680 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12681 (eq:QI (match_operator 1 "ix86_comparison_operator"
12682 [(reg FLAGS_REG) (const_int 0)])
12685 [(set (match_dup 0) (match_dup 1))]
12687 rtx new_op1 = copy_rtx (operands[1]);
12688 operands[1] = new_op1;
12689 PUT_MODE (new_op1, QImode);
12690 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12691 GET_MODE (XEXP (new_op1, 0))));
12693 /* Make sure that (a) the CCmode we have for the flags is strong
12694 enough for the reversed compare or (b) we have a valid FP compare. */
12695 if (! ix86_comparison_operator (new_op1, VOIDmode))
12700 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
12701 (eq:QI (match_operator 1 "ix86_comparison_operator"
12702 [(reg FLAGS_REG) (const_int 0)])
12705 [(set (match_dup 0) (match_dup 1))]
12707 rtx new_op1 = copy_rtx (operands[1]);
12708 operands[1] = new_op1;
12709 PUT_MODE (new_op1, QImode);
12710 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
12711 GET_MODE (XEXP (new_op1, 0))));
12713 /* Make sure that (a) the CCmode we have for the flags is strong
12714 enough for the reversed compare or (b) we have a valid FP compare. */
12715 if (! ix86_comparison_operator (new_op1, VOIDmode))
12719 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
12720 ;; subsequent logical operations are used to imitate conditional moves.
12721 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
12724 (define_insn "*avx_setcc<mode>"
12725 [(set (match_operand:MODEF 0 "register_operand" "=x")
12726 (match_operator:MODEF 1 "avx_comparison_float_operator"
12727 [(match_operand:MODEF 2 "register_operand" "x")
12728 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12730 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
12731 [(set_attr "type" "ssecmp")
12732 (set_attr "prefix" "vex")
12733 (set_attr "length_immediate" "1")
12734 (set_attr "mode" "<MODE>")])
12736 (define_insn "*sse_setcc<mode>"
12737 [(set (match_operand:MODEF 0 "register_operand" "=x")
12738 (match_operator:MODEF 1 "sse_comparison_operator"
12739 [(match_operand:MODEF 2 "register_operand" "0")
12740 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
12741 "SSE_FLOAT_MODE_P (<MODE>mode)"
12742 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
12743 [(set_attr "type" "ssecmp")
12744 (set_attr "length_immediate" "1")
12745 (set_attr "mode" "<MODE>")])
12747 ;; Basic conditional jump instructions.
12748 ;; We ignore the overflow flag for signed branch instructions.
12750 (define_insn "*jcc_1"
12752 (if_then_else (match_operator 1 "ix86_comparison_operator"
12753 [(reg FLAGS_REG) (const_int 0)])
12754 (label_ref (match_operand 0 "" ""))
12758 [(set_attr "type" "ibr")
12759 (set_attr "modrm" "0")
12760 (set (attr "length")
12761 (if_then_else (and (ge (minus (match_dup 0) (pc))
12763 (lt (minus (match_dup 0) (pc))
12768 (define_insn "*jcc_2"
12770 (if_then_else (match_operator 1 "ix86_comparison_operator"
12771 [(reg FLAGS_REG) (const_int 0)])
12773 (label_ref (match_operand 0 "" ""))))]
12776 [(set_attr "type" "ibr")
12777 (set_attr "modrm" "0")
12778 (set (attr "length")
12779 (if_then_else (and (ge (minus (match_dup 0) (pc))
12781 (lt (minus (match_dup 0) (pc))
12786 ;; In general it is not safe to assume too much about CCmode registers,
12787 ;; so simplify-rtx stops when it sees a second one. Under certain
12788 ;; conditions this is safe on x86, so help combine not create
12796 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
12797 [(reg FLAGS_REG) (const_int 0)])
12799 (label_ref (match_operand 1 "" ""))
12803 (if_then_else (match_dup 0)
12804 (label_ref (match_dup 1))
12807 PUT_MODE (operands[0], VOIDmode);
12812 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
12813 [(reg FLAGS_REG) (const_int 0)])
12815 (label_ref (match_operand 1 "" ""))
12819 (if_then_else (match_dup 0)
12820 (label_ref (match_dup 1))
12823 rtx new_op0 = copy_rtx (operands[0]);
12824 operands[0] = new_op0;
12825 PUT_MODE (new_op0, VOIDmode);
12826 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
12827 GET_MODE (XEXP (new_op0, 0))));
12829 /* Make sure that (a) the CCmode we have for the flags is strong
12830 enough for the reversed compare or (b) we have a valid FP compare. */
12831 if (! ix86_comparison_operator (new_op0, VOIDmode))
12835 ;; zero_extend in SImode is correct, since this is what combine pass
12836 ;; generates from shift insn with QImode operand. Actually, the mode of
12837 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
12838 ;; appropriate modulo of the bit offset value.
12840 (define_insn_and_split "*jcc_btdi_rex64"
12842 (if_then_else (match_operator 0 "bt_comparison_operator"
12844 (match_operand:DI 1 "register_operand" "r")
12847 (match_operand:QI 2 "register_operand" "r")))
12849 (label_ref (match_operand 3 "" ""))
12851 (clobber (reg:CC FLAGS_REG))]
12852 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
12855 [(set (reg:CCC FLAGS_REG)
12863 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12864 (label_ref (match_dup 3))
12867 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
12869 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12872 ;; avoid useless masking of bit offset operand
12873 (define_insn_and_split "*jcc_btdi_mask_rex64"
12875 (if_then_else (match_operator 0 "bt_comparison_operator"
12877 (match_operand:DI 1 "register_operand" "r")
12880 (match_operand:SI 2 "register_operand" "r")
12881 (match_operand:SI 3 "const_int_operand" "n")))])
12882 (label_ref (match_operand 4 "" ""))
12884 (clobber (reg:CC FLAGS_REG))]
12885 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
12886 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
12889 [(set (reg:CCC FLAGS_REG)
12897 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12898 (label_ref (match_dup 4))
12901 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
12903 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12906 (define_insn_and_split "*jcc_btsi"
12908 (if_then_else (match_operator 0 "bt_comparison_operator"
12910 (match_operand:SI 1 "register_operand" "r")
12913 (match_operand:QI 2 "register_operand" "r")))
12915 (label_ref (match_operand 3 "" ""))
12917 (clobber (reg:CC FLAGS_REG))]
12918 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12921 [(set (reg:CCC FLAGS_REG)
12929 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12930 (label_ref (match_dup 3))
12933 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
12935 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
12938 ;; avoid useless masking of bit offset operand
12939 (define_insn_and_split "*jcc_btsi_mask"
12941 (if_then_else (match_operator 0 "bt_comparison_operator"
12943 (match_operand:SI 1 "register_operand" "r")
12946 (match_operand:SI 2 "register_operand" "r")
12947 (match_operand:SI 3 "const_int_operand" "n")))])
12948 (label_ref (match_operand 4 "" ""))
12950 (clobber (reg:CC FLAGS_REG))]
12951 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
12952 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
12955 [(set (reg:CCC FLAGS_REG)
12963 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12964 (label_ref (match_dup 4))
12966 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
12968 (define_insn_and_split "*jcc_btsi_1"
12970 (if_then_else (match_operator 0 "bt_comparison_operator"
12973 (match_operand:SI 1 "register_operand" "r")
12974 (match_operand:QI 2 "register_operand" "r"))
12977 (label_ref (match_operand 3 "" ""))
12979 (clobber (reg:CC FLAGS_REG))]
12980 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
12983 [(set (reg:CCC FLAGS_REG)
12991 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
12992 (label_ref (match_dup 3))
12995 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
12997 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
13000 ;; avoid useless masking of bit offset operand
13001 (define_insn_and_split "*jcc_btsi_mask_1"
13004 (match_operator 0 "bt_comparison_operator"
13007 (match_operand:SI 1 "register_operand" "r")
13010 (match_operand:SI 2 "register_operand" "r")
13011 (match_operand:SI 3 "const_int_operand" "n")) 0))
13014 (label_ref (match_operand 4 "" ""))
13016 (clobber (reg:CC FLAGS_REG))]
13017 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
13018 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
13021 [(set (reg:CCC FLAGS_REG)
13029 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
13030 (label_ref (match_dup 4))
13032 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
13034 ;; Define combination compare-and-branch fp compare instructions to help
13037 (define_insn "*fp_jcc_3_387"
13039 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13040 [(match_operand 1 "register_operand" "f")
13041 (match_operand 2 "nonimmediate_operand" "fm")])
13042 (label_ref (match_operand 3 "" ""))
13044 (clobber (reg:CCFP FPSR_REG))
13045 (clobber (reg:CCFP FLAGS_REG))
13046 (clobber (match_scratch:HI 4 "=a"))]
13048 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13049 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13050 && SELECT_CC_MODE (GET_CODE (operands[0]),
13051 operands[1], operands[2]) == CCFPmode
13055 (define_insn "*fp_jcc_4_387"
13057 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13058 [(match_operand 1 "register_operand" "f")
13059 (match_operand 2 "nonimmediate_operand" "fm")])
13061 (label_ref (match_operand 3 "" ""))))
13062 (clobber (reg:CCFP FPSR_REG))
13063 (clobber (reg:CCFP FLAGS_REG))
13064 (clobber (match_scratch:HI 4 "=a"))]
13066 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
13067 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13068 && SELECT_CC_MODE (GET_CODE (operands[0]),
13069 operands[1], operands[2]) == CCFPmode
13073 (define_insn "*fp_jcc_5_387"
13075 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13076 [(match_operand 1 "register_operand" "f")
13077 (match_operand 2 "register_operand" "f")])
13078 (label_ref (match_operand 3 "" ""))
13080 (clobber (reg:CCFP FPSR_REG))
13081 (clobber (reg:CCFP FLAGS_REG))
13082 (clobber (match_scratch:HI 4 "=a"))]
13083 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13084 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13088 (define_insn "*fp_jcc_6_387"
13090 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13091 [(match_operand 1 "register_operand" "f")
13092 (match_operand 2 "register_operand" "f")])
13094 (label_ref (match_operand 3 "" ""))))
13095 (clobber (reg:CCFP FPSR_REG))
13096 (clobber (reg:CCFP FLAGS_REG))
13097 (clobber (match_scratch:HI 4 "=a"))]
13098 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13099 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13103 (define_insn "*fp_jcc_7_387"
13105 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13106 [(match_operand 1 "register_operand" "f")
13107 (match_operand 2 "const0_operand" "")])
13108 (label_ref (match_operand 3 "" ""))
13110 (clobber (reg:CCFP FPSR_REG))
13111 (clobber (reg:CCFP FLAGS_REG))
13112 (clobber (match_scratch:HI 4 "=a"))]
13113 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
13114 && GET_MODE (operands[1]) == GET_MODE (operands[2])
13115 && SELECT_CC_MODE (GET_CODE (operands[0]),
13116 operands[1], operands[2]) == CCFPmode
13120 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
13121 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
13122 ;; with a precedence over other operators and is always put in the first
13123 ;; place. Swap condition and operands to match ficom instruction.
13125 (define_insn "*fp_jcc_8<mode>_387"
13127 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13128 [(match_operator 1 "float_operator"
13129 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
13130 (match_operand 3 "register_operand" "f,f")])
13131 (label_ref (match_operand 4 "" ""))
13133 (clobber (reg:CCFP FPSR_REG))
13134 (clobber (reg:CCFP FLAGS_REG))
13135 (clobber (match_scratch:HI 5 "=a,a"))]
13136 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
13137 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
13138 && GET_MODE (operands[1]) == GET_MODE (operands[3])
13139 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
13145 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13146 [(match_operand 1 "register_operand" "")
13147 (match_operand 2 "nonimmediate_operand" "")])
13148 (match_operand 3 "" "")
13149 (match_operand 4 "" "")))
13150 (clobber (reg:CCFP FPSR_REG))
13151 (clobber (reg:CCFP FLAGS_REG))]
13155 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13156 operands[3], operands[4], NULL_RTX, NULL_RTX);
13162 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13163 [(match_operand 1 "register_operand" "")
13164 (match_operand 2 "general_operand" "")])
13165 (match_operand 3 "" "")
13166 (match_operand 4 "" "")))
13167 (clobber (reg:CCFP FPSR_REG))
13168 (clobber (reg:CCFP FLAGS_REG))
13169 (clobber (match_scratch:HI 5 "=a"))]
13173 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
13174 operands[3], operands[4], operands[5], NULL_RTX);
13180 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13181 [(match_operator 1 "float_operator"
13182 [(match_operand:X87MODEI12 2 "memory_operand" "")])
13183 (match_operand 3 "register_operand" "")])
13184 (match_operand 4 "" "")
13185 (match_operand 5 "" "")))
13186 (clobber (reg:CCFP FPSR_REG))
13187 (clobber (reg:CCFP FLAGS_REG))
13188 (clobber (match_scratch:HI 6 "=a"))]
13192 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
13193 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13194 operands[3], operands[7],
13195 operands[4], operands[5], operands[6], NULL_RTX);
13199 ;; %%% Kill this when reload knows how to do it.
13202 (if_then_else (match_operator 0 "ix86_fp_comparison_operator"
13203 [(match_operator 1 "float_operator"
13204 [(match_operand:X87MODEI12 2 "register_operand" "")])
13205 (match_operand 3 "register_operand" "")])
13206 (match_operand 4 "" "")
13207 (match_operand 5 "" "")))
13208 (clobber (reg:CCFP FPSR_REG))
13209 (clobber (reg:CCFP FLAGS_REG))
13210 (clobber (match_scratch:HI 6 "=a"))]
13214 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
13215 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
13216 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
13217 operands[3], operands[7],
13218 operands[4], operands[5], operands[6], operands[2]);
13222 ;; Unconditional and other jump instructions
13224 (define_insn "jump"
13226 (label_ref (match_operand 0 "" "")))]
13229 [(set_attr "type" "ibr")
13230 (set (attr "length")
13231 (if_then_else (and (ge (minus (match_dup 0) (pc))
13233 (lt (minus (match_dup 0) (pc))
13237 (set_attr "modrm" "0")])
13239 (define_expand "indirect_jump"
13240 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
13244 (define_insn "*indirect_jump"
13245 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
13248 [(set_attr "type" "ibr")
13249 (set_attr "length_immediate" "0")])
13251 (define_expand "tablejump"
13252 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
13253 (use (label_ref (match_operand 1 "" "")))])]
13256 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
13257 relative. Convert the relative address to an absolute address. */
13261 enum rtx_code code;
13263 /* We can't use @GOTOFF for text labels on VxWorks;
13264 see gotoff_operand. */
13265 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
13269 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
13271 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
13275 op1 = pic_offset_table_rtx;
13280 op0 = pic_offset_table_rtx;
13284 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
13289 (define_insn "*tablejump_1"
13290 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
13291 (use (label_ref (match_operand 1 "" "")))]
13294 [(set_attr "type" "ibr")
13295 (set_attr "length_immediate" "0")])
13297 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
13300 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13301 (set (match_operand:QI 1 "register_operand" "")
13302 (match_operator:QI 2 "ix86_comparison_operator"
13303 [(reg FLAGS_REG) (const_int 0)]))
13304 (set (match_operand 3 "q_regs_operand" "")
13305 (zero_extend (match_dup 1)))]
13306 "(peep2_reg_dead_p (3, operands[1])
13307 || operands_match_p (operands[1], operands[3]))
13308 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13309 [(set (match_dup 4) (match_dup 0))
13310 (set (strict_low_part (match_dup 5))
13313 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13314 operands[5] = gen_lowpart (QImode, operands[3]);
13315 ix86_expand_clear (operands[3]);
13318 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
13321 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
13322 (set (match_operand:QI 1 "register_operand" "")
13323 (match_operator:QI 2 "ix86_comparison_operator"
13324 [(reg FLAGS_REG) (const_int 0)]))
13325 (parallel [(set (match_operand 3 "q_regs_operand" "")
13326 (zero_extend (match_dup 1)))
13327 (clobber (reg:CC FLAGS_REG))])]
13328 "(peep2_reg_dead_p (3, operands[1])
13329 || operands_match_p (operands[1], operands[3]))
13330 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
13331 [(set (match_dup 4) (match_dup 0))
13332 (set (strict_low_part (match_dup 5))
13335 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
13336 operands[5] = gen_lowpart (QImode, operands[3]);
13337 ix86_expand_clear (operands[3]);
13340 ;; Call instructions.
13342 ;; The predicates normally associated with named expanders are not properly
13343 ;; checked for calls. This is a bug in the generic code, but it isn't that
13344 ;; easy to fix. Ignore it for now and be prepared to fix things up.
13346 ;; P6 processors will jump to the address after the decrement when %esp
13347 ;; is used as a call operand, so they will execute return address as a code.
13348 ;; See Pentium Pro errata 70, Pentium 2 errata A33 and Pentium 3 errata E17.
13350 ;; Call subroutine returning no value.
13352 (define_expand "call_pop"
13353 [(parallel [(call (match_operand:QI 0 "" "")
13354 (match_operand:SI 1 "" ""))
13355 (set (reg:SI SP_REG)
13356 (plus:SI (reg:SI SP_REG)
13357 (match_operand:SI 3 "" "")))])]
13360 ix86_expand_call (NULL, operands[0], operands[1],
13361 operands[2], operands[3], 0);
13365 (define_insn "*call_pop_0"
13366 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
13367 (match_operand:SI 1 "" ""))
13368 (set (reg:SI SP_REG)
13369 (plus:SI (reg:SI SP_REG)
13370 (match_operand:SI 2 "immediate_operand" "")))]
13373 if (SIBLING_CALL_P (insn))
13376 return "call\t%P0";
13378 [(set_attr "type" "call")])
13380 (define_insn "*call_pop_1"
13381 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13382 (match_operand:SI 1 "" ""))
13383 (set (reg:SI SP_REG)
13384 (plus:SI (reg:SI SP_REG)
13385 (match_operand:SI 2 "immediate_operand" "i")))]
13386 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13388 if (constant_call_address_operand (operands[0], Pmode))
13389 return "call\t%P0";
13390 return "call\t%A0";
13392 [(set_attr "type" "call")])
13394 (define_insn "*sibcall_pop_1"
13395 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13396 (match_operand:SI 1 "" ""))
13397 (set (reg:SI SP_REG)
13398 (plus:SI (reg:SI SP_REG)
13399 (match_operand:SI 2 "immediate_operand" "i,i")))]
13400 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13404 [(set_attr "type" "call")])
13406 (define_expand "call"
13407 [(call (match_operand:QI 0 "" "")
13408 (match_operand 1 "" ""))
13409 (use (match_operand 2 "" ""))]
13412 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
13416 (define_expand "sibcall"
13417 [(call (match_operand:QI 0 "" "")
13418 (match_operand 1 "" ""))
13419 (use (match_operand 2 "" ""))]
13422 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
13426 (define_insn "*call_0"
13427 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
13428 (match_operand 1 "" ""))]
13431 if (SIBLING_CALL_P (insn))
13434 return "call\t%P0";
13436 [(set_attr "type" "call")])
13438 (define_insn "*call_1"
13439 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "lsm"))
13440 (match_operand 1 "" ""))]
13441 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
13443 if (constant_call_address_operand (operands[0], Pmode))
13444 return "call\t%P0";
13445 return "call\t%A0";
13447 [(set_attr "type" "call")])
13449 (define_insn "*sibcall_1"
13450 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,U"))
13451 (match_operand 1 "" ""))]
13452 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
13456 [(set_attr "type" "call")])
13458 (define_insn "*call_1_rex64"
13459 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13460 (match_operand 1 "" ""))]
13461 "TARGET_64BIT && !SIBLING_CALL_P (insn)
13462 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
13464 if (constant_call_address_operand (operands[0], Pmode))
13465 return "call\t%P0";
13466 return "call\t%A0";
13468 [(set_attr "type" "call")])
13470 (define_insn "*call_1_rex64_ms_sysv"
13471 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
13472 (match_operand 1 "" ""))
13473 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
13474 (clobber (reg:TI XMM6_REG))
13475 (clobber (reg:TI XMM7_REG))
13476 (clobber (reg:TI XMM8_REG))
13477 (clobber (reg:TI XMM9_REG))
13478 (clobber (reg:TI XMM10_REG))
13479 (clobber (reg:TI XMM11_REG))
13480 (clobber (reg:TI XMM12_REG))
13481 (clobber (reg:TI XMM13_REG))
13482 (clobber (reg:TI XMM14_REG))
13483 (clobber (reg:TI XMM15_REG))
13484 (clobber (reg:DI SI_REG))
13485 (clobber (reg:DI DI_REG))]
13486 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13488 if (constant_call_address_operand (operands[0], Pmode))
13489 return "call\t%P0";
13490 return "call\t%A0";
13492 [(set_attr "type" "call")])
13494 (define_insn "*call_1_rex64_large"
13495 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
13496 (match_operand 1 "" ""))]
13497 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
13499 [(set_attr "type" "call")])
13501 (define_insn "*sibcall_1_rex64"
13502 [(call (mem:QI (match_operand:DI 0 "sibcall_insn_operand" "s,U"))
13503 (match_operand 1 "" ""))]
13504 "TARGET_64BIT && SIBLING_CALL_P (insn)"
13508 [(set_attr "type" "call")])
13510 ;; Call subroutine, returning value in operand 0
13511 (define_expand "call_value_pop"
13512 [(parallel [(set (match_operand 0 "" "")
13513 (call (match_operand:QI 1 "" "")
13514 (match_operand:SI 2 "" "")))
13515 (set (reg:SI SP_REG)
13516 (plus:SI (reg:SI SP_REG)
13517 (match_operand:SI 4 "" "")))])]
13520 ix86_expand_call (operands[0], operands[1], operands[2],
13521 operands[3], operands[4], 0);
13525 (define_expand "call_value"
13526 [(set (match_operand 0 "" "")
13527 (call (match_operand:QI 1 "" "")
13528 (match_operand:SI 2 "" "")))
13529 (use (match_operand:SI 3 "" ""))]
13530 ;; Operand 3 is not used on the i386.
13533 ix86_expand_call (operands[0], operands[1], operands[2],
13534 operands[3], NULL, 0);
13538 (define_expand "sibcall_value"
13539 [(set (match_operand 0 "" "")
13540 (call (match_operand:QI 1 "" "")
13541 (match_operand:SI 2 "" "")))
13542 (use (match_operand:SI 3 "" ""))]
13543 ;; Operand 3 is not used on the i386.
13546 ix86_expand_call (operands[0], operands[1], operands[2],
13547 operands[3], NULL, 1);
13551 ;; Call subroutine returning any type.
13553 (define_expand "untyped_call"
13554 [(parallel [(call (match_operand 0 "" "")
13556 (match_operand 1 "" "")
13557 (match_operand 2 "" "")])]
13562 /* In order to give reg-stack an easier job in validating two
13563 coprocessor registers as containing a possible return value,
13564 simply pretend the untyped call returns a complex long double
13567 We can't use SSE_REGPARM_MAX here since callee is unprototyped
13568 and should have the default ABI. */
13570 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
13571 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
13572 operands[0], const0_rtx,
13573 GEN_INT ((TARGET_64BIT
13574 ? (ix86_abi == SYSV_ABI
13575 ? X86_64_SSE_REGPARM_MAX
13576 : X86_64_MS_SSE_REGPARM_MAX)
13577 : X86_32_SSE_REGPARM_MAX)
13581 for (i = 0; i < XVECLEN (operands[2], 0); i++)
13583 rtx set = XVECEXP (operands[2], 0, i);
13584 emit_move_insn (SET_DEST (set), SET_SRC (set));
13587 /* The optimizer does not know that the call sets the function value
13588 registers we stored in the result block. We avoid problems by
13589 claiming that all hard registers are used and clobbered at this
13591 emit_insn (gen_blockage ());
13596 ;; Prologue and epilogue instructions
13598 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
13599 ;; all of memory. This blocks insns from being moved across this point.
13601 (define_insn "blockage"
13602 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
13605 [(set_attr "length" "0")])
13607 ;; Do not schedule instructions accessing memory across this point.
13609 (define_expand "memory_blockage"
13610 [(set (match_dup 0)
13611 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13614 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
13615 MEM_VOLATILE_P (operands[0]) = 1;
13618 (define_insn "*memory_blockage"
13619 [(set (match_operand:BLK 0 "" "")
13620 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
13623 [(set_attr "length" "0")])
13625 ;; As USE insns aren't meaningful after reload, this is used instead
13626 ;; to prevent deleting instructions setting registers for PIC code
13627 (define_insn "prologue_use"
13628 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
13631 [(set_attr "length" "0")])
13633 ;; Insn emitted into the body of a function to return from a function.
13634 ;; This is only done if the function's epilogue is known to be simple.
13635 ;; See comments for ix86_can_use_return_insn_p in i386.c.
13637 (define_expand "return"
13639 "ix86_can_use_return_insn_p ()"
13641 if (crtl->args.pops_args)
13643 rtx popc = GEN_INT (crtl->args.pops_args);
13644 emit_jump_insn (gen_return_pop_internal (popc));
13649 (define_insn "return_internal"
13653 [(set_attr "length" "1")
13654 (set_attr "atom_unit" "jeu")
13655 (set_attr "length_immediate" "0")
13656 (set_attr "modrm" "0")])
13658 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
13659 ;; instruction Athlon and K8 have.
13661 (define_insn "return_internal_long"
13663 (unspec [(const_int 0)] UNSPEC_REP)]
13666 [(set_attr "length" "2")
13667 (set_attr "atom_unit" "jeu")
13668 (set_attr "length_immediate" "0")
13669 (set_attr "prefix_rep" "1")
13670 (set_attr "modrm" "0")])
13672 (define_insn "return_pop_internal"
13674 (use (match_operand:SI 0 "const_int_operand" ""))]
13677 [(set_attr "length" "3")
13678 (set_attr "atom_unit" "jeu")
13679 (set_attr "length_immediate" "2")
13680 (set_attr "modrm" "0")])
13682 (define_insn "return_indirect_internal"
13684 (use (match_operand:SI 0 "register_operand" "r"))]
13687 [(set_attr "type" "ibr")
13688 (set_attr "length_immediate" "0")])
13694 [(set_attr "length" "1")
13695 (set_attr "length_immediate" "0")
13696 (set_attr "modrm" "0")])
13698 (define_insn "vswapmov"
13699 [(set (match_operand:SI 0 "register_operand" "=r")
13700 (match_operand:SI 1 "register_operand" "r"))
13701 (unspec_volatile [(const_int 0)] UNSPECV_VSWAPMOV)]
13703 "movl.s\t{%1, %0|%0, %1}"
13704 [(set_attr "length" "2")
13705 (set_attr "length_immediate" "0")
13706 (set_attr "modrm" "0")])
13708 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
13709 ;; branch prediction penalty for the third jump in a 16-byte
13713 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
13716 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
13717 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
13719 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
13720 The align insn is used to avoid 3 jump instructions in the row to improve
13721 branch prediction and the benefits hardly outweigh the cost of extra 8
13722 nops on the average inserted by full alignment pseudo operation. */
13726 [(set_attr "length" "16")])
13728 (define_expand "prologue"
13731 "ix86_expand_prologue (); DONE;")
13733 (define_insn "set_got"
13734 [(set (match_operand:SI 0 "register_operand" "=r")
13735 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
13736 (clobber (reg:CC FLAGS_REG))]
13738 { return output_set_got (operands[0], NULL_RTX); }
13739 [(set_attr "type" "multi")
13740 (set_attr "length" "12")])
13742 (define_insn "set_got_labelled"
13743 [(set (match_operand:SI 0 "register_operand" "=r")
13744 (unspec:SI [(label_ref (match_operand 1 "" ""))]
13746 (clobber (reg:CC FLAGS_REG))]
13748 { return output_set_got (operands[0], operands[1]); }
13749 [(set_attr "type" "multi")
13750 (set_attr "length" "12")])
13752 (define_insn "set_got_rex64"
13753 [(set (match_operand:DI 0 "register_operand" "=r")
13754 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
13756 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
13757 [(set_attr "type" "lea")
13758 (set_attr "length_address" "4")
13759 (set_attr "mode" "DI")])
13761 (define_insn "set_rip_rex64"
13762 [(set (match_operand:DI 0 "register_operand" "=r")
13763 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
13765 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
13766 [(set_attr "type" "lea")
13767 (set_attr "length_address" "4")
13768 (set_attr "mode" "DI")])
13770 (define_insn "set_got_offset_rex64"
13771 [(set (match_operand:DI 0 "register_operand" "=r")
13773 [(label_ref (match_operand 1 "" ""))]
13774 UNSPEC_SET_GOT_OFFSET))]
13776 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
13777 [(set_attr "type" "imov")
13778 (set_attr "length_immediate" "0")
13779 (set_attr "length_address" "8")
13780 (set_attr "mode" "DI")])
13782 (define_expand "epilogue"
13785 "ix86_expand_epilogue (1); DONE;")
13787 (define_expand "sibcall_epilogue"
13790 "ix86_expand_epilogue (0); DONE;")
13792 (define_expand "eh_return"
13793 [(use (match_operand 0 "register_operand" ""))]
13796 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
13798 /* Tricky bit: we write the address of the handler to which we will
13799 be returning into someone else's stack frame, one word below the
13800 stack address we wish to restore. */
13801 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
13802 tmp = plus_constant (tmp, -UNITS_PER_WORD);
13803 tmp = gen_rtx_MEM (Pmode, tmp);
13804 emit_move_insn (tmp, ra);
13806 emit_jump_insn (gen_eh_return_internal ());
13811 (define_insn_and_split "eh_return_internal"
13815 "epilogue_completed"
13817 "ix86_expand_epilogue (2); DONE;")
13819 (define_insn "leave"
13820 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
13821 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
13822 (clobber (mem:BLK (scratch)))]
13825 [(set_attr "type" "leave")])
13827 (define_insn "leave_rex64"
13828 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
13829 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
13830 (clobber (mem:BLK (scratch)))]
13833 [(set_attr "type" "leave")])
13835 (define_expand "ffssi2"
13837 [(set (match_operand:SI 0 "register_operand" "")
13838 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
13839 (clobber (match_scratch:SI 2 ""))
13840 (clobber (reg:CC FLAGS_REG))])]
13845 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
13850 (define_expand "ffs_cmove"
13851 [(set (match_dup 2) (const_int -1))
13852 (parallel [(set (reg:CCZ FLAGS_REG)
13853 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
13855 (set (match_operand:SI 0 "register_operand" "")
13856 (ctz:SI (match_dup 1)))])
13857 (set (match_dup 0) (if_then_else:SI
13858 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13861 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13862 (clobber (reg:CC FLAGS_REG))])]
13864 "operands[2] = gen_reg_rtx (SImode);")
13866 (define_insn_and_split "*ffs_no_cmove"
13867 [(set (match_operand:SI 0 "register_operand" "=r")
13868 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13869 (clobber (match_scratch:SI 2 "=&q"))
13870 (clobber (reg:CC FLAGS_REG))]
13873 "&& reload_completed"
13874 [(parallel [(set (reg:CCZ FLAGS_REG)
13875 (compare:CCZ (match_dup 1) (const_int 0)))
13876 (set (match_dup 0) (ctz:SI (match_dup 1)))])
13877 (set (strict_low_part (match_dup 3))
13878 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
13879 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
13880 (clobber (reg:CC FLAGS_REG))])
13881 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
13882 (clobber (reg:CC FLAGS_REG))])
13883 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
13884 (clobber (reg:CC FLAGS_REG))])]
13886 operands[3] = gen_lowpart (QImode, operands[2]);
13887 ix86_expand_clear (operands[2]);
13890 (define_insn "*ffssi_1"
13891 [(set (reg:CCZ FLAGS_REG)
13892 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
13894 (set (match_operand:SI 0 "register_operand" "=r")
13895 (ctz:SI (match_dup 1)))]
13897 "bsf{l}\t{%1, %0|%0, %1}"
13898 [(set_attr "type" "alu1")
13899 (set_attr "prefix_0f" "1")
13900 (set_attr "mode" "SI")])
13902 (define_expand "ffsdi2"
13903 [(set (match_dup 2) (const_int -1))
13904 (parallel [(set (reg:CCZ FLAGS_REG)
13905 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
13907 (set (match_operand:DI 0 "register_operand" "")
13908 (ctz:DI (match_dup 1)))])
13909 (set (match_dup 0) (if_then_else:DI
13910 (eq (reg:CCZ FLAGS_REG) (const_int 0))
13913 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
13914 (clobber (reg:CC FLAGS_REG))])]
13916 "operands[2] = gen_reg_rtx (DImode);")
13918 (define_insn "*ffsdi_1"
13919 [(set (reg:CCZ FLAGS_REG)
13920 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
13922 (set (match_operand:DI 0 "register_operand" "=r")
13923 (ctz:DI (match_dup 1)))]
13925 "bsf{q}\t{%1, %0|%0, %1}"
13926 [(set_attr "type" "alu1")
13927 (set_attr "prefix_0f" "1")
13928 (set_attr "mode" "DI")])
13930 (define_insn "ctzsi2"
13931 [(set (match_operand:SI 0 "register_operand" "=r")
13932 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13933 (clobber (reg:CC FLAGS_REG))]
13935 "bsf{l}\t{%1, %0|%0, %1}"
13936 [(set_attr "type" "alu1")
13937 (set_attr "prefix_0f" "1")
13938 (set_attr "mode" "SI")])
13940 (define_insn "ctzdi2"
13941 [(set (match_operand:DI 0 "register_operand" "=r")
13942 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
13943 (clobber (reg:CC FLAGS_REG))]
13945 "bsf{q}\t{%1, %0|%0, %1}"
13946 [(set_attr "type" "alu1")
13947 (set_attr "prefix_0f" "1")
13948 (set_attr "mode" "DI")])
13950 (define_expand "clzsi2"
13952 [(set (match_operand:SI 0 "register_operand" "")
13953 (minus:SI (const_int 31)
13954 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
13955 (clobber (reg:CC FLAGS_REG))])
13957 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
13958 (clobber (reg:CC FLAGS_REG))])]
13963 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
13968 (define_insn "clzsi2_abm"
13969 [(set (match_operand:SI 0 "register_operand" "=r")
13970 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
13971 (clobber (reg:CC FLAGS_REG))]
13973 "lzcnt{l}\t{%1, %0|%0, %1}"
13974 [(set_attr "prefix_rep" "1")
13975 (set_attr "type" "bitmanip")
13976 (set_attr "mode" "SI")])
13979 [(set (match_operand:SI 0 "register_operand" "=r")
13980 (minus:SI (const_int 31)
13981 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
13982 (clobber (reg:CC FLAGS_REG))]
13984 "bsr{l}\t{%1, %0|%0, %1}"
13985 [(set_attr "type" "alu1")
13986 (set_attr "prefix_0f" "1")
13987 (set_attr "mode" "SI")])
13989 (define_insn "popcount<mode>2"
13990 [(set (match_operand:SWI248 0 "register_operand" "=r")
13992 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
13993 (clobber (reg:CC FLAGS_REG))]
13997 return "popcnt\t{%1, %0|%0, %1}";
13999 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14002 [(set_attr "prefix_rep" "1")
14003 (set_attr "type" "bitmanip")
14004 (set_attr "mode" "<MODE>")])
14006 (define_insn "*popcount<mode>2_cmp"
14007 [(set (reg FLAGS_REG)
14010 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
14012 (set (match_operand:SWI248 0 "register_operand" "=r")
14013 (popcount:SWI248 (match_dup 1)))]
14014 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14017 return "popcnt\t{%1, %0|%0, %1}";
14019 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14022 [(set_attr "prefix_rep" "1")
14023 (set_attr "type" "bitmanip")
14024 (set_attr "mode" "<MODE>")])
14026 (define_insn "*popcountsi2_cmp_zext"
14027 [(set (reg FLAGS_REG)
14029 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
14031 (set (match_operand:DI 0 "register_operand" "=r")
14032 (zero_extend:DI(popcount:SI (match_dup 1))))]
14033 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
14036 return "popcnt\t{%1, %0|%0, %1}";
14038 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
14041 [(set_attr "prefix_rep" "1")
14042 (set_attr "type" "bitmanip")
14043 (set_attr "mode" "SI")])
14045 (define_expand "bswapsi2"
14046 [(set (match_operand:SI 0 "register_operand" "")
14047 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
14050 if (!(TARGET_BSWAP || TARGET_MOVBE))
14052 rtx x = operands[0];
14054 emit_move_insn (x, operands[1]);
14055 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14056 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
14057 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
14062 (define_insn "*bswapsi_movbe"
14063 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
14064 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
14065 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14068 movbe\t{%1, %0|%0, %1}
14069 movbe\t{%1, %0|%0, %1}"
14070 [(set_attr "type" "*,imov,imov")
14071 (set_attr "modrm" "*,1,1")
14072 (set_attr "prefix_0f" "1")
14073 (set_attr "prefix_extra" "*,1,1")
14074 (set_attr "length" "2,*,*")
14075 (set_attr "mode" "SI")])
14077 (define_insn "*bswapsi_1"
14078 [(set (match_operand:SI 0 "register_operand" "=r")
14079 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
14082 [(set_attr "prefix_0f" "1")
14083 (set_attr "length" "2")])
14085 (define_insn "*bswaphi_lowpart_1"
14086 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
14087 (bswap:HI (match_dup 0)))
14088 (clobber (reg:CC FLAGS_REG))]
14089 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
14091 xchg{b}\t{%h0, %b0|%b0, %h0}
14092 rol{w}\t{$8, %0|%0, 8}"
14093 [(set_attr "length" "2,4")
14094 (set_attr "mode" "QI,HI")])
14096 (define_insn "bswaphi_lowpart"
14097 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
14098 (bswap:HI (match_dup 0)))
14099 (clobber (reg:CC FLAGS_REG))]
14101 "rol{w}\t{$8, %0|%0, 8}"
14102 [(set_attr "length" "4")
14103 (set_attr "mode" "HI")])
14105 (define_expand "bswapdi2"
14106 [(set (match_operand:DI 0 "register_operand" "")
14107 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
14111 (define_insn "*bswapdi_movbe"
14112 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
14113 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
14114 "TARGET_64BIT && TARGET_MOVBE
14115 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14118 movbe\t{%1, %0|%0, %1}
14119 movbe\t{%1, %0|%0, %1}"
14120 [(set_attr "type" "*,imov,imov")
14121 (set_attr "modrm" "*,1,1")
14122 (set_attr "prefix_0f" "1")
14123 (set_attr "prefix_extra" "*,1,1")
14124 (set_attr "length" "3,*,*")
14125 (set_attr "mode" "DI")])
14127 (define_insn "*bswapdi_1"
14128 [(set (match_operand:DI 0 "register_operand" "=r")
14129 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
14132 [(set_attr "prefix_0f" "1")
14133 (set_attr "length" "3")])
14135 (define_expand "clzdi2"
14137 [(set (match_operand:DI 0 "register_operand" "")
14138 (minus:DI (const_int 63)
14139 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
14140 (clobber (reg:CC FLAGS_REG))])
14142 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
14143 (clobber (reg:CC FLAGS_REG))])]
14148 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
14153 (define_insn "clzdi2_abm"
14154 [(set (match_operand:DI 0 "register_operand" "=r")
14155 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
14156 (clobber (reg:CC FLAGS_REG))]
14157 "TARGET_64BIT && TARGET_ABM"
14158 "lzcnt{q}\t{%1, %0|%0, %1}"
14159 [(set_attr "prefix_rep" "1")
14160 (set_attr "type" "bitmanip")
14161 (set_attr "mode" "DI")])
14163 (define_insn "bsr_rex64"
14164 [(set (match_operand:DI 0 "register_operand" "=r")
14165 (minus:DI (const_int 63)
14166 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
14167 (clobber (reg:CC FLAGS_REG))]
14169 "bsr{q}\t{%1, %0|%0, %1}"
14170 [(set_attr "type" "alu1")
14171 (set_attr "prefix_0f" "1")
14172 (set_attr "mode" "DI")])
14174 (define_expand "clzhi2"
14176 [(set (match_operand:HI 0 "register_operand" "")
14177 (minus:HI (const_int 15)
14178 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
14179 (clobber (reg:CC FLAGS_REG))])
14181 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
14182 (clobber (reg:CC FLAGS_REG))])]
14187 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
14192 (define_insn "clzhi2_abm"
14193 [(set (match_operand:HI 0 "register_operand" "=r")
14194 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
14195 (clobber (reg:CC FLAGS_REG))]
14197 "lzcnt{w}\t{%1, %0|%0, %1}"
14198 [(set_attr "prefix_rep" "1")
14199 (set_attr "type" "bitmanip")
14200 (set_attr "mode" "HI")])
14202 (define_insn "*bsrhi"
14203 [(set (match_operand:HI 0 "register_operand" "=r")
14204 (minus:HI (const_int 15)
14205 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
14206 (clobber (reg:CC FLAGS_REG))]
14208 "bsr{w}\t{%1, %0|%0, %1}"
14209 [(set_attr "type" "alu1")
14210 (set_attr "prefix_0f" "1")
14211 (set_attr "mode" "HI")])
14213 (define_expand "paritydi2"
14214 [(set (match_operand:DI 0 "register_operand" "")
14215 (parity:DI (match_operand:DI 1 "register_operand" "")))]
14218 rtx scratch = gen_reg_rtx (QImode);
14221 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
14222 NULL_RTX, operands[1]));
14224 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14225 gen_rtx_REG (CCmode, FLAGS_REG),
14227 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14230 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
14233 rtx tmp = gen_reg_rtx (SImode);
14235 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
14236 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
14241 (define_insn_and_split "paritydi2_cmp"
14242 [(set (reg:CC FLAGS_REG)
14243 (parity:CC (match_operand:DI 3 "register_operand" "0")))
14244 (clobber (match_scratch:DI 0 "=r"))
14245 (clobber (match_scratch:SI 1 "=&r"))
14246 (clobber (match_scratch:HI 2 "=Q"))]
14249 "&& reload_completed"
14251 [(set (match_dup 1)
14252 (xor:SI (match_dup 1) (match_dup 4)))
14253 (clobber (reg:CC FLAGS_REG))])
14255 [(set (reg:CC FLAGS_REG)
14256 (parity:CC (match_dup 1)))
14257 (clobber (match_dup 1))
14258 (clobber (match_dup 2))])]
14260 operands[4] = gen_lowpart (SImode, operands[3]);
14264 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
14265 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
14268 operands[1] = gen_highpart (SImode, operands[3]);
14271 (define_expand "paritysi2"
14272 [(set (match_operand:SI 0 "register_operand" "")
14273 (parity:SI (match_operand:SI 1 "register_operand" "")))]
14276 rtx scratch = gen_reg_rtx (QImode);
14279 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
14281 cond = gen_rtx_fmt_ee (ORDERED, QImode,
14282 gen_rtx_REG (CCmode, FLAGS_REG),
14284 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
14286 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
14290 (define_insn_and_split "paritysi2_cmp"
14291 [(set (reg:CC FLAGS_REG)
14292 (parity:CC (match_operand:SI 2 "register_operand" "0")))
14293 (clobber (match_scratch:SI 0 "=r"))
14294 (clobber (match_scratch:HI 1 "=&Q"))]
14297 "&& reload_completed"
14299 [(set (match_dup 1)
14300 (xor:HI (match_dup 1) (match_dup 3)))
14301 (clobber (reg:CC FLAGS_REG))])
14303 [(set (reg:CC FLAGS_REG)
14304 (parity:CC (match_dup 1)))
14305 (clobber (match_dup 1))])]
14307 operands[3] = gen_lowpart (HImode, operands[2]);
14309 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
14310 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
14313 (define_insn "*parityhi2_cmp"
14314 [(set (reg:CC FLAGS_REG)
14315 (parity:CC (match_operand:HI 1 "register_operand" "0")))
14316 (clobber (match_scratch:HI 0 "=Q"))]
14318 "xor{b}\t{%h0, %b0|%b0, %h0}"
14319 [(set_attr "length" "2")
14320 (set_attr "mode" "HI")])
14322 (define_insn "*parityqi2_cmp"
14323 [(set (reg:CC FLAGS_REG)
14324 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
14327 [(set_attr "length" "2")
14328 (set_attr "mode" "QI")])
14330 ;; Thread-local storage patterns for ELF.
14332 ;; Note that these code sequences must appear exactly as shown
14333 ;; in order to allow linker relaxation.
14335 (define_insn "*tls_global_dynamic_32_gnu"
14336 [(set (match_operand:SI 0 "register_operand" "=a")
14337 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14338 (match_operand:SI 2 "tls_symbolic_operand" "")
14339 (match_operand:SI 3 "call_insn_operand" "")]
14341 (clobber (match_scratch:SI 4 "=d"))
14342 (clobber (match_scratch:SI 5 "=c"))
14343 (clobber (reg:CC FLAGS_REG))]
14344 "!TARGET_64BIT && TARGET_GNU_TLS"
14345 "lea{l}\t{%a2@tlsgd(,%1,1), %0|%0, %a2@tlsgd[%1*1]}\;call\t%P3"
14346 [(set_attr "type" "multi")
14347 (set_attr "length" "12")])
14349 (define_expand "tls_global_dynamic_32"
14350 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14353 (match_operand:SI 1 "tls_symbolic_operand" "")
14356 (clobber (match_scratch:SI 4 ""))
14357 (clobber (match_scratch:SI 5 ""))
14358 (clobber (reg:CC FLAGS_REG))])]
14362 operands[2] = pic_offset_table_rtx;
14365 operands[2] = gen_reg_rtx (Pmode);
14366 emit_insn (gen_set_got (operands[2]));
14368 if (TARGET_GNU2_TLS)
14370 emit_insn (gen_tls_dynamic_gnu2_32
14371 (operands[0], operands[1], operands[2]));
14374 operands[3] = ix86_tls_get_addr ();
14377 (define_insn "*tls_global_dynamic_64"
14378 [(set (match_operand:DI 0 "register_operand" "=a")
14379 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
14380 (match_operand:DI 3 "" "")))
14381 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14384 { 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"; }
14385 [(set_attr "type" "multi")
14386 (set_attr "length" "16")])
14388 (define_expand "tls_global_dynamic_64"
14389 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14390 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
14391 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14395 if (TARGET_GNU2_TLS)
14397 emit_insn (gen_tls_dynamic_gnu2_64
14398 (operands[0], operands[1]));
14401 operands[2] = ix86_tls_get_addr ();
14404 (define_insn "*tls_local_dynamic_base_32_gnu"
14405 [(set (match_operand:SI 0 "register_operand" "=a")
14406 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14407 (match_operand:SI 2 "call_insn_operand" "")]
14408 UNSPEC_TLS_LD_BASE))
14409 (clobber (match_scratch:SI 3 "=d"))
14410 (clobber (match_scratch:SI 4 "=c"))
14411 (clobber (reg:CC FLAGS_REG))]
14412 "!TARGET_64BIT && TARGET_GNU_TLS"
14413 "lea{l}\t{%&@tlsldm(%1), %0|%0, %&@tlsldm[%1]}\;call\t%P2"
14414 [(set_attr "type" "multi")
14415 (set_attr "length" "11")])
14417 (define_expand "tls_local_dynamic_base_32"
14418 [(parallel [(set (match_operand:SI 0 "register_operand" "")
14419 (unspec:SI [(match_dup 1) (match_dup 2)]
14420 UNSPEC_TLS_LD_BASE))
14421 (clobber (match_scratch:SI 3 ""))
14422 (clobber (match_scratch:SI 4 ""))
14423 (clobber (reg:CC FLAGS_REG))])]
14427 operands[1] = pic_offset_table_rtx;
14430 operands[1] = gen_reg_rtx (Pmode);
14431 emit_insn (gen_set_got (operands[1]));
14433 if (TARGET_GNU2_TLS)
14435 emit_insn (gen_tls_dynamic_gnu2_32
14436 (operands[0], ix86_tls_module_base (), operands[1]));
14439 operands[2] = ix86_tls_get_addr ();
14442 (define_insn "*tls_local_dynamic_base_64"
14443 [(set (match_operand:DI 0 "register_operand" "=a")
14444 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
14445 (match_operand:DI 2 "" "")))
14446 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
14448 "lea{q}\t{%&@tlsld(%%rip), %%rdi|rdi, %&@tlsld[rip]}\;call\t%P1"
14449 [(set_attr "type" "multi")
14450 (set_attr "length" "12")])
14452 (define_expand "tls_local_dynamic_base_64"
14453 [(parallel [(set (match_operand:DI 0 "register_operand" "")
14454 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
14455 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
14458 if (TARGET_GNU2_TLS)
14460 emit_insn (gen_tls_dynamic_gnu2_64
14461 (operands[0], ix86_tls_module_base ()));
14464 operands[1] = ix86_tls_get_addr ();
14467 ;; Local dynamic of a single variable is a lose. Show combine how
14468 ;; to convert that back to global dynamic.
14470 (define_insn_and_split "*tls_local_dynamic_32_once"
14471 [(set (match_operand:SI 0 "register_operand" "=a")
14472 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
14473 (match_operand:SI 2 "call_insn_operand" "")]
14474 UNSPEC_TLS_LD_BASE)
14475 (const:SI (unspec:SI
14476 [(match_operand:SI 3 "tls_symbolic_operand" "")]
14478 (clobber (match_scratch:SI 4 "=d"))
14479 (clobber (match_scratch:SI 5 "=c"))
14480 (clobber (reg:CC FLAGS_REG))]
14484 [(parallel [(set (match_dup 0)
14485 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
14487 (clobber (match_dup 4))
14488 (clobber (match_dup 5))
14489 (clobber (reg:CC FLAGS_REG))])]
14492 ;; Load and add the thread base pointer from %gs:0.
14494 (define_insn "*load_tp_si"
14495 [(set (match_operand:SI 0 "register_operand" "=r")
14496 (unspec:SI [(const_int 0)] UNSPEC_TP))]
14498 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14499 [(set_attr "type" "imov")
14500 (set_attr "modrm" "0")
14501 (set_attr "length" "7")
14502 (set_attr "memory" "load")
14503 (set_attr "imm_disp" "false")])
14505 (define_insn "*add_tp_si"
14506 [(set (match_operand:SI 0 "register_operand" "=r")
14507 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
14508 (match_operand:SI 1 "register_operand" "0")))
14509 (clobber (reg:CC FLAGS_REG))]
14511 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
14512 [(set_attr "type" "alu")
14513 (set_attr "modrm" "0")
14514 (set_attr "length" "7")
14515 (set_attr "memory" "load")
14516 (set_attr "imm_disp" "false")])
14518 (define_insn "*load_tp_di"
14519 [(set (match_operand:DI 0 "register_operand" "=r")
14520 (unspec:DI [(const_int 0)] UNSPEC_TP))]
14522 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14523 [(set_attr "type" "imov")
14524 (set_attr "modrm" "0")
14525 (set_attr "length" "7")
14526 (set_attr "memory" "load")
14527 (set_attr "imm_disp" "false")])
14529 (define_insn "*add_tp_di"
14530 [(set (match_operand:DI 0 "register_operand" "=r")
14531 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
14532 (match_operand:DI 1 "register_operand" "0")))
14533 (clobber (reg:CC FLAGS_REG))]
14535 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
14536 [(set_attr "type" "alu")
14537 (set_attr "modrm" "0")
14538 (set_attr "length" "7")
14539 (set_attr "memory" "load")
14540 (set_attr "imm_disp" "false")])
14542 ;; GNU2 TLS patterns can be split.
14544 (define_expand "tls_dynamic_gnu2_32"
14545 [(set (match_dup 3)
14546 (plus:SI (match_operand:SI 2 "register_operand" "")
14548 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
14551 [(set (match_operand:SI 0 "register_operand" "")
14552 (unspec:SI [(match_dup 1) (match_dup 3)
14553 (match_dup 2) (reg:SI SP_REG)]
14555 (clobber (reg:CC FLAGS_REG))])]
14556 "!TARGET_64BIT && TARGET_GNU2_TLS"
14558 operands[3] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14559 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14562 (define_insn "*tls_dynamic_lea_32"
14563 [(set (match_operand:SI 0 "register_operand" "=r")
14564 (plus:SI (match_operand:SI 1 "register_operand" "b")
14566 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
14567 UNSPEC_TLSDESC))))]
14568 "!TARGET_64BIT && TARGET_GNU2_TLS"
14569 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
14570 [(set_attr "type" "lea")
14571 (set_attr "mode" "SI")
14572 (set_attr "length" "6")
14573 (set_attr "length_address" "4")])
14575 (define_insn "*tls_dynamic_call_32"
14576 [(set (match_operand:SI 0 "register_operand" "=a")
14577 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
14578 (match_operand:SI 2 "register_operand" "0")
14579 ;; we have to make sure %ebx still points to the GOT
14580 (match_operand:SI 3 "register_operand" "b")
14583 (clobber (reg:CC FLAGS_REG))]
14584 "!TARGET_64BIT && TARGET_GNU2_TLS"
14585 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
14586 [(set_attr "type" "call")
14587 (set_attr "length" "2")
14588 (set_attr "length_address" "0")])
14590 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
14591 [(set (match_operand:SI 0 "register_operand" "=&a")
14593 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
14594 (match_operand:SI 4 "" "")
14595 (match_operand:SI 2 "register_operand" "b")
14598 (const:SI (unspec:SI
14599 [(match_operand:SI 1 "tls_symbolic_operand" "")]
14601 (clobber (reg:CC FLAGS_REG))]
14602 "!TARGET_64BIT && TARGET_GNU2_TLS"
14605 [(set (match_dup 0) (match_dup 5))]
14607 operands[5] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14608 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
14611 (define_expand "tls_dynamic_gnu2_64"
14612 [(set (match_dup 2)
14613 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14616 [(set (match_operand:DI 0 "register_operand" "")
14617 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
14619 (clobber (reg:CC FLAGS_REG))])]
14620 "TARGET_64BIT && TARGET_GNU2_TLS"
14622 operands[2] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14623 ix86_tls_descriptor_calls_expanded_in_cfun = true;
14626 (define_insn "*tls_dynamic_lea_64"
14627 [(set (match_operand:DI 0 "register_operand" "=r")
14628 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
14630 "TARGET_64BIT && TARGET_GNU2_TLS"
14631 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
14632 [(set_attr "type" "lea")
14633 (set_attr "mode" "DI")
14634 (set_attr "length" "7")
14635 (set_attr "length_address" "4")])
14637 (define_insn "*tls_dynamic_call_64"
14638 [(set (match_operand:DI 0 "register_operand" "=a")
14639 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
14640 (match_operand:DI 2 "register_operand" "0")
14643 (clobber (reg:CC FLAGS_REG))]
14644 "TARGET_64BIT && TARGET_GNU2_TLS"
14645 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
14646 [(set_attr "type" "call")
14647 (set_attr "length" "2")
14648 (set_attr "length_address" "0")])
14650 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
14651 [(set (match_operand:DI 0 "register_operand" "=&a")
14653 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
14654 (match_operand:DI 3 "" "")
14657 (const:DI (unspec:DI
14658 [(match_operand:DI 1 "tls_symbolic_operand" "")]
14660 (clobber (reg:CC FLAGS_REG))]
14661 "TARGET_64BIT && TARGET_GNU2_TLS"
14664 [(set (match_dup 0) (match_dup 4))]
14666 operands[4] = can_create_pseudo_p () ? gen_reg_rtx (Pmode) : operands[0];
14667 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
14672 ;; These patterns match the binary 387 instructions for addM3, subM3,
14673 ;; mulM3 and divM3. There are three patterns for each of DFmode and
14674 ;; SFmode. The first is the normal insn, the second the same insn but
14675 ;; with one operand a conversion, and the third the same insn but with
14676 ;; the other operand a conversion. The conversion may be SFmode or
14677 ;; SImode if the target mode DFmode, but only SImode if the target mode
14680 ;; Gcc is slightly more smart about handling normal two address instructions
14681 ;; so use special patterns for add and mull.
14683 (define_insn "*fop_<mode>_comm_mixed_avx"
14684 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14685 (match_operator:MODEF 3 "binary_fp_operator"
14686 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
14687 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14688 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14689 && COMMUTATIVE_ARITH_P (operands[3])
14690 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14691 "* return output_387_binary_op (insn, operands);"
14692 [(set (attr "type")
14693 (if_then_else (eq_attr "alternative" "1")
14694 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14695 (const_string "ssemul")
14696 (const_string "sseadd"))
14697 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14698 (const_string "fmul")
14699 (const_string "fop"))))
14700 (set_attr "prefix" "orig,maybe_vex")
14701 (set_attr "mode" "<MODE>")])
14703 (define_insn "*fop_<mode>_comm_mixed"
14704 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
14705 (match_operator:MODEF 3 "binary_fp_operator"
14706 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
14707 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
14708 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14709 && COMMUTATIVE_ARITH_P (operands[3])
14710 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14711 "* return output_387_binary_op (insn, operands);"
14712 [(set (attr "type")
14713 (if_then_else (eq_attr "alternative" "1")
14714 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14715 (const_string "ssemul")
14716 (const_string "sseadd"))
14717 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14718 (const_string "fmul")
14719 (const_string "fop"))))
14720 (set_attr "mode" "<MODE>")])
14722 (define_insn "*fop_<mode>_comm_avx"
14723 [(set (match_operand:MODEF 0 "register_operand" "=x")
14724 (match_operator:MODEF 3 "binary_fp_operator"
14725 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
14726 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14727 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14728 && COMMUTATIVE_ARITH_P (operands[3])
14729 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14730 "* return output_387_binary_op (insn, operands);"
14731 [(set (attr "type")
14732 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14733 (const_string "ssemul")
14734 (const_string "sseadd")))
14735 (set_attr "prefix" "vex")
14736 (set_attr "mode" "<MODE>")])
14738 (define_insn "*fop_<mode>_comm_sse"
14739 [(set (match_operand:MODEF 0 "register_operand" "=x")
14740 (match_operator:MODEF 3 "binary_fp_operator"
14741 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14742 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14743 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14744 && COMMUTATIVE_ARITH_P (operands[3])
14745 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14746 "* return output_387_binary_op (insn, operands);"
14747 [(set (attr "type")
14748 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14749 (const_string "ssemul")
14750 (const_string "sseadd")))
14751 (set_attr "mode" "<MODE>")])
14753 (define_insn "*fop_<mode>_comm_i387"
14754 [(set (match_operand:MODEF 0 "register_operand" "=f")
14755 (match_operator:MODEF 3 "binary_fp_operator"
14756 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
14757 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
14758 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14759 && COMMUTATIVE_ARITH_P (operands[3])
14760 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14761 "* return output_387_binary_op (insn, operands);"
14762 [(set (attr "type")
14763 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
14764 (const_string "fmul")
14765 (const_string "fop")))
14766 (set_attr "mode" "<MODE>")])
14768 (define_insn "*fop_<mode>_1_mixed_avx"
14769 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14770 (match_operator:MODEF 3 "binary_fp_operator"
14771 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
14772 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14773 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14774 && !COMMUTATIVE_ARITH_P (operands[3])
14775 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14776 "* return output_387_binary_op (insn, operands);"
14777 [(set (attr "type")
14778 (cond [(and (eq_attr "alternative" "2")
14779 (match_operand:MODEF 3 "mult_operator" ""))
14780 (const_string "ssemul")
14781 (and (eq_attr "alternative" "2")
14782 (match_operand:MODEF 3 "div_operator" ""))
14783 (const_string "ssediv")
14784 (eq_attr "alternative" "2")
14785 (const_string "sseadd")
14786 (match_operand:MODEF 3 "mult_operator" "")
14787 (const_string "fmul")
14788 (match_operand:MODEF 3 "div_operator" "")
14789 (const_string "fdiv")
14791 (const_string "fop")))
14792 (set_attr "prefix" "orig,orig,maybe_vex")
14793 (set_attr "mode" "<MODE>")])
14795 (define_insn "*fop_<mode>_1_mixed"
14796 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
14797 (match_operator:MODEF 3 "binary_fp_operator"
14798 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
14799 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
14800 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
14801 && !COMMUTATIVE_ARITH_P (operands[3])
14802 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14803 "* return output_387_binary_op (insn, operands);"
14804 [(set (attr "type")
14805 (cond [(and (eq_attr "alternative" "2")
14806 (match_operand:MODEF 3 "mult_operator" ""))
14807 (const_string "ssemul")
14808 (and (eq_attr "alternative" "2")
14809 (match_operand:MODEF 3 "div_operator" ""))
14810 (const_string "ssediv")
14811 (eq_attr "alternative" "2")
14812 (const_string "sseadd")
14813 (match_operand:MODEF 3 "mult_operator" "")
14814 (const_string "fmul")
14815 (match_operand:MODEF 3 "div_operator" "")
14816 (const_string "fdiv")
14818 (const_string "fop")))
14819 (set_attr "mode" "<MODE>")])
14821 (define_insn "*rcpsf2_sse"
14822 [(set (match_operand:SF 0 "register_operand" "=x")
14823 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
14826 "%vrcpss\t{%1, %d0|%d0, %1}"
14827 [(set_attr "type" "sse")
14828 (set_attr "atom_sse_attr" "rcp")
14829 (set_attr "prefix" "maybe_vex")
14830 (set_attr "mode" "SF")])
14832 (define_insn "*fop_<mode>_1_avx"
14833 [(set (match_operand:MODEF 0 "register_operand" "=x")
14834 (match_operator:MODEF 3 "binary_fp_operator"
14835 [(match_operand:MODEF 1 "register_operand" "x")
14836 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14837 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14838 && !COMMUTATIVE_ARITH_P (operands[3])"
14839 "* return output_387_binary_op (insn, operands);"
14840 [(set (attr "type")
14841 (cond [(match_operand:MODEF 3 "mult_operator" "")
14842 (const_string "ssemul")
14843 (match_operand:MODEF 3 "div_operator" "")
14844 (const_string "ssediv")
14846 (const_string "sseadd")))
14847 (set_attr "prefix" "vex")
14848 (set_attr "mode" "<MODE>")])
14850 (define_insn "*fop_<mode>_1_sse"
14851 [(set (match_operand:MODEF 0 "register_operand" "=x")
14852 (match_operator:MODEF 3 "binary_fp_operator"
14853 [(match_operand:MODEF 1 "register_operand" "0")
14854 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
14855 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
14856 && !COMMUTATIVE_ARITH_P (operands[3])"
14857 "* return output_387_binary_op (insn, operands);"
14858 [(set (attr "type")
14859 (cond [(match_operand:MODEF 3 "mult_operator" "")
14860 (const_string "ssemul")
14861 (match_operand:MODEF 3 "div_operator" "")
14862 (const_string "ssediv")
14864 (const_string "sseadd")))
14865 (set_attr "mode" "<MODE>")])
14867 ;; This pattern is not fully shadowed by the pattern above.
14868 (define_insn "*fop_<mode>_1_i387"
14869 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14870 (match_operator:MODEF 3 "binary_fp_operator"
14871 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
14872 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
14873 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
14874 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
14875 && !COMMUTATIVE_ARITH_P (operands[3])
14876 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14877 "* return output_387_binary_op (insn, operands);"
14878 [(set (attr "type")
14879 (cond [(match_operand:MODEF 3 "mult_operator" "")
14880 (const_string "fmul")
14881 (match_operand:MODEF 3 "div_operator" "")
14882 (const_string "fdiv")
14884 (const_string "fop")))
14885 (set_attr "mode" "<MODE>")])
14887 ;; ??? Add SSE splitters for these!
14888 (define_insn "*fop_<MODEF:mode>_2_i387"
14889 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14890 (match_operator:MODEF 3 "binary_fp_operator"
14892 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
14893 (match_operand:MODEF 2 "register_operand" "0,0")]))]
14894 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
14895 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14896 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14897 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14898 [(set (attr "type")
14899 (cond [(match_operand:MODEF 3 "mult_operator" "")
14900 (const_string "fmul")
14901 (match_operand:MODEF 3 "div_operator" "")
14902 (const_string "fdiv")
14904 (const_string "fop")))
14905 (set_attr "fp_int_src" "true")
14906 (set_attr "mode" "<X87MODEI12:MODE>")])
14908 (define_insn "*fop_<MODEF:mode>_3_i387"
14909 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
14910 (match_operator:MODEF 3 "binary_fp_operator"
14911 [(match_operand:MODEF 1 "register_operand" "0,0")
14913 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
14914 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
14915 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
14916 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
14917 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
14918 [(set (attr "type")
14919 (cond [(match_operand:MODEF 3 "mult_operator" "")
14920 (const_string "fmul")
14921 (match_operand:MODEF 3 "div_operator" "")
14922 (const_string "fdiv")
14924 (const_string "fop")))
14925 (set_attr "fp_int_src" "true")
14926 (set_attr "mode" "<MODE>")])
14928 (define_insn "*fop_df_4_i387"
14929 [(set (match_operand:DF 0 "register_operand" "=f,f")
14930 (match_operator:DF 3 "binary_fp_operator"
14932 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
14933 (match_operand:DF 2 "register_operand" "0,f")]))]
14934 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14935 && !(TARGET_SSE2 && TARGET_SSE_MATH)
14936 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
14937 "* return output_387_binary_op (insn, operands);"
14938 [(set (attr "type")
14939 (cond [(match_operand:DF 3 "mult_operator" "")
14940 (const_string "fmul")
14941 (match_operand:DF 3 "div_operator" "")
14942 (const_string "fdiv")
14944 (const_string "fop")))
14945 (set_attr "mode" "SF")])
14947 (define_insn "*fop_df_5_i387"
14948 [(set (match_operand:DF 0 "register_operand" "=f,f")
14949 (match_operator:DF 3 "binary_fp_operator"
14950 [(match_operand:DF 1 "register_operand" "0,f")
14952 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14953 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14954 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14955 "* return output_387_binary_op (insn, operands);"
14956 [(set (attr "type")
14957 (cond [(match_operand:DF 3 "mult_operator" "")
14958 (const_string "fmul")
14959 (match_operand:DF 3 "div_operator" "")
14960 (const_string "fdiv")
14962 (const_string "fop")))
14963 (set_attr "mode" "SF")])
14965 (define_insn "*fop_df_6_i387"
14966 [(set (match_operand:DF 0 "register_operand" "=f,f")
14967 (match_operator:DF 3 "binary_fp_operator"
14969 (match_operand:SF 1 "register_operand" "0,f"))
14971 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
14972 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
14973 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
14974 "* return output_387_binary_op (insn, operands);"
14975 [(set (attr "type")
14976 (cond [(match_operand:DF 3 "mult_operator" "")
14977 (const_string "fmul")
14978 (match_operand:DF 3 "div_operator" "")
14979 (const_string "fdiv")
14981 (const_string "fop")))
14982 (set_attr "mode" "SF")])
14984 (define_insn "*fop_xf_comm_i387"
14985 [(set (match_operand:XF 0 "register_operand" "=f")
14986 (match_operator:XF 3 "binary_fp_operator"
14987 [(match_operand:XF 1 "register_operand" "%0")
14988 (match_operand:XF 2 "register_operand" "f")]))]
14990 && COMMUTATIVE_ARITH_P (operands[3])"
14991 "* return output_387_binary_op (insn, operands);"
14992 [(set (attr "type")
14993 (if_then_else (match_operand:XF 3 "mult_operator" "")
14994 (const_string "fmul")
14995 (const_string "fop")))
14996 (set_attr "mode" "XF")])
14998 (define_insn "*fop_xf_1_i387"
14999 [(set (match_operand:XF 0 "register_operand" "=f,f")
15000 (match_operator:XF 3 "binary_fp_operator"
15001 [(match_operand:XF 1 "register_operand" "0,f")
15002 (match_operand:XF 2 "register_operand" "f,0")]))]
15004 && !COMMUTATIVE_ARITH_P (operands[3])"
15005 "* return output_387_binary_op (insn, operands);"
15006 [(set (attr "type")
15007 (cond [(match_operand:XF 3 "mult_operator" "")
15008 (const_string "fmul")
15009 (match_operand:XF 3 "div_operator" "")
15010 (const_string "fdiv")
15012 (const_string "fop")))
15013 (set_attr "mode" "XF")])
15015 (define_insn "*fop_xf_2_i387"
15016 [(set (match_operand:XF 0 "register_operand" "=f,f")
15017 (match_operator:XF 3 "binary_fp_operator"
15019 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
15020 (match_operand:XF 2 "register_operand" "0,0")]))]
15021 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15022 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15023 [(set (attr "type")
15024 (cond [(match_operand:XF 3 "mult_operator" "")
15025 (const_string "fmul")
15026 (match_operand:XF 3 "div_operator" "")
15027 (const_string "fdiv")
15029 (const_string "fop")))
15030 (set_attr "fp_int_src" "true")
15031 (set_attr "mode" "<MODE>")])
15033 (define_insn "*fop_xf_3_i387"
15034 [(set (match_operand:XF 0 "register_operand" "=f,f")
15035 (match_operator:XF 3 "binary_fp_operator"
15036 [(match_operand:XF 1 "register_operand" "0,0")
15038 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
15039 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
15040 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
15041 [(set (attr "type")
15042 (cond [(match_operand:XF 3 "mult_operator" "")
15043 (const_string "fmul")
15044 (match_operand:XF 3 "div_operator" "")
15045 (const_string "fdiv")
15047 (const_string "fop")))
15048 (set_attr "fp_int_src" "true")
15049 (set_attr "mode" "<MODE>")])
15051 (define_insn "*fop_xf_4_i387"
15052 [(set (match_operand:XF 0 "register_operand" "=f,f")
15053 (match_operator:XF 3 "binary_fp_operator"
15055 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
15056 (match_operand:XF 2 "register_operand" "0,f")]))]
15058 "* return output_387_binary_op (insn, operands);"
15059 [(set (attr "type")
15060 (cond [(match_operand:XF 3 "mult_operator" "")
15061 (const_string "fmul")
15062 (match_operand:XF 3 "div_operator" "")
15063 (const_string "fdiv")
15065 (const_string "fop")))
15066 (set_attr "mode" "<MODE>")])
15068 (define_insn "*fop_xf_5_i387"
15069 [(set (match_operand:XF 0 "register_operand" "=f,f")
15070 (match_operator:XF 3 "binary_fp_operator"
15071 [(match_operand:XF 1 "register_operand" "0,f")
15073 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15075 "* return output_387_binary_op (insn, operands);"
15076 [(set (attr "type")
15077 (cond [(match_operand:XF 3 "mult_operator" "")
15078 (const_string "fmul")
15079 (match_operand:XF 3 "div_operator" "")
15080 (const_string "fdiv")
15082 (const_string "fop")))
15083 (set_attr "mode" "<MODE>")])
15085 (define_insn "*fop_xf_6_i387"
15086 [(set (match_operand:XF 0 "register_operand" "=f,f")
15087 (match_operator:XF 3 "binary_fp_operator"
15089 (match_operand:MODEF 1 "register_operand" "0,f"))
15091 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
15093 "* return output_387_binary_op (insn, operands);"
15094 [(set (attr "type")
15095 (cond [(match_operand:XF 3 "mult_operator" "")
15096 (const_string "fmul")
15097 (match_operand:XF 3 "div_operator" "")
15098 (const_string "fdiv")
15100 (const_string "fop")))
15101 (set_attr "mode" "<MODE>")])
15104 [(set (match_operand 0 "register_operand" "")
15105 (match_operator 3 "binary_fp_operator"
15106 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
15107 (match_operand 2 "register_operand" "")]))]
15109 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15110 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
15113 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
15114 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15115 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15116 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15117 GET_MODE (operands[3]),
15120 ix86_free_from_memory (GET_MODE (operands[1]));
15125 [(set (match_operand 0 "register_operand" "")
15126 (match_operator 3 "binary_fp_operator"
15127 [(match_operand 1 "register_operand" "")
15128 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
15130 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
15131 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
15134 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15135 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
15136 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
15137 gen_rtx_fmt_ee (GET_CODE (operands[3]),
15138 GET_MODE (operands[3]),
15141 ix86_free_from_memory (GET_MODE (operands[2]));
15145 ;; FPU special functions.
15147 ;; This pattern implements a no-op XFmode truncation for
15148 ;; all fancy i386 XFmode math functions.
15150 (define_insn "truncxf<mode>2_i387_noop_unspec"
15151 [(set (match_operand:MODEF 0 "register_operand" "=f")
15152 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
15153 UNSPEC_TRUNC_NOOP))]
15154 "TARGET_USE_FANCY_MATH_387"
15155 "* return output_387_reg_move (insn, operands);"
15156 [(set_attr "type" "fmov")
15157 (set_attr "mode" "<MODE>")])
15159 (define_insn "sqrtxf2"
15160 [(set (match_operand:XF 0 "register_operand" "=f")
15161 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
15162 "TARGET_USE_FANCY_MATH_387"
15164 [(set_attr "type" "fpspc")
15165 (set_attr "mode" "XF")
15166 (set_attr "athlon_decode" "direct")
15167 (set_attr "amdfam10_decode" "direct")])
15169 (define_insn "sqrt_extend<mode>xf2_i387"
15170 [(set (match_operand:XF 0 "register_operand" "=f")
15173 (match_operand:MODEF 1 "register_operand" "0"))))]
15174 "TARGET_USE_FANCY_MATH_387"
15176 [(set_attr "type" "fpspc")
15177 (set_attr "mode" "XF")
15178 (set_attr "athlon_decode" "direct")
15179 (set_attr "amdfam10_decode" "direct")])
15181 (define_insn "*rsqrtsf2_sse"
15182 [(set (match_operand:SF 0 "register_operand" "=x")
15183 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
15186 "%vrsqrtss\t{%1, %d0|%d0, %1}"
15187 [(set_attr "type" "sse")
15188 (set_attr "atom_sse_attr" "rcp")
15189 (set_attr "prefix" "maybe_vex")
15190 (set_attr "mode" "SF")])
15192 (define_expand "rsqrtsf2"
15193 [(set (match_operand:SF 0 "register_operand" "")
15194 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
15198 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
15202 (define_insn "*sqrt<mode>2_sse"
15203 [(set (match_operand:MODEF 0 "register_operand" "=x")
15205 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
15206 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
15207 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
15208 [(set_attr "type" "sse")
15209 (set_attr "atom_sse_attr" "sqrt")
15210 (set_attr "prefix" "maybe_vex")
15211 (set_attr "mode" "<MODE>")
15212 (set_attr "athlon_decode" "*")
15213 (set_attr "amdfam10_decode" "*")])
15215 (define_expand "sqrt<mode>2"
15216 [(set (match_operand:MODEF 0 "register_operand" "")
15218 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
15219 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
15220 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
15222 if (<MODE>mode == SFmode
15223 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
15224 && flag_finite_math_only && !flag_trapping_math
15225 && flag_unsafe_math_optimizations)
15227 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
15231 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
15233 rtx op0 = gen_reg_rtx (XFmode);
15234 rtx op1 = force_reg (<MODE>mode, operands[1]);
15236 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
15237 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
15242 (define_insn "fpremxf4_i387"
15243 [(set (match_operand:XF 0 "register_operand" "=f")
15244 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15245 (match_operand:XF 3 "register_operand" "1")]
15247 (set (match_operand:XF 1 "register_operand" "=u")
15248 (unspec:XF [(match_dup 2) (match_dup 3)]
15250 (set (reg:CCFP FPSR_REG)
15251 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15253 "TARGET_USE_FANCY_MATH_387"
15255 [(set_attr "type" "fpspc")
15256 (set_attr "mode" "XF")])
15258 (define_expand "fmodxf3"
15259 [(use (match_operand:XF 0 "register_operand" ""))
15260 (use (match_operand:XF 1 "general_operand" ""))
15261 (use (match_operand:XF 2 "general_operand" ""))]
15262 "TARGET_USE_FANCY_MATH_387"
15264 rtx label = gen_label_rtx ();
15266 rtx op1 = gen_reg_rtx (XFmode);
15267 rtx op2 = gen_reg_rtx (XFmode);
15269 emit_move_insn (op2, operands[2]);
15270 emit_move_insn (op1, operands[1]);
15272 emit_label (label);
15273 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15274 ix86_emit_fp_unordered_jump (label);
15275 LABEL_NUSES (label) = 1;
15277 emit_move_insn (operands[0], op1);
15281 (define_expand "fmod<mode>3"
15282 [(use (match_operand:MODEF 0 "register_operand" ""))
15283 (use (match_operand:MODEF 1 "general_operand" ""))
15284 (use (match_operand:MODEF 2 "general_operand" ""))]
15285 "TARGET_USE_FANCY_MATH_387"
15287 rtx label = gen_label_rtx ();
15289 rtx op1 = gen_reg_rtx (XFmode);
15290 rtx op2 = gen_reg_rtx (XFmode);
15292 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15293 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15295 emit_label (label);
15296 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
15297 ix86_emit_fp_unordered_jump (label);
15298 LABEL_NUSES (label) = 1;
15300 /* Truncate the result properly for strict SSE math. */
15301 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15302 && !TARGET_MIX_SSE_I387)
15303 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15305 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15310 (define_insn "fprem1xf4_i387"
15311 [(set (match_operand:XF 0 "register_operand" "=f")
15312 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
15313 (match_operand:XF 3 "register_operand" "1")]
15315 (set (match_operand:XF 1 "register_operand" "=u")
15316 (unspec:XF [(match_dup 2) (match_dup 3)]
15318 (set (reg:CCFP FPSR_REG)
15319 (unspec:CCFP [(match_dup 2) (match_dup 3)]
15321 "TARGET_USE_FANCY_MATH_387"
15323 [(set_attr "type" "fpspc")
15324 (set_attr "mode" "XF")])
15326 (define_expand "remainderxf3"
15327 [(use (match_operand:XF 0 "register_operand" ""))
15328 (use (match_operand:XF 1 "general_operand" ""))
15329 (use (match_operand:XF 2 "general_operand" ""))]
15330 "TARGET_USE_FANCY_MATH_387"
15332 rtx label = gen_label_rtx ();
15334 rtx op1 = gen_reg_rtx (XFmode);
15335 rtx op2 = gen_reg_rtx (XFmode);
15337 emit_move_insn (op2, operands[2]);
15338 emit_move_insn (op1, operands[1]);
15340 emit_label (label);
15341 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15342 ix86_emit_fp_unordered_jump (label);
15343 LABEL_NUSES (label) = 1;
15345 emit_move_insn (operands[0], op1);
15349 (define_expand "remainder<mode>3"
15350 [(use (match_operand:MODEF 0 "register_operand" ""))
15351 (use (match_operand:MODEF 1 "general_operand" ""))
15352 (use (match_operand:MODEF 2 "general_operand" ""))]
15353 "TARGET_USE_FANCY_MATH_387"
15355 rtx label = gen_label_rtx ();
15357 rtx op1 = gen_reg_rtx (XFmode);
15358 rtx op2 = gen_reg_rtx (XFmode);
15360 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
15361 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15363 emit_label (label);
15365 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
15366 ix86_emit_fp_unordered_jump (label);
15367 LABEL_NUSES (label) = 1;
15369 /* Truncate the result properly for strict SSE math. */
15370 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
15371 && !TARGET_MIX_SSE_I387)
15372 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
15374 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
15379 (define_insn "*sinxf2_i387"
15380 [(set (match_operand:XF 0 "register_operand" "=f")
15381 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
15382 "TARGET_USE_FANCY_MATH_387
15383 && flag_unsafe_math_optimizations"
15385 [(set_attr "type" "fpspc")
15386 (set_attr "mode" "XF")])
15388 (define_insn "*sin_extend<mode>xf2_i387"
15389 [(set (match_operand:XF 0 "register_operand" "=f")
15390 (unspec:XF [(float_extend:XF
15391 (match_operand:MODEF 1 "register_operand" "0"))]
15393 "TARGET_USE_FANCY_MATH_387
15394 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15395 || TARGET_MIX_SSE_I387)
15396 && flag_unsafe_math_optimizations"
15398 [(set_attr "type" "fpspc")
15399 (set_attr "mode" "XF")])
15401 (define_insn "*cosxf2_i387"
15402 [(set (match_operand:XF 0 "register_operand" "=f")
15403 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
15404 "TARGET_USE_FANCY_MATH_387
15405 && flag_unsafe_math_optimizations"
15407 [(set_attr "type" "fpspc")
15408 (set_attr "mode" "XF")])
15410 (define_insn "*cos_extend<mode>xf2_i387"
15411 [(set (match_operand:XF 0 "register_operand" "=f")
15412 (unspec:XF [(float_extend:XF
15413 (match_operand:MODEF 1 "register_operand" "0"))]
15415 "TARGET_USE_FANCY_MATH_387
15416 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15417 || TARGET_MIX_SSE_I387)
15418 && flag_unsafe_math_optimizations"
15420 [(set_attr "type" "fpspc")
15421 (set_attr "mode" "XF")])
15423 ;; When sincos pattern is defined, sin and cos builtin functions will be
15424 ;; expanded to sincos pattern with one of its outputs left unused.
15425 ;; CSE pass will figure out if two sincos patterns can be combined,
15426 ;; otherwise sincos pattern will be split back to sin or cos pattern,
15427 ;; depending on the unused output.
15429 (define_insn "sincosxf3"
15430 [(set (match_operand:XF 0 "register_operand" "=f")
15431 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15432 UNSPEC_SINCOS_COS))
15433 (set (match_operand:XF 1 "register_operand" "=u")
15434 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15435 "TARGET_USE_FANCY_MATH_387
15436 && flag_unsafe_math_optimizations"
15438 [(set_attr "type" "fpspc")
15439 (set_attr "mode" "XF")])
15442 [(set (match_operand:XF 0 "register_operand" "")
15443 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15444 UNSPEC_SINCOS_COS))
15445 (set (match_operand:XF 1 "register_operand" "")
15446 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15447 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15448 && !(reload_completed || reload_in_progress)"
15449 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
15453 [(set (match_operand:XF 0 "register_operand" "")
15454 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
15455 UNSPEC_SINCOS_COS))
15456 (set (match_operand:XF 1 "register_operand" "")
15457 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
15458 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15459 && !(reload_completed || reload_in_progress)"
15460 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
15463 (define_insn "sincos_extend<mode>xf3_i387"
15464 [(set (match_operand:XF 0 "register_operand" "=f")
15465 (unspec:XF [(float_extend:XF
15466 (match_operand:MODEF 2 "register_operand" "0"))]
15467 UNSPEC_SINCOS_COS))
15468 (set (match_operand:XF 1 "register_operand" "=u")
15469 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15470 "TARGET_USE_FANCY_MATH_387
15471 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15472 || TARGET_MIX_SSE_I387)
15473 && flag_unsafe_math_optimizations"
15475 [(set_attr "type" "fpspc")
15476 (set_attr "mode" "XF")])
15479 [(set (match_operand:XF 0 "register_operand" "")
15480 (unspec:XF [(float_extend:XF
15481 (match_operand:MODEF 2 "register_operand" ""))]
15482 UNSPEC_SINCOS_COS))
15483 (set (match_operand:XF 1 "register_operand" "")
15484 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15485 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
15486 && !(reload_completed || reload_in_progress)"
15487 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
15491 [(set (match_operand:XF 0 "register_operand" "")
15492 (unspec:XF [(float_extend:XF
15493 (match_operand:MODEF 2 "register_operand" ""))]
15494 UNSPEC_SINCOS_COS))
15495 (set (match_operand:XF 1 "register_operand" "")
15496 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
15497 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
15498 && !(reload_completed || reload_in_progress)"
15499 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
15502 (define_expand "sincos<mode>3"
15503 [(use (match_operand:MODEF 0 "register_operand" ""))
15504 (use (match_operand:MODEF 1 "register_operand" ""))
15505 (use (match_operand:MODEF 2 "register_operand" ""))]
15506 "TARGET_USE_FANCY_MATH_387
15507 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15508 || TARGET_MIX_SSE_I387)
15509 && flag_unsafe_math_optimizations"
15511 rtx op0 = gen_reg_rtx (XFmode);
15512 rtx op1 = gen_reg_rtx (XFmode);
15514 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
15515 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15516 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
15520 (define_insn "fptanxf4_i387"
15521 [(set (match_operand:XF 0 "register_operand" "=f")
15522 (match_operand:XF 3 "const_double_operand" "F"))
15523 (set (match_operand:XF 1 "register_operand" "=u")
15524 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15526 "TARGET_USE_FANCY_MATH_387
15527 && flag_unsafe_math_optimizations
15528 && standard_80387_constant_p (operands[3]) == 2"
15530 [(set_attr "type" "fpspc")
15531 (set_attr "mode" "XF")])
15533 (define_insn "fptan_extend<mode>xf4_i387"
15534 [(set (match_operand:MODEF 0 "register_operand" "=f")
15535 (match_operand:MODEF 3 "const_double_operand" "F"))
15536 (set (match_operand:XF 1 "register_operand" "=u")
15537 (unspec:XF [(float_extend:XF
15538 (match_operand:MODEF 2 "register_operand" "0"))]
15540 "TARGET_USE_FANCY_MATH_387
15541 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15542 || TARGET_MIX_SSE_I387)
15543 && flag_unsafe_math_optimizations
15544 && standard_80387_constant_p (operands[3]) == 2"
15546 [(set_attr "type" "fpspc")
15547 (set_attr "mode" "XF")])
15549 (define_expand "tanxf2"
15550 [(use (match_operand:XF 0 "register_operand" ""))
15551 (use (match_operand:XF 1 "register_operand" ""))]
15552 "TARGET_USE_FANCY_MATH_387
15553 && flag_unsafe_math_optimizations"
15555 rtx one = gen_reg_rtx (XFmode);
15556 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
15558 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
15562 (define_expand "tan<mode>2"
15563 [(use (match_operand:MODEF 0 "register_operand" ""))
15564 (use (match_operand:MODEF 1 "register_operand" ""))]
15565 "TARGET_USE_FANCY_MATH_387
15566 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15567 || TARGET_MIX_SSE_I387)
15568 && flag_unsafe_math_optimizations"
15570 rtx op0 = gen_reg_rtx (XFmode);
15572 rtx one = gen_reg_rtx (<MODE>mode);
15573 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
15575 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
15576 operands[1], op2));
15577 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15581 (define_insn "*fpatanxf3_i387"
15582 [(set (match_operand:XF 0 "register_operand" "=f")
15583 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15584 (match_operand:XF 2 "register_operand" "u")]
15586 (clobber (match_scratch:XF 3 "=2"))]
15587 "TARGET_USE_FANCY_MATH_387
15588 && flag_unsafe_math_optimizations"
15590 [(set_attr "type" "fpspc")
15591 (set_attr "mode" "XF")])
15593 (define_insn "fpatan_extend<mode>xf3_i387"
15594 [(set (match_operand:XF 0 "register_operand" "=f")
15595 (unspec:XF [(float_extend:XF
15596 (match_operand:MODEF 1 "register_operand" "0"))
15598 (match_operand:MODEF 2 "register_operand" "u"))]
15600 (clobber (match_scratch:XF 3 "=2"))]
15601 "TARGET_USE_FANCY_MATH_387
15602 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15603 || TARGET_MIX_SSE_I387)
15604 && flag_unsafe_math_optimizations"
15606 [(set_attr "type" "fpspc")
15607 (set_attr "mode" "XF")])
15609 (define_expand "atan2xf3"
15610 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15611 (unspec:XF [(match_operand:XF 2 "register_operand" "")
15612 (match_operand:XF 1 "register_operand" "")]
15614 (clobber (match_scratch:XF 3 ""))])]
15615 "TARGET_USE_FANCY_MATH_387
15616 && flag_unsafe_math_optimizations"
15619 (define_expand "atan2<mode>3"
15620 [(use (match_operand:MODEF 0 "register_operand" ""))
15621 (use (match_operand:MODEF 1 "register_operand" ""))
15622 (use (match_operand:MODEF 2 "register_operand" ""))]
15623 "TARGET_USE_FANCY_MATH_387
15624 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15625 || TARGET_MIX_SSE_I387)
15626 && flag_unsafe_math_optimizations"
15628 rtx op0 = gen_reg_rtx (XFmode);
15630 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
15631 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15635 (define_expand "atanxf2"
15636 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15637 (unspec:XF [(match_dup 2)
15638 (match_operand:XF 1 "register_operand" "")]
15640 (clobber (match_scratch:XF 3 ""))])]
15641 "TARGET_USE_FANCY_MATH_387
15642 && flag_unsafe_math_optimizations"
15644 operands[2] = gen_reg_rtx (XFmode);
15645 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15648 (define_expand "atan<mode>2"
15649 [(use (match_operand:MODEF 0 "register_operand" ""))
15650 (use (match_operand:MODEF 1 "register_operand" ""))]
15651 "TARGET_USE_FANCY_MATH_387
15652 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15653 || TARGET_MIX_SSE_I387)
15654 && flag_unsafe_math_optimizations"
15656 rtx op0 = gen_reg_rtx (XFmode);
15658 rtx op2 = gen_reg_rtx (<MODE>mode);
15659 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
15661 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
15662 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15666 (define_expand "asinxf2"
15667 [(set (match_dup 2)
15668 (mult:XF (match_operand:XF 1 "register_operand" "")
15670 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15671 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15672 (parallel [(set (match_operand:XF 0 "register_operand" "")
15673 (unspec:XF [(match_dup 5) (match_dup 1)]
15675 (clobber (match_scratch:XF 6 ""))])]
15676 "TARGET_USE_FANCY_MATH_387
15677 && flag_unsafe_math_optimizations"
15681 if (optimize_insn_for_size_p ())
15684 for (i = 2; i < 6; i++)
15685 operands[i] = gen_reg_rtx (XFmode);
15687 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15690 (define_expand "asin<mode>2"
15691 [(use (match_operand:MODEF 0 "register_operand" ""))
15692 (use (match_operand:MODEF 1 "general_operand" ""))]
15693 "TARGET_USE_FANCY_MATH_387
15694 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15695 || TARGET_MIX_SSE_I387)
15696 && flag_unsafe_math_optimizations"
15698 rtx op0 = gen_reg_rtx (XFmode);
15699 rtx op1 = gen_reg_rtx (XFmode);
15701 if (optimize_insn_for_size_p ())
15704 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15705 emit_insn (gen_asinxf2 (op0, op1));
15706 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15710 (define_expand "acosxf2"
15711 [(set (match_dup 2)
15712 (mult:XF (match_operand:XF 1 "register_operand" "")
15714 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
15715 (set (match_dup 5) (sqrt:XF (match_dup 4)))
15716 (parallel [(set (match_operand:XF 0 "register_operand" "")
15717 (unspec:XF [(match_dup 1) (match_dup 5)]
15719 (clobber (match_scratch:XF 6 ""))])]
15720 "TARGET_USE_FANCY_MATH_387
15721 && flag_unsafe_math_optimizations"
15725 if (optimize_insn_for_size_p ())
15728 for (i = 2; i < 6; i++)
15729 operands[i] = gen_reg_rtx (XFmode);
15731 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
15734 (define_expand "acos<mode>2"
15735 [(use (match_operand:MODEF 0 "register_operand" ""))
15736 (use (match_operand:MODEF 1 "general_operand" ""))]
15737 "TARGET_USE_FANCY_MATH_387
15738 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15739 || TARGET_MIX_SSE_I387)
15740 && flag_unsafe_math_optimizations"
15742 rtx op0 = gen_reg_rtx (XFmode);
15743 rtx op1 = gen_reg_rtx (XFmode);
15745 if (optimize_insn_for_size_p ())
15748 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
15749 emit_insn (gen_acosxf2 (op0, op1));
15750 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15754 (define_insn "fyl2xxf3_i387"
15755 [(set (match_operand:XF 0 "register_operand" "=f")
15756 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15757 (match_operand:XF 2 "register_operand" "u")]
15759 (clobber (match_scratch:XF 3 "=2"))]
15760 "TARGET_USE_FANCY_MATH_387
15761 && flag_unsafe_math_optimizations"
15763 [(set_attr "type" "fpspc")
15764 (set_attr "mode" "XF")])
15766 (define_insn "fyl2x_extend<mode>xf3_i387"
15767 [(set (match_operand:XF 0 "register_operand" "=f")
15768 (unspec:XF [(float_extend:XF
15769 (match_operand:MODEF 1 "register_operand" "0"))
15770 (match_operand:XF 2 "register_operand" "u")]
15772 (clobber (match_scratch:XF 3 "=2"))]
15773 "TARGET_USE_FANCY_MATH_387
15774 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15775 || TARGET_MIX_SSE_I387)
15776 && flag_unsafe_math_optimizations"
15778 [(set_attr "type" "fpspc")
15779 (set_attr "mode" "XF")])
15781 (define_expand "logxf2"
15782 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15783 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15784 (match_dup 2)] UNSPEC_FYL2X))
15785 (clobber (match_scratch:XF 3 ""))])]
15786 "TARGET_USE_FANCY_MATH_387
15787 && flag_unsafe_math_optimizations"
15789 operands[2] = gen_reg_rtx (XFmode);
15790 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
15793 (define_expand "log<mode>2"
15794 [(use (match_operand:MODEF 0 "register_operand" ""))
15795 (use (match_operand:MODEF 1 "register_operand" ""))]
15796 "TARGET_USE_FANCY_MATH_387
15797 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15798 || TARGET_MIX_SSE_I387)
15799 && flag_unsafe_math_optimizations"
15801 rtx op0 = gen_reg_rtx (XFmode);
15803 rtx op2 = gen_reg_rtx (XFmode);
15804 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
15806 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15807 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15811 (define_expand "log10xf2"
15812 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15813 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15814 (match_dup 2)] UNSPEC_FYL2X))
15815 (clobber (match_scratch:XF 3 ""))])]
15816 "TARGET_USE_FANCY_MATH_387
15817 && flag_unsafe_math_optimizations"
15819 operands[2] = gen_reg_rtx (XFmode);
15820 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
15823 (define_expand "log10<mode>2"
15824 [(use (match_operand:MODEF 0 "register_operand" ""))
15825 (use (match_operand:MODEF 1 "register_operand" ""))]
15826 "TARGET_USE_FANCY_MATH_387
15827 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15828 || TARGET_MIX_SSE_I387)
15829 && flag_unsafe_math_optimizations"
15831 rtx op0 = gen_reg_rtx (XFmode);
15833 rtx op2 = gen_reg_rtx (XFmode);
15834 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
15836 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15837 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15841 (define_expand "log2xf2"
15842 [(parallel [(set (match_operand:XF 0 "register_operand" "")
15843 (unspec:XF [(match_operand:XF 1 "register_operand" "")
15844 (match_dup 2)] UNSPEC_FYL2X))
15845 (clobber (match_scratch:XF 3 ""))])]
15846 "TARGET_USE_FANCY_MATH_387
15847 && flag_unsafe_math_optimizations"
15849 operands[2] = gen_reg_rtx (XFmode);
15850 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
15853 (define_expand "log2<mode>2"
15854 [(use (match_operand:MODEF 0 "register_operand" ""))
15855 (use (match_operand:MODEF 1 "register_operand" ""))]
15856 "TARGET_USE_FANCY_MATH_387
15857 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15858 || TARGET_MIX_SSE_I387)
15859 && flag_unsafe_math_optimizations"
15861 rtx op0 = gen_reg_rtx (XFmode);
15863 rtx op2 = gen_reg_rtx (XFmode);
15864 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
15866 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
15867 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15871 (define_insn "fyl2xp1xf3_i387"
15872 [(set (match_operand:XF 0 "register_operand" "=f")
15873 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
15874 (match_operand:XF 2 "register_operand" "u")]
15876 (clobber (match_scratch:XF 3 "=2"))]
15877 "TARGET_USE_FANCY_MATH_387
15878 && flag_unsafe_math_optimizations"
15880 [(set_attr "type" "fpspc")
15881 (set_attr "mode" "XF")])
15883 (define_insn "fyl2xp1_extend<mode>xf3_i387"
15884 [(set (match_operand:XF 0 "register_operand" "=f")
15885 (unspec:XF [(float_extend:XF
15886 (match_operand:MODEF 1 "register_operand" "0"))
15887 (match_operand:XF 2 "register_operand" "u")]
15889 (clobber (match_scratch:XF 3 "=2"))]
15890 "TARGET_USE_FANCY_MATH_387
15891 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15892 || TARGET_MIX_SSE_I387)
15893 && flag_unsafe_math_optimizations"
15895 [(set_attr "type" "fpspc")
15896 (set_attr "mode" "XF")])
15898 (define_expand "log1pxf2"
15899 [(use (match_operand:XF 0 "register_operand" ""))
15900 (use (match_operand:XF 1 "register_operand" ""))]
15901 "TARGET_USE_FANCY_MATH_387
15902 && flag_unsafe_math_optimizations"
15904 if (optimize_insn_for_size_p ())
15907 ix86_emit_i387_log1p (operands[0], operands[1]);
15911 (define_expand "log1p<mode>2"
15912 [(use (match_operand:MODEF 0 "register_operand" ""))
15913 (use (match_operand:MODEF 1 "register_operand" ""))]
15914 "TARGET_USE_FANCY_MATH_387
15915 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15916 || TARGET_MIX_SSE_I387)
15917 && flag_unsafe_math_optimizations"
15921 if (optimize_insn_for_size_p ())
15924 op0 = gen_reg_rtx (XFmode);
15926 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
15928 ix86_emit_i387_log1p (op0, operands[1]);
15929 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
15933 (define_insn "fxtractxf3_i387"
15934 [(set (match_operand:XF 0 "register_operand" "=f")
15935 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
15936 UNSPEC_XTRACT_FRACT))
15937 (set (match_operand:XF 1 "register_operand" "=u")
15938 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
15939 "TARGET_USE_FANCY_MATH_387
15940 && flag_unsafe_math_optimizations"
15942 [(set_attr "type" "fpspc")
15943 (set_attr "mode" "XF")])
15945 (define_insn "fxtract_extend<mode>xf3_i387"
15946 [(set (match_operand:XF 0 "register_operand" "=f")
15947 (unspec:XF [(float_extend:XF
15948 (match_operand:MODEF 2 "register_operand" "0"))]
15949 UNSPEC_XTRACT_FRACT))
15950 (set (match_operand:XF 1 "register_operand" "=u")
15951 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
15952 "TARGET_USE_FANCY_MATH_387
15953 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15954 || TARGET_MIX_SSE_I387)
15955 && flag_unsafe_math_optimizations"
15957 [(set_attr "type" "fpspc")
15958 (set_attr "mode" "XF")])
15960 (define_expand "logbxf2"
15961 [(parallel [(set (match_dup 2)
15962 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
15963 UNSPEC_XTRACT_FRACT))
15964 (set (match_operand:XF 0 "register_operand" "")
15965 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
15966 "TARGET_USE_FANCY_MATH_387
15967 && flag_unsafe_math_optimizations"
15969 operands[2] = gen_reg_rtx (XFmode);
15972 (define_expand "logb<mode>2"
15973 [(use (match_operand:MODEF 0 "register_operand" ""))
15974 (use (match_operand:MODEF 1 "register_operand" ""))]
15975 "TARGET_USE_FANCY_MATH_387
15976 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
15977 || TARGET_MIX_SSE_I387)
15978 && flag_unsafe_math_optimizations"
15980 rtx op0 = gen_reg_rtx (XFmode);
15981 rtx op1 = gen_reg_rtx (XFmode);
15983 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
15984 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
15988 (define_expand "ilogbxf2"
15989 [(use (match_operand:SI 0 "register_operand" ""))
15990 (use (match_operand:XF 1 "register_operand" ""))]
15991 "TARGET_USE_FANCY_MATH_387
15992 && flag_unsafe_math_optimizations"
15996 if (optimize_insn_for_size_p ())
15999 op0 = gen_reg_rtx (XFmode);
16000 op1 = gen_reg_rtx (XFmode);
16002 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
16003 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16007 (define_expand "ilogb<mode>2"
16008 [(use (match_operand:SI 0 "register_operand" ""))
16009 (use (match_operand:MODEF 1 "register_operand" ""))]
16010 "TARGET_USE_FANCY_MATH_387
16011 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16012 || TARGET_MIX_SSE_I387)
16013 && flag_unsafe_math_optimizations"
16017 if (optimize_insn_for_size_p ())
16020 op0 = gen_reg_rtx (XFmode);
16021 op1 = gen_reg_rtx (XFmode);
16023 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16024 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
16028 (define_insn "*f2xm1xf2_i387"
16029 [(set (match_operand:XF 0 "register_operand" "=f")
16030 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16032 "TARGET_USE_FANCY_MATH_387
16033 && flag_unsafe_math_optimizations"
16035 [(set_attr "type" "fpspc")
16036 (set_attr "mode" "XF")])
16038 (define_insn "*fscalexf4_i387"
16039 [(set (match_operand:XF 0 "register_operand" "=f")
16040 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
16041 (match_operand:XF 3 "register_operand" "1")]
16042 UNSPEC_FSCALE_FRACT))
16043 (set (match_operand:XF 1 "register_operand" "=u")
16044 (unspec:XF [(match_dup 2) (match_dup 3)]
16045 UNSPEC_FSCALE_EXP))]
16046 "TARGET_USE_FANCY_MATH_387
16047 && flag_unsafe_math_optimizations"
16049 [(set_attr "type" "fpspc")
16050 (set_attr "mode" "XF")])
16052 (define_expand "expNcorexf3"
16053 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16054 (match_operand:XF 2 "register_operand" "")))
16055 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16056 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16057 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16058 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
16059 (parallel [(set (match_operand:XF 0 "register_operand" "")
16060 (unspec:XF [(match_dup 8) (match_dup 4)]
16061 UNSPEC_FSCALE_FRACT))
16063 (unspec:XF [(match_dup 8) (match_dup 4)]
16064 UNSPEC_FSCALE_EXP))])]
16065 "TARGET_USE_FANCY_MATH_387
16066 && flag_unsafe_math_optimizations"
16070 if (optimize_insn_for_size_p ())
16073 for (i = 3; i < 10; i++)
16074 operands[i] = gen_reg_rtx (XFmode);
16076 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
16079 (define_expand "expxf2"
16080 [(use (match_operand:XF 0 "register_operand" ""))
16081 (use (match_operand:XF 1 "register_operand" ""))]
16082 "TARGET_USE_FANCY_MATH_387
16083 && flag_unsafe_math_optimizations"
16087 if (optimize_insn_for_size_p ())
16090 op2 = gen_reg_rtx (XFmode);
16091 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
16093 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16097 (define_expand "exp<mode>2"
16098 [(use (match_operand:MODEF 0 "register_operand" ""))
16099 (use (match_operand:MODEF 1 "general_operand" ""))]
16100 "TARGET_USE_FANCY_MATH_387
16101 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16102 || TARGET_MIX_SSE_I387)
16103 && flag_unsafe_math_optimizations"
16107 if (optimize_insn_for_size_p ())
16110 op0 = gen_reg_rtx (XFmode);
16111 op1 = gen_reg_rtx (XFmode);
16113 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16114 emit_insn (gen_expxf2 (op0, op1));
16115 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16119 (define_expand "exp10xf2"
16120 [(use (match_operand:XF 0 "register_operand" ""))
16121 (use (match_operand:XF 1 "register_operand" ""))]
16122 "TARGET_USE_FANCY_MATH_387
16123 && flag_unsafe_math_optimizations"
16127 if (optimize_insn_for_size_p ())
16130 op2 = gen_reg_rtx (XFmode);
16131 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
16133 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16137 (define_expand "exp10<mode>2"
16138 [(use (match_operand:MODEF 0 "register_operand" ""))
16139 (use (match_operand:MODEF 1 "general_operand" ""))]
16140 "TARGET_USE_FANCY_MATH_387
16141 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16142 || TARGET_MIX_SSE_I387)
16143 && flag_unsafe_math_optimizations"
16147 if (optimize_insn_for_size_p ())
16150 op0 = gen_reg_rtx (XFmode);
16151 op1 = gen_reg_rtx (XFmode);
16153 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16154 emit_insn (gen_exp10xf2 (op0, op1));
16155 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16159 (define_expand "exp2xf2"
16160 [(use (match_operand:XF 0 "register_operand" ""))
16161 (use (match_operand:XF 1 "register_operand" ""))]
16162 "TARGET_USE_FANCY_MATH_387
16163 && flag_unsafe_math_optimizations"
16167 if (optimize_insn_for_size_p ())
16170 op2 = gen_reg_rtx (XFmode);
16171 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
16173 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
16177 (define_expand "exp2<mode>2"
16178 [(use (match_operand:MODEF 0 "register_operand" ""))
16179 (use (match_operand:MODEF 1 "general_operand" ""))]
16180 "TARGET_USE_FANCY_MATH_387
16181 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16182 || TARGET_MIX_SSE_I387)
16183 && flag_unsafe_math_optimizations"
16187 if (optimize_insn_for_size_p ())
16190 op0 = gen_reg_rtx (XFmode);
16191 op1 = gen_reg_rtx (XFmode);
16193 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16194 emit_insn (gen_exp2xf2 (op0, op1));
16195 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16199 (define_expand "expm1xf2"
16200 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
16202 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
16203 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
16204 (set (match_dup 9) (float_extend:XF (match_dup 13)))
16205 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
16206 (parallel [(set (match_dup 7)
16207 (unspec:XF [(match_dup 6) (match_dup 4)]
16208 UNSPEC_FSCALE_FRACT))
16210 (unspec:XF [(match_dup 6) (match_dup 4)]
16211 UNSPEC_FSCALE_EXP))])
16212 (parallel [(set (match_dup 10)
16213 (unspec:XF [(match_dup 9) (match_dup 8)]
16214 UNSPEC_FSCALE_FRACT))
16215 (set (match_dup 11)
16216 (unspec:XF [(match_dup 9) (match_dup 8)]
16217 UNSPEC_FSCALE_EXP))])
16218 (set (match_dup 12) (minus:XF (match_dup 10)
16219 (float_extend:XF (match_dup 13))))
16220 (set (match_operand:XF 0 "register_operand" "")
16221 (plus:XF (match_dup 12) (match_dup 7)))]
16222 "TARGET_USE_FANCY_MATH_387
16223 && flag_unsafe_math_optimizations"
16227 if (optimize_insn_for_size_p ())
16230 for (i = 2; i < 13; i++)
16231 operands[i] = gen_reg_rtx (XFmode);
16234 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
16236 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
16239 (define_expand "expm1<mode>2"
16240 [(use (match_operand:MODEF 0 "register_operand" ""))
16241 (use (match_operand:MODEF 1 "general_operand" ""))]
16242 "TARGET_USE_FANCY_MATH_387
16243 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16244 || TARGET_MIX_SSE_I387)
16245 && flag_unsafe_math_optimizations"
16249 if (optimize_insn_for_size_p ())
16252 op0 = gen_reg_rtx (XFmode);
16253 op1 = gen_reg_rtx (XFmode);
16255 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16256 emit_insn (gen_expm1xf2 (op0, op1));
16257 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16261 (define_expand "ldexpxf3"
16262 [(set (match_dup 3)
16263 (float:XF (match_operand:SI 2 "register_operand" "")))
16264 (parallel [(set (match_operand:XF 0 " register_operand" "")
16265 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16267 UNSPEC_FSCALE_FRACT))
16269 (unspec:XF [(match_dup 1) (match_dup 3)]
16270 UNSPEC_FSCALE_EXP))])]
16271 "TARGET_USE_FANCY_MATH_387
16272 && flag_unsafe_math_optimizations"
16274 if (optimize_insn_for_size_p ())
16277 operands[3] = gen_reg_rtx (XFmode);
16278 operands[4] = gen_reg_rtx (XFmode);
16281 (define_expand "ldexp<mode>3"
16282 [(use (match_operand:MODEF 0 "register_operand" ""))
16283 (use (match_operand:MODEF 1 "general_operand" ""))
16284 (use (match_operand:SI 2 "register_operand" ""))]
16285 "TARGET_USE_FANCY_MATH_387
16286 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16287 || TARGET_MIX_SSE_I387)
16288 && flag_unsafe_math_optimizations"
16292 if (optimize_insn_for_size_p ())
16295 op0 = gen_reg_rtx (XFmode);
16296 op1 = gen_reg_rtx (XFmode);
16298 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16299 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
16300 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16304 (define_expand "scalbxf3"
16305 [(parallel [(set (match_operand:XF 0 " register_operand" "")
16306 (unspec:XF [(match_operand:XF 1 "register_operand" "")
16307 (match_operand:XF 2 "register_operand" "")]
16308 UNSPEC_FSCALE_FRACT))
16310 (unspec:XF [(match_dup 1) (match_dup 2)]
16311 UNSPEC_FSCALE_EXP))])]
16312 "TARGET_USE_FANCY_MATH_387
16313 && flag_unsafe_math_optimizations"
16315 if (optimize_insn_for_size_p ())
16318 operands[3] = gen_reg_rtx (XFmode);
16321 (define_expand "scalb<mode>3"
16322 [(use (match_operand:MODEF 0 "register_operand" ""))
16323 (use (match_operand:MODEF 1 "general_operand" ""))
16324 (use (match_operand:MODEF 2 "general_operand" ""))]
16325 "TARGET_USE_FANCY_MATH_387
16326 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16327 || TARGET_MIX_SSE_I387)
16328 && flag_unsafe_math_optimizations"
16332 if (optimize_insn_for_size_p ())
16335 op0 = gen_reg_rtx (XFmode);
16336 op1 = gen_reg_rtx (XFmode);
16337 op2 = gen_reg_rtx (XFmode);
16339 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16340 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
16341 emit_insn (gen_scalbxf3 (op0, op1, op2));
16342 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16346 (define_expand "significandxf2"
16347 [(parallel [(set (match_operand:XF 0 "register_operand" "")
16348 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16349 UNSPEC_XTRACT_FRACT))
16351 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
16352 "TARGET_USE_FANCY_MATH_387
16353 && flag_unsafe_math_optimizations"
16355 operands[2] = gen_reg_rtx (XFmode);
16358 (define_expand "significand<mode>2"
16359 [(use (match_operand:MODEF 0 "register_operand" ""))
16360 (use (match_operand:MODEF 1 "register_operand" ""))]
16361 "TARGET_USE_FANCY_MATH_387
16362 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16363 || TARGET_MIX_SSE_I387)
16364 && flag_unsafe_math_optimizations"
16366 rtx op0 = gen_reg_rtx (XFmode);
16367 rtx op1 = gen_reg_rtx (XFmode);
16369 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
16370 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16375 (define_insn "sse4_1_round<mode>2"
16376 [(set (match_operand:MODEF 0 "register_operand" "=x")
16377 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
16378 (match_operand:SI 2 "const_0_to_15_operand" "n")]
16381 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
16382 [(set_attr "type" "ssecvt")
16383 (set_attr "prefix_extra" "1")
16384 (set_attr "prefix" "maybe_vex")
16385 (set_attr "mode" "<MODE>")])
16387 (define_insn "rintxf2"
16388 [(set (match_operand:XF 0 "register_operand" "=f")
16389 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16391 "TARGET_USE_FANCY_MATH_387
16392 && flag_unsafe_math_optimizations"
16394 [(set_attr "type" "fpspc")
16395 (set_attr "mode" "XF")])
16397 (define_expand "rint<mode>2"
16398 [(use (match_operand:MODEF 0 "register_operand" ""))
16399 (use (match_operand:MODEF 1 "register_operand" ""))]
16400 "(TARGET_USE_FANCY_MATH_387
16401 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16402 || TARGET_MIX_SSE_I387)
16403 && flag_unsafe_math_optimizations)
16404 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16405 && !flag_trapping_math)"
16407 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16408 && !flag_trapping_math)
16410 if (!TARGET_ROUND && optimize_insn_for_size_p ())
16413 emit_insn (gen_sse4_1_round<mode>2
16414 (operands[0], operands[1], GEN_INT (0x04)));
16416 ix86_expand_rint (operand0, operand1);
16420 rtx op0 = gen_reg_rtx (XFmode);
16421 rtx op1 = gen_reg_rtx (XFmode);
16423 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16424 emit_insn (gen_rintxf2 (op0, op1));
16426 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16431 (define_expand "round<mode>2"
16432 [(match_operand:MODEF 0 "register_operand" "")
16433 (match_operand:MODEF 1 "nonimmediate_operand" "")]
16434 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16435 && !flag_trapping_math && !flag_rounding_math"
16437 if (optimize_insn_for_size_p ())
16439 if (TARGET_64BIT || (<MODE>mode != DFmode))
16440 ix86_expand_round (operand0, operand1);
16442 ix86_expand_rounddf_32 (operand0, operand1);
16446 (define_insn_and_split "*fistdi2_1"
16447 [(set (match_operand:DI 0 "nonimmediate_operand" "")
16448 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16450 "TARGET_USE_FANCY_MATH_387
16451 && can_create_pseudo_p ()"
16456 if (memory_operand (operands[0], VOIDmode))
16457 emit_insn (gen_fistdi2 (operands[0], operands[1]));
16460 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
16461 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
16466 [(set_attr "type" "fpspc")
16467 (set_attr "mode" "DI")])
16469 (define_insn "fistdi2"
16470 [(set (match_operand:DI 0 "memory_operand" "=m")
16471 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16473 (clobber (match_scratch:XF 2 "=&1f"))]
16474 "TARGET_USE_FANCY_MATH_387"
16475 "* return output_fix_trunc (insn, operands, 0);"
16476 [(set_attr "type" "fpspc")
16477 (set_attr "mode" "DI")])
16479 (define_insn "fistdi2_with_temp"
16480 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16481 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16483 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
16484 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
16485 "TARGET_USE_FANCY_MATH_387"
16487 [(set_attr "type" "fpspc")
16488 (set_attr "mode" "DI")])
16491 [(set (match_operand:DI 0 "register_operand" "")
16492 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16494 (clobber (match_operand:DI 2 "memory_operand" ""))
16495 (clobber (match_scratch 3 ""))]
16497 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16498 (clobber (match_dup 3))])
16499 (set (match_dup 0) (match_dup 2))]
16503 [(set (match_operand:DI 0 "memory_operand" "")
16504 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16506 (clobber (match_operand:DI 2 "memory_operand" ""))
16507 (clobber (match_scratch 3 ""))]
16509 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
16510 (clobber (match_dup 3))])]
16513 (define_insn_and_split "*fist<mode>2_1"
16514 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16515 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16517 "TARGET_USE_FANCY_MATH_387
16518 && can_create_pseudo_p ()"
16523 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16524 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
16528 [(set_attr "type" "fpspc")
16529 (set_attr "mode" "<MODE>")])
16531 (define_insn "fist<mode>2"
16532 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16533 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16535 "TARGET_USE_FANCY_MATH_387"
16536 "* return output_fix_trunc (insn, operands, 0);"
16537 [(set_attr "type" "fpspc")
16538 (set_attr "mode" "<MODE>")])
16540 (define_insn "fist<mode>2_with_temp"
16541 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
16542 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16544 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
16545 "TARGET_USE_FANCY_MATH_387"
16547 [(set_attr "type" "fpspc")
16548 (set_attr "mode" "<MODE>")])
16551 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16552 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16554 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16556 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
16557 (set (match_dup 0) (match_dup 2))]
16561 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16562 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16564 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
16566 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
16569 (define_expand "lrintxf<mode>2"
16570 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16571 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16573 "TARGET_USE_FANCY_MATH_387"
16576 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
16577 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16578 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
16579 UNSPEC_FIX_NOTRUNC))]
16580 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16581 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
16584 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
16585 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
16586 (match_operand:MODEF 1 "register_operand" "")]
16587 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16588 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
16589 && !flag_trapping_math && !flag_rounding_math"
16591 if (optimize_insn_for_size_p ())
16593 ix86_expand_lround (operand0, operand1);
16597 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16598 (define_insn_and_split "frndintxf2_floor"
16599 [(set (match_operand:XF 0 "register_operand" "")
16600 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16601 UNSPEC_FRNDINT_FLOOR))
16602 (clobber (reg:CC FLAGS_REG))]
16603 "TARGET_USE_FANCY_MATH_387
16604 && flag_unsafe_math_optimizations
16605 && can_create_pseudo_p ()"
16610 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16612 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16613 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16615 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
16616 operands[2], operands[3]));
16619 [(set_attr "type" "frndint")
16620 (set_attr "i387_cw" "floor")
16621 (set_attr "mode" "XF")])
16623 (define_insn "frndintxf2_floor_i387"
16624 [(set (match_operand:XF 0 "register_operand" "=f")
16625 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16626 UNSPEC_FRNDINT_FLOOR))
16627 (use (match_operand:HI 2 "memory_operand" "m"))
16628 (use (match_operand:HI 3 "memory_operand" "m"))]
16629 "TARGET_USE_FANCY_MATH_387
16630 && flag_unsafe_math_optimizations"
16631 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16632 [(set_attr "type" "frndint")
16633 (set_attr "i387_cw" "floor")
16634 (set_attr "mode" "XF")])
16636 (define_expand "floorxf2"
16637 [(use (match_operand:XF 0 "register_operand" ""))
16638 (use (match_operand:XF 1 "register_operand" ""))]
16639 "TARGET_USE_FANCY_MATH_387
16640 && flag_unsafe_math_optimizations"
16642 if (optimize_insn_for_size_p ())
16644 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
16648 (define_expand "floor<mode>2"
16649 [(use (match_operand:MODEF 0 "register_operand" ""))
16650 (use (match_operand:MODEF 1 "register_operand" ""))]
16651 "(TARGET_USE_FANCY_MATH_387
16652 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16653 || TARGET_MIX_SSE_I387)
16654 && flag_unsafe_math_optimizations)
16655 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16656 && !flag_trapping_math)"
16658 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16659 && !flag_trapping_math
16660 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16662 if (!TARGET_ROUND && optimize_insn_for_size_p ())
16665 emit_insn (gen_sse4_1_round<mode>2
16666 (operands[0], operands[1], GEN_INT (0x01)));
16667 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16668 ix86_expand_floorceil (operand0, operand1, true);
16670 ix86_expand_floorceildf_32 (operand0, operand1, true);
16676 if (optimize_insn_for_size_p ())
16679 op0 = gen_reg_rtx (XFmode);
16680 op1 = gen_reg_rtx (XFmode);
16681 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16682 emit_insn (gen_frndintxf2_floor (op0, op1));
16684 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16689 (define_insn_and_split "*fist<mode>2_floor_1"
16690 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16691 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16692 UNSPEC_FIST_FLOOR))
16693 (clobber (reg:CC FLAGS_REG))]
16694 "TARGET_USE_FANCY_MATH_387
16695 && flag_unsafe_math_optimizations
16696 && can_create_pseudo_p ()"
16701 ix86_optimize_mode_switching[I387_FLOOR] = 1;
16703 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16704 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
16705 if (memory_operand (operands[0], VOIDmode))
16706 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
16707 operands[2], operands[3]));
16710 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16711 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
16712 operands[2], operands[3],
16717 [(set_attr "type" "fistp")
16718 (set_attr "i387_cw" "floor")
16719 (set_attr "mode" "<MODE>")])
16721 (define_insn "fistdi2_floor"
16722 [(set (match_operand:DI 0 "memory_operand" "=m")
16723 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16724 UNSPEC_FIST_FLOOR))
16725 (use (match_operand:HI 2 "memory_operand" "m"))
16726 (use (match_operand:HI 3 "memory_operand" "m"))
16727 (clobber (match_scratch:XF 4 "=&1f"))]
16728 "TARGET_USE_FANCY_MATH_387
16729 && flag_unsafe_math_optimizations"
16730 "* return output_fix_trunc (insn, operands, 0);"
16731 [(set_attr "type" "fistp")
16732 (set_attr "i387_cw" "floor")
16733 (set_attr "mode" "DI")])
16735 (define_insn "fistdi2_floor_with_temp"
16736 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16737 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
16738 UNSPEC_FIST_FLOOR))
16739 (use (match_operand:HI 2 "memory_operand" "m,m"))
16740 (use (match_operand:HI 3 "memory_operand" "m,m"))
16741 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
16742 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
16743 "TARGET_USE_FANCY_MATH_387
16744 && flag_unsafe_math_optimizations"
16746 [(set_attr "type" "fistp")
16747 (set_attr "i387_cw" "floor")
16748 (set_attr "mode" "DI")])
16751 [(set (match_operand:DI 0 "register_operand" "")
16752 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16753 UNSPEC_FIST_FLOOR))
16754 (use (match_operand:HI 2 "memory_operand" ""))
16755 (use (match_operand:HI 3 "memory_operand" ""))
16756 (clobber (match_operand:DI 4 "memory_operand" ""))
16757 (clobber (match_scratch 5 ""))]
16759 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16760 (use (match_dup 2))
16761 (use (match_dup 3))
16762 (clobber (match_dup 5))])
16763 (set (match_dup 0) (match_dup 4))]
16767 [(set (match_operand:DI 0 "memory_operand" "")
16768 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
16769 UNSPEC_FIST_FLOOR))
16770 (use (match_operand:HI 2 "memory_operand" ""))
16771 (use (match_operand:HI 3 "memory_operand" ""))
16772 (clobber (match_operand:DI 4 "memory_operand" ""))
16773 (clobber (match_scratch 5 ""))]
16775 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
16776 (use (match_dup 2))
16777 (use (match_dup 3))
16778 (clobber (match_dup 5))])]
16781 (define_insn "fist<mode>2_floor"
16782 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
16783 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
16784 UNSPEC_FIST_FLOOR))
16785 (use (match_operand:HI 2 "memory_operand" "m"))
16786 (use (match_operand:HI 3 "memory_operand" "m"))]
16787 "TARGET_USE_FANCY_MATH_387
16788 && flag_unsafe_math_optimizations"
16789 "* return output_fix_trunc (insn, operands, 0);"
16790 [(set_attr "type" "fistp")
16791 (set_attr "i387_cw" "floor")
16792 (set_attr "mode" "<MODE>")])
16794 (define_insn "fist<mode>2_floor_with_temp"
16795 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
16796 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
16797 UNSPEC_FIST_FLOOR))
16798 (use (match_operand:HI 2 "memory_operand" "m,m"))
16799 (use (match_operand:HI 3 "memory_operand" "m,m"))
16800 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
16801 "TARGET_USE_FANCY_MATH_387
16802 && flag_unsafe_math_optimizations"
16804 [(set_attr "type" "fistp")
16805 (set_attr "i387_cw" "floor")
16806 (set_attr "mode" "<MODE>")])
16809 [(set (match_operand:X87MODEI12 0 "register_operand" "")
16810 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16811 UNSPEC_FIST_FLOOR))
16812 (use (match_operand:HI 2 "memory_operand" ""))
16813 (use (match_operand:HI 3 "memory_operand" ""))
16814 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16816 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
16817 UNSPEC_FIST_FLOOR))
16818 (use (match_dup 2))
16819 (use (match_dup 3))])
16820 (set (match_dup 0) (match_dup 4))]
16824 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
16825 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
16826 UNSPEC_FIST_FLOOR))
16827 (use (match_operand:HI 2 "memory_operand" ""))
16828 (use (match_operand:HI 3 "memory_operand" ""))
16829 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
16831 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
16832 UNSPEC_FIST_FLOOR))
16833 (use (match_dup 2))
16834 (use (match_dup 3))])]
16837 (define_expand "lfloorxf<mode>2"
16838 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16839 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16840 UNSPEC_FIST_FLOOR))
16841 (clobber (reg:CC FLAGS_REG))])]
16842 "TARGET_USE_FANCY_MATH_387
16843 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
16844 && flag_unsafe_math_optimizations"
16847 (define_expand "lfloor<MODEF:mode><SWI48:mode>2"
16848 [(match_operand:SWI48 0 "nonimmediate_operand" "")
16849 (match_operand:MODEF 1 "register_operand" "")]
16850 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
16851 && !flag_trapping_math"
16853 if (TARGET_64BIT && optimize_insn_for_size_p ())
16855 ix86_expand_lfloorceil (operand0, operand1, true);
16859 ;; Rounding mode control word calculation could clobber FLAGS_REG.
16860 (define_insn_and_split "frndintxf2_ceil"
16861 [(set (match_operand:XF 0 "register_operand" "")
16862 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
16863 UNSPEC_FRNDINT_CEIL))
16864 (clobber (reg:CC FLAGS_REG))]
16865 "TARGET_USE_FANCY_MATH_387
16866 && flag_unsafe_math_optimizations
16867 && can_create_pseudo_p ()"
16872 ix86_optimize_mode_switching[I387_CEIL] = 1;
16874 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16875 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16877 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
16878 operands[2], operands[3]));
16881 [(set_attr "type" "frndint")
16882 (set_attr "i387_cw" "ceil")
16883 (set_attr "mode" "XF")])
16885 (define_insn "frndintxf2_ceil_i387"
16886 [(set (match_operand:XF 0 "register_operand" "=f")
16887 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
16888 UNSPEC_FRNDINT_CEIL))
16889 (use (match_operand:HI 2 "memory_operand" "m"))
16890 (use (match_operand:HI 3 "memory_operand" "m"))]
16891 "TARGET_USE_FANCY_MATH_387
16892 && flag_unsafe_math_optimizations"
16893 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
16894 [(set_attr "type" "frndint")
16895 (set_attr "i387_cw" "ceil")
16896 (set_attr "mode" "XF")])
16898 (define_expand "ceilxf2"
16899 [(use (match_operand:XF 0 "register_operand" ""))
16900 (use (match_operand:XF 1 "register_operand" ""))]
16901 "TARGET_USE_FANCY_MATH_387
16902 && flag_unsafe_math_optimizations"
16904 if (optimize_insn_for_size_p ())
16906 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
16910 (define_expand "ceil<mode>2"
16911 [(use (match_operand:MODEF 0 "register_operand" ""))
16912 (use (match_operand:MODEF 1 "register_operand" ""))]
16913 "(TARGET_USE_FANCY_MATH_387
16914 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
16915 || TARGET_MIX_SSE_I387)
16916 && flag_unsafe_math_optimizations)
16917 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16918 && !flag_trapping_math)"
16920 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16921 && !flag_trapping_math
16922 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
16925 emit_insn (gen_sse4_1_round<mode>2
16926 (operands[0], operands[1], GEN_INT (0x02)));
16927 else if (optimize_insn_for_size_p ())
16929 else if (TARGET_64BIT || (<MODE>mode != DFmode))
16930 ix86_expand_floorceil (operand0, operand1, false);
16932 ix86_expand_floorceildf_32 (operand0, operand1, false);
16938 if (optimize_insn_for_size_p ())
16941 op0 = gen_reg_rtx (XFmode);
16942 op1 = gen_reg_rtx (XFmode);
16943 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
16944 emit_insn (gen_frndintxf2_ceil (op0, op1));
16946 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
16951 (define_insn_and_split "*fist<mode>2_ceil_1"
16952 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
16953 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
16955 (clobber (reg:CC FLAGS_REG))]
16956 "TARGET_USE_FANCY_MATH_387
16957 && flag_unsafe_math_optimizations
16958 && can_create_pseudo_p ()"
16963 ix86_optimize_mode_switching[I387_CEIL] = 1;
16965 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
16966 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
16967 if (memory_operand (operands[0], VOIDmode))
16968 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
16969 operands[2], operands[3]));
16972 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
16973 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
16974 operands[2], operands[3],
16979 [(set_attr "type" "fistp")
16980 (set_attr "i387_cw" "ceil")
16981 (set_attr "mode" "<MODE>")])
16983 (define_insn "fistdi2_ceil"
16984 [(set (match_operand:DI 0 "memory_operand" "=m")
16985 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
16987 (use (match_operand:HI 2 "memory_operand" "m"))
16988 (use (match_operand:HI 3 "memory_operand" "m"))
16989 (clobber (match_scratch:XF 4 "=&1f"))]
16990 "TARGET_USE_FANCY_MATH_387
16991 && flag_unsafe_math_optimizations"
16992 "* return output_fix_trunc (insn, operands, 0);"
16993 [(set_attr "type" "fistp")
16994 (set_attr "i387_cw" "ceil")
16995 (set_attr "mode" "DI")])
16997 (define_insn "fistdi2_ceil_with_temp"
16998 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
16999 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
17001 (use (match_operand:HI 2 "memory_operand" "m,m"))
17002 (use (match_operand:HI 3 "memory_operand" "m,m"))
17003 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
17004 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
17005 "TARGET_USE_FANCY_MATH_387
17006 && flag_unsafe_math_optimizations"
17008 [(set_attr "type" "fistp")
17009 (set_attr "i387_cw" "ceil")
17010 (set_attr "mode" "DI")])
17013 [(set (match_operand:DI 0 "register_operand" "")
17014 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17016 (use (match_operand:HI 2 "memory_operand" ""))
17017 (use (match_operand:HI 3 "memory_operand" ""))
17018 (clobber (match_operand:DI 4 "memory_operand" ""))
17019 (clobber (match_scratch 5 ""))]
17021 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17022 (use (match_dup 2))
17023 (use (match_dup 3))
17024 (clobber (match_dup 5))])
17025 (set (match_dup 0) (match_dup 4))]
17029 [(set (match_operand:DI 0 "memory_operand" "")
17030 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
17032 (use (match_operand:HI 2 "memory_operand" ""))
17033 (use (match_operand:HI 3 "memory_operand" ""))
17034 (clobber (match_operand:DI 4 "memory_operand" ""))
17035 (clobber (match_scratch 5 ""))]
17037 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
17038 (use (match_dup 2))
17039 (use (match_dup 3))
17040 (clobber (match_dup 5))])]
17043 (define_insn "fist<mode>2_ceil"
17044 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
17045 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
17047 (use (match_operand:HI 2 "memory_operand" "m"))
17048 (use (match_operand:HI 3 "memory_operand" "m"))]
17049 "TARGET_USE_FANCY_MATH_387
17050 && flag_unsafe_math_optimizations"
17051 "* return output_fix_trunc (insn, operands, 0);"
17052 [(set_attr "type" "fistp")
17053 (set_attr "i387_cw" "ceil")
17054 (set_attr "mode" "<MODE>")])
17056 (define_insn "fist<mode>2_ceil_with_temp"
17057 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
17058 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
17060 (use (match_operand:HI 2 "memory_operand" "m,m"))
17061 (use (match_operand:HI 3 "memory_operand" "m,m"))
17062 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
17063 "TARGET_USE_FANCY_MATH_387
17064 && flag_unsafe_math_optimizations"
17066 [(set_attr "type" "fistp")
17067 (set_attr "i387_cw" "ceil")
17068 (set_attr "mode" "<MODE>")])
17071 [(set (match_operand:X87MODEI12 0 "register_operand" "")
17072 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17074 (use (match_operand:HI 2 "memory_operand" ""))
17075 (use (match_operand:HI 3 "memory_operand" ""))
17076 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17078 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
17080 (use (match_dup 2))
17081 (use (match_dup 3))])
17082 (set (match_dup 0) (match_dup 4))]
17086 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
17087 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
17089 (use (match_operand:HI 2 "memory_operand" ""))
17090 (use (match_operand:HI 3 "memory_operand" ""))
17091 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
17093 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
17095 (use (match_dup 2))
17096 (use (match_dup 3))])]
17099 (define_expand "lceilxf<mode>2"
17100 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
17101 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
17103 (clobber (reg:CC FLAGS_REG))])]
17104 "TARGET_USE_FANCY_MATH_387
17105 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
17106 && flag_unsafe_math_optimizations"
17109 (define_expand "lceil<MODEF:mode><SWI48:mode>2"
17110 [(match_operand:SWI48 0 "nonimmediate_operand" "")
17111 (match_operand:MODEF 1 "register_operand" "")]
17112 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
17113 && !flag_trapping_math"
17115 ix86_expand_lfloorceil (operand0, operand1, false);
17119 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17120 (define_insn_and_split "frndintxf2_trunc"
17121 [(set (match_operand:XF 0 "register_operand" "")
17122 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17123 UNSPEC_FRNDINT_TRUNC))
17124 (clobber (reg:CC FLAGS_REG))]
17125 "TARGET_USE_FANCY_MATH_387
17126 && flag_unsafe_math_optimizations
17127 && can_create_pseudo_p ()"
17132 ix86_optimize_mode_switching[I387_TRUNC] = 1;
17134 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17135 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
17137 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
17138 operands[2], operands[3]));
17141 [(set_attr "type" "frndint")
17142 (set_attr "i387_cw" "trunc")
17143 (set_attr "mode" "XF")])
17145 (define_insn "frndintxf2_trunc_i387"
17146 [(set (match_operand:XF 0 "register_operand" "=f")
17147 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17148 UNSPEC_FRNDINT_TRUNC))
17149 (use (match_operand:HI 2 "memory_operand" "m"))
17150 (use (match_operand:HI 3 "memory_operand" "m"))]
17151 "TARGET_USE_FANCY_MATH_387
17152 && flag_unsafe_math_optimizations"
17153 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
17154 [(set_attr "type" "frndint")
17155 (set_attr "i387_cw" "trunc")
17156 (set_attr "mode" "XF")])
17158 (define_expand "btruncxf2"
17159 [(use (match_operand:XF 0 "register_operand" ""))
17160 (use (match_operand:XF 1 "register_operand" ""))]
17161 "TARGET_USE_FANCY_MATH_387
17162 && flag_unsafe_math_optimizations"
17164 if (optimize_insn_for_size_p ())
17166 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
17170 (define_expand "btrunc<mode>2"
17171 [(use (match_operand:MODEF 0 "register_operand" ""))
17172 (use (match_operand:MODEF 1 "register_operand" ""))]
17173 "(TARGET_USE_FANCY_MATH_387
17174 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17175 || TARGET_MIX_SSE_I387)
17176 && flag_unsafe_math_optimizations)
17177 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17178 && !flag_trapping_math)"
17180 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17181 && !flag_trapping_math
17182 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
17185 emit_insn (gen_sse4_1_round<mode>2
17186 (operands[0], operands[1], GEN_INT (0x03)));
17187 else if (optimize_insn_for_size_p ())
17189 else if (TARGET_64BIT || (<MODE>mode != DFmode))
17190 ix86_expand_trunc (operand0, operand1);
17192 ix86_expand_truncdf_32 (operand0, operand1);
17198 if (optimize_insn_for_size_p ())
17201 op0 = gen_reg_rtx (XFmode);
17202 op1 = gen_reg_rtx (XFmode);
17203 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17204 emit_insn (gen_frndintxf2_trunc (op0, op1));
17206 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17211 ;; Rounding mode control word calculation could clobber FLAGS_REG.
17212 (define_insn_and_split "frndintxf2_mask_pm"
17213 [(set (match_operand:XF 0 "register_operand" "")
17214 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
17215 UNSPEC_FRNDINT_MASK_PM))
17216 (clobber (reg:CC FLAGS_REG))]
17217 "TARGET_USE_FANCY_MATH_387
17218 && flag_unsafe_math_optimizations
17219 && can_create_pseudo_p ()"
17224 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
17226 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
17227 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
17229 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
17230 operands[2], operands[3]));
17233 [(set_attr "type" "frndint")
17234 (set_attr "i387_cw" "mask_pm")
17235 (set_attr "mode" "XF")])
17237 (define_insn "frndintxf2_mask_pm_i387"
17238 [(set (match_operand:XF 0 "register_operand" "=f")
17239 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
17240 UNSPEC_FRNDINT_MASK_PM))
17241 (use (match_operand:HI 2 "memory_operand" "m"))
17242 (use (match_operand:HI 3 "memory_operand" "m"))]
17243 "TARGET_USE_FANCY_MATH_387
17244 && flag_unsafe_math_optimizations"
17245 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
17246 [(set_attr "type" "frndint")
17247 (set_attr "i387_cw" "mask_pm")
17248 (set_attr "mode" "XF")])
17250 (define_expand "nearbyintxf2"
17251 [(use (match_operand:XF 0 "register_operand" ""))
17252 (use (match_operand:XF 1 "register_operand" ""))]
17253 "TARGET_USE_FANCY_MATH_387
17254 && flag_unsafe_math_optimizations"
17256 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
17261 (define_expand "nearbyint<mode>2"
17262 [(use (match_operand:MODEF 0 "register_operand" ""))
17263 (use (match_operand:MODEF 1 "register_operand" ""))]
17264 "TARGET_USE_FANCY_MATH_387
17265 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17266 || TARGET_MIX_SSE_I387)
17267 && flag_unsafe_math_optimizations"
17269 rtx op0 = gen_reg_rtx (XFmode);
17270 rtx op1 = gen_reg_rtx (XFmode);
17272 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17273 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
17275 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17279 (define_insn "fxam<mode>2_i387"
17280 [(set (match_operand:HI 0 "register_operand" "=a")
17282 [(match_operand:X87MODEF 1 "register_operand" "f")]
17284 "TARGET_USE_FANCY_MATH_387"
17285 "fxam\n\tfnstsw\t%0"
17286 [(set_attr "type" "multi")
17287 (set_attr "length" "4")
17288 (set_attr "unit" "i387")
17289 (set_attr "mode" "<MODE>")])
17291 (define_insn_and_split "fxam<mode>2_i387_with_temp"
17292 [(set (match_operand:HI 0 "register_operand" "")
17294 [(match_operand:MODEF 1 "memory_operand" "")]
17296 "TARGET_USE_FANCY_MATH_387
17297 && can_create_pseudo_p ()"
17300 [(set (match_dup 2)(match_dup 1))
17302 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
17304 operands[2] = gen_reg_rtx (<MODE>mode);
17306 MEM_VOLATILE_P (operands[1]) = 1;
17308 [(set_attr "type" "multi")
17309 (set_attr "unit" "i387")
17310 (set_attr "mode" "<MODE>")])
17312 (define_expand "isinfxf2"
17313 [(use (match_operand:SI 0 "register_operand" ""))
17314 (use (match_operand:XF 1 "register_operand" ""))]
17315 "TARGET_USE_FANCY_MATH_387
17316 && TARGET_C99_FUNCTIONS"
17318 rtx mask = GEN_INT (0x45);
17319 rtx val = GEN_INT (0x05);
17323 rtx scratch = gen_reg_rtx (HImode);
17324 rtx res = gen_reg_rtx (QImode);
17326 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
17328 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17329 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17330 cond = gen_rtx_fmt_ee (EQ, QImode,
17331 gen_rtx_REG (CCmode, FLAGS_REG),
17333 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17334 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17338 (define_expand "isinf<mode>2"
17339 [(use (match_operand:SI 0 "register_operand" ""))
17340 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
17341 "TARGET_USE_FANCY_MATH_387
17342 && TARGET_C99_FUNCTIONS
17343 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17345 rtx mask = GEN_INT (0x45);
17346 rtx val = GEN_INT (0x05);
17350 rtx scratch = gen_reg_rtx (HImode);
17351 rtx res = gen_reg_rtx (QImode);
17353 /* Remove excess precision by forcing value through memory. */
17354 if (memory_operand (operands[1], VOIDmode))
17355 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
17358 enum ix86_stack_slot slot = (virtuals_instantiated
17361 rtx temp = assign_386_stack_local (<MODE>mode, slot);
17363 emit_move_insn (temp, operands[1]);
17364 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
17367 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
17368 emit_insn (gen_cmpqi_ext_3 (scratch, val));
17369 cond = gen_rtx_fmt_ee (EQ, QImode,
17370 gen_rtx_REG (CCmode, FLAGS_REG),
17372 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
17373 emit_insn (gen_zero_extendqisi2 (operands[0], res));
17377 (define_expand "signbit<mode>2"
17378 [(use (match_operand:SI 0 "register_operand" ""))
17379 (use (match_operand:X87MODEF 1 "register_operand" ""))]
17380 "TARGET_USE_FANCY_MATH_387
17381 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17383 rtx mask = GEN_INT (0x0200);
17385 rtx scratch = gen_reg_rtx (HImode);
17387 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
17388 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
17392 ;; Block operation instructions
17395 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
17398 [(set_attr "length" "1")
17399 (set_attr "length_immediate" "0")
17400 (set_attr "modrm" "0")])
17402 (define_expand "movmemsi"
17403 [(use (match_operand:BLK 0 "memory_operand" ""))
17404 (use (match_operand:BLK 1 "memory_operand" ""))
17405 (use (match_operand:SI 2 "nonmemory_operand" ""))
17406 (use (match_operand:SI 3 "const_int_operand" ""))
17407 (use (match_operand:SI 4 "const_int_operand" ""))
17408 (use (match_operand:SI 5 "const_int_operand" ""))]
17411 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17412 operands[4], operands[5]))
17418 (define_expand "movmemdi"
17419 [(use (match_operand:BLK 0 "memory_operand" ""))
17420 (use (match_operand:BLK 1 "memory_operand" ""))
17421 (use (match_operand:DI 2 "nonmemory_operand" ""))
17422 (use (match_operand:DI 3 "const_int_operand" ""))
17423 (use (match_operand:SI 4 "const_int_operand" ""))
17424 (use (match_operand:SI 5 "const_int_operand" ""))]
17427 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
17428 operands[4], operands[5]))
17434 ;; Most CPUs don't like single string operations
17435 ;; Handle this case here to simplify previous expander.
17437 (define_expand "strmov"
17438 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
17439 (set (match_operand 1 "memory_operand" "") (match_dup 4))
17440 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
17441 (clobber (reg:CC FLAGS_REG))])
17442 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
17443 (clobber (reg:CC FLAGS_REG))])]
17446 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
17448 /* If .md ever supports :P for Pmode, these can be directly
17449 in the pattern above. */
17450 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
17451 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
17453 /* Can't use this if the user has appropriated esi or edi. */
17454 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17455 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
17457 emit_insn (gen_strmov_singleop (operands[0], operands[1],
17458 operands[2], operands[3],
17459 operands[5], operands[6]));
17463 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
17466 (define_expand "strmov_singleop"
17467 [(parallel [(set (match_operand 1 "memory_operand" "")
17468 (match_operand 3 "memory_operand" ""))
17469 (set (match_operand 0 "register_operand" "")
17470 (match_operand 4 "" ""))
17471 (set (match_operand 2 "register_operand" "")
17472 (match_operand 5 "" ""))])]
17474 "ix86_current_function_needs_cld = 1;")
17476 (define_insn "*strmovdi_rex_1"
17477 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
17478 (mem:DI (match_operand:DI 3 "register_operand" "1")))
17479 (set (match_operand:DI 0 "register_operand" "=D")
17480 (plus:DI (match_dup 2)
17482 (set (match_operand:DI 1 "register_operand" "=S")
17483 (plus:DI (match_dup 3)
17487 [(set_attr "type" "str")
17488 (set_attr "mode" "DI")
17489 (set_attr "memory" "both")])
17491 (define_insn "*strmovsi_1"
17492 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
17493 (mem:SI (match_operand:SI 3 "register_operand" "1")))
17494 (set (match_operand:SI 0 "register_operand" "=D")
17495 (plus:SI (match_dup 2)
17497 (set (match_operand:SI 1 "register_operand" "=S")
17498 (plus:SI (match_dup 3)
17502 [(set_attr "type" "str")
17503 (set_attr "mode" "SI")
17504 (set_attr "memory" "both")])
17506 (define_insn "*strmovsi_rex_1"
17507 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
17508 (mem:SI (match_operand:DI 3 "register_operand" "1")))
17509 (set (match_operand:DI 0 "register_operand" "=D")
17510 (plus:DI (match_dup 2)
17512 (set (match_operand:DI 1 "register_operand" "=S")
17513 (plus:DI (match_dup 3)
17517 [(set_attr "type" "str")
17518 (set_attr "mode" "SI")
17519 (set_attr "memory" "both")])
17521 (define_insn "*strmovhi_1"
17522 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
17523 (mem:HI (match_operand:SI 3 "register_operand" "1")))
17524 (set (match_operand:SI 0 "register_operand" "=D")
17525 (plus:SI (match_dup 2)
17527 (set (match_operand:SI 1 "register_operand" "=S")
17528 (plus:SI (match_dup 3)
17532 [(set_attr "type" "str")
17533 (set_attr "memory" "both")
17534 (set_attr "mode" "HI")])
17536 (define_insn "*strmovhi_rex_1"
17537 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
17538 (mem:HI (match_operand:DI 3 "register_operand" "1")))
17539 (set (match_operand:DI 0 "register_operand" "=D")
17540 (plus:DI (match_dup 2)
17542 (set (match_operand:DI 1 "register_operand" "=S")
17543 (plus:DI (match_dup 3)
17547 [(set_attr "type" "str")
17548 (set_attr "memory" "both")
17549 (set_attr "mode" "HI")])
17551 (define_insn "*strmovqi_1"
17552 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
17553 (mem:QI (match_operand:SI 3 "register_operand" "1")))
17554 (set (match_operand:SI 0 "register_operand" "=D")
17555 (plus:SI (match_dup 2)
17557 (set (match_operand:SI 1 "register_operand" "=S")
17558 (plus:SI (match_dup 3)
17562 [(set_attr "type" "str")
17563 (set_attr "memory" "both")
17564 (set_attr "mode" "QI")])
17566 (define_insn "*strmovqi_rex_1"
17567 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
17568 (mem:QI (match_operand:DI 3 "register_operand" "1")))
17569 (set (match_operand:DI 0 "register_operand" "=D")
17570 (plus:DI (match_dup 2)
17572 (set (match_operand:DI 1 "register_operand" "=S")
17573 (plus:DI (match_dup 3)
17577 [(set_attr "type" "str")
17578 (set_attr "memory" "both")
17579 (set_attr "prefix_rex" "0")
17580 (set_attr "mode" "QI")])
17582 (define_expand "rep_mov"
17583 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
17584 (set (match_operand 0 "register_operand" "")
17585 (match_operand 5 "" ""))
17586 (set (match_operand 2 "register_operand" "")
17587 (match_operand 6 "" ""))
17588 (set (match_operand 1 "memory_operand" "")
17589 (match_operand 3 "memory_operand" ""))
17590 (use (match_dup 4))])]
17592 "ix86_current_function_needs_cld = 1;")
17594 (define_insn "*rep_movdi_rex64"
17595 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17596 (set (match_operand:DI 0 "register_operand" "=D")
17597 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17599 (match_operand:DI 3 "register_operand" "0")))
17600 (set (match_operand:DI 1 "register_operand" "=S")
17601 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
17602 (match_operand:DI 4 "register_operand" "1")))
17603 (set (mem:BLK (match_dup 3))
17604 (mem:BLK (match_dup 4)))
17605 (use (match_dup 5))]
17608 [(set_attr "type" "str")
17609 (set_attr "prefix_rep" "1")
17610 (set_attr "memory" "both")
17611 (set_attr "mode" "DI")])
17613 (define_insn "*rep_movsi"
17614 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17615 (set (match_operand:SI 0 "register_operand" "=D")
17616 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
17618 (match_operand:SI 3 "register_operand" "0")))
17619 (set (match_operand:SI 1 "register_operand" "=S")
17620 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
17621 (match_operand:SI 4 "register_operand" "1")))
17622 (set (mem:BLK (match_dup 3))
17623 (mem:BLK (match_dup 4)))
17624 (use (match_dup 5))]
17627 [(set_attr "type" "str")
17628 (set_attr "prefix_rep" "1")
17629 (set_attr "memory" "both")
17630 (set_attr "mode" "SI")])
17632 (define_insn "*rep_movsi_rex64"
17633 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17634 (set (match_operand:DI 0 "register_operand" "=D")
17635 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
17637 (match_operand:DI 3 "register_operand" "0")))
17638 (set (match_operand:DI 1 "register_operand" "=S")
17639 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
17640 (match_operand:DI 4 "register_operand" "1")))
17641 (set (mem:BLK (match_dup 3))
17642 (mem:BLK (match_dup 4)))
17643 (use (match_dup 5))]
17646 [(set_attr "type" "str")
17647 (set_attr "prefix_rep" "1")
17648 (set_attr "memory" "both")
17649 (set_attr "mode" "SI")])
17651 (define_insn "*rep_movqi"
17652 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
17653 (set (match_operand:SI 0 "register_operand" "=D")
17654 (plus:SI (match_operand:SI 3 "register_operand" "0")
17655 (match_operand:SI 5 "register_operand" "2")))
17656 (set (match_operand:SI 1 "register_operand" "=S")
17657 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
17658 (set (mem:BLK (match_dup 3))
17659 (mem:BLK (match_dup 4)))
17660 (use (match_dup 5))]
17663 [(set_attr "type" "str")
17664 (set_attr "prefix_rep" "1")
17665 (set_attr "memory" "both")
17666 (set_attr "mode" "SI")])
17668 (define_insn "*rep_movqi_rex64"
17669 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
17670 (set (match_operand:DI 0 "register_operand" "=D")
17671 (plus:DI (match_operand:DI 3 "register_operand" "0")
17672 (match_operand:DI 5 "register_operand" "2")))
17673 (set (match_operand:DI 1 "register_operand" "=S")
17674 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
17675 (set (mem:BLK (match_dup 3))
17676 (mem:BLK (match_dup 4)))
17677 (use (match_dup 5))]
17680 [(set_attr "type" "str")
17681 (set_attr "prefix_rep" "1")
17682 (set_attr "memory" "both")
17683 (set_attr "mode" "SI")])
17685 (define_expand "setmemsi"
17686 [(use (match_operand:BLK 0 "memory_operand" ""))
17687 (use (match_operand:SI 1 "nonmemory_operand" ""))
17688 (use (match_operand 2 "const_int_operand" ""))
17689 (use (match_operand 3 "const_int_operand" ""))
17690 (use (match_operand:SI 4 "const_int_operand" ""))
17691 (use (match_operand:SI 5 "const_int_operand" ""))]
17694 if (ix86_expand_setmem (operands[0], operands[1],
17695 operands[2], operands[3],
17696 operands[4], operands[5]))
17702 (define_expand "setmemdi"
17703 [(use (match_operand:BLK 0 "memory_operand" ""))
17704 (use (match_operand:DI 1 "nonmemory_operand" ""))
17705 (use (match_operand 2 "const_int_operand" ""))
17706 (use (match_operand 3 "const_int_operand" ""))
17707 (use (match_operand 4 "const_int_operand" ""))
17708 (use (match_operand 5 "const_int_operand" ""))]
17711 if (ix86_expand_setmem (operands[0], operands[1],
17712 operands[2], operands[3],
17713 operands[4], operands[5]))
17719 ;; Most CPUs don't like single string operations
17720 ;; Handle this case here to simplify previous expander.
17722 (define_expand "strset"
17723 [(set (match_operand 1 "memory_operand" "")
17724 (match_operand 2 "register_operand" ""))
17725 (parallel [(set (match_operand 0 "register_operand" "")
17727 (clobber (reg:CC FLAGS_REG))])]
17730 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
17731 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
17733 /* If .md ever supports :P for Pmode, this can be directly
17734 in the pattern above. */
17735 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
17736 GEN_INT (GET_MODE_SIZE (GET_MODE
17738 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
17740 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
17746 (define_expand "strset_singleop"
17747 [(parallel [(set (match_operand 1 "memory_operand" "")
17748 (match_operand 2 "register_operand" ""))
17749 (set (match_operand 0 "register_operand" "")
17750 (match_operand 3 "" ""))])]
17752 "ix86_current_function_needs_cld = 1;")
17754 (define_insn "*strsetdi_rex_1"
17755 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
17756 (match_operand:DI 2 "register_operand" "a"))
17757 (set (match_operand:DI 0 "register_operand" "=D")
17758 (plus:DI (match_dup 1)
17762 [(set_attr "type" "str")
17763 (set_attr "memory" "store")
17764 (set_attr "mode" "DI")])
17766 (define_insn "*strsetsi_1"
17767 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
17768 (match_operand:SI 2 "register_operand" "a"))
17769 (set (match_operand:SI 0 "register_operand" "=D")
17770 (plus:SI (match_dup 1)
17774 [(set_attr "type" "str")
17775 (set_attr "memory" "store")
17776 (set_attr "mode" "SI")])
17778 (define_insn "*strsetsi_rex_1"
17779 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
17780 (match_operand:SI 2 "register_operand" "a"))
17781 (set (match_operand:DI 0 "register_operand" "=D")
17782 (plus:DI (match_dup 1)
17786 [(set_attr "type" "str")
17787 (set_attr "memory" "store")
17788 (set_attr "mode" "SI")])
17790 (define_insn "*strsethi_1"
17791 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
17792 (match_operand:HI 2 "register_operand" "a"))
17793 (set (match_operand:SI 0 "register_operand" "=D")
17794 (plus:SI (match_dup 1)
17798 [(set_attr "type" "str")
17799 (set_attr "memory" "store")
17800 (set_attr "mode" "HI")])
17802 (define_insn "*strsethi_rex_1"
17803 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
17804 (match_operand:HI 2 "register_operand" "a"))
17805 (set (match_operand:DI 0 "register_operand" "=D")
17806 (plus:DI (match_dup 1)
17810 [(set_attr "type" "str")
17811 (set_attr "memory" "store")
17812 (set_attr "mode" "HI")])
17814 (define_insn "*strsetqi_1"
17815 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
17816 (match_operand:QI 2 "register_operand" "a"))
17817 (set (match_operand:SI 0 "register_operand" "=D")
17818 (plus:SI (match_dup 1)
17822 [(set_attr "type" "str")
17823 (set_attr "memory" "store")
17824 (set_attr "mode" "QI")])
17826 (define_insn "*strsetqi_rex_1"
17827 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
17828 (match_operand:QI 2 "register_operand" "a"))
17829 (set (match_operand:DI 0 "register_operand" "=D")
17830 (plus:DI (match_dup 1)
17834 [(set_attr "type" "str")
17835 (set_attr "memory" "store")
17836 (set_attr "prefix_rex" "0")
17837 (set_attr "mode" "QI")])
17839 (define_expand "rep_stos"
17840 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
17841 (set (match_operand 0 "register_operand" "")
17842 (match_operand 4 "" ""))
17843 (set (match_operand 2 "memory_operand" "") (const_int 0))
17844 (use (match_operand 3 "register_operand" ""))
17845 (use (match_dup 1))])]
17847 "ix86_current_function_needs_cld = 1;")
17849 (define_insn "*rep_stosdi_rex64"
17850 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17851 (set (match_operand:DI 0 "register_operand" "=D")
17852 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17854 (match_operand:DI 3 "register_operand" "0")))
17855 (set (mem:BLK (match_dup 3))
17857 (use (match_operand:DI 2 "register_operand" "a"))
17858 (use (match_dup 4))]
17861 [(set_attr "type" "str")
17862 (set_attr "prefix_rep" "1")
17863 (set_attr "memory" "store")
17864 (set_attr "mode" "DI")])
17866 (define_insn "*rep_stossi"
17867 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17868 (set (match_operand:SI 0 "register_operand" "=D")
17869 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
17871 (match_operand:SI 3 "register_operand" "0")))
17872 (set (mem:BLK (match_dup 3))
17874 (use (match_operand:SI 2 "register_operand" "a"))
17875 (use (match_dup 4))]
17878 [(set_attr "type" "str")
17879 (set_attr "prefix_rep" "1")
17880 (set_attr "memory" "store")
17881 (set_attr "mode" "SI")])
17883 (define_insn "*rep_stossi_rex64"
17884 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17885 (set (match_operand:DI 0 "register_operand" "=D")
17886 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
17888 (match_operand:DI 3 "register_operand" "0")))
17889 (set (mem:BLK (match_dup 3))
17891 (use (match_operand:SI 2 "register_operand" "a"))
17892 (use (match_dup 4))]
17895 [(set_attr "type" "str")
17896 (set_attr "prefix_rep" "1")
17897 (set_attr "memory" "store")
17898 (set_attr "mode" "SI")])
17900 (define_insn "*rep_stosqi"
17901 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
17902 (set (match_operand:SI 0 "register_operand" "=D")
17903 (plus:SI (match_operand:SI 3 "register_operand" "0")
17904 (match_operand:SI 4 "register_operand" "1")))
17905 (set (mem:BLK (match_dup 3))
17907 (use (match_operand:QI 2 "register_operand" "a"))
17908 (use (match_dup 4))]
17911 [(set_attr "type" "str")
17912 (set_attr "prefix_rep" "1")
17913 (set_attr "memory" "store")
17914 (set_attr "mode" "QI")])
17916 (define_insn "*rep_stosqi_rex64"
17917 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
17918 (set (match_operand:DI 0 "register_operand" "=D")
17919 (plus:DI (match_operand:DI 3 "register_operand" "0")
17920 (match_operand:DI 4 "register_operand" "1")))
17921 (set (mem:BLK (match_dup 3))
17923 (use (match_operand:QI 2 "register_operand" "a"))
17924 (use (match_dup 4))]
17927 [(set_attr "type" "str")
17928 (set_attr "prefix_rep" "1")
17929 (set_attr "memory" "store")
17930 (set_attr "prefix_rex" "0")
17931 (set_attr "mode" "QI")])
17933 (define_expand "cmpstrnsi"
17934 [(set (match_operand:SI 0 "register_operand" "")
17935 (compare:SI (match_operand:BLK 1 "general_operand" "")
17936 (match_operand:BLK 2 "general_operand" "")))
17937 (use (match_operand 3 "general_operand" ""))
17938 (use (match_operand 4 "immediate_operand" ""))]
17941 rtx addr1, addr2, out, outlow, count, countreg, align;
17943 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
17946 /* Can't use this if the user has appropriated esi or edi. */
17947 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
17952 out = gen_reg_rtx (SImode);
17954 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
17955 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
17956 if (addr1 != XEXP (operands[1], 0))
17957 operands[1] = replace_equiv_address_nv (operands[1], addr1);
17958 if (addr2 != XEXP (operands[2], 0))
17959 operands[2] = replace_equiv_address_nv (operands[2], addr2);
17961 count = operands[3];
17962 countreg = ix86_zero_extend_to_Pmode (count);
17964 /* %%% Iff we are testing strict equality, we can use known alignment
17965 to good advantage. This may be possible with combine, particularly
17966 once cc0 is dead. */
17967 align = operands[4];
17969 if (CONST_INT_P (count))
17971 if (INTVAL (count) == 0)
17973 emit_move_insn (operands[0], const0_rtx);
17976 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
17977 operands[1], operands[2]));
17981 rtx (*cmp_insn)(rtx, rtx);
17984 cmp_insn = gen_cmpdi_1;
17986 cmp_insn = gen_cmpsi_1;
17987 emit_insn (cmp_insn (countreg, countreg));
17988 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
17989 operands[1], operands[2]));
17992 outlow = gen_lowpart (QImode, out);
17993 emit_insn (gen_cmpintqi (outlow));
17994 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
17996 if (operands[0] != out)
17997 emit_move_insn (operands[0], out);
18002 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
18004 (define_expand "cmpintqi"
18005 [(set (match_dup 1)
18006 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18008 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18009 (parallel [(set (match_operand:QI 0 "register_operand" "")
18010 (minus:QI (match_dup 1)
18012 (clobber (reg:CC FLAGS_REG))])]
18014 "operands[1] = gen_reg_rtx (QImode);
18015 operands[2] = gen_reg_rtx (QImode);")
18017 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
18018 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
18020 (define_expand "cmpstrnqi_nz_1"
18021 [(parallel [(set (reg:CC FLAGS_REG)
18022 (compare:CC (match_operand 4 "memory_operand" "")
18023 (match_operand 5 "memory_operand" "")))
18024 (use (match_operand 2 "register_operand" ""))
18025 (use (match_operand:SI 3 "immediate_operand" ""))
18026 (clobber (match_operand 0 "register_operand" ""))
18027 (clobber (match_operand 1 "register_operand" ""))
18028 (clobber (match_dup 2))])]
18030 "ix86_current_function_needs_cld = 1;")
18032 (define_insn "*cmpstrnqi_nz_1"
18033 [(set (reg:CC FLAGS_REG)
18034 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18035 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
18036 (use (match_operand:SI 6 "register_operand" "2"))
18037 (use (match_operand:SI 3 "immediate_operand" "i"))
18038 (clobber (match_operand:SI 0 "register_operand" "=S"))
18039 (clobber (match_operand:SI 1 "register_operand" "=D"))
18040 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18043 [(set_attr "type" "str")
18044 (set_attr "mode" "QI")
18045 (set_attr "prefix_rep" "1")])
18047 (define_insn "*cmpstrnqi_nz_rex_1"
18048 [(set (reg:CC FLAGS_REG)
18049 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18050 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
18051 (use (match_operand:DI 6 "register_operand" "2"))
18052 (use (match_operand:SI 3 "immediate_operand" "i"))
18053 (clobber (match_operand:DI 0 "register_operand" "=S"))
18054 (clobber (match_operand:DI 1 "register_operand" "=D"))
18055 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18058 [(set_attr "type" "str")
18059 (set_attr "mode" "QI")
18060 (set_attr "prefix_rex" "0")
18061 (set_attr "prefix_rep" "1")])
18063 ;; The same, but the count is not known to not be zero.
18065 (define_expand "cmpstrnqi_1"
18066 [(parallel [(set (reg:CC FLAGS_REG)
18067 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
18069 (compare:CC (match_operand 4 "memory_operand" "")
18070 (match_operand 5 "memory_operand" ""))
18072 (use (match_operand:SI 3 "immediate_operand" ""))
18073 (use (reg:CC FLAGS_REG))
18074 (clobber (match_operand 0 "register_operand" ""))
18075 (clobber (match_operand 1 "register_operand" ""))
18076 (clobber (match_dup 2))])]
18078 "ix86_current_function_needs_cld = 1;")
18080 (define_insn "*cmpstrnqi_1"
18081 [(set (reg:CC FLAGS_REG)
18082 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
18084 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
18085 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
18087 (use (match_operand:SI 3 "immediate_operand" "i"))
18088 (use (reg:CC FLAGS_REG))
18089 (clobber (match_operand:SI 0 "register_operand" "=S"))
18090 (clobber (match_operand:SI 1 "register_operand" "=D"))
18091 (clobber (match_operand:SI 2 "register_operand" "=c"))]
18094 [(set_attr "type" "str")
18095 (set_attr "mode" "QI")
18096 (set_attr "prefix_rep" "1")])
18098 (define_insn "*cmpstrnqi_rex_1"
18099 [(set (reg:CC FLAGS_REG)
18100 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
18102 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
18103 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
18105 (use (match_operand:SI 3 "immediate_operand" "i"))
18106 (use (reg:CC FLAGS_REG))
18107 (clobber (match_operand:DI 0 "register_operand" "=S"))
18108 (clobber (match_operand:DI 1 "register_operand" "=D"))
18109 (clobber (match_operand:DI 2 "register_operand" "=c"))]
18112 [(set_attr "type" "str")
18113 (set_attr "mode" "QI")
18114 (set_attr "prefix_rex" "0")
18115 (set_attr "prefix_rep" "1")])
18117 (define_expand "strlensi"
18118 [(set (match_operand:SI 0 "register_operand" "")
18119 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
18120 (match_operand:QI 2 "immediate_operand" "")
18121 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18124 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18130 (define_expand "strlendi"
18131 [(set (match_operand:DI 0 "register_operand" "")
18132 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
18133 (match_operand:QI 2 "immediate_operand" "")
18134 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
18137 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
18143 (define_expand "strlenqi_1"
18144 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
18145 (clobber (match_operand 1 "register_operand" ""))
18146 (clobber (reg:CC FLAGS_REG))])]
18148 "ix86_current_function_needs_cld = 1;")
18150 (define_insn "*strlenqi_1"
18151 [(set (match_operand:SI 0 "register_operand" "=&c")
18152 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
18153 (match_operand:QI 2 "register_operand" "a")
18154 (match_operand:SI 3 "immediate_operand" "i")
18155 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
18156 (clobber (match_operand:SI 1 "register_operand" "=D"))
18157 (clobber (reg:CC FLAGS_REG))]
18160 [(set_attr "type" "str")
18161 (set_attr "mode" "QI")
18162 (set_attr "prefix_rep" "1")])
18164 (define_insn "*strlenqi_rex_1"
18165 [(set (match_operand:DI 0 "register_operand" "=&c")
18166 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
18167 (match_operand:QI 2 "register_operand" "a")
18168 (match_operand:DI 3 "immediate_operand" "i")
18169 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
18170 (clobber (match_operand:DI 1 "register_operand" "=D"))
18171 (clobber (reg:CC FLAGS_REG))]
18174 [(set_attr "type" "str")
18175 (set_attr "mode" "QI")
18176 (set_attr "prefix_rex" "0")
18177 (set_attr "prefix_rep" "1")])
18179 ;; Peephole optimizations to clean up after cmpstrn*. This should be
18180 ;; handled in combine, but it is not currently up to the task.
18181 ;; When used for their truth value, the cmpstrn* expanders generate
18190 ;; The intermediate three instructions are unnecessary.
18192 ;; This one handles cmpstrn*_nz_1...
18195 (set (reg:CC FLAGS_REG)
18196 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18197 (mem:BLK (match_operand 5 "register_operand" ""))))
18198 (use (match_operand 6 "register_operand" ""))
18199 (use (match_operand:SI 3 "immediate_operand" ""))
18200 (clobber (match_operand 0 "register_operand" ""))
18201 (clobber (match_operand 1 "register_operand" ""))
18202 (clobber (match_operand 2 "register_operand" ""))])
18203 (set (match_operand:QI 7 "register_operand" "")
18204 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18205 (set (match_operand:QI 8 "register_operand" "")
18206 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18207 (set (reg FLAGS_REG)
18208 (compare (match_dup 7) (match_dup 8)))
18210 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18212 (set (reg:CC FLAGS_REG)
18213 (compare:CC (mem:BLK (match_dup 4))
18214 (mem:BLK (match_dup 5))))
18215 (use (match_dup 6))
18216 (use (match_dup 3))
18217 (clobber (match_dup 0))
18218 (clobber (match_dup 1))
18219 (clobber (match_dup 2))])]
18222 ;; ...and this one handles cmpstrn*_1.
18225 (set (reg:CC FLAGS_REG)
18226 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
18228 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
18229 (mem:BLK (match_operand 5 "register_operand" "")))
18231 (use (match_operand:SI 3 "immediate_operand" ""))
18232 (use (reg:CC FLAGS_REG))
18233 (clobber (match_operand 0 "register_operand" ""))
18234 (clobber (match_operand 1 "register_operand" ""))
18235 (clobber (match_operand 2 "register_operand" ""))])
18236 (set (match_operand:QI 7 "register_operand" "")
18237 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
18238 (set (match_operand:QI 8 "register_operand" "")
18239 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
18240 (set (reg FLAGS_REG)
18241 (compare (match_dup 7) (match_dup 8)))
18243 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
18245 (set (reg:CC FLAGS_REG)
18246 (if_then_else:CC (ne (match_dup 6)
18248 (compare:CC (mem:BLK (match_dup 4))
18249 (mem:BLK (match_dup 5)))
18251 (use (match_dup 3))
18252 (use (reg:CC FLAGS_REG))
18253 (clobber (match_dup 0))
18254 (clobber (match_dup 1))
18255 (clobber (match_dup 2))])]
18260 ;; Conditional move instructions.
18262 (define_expand "mov<mode>cc"
18263 [(set (match_operand:SWIM 0 "register_operand" "")
18264 (if_then_else:SWIM (match_operand 1 "comparison_operator" "")
18265 (match_operand:SWIM 2 "general_operand" "")
18266 (match_operand:SWIM 3 "general_operand" "")))]
18268 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
18270 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
18271 ;; the register first winds up with `sbbl $0,reg', which is also weird.
18272 ;; So just document what we're doing explicitly.
18274 (define_expand "x86_mov<mode>cc_0_m1"
18276 [(set (match_operand:SWI48 0 "register_operand" "")
18277 (if_then_else:SWI48
18278 (match_operator:SWI48 2 "ix86_carry_flag_operator"
18279 [(match_operand 1 "flags_reg_operand" "")
18283 (clobber (reg:CC FLAGS_REG))])]
18287 (define_insn "*x86_mov<mode>cc_0_m1"
18288 [(set (match_operand:SWI48 0 "register_operand" "=r")
18289 (if_then_else:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18290 [(reg FLAGS_REG) (const_int 0)])
18293 (clobber (reg:CC FLAGS_REG))]
18295 "sbb{<imodesuffix>}\t%0, %0"
18296 ; Since we don't have the proper number of operands for an alu insn,
18297 ; fill in all the blanks.
18298 [(set_attr "type" "alu")
18299 (set_attr "use_carry" "1")
18300 (set_attr "pent_pair" "pu")
18301 (set_attr "memory" "none")
18302 (set_attr "imm_disp" "false")
18303 (set_attr "mode" "<MODE>")
18304 (set_attr "length_immediate" "0")])
18306 (define_insn "*x86_mov<mode>cc_0_m1_se"
18307 [(set (match_operand:SWI48 0 "register_operand" "=r")
18308 (sign_extract:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18309 [(reg FLAGS_REG) (const_int 0)])
18312 (clobber (reg:CC FLAGS_REG))]
18314 "sbb{<imodesuffix>}\t%0, %0"
18315 [(set_attr "type" "alu")
18316 (set_attr "use_carry" "1")
18317 (set_attr "pent_pair" "pu")
18318 (set_attr "memory" "none")
18319 (set_attr "imm_disp" "false")
18320 (set_attr "mode" "<MODE>")
18321 (set_attr "length_immediate" "0")])
18323 (define_insn "*x86_mov<mode>cc_0_m1_neg"
18324 [(set (match_operand:SWI48 0 "register_operand" "=r")
18325 (neg:SWI48 (match_operator 1 "ix86_carry_flag_operator"
18326 [(reg FLAGS_REG) (const_int 0)])))]
18328 "sbb{<imodesuffix>}\t%0, %0"
18329 [(set_attr "type" "alu")
18330 (set_attr "use_carry" "1")
18331 (set_attr "pent_pair" "pu")
18332 (set_attr "memory" "none")
18333 (set_attr "imm_disp" "false")
18334 (set_attr "mode" "<MODE>")
18335 (set_attr "length_immediate" "0")])
18337 (define_insn "*mov<mode>cc_noc"
18338 [(set (match_operand:SWI248 0 "register_operand" "=r,r")
18339 (if_then_else:SWI248 (match_operator 1 "ix86_comparison_operator"
18340 [(reg FLAGS_REG) (const_int 0)])
18341 (match_operand:SWI248 2 "nonimmediate_operand" "rm,0")
18342 (match_operand:SWI248 3 "nonimmediate_operand" "0,rm")))]
18343 "TARGET_CMOVE && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18345 cmov%O2%C1\t{%2, %0|%0, %2}
18346 cmov%O2%c1\t{%3, %0|%0, %3}"
18347 [(set_attr "type" "icmov")
18348 (set_attr "mode" "<MODE>")])
18350 (define_insn_and_split "*movqicc_noc"
18351 [(set (match_operand:QI 0 "register_operand" "=r,r")
18352 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
18353 [(match_operand 4 "flags_reg_operand" "")
18355 (match_operand:QI 2 "register_operand" "r,0")
18356 (match_operand:QI 3 "register_operand" "0,r")))]
18357 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
18359 "&& reload_completed"
18360 [(set (match_dup 0)
18361 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18364 "operands[0] = gen_lowpart (SImode, operands[0]);
18365 operands[2] = gen_lowpart (SImode, operands[2]);
18366 operands[3] = gen_lowpart (SImode, operands[3]);"
18367 [(set_attr "type" "icmov")
18368 (set_attr "mode" "SI")])
18370 (define_expand "mov<mode>cc"
18371 [(set (match_operand:X87MODEF 0 "register_operand" "")
18372 (if_then_else:X87MODEF
18373 (match_operand 1 "ix86_fp_comparison_operator" "")
18374 (match_operand:X87MODEF 2 "register_operand" "")
18375 (match_operand:X87MODEF 3 "register_operand" "")))]
18376 "(TARGET_80387 && TARGET_CMOVE)
18377 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
18378 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
18380 (define_insn "*movsfcc_1_387"
18381 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
18382 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
18383 [(reg FLAGS_REG) (const_int 0)])
18384 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
18385 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
18386 "TARGET_80387 && TARGET_CMOVE
18387 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18389 fcmov%F1\t{%2, %0|%0, %2}
18390 fcmov%f1\t{%3, %0|%0, %3}
18391 cmov%O2%C1\t{%2, %0|%0, %2}
18392 cmov%O2%c1\t{%3, %0|%0, %3}"
18393 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18394 (set_attr "mode" "SF,SF,SI,SI")])
18396 (define_insn "*movdfcc_1"
18397 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
18398 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18399 [(reg FLAGS_REG) (const_int 0)])
18400 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18401 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18402 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18403 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18405 fcmov%F1\t{%2, %0|%0, %2}
18406 fcmov%f1\t{%3, %0|%0, %3}
18409 [(set_attr "type" "fcmov,fcmov,multi,multi")
18410 (set_attr "mode" "DF")])
18412 (define_insn "*movdfcc_1_rex64"
18413 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
18414 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18415 [(reg FLAGS_REG) (const_int 0)])
18416 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
18417 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
18418 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
18419 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
18421 fcmov%F1\t{%2, %0|%0, %2}
18422 fcmov%f1\t{%3, %0|%0, %3}
18423 cmov%O2%C1\t{%2, %0|%0, %2}
18424 cmov%O2%c1\t{%3, %0|%0, %3}"
18425 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
18426 (set_attr "mode" "DF")])
18429 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
18430 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
18431 [(match_operand 4 "flags_reg_operand" "")
18433 (match_operand:DF 2 "nonimmediate_operand" "")
18434 (match_operand:DF 3 "nonimmediate_operand" "")))]
18435 "!TARGET_64BIT && reload_completed"
18436 [(set (match_dup 2)
18437 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18441 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
18444 "split_di (&operands[2], 2, &operands[5], &operands[7]);
18445 split_di (&operands[0], 1, &operands[2], &operands[3]);")
18447 (define_insn "*movxfcc_1"
18448 [(set (match_operand:XF 0 "register_operand" "=f,f")
18449 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
18450 [(reg FLAGS_REG) (const_int 0)])
18451 (match_operand:XF 2 "register_operand" "f,0")
18452 (match_operand:XF 3 "register_operand" "0,f")))]
18453 "TARGET_80387 && TARGET_CMOVE"
18455 fcmov%F1\t{%2, %0|%0, %2}
18456 fcmov%f1\t{%3, %0|%0, %3}"
18457 [(set_attr "type" "fcmov")
18458 (set_attr "mode" "XF")])
18460 ;; All moves in XOP pcmov instructions are 128 bits and hence we restrict
18461 ;; the scalar versions to have only XMM registers as operands.
18463 ;; XOP conditional move
18464 (define_insn "*xop_pcmov_<mode>"
18465 [(set (match_operand:MODEF 0 "register_operand" "=x")
18466 (if_then_else:MODEF
18467 (match_operand:MODEF 1 "register_operand" "x")
18468 (match_operand:MODEF 2 "register_operand" "x")
18469 (match_operand:MODEF 3 "register_operand" "x")))]
18471 "vpcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
18472 [(set_attr "type" "sse4arg")])
18474 ;; These versions of the min/max patterns are intentionally ignorant of
18475 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
18476 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
18477 ;; are undefined in this condition, we're certain this is correct.
18479 (define_insn "*avx_<code><mode>3"
18480 [(set (match_operand:MODEF 0 "register_operand" "=x")
18482 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
18483 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18484 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18485 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18486 [(set_attr "type" "sseadd")
18487 (set_attr "prefix" "vex")
18488 (set_attr "mode" "<MODE>")])
18490 (define_insn "<code><mode>3"
18491 [(set (match_operand:MODEF 0 "register_operand" "=x")
18493 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
18494 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
18495 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18496 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
18497 [(set_attr "type" "sseadd")
18498 (set_attr "mode" "<MODE>")])
18500 ;; These versions of the min/max patterns implement exactly the operations
18501 ;; min = (op1 < op2 ? op1 : op2)
18502 ;; max = (!(op1 < op2) ? op1 : op2)
18503 ;; Their operands are not commutative, and thus they may be used in the
18504 ;; presence of -0.0 and NaN.
18506 (define_insn "*avx_ieee_smin<mode>3"
18507 [(set (match_operand:MODEF 0 "register_operand" "=x")
18509 [(match_operand:MODEF 1 "register_operand" "x")
18510 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18512 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18513 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18514 [(set_attr "type" "sseadd")
18515 (set_attr "prefix" "vex")
18516 (set_attr "mode" "<MODE>")])
18518 (define_insn "*ieee_smin<mode>3"
18519 [(set (match_operand:MODEF 0 "register_operand" "=x")
18521 [(match_operand:MODEF 1 "register_operand" "0")
18522 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18524 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18525 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
18526 [(set_attr "type" "sseadd")
18527 (set_attr "mode" "<MODE>")])
18529 (define_insn "*avx_ieee_smax<mode>3"
18530 [(set (match_operand:MODEF 0 "register_operand" "=x")
18532 [(match_operand:MODEF 1 "register_operand" "0")
18533 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18535 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18536 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
18537 [(set_attr "type" "sseadd")
18538 (set_attr "prefix" "vex")
18539 (set_attr "mode" "<MODE>")])
18541 (define_insn "*ieee_smax<mode>3"
18542 [(set (match_operand:MODEF 0 "register_operand" "=x")
18544 [(match_operand:MODEF 1 "register_operand" "0")
18545 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
18547 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
18548 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
18549 [(set_attr "type" "sseadd")
18550 (set_attr "mode" "<MODE>")])
18552 ;; Make two stack loads independent:
18554 ;; fld %st(0) -> fld bb
18555 ;; fmul bb fmul %st(1), %st
18557 ;; Actually we only match the last two instructions for simplicity.
18559 [(set (match_operand 0 "fp_register_operand" "")
18560 (match_operand 1 "fp_register_operand" ""))
18562 (match_operator 2 "binary_fp_operator"
18564 (match_operand 3 "memory_operand" "")]))]
18565 "REGNO (operands[0]) != REGNO (operands[1])"
18566 [(set (match_dup 0) (match_dup 3))
18567 (set (match_dup 0) (match_dup 4))]
18569 ;; The % modifier is not operational anymore in peephole2's, so we have to
18570 ;; swap the operands manually in the case of addition and multiplication.
18571 "if (COMMUTATIVE_ARITH_P (operands[2]))
18572 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18573 operands[0], operands[1]);
18575 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
18576 operands[1], operands[0]);")
18578 ;; Conditional addition patterns
18579 (define_expand "add<mode>cc"
18580 [(match_operand:SWI 0 "register_operand" "")
18581 (match_operand 1 "comparison_operator" "")
18582 (match_operand:SWI 2 "register_operand" "")
18583 (match_operand:SWI 3 "const_int_operand" "")]
18585 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
18588 ;; Misc patterns (?)
18590 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
18591 ;; Otherwise there will be nothing to keep
18593 ;; [(set (reg ebp) (reg esp))]
18594 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
18595 ;; (clobber (eflags)]
18596 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
18598 ;; in proper program order.
18599 (define_insn "pro_epilogue_adjust_stack_1"
18600 [(set (match_operand:SI 0 "register_operand" "=r,r")
18601 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
18602 (match_operand:SI 2 "immediate_operand" "i,i")))
18603 (clobber (reg:CC FLAGS_REG))
18604 (clobber (mem:BLK (scratch)))]
18607 switch (get_attr_type (insn))
18610 return "mov{l}\t{%1, %0|%0, %1}";
18613 if (CONST_INT_P (operands[2])
18614 && (INTVAL (operands[2]) == 128
18615 || (INTVAL (operands[2]) < 0
18616 && INTVAL (operands[2]) != -128)))
18618 operands[2] = GEN_INT (-INTVAL (operands[2]));
18619 return "sub{l}\t{%2, %0|%0, %2}";
18621 return "add{l}\t{%2, %0|%0, %2}";
18624 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18625 return "lea{l}\t{%a2, %0|%0, %a2}";
18628 gcc_unreachable ();
18631 [(set (attr "type")
18632 (cond [(and (eq_attr "alternative" "0")
18633 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18634 (const_string "alu")
18635 (match_operand:SI 2 "const0_operand" "")
18636 (const_string "imov")
18638 (const_string "lea")))
18639 (set (attr "length_immediate")
18640 (cond [(eq_attr "type" "imov")
18642 (and (eq_attr "type" "alu")
18643 (match_operand 2 "const128_operand" ""))
18646 (const_string "*")))
18647 (set_attr "mode" "SI")])
18649 (define_insn "pro_epilogue_adjust_stack_rex64"
18650 [(set (match_operand:DI 0 "register_operand" "=r,r")
18651 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18652 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
18653 (clobber (reg:CC FLAGS_REG))
18654 (clobber (mem:BLK (scratch)))]
18657 switch (get_attr_type (insn))
18660 return "mov{q}\t{%1, %0|%0, %1}";
18663 if (CONST_INT_P (operands[2])
18664 /* Avoid overflows. */
18665 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
18666 && (INTVAL (operands[2]) == 128
18667 || (INTVAL (operands[2]) < 0
18668 && INTVAL (operands[2]) != -128)))
18670 operands[2] = GEN_INT (-INTVAL (operands[2]));
18671 return "sub{q}\t{%2, %0|%0, %2}";
18673 return "add{q}\t{%2, %0|%0, %2}";
18676 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
18677 return "lea{q}\t{%a2, %0|%0, %a2}";
18680 gcc_unreachable ();
18683 [(set (attr "type")
18684 (cond [(and (eq_attr "alternative" "0")
18685 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
18686 (const_string "alu")
18687 (match_operand:DI 2 "const0_operand" "")
18688 (const_string "imov")
18690 (const_string "lea")))
18691 (set (attr "length_immediate")
18692 (cond [(eq_attr "type" "imov")
18694 (and (eq_attr "type" "alu")
18695 (match_operand 2 "const128_operand" ""))
18698 (const_string "*")))
18699 (set_attr "mode" "DI")])
18701 (define_insn "pro_epilogue_adjust_stack_rex64_2"
18702 [(set (match_operand:DI 0 "register_operand" "=r,r")
18703 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
18704 (match_operand:DI 3 "immediate_operand" "i,i")))
18705 (use (match_operand:DI 2 "register_operand" "r,r"))
18706 (clobber (reg:CC FLAGS_REG))
18707 (clobber (mem:BLK (scratch)))]
18710 switch (get_attr_type (insn))
18713 return "add{q}\t{%2, %0|%0, %2}";
18716 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
18717 return "lea{q}\t{%a2, %0|%0, %a2}";
18720 gcc_unreachable ();
18723 [(set_attr "type" "alu,lea")
18724 (set_attr "mode" "DI")])
18726 (define_insn "allocate_stack_worker_32"
18727 [(set (match_operand:SI 0 "register_operand" "=a")
18728 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
18729 UNSPECV_STACK_PROBE))
18730 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
18731 (clobber (reg:CC FLAGS_REG))]
18732 "!TARGET_64BIT && TARGET_STACK_PROBE"
18734 [(set_attr "type" "multi")
18735 (set_attr "length" "5")])
18737 (define_insn "allocate_stack_worker_64"
18738 [(set (match_operand:DI 0 "register_operand" "=a")
18739 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
18740 UNSPECV_STACK_PROBE))
18741 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
18742 (clobber (reg:DI R10_REG))
18743 (clobber (reg:DI R11_REG))
18744 (clobber (reg:CC FLAGS_REG))]
18745 "TARGET_64BIT && TARGET_STACK_PROBE"
18747 [(set_attr "type" "multi")
18748 (set_attr "length" "5")])
18750 (define_expand "allocate_stack"
18751 [(match_operand 0 "register_operand" "")
18752 (match_operand 1 "general_operand" "")]
18753 "TARGET_STACK_PROBE"
18757 #ifndef CHECK_STACK_LIMIT
18758 #define CHECK_STACK_LIMIT 0
18761 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
18762 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
18764 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
18765 stack_pointer_rtx, 0, OPTAB_DIRECT);
18766 if (x != stack_pointer_rtx)
18767 emit_move_insn (stack_pointer_rtx, x);
18771 x = copy_to_mode_reg (Pmode, operands[1]);
18773 x = gen_allocate_stack_worker_64 (x, x);
18775 x = gen_allocate_stack_worker_32 (x, x);
18779 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
18783 ;; Use IOR for stack probes, this is shorter.
18784 (define_expand "probe_stack"
18785 [(match_operand 0 "memory_operand" "")]
18788 if (GET_MODE (operands[0]) == DImode)
18789 emit_insn (gen_iordi3 (operands[0], operands[0], const0_rtx));
18791 emit_insn (gen_iorsi3 (operands[0], operands[0], const0_rtx));
18795 (define_expand "builtin_setjmp_receiver"
18796 [(label_ref (match_operand 0 "" ""))]
18797 "!TARGET_64BIT && flag_pic"
18803 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
18804 rtx label_rtx = gen_label_rtx ();
18805 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
18806 xops[0] = xops[1] = picreg;
18807 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
18808 ix86_expand_binary_operator (MINUS, SImode, xops);
18812 emit_insn (gen_set_got (pic_offset_table_rtx));
18816 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
18819 [(set (match_operand 0 "register_operand" "")
18820 (match_operator 3 "promotable_binary_operator"
18821 [(match_operand 1 "register_operand" "")
18822 (match_operand 2 "aligned_operand" "")]))
18823 (clobber (reg:CC FLAGS_REG))]
18824 "! TARGET_PARTIAL_REG_STALL && reload_completed
18825 && ((GET_MODE (operands[0]) == HImode
18826 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
18827 /* ??? next two lines just !satisfies_constraint_K (...) */
18828 || !CONST_INT_P (operands[2])
18829 || satisfies_constraint_K (operands[2])))
18830 || (GET_MODE (operands[0]) == QImode
18831 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
18832 [(parallel [(set (match_dup 0)
18833 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
18834 (clobber (reg:CC FLAGS_REG))])]
18835 "operands[0] = gen_lowpart (SImode, operands[0]);
18836 operands[1] = gen_lowpart (SImode, operands[1]);
18837 if (GET_CODE (operands[3]) != ASHIFT)
18838 operands[2] = gen_lowpart (SImode, operands[2]);
18839 PUT_MODE (operands[3], SImode);")
18841 ; Promote the QImode tests, as i386 has encoding of the AND
18842 ; instruction with 32-bit sign-extended immediate and thus the
18843 ; instruction size is unchanged, except in the %eax case for
18844 ; which it is increased by one byte, hence the ! optimize_size.
18846 [(set (match_operand 0 "flags_reg_operand" "")
18847 (match_operator 2 "compare_operator"
18848 [(and (match_operand 3 "aligned_operand" "")
18849 (match_operand 4 "const_int_operand" ""))
18851 (set (match_operand 1 "register_operand" "")
18852 (and (match_dup 3) (match_dup 4)))]
18853 "! TARGET_PARTIAL_REG_STALL && reload_completed
18854 && optimize_insn_for_speed_p ()
18855 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
18856 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
18857 /* Ensure that the operand will remain sign-extended immediate. */
18858 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
18859 [(parallel [(set (match_dup 0)
18860 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
18863 (and:SI (match_dup 3) (match_dup 4)))])]
18866 = gen_int_mode (INTVAL (operands[4])
18867 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
18868 operands[1] = gen_lowpart (SImode, operands[1]);
18869 operands[3] = gen_lowpart (SImode, operands[3]);
18872 ; Don't promote the QImode tests, as i386 doesn't have encoding of
18873 ; the TEST instruction with 32-bit sign-extended immediate and thus
18874 ; the instruction size would at least double, which is not what we
18875 ; want even with ! optimize_size.
18877 [(set (match_operand 0 "flags_reg_operand" "")
18878 (match_operator 1 "compare_operator"
18879 [(and (match_operand:HI 2 "aligned_operand" "")
18880 (match_operand:HI 3 "const_int_operand" ""))
18882 "! TARGET_PARTIAL_REG_STALL && reload_completed
18883 && ! TARGET_FAST_PREFIX
18884 && optimize_insn_for_speed_p ()
18885 /* Ensure that the operand will remain sign-extended immediate. */
18886 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
18887 [(set (match_dup 0)
18888 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
18892 = gen_int_mode (INTVAL (operands[3])
18893 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
18894 operands[2] = gen_lowpart (SImode, operands[2]);
18898 [(set (match_operand 0 "register_operand" "")
18899 (neg (match_operand 1 "register_operand" "")))
18900 (clobber (reg:CC FLAGS_REG))]
18901 "! TARGET_PARTIAL_REG_STALL && reload_completed
18902 && (GET_MODE (operands[0]) == HImode
18903 || (GET_MODE (operands[0]) == QImode
18904 && (TARGET_PROMOTE_QImode
18905 || optimize_insn_for_size_p ())))"
18906 [(parallel [(set (match_dup 0)
18907 (neg:SI (match_dup 1)))
18908 (clobber (reg:CC FLAGS_REG))])]
18909 "operands[0] = gen_lowpart (SImode, operands[0]);
18910 operands[1] = gen_lowpart (SImode, operands[1]);")
18913 [(set (match_operand 0 "register_operand" "")
18914 (not (match_operand 1 "register_operand" "")))]
18915 "! TARGET_PARTIAL_REG_STALL && reload_completed
18916 && (GET_MODE (operands[0]) == HImode
18917 || (GET_MODE (operands[0]) == QImode
18918 && (TARGET_PROMOTE_QImode
18919 || optimize_insn_for_size_p ())))"
18920 [(set (match_dup 0)
18921 (not:SI (match_dup 1)))]
18922 "operands[0] = gen_lowpart (SImode, operands[0]);
18923 operands[1] = gen_lowpart (SImode, operands[1]);")
18926 [(set (match_operand 0 "register_operand" "")
18927 (if_then_else (match_operator 1 "comparison_operator"
18928 [(reg FLAGS_REG) (const_int 0)])
18929 (match_operand 2 "register_operand" "")
18930 (match_operand 3 "register_operand" "")))]
18931 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
18932 && (GET_MODE (operands[0]) == HImode
18933 || (GET_MODE (operands[0]) == QImode
18934 && (TARGET_PROMOTE_QImode
18935 || optimize_insn_for_size_p ())))"
18936 [(set (match_dup 0)
18937 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
18938 "operands[0] = gen_lowpart (SImode, operands[0]);
18939 operands[2] = gen_lowpart (SImode, operands[2]);
18940 operands[3] = gen_lowpart (SImode, operands[3]);")
18943 ;; RTL Peephole optimizations, run before sched2. These primarily look to
18944 ;; transform a complex memory operation into two memory to register operations.
18946 ;; Don't push memory operands
18948 [(set (match_operand:SI 0 "push_operand" "")
18949 (match_operand:SI 1 "memory_operand" ""))
18950 (match_scratch:SI 2 "r")]
18951 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18952 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18953 [(set (match_dup 2) (match_dup 1))
18954 (set (match_dup 0) (match_dup 2))]
18958 [(set (match_operand:DI 0 "push_operand" "")
18959 (match_operand:DI 1 "memory_operand" ""))
18960 (match_scratch:DI 2 "r")]
18961 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18962 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18963 [(set (match_dup 2) (match_dup 1))
18964 (set (match_dup 0) (match_dup 2))]
18967 ;; We need to handle SFmode only, because DFmode and XFmode is split to
18970 [(set (match_operand:SF 0 "push_operand" "")
18971 (match_operand:SF 1 "memory_operand" ""))
18972 (match_scratch:SF 2 "r")]
18973 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18974 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18975 [(set (match_dup 2) (match_dup 1))
18976 (set (match_dup 0) (match_dup 2))]
18980 [(set (match_operand:HI 0 "push_operand" "")
18981 (match_operand:HI 1 "memory_operand" ""))
18982 (match_scratch:HI 2 "r")]
18983 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18984 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18985 [(set (match_dup 2) (match_dup 1))
18986 (set (match_dup 0) (match_dup 2))]
18990 [(set (match_operand:QI 0 "push_operand" "")
18991 (match_operand:QI 1 "memory_operand" ""))
18992 (match_scratch:QI 2 "q")]
18993 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
18994 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
18995 [(set (match_dup 2) (match_dup 1))
18996 (set (match_dup 0) (match_dup 2))]
18999 ;; Don't move an immediate directly to memory when the instruction
19002 [(match_scratch:SI 1 "r")
19003 (set (match_operand:SI 0 "memory_operand" "")
19005 "optimize_insn_for_speed_p ()
19006 && ! TARGET_USE_MOV0
19007 && TARGET_SPLIT_LONG_MOVES
19008 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19009 && peep2_regno_dead_p (0, FLAGS_REG)"
19010 [(parallel [(set (match_dup 1) (const_int 0))
19011 (clobber (reg:CC FLAGS_REG))])
19012 (set (match_dup 0) (match_dup 1))]
19016 [(match_scratch:HI 1 "r")
19017 (set (match_operand:HI 0 "memory_operand" "")
19019 "optimize_insn_for_speed_p ()
19020 && ! TARGET_USE_MOV0
19021 && TARGET_SPLIT_LONG_MOVES
19022 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19023 && peep2_regno_dead_p (0, FLAGS_REG)"
19024 [(parallel [(set (match_dup 2) (const_int 0))
19025 (clobber (reg:CC FLAGS_REG))])
19026 (set (match_dup 0) (match_dup 1))]
19027 "operands[2] = gen_lowpart (SImode, operands[1]);")
19030 [(match_scratch:QI 1 "q")
19031 (set (match_operand:QI 0 "memory_operand" "")
19033 "optimize_insn_for_speed_p ()
19034 && ! TARGET_USE_MOV0
19035 && TARGET_SPLIT_LONG_MOVES
19036 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
19037 && peep2_regno_dead_p (0, FLAGS_REG)"
19038 [(parallel [(set (match_dup 2) (const_int 0))
19039 (clobber (reg:CC FLAGS_REG))])
19040 (set (match_dup 0) (match_dup 1))]
19041 "operands[2] = gen_lowpart (SImode, operands[1]);")
19044 [(match_scratch:SI 2 "r")
19045 (set (match_operand:SI 0 "memory_operand" "")
19046 (match_operand:SI 1 "immediate_operand" ""))]
19047 "optimize_insn_for_speed_p ()
19048 && TARGET_SPLIT_LONG_MOVES
19049 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19050 [(set (match_dup 2) (match_dup 1))
19051 (set (match_dup 0) (match_dup 2))]
19055 [(match_scratch:HI 2 "r")
19056 (set (match_operand:HI 0 "memory_operand" "")
19057 (match_operand:HI 1 "immediate_operand" ""))]
19058 "optimize_insn_for_speed_p ()
19059 && TARGET_SPLIT_LONG_MOVES
19060 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19061 [(set (match_dup 2) (match_dup 1))
19062 (set (match_dup 0) (match_dup 2))]
19066 [(match_scratch:QI 2 "q")
19067 (set (match_operand:QI 0 "memory_operand" "")
19068 (match_operand:QI 1 "immediate_operand" ""))]
19069 "optimize_insn_for_speed_p ()
19070 && TARGET_SPLIT_LONG_MOVES
19071 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
19072 [(set (match_dup 2) (match_dup 1))
19073 (set (match_dup 0) (match_dup 2))]
19076 ;; Don't compare memory with zero, load and use a test instead.
19078 [(set (match_operand 0 "flags_reg_operand" "")
19079 (match_operator 1 "compare_operator"
19080 [(match_operand:SI 2 "memory_operand" "")
19082 (match_scratch:SI 3 "r")]
19083 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
19084 [(set (match_dup 3) (match_dup 2))
19085 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
19088 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
19089 ;; Don't split NOTs with a displacement operand, because resulting XOR
19090 ;; will not be pairable anyway.
19092 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
19093 ;; represented using a modRM byte. The XOR replacement is long decoded,
19094 ;; so this split helps here as well.
19096 ;; Note: Can't do this as a regular split because we can't get proper
19097 ;; lifetime information then.
19100 [(set (match_operand:SI 0 "nonimmediate_operand" "")
19101 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
19102 "optimize_insn_for_speed_p ()
19103 && ((TARGET_NOT_UNPAIRABLE
19104 && (!MEM_P (operands[0])
19105 || !memory_displacement_operand (operands[0], SImode)))
19106 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
19107 && peep2_regno_dead_p (0, FLAGS_REG)"
19108 [(parallel [(set (match_dup 0)
19109 (xor:SI (match_dup 1) (const_int -1)))
19110 (clobber (reg:CC FLAGS_REG))])]
19114 [(set (match_operand:HI 0 "nonimmediate_operand" "")
19115 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
19116 "optimize_insn_for_speed_p ()
19117 && ((TARGET_NOT_UNPAIRABLE
19118 && (!MEM_P (operands[0])
19119 || !memory_displacement_operand (operands[0], HImode)))
19120 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
19121 && peep2_regno_dead_p (0, FLAGS_REG)"
19122 [(parallel [(set (match_dup 0)
19123 (xor:HI (match_dup 1) (const_int -1)))
19124 (clobber (reg:CC FLAGS_REG))])]
19128 [(set (match_operand:QI 0 "nonimmediate_operand" "")
19129 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
19130 "optimize_insn_for_speed_p ()
19131 && ((TARGET_NOT_UNPAIRABLE
19132 && (!MEM_P (operands[0])
19133 || !memory_displacement_operand (operands[0], QImode)))
19134 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
19135 && peep2_regno_dead_p (0, FLAGS_REG)"
19136 [(parallel [(set (match_dup 0)
19137 (xor:QI (match_dup 1) (const_int -1)))
19138 (clobber (reg:CC FLAGS_REG))])]
19141 ;; Non pairable "test imm, reg" instructions can be translated to
19142 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
19143 ;; byte opcode instead of two, have a short form for byte operands),
19144 ;; so do it for other CPUs as well. Given that the value was dead,
19145 ;; this should not create any new dependencies. Pass on the sub-word
19146 ;; versions if we're concerned about partial register stalls.
19149 [(set (match_operand 0 "flags_reg_operand" "")
19150 (match_operator 1 "compare_operator"
19151 [(and:SI (match_operand:SI 2 "register_operand" "")
19152 (match_operand:SI 3 "immediate_operand" ""))
19154 "ix86_match_ccmode (insn, CCNOmode)
19155 && (true_regnum (operands[2]) != AX_REG
19156 || satisfies_constraint_K (operands[3]))
19157 && peep2_reg_dead_p (1, operands[2])"
19159 [(set (match_dup 0)
19160 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
19163 (and:SI (match_dup 2) (match_dup 3)))])]
19166 ;; We don't need to handle HImode case, because it will be promoted to SImode
19167 ;; on ! TARGET_PARTIAL_REG_STALL
19170 [(set (match_operand 0 "flags_reg_operand" "")
19171 (match_operator 1 "compare_operator"
19172 [(and:QI (match_operand:QI 2 "register_operand" "")
19173 (match_operand:QI 3 "immediate_operand" ""))
19175 "! TARGET_PARTIAL_REG_STALL
19176 && ix86_match_ccmode (insn, CCNOmode)
19177 && true_regnum (operands[2]) != AX_REG
19178 && peep2_reg_dead_p (1, operands[2])"
19180 [(set (match_dup 0)
19181 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
19184 (and:QI (match_dup 2) (match_dup 3)))])]
19188 [(set (match_operand 0 "flags_reg_operand" "")
19189 (match_operator 1 "compare_operator"
19192 (match_operand 2 "ext_register_operand" "")
19195 (match_operand 3 "const_int_operand" ""))
19197 "! TARGET_PARTIAL_REG_STALL
19198 && ix86_match_ccmode (insn, CCNOmode)
19199 && true_regnum (operands[2]) != AX_REG
19200 && peep2_reg_dead_p (1, operands[2])"
19201 [(parallel [(set (match_dup 0)
19210 (set (zero_extract:SI (match_dup 2)
19221 ;; Don't do logical operations with memory inputs.
19223 [(match_scratch:SI 2 "r")
19224 (parallel [(set (match_operand:SI 0 "register_operand" "")
19225 (match_operator:SI 3 "arith_or_logical_operator"
19227 (match_operand:SI 1 "memory_operand" "")]))
19228 (clobber (reg:CC FLAGS_REG))])]
19229 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19230 [(set (match_dup 2) (match_dup 1))
19231 (parallel [(set (match_dup 0)
19232 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
19233 (clobber (reg:CC FLAGS_REG))])]
19237 [(match_scratch:SI 2 "r")
19238 (parallel [(set (match_operand:SI 0 "register_operand" "")
19239 (match_operator:SI 3 "arith_or_logical_operator"
19240 [(match_operand:SI 1 "memory_operand" "")
19242 (clobber (reg:CC FLAGS_REG))])]
19243 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
19244 [(set (match_dup 2) (match_dup 1))
19245 (parallel [(set (match_dup 0)
19246 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
19247 (clobber (reg:CC FLAGS_REG))])]
19250 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
19251 ;; refers to the destination of the load!
19254 [(set (match_operand:SI 0 "register_operand" "")
19255 (match_operand:SI 1 "register_operand" ""))
19256 (parallel [(set (match_dup 0)
19257 (match_operator:SI 3 "commutative_operator"
19259 (match_operand:SI 2 "memory_operand" "")]))
19260 (clobber (reg:CC FLAGS_REG))])]
19261 "REGNO (operands[0]) != REGNO (operands[1])
19262 && GENERAL_REGNO_P (REGNO (operands[0]))
19263 && GENERAL_REGNO_P (REGNO (operands[1]))"
19264 [(set (match_dup 0) (match_dup 4))
19265 (parallel [(set (match_dup 0)
19266 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
19267 (clobber (reg:CC FLAGS_REG))])]
19268 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
19271 [(set (match_operand 0 "register_operand" "")
19272 (match_operand 1 "register_operand" ""))
19274 (match_operator 3 "commutative_operator"
19276 (match_operand 2 "memory_operand" "")]))]
19277 "REGNO (operands[0]) != REGNO (operands[1])
19278 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
19279 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
19280 [(set (match_dup 0) (match_dup 2))
19282 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
19285 ; Don't do logical operations with memory outputs
19287 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
19288 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
19289 ; the same decoder scheduling characteristics as the original.
19292 [(match_scratch:SI 2 "r")
19293 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19294 (match_operator:SI 3 "arith_or_logical_operator"
19296 (match_operand:SI 1 "nonmemory_operand" "")]))
19297 (clobber (reg:CC FLAGS_REG))])]
19298 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19299 /* Do not split stack checking probes. */
19300 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19301 [(set (match_dup 2) (match_dup 0))
19302 (parallel [(set (match_dup 2)
19303 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
19304 (clobber (reg:CC FLAGS_REG))])
19305 (set (match_dup 0) (match_dup 2))]
19309 [(match_scratch:SI 2 "r")
19310 (parallel [(set (match_operand:SI 0 "memory_operand" "")
19311 (match_operator:SI 3 "arith_or_logical_operator"
19312 [(match_operand:SI 1 "nonmemory_operand" "")
19314 (clobber (reg:CC FLAGS_REG))])]
19315 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE
19316 /* Do not split stack checking probes. */
19317 && GET_CODE (operands[3]) != IOR && operands[1] != const0_rtx"
19318 [(set (match_dup 2) (match_dup 0))
19319 (parallel [(set (match_dup 2)
19320 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
19321 (clobber (reg:CC FLAGS_REG))])
19322 (set (match_dup 0) (match_dup 2))]
19325 ;; Attempt to always use XOR for zeroing registers.
19327 [(set (match_operand 0 "register_operand" "")
19328 (match_operand 1 "const0_operand" ""))]
19329 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
19330 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19331 && GENERAL_REG_P (operands[0])
19332 && peep2_regno_dead_p (0, FLAGS_REG)"
19333 [(parallel [(set (match_dup 0) (const_int 0))
19334 (clobber (reg:CC FLAGS_REG))])]
19336 operands[0] = gen_lowpart (word_mode, operands[0]);
19340 [(set (strict_low_part (match_operand 0 "register_operand" ""))
19342 "(GET_MODE (operands[0]) == QImode
19343 || GET_MODE (operands[0]) == HImode)
19344 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
19345 && peep2_regno_dead_p (0, FLAGS_REG)"
19346 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
19347 (clobber (reg:CC FLAGS_REG))])])
19349 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
19351 [(set (match_operand 0 "register_operand" "")
19353 "(GET_MODE (operands[0]) == HImode
19354 || GET_MODE (operands[0]) == SImode
19355 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
19356 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
19357 && peep2_regno_dead_p (0, FLAGS_REG)"
19358 [(parallel [(set (match_dup 0) (const_int -1))
19359 (clobber (reg:CC FLAGS_REG))])]
19360 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
19363 ;; Attempt to convert simple leas to adds. These can be created by
19366 [(set (match_operand:SI 0 "register_operand" "")
19367 (plus:SI (match_dup 0)
19368 (match_operand:SI 1 "nonmemory_operand" "")))]
19369 "peep2_regno_dead_p (0, FLAGS_REG)"
19370 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
19371 (clobber (reg:CC FLAGS_REG))])]
19375 [(set (match_operand:SI 0 "register_operand" "")
19376 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
19377 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
19378 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
19379 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
19380 (clobber (reg:CC FLAGS_REG))])]
19381 "operands[2] = gen_lowpart (SImode, operands[2]);")
19384 [(set (match_operand:DI 0 "register_operand" "")
19385 (plus:DI (match_dup 0)
19386 (match_operand:DI 1 "x86_64_general_operand" "")))]
19387 "peep2_regno_dead_p (0, FLAGS_REG)"
19388 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
19389 (clobber (reg:CC FLAGS_REG))])]
19393 [(set (match_operand:SI 0 "register_operand" "")
19394 (mult:SI (match_dup 0)
19395 (match_operand:SI 1 "const_int_operand" "")))]
19396 "exact_log2 (INTVAL (operands[1])) >= 0
19397 && peep2_regno_dead_p (0, FLAGS_REG)"
19398 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19399 (clobber (reg:CC FLAGS_REG))])]
19400 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19403 [(set (match_operand:DI 0 "register_operand" "")
19404 (mult:DI (match_dup 0)
19405 (match_operand:DI 1 "const_int_operand" "")))]
19406 "exact_log2 (INTVAL (operands[1])) >= 0
19407 && peep2_regno_dead_p (0, FLAGS_REG)"
19408 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
19409 (clobber (reg:CC FLAGS_REG))])]
19410 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
19413 [(set (match_operand:SI 0 "register_operand" "")
19414 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
19415 (match_operand:DI 2 "const_int_operand" "")) 0))]
19416 "exact_log2 (INTVAL (operands[2])) >= 0
19417 && REGNO (operands[0]) == REGNO (operands[1])
19418 && peep2_regno_dead_p (0, FLAGS_REG)"
19419 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
19420 (clobber (reg:CC FLAGS_REG))])]
19421 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
19423 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
19424 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
19425 ;; many CPUs it is also faster, since special hardware to avoid esp
19426 ;; dependencies is present.
19428 ;; While some of these conversions may be done using splitters, we use peepholes
19429 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
19431 ;; Convert prologue esp subtractions to push.
19432 ;; We need register to push. In order to keep verify_flow_info happy we have
19434 ;; - use scratch and clobber it in order to avoid dependencies
19435 ;; - use already live register
19436 ;; We can't use the second way right now, since there is no reliable way how to
19437 ;; verify that given register is live. First choice will also most likely in
19438 ;; fewer dependencies. On the place of esp adjustments it is very likely that
19439 ;; call clobbered registers are dead. We may want to use base pointer as an
19440 ;; alternative when no register is available later.
19443 [(match_scratch:SI 0 "r")
19444 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19445 (clobber (reg:CC FLAGS_REG))
19446 (clobber (mem:BLK (scratch)))])]
19447 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19448 [(clobber (match_dup 0))
19449 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19450 (clobber (mem:BLK (scratch)))])])
19453 [(match_scratch:SI 0 "r")
19454 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19455 (clobber (reg:CC FLAGS_REG))
19456 (clobber (mem:BLK (scratch)))])]
19457 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19458 [(clobber (match_dup 0))
19459 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19460 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19461 (clobber (mem:BLK (scratch)))])])
19463 ;; Convert esp subtractions to push.
19465 [(match_scratch:SI 0 "r")
19466 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
19467 (clobber (reg:CC FLAGS_REG))])]
19468 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19469 [(clobber (match_dup 0))
19470 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19473 [(match_scratch:SI 0 "r")
19474 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
19475 (clobber (reg:CC FLAGS_REG))])]
19476 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19477 [(clobber (match_dup 0))
19478 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
19479 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
19481 ;; Convert epilogue deallocator to pop.
19483 [(match_scratch:SI 0 "r")
19484 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19485 (clobber (reg:CC FLAGS_REG))
19486 (clobber (mem:BLK (scratch)))])]
19487 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19488 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19489 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19490 (clobber (mem:BLK (scratch)))])]
19493 ;; Two pops case is tricky, since pop causes dependency on destination register.
19494 ;; We use two registers if available.
19496 [(match_scratch:SI 0 "r")
19497 (match_scratch:SI 1 "r")
19498 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19499 (clobber (reg:CC FLAGS_REG))
19500 (clobber (mem:BLK (scratch)))])]
19501 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19502 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19503 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19504 (clobber (mem:BLK (scratch)))])
19505 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19506 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19510 [(match_scratch:SI 0 "r")
19511 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19512 (clobber (reg:CC FLAGS_REG))
19513 (clobber (mem:BLK (scratch)))])]
19514 "optimize_insn_for_size_p ()"
19515 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19516 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19517 (clobber (mem:BLK (scratch)))])
19518 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19519 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19522 ;; Convert esp additions to pop.
19524 [(match_scratch:SI 0 "r")
19525 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
19526 (clobber (reg:CC FLAGS_REG))])]
19528 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19529 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19532 ;; Two pops case is tricky, since pop causes dependency on destination register.
19533 ;; We use two registers if available.
19535 [(match_scratch:SI 0 "r")
19536 (match_scratch:SI 1 "r")
19537 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19538 (clobber (reg:CC FLAGS_REG))])]
19540 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19541 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19542 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
19543 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19547 [(match_scratch:SI 0 "r")
19548 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
19549 (clobber (reg:CC FLAGS_REG))])]
19550 "optimize_insn_for_size_p ()"
19551 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19552 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
19553 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
19554 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
19557 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
19558 ;; required and register dies. Similarly for 128 to -128.
19560 [(set (match_operand 0 "flags_reg_operand" "")
19561 (match_operator 1 "compare_operator"
19562 [(match_operand 2 "register_operand" "")
19563 (match_operand 3 "const_int_operand" "")]))]
19564 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
19565 && incdec_operand (operands[3], GET_MODE (operands[3])))
19566 || (!TARGET_FUSE_CMP_AND_BRANCH
19567 && INTVAL (operands[3]) == 128))
19568 && ix86_match_ccmode (insn, CCGCmode)
19569 && peep2_reg_dead_p (1, operands[2])"
19570 [(parallel [(set (match_dup 0)
19571 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
19572 (clobber (match_dup 2))])]
19576 [(match_scratch:DI 0 "r")
19577 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19578 (clobber (reg:CC FLAGS_REG))
19579 (clobber (mem:BLK (scratch)))])]
19580 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19581 [(clobber (match_dup 0))
19582 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19583 (clobber (mem:BLK (scratch)))])])
19586 [(match_scratch:DI 0 "r")
19587 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19588 (clobber (reg:CC FLAGS_REG))
19589 (clobber (mem:BLK (scratch)))])]
19590 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19591 [(clobber (match_dup 0))
19592 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19593 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19594 (clobber (mem:BLK (scratch)))])])
19596 ;; Convert esp subtractions to push.
19598 [(match_scratch:DI 0 "r")
19599 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
19600 (clobber (reg:CC FLAGS_REG))])]
19601 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
19602 [(clobber (match_dup 0))
19603 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19606 [(match_scratch:DI 0 "r")
19607 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
19608 (clobber (reg:CC FLAGS_REG))])]
19609 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
19610 [(clobber (match_dup 0))
19611 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
19612 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
19614 ;; Convert epilogue deallocator to pop.
19616 [(match_scratch:DI 0 "r")
19617 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19618 (clobber (reg:CC FLAGS_REG))
19619 (clobber (mem:BLK (scratch)))])]
19620 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
19621 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19622 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19623 (clobber (mem:BLK (scratch)))])]
19626 ;; Two pops case is tricky, since pop causes dependency on destination register.
19627 ;; We use two registers if available.
19629 [(match_scratch:DI 0 "r")
19630 (match_scratch:DI 1 "r")
19631 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19632 (clobber (reg:CC FLAGS_REG))
19633 (clobber (mem:BLK (scratch)))])]
19634 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
19635 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19636 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19637 (clobber (mem:BLK (scratch)))])
19638 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19639 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19643 [(match_scratch:DI 0 "r")
19644 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19645 (clobber (reg:CC FLAGS_REG))
19646 (clobber (mem:BLK (scratch)))])]
19647 "optimize_insn_for_size_p ()"
19648 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19649 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19650 (clobber (mem:BLK (scratch)))])
19651 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19652 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19655 ;; Convert esp additions to pop.
19657 [(match_scratch:DI 0 "r")
19658 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
19659 (clobber (reg:CC FLAGS_REG))])]
19661 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19662 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19665 ;; Two pops case is tricky, since pop causes dependency on destination register.
19666 ;; We use two registers if available.
19668 [(match_scratch:DI 0 "r")
19669 (match_scratch:DI 1 "r")
19670 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19671 (clobber (reg:CC FLAGS_REG))])]
19673 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19674 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19675 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
19676 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19680 [(match_scratch:DI 0 "r")
19681 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
19682 (clobber (reg:CC FLAGS_REG))])]
19683 "optimize_insn_for_size_p ()"
19684 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19685 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
19686 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
19687 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
19690 ;; Convert imul by three, five and nine into lea
19693 [(set (match_operand:SI 0 "register_operand" "")
19694 (mult:SI (match_operand:SI 1 "register_operand" "")
19695 (match_operand:SI 2 "const_int_operand" "")))
19696 (clobber (reg:CC FLAGS_REG))])]
19697 "INTVAL (operands[2]) == 3
19698 || INTVAL (operands[2]) == 5
19699 || INTVAL (operands[2]) == 9"
19700 [(set (match_dup 0)
19701 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
19703 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19707 [(set (match_operand:SI 0 "register_operand" "")
19708 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19709 (match_operand:SI 2 "const_int_operand" "")))
19710 (clobber (reg:CC FLAGS_REG))])]
19711 "optimize_insn_for_speed_p ()
19712 && (INTVAL (operands[2]) == 3
19713 || INTVAL (operands[2]) == 5
19714 || INTVAL (operands[2]) == 9)"
19715 [(set (match_dup 0) (match_dup 1))
19717 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
19719 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19723 [(set (match_operand:DI 0 "register_operand" "")
19724 (mult:DI (match_operand:DI 1 "register_operand" "")
19725 (match_operand:DI 2 "const_int_operand" "")))
19726 (clobber (reg:CC FLAGS_REG))])]
19728 && (INTVAL (operands[2]) == 3
19729 || INTVAL (operands[2]) == 5
19730 || INTVAL (operands[2]) == 9)"
19731 [(set (match_dup 0)
19732 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
19734 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19738 [(set (match_operand:DI 0 "register_operand" "")
19739 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19740 (match_operand:DI 2 "const_int_operand" "")))
19741 (clobber (reg:CC FLAGS_REG))])]
19743 && optimize_insn_for_speed_p ()
19744 && (INTVAL (operands[2]) == 3
19745 || INTVAL (operands[2]) == 5
19746 || INTVAL (operands[2]) == 9)"
19747 [(set (match_dup 0) (match_dup 1))
19749 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
19751 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
19753 ;; Imul $32bit_imm, mem, reg is vector decoded, while
19754 ;; imul $32bit_imm, reg, reg is direct decoded.
19756 [(match_scratch:DI 3 "r")
19757 (parallel [(set (match_operand:DI 0 "register_operand" "")
19758 (mult:DI (match_operand:DI 1 "memory_operand" "")
19759 (match_operand:DI 2 "immediate_operand" "")))
19760 (clobber (reg:CC FLAGS_REG))])]
19761 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19762 && !satisfies_constraint_K (operands[2])"
19763 [(set (match_dup 3) (match_dup 1))
19764 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
19765 (clobber (reg:CC FLAGS_REG))])]
19769 [(match_scratch:SI 3 "r")
19770 (parallel [(set (match_operand:SI 0 "register_operand" "")
19771 (mult:SI (match_operand:SI 1 "memory_operand" "")
19772 (match_operand:SI 2 "immediate_operand" "")))
19773 (clobber (reg:CC FLAGS_REG))])]
19774 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19775 && !satisfies_constraint_K (operands[2])"
19776 [(set (match_dup 3) (match_dup 1))
19777 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
19778 (clobber (reg:CC FLAGS_REG))])]
19782 [(match_scratch:SI 3 "r")
19783 (parallel [(set (match_operand:DI 0 "register_operand" "")
19785 (mult:SI (match_operand:SI 1 "memory_operand" "")
19786 (match_operand:SI 2 "immediate_operand" ""))))
19787 (clobber (reg:CC FLAGS_REG))])]
19788 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
19789 && !satisfies_constraint_K (operands[2])"
19790 [(set (match_dup 3) (match_dup 1))
19791 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
19792 (clobber (reg:CC FLAGS_REG))])]
19795 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
19796 ;; Convert it into imul reg, reg
19797 ;; It would be better to force assembler to encode instruction using long
19798 ;; immediate, but there is apparently no way to do so.
19800 [(parallel [(set (match_operand:DI 0 "register_operand" "")
19801 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
19802 (match_operand:DI 2 "const_int_operand" "")))
19803 (clobber (reg:CC FLAGS_REG))])
19804 (match_scratch:DI 3 "r")]
19805 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19806 && satisfies_constraint_K (operands[2])"
19807 [(set (match_dup 3) (match_dup 2))
19808 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
19809 (clobber (reg:CC FLAGS_REG))])]
19811 if (!rtx_equal_p (operands[0], operands[1]))
19812 emit_move_insn (operands[0], operands[1]);
19816 [(parallel [(set (match_operand:SI 0 "register_operand" "")
19817 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
19818 (match_operand:SI 2 "const_int_operand" "")))
19819 (clobber (reg:CC FLAGS_REG))])
19820 (match_scratch:SI 3 "r")]
19821 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
19822 && satisfies_constraint_K (operands[2])"
19823 [(set (match_dup 3) (match_dup 2))
19824 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
19825 (clobber (reg:CC FLAGS_REG))])]
19827 if (!rtx_equal_p (operands[0], operands[1]))
19828 emit_move_insn (operands[0], operands[1]);
19832 [(parallel [(set (match_operand:HI 0 "register_operand" "")
19833 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
19834 (match_operand:HI 2 "immediate_operand" "")))
19835 (clobber (reg:CC FLAGS_REG))])
19836 (match_scratch:HI 3 "r")]
19837 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
19838 [(set (match_dup 3) (match_dup 2))
19839 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
19840 (clobber (reg:CC FLAGS_REG))])]
19842 if (!rtx_equal_p (operands[0], operands[1]))
19843 emit_move_insn (operands[0], operands[1]);
19846 ;; After splitting up read-modify operations, array accesses with memory
19847 ;; operands might end up in form:
19849 ;; movl 4(%esp), %edx
19851 ;; instead of pre-splitting:
19853 ;; addl 4(%esp), %eax
19855 ;; movl 4(%esp), %edx
19856 ;; leal (%edx,%eax,4), %eax
19859 [(parallel [(set (match_operand 0 "register_operand" "")
19860 (ashift (match_operand 1 "register_operand" "")
19861 (match_operand 2 "const_int_operand" "")))
19862 (clobber (reg:CC FLAGS_REG))])
19863 (set (match_operand 3 "register_operand")
19864 (match_operand 4 "x86_64_general_operand" ""))
19865 (parallel [(set (match_operand 5 "register_operand" "")
19866 (plus (match_operand 6 "register_operand" "")
19867 (match_operand 7 "register_operand" "")))
19868 (clobber (reg:CC FLAGS_REG))])]
19869 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
19870 /* Validate MODE for lea. */
19871 && ((!TARGET_PARTIAL_REG_STALL
19872 && (GET_MODE (operands[0]) == QImode
19873 || GET_MODE (operands[0]) == HImode))
19874 || GET_MODE (operands[0]) == SImode
19875 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
19876 /* We reorder load and the shift. */
19877 && !rtx_equal_p (operands[1], operands[3])
19878 && !reg_overlap_mentioned_p (operands[0], operands[4])
19879 /* Last PLUS must consist of operand 0 and 3. */
19880 && !rtx_equal_p (operands[0], operands[3])
19881 && (rtx_equal_p (operands[3], operands[6])
19882 || rtx_equal_p (operands[3], operands[7]))
19883 && (rtx_equal_p (operands[0], operands[6])
19884 || rtx_equal_p (operands[0], operands[7]))
19885 /* The intermediate operand 0 must die or be same as output. */
19886 && (rtx_equal_p (operands[0], operands[5])
19887 || peep2_reg_dead_p (3, operands[0]))"
19888 [(set (match_dup 3) (match_dup 4))
19889 (set (match_dup 0) (match_dup 1))]
19891 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
19892 int scale = 1 << INTVAL (operands[2]);
19893 rtx index = gen_lowpart (Pmode, operands[1]);
19894 rtx base = gen_lowpart (Pmode, operands[3]);
19895 rtx dest = gen_lowpart (mode, operands[5]);
19897 operands[1] = gen_rtx_PLUS (Pmode, base,
19898 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
19900 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
19901 operands[0] = dest;
19904 ;; Call-value patterns last so that the wildcard operand does not
19905 ;; disrupt insn-recog's switch tables.
19907 (define_insn "*call_value_pop_0"
19908 [(set (match_operand 0 "" "")
19909 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19910 (match_operand:SI 2 "" "")))
19911 (set (reg:SI SP_REG)
19912 (plus:SI (reg:SI SP_REG)
19913 (match_operand:SI 3 "immediate_operand" "")))]
19916 if (SIBLING_CALL_P (insn))
19919 return "call\t%P1";
19921 [(set_attr "type" "callv")])
19923 (define_insn "*call_value_pop_1"
19924 [(set (match_operand 0 "" "")
19925 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
19926 (match_operand:SI 2 "" "")))
19927 (set (reg:SI SP_REG)
19928 (plus:SI (reg:SI SP_REG)
19929 (match_operand:SI 3 "immediate_operand" "i")))]
19930 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
19932 if (constant_call_address_operand (operands[1], Pmode))
19933 return "call\t%P1";
19934 return "call\t%A1";
19936 [(set_attr "type" "callv")])
19938 (define_insn "*sibcall_value_pop_1"
19939 [(set (match_operand 0 "" "")
19940 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
19941 (match_operand:SI 2 "" "")))
19942 (set (reg:SI SP_REG)
19943 (plus:SI (reg:SI SP_REG)
19944 (match_operand:SI 3 "immediate_operand" "i,i")))]
19945 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
19949 [(set_attr "type" "callv")])
19951 (define_insn "*call_value_0"
19952 [(set (match_operand 0 "" "")
19953 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
19954 (match_operand:SI 2 "" "")))]
19957 if (SIBLING_CALL_P (insn))
19960 return "call\t%P1";
19962 [(set_attr "type" "callv")])
19964 (define_insn "*call_value_0_rex64"
19965 [(set (match_operand 0 "" "")
19966 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19967 (match_operand:DI 2 "const_int_operand" "")))]
19970 if (SIBLING_CALL_P (insn))
19973 return "call\t%P1";
19975 [(set_attr "type" "callv")])
19977 (define_insn "*call_value_0_rex64_ms_sysv"
19978 [(set (match_operand 0 "" "")
19979 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
19980 (match_operand:DI 2 "const_int_operand" "")))
19981 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
19982 (clobber (reg:TI XMM6_REG))
19983 (clobber (reg:TI XMM7_REG))
19984 (clobber (reg:TI XMM8_REG))
19985 (clobber (reg:TI XMM9_REG))
19986 (clobber (reg:TI XMM10_REG))
19987 (clobber (reg:TI XMM11_REG))
19988 (clobber (reg:TI XMM12_REG))
19989 (clobber (reg:TI XMM13_REG))
19990 (clobber (reg:TI XMM14_REG))
19991 (clobber (reg:TI XMM15_REG))
19992 (clobber (reg:DI SI_REG))
19993 (clobber (reg:DI DI_REG))]
19994 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
19996 if (SIBLING_CALL_P (insn))
19999 return "call\t%P1";
20001 [(set_attr "type" "callv")])
20003 (define_insn "*call_value_1"
20004 [(set (match_operand 0 "" "")
20005 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "lsm"))
20006 (match_operand:SI 2 "" "")))]
20007 "!TARGET_64BIT && !SIBLING_CALL_P (insn)"
20009 if (constant_call_address_operand (operands[1], Pmode))
20010 return "call\t%P1";
20011 return "call\t%A1";
20013 [(set_attr "type" "callv")])
20015 (define_insn "*sibcall_value_1"
20016 [(set (match_operand 0 "" "")
20017 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,U"))
20018 (match_operand:SI 2 "" "")))]
20019 "!TARGET_64BIT && SIBLING_CALL_P (insn)"
20023 [(set_attr "type" "callv")])
20025 (define_insn "*call_value_1_rex64"
20026 [(set (match_operand 0 "" "")
20027 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20028 (match_operand:DI 2 "" "")))]
20029 "TARGET_64BIT && !SIBLING_CALL_P (insn)
20030 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
20032 if (constant_call_address_operand (operands[1], Pmode))
20033 return "call\t%P1";
20034 return "call\t%A1";
20036 [(set_attr "type" "callv")])
20038 (define_insn "*call_value_1_rex64_ms_sysv"
20039 [(set (match_operand 0 "" "")
20040 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
20041 (match_operand:DI 2 "" "")))
20042 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
20043 (clobber (reg:TI XMM6_REG))
20044 (clobber (reg:TI XMM7_REG))
20045 (clobber (reg:TI XMM8_REG))
20046 (clobber (reg:TI XMM9_REG))
20047 (clobber (reg:TI XMM10_REG))
20048 (clobber (reg:TI XMM11_REG))
20049 (clobber (reg:TI XMM12_REG))
20050 (clobber (reg:TI XMM13_REG))
20051 (clobber (reg:TI XMM14_REG))
20052 (clobber (reg:TI XMM15_REG))
20053 (clobber (reg:DI SI_REG))
20054 (clobber (reg:DI DI_REG))]
20055 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20057 if (constant_call_address_operand (operands[1], Pmode))
20058 return "call\t%P1";
20059 return "call\t%A1";
20061 [(set_attr "type" "callv")])
20063 (define_insn "*call_value_1_rex64_large"
20064 [(set (match_operand 0 "" "")
20065 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
20066 (match_operand:DI 2 "" "")))]
20067 "TARGET_64BIT && !SIBLING_CALL_P (insn)"
20069 [(set_attr "type" "callv")])
20071 (define_insn "*sibcall_value_1_rex64"
20072 [(set (match_operand 0 "" "")
20073 (call (mem:QI (match_operand:DI 1 "sibcall_insn_operand" "s,U"))
20074 (match_operand:DI 2 "" "")))]
20075 "TARGET_64BIT && SIBLING_CALL_P (insn)"
20079 [(set_attr "type" "callv")])
20081 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
20082 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
20083 ;; caught for use by garbage collectors and the like. Using an insn that
20084 ;; maps to SIGILL makes it more likely the program will rightfully die.
20085 ;; Keeping with tradition, "6" is in honor of #UD.
20086 (define_insn "trap"
20087 [(trap_if (const_int 1) (const_int 6))]
20089 { return ASM_SHORT "0x0b0f"; }
20090 [(set_attr "length" "2")])
20092 (define_expand "sse_prologue_save"
20093 [(parallel [(set (match_operand:BLK 0 "" "")
20094 (unspec:BLK [(reg:DI XMM0_REG)
20101 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20102 (use (match_operand:DI 1 "register_operand" ""))
20103 (use (match_operand:DI 2 "immediate_operand" ""))
20104 (use (label_ref:DI (match_operand 3 "" "")))])]
20108 (define_insn "*sse_prologue_save_insn"
20109 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
20110 (match_operand:DI 4 "const_int_operand" "n")))
20111 (unspec:BLK [(reg:DI XMM0_REG)
20118 (reg:DI XMM7_REG)] UNSPEC_SSE_PROLOGUE_SAVE))
20119 (use (match_operand:DI 1 "register_operand" "r"))
20120 (use (match_operand:DI 2 "const_int_operand" "i"))
20121 (use (label_ref:DI (match_operand 3 "" "X")))]
20123 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
20124 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
20127 operands[0] = gen_rtx_MEM (Pmode,
20128 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
20129 /* VEX instruction with a REX prefix will #UD. */
20130 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
20131 gcc_unreachable ();
20133 output_asm_insn ("jmp\t%A1", operands);
20134 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
20136 operands[4] = adjust_address (operands[0], DImode, i*16);
20137 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
20138 PUT_MODE (operands[4], TImode);
20139 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
20140 output_asm_insn ("rex", operands);
20141 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
20143 (*targetm.asm_out.internal_label) (asm_out_file, "L",
20144 CODE_LABEL_NUMBER (operands[3]));
20147 [(set_attr "type" "other")
20148 (set_attr "length_immediate" "0")
20149 (set_attr "length_address" "0")
20150 (set (attr "length")
20152 (eq (symbol_ref "TARGET_AVX") (const_int 0))
20153 (const_string "34")
20154 (const_string "42")))
20155 (set_attr "memory" "store")
20156 (set_attr "modrm" "0")
20157 (set_attr "prefix" "maybe_vex")
20158 (set_attr "mode" "DI")])
20160 (define_expand "prefetch"
20161 [(prefetch (match_operand 0 "address_operand" "")
20162 (match_operand:SI 1 "const_int_operand" "")
20163 (match_operand:SI 2 "const_int_operand" ""))]
20164 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
20166 int rw = INTVAL (operands[1]);
20167 int locality = INTVAL (operands[2]);
20169 gcc_assert (rw == 0 || rw == 1);
20170 gcc_assert (locality >= 0 && locality <= 3);
20171 gcc_assert (GET_MODE (operands[0]) == Pmode
20172 || GET_MODE (operands[0]) == VOIDmode);
20174 /* Use 3dNOW prefetch in case we are asking for write prefetch not
20175 supported by SSE counterpart or the SSE prefetch is not available
20176 (K6 machines). Otherwise use SSE prefetch as it allows specifying
20178 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
20179 operands[2] = GEN_INT (3);
20181 operands[1] = const0_rtx;
20184 (define_insn "*prefetch_sse"
20185 [(prefetch (match_operand:SI 0 "address_operand" "p")
20187 (match_operand:SI 1 "const_int_operand" ""))]
20188 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
20190 static const char * const patterns[4] = {
20191 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20194 int locality = INTVAL (operands[1]);
20195 gcc_assert (locality >= 0 && locality <= 3);
20197 return patterns[locality];
20199 [(set_attr "type" "sse")
20200 (set_attr "atom_sse_attr" "prefetch")
20201 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20202 (set_attr "memory" "none")])
20204 (define_insn "*prefetch_sse_rex"
20205 [(prefetch (match_operand:DI 0 "address_operand" "p")
20207 (match_operand:SI 1 "const_int_operand" ""))]
20208 "TARGET_PREFETCH_SSE && TARGET_64BIT"
20210 static const char * const patterns[4] = {
20211 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
20214 int locality = INTVAL (operands[1]);
20215 gcc_assert (locality >= 0 && locality <= 3);
20217 return patterns[locality];
20219 [(set_attr "type" "sse")
20220 (set_attr "atom_sse_attr" "prefetch")
20221 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20222 (set_attr "memory" "none")])
20224 (define_insn "*prefetch_3dnow"
20225 [(prefetch (match_operand:SI 0 "address_operand" "p")
20226 (match_operand:SI 1 "const_int_operand" "n")
20228 "TARGET_3DNOW && !TARGET_64BIT"
20230 if (INTVAL (operands[1]) == 0)
20231 return "prefetch\t%a0";
20233 return "prefetchw\t%a0";
20235 [(set_attr "type" "mmx")
20236 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20237 (set_attr "memory" "none")])
20239 (define_insn "*prefetch_3dnow_rex"
20240 [(prefetch (match_operand:DI 0 "address_operand" "p")
20241 (match_operand:SI 1 "const_int_operand" "n")
20243 "TARGET_3DNOW && TARGET_64BIT"
20245 if (INTVAL (operands[1]) == 0)
20246 return "prefetch\t%a0";
20248 return "prefetchw\t%a0";
20250 [(set_attr "type" "mmx")
20251 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
20252 (set_attr "memory" "none")])
20254 (define_expand "stack_protect_set"
20255 [(match_operand 0 "memory_operand" "")
20256 (match_operand 1 "memory_operand" "")]
20259 #ifdef TARGET_THREAD_SSP_OFFSET
20261 emit_insn (gen_stack_tls_protect_set_di (operands[0],
20262 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20264 emit_insn (gen_stack_tls_protect_set_si (operands[0],
20265 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20268 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
20270 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
20275 (define_insn "stack_protect_set_si"
20276 [(set (match_operand:SI 0 "memory_operand" "=m")
20277 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20278 (set (match_scratch:SI 2 "=&r") (const_int 0))
20279 (clobber (reg:CC FLAGS_REG))]
20281 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20282 [(set_attr "type" "multi")])
20284 (define_insn "stack_protect_set_di"
20285 [(set (match_operand:DI 0 "memory_operand" "=m")
20286 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
20287 (set (match_scratch:DI 2 "=&r") (const_int 0))
20288 (clobber (reg:CC FLAGS_REG))]
20290 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
20291 [(set_attr "type" "multi")])
20293 (define_insn "stack_tls_protect_set_si"
20294 [(set (match_operand:SI 0 "memory_operand" "=m")
20295 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20296 (set (match_scratch:SI 2 "=&r") (const_int 0))
20297 (clobber (reg:CC FLAGS_REG))]
20299 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
20300 [(set_attr "type" "multi")])
20302 (define_insn "stack_tls_protect_set_di"
20303 [(set (match_operand:DI 0 "memory_operand" "=m")
20304 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
20305 (set (match_scratch:DI 2 "=&r") (const_int 0))
20306 (clobber (reg:CC FLAGS_REG))]
20309 /* The kernel uses a different segment register for performance reasons; a
20310 system call would not have to trash the userspace segment register,
20311 which would be expensive */
20312 if (ix86_cmodel != CM_KERNEL)
20313 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20315 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
20317 [(set_attr "type" "multi")])
20319 (define_expand "stack_protect_test"
20320 [(match_operand 0 "memory_operand" "")
20321 (match_operand 1 "memory_operand" "")
20322 (match_operand 2 "" "")]
20325 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
20327 #ifdef TARGET_THREAD_SSP_OFFSET
20329 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
20330 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20332 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
20333 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
20336 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
20338 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
20341 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
20342 flags, const0_rtx, operands[2]));
20346 (define_insn "stack_protect_test_si"
20347 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20348 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20349 (match_operand:SI 2 "memory_operand" "m")]
20351 (clobber (match_scratch:SI 3 "=&r"))]
20353 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
20354 [(set_attr "type" "multi")])
20356 (define_insn "stack_protect_test_di"
20357 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20358 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20359 (match_operand:DI 2 "memory_operand" "m")]
20361 (clobber (match_scratch:DI 3 "=&r"))]
20363 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
20364 [(set_attr "type" "multi")])
20366 (define_insn "stack_tls_protect_test_si"
20367 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20368 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
20369 (match_operand:SI 2 "const_int_operand" "i")]
20370 UNSPEC_SP_TLS_TEST))
20371 (clobber (match_scratch:SI 3 "=r"))]
20373 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
20374 [(set_attr "type" "multi")])
20376 (define_insn "stack_tls_protect_test_di"
20377 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
20378 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
20379 (match_operand:DI 2 "const_int_operand" "i")]
20380 UNSPEC_SP_TLS_TEST))
20381 (clobber (match_scratch:DI 3 "=r"))]
20384 /* The kernel uses a different segment register for performance reasons; a
20385 system call would not have to trash the userspace segment register,
20386 which would be expensive */
20387 if (ix86_cmodel != CM_KERNEL)
20388 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
20390 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
20392 [(set_attr "type" "multi")])
20394 (define_insn "sse4_2_crc32<mode>"
20395 [(set (match_operand:SI 0 "register_operand" "=r")
20397 [(match_operand:SI 1 "register_operand" "0")
20398 (match_operand:SWI124 2 "nonimmediate_operand" "<r>m")]
20400 "TARGET_SSE4_2 || TARGET_CRC32"
20401 "crc32{<imodesuffix>}\t{%2, %0|%0, %2}"
20402 [(set_attr "type" "sselog1")
20403 (set_attr "prefix_rep" "1")
20404 (set_attr "prefix_extra" "1")
20405 (set (attr "prefix_data16")
20406 (if_then_else (match_operand:HI 2 "" "")
20408 (const_string "*")))
20409 (set (attr "prefix_rex")
20410 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
20412 (const_string "*")))
20413 (set_attr "mode" "SI")])
20415 (define_insn "sse4_2_crc32di"
20416 [(set (match_operand:DI 0 "register_operand" "=r")
20418 [(match_operand:DI 1 "register_operand" "0")
20419 (match_operand:DI 2 "nonimmediate_operand" "rm")]
20421 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
20422 "crc32{q}\t{%2, %0|%0, %2}"
20423 [(set_attr "type" "sselog1")
20424 (set_attr "prefix_rep" "1")
20425 (set_attr "prefix_extra" "1")
20426 (set_attr "mode" "DI")])
20428 (define_expand "rdpmc"
20429 [(match_operand:DI 0 "register_operand" "")
20430 (match_operand:SI 1 "register_operand" "")]
20433 rtx reg = gen_reg_rtx (DImode);
20436 /* Force operand 1 into ECX. */
20437 rtx ecx = gen_rtx_REG (SImode, CX_REG);
20438 emit_insn (gen_rtx_SET (VOIDmode, ecx, operands[1]));
20439 si = gen_rtx_UNSPEC_VOLATILE (DImode, gen_rtvec (1, ecx),
20444 rtvec vec = rtvec_alloc (2);
20445 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20446 rtx upper = gen_reg_rtx (DImode);
20447 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20448 gen_rtvec (1, const0_rtx),
20450 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, si);
20451 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20453 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20454 NULL, 1, OPTAB_DIRECT);
20455 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20459 emit_insn (gen_rtx_SET (VOIDmode, reg, si));
20460 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20464 (define_insn "*rdpmc"
20465 [(set (match_operand:DI 0 "register_operand" "=A")
20466 (unspec_volatile:DI [(match_operand:SI 1 "register_operand" "c")]
20470 [(set_attr "type" "other")
20471 (set_attr "length" "2")])
20473 (define_insn "*rdpmc_rex64"
20474 [(set (match_operand:DI 0 "register_operand" "=a")
20475 (unspec_volatile:DI [(match_operand:SI 2 "register_operand" "c")]
20477 (set (match_operand:DI 1 "register_operand" "=d")
20478 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDPMC))]
20481 [(set_attr "type" "other")
20482 (set_attr "length" "2")])
20484 (define_expand "rdtsc"
20485 [(set (match_operand:DI 0 "register_operand" "")
20486 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20491 rtvec vec = rtvec_alloc (2);
20492 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20493 rtx upper = gen_reg_rtx (DImode);
20494 rtx lower = gen_reg_rtx (DImode);
20495 rtx src = gen_rtx_UNSPEC_VOLATILE (DImode,
20496 gen_rtvec (1, const0_rtx),
20498 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, lower, src);
20499 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, src);
20501 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20502 NULL, 1, OPTAB_DIRECT);
20503 lower = expand_simple_binop (DImode, IOR, lower, upper, lower, 1,
20505 emit_insn (gen_rtx_SET (VOIDmode, operands[0], lower));
20510 (define_insn "*rdtsc"
20511 [(set (match_operand:DI 0 "register_operand" "=A")
20512 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20515 [(set_attr "type" "other")
20516 (set_attr "length" "2")])
20518 (define_insn "*rdtsc_rex64"
20519 [(set (match_operand:DI 0 "register_operand" "=a")
20520 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))
20521 (set (match_operand:DI 1 "register_operand" "=d")
20522 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSC))]
20525 [(set_attr "type" "other")
20526 (set_attr "length" "2")])
20528 (define_expand "rdtscp"
20529 [(match_operand:DI 0 "register_operand" "")
20530 (match_operand:SI 1 "memory_operand" "")]
20533 rtx di = gen_rtx_UNSPEC_VOLATILE (DImode,
20534 gen_rtvec (1, const0_rtx),
20536 rtx si = gen_rtx_UNSPEC_VOLATILE (SImode,
20537 gen_rtvec (1, const0_rtx),
20539 rtx reg = gen_reg_rtx (DImode);
20540 rtx tmp = gen_reg_rtx (SImode);
20544 rtvec vec = rtvec_alloc (3);
20545 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20546 rtx upper = gen_reg_rtx (DImode);
20547 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20548 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, upper, di);
20549 RTVEC_ELT (vec, 2) = gen_rtx_SET (VOIDmode, tmp, si);
20551 upper = expand_simple_binop (DImode, ASHIFT, upper, GEN_INT (32),
20552 NULL, 1, OPTAB_DIRECT);
20553 reg = expand_simple_binop (DImode, IOR, reg, upper, reg, 1,
20558 rtvec vec = rtvec_alloc (2);
20559 rtx load = gen_rtx_PARALLEL (VOIDmode, vec);
20560 RTVEC_ELT (vec, 0) = gen_rtx_SET (VOIDmode, reg, di);
20561 RTVEC_ELT (vec, 1) = gen_rtx_SET (VOIDmode, tmp, si);
20564 emit_insn (gen_rtx_SET (VOIDmode, operands[0], reg));
20565 emit_insn (gen_rtx_SET (VOIDmode, operands[1], tmp));
20569 (define_insn "*rdtscp"
20570 [(set (match_operand:DI 0 "register_operand" "=A")
20571 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20572 (set (match_operand:SI 1 "register_operand" "=c")
20573 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20576 [(set_attr "type" "other")
20577 (set_attr "length" "3")])
20579 (define_insn "*rdtscp_rex64"
20580 [(set (match_operand:DI 0 "register_operand" "=a")
20581 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20582 (set (match_operand:DI 1 "register_operand" "=d")
20583 (unspec_volatile:DI [(const_int 0)] UNSPECV_RDTSCP))
20584 (set (match_operand:SI 2 "register_operand" "=c")
20585 (unspec_volatile:SI [(const_int 0)] UNSPECV_RDTSCP))]
20588 [(set_attr "type" "other")
20589 (set_attr "length" "3")])
20591 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20593 ;; LWP instructions
20595 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
20597 (define_expand "lwp_llwpcb"
20598 [(unspec_volatile [(match_operand 0 "register_operand" "r")]
20599 UNSPECV_LLWP_INTRINSIC)]
20603 (define_insn "*lwp_llwpcb<mode>1"
20604 [(unspec_volatile [(match_operand:P 0 "register_operand" "r")]
20605 UNSPECV_LLWP_INTRINSIC)]
20608 [(set_attr "type" "lwp")
20609 (set_attr "mode" "<MODE>")
20610 (set_attr "length" "5")])
20612 (define_expand "lwp_slwpcb"
20613 [(set (match_operand 0 "register_operand" "=r")
20614 (unspec_volatile [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20618 emit_insn (gen_lwp_slwpcbdi (operands[0]));
20620 emit_insn (gen_lwp_slwpcbsi (operands[0]));
20624 (define_insn "lwp_slwpcb<mode>"
20625 [(set (match_operand:P 0 "register_operand" "=r")
20626 (unspec_volatile:P [(const_int 0)] UNSPECV_SLWP_INTRINSIC))]
20629 [(set_attr "type" "lwp")
20630 (set_attr "mode" "<MODE>")
20631 (set_attr "length" "5")])
20633 (define_expand "lwp_lwpval<mode>3"
20634 [(unspec_volatile [(match_operand:SWI48 1 "register_operand" "r")
20635 (match_operand:SI 2 "nonimmediate_operand" "rm")
20636 (match_operand:SI 3 "const_int_operand" "i")]
20637 UNSPECV_LWPVAL_INTRINSIC)]
20639 "/* Avoid unused variable warning. */
20642 (define_insn "*lwp_lwpval<mode>3_1"
20643 [(unspec_volatile [(match_operand:SWI48 0 "register_operand" "r")
20644 (match_operand:SI 1 "nonimmediate_operand" "rm")
20645 (match_operand:SI 2 "const_int_operand" "i")]
20646 UNSPECV_LWPVAL_INTRINSIC)]
20648 "lwpval\t{%2, %1, %0|%0, %1, %2}"
20649 [(set_attr "type" "lwp")
20650 (set_attr "mode" "<MODE>")
20651 (set (attr "length")
20652 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20654 (define_expand "lwp_lwpins<mode>3"
20655 [(set (reg:CCC FLAGS_REG)
20656 (unspec_volatile:CCC [(match_operand:SWI48 1 "register_operand" "r")
20657 (match_operand:SI 2 "nonimmediate_operand" "rm")
20658 (match_operand:SI 3 "const_int_operand" "i")]
20659 UNSPECV_LWPINS_INTRINSIC))
20660 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
20661 (eq:QI (reg:CCC FLAGS_REG) (const_int 0)))]
20665 (define_insn "*lwp_lwpins<mode>3_1"
20666 [(set (reg:CCC FLAGS_REG)
20667 (unspec_volatile:CCC [(match_operand:SWI48 0 "register_operand" "r")
20668 (match_operand:SI 1 "nonimmediate_operand" "rm")
20669 (match_operand:SI 2 "const_int_operand" "i")]
20670 UNSPECV_LWPINS_INTRINSIC))]
20672 "lwpins\t{%2, %1, %0|%0, %1, %2}"
20673 [(set_attr "type" "lwp")
20674 (set_attr "mode" "<MODE>")
20675 (set (attr "length")
20676 (symbol_ref "ix86_attr_length_address_default (insn) + 9"))])
20680 (include "sync.md")