1 ;; GCC machine description for IA-32 and x86-64.
2 ;; Copyright (C) 1988, 1994, 1995, 1996, 1997, 1998, 1999, 2000,
3 ;; 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009
4 ;; Free Software Foundation, Inc.
5 ;; Mostly by William Schelter.
6 ;; x86_64 support added by Jan Hubicka
8 ;; This file is part of GCC.
10 ;; GCC is free software; you can redistribute it and/or modify
11 ;; it under the terms of the GNU General Public License as published by
12 ;; the Free Software Foundation; either version 3, or (at your option)
15 ;; GCC is distributed in the hope that it will be useful,
16 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 ;; GNU General Public License for more details.
20 ;; You should have received a copy of the GNU General Public License
21 ;; along with GCC; see the file COPYING3. If not see
22 ;; <http://www.gnu.org/licenses/>. */
24 ;; The original PO technology requires these to be ordered by speed,
25 ;; so that assigner will pick the fastest.
27 ;; See file "rtl.def" for documentation on define_insn, match_*, et. al.
29 ;; The special asm out single letter directives following a '%' are:
30 ;; L,W,B,Q,S,T -- print the opcode suffix for specified size of operand.
31 ;; C -- print opcode suffix for set/cmov insn.
32 ;; c -- like C, but print reversed condition
33 ;; E,e -- likewise, but for compare-and-branch fused insn.
34 ;; F,f -- likewise, but for floating-point.
35 ;; O -- if HAVE_AS_IX86_CMOV_SUN_SYNTAX, expand to "w.", "l." or "q.",
37 ;; R -- print the prefix for register names.
38 ;; z -- print the opcode suffix for the size of the current operand.
39 ;; Z -- likewise, with special suffixes for x87 instructions.
40 ;; * -- print a star (in certain assembler syntax)
41 ;; A -- print an absolute memory reference.
42 ;; w -- print the operand as if it's a "word" (HImode) even if it isn't.
43 ;; s -- print a shift double count, followed by the assemblers argument
45 ;; b -- print the QImode name of the register for the indicated operand.
46 ;; %b0 would print %al if operands[0] is reg 0.
47 ;; w -- likewise, print the HImode name of the register.
48 ;; k -- likewise, print the SImode name of the register.
49 ;; q -- likewise, print the DImode name of the register.
50 ;; x -- likewise, print the V4SFmode name of the register.
51 ;; t -- likewise, print the V8SFmode name of the register.
52 ;; h -- print the QImode name for a "high" register, either ah, bh, ch or dh.
53 ;; y -- print "st(0)" instead of "st" as a register.
54 ;; d -- print duplicated register operand for AVX instruction.
55 ;; D -- print condition for SSE cmp instruction.
56 ;; P -- if PIC, print an @PLT suffix.
57 ;; X -- don't print any sort of PIC '@' suffix for a symbol.
58 ;; & -- print some in-use local-dynamic symbol name.
59 ;; H -- print a memory address offset by 8; used for sse high-parts
60 ;; Y -- print condition for SSE5 com* instruction.
61 ;; + -- print a branch hint as 'cs' or 'ds' prefix
62 ;; ; -- print a semicolon (after prefixes due to bug in older gas).
67 [; Relocation specifiers
78 (UNSPEC_MACHOPIC_OFFSET 10)
81 (UNSPEC_STACK_ALLOC 11)
83 (UNSPEC_SSE_PROLOGUE_SAVE 13)
87 (UNSPEC_SET_GOT_OFFSET 17)
88 (UNSPEC_MEMORY_BLOCKAGE 18)
93 (UNSPEC_TLS_LD_BASE 22)
96 ; Other random patterns
101 (UNSPEC_ADD_CARRY 34)
104 (UNSPEC_LD_MPIC 38) ; load_macho_picbase
105 (UNSPEC_TRUNC_NOOP 39)
107 ; For SSE/MMX support:
108 (UNSPEC_FIX_NOTRUNC 40)
125 (UNSPEC_MS_TO_SYSV_CALL 48)
127 ; Generic math support
129 (UNSPEC_IEEE_MIN 51) ; not commutative
130 (UNSPEC_IEEE_MAX 52) ; not commutative
145 (UNSPEC_FRNDINT_FLOOR 70)
146 (UNSPEC_FRNDINT_CEIL 71)
147 (UNSPEC_FRNDINT_TRUNC 72)
148 (UNSPEC_FRNDINT_MASK_PM 73)
149 (UNSPEC_FIST_FLOOR 74)
150 (UNSPEC_FIST_CEIL 75)
152 ; x87 Double output FP
153 (UNSPEC_SINCOS_COS 80)
154 (UNSPEC_SINCOS_SIN 81)
155 (UNSPEC_XTRACT_FRACT 84)
156 (UNSPEC_XTRACT_EXP 85)
157 (UNSPEC_FSCALE_FRACT 86)
158 (UNSPEC_FSCALE_EXP 87)
170 (UNSPEC_SP_TLS_SET 102)
171 (UNSPEC_SP_TLS_TEST 103)
181 (UNSPEC_INSERTQI 132)
186 (UNSPEC_INSERTPS 135)
188 (UNSPEC_MOVNTDQA 137)
190 (UNSPEC_PHMINPOSUW 139)
196 (UNSPEC_PCMPESTR 144)
197 (UNSPEC_PCMPISTR 145)
200 (UNSPEC_SSE5_INTRINSIC 150)
201 (UNSPEC_SSE5_UNSIGNED_CMP 151)
202 (UNSPEC_SSE5_TRUEFALSE 152)
203 (UNSPEC_SSE5_PERMUTE 153)
205 (UNSPEC_CVTPH2PS 155)
206 (UNSPEC_CVTPS2PH 156)
210 (UNSPEC_AESENCLAST 160)
212 (UNSPEC_AESDECLAST 162)
214 (UNSPEC_AESKEYGENASSIST 164)
222 (UNSPEC_VPERMIL2F128 168)
223 (UNSPEC_MASKLOAD 169)
224 (UNSPEC_MASKSTORE 170)
230 [(UNSPECV_BLOCKAGE 0)
231 (UNSPECV_STACK_PROBE 1)
243 (UNSPECV_PROLOGUE_USE 14)
245 (UNSPECV_VZEROALL 16)
246 (UNSPECV_VZEROUPPER 17)
249 ;; Constants to represent pcomtrue/pcomfalse variants
259 ;; Constants used in the SSE5 pperm instruction
261 [(PPERM_SRC 0x00) /* copy source */
262 (PPERM_INVERT 0x20) /* invert source */
263 (PPERM_REVERSE 0x40) /* bit reverse source */
264 (PPERM_REV_INV 0x60) /* bit reverse & invert src */
265 (PPERM_ZERO 0x80) /* all 0's */
266 (PPERM_ONES 0xa0) /* all 1's */
267 (PPERM_SIGN 0xc0) /* propagate sign bit */
268 (PPERM_INV_SIGN 0xe0) /* invert & propagate sign */
269 (PPERM_SRC1 0x00) /* use first source byte */
270 (PPERM_SRC2 0x10) /* use second source byte */
273 ;; Registers by name.
326 ;; Insns whose names begin with "x86_" are emitted by gen_FOO calls
329 ;; In C guard expressions, put expressions which may be compile-time
330 ;; constants first. This allows for better optimization. For
331 ;; example, write "TARGET_64BIT && reload_completed", not
332 ;; "reload_completed && TARGET_64BIT".
336 (define_attr "cpu" "none,pentium,pentiumpro,geode,k6,athlon,k8,core2,atom,
338 (const (symbol_ref "ix86_schedule")))
340 ;; A basic instruction type. Refinements due to arguments to be
341 ;; provided in other attributes.
344 alu,alu1,negnot,imov,imovx,lea,
345 incdec,ishift,ishift1,rotate,rotate1,imul,idiv,
346 icmp,test,ibr,setcc,icmov,
347 push,pop,call,callv,leave,
349 fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint,
350 sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
351 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,ssediv,sseins,
353 mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft"
354 (const_string "other"))
356 ;; Main data type used by the insn
358 "unknown,none,QI,HI,SI,DI,TI,OI,SF,DF,XF,TF,V8SF,V4DF,V4SF,V2DF,V2SF,V1DF"
359 (const_string "unknown"))
361 ;; The CPU unit operations uses.
362 (define_attr "unit" "integer,i387,sse,mmx,unknown"
363 (cond [(eq_attr "type" "fmov,fop,fsgn,fmul,fdiv,fpspc,fcmov,fcmp,fxch,fistp,fisttp,frndint")
364 (const_string "i387")
365 (eq_attr "type" "sselog,sselog1,sseiadd,sseiadd1,sseishft,sseimul,
366 sse,ssemov,sseadd,ssemul,ssecmp,ssecomi,ssecvt,
367 ssecvt1,sseicvt,ssediv,sseins,ssemuladd,sse4arg")
369 (eq_attr "type" "mmx,mmxmov,mmxadd,mmxmul,mmxcmp,mmxcvt,mmxshft")
371 (eq_attr "type" "other")
372 (const_string "unknown")]
373 (const_string "integer")))
375 ;; The (bounding maximum) length of an instruction immediate.
376 (define_attr "length_immediate" ""
377 (cond [(eq_attr "type" "incdec,setcc,icmov,str,lea,other,multi,idiv,leave,
380 (eq_attr "unit" "i387,sse,mmx")
382 (eq_attr "type" "alu,alu1,negnot,imovx,ishift,rotate,ishift1,rotate1,
384 (symbol_ref "ix86_attr_length_immediate_default(insn,1)")
385 (eq_attr "type" "imov,test")
386 (symbol_ref "ix86_attr_length_immediate_default(insn,0)")
387 (eq_attr "type" "call")
388 (if_then_else (match_operand 0 "constant_call_address_operand" "")
391 (eq_attr "type" "callv")
392 (if_then_else (match_operand 1 "constant_call_address_operand" "")
395 ;; We don't know the size before shorten_branches. Expect
396 ;; the instruction to fit for better scheduling.
397 (eq_attr "type" "ibr")
400 (symbol_ref "/* Update immediate_length and other attributes! */
401 gcc_unreachable (),1")))
403 ;; The (bounding maximum) length of an instruction address.
404 (define_attr "length_address" ""
405 (cond [(eq_attr "type" "str,other,multi,fxch")
407 (and (eq_attr "type" "call")
408 (match_operand 0 "constant_call_address_operand" ""))
410 (and (eq_attr "type" "callv")
411 (match_operand 1 "constant_call_address_operand" ""))
414 (symbol_ref "ix86_attr_length_address_default (insn)")))
416 ;; Set when length prefix is used.
417 (define_attr "prefix_data16" ""
418 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
420 (eq_attr "mode" "HI")
422 (and (eq_attr "unit" "sse") (eq_attr "mode" "V2DF,TI"))
427 ;; Set when string REP prefix is used.
428 (define_attr "prefix_rep" ""
429 (cond [(eq_attr "type" "ssemuladd,sse4arg,sseiadd1,ssecvt1")
431 (and (eq_attr "unit" "sse") (eq_attr "mode" "SF,DF"))
436 ;; Set when 0f opcode prefix is used.
437 (define_attr "prefix_0f" ""
439 (ior (eq_attr "type" "imovx,setcc,icmov,bitmanip")
440 (eq_attr "unit" "sse,mmx"))
444 ;; Set when REX opcode prefix is used.
445 (define_attr "prefix_rex" ""
446 (cond [(ne (symbol_ref "!TARGET_64BIT") (const_int 0))
448 (and (eq_attr "mode" "DI")
449 (and (eq_attr "type" "!push,pop,call,callv,leave,ibr")
450 (eq_attr "unit" "!mmx")))
452 (and (eq_attr "mode" "QI")
453 (ne (symbol_ref "x86_extended_QIreg_mentioned_p (insn)")
456 (ne (symbol_ref "x86_extended_reg_mentioned_p (insn)")
459 (and (eq_attr "type" "imovx")
460 (match_operand:QI 1 "ext_QIreg_operand" ""))
465 ;; There are also additional prefixes in 3DNOW, SSSE3 or SSE5.
466 ;; ssemuladd,sse4arg default to 0f24/0f25 and DREX byte,
467 ;; sseiadd1,ssecvt1 to 0f7a with no DREX byte.
468 ;; 3DNOW has 0f0f prefix, SSSE3 and SSE4_{1,2} 0f38/0f3a.
469 (define_attr "prefix_extra" ""
470 (cond [(eq_attr "type" "ssemuladd,sse4arg")
472 (eq_attr "type" "sseiadd1,ssecvt1")
477 ;; Prefix used: original, VEX or maybe VEX.
478 (define_attr "prefix" "orig,vex,maybe_vex"
479 (if_then_else (eq_attr "mode" "OI,V8SF,V4DF")
481 (const_string "orig")))
483 ;; VEX W bit is used.
484 (define_attr "prefix_vex_w" "" (const_int 0))
486 ;; The length of VEX prefix
487 ;; Only instructions with 0f prefix can have 2 byte VEX prefix,
488 ;; 0f38/0f3a prefixes can't. In i386.md 0f3[8a] is
489 ;; still prefix_0f 1, with prefix_extra 1.
490 (define_attr "length_vex" ""
491 (if_then_else (and (eq_attr "prefix_0f" "1")
492 (eq_attr "prefix_extra" "0"))
493 (if_then_else (eq_attr "prefix_vex_w" "1")
494 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 1)")
495 (symbol_ref "ix86_attr_length_vex_default (insn, 1, 0)"))
496 (if_then_else (eq_attr "prefix_vex_w" "1")
497 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 1)")
498 (symbol_ref "ix86_attr_length_vex_default (insn, 0, 0)"))))
500 ;; Set when modrm byte is used.
501 (define_attr "modrm" ""
502 (cond [(eq_attr "type" "str,leave")
504 (eq_attr "unit" "i387")
506 (and (eq_attr "type" "incdec")
507 (and (eq (symbol_ref "TARGET_64BIT") (const_int 0))
508 (ior (match_operand:SI 1 "register_operand" "")
509 (match_operand:HI 1 "register_operand" ""))))
511 (and (eq_attr "type" "push")
512 (not (match_operand 1 "memory_operand" "")))
514 (and (eq_attr "type" "pop")
515 (not (match_operand 0 "memory_operand" "")))
517 (and (eq_attr "type" "imov")
518 (and (not (eq_attr "mode" "DI"))
519 (ior (and (match_operand 0 "register_operand" "")
520 (match_operand 1 "immediate_operand" ""))
521 (ior (and (match_operand 0 "ax_reg_operand" "")
522 (match_operand 1 "memory_displacement_only_operand" ""))
523 (and (match_operand 0 "memory_displacement_only_operand" "")
524 (match_operand 1 "ax_reg_operand" ""))))))
526 (and (eq_attr "type" "call")
527 (match_operand 0 "constant_call_address_operand" ""))
529 (and (eq_attr "type" "callv")
530 (match_operand 1 "constant_call_address_operand" ""))
532 (and (eq_attr "type" "alu,alu1,icmp,test")
533 (match_operand 0 "ax_reg_operand" ""))
534 (symbol_ref "(get_attr_length_immediate (insn) <= (get_attr_mode (insn) != MODE_QI))")
538 ;; The (bounding maximum) length of an instruction in bytes.
539 ;; ??? fistp and frndint are in fact fldcw/{fistp,frndint}/fldcw sequences.
540 ;; Later we may want to split them and compute proper length as for
542 (define_attr "length" ""
543 (cond [(eq_attr "type" "other,multi,fistp,frndint")
545 (eq_attr "type" "fcmp")
547 (eq_attr "unit" "i387")
549 (plus (attr "prefix_data16")
550 (attr "length_address")))
551 (ior (eq_attr "prefix" "vex")
552 (and (eq_attr "prefix" "maybe_vex")
553 (ne (symbol_ref "TARGET_AVX") (const_int 0))))
554 (plus (attr "length_vex")
555 (plus (attr "length_immediate")
557 (attr "length_address"))))]
558 (plus (plus (attr "modrm")
559 (plus (attr "prefix_0f")
560 (plus (attr "prefix_rex")
561 (plus (attr "prefix_extra")
563 (plus (attr "prefix_rep")
564 (plus (attr "prefix_data16")
565 (plus (attr "length_immediate")
566 (attr "length_address")))))))
568 ;; The `memory' attribute is `none' if no memory is referenced, `load' or
569 ;; `store' if there is a simple memory reference therein, or `unknown'
570 ;; if the instruction is complex.
572 (define_attr "memory" "none,load,store,both,unknown"
573 (cond [(eq_attr "type" "other,multi,str")
574 (const_string "unknown")
575 (eq_attr "type" "lea,fcmov,fpspc")
576 (const_string "none")
577 (eq_attr "type" "fistp,leave")
578 (const_string "both")
579 (eq_attr "type" "frndint")
580 (const_string "load")
581 (eq_attr "type" "push")
582 (if_then_else (match_operand 1 "memory_operand" "")
583 (const_string "both")
584 (const_string "store"))
585 (eq_attr "type" "pop")
586 (if_then_else (match_operand 0 "memory_operand" "")
587 (const_string "both")
588 (const_string "load"))
589 (eq_attr "type" "setcc")
590 (if_then_else (match_operand 0 "memory_operand" "")
591 (const_string "store")
592 (const_string "none"))
593 (eq_attr "type" "icmp,test,ssecmp,ssecomi,mmxcmp,fcmp")
594 (if_then_else (ior (match_operand 0 "memory_operand" "")
595 (match_operand 1 "memory_operand" ""))
596 (const_string "load")
597 (const_string "none"))
598 (eq_attr "type" "ibr")
599 (if_then_else (match_operand 0 "memory_operand" "")
600 (const_string "load")
601 (const_string "none"))
602 (eq_attr "type" "call")
603 (if_then_else (match_operand 0 "constant_call_address_operand" "")
604 (const_string "none")
605 (const_string "load"))
606 (eq_attr "type" "callv")
607 (if_then_else (match_operand 1 "constant_call_address_operand" "")
608 (const_string "none")
609 (const_string "load"))
610 (and (eq_attr "type" "alu1,negnot,ishift1,sselog1")
611 (match_operand 1 "memory_operand" ""))
612 (const_string "both")
613 (and (match_operand 0 "memory_operand" "")
614 (match_operand 1 "memory_operand" ""))
615 (const_string "both")
616 (match_operand 0 "memory_operand" "")
617 (const_string "store")
618 (match_operand 1 "memory_operand" "")
619 (const_string "load")
621 "!alu1,negnot,ishift1,
622 imov,imovx,icmp,test,bitmanip,
624 sse,ssemov,ssecmp,ssecomi,ssecvt,ssecvt1,sseicvt,sselog1,
625 sseiadd1,mmx,mmxmov,mmxcmp,mmxcvt")
626 (match_operand 2 "memory_operand" ""))
627 (const_string "load")
628 (and (eq_attr "type" "icmov,ssemuladd,sse4arg")
629 (match_operand 3 "memory_operand" ""))
630 (const_string "load")
632 (const_string "none")))
634 ;; Indicates if an instruction has both an immediate and a displacement.
636 (define_attr "imm_disp" "false,true,unknown"
637 (cond [(eq_attr "type" "other,multi")
638 (const_string "unknown")
639 (and (eq_attr "type" "icmp,test,imov,alu1,ishift1,rotate1")
640 (and (match_operand 0 "memory_displacement_operand" "")
641 (match_operand 1 "immediate_operand" "")))
642 (const_string "true")
643 (and (eq_attr "type" "alu,ishift,rotate,imul,idiv")
644 (and (match_operand 0 "memory_displacement_operand" "")
645 (match_operand 2 "immediate_operand" "")))
646 (const_string "true")
648 (const_string "false")))
650 ;; Indicates if an FP operation has an integer source.
652 (define_attr "fp_int_src" "false,true"
653 (const_string "false"))
655 ;; Defines rounding mode of an FP operation.
657 (define_attr "i387_cw" "trunc,floor,ceil,mask_pm,uninitialized,any"
658 (const_string "any"))
660 ;; Define attribute to classify add/sub insns that consumes carry flag (CF)
661 (define_attr "use_carry" "0,1" (const_string "0"))
663 ;; Define attribute to indicate unaligned ssemov insns
664 (define_attr "movu" "0,1" (const_string "0"))
666 ;; Describe a user's asm statement.
667 (define_asm_attributes
668 [(set_attr "length" "128")
669 (set_attr "type" "multi")])
671 ;; All integer comparison codes.
672 (define_code_iterator int_cond [ne eq ge gt le lt geu gtu leu ltu ])
674 ;; All floating-point comparison codes.
675 (define_code_iterator fp_cond [unordered ordered
676 uneq unge ungt unle unlt ltgt ])
678 (define_code_iterator plusminus [plus minus])
680 (define_code_iterator sat_plusminus [ss_plus us_plus ss_minus us_minus])
682 ;; Base name for define_insn
683 (define_code_attr plusminus_insn
684 [(plus "add") (ss_plus "ssadd") (us_plus "usadd")
685 (minus "sub") (ss_minus "sssub") (us_minus "ussub")])
687 ;; Base name for insn mnemonic.
688 (define_code_attr plusminus_mnemonic
689 [(plus "add") (ss_plus "adds") (us_plus "addus")
690 (minus "sub") (ss_minus "subs") (us_minus "subus")])
692 ;; Mark commutative operators as such in constraints.
693 (define_code_attr comm [(plus "%") (ss_plus "%") (us_plus "%")
694 (minus "") (ss_minus "") (us_minus "")])
696 ;; Mapping of signed max and min
697 (define_code_iterator smaxmin [smax smin])
699 ;; Mapping of unsigned max and min
700 (define_code_iterator umaxmin [umax umin])
702 ;; Mapping of signed/unsigned max and min
703 (define_code_iterator maxmin [smax smin umax umin])
705 ;; Base name for integer and FP insn mnemonic
706 (define_code_attr maxminiprefix [(smax "maxs") (smin "mins")
707 (umax "maxu") (umin "minu")])
708 (define_code_attr maxminfprefix [(smax "max") (smin "min")])
710 ;; Mapping of parallel logic operators
711 (define_code_iterator plogic [and ior xor])
713 ;; Base name for insn mnemonic.
714 (define_code_attr plogicprefix [(and "and") (ior "or") (xor "xor")])
716 ;; Mapping of abs neg operators
717 (define_code_iterator absneg [abs neg])
719 ;; Base name for x87 insn mnemonic.
720 (define_code_attr absnegprefix [(abs "abs") (neg "chs")])
722 ;; All single word integer modes.
723 (define_mode_iterator SWI [QI HI SI (DI "TARGET_64BIT")])
725 ;; Single word integer modes without QImode.
726 (define_mode_iterator SWI248 [HI SI (DI "TARGET_64BIT")])
728 ;; Instruction suffix for integer modes.
729 (define_mode_attr imodesuffix [(QI "b") (HI "w") (SI "l") (DI "q")])
731 ;; Register class for integer modes.
732 (define_mode_attr r [(QI "q") (HI "r") (SI "r") (DI "r")])
734 ;; Immediate operand constraint for integer modes.
735 (define_mode_attr i [(QI "n") (HI "n") (SI "i") (DI "e")])
737 ;; General operand predicate for integer modes.
738 (define_mode_attr general_operand
739 [(QI "general_operand")
740 (HI "general_operand")
741 (SI "general_operand")
742 (DI "x86_64_general_operand")])
744 ;; SSE and x87 SFmode and DFmode floating point modes
745 (define_mode_iterator MODEF [SF DF])
747 ;; All x87 floating point modes
748 (define_mode_iterator X87MODEF [SF DF XF])
750 ;; All integer modes handled by x87 fisttp operator.
751 (define_mode_iterator X87MODEI [HI SI DI])
753 ;; All integer modes handled by integer x87 operators.
754 (define_mode_iterator X87MODEI12 [HI SI])
756 ;; All integer modes handled by SSE cvtts?2si* operators.
757 (define_mode_iterator SSEMODEI24 [SI DI])
759 ;; SSE asm suffix for floating point modes
760 (define_mode_attr ssemodefsuffix [(SF "s") (DF "d")])
762 ;; SSE vector mode corresponding to a scalar mode
763 (define_mode_attr ssevecmode
764 [(QI "V16QI") (HI "V8HI") (SI "V4SI") (DI "V2DI") (SF "V4SF") (DF "V2DF")])
766 ;; Instruction suffix for REX 64bit operators.
767 (define_mode_attr rex64suffix [(SI "") (DI "{q}")])
769 ;; This mode iterator allows :P to be used for patterns that operate on
770 ;; pointer-sized quantities. Exactly one of the two alternatives will match.
771 (define_mode_iterator P [(SI "Pmode == SImode") (DI "Pmode == DImode")])
774 ;; Scheduling descriptions
776 (include "pentium.md")
779 (include "athlon.md")
784 ;; Operand and operator predicates and constraints
786 (include "predicates.md")
787 (include "constraints.md")
790 ;; Compare and branch/compare and store instructions.
792 (define_expand "cbranchti4"
793 [(set (reg:CC FLAGS_REG)
794 (compare:CC (match_operand:TI 1 "nonimmediate_operand" "")
795 (match_operand:TI 2 "x86_64_general_operand" "")))
796 (set (pc) (if_then_else
797 (match_operator 0 "comparison_operator"
800 (label_ref (match_operand 3 "" ""))
804 if (MEM_P (operands[1]) && MEM_P (operands[2]))
805 operands[1] = force_reg (TImode, operands[1]);
806 ix86_compare_op0 = operands[1];
807 ix86_compare_op1 = operands[2];
808 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
812 (define_expand "cbranchdi4"
813 [(set (reg:CC FLAGS_REG)
814 (compare:CC (match_operand:DI 1 "nonimmediate_operand" "")
815 (match_operand:DI 2 "x86_64_general_operand" "")))
816 (set (pc) (if_then_else
817 (match_operator 0 "comparison_operator"
820 (label_ref (match_operand 3 "" ""))
824 if (MEM_P (operands[1]) && MEM_P (operands[2]))
825 operands[1] = force_reg (DImode, operands[1]);
826 ix86_compare_op0 = operands[1];
827 ix86_compare_op1 = operands[2];
828 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
832 (define_expand "cstoredi4"
833 [(set (reg:CC FLAGS_REG)
834 (compare:CC (match_operand:DI 2 "nonimmediate_operand" "")
835 (match_operand:DI 3 "x86_64_general_operand" "")))
836 (set (match_operand:QI 0 "register_operand" "")
837 (match_operator 1 "comparison_operator"
842 if (MEM_P (operands[2]) && MEM_P (operands[3]))
843 operands[2] = force_reg (DImode, operands[2]);
844 ix86_compare_op0 = operands[2];
845 ix86_compare_op1 = operands[3];
846 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
850 (define_expand "cbranchsi4"
851 [(set (reg:CC FLAGS_REG)
852 (compare:CC (match_operand:SI 1 "cmpsi_operand" "")
853 (match_operand:SI 2 "general_operand" "")))
854 (set (pc) (if_then_else
855 (match_operator 0 "comparison_operator"
858 (label_ref (match_operand 3 "" ""))
862 if (MEM_P (operands[1]) && MEM_P (operands[2]))
863 operands[1] = force_reg (SImode, operands[1]);
864 ix86_compare_op0 = operands[1];
865 ix86_compare_op1 = operands[2];
866 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
870 (define_expand "cstoresi4"
871 [(set (reg:CC FLAGS_REG)
872 (compare:CC (match_operand:SI 2 "cmpsi_operand" "")
873 (match_operand:SI 3 "general_operand" "")))
874 (set (match_operand:QI 0 "register_operand" "")
875 (match_operator 1 "comparison_operator"
880 if (MEM_P (operands[2]) && MEM_P (operands[3]))
881 operands[2] = force_reg (SImode, operands[2]);
882 ix86_compare_op0 = operands[2];
883 ix86_compare_op1 = operands[3];
884 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
888 (define_expand "cbranchhi4"
889 [(set (reg:CC FLAGS_REG)
890 (compare:CC (match_operand:HI 1 "nonimmediate_operand" "")
891 (match_operand:HI 2 "general_operand" "")))
892 (set (pc) (if_then_else
893 (match_operator 0 "comparison_operator"
896 (label_ref (match_operand 3 "" ""))
900 if (MEM_P (operands[1]) && MEM_P (operands[2]))
901 operands[1] = force_reg (HImode, operands[1]);
902 ix86_compare_op0 = operands[1];
903 ix86_compare_op1 = operands[2];
904 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
908 (define_expand "cstorehi4"
909 [(set (reg:CC FLAGS_REG)
910 (compare:CC (match_operand:HI 2 "nonimmediate_operand" "")
911 (match_operand:HI 3 "general_operand" "")))
912 (set (match_operand:QI 0 "register_operand" "")
913 (match_operator 1 "comparison_operator"
918 if (MEM_P (operands[2]) && MEM_P (operands[3]))
919 operands[2] = force_reg (HImode, operands[2]);
920 ix86_compare_op0 = operands[2];
921 ix86_compare_op1 = operands[3];
922 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
927 (define_expand "cbranchqi4"
928 [(set (reg:CC FLAGS_REG)
929 (compare:CC (match_operand:QI 1 "nonimmediate_operand" "")
930 (match_operand:QI 2 "general_operand" "")))
931 (set (pc) (if_then_else
932 (match_operator 0 "comparison_operator"
935 (label_ref (match_operand 3 "" ""))
939 if (MEM_P (operands[1]) && MEM_P (operands[2]))
940 operands[1] = force_reg (QImode, operands[1]);
941 ix86_compare_op0 = operands[1];
942 ix86_compare_op1 = operands[2];
943 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
948 (define_expand "cstoreqi4"
949 [(set (reg:CC FLAGS_REG)
950 (compare:CC (match_operand:QI 2 "nonimmediate_operand" "")
951 (match_operand:QI 3 "general_operand" "")))
952 (set (match_operand:QI 0 "register_operand" "")
953 (match_operator 1 "comparison_operator"
958 if (MEM_P (operands[2]) && MEM_P (operands[3]))
959 operands[2] = force_reg (QImode, operands[2]);
960 ix86_compare_op0 = operands[2];
961 ix86_compare_op1 = operands[3];
962 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
967 (define_insn "cmpdi_ccno_1_rex64"
968 [(set (reg FLAGS_REG)
969 (compare (match_operand:DI 0 "nonimmediate_operand" "r,?mr")
970 (match_operand:DI 1 "const0_operand" "")))]
971 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
974 cmp{q}\t{%1, %0|%0, %1}"
975 [(set_attr "type" "test,icmp")
976 (set_attr "length_immediate" "0,1")
977 (set_attr "mode" "DI")])
979 (define_insn "*cmpdi_minus_1_rex64"
980 [(set (reg FLAGS_REG)
981 (compare (minus:DI (match_operand:DI 0 "nonimmediate_operand" "rm,r")
982 (match_operand:DI 1 "x86_64_general_operand" "re,mr"))
984 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)"
985 "cmp{q}\t{%1, %0|%0, %1}"
986 [(set_attr "type" "icmp")
987 (set_attr "mode" "DI")])
989 (define_expand "cmpdi_1_rex64"
990 [(set (reg:CC FLAGS_REG)
991 (compare:CC (match_operand:DI 0 "nonimmediate_operand" "")
992 (match_operand:DI 1 "general_operand" "")))]
996 (define_insn "cmpdi_1_insn_rex64"
997 [(set (reg FLAGS_REG)
998 (compare (match_operand:DI 0 "nonimmediate_operand" "mr,r")
999 (match_operand:DI 1 "x86_64_general_operand" "re,mr")))]
1000 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1001 "cmp{q}\t{%1, %0|%0, %1}"
1002 [(set_attr "type" "icmp")
1003 (set_attr "mode" "DI")])
1006 (define_insn "*cmpsi_ccno_1"
1007 [(set (reg FLAGS_REG)
1008 (compare (match_operand:SI 0 "nonimmediate_operand" "r,?mr")
1009 (match_operand:SI 1 "const0_operand" "")))]
1010 "ix86_match_ccmode (insn, CCNOmode)"
1013 cmp{l}\t{%1, %0|%0, %1}"
1014 [(set_attr "type" "test,icmp")
1015 (set_attr "length_immediate" "0,1")
1016 (set_attr "mode" "SI")])
1018 (define_insn "*cmpsi_minus_1"
1019 [(set (reg FLAGS_REG)
1020 (compare (minus:SI (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1021 (match_operand:SI 1 "general_operand" "ri,mr"))
1023 "ix86_match_ccmode (insn, CCGOCmode)"
1024 "cmp{l}\t{%1, %0|%0, %1}"
1025 [(set_attr "type" "icmp")
1026 (set_attr "mode" "SI")])
1028 (define_expand "cmpsi_1"
1029 [(set (reg:CC FLAGS_REG)
1030 (compare:CC (match_operand:SI 0 "nonimmediate_operand" "")
1031 (match_operand:SI 1 "general_operand" "")))]
1035 (define_insn "*cmpsi_1_insn"
1036 [(set (reg FLAGS_REG)
1037 (compare (match_operand:SI 0 "nonimmediate_operand" "rm,r")
1038 (match_operand:SI 1 "general_operand" "ri,mr")))]
1039 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1040 && ix86_match_ccmode (insn, CCmode)"
1041 "cmp{l}\t{%1, %0|%0, %1}"
1042 [(set_attr "type" "icmp")
1043 (set_attr "mode" "SI")])
1045 (define_insn "*cmphi_ccno_1"
1046 [(set (reg FLAGS_REG)
1047 (compare (match_operand:HI 0 "nonimmediate_operand" "r,?mr")
1048 (match_operand:HI 1 "const0_operand" "")))]
1049 "ix86_match_ccmode (insn, CCNOmode)"
1052 cmp{w}\t{%1, %0|%0, %1}"
1053 [(set_attr "type" "test,icmp")
1054 (set_attr "length_immediate" "0,1")
1055 (set_attr "mode" "HI")])
1057 (define_insn "*cmphi_minus_1"
1058 [(set (reg FLAGS_REG)
1059 (compare (minus:HI (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1060 (match_operand:HI 1 "general_operand" "rn,mr"))
1062 "ix86_match_ccmode (insn, CCGOCmode)"
1063 "cmp{w}\t{%1, %0|%0, %1}"
1064 [(set_attr "type" "icmp")
1065 (set_attr "mode" "HI")])
1067 (define_insn "*cmphi_1"
1068 [(set (reg FLAGS_REG)
1069 (compare (match_operand:HI 0 "nonimmediate_operand" "rm,r")
1070 (match_operand:HI 1 "general_operand" "rn,mr")))]
1071 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1072 && ix86_match_ccmode (insn, CCmode)"
1073 "cmp{w}\t{%1, %0|%0, %1}"
1074 [(set_attr "type" "icmp")
1075 (set_attr "mode" "HI")])
1077 (define_insn "*cmpqi_ccno_1"
1078 [(set (reg FLAGS_REG)
1079 (compare (match_operand:QI 0 "nonimmediate_operand" "q,?mq")
1080 (match_operand:QI 1 "const0_operand" "")))]
1081 "ix86_match_ccmode (insn, CCNOmode)"
1084 cmp{b}\t{$0, %0|%0, 0}"
1085 [(set_attr "type" "test,icmp")
1086 (set_attr "length_immediate" "0,1")
1087 (set_attr "mode" "QI")])
1089 (define_insn "*cmpqi_1"
1090 [(set (reg FLAGS_REG)
1091 (compare (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1092 (match_operand:QI 1 "general_operand" "qn,mq")))]
1093 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
1094 && ix86_match_ccmode (insn, CCmode)"
1095 "cmp{b}\t{%1, %0|%0, %1}"
1096 [(set_attr "type" "icmp")
1097 (set_attr "mode" "QI")])
1099 (define_insn "*cmpqi_minus_1"
1100 [(set (reg FLAGS_REG)
1101 (compare (minus:QI (match_operand:QI 0 "nonimmediate_operand" "qm,q")
1102 (match_operand:QI 1 "general_operand" "qn,mq"))
1104 "ix86_match_ccmode (insn, CCGOCmode)"
1105 "cmp{b}\t{%1, %0|%0, %1}"
1106 [(set_attr "type" "icmp")
1107 (set_attr "mode" "QI")])
1109 (define_insn "*cmpqi_ext_1"
1110 [(set (reg FLAGS_REG)
1112 (match_operand:QI 0 "general_operand" "Qm")
1115 (match_operand 1 "ext_register_operand" "Q")
1117 (const_int 8)) 0)))]
1118 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1119 "cmp{b}\t{%h1, %0|%0, %h1}"
1120 [(set_attr "type" "icmp")
1121 (set_attr "mode" "QI")])
1123 (define_insn "*cmpqi_ext_1_rex64"
1124 [(set (reg FLAGS_REG)
1126 (match_operand:QI 0 "register_operand" "Q")
1129 (match_operand 1 "ext_register_operand" "Q")
1131 (const_int 8)) 0)))]
1132 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1133 "cmp{b}\t{%h1, %0|%0, %h1}"
1134 [(set_attr "type" "icmp")
1135 (set_attr "mode" "QI")])
1137 (define_insn "*cmpqi_ext_2"
1138 [(set (reg FLAGS_REG)
1142 (match_operand 0 "ext_register_operand" "Q")
1145 (match_operand:QI 1 "const0_operand" "")))]
1146 "ix86_match_ccmode (insn, CCNOmode)"
1148 [(set_attr "type" "test")
1149 (set_attr "length_immediate" "0")
1150 (set_attr "mode" "QI")])
1152 (define_expand "cmpqi_ext_3"
1153 [(set (reg:CC FLAGS_REG)
1157 (match_operand 0 "ext_register_operand" "")
1160 (match_operand:QI 1 "general_operand" "")))]
1164 (define_insn "cmpqi_ext_3_insn"
1165 [(set (reg FLAGS_REG)
1169 (match_operand 0 "ext_register_operand" "Q")
1172 (match_operand:QI 1 "general_operand" "Qmn")))]
1173 "!TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1174 "cmp{b}\t{%1, %h0|%h0, %1}"
1175 [(set_attr "type" "icmp")
1176 (set_attr "modrm" "1")
1177 (set_attr "mode" "QI")])
1179 (define_insn "cmpqi_ext_3_insn_rex64"
1180 [(set (reg FLAGS_REG)
1184 (match_operand 0 "ext_register_operand" "Q")
1187 (match_operand:QI 1 "nonmemory_operand" "Qn")))]
1188 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)"
1189 "cmp{b}\t{%1, %h0|%h0, %1}"
1190 [(set_attr "type" "icmp")
1191 (set_attr "modrm" "1")
1192 (set_attr "mode" "QI")])
1194 (define_insn "*cmpqi_ext_4"
1195 [(set (reg FLAGS_REG)
1199 (match_operand 0 "ext_register_operand" "Q")
1204 (match_operand 1 "ext_register_operand" "Q")
1206 (const_int 8)) 0)))]
1207 "ix86_match_ccmode (insn, CCmode)"
1208 "cmp{b}\t{%h1, %h0|%h0, %h1}"
1209 [(set_attr "type" "icmp")
1210 (set_attr "mode" "QI")])
1212 ;; These implement float point compares.
1213 ;; %%% See if we can get away with VOIDmode operands on the actual insns,
1214 ;; which would allow mix and match FP modes on the compares. Which is what
1215 ;; the old patterns did, but with many more of them.
1217 (define_expand "cbranchxf4"
1218 [(set (reg:CC FLAGS_REG)
1219 (compare:CC (match_operand:XF 1 "nonmemory_operand" "")
1220 (match_operand:XF 2 "nonmemory_operand" "")))
1221 (set (pc) (if_then_else
1222 (match_operator 0 "comparison_operator"
1225 (label_ref (match_operand 3 "" ""))
1229 ix86_compare_op0 = operands[1];
1230 ix86_compare_op1 = operands[2];
1231 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1235 (define_expand "cstorexf4"
1236 [(set (reg:CC FLAGS_REG)
1237 (compare:CC (match_operand:XF 2 "nonmemory_operand" "")
1238 (match_operand:XF 3 "nonmemory_operand" "")))
1239 (set (match_operand:QI 0 "register_operand" "")
1240 (match_operator 1 "comparison_operator"
1245 ix86_compare_op0 = operands[2];
1246 ix86_compare_op1 = operands[3];
1247 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1251 (define_expand "cbranch<mode>4"
1252 [(set (reg:CC FLAGS_REG)
1253 (compare:CC (match_operand:MODEF 1 "cmp_fp_expander_operand" "")
1254 (match_operand:MODEF 2 "cmp_fp_expander_operand" "")))
1255 (set (pc) (if_then_else
1256 (match_operator 0 "comparison_operator"
1259 (label_ref (match_operand 3 "" ""))
1261 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1263 ix86_compare_op0 = operands[1];
1264 ix86_compare_op1 = operands[2];
1265 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1269 (define_expand "cstore<mode>4"
1270 [(set (reg:CC FLAGS_REG)
1271 (compare:CC (match_operand:MODEF 2 "cmp_fp_expander_operand" "")
1272 (match_operand:MODEF 3 "cmp_fp_expander_operand" "")))
1273 (set (match_operand:QI 0 "register_operand" "")
1274 (match_operator 1 "comparison_operator"
1277 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
1279 ix86_compare_op0 = operands[2];
1280 ix86_compare_op1 = operands[3];
1281 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1285 (define_expand "cbranchcc4"
1286 [(set (pc) (if_then_else
1287 (match_operator 0 "comparison_operator"
1288 [(match_operand 1 "flags_reg_operand" "")
1289 (match_operand 2 "const0_operand" "")])
1290 (label_ref (match_operand 3 "" ""))
1294 ix86_compare_op0 = operands[1];
1295 ix86_compare_op1 = operands[2];
1296 ix86_expand_branch (GET_CODE (operands[0]), operands[3]);
1300 (define_expand "cstorecc4"
1301 [(set (match_operand:QI 0 "register_operand" "")
1302 (match_operator 1 "comparison_operator"
1303 [(match_operand 2 "flags_reg_operand" "")
1304 (match_operand 3 "const0_operand" "")]))]
1307 ix86_compare_op0 = operands[2];
1308 ix86_compare_op1 = operands[3];
1309 ix86_expand_setcc (GET_CODE (operands[1]), operands[0]);
1314 ;; FP compares, step 1:
1315 ;; Set the FP condition codes.
1317 ;; CCFPmode compare with exceptions
1318 ;; CCFPUmode compare with no exceptions
1320 ;; We may not use "#" to split and emit these, since the REG_DEAD notes
1321 ;; used to manage the reg stack popping would not be preserved.
1323 (define_insn "*cmpfp_0"
1324 [(set (match_operand:HI 0 "register_operand" "=a")
1327 (match_operand 1 "register_operand" "f")
1328 (match_operand 2 "const0_operand" ""))]
1330 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1331 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1332 "* return output_fp_compare (insn, operands, 0, 0);"
1333 [(set_attr "type" "multi")
1334 (set_attr "unit" "i387")
1336 (cond [(match_operand:SF 1 "" "")
1338 (match_operand:DF 1 "" "")
1341 (const_string "XF")))])
1343 (define_insn_and_split "*cmpfp_0_cc"
1344 [(set (reg:CCFP FLAGS_REG)
1346 (match_operand 1 "register_operand" "f")
1347 (match_operand 2 "const0_operand" "")))
1348 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1349 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1350 && TARGET_SAHF && !TARGET_CMOVE
1351 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1353 "&& reload_completed"
1356 [(compare:CCFP (match_dup 1)(match_dup 2))]
1358 (set (reg:CC FLAGS_REG)
1359 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1361 [(set_attr "type" "multi")
1362 (set_attr "unit" "i387")
1364 (cond [(match_operand:SF 1 "" "")
1366 (match_operand:DF 1 "" "")
1369 (const_string "XF")))])
1371 (define_insn "*cmpfp_xf"
1372 [(set (match_operand:HI 0 "register_operand" "=a")
1375 (match_operand:XF 1 "register_operand" "f")
1376 (match_operand:XF 2 "register_operand" "f"))]
1379 "* return output_fp_compare (insn, operands, 0, 0);"
1380 [(set_attr "type" "multi")
1381 (set_attr "unit" "i387")
1382 (set_attr "mode" "XF")])
1384 (define_insn_and_split "*cmpfp_xf_cc"
1385 [(set (reg:CCFP FLAGS_REG)
1387 (match_operand:XF 1 "register_operand" "f")
1388 (match_operand:XF 2 "register_operand" "f")))
1389 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1391 && TARGET_SAHF && !TARGET_CMOVE"
1393 "&& reload_completed"
1396 [(compare:CCFP (match_dup 1)(match_dup 2))]
1398 (set (reg:CC FLAGS_REG)
1399 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1401 [(set_attr "type" "multi")
1402 (set_attr "unit" "i387")
1403 (set_attr "mode" "XF")])
1405 (define_insn "*cmpfp_<mode>"
1406 [(set (match_operand:HI 0 "register_operand" "=a")
1409 (match_operand:MODEF 1 "register_operand" "f")
1410 (match_operand:MODEF 2 "nonimmediate_operand" "fm"))]
1413 "* return output_fp_compare (insn, operands, 0, 0);"
1414 [(set_attr "type" "multi")
1415 (set_attr "unit" "i387")
1416 (set_attr "mode" "<MODE>")])
1418 (define_insn_and_split "*cmpfp_<mode>_cc"
1419 [(set (reg:CCFP FLAGS_REG)
1421 (match_operand:MODEF 1 "register_operand" "f")
1422 (match_operand:MODEF 2 "nonimmediate_operand" "fm")))
1423 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1425 && TARGET_SAHF && !TARGET_CMOVE"
1427 "&& reload_completed"
1430 [(compare:CCFP (match_dup 1)(match_dup 2))]
1432 (set (reg:CC FLAGS_REG)
1433 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1435 [(set_attr "type" "multi")
1436 (set_attr "unit" "i387")
1437 (set_attr "mode" "<MODE>")])
1439 (define_insn "*cmpfp_u"
1440 [(set (match_operand:HI 0 "register_operand" "=a")
1443 (match_operand 1 "register_operand" "f")
1444 (match_operand 2 "register_operand" "f"))]
1446 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1447 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1448 "* return output_fp_compare (insn, operands, 0, 1);"
1449 [(set_attr "type" "multi")
1450 (set_attr "unit" "i387")
1452 (cond [(match_operand:SF 1 "" "")
1454 (match_operand:DF 1 "" "")
1457 (const_string "XF")))])
1459 (define_insn_and_split "*cmpfp_u_cc"
1460 [(set (reg:CCFPU FLAGS_REG)
1462 (match_operand 1 "register_operand" "f")
1463 (match_operand 2 "register_operand" "f")))
1464 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1465 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1466 && TARGET_SAHF && !TARGET_CMOVE
1467 && GET_MODE (operands[1]) == GET_MODE (operands[2])"
1469 "&& reload_completed"
1472 [(compare:CCFPU (match_dup 1)(match_dup 2))]
1474 (set (reg:CC FLAGS_REG)
1475 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1477 [(set_attr "type" "multi")
1478 (set_attr "unit" "i387")
1480 (cond [(match_operand:SF 1 "" "")
1482 (match_operand:DF 1 "" "")
1485 (const_string "XF")))])
1487 (define_insn "*cmpfp_<mode>"
1488 [(set (match_operand:HI 0 "register_operand" "=a")
1491 (match_operand 1 "register_operand" "f")
1492 (match_operator 3 "float_operator"
1493 [(match_operand:X87MODEI12 2 "memory_operand" "m")]))]
1495 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1496 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1497 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1498 "* return output_fp_compare (insn, operands, 0, 0);"
1499 [(set_attr "type" "multi")
1500 (set_attr "unit" "i387")
1501 (set_attr "fp_int_src" "true")
1502 (set_attr "mode" "<MODE>")])
1504 (define_insn_and_split "*cmpfp_<mode>_cc"
1505 [(set (reg:CCFP FLAGS_REG)
1507 (match_operand 1 "register_operand" "f")
1508 (match_operator 3 "float_operator"
1509 [(match_operand:X87MODEI12 2 "memory_operand" "m")])))
1510 (clobber (match_operand:HI 0 "register_operand" "=a"))]
1511 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
1512 && TARGET_SAHF && !TARGET_CMOVE
1513 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
1514 && (GET_MODE (operands [3]) == GET_MODE (operands[1]))"
1516 "&& reload_completed"
1521 (match_op_dup 3 [(match_dup 2)]))]
1523 (set (reg:CC FLAGS_REG)
1524 (unspec:CC [(match_dup 0)] UNSPEC_SAHF))]
1526 [(set_attr "type" "multi")
1527 (set_attr "unit" "i387")
1528 (set_attr "fp_int_src" "true")
1529 (set_attr "mode" "<MODE>")])
1531 ;; FP compares, step 2
1532 ;; Move the fpsw to ax.
1534 (define_insn "x86_fnstsw_1"
1535 [(set (match_operand:HI 0 "register_operand" "=a")
1536 (unspec:HI [(reg:CCFP FPSR_REG)] UNSPEC_FNSTSW))]
1539 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
1540 (set_attr "mode" "SI")
1541 (set_attr "unit" "i387")])
1543 ;; FP compares, step 3
1544 ;; Get ax into flags, general case.
1546 (define_insn "x86_sahf_1"
1547 [(set (reg:CC FLAGS_REG)
1548 (unspec:CC [(match_operand:HI 0 "register_operand" "a")]
1552 #ifdef HAVE_AS_IX86_SAHF
1555 return ".byte\t0x9e";
1558 [(set_attr "length" "1")
1559 (set_attr "athlon_decode" "vector")
1560 (set_attr "amdfam10_decode" "direct")
1561 (set_attr "mode" "SI")])
1563 ;; Pentium Pro can do steps 1 through 3 in one go.
1564 ;; comi*, ucomi*, fcomi*, ficomi*,fucomi* (i387 instructions set condition codes)
1565 (define_insn "*cmpfp_i_mixed"
1566 [(set (reg:CCFP FLAGS_REG)
1567 (compare:CCFP (match_operand 0 "register_operand" "f,x")
1568 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1569 "TARGET_MIX_SSE_I387
1570 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1571 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1572 "* return output_fp_compare (insn, operands, 1, 0);"
1573 [(set_attr "type" "fcmp,ssecomi")
1574 (set_attr "prefix" "orig,maybe_vex")
1576 (if_then_else (match_operand:SF 1 "" "")
1578 (const_string "DF")))
1579 (set (attr "prefix_rep")
1580 (if_then_else (eq_attr "type" "ssecomi")
1582 (const_string "*")))
1583 (set (attr "prefix_data16")
1584 (cond [(eq_attr "type" "fcmp")
1586 (eq_attr "mode" "DF")
1589 (const_string "0")))
1590 (set_attr "athlon_decode" "vector")
1591 (set_attr "amdfam10_decode" "direct")])
1593 (define_insn "*cmpfp_i_sse"
1594 [(set (reg:CCFP FLAGS_REG)
1595 (compare:CCFP (match_operand 0 "register_operand" "x")
1596 (match_operand 1 "nonimmediate_operand" "xm")))]
1598 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1599 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1600 "* return output_fp_compare (insn, operands, 1, 0);"
1601 [(set_attr "type" "ssecomi")
1602 (set_attr "prefix" "maybe_vex")
1604 (if_then_else (match_operand:SF 1 "" "")
1606 (const_string "DF")))
1607 (set_attr "prefix_rep" "0")
1608 (set (attr "prefix_data16")
1609 (if_then_else (eq_attr "mode" "DF")
1611 (const_string "0")))
1612 (set_attr "athlon_decode" "vector")
1613 (set_attr "amdfam10_decode" "direct")])
1615 (define_insn "*cmpfp_i_i387"
1616 [(set (reg:CCFP FLAGS_REG)
1617 (compare:CCFP (match_operand 0 "register_operand" "f")
1618 (match_operand 1 "register_operand" "f")))]
1619 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1621 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1622 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1623 "* return output_fp_compare (insn, operands, 1, 0);"
1624 [(set_attr "type" "fcmp")
1626 (cond [(match_operand:SF 1 "" "")
1628 (match_operand:DF 1 "" "")
1631 (const_string "XF")))
1632 (set_attr "athlon_decode" "vector")
1633 (set_attr "amdfam10_decode" "direct")])
1635 (define_insn "*cmpfp_iu_mixed"
1636 [(set (reg:CCFPU FLAGS_REG)
1637 (compare:CCFPU (match_operand 0 "register_operand" "f,x")
1638 (match_operand 1 "nonimmediate_operand" "f,xm")))]
1639 "TARGET_MIX_SSE_I387
1640 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1641 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1642 "* return output_fp_compare (insn, operands, 1, 1);"
1643 [(set_attr "type" "fcmp,ssecomi")
1644 (set_attr "prefix" "orig,maybe_vex")
1646 (if_then_else (match_operand:SF 1 "" "")
1648 (const_string "DF")))
1649 (set (attr "prefix_rep")
1650 (if_then_else (eq_attr "type" "ssecomi")
1652 (const_string "*")))
1653 (set (attr "prefix_data16")
1654 (cond [(eq_attr "type" "fcmp")
1656 (eq_attr "mode" "DF")
1659 (const_string "0")))
1660 (set_attr "athlon_decode" "vector")
1661 (set_attr "amdfam10_decode" "direct")])
1663 (define_insn "*cmpfp_iu_sse"
1664 [(set (reg:CCFPU FLAGS_REG)
1665 (compare:CCFPU (match_operand 0 "register_operand" "x")
1666 (match_operand 1 "nonimmediate_operand" "xm")))]
1668 && SSE_FLOAT_MODE_P (GET_MODE (operands[0]))
1669 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1670 "* return output_fp_compare (insn, operands, 1, 1);"
1671 [(set_attr "type" "ssecomi")
1672 (set_attr "prefix" "maybe_vex")
1674 (if_then_else (match_operand:SF 1 "" "")
1676 (const_string "DF")))
1677 (set_attr "prefix_rep" "0")
1678 (set (attr "prefix_data16")
1679 (if_then_else (eq_attr "mode" "DF")
1681 (const_string "0")))
1682 (set_attr "athlon_decode" "vector")
1683 (set_attr "amdfam10_decode" "direct")])
1685 (define_insn "*cmpfp_iu_387"
1686 [(set (reg:CCFPU FLAGS_REG)
1687 (compare:CCFPU (match_operand 0 "register_operand" "f")
1688 (match_operand 1 "register_operand" "f")))]
1689 "X87_FLOAT_MODE_P (GET_MODE (operands[0]))
1691 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[0])) && TARGET_SSE_MATH)
1692 && GET_MODE (operands[0]) == GET_MODE (operands[1])"
1693 "* return output_fp_compare (insn, operands, 1, 1);"
1694 [(set_attr "type" "fcmp")
1696 (cond [(match_operand:SF 1 "" "")
1698 (match_operand:DF 1 "" "")
1701 (const_string "XF")))
1702 (set_attr "athlon_decode" "vector")
1703 (set_attr "amdfam10_decode" "direct")])
1705 ;; Move instructions.
1707 ;; General case of fullword move.
1709 (define_expand "movsi"
1710 [(set (match_operand:SI 0 "nonimmediate_operand" "")
1711 (match_operand:SI 1 "general_operand" ""))]
1713 "ix86_expand_move (SImode, operands); DONE;")
1715 ;; Push/pop instructions. They are separate since autoinc/dec is not a
1718 ;; %%% We don't use a post-inc memory reference because x86 is not a
1719 ;; general AUTO_INC_DEC host, which impacts how it is treated in flow.
1720 ;; Changing this impacts compiler performance on other non-AUTO_INC_DEC
1721 ;; targets without our curiosities, and it is just as easy to represent
1722 ;; this differently.
1724 (define_insn "*pushsi2"
1725 [(set (match_operand:SI 0 "push_operand" "=<")
1726 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))]
1729 [(set_attr "type" "push")
1730 (set_attr "mode" "SI")])
1732 ;; For 64BIT abi we always round up to 8 bytes.
1733 (define_insn "*pushsi2_rex64"
1734 [(set (match_operand:SI 0 "push_operand" "=X")
1735 (match_operand:SI 1 "nonmemory_no_elim_operand" "ri"))]
1738 [(set_attr "type" "push")
1739 (set_attr "mode" "SI")])
1741 (define_insn "*pushsi2_prologue"
1742 [(set (match_operand:SI 0 "push_operand" "=<")
1743 (match_operand:SI 1 "general_no_elim_operand" "ri*m"))
1744 (clobber (mem:BLK (scratch)))]
1747 [(set_attr "type" "push")
1748 (set_attr "mode" "SI")])
1750 (define_insn "*popsi1_epilogue"
1751 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1752 (mem:SI (reg:SI SP_REG)))
1753 (set (reg:SI SP_REG)
1754 (plus:SI (reg:SI SP_REG) (const_int 4)))
1755 (clobber (mem:BLK (scratch)))]
1758 [(set_attr "type" "pop")
1759 (set_attr "mode" "SI")])
1761 (define_insn "popsi1"
1762 [(set (match_operand:SI 0 "nonimmediate_operand" "=r*m")
1763 (mem:SI (reg:SI SP_REG)))
1764 (set (reg:SI SP_REG)
1765 (plus:SI (reg:SI SP_REG) (const_int 4)))]
1768 [(set_attr "type" "pop")
1769 (set_attr "mode" "SI")])
1771 (define_insn "*movsi_xor"
1772 [(set (match_operand:SI 0 "register_operand" "=r")
1773 (match_operand:SI 1 "const0_operand" ""))
1774 (clobber (reg:CC FLAGS_REG))]
1777 [(set_attr "type" "alu1")
1778 (set_attr "mode" "SI")
1779 (set_attr "length_immediate" "0")])
1781 (define_insn "*movsi_or"
1782 [(set (match_operand:SI 0 "register_operand" "=r")
1783 (match_operand:SI 1 "immediate_operand" "i"))
1784 (clobber (reg:CC FLAGS_REG))]
1786 && operands[1] == constm1_rtx"
1788 operands[1] = constm1_rtx;
1789 return "or{l}\t{%1, %0|%0, %1}";
1791 [(set_attr "type" "alu1")
1792 (set_attr "mode" "SI")
1793 (set_attr "length_immediate" "1")])
1795 (define_insn "*movsi_1"
1796 [(set (match_operand:SI 0 "nonimmediate_operand"
1797 "=r,m ,*y,*y,?rm,?*y,*x,*x,?r ,m ,?*Yi,*x")
1798 (match_operand:SI 1 "general_operand"
1799 "g ,ri,C ,*y,*y ,rm ,C ,*x,*Yi,*x,r ,m "))]
1800 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1802 switch (get_attr_type (insn))
1805 if (get_attr_mode (insn) == MODE_TI)
1806 return "%vpxor\t%0, %d0";
1807 return "%vxorps\t%0, %d0";
1810 switch (get_attr_mode (insn))
1813 return "%vmovdqa\t{%1, %0|%0, %1}";
1815 return "%vmovaps\t{%1, %0|%0, %1}";
1817 return "%vmovd\t{%1, %0|%0, %1}";
1819 return "%vmovss\t{%1, %0|%0, %1}";
1825 return "pxor\t%0, %0";
1828 if (get_attr_mode (insn) == MODE_DI)
1829 return "movq\t{%1, %0|%0, %1}";
1830 return "movd\t{%1, %0|%0, %1}";
1833 return "lea{l}\t{%1, %0|%0, %1}";
1836 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
1837 return "mov{l}\t{%1, %0|%0, %1}";
1841 (cond [(eq_attr "alternative" "2")
1842 (const_string "mmx")
1843 (eq_attr "alternative" "3,4,5")
1844 (const_string "mmxmov")
1845 (eq_attr "alternative" "6")
1846 (const_string "sselog1")
1847 (eq_attr "alternative" "7,8,9,10,11")
1848 (const_string "ssemov")
1849 (match_operand:DI 1 "pic_32bit_operand" "")
1850 (const_string "lea")
1852 (const_string "imov")))
1853 (set (attr "prefix")
1854 (if_then_else (eq_attr "alternative" "0,1,2,3,4,5")
1855 (const_string "orig")
1856 (const_string "maybe_vex")))
1857 (set (attr "prefix_data16")
1858 (if_then_else (and (eq_attr "type" "ssemov") (eq_attr "mode" "SI"))
1860 (const_string "*")))
1862 (cond [(eq_attr "alternative" "2,3")
1864 (eq_attr "alternative" "6,7")
1866 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
1867 (const_string "V4SF")
1868 (const_string "TI"))
1869 (and (eq_attr "alternative" "8,9,10,11")
1870 (eq (symbol_ref "TARGET_SSE2") (const_int 0)))
1873 (const_string "SI")))])
1875 ;; Stores and loads of ax to arbitrary constant address.
1876 ;; We fake an second form of instruction to force reload to load address
1877 ;; into register when rax is not available
1878 (define_insn "*movabssi_1_rex64"
1879 [(set (mem:SI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1880 (match_operand:SI 1 "nonmemory_operand" "a,er"))]
1881 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
1883 movabs{l}\t{%1, %P0|%P0, %1}
1884 mov{l}\t{%1, %a0|%a0, %1}"
1885 [(set_attr "type" "imov")
1886 (set_attr "modrm" "0,*")
1887 (set_attr "length_address" "8,0")
1888 (set_attr "length_immediate" "0,*")
1889 (set_attr "memory" "store")
1890 (set_attr "mode" "SI")])
1892 (define_insn "*movabssi_2_rex64"
1893 [(set (match_operand:SI 0 "register_operand" "=a,r")
1894 (mem:SI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
1895 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
1897 movabs{l}\t{%P1, %0|%0, %P1}
1898 mov{l}\t{%a1, %0|%0, %a1}"
1899 [(set_attr "type" "imov")
1900 (set_attr "modrm" "0,*")
1901 (set_attr "length_address" "8,0")
1902 (set_attr "length_immediate" "0")
1903 (set_attr "memory" "load")
1904 (set_attr "mode" "SI")])
1906 (define_insn "*swapsi"
1907 [(set (match_operand:SI 0 "register_operand" "+r")
1908 (match_operand:SI 1 "register_operand" "+r"))
1913 [(set_attr "type" "imov")
1914 (set_attr "mode" "SI")
1915 (set_attr "pent_pair" "np")
1916 (set_attr "athlon_decode" "vector")
1917 (set_attr "amdfam10_decode" "double")])
1919 (define_expand "movhi"
1920 [(set (match_operand:HI 0 "nonimmediate_operand" "")
1921 (match_operand:HI 1 "general_operand" ""))]
1923 "ix86_expand_move (HImode, operands); DONE;")
1925 (define_insn "*pushhi2"
1926 [(set (match_operand:HI 0 "push_operand" "=X")
1927 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1930 [(set_attr "type" "push")
1931 (set_attr "mode" "SI")])
1933 ;; For 64BIT abi we always round up to 8 bytes.
1934 (define_insn "*pushhi2_rex64"
1935 [(set (match_operand:HI 0 "push_operand" "=X")
1936 (match_operand:HI 1 "nonmemory_no_elim_operand" "rn"))]
1939 [(set_attr "type" "push")
1940 (set_attr "mode" "DI")])
1942 (define_insn "*movhi_1"
1943 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,r,r,m")
1944 (match_operand:HI 1 "general_operand" "r,rn,rm,rn"))]
1945 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
1947 switch (get_attr_type (insn))
1950 /* movzwl is faster than movw on p2 due to partial word stalls,
1951 though not as fast as an aligned movl. */
1952 return "movz{wl|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{w}\t{%1, %0|%0, %1}";
1961 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
1962 (const_string "imov")
1963 (and (eq_attr "alternative" "0")
1964 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1966 (eq (symbol_ref "TARGET_HIMODE_MATH")
1968 (const_string "imov")
1969 (and (eq_attr "alternative" "1,2")
1970 (match_operand:HI 1 "aligned_operand" ""))
1971 (const_string "imov")
1972 (and (ne (symbol_ref "TARGET_MOVX")
1974 (eq_attr "alternative" "0,2"))
1975 (const_string "imovx")
1977 (const_string "imov")))
1979 (cond [(eq_attr "type" "imovx")
1981 (and (eq_attr "alternative" "1,2")
1982 (match_operand:HI 1 "aligned_operand" ""))
1984 (and (eq_attr "alternative" "0")
1985 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
1987 (eq (symbol_ref "TARGET_HIMODE_MATH")
1991 (const_string "HI")))])
1993 ;; Stores and loads of ax to arbitrary constant address.
1994 ;; We fake an second form of instruction to force reload to load address
1995 ;; into register when rax is not available
1996 (define_insn "*movabshi_1_rex64"
1997 [(set (mem:HI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
1998 (match_operand:HI 1 "nonmemory_operand" "a,er"))]
1999 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2001 movabs{w}\t{%1, %P0|%P0, %1}
2002 mov{w}\t{%1, %a0|%a0, %1}"
2003 [(set_attr "type" "imov")
2004 (set_attr "modrm" "0,*")
2005 (set_attr "length_address" "8,0")
2006 (set_attr "length_immediate" "0,*")
2007 (set_attr "memory" "store")
2008 (set_attr "mode" "HI")])
2010 (define_insn "*movabshi_2_rex64"
2011 [(set (match_operand:HI 0 "register_operand" "=a,r")
2012 (mem:HI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2013 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2015 movabs{w}\t{%P1, %0|%0, %P1}
2016 mov{w}\t{%a1, %0|%0, %a1}"
2017 [(set_attr "type" "imov")
2018 (set_attr "modrm" "0,*")
2019 (set_attr "length_address" "8,0")
2020 (set_attr "length_immediate" "0")
2021 (set_attr "memory" "load")
2022 (set_attr "mode" "HI")])
2024 (define_insn "*swaphi_1"
2025 [(set (match_operand:HI 0 "register_operand" "+r")
2026 (match_operand:HI 1 "register_operand" "+r"))
2029 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2031 [(set_attr "type" "imov")
2032 (set_attr "mode" "SI")
2033 (set_attr "pent_pair" "np")
2034 (set_attr "athlon_decode" "vector")
2035 (set_attr "amdfam10_decode" "double")])
2037 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2038 (define_insn "*swaphi_2"
2039 [(set (match_operand:HI 0 "register_operand" "+r")
2040 (match_operand:HI 1 "register_operand" "+r"))
2043 "TARGET_PARTIAL_REG_STALL"
2045 [(set_attr "type" "imov")
2046 (set_attr "mode" "HI")
2047 (set_attr "pent_pair" "np")
2048 (set_attr "athlon_decode" "vector")])
2050 (define_expand "movstricthi"
2051 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" ""))
2052 (match_operand:HI 1 "general_operand" ""))]
2055 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2057 /* Don't generate memory->memory moves, go through a register */
2058 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2059 operands[1] = force_reg (HImode, operands[1]);
2062 (define_insn "*movstricthi_1"
2063 [(set (strict_low_part (match_operand:HI 0 "nonimmediate_operand" "+rm,r"))
2064 (match_operand:HI 1 "general_operand" "rn,m"))]
2065 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2066 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2067 "mov{w}\t{%1, %0|%0, %1}"
2068 [(set_attr "type" "imov")
2069 (set_attr "mode" "HI")])
2071 (define_insn "*movstricthi_xor"
2072 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
2073 (match_operand:HI 1 "const0_operand" ""))
2074 (clobber (reg:CC FLAGS_REG))]
2077 [(set_attr "type" "alu1")
2078 (set_attr "mode" "HI")
2079 (set_attr "length_immediate" "0")])
2081 (define_expand "movqi"
2082 [(set (match_operand:QI 0 "nonimmediate_operand" "")
2083 (match_operand:QI 1 "general_operand" ""))]
2085 "ix86_expand_move (QImode, operands); DONE;")
2087 ;; emit_push_insn when it calls move_by_pieces requires an insn to
2088 ;; "push a byte". But actually we use pushl, which has the effect
2089 ;; of rounding the amount pushed up to a word.
2091 (define_insn "*pushqi2"
2092 [(set (match_operand:QI 0 "push_operand" "=X")
2093 (match_operand:QI 1 "nonmemory_no_elim_operand" "rn"))]
2096 [(set_attr "type" "push")
2097 (set_attr "mode" "SI")])
2099 ;; For 64BIT abi we always round up to 8 bytes.
2100 (define_insn "*pushqi2_rex64"
2101 [(set (match_operand:QI 0 "push_operand" "=X")
2102 (match_operand:QI 1 "nonmemory_no_elim_operand" "qn"))]
2105 [(set_attr "type" "push")
2106 (set_attr "mode" "DI")])
2108 ;; Situation is quite tricky about when to choose full sized (SImode) move
2109 ;; over QImode moves. For Q_REG -> Q_REG move we use full size only for
2110 ;; partial register dependency machines (such as AMD Athlon), where QImode
2111 ;; moves issue extra dependency and for partial register stalls machines
2112 ;; that don't use QImode patterns (and QImode move cause stall on the next
2115 ;; For loads of Q_REG to NONQ_REG we use full sized moves except for partial
2116 ;; register stall machines with, where we use QImode instructions, since
2117 ;; partial register stall can be caused there. Then we use movzx.
2118 (define_insn "*movqi_1"
2119 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,q ,q ,r,r ,?r,m")
2120 (match_operand:QI 1 "general_operand" " q,qn,qm,q,rn,qm,qn"))]
2121 "!(MEM_P (operands[0]) && MEM_P (operands[1]))"
2123 switch (get_attr_type (insn))
2126 gcc_assert (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]));
2127 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
2129 if (get_attr_mode (insn) == MODE_SI)
2130 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2132 return "mov{b}\t{%1, %0|%0, %1}";
2136 (cond [(and (eq_attr "alternative" "5")
2137 (not (match_operand:QI 1 "aligned_operand" "")))
2138 (const_string "imovx")
2139 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0))
2140 (const_string "imov")
2141 (and (eq_attr "alternative" "3")
2142 (ior (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2144 (eq (symbol_ref "TARGET_QIMODE_MATH")
2146 (const_string "imov")
2147 (eq_attr "alternative" "3,5")
2148 (const_string "imovx")
2149 (and (ne (symbol_ref "TARGET_MOVX")
2151 (eq_attr "alternative" "2"))
2152 (const_string "imovx")
2154 (const_string "imov")))
2156 (cond [(eq_attr "alternative" "3,4,5")
2158 (eq_attr "alternative" "6")
2160 (eq_attr "type" "imovx")
2162 (and (eq_attr "type" "imov")
2163 (and (eq_attr "alternative" "0,1")
2164 (and (ne (symbol_ref "TARGET_PARTIAL_REG_DEPENDENCY")
2166 (and (eq (symbol_ref "optimize_function_for_size_p (cfun)")
2168 (eq (symbol_ref "TARGET_PARTIAL_REG_STALL")
2171 ;; Avoid partial register stalls when not using QImode arithmetic
2172 (and (eq_attr "type" "imov")
2173 (and (eq_attr "alternative" "0,1")
2174 (and (ne (symbol_ref "TARGET_PARTIAL_REG_STALL")
2176 (eq (symbol_ref "TARGET_QIMODE_MATH")
2180 (const_string "QI")))])
2182 (define_insn "*swapqi_1"
2183 [(set (match_operand:QI 0 "register_operand" "+r")
2184 (match_operand:QI 1 "register_operand" "+r"))
2187 "!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun)"
2189 [(set_attr "type" "imov")
2190 (set_attr "mode" "SI")
2191 (set_attr "pent_pair" "np")
2192 (set_attr "athlon_decode" "vector")
2193 (set_attr "amdfam10_decode" "vector")])
2195 ;; Not added amdfam10_decode since TARGET_PARTIAL_REG_STALL is disabled for AMDFAM10
2196 (define_insn "*swapqi_2"
2197 [(set (match_operand:QI 0 "register_operand" "+q")
2198 (match_operand:QI 1 "register_operand" "+q"))
2201 "TARGET_PARTIAL_REG_STALL"
2203 [(set_attr "type" "imov")
2204 (set_attr "mode" "QI")
2205 (set_attr "pent_pair" "np")
2206 (set_attr "athlon_decode" "vector")])
2208 (define_expand "movstrictqi"
2209 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
2210 (match_operand:QI 1 "general_operand" ""))]
2213 if (TARGET_PARTIAL_REG_STALL && optimize_function_for_speed_p (cfun))
2215 /* Don't generate memory->memory moves, go through a register. */
2216 if (MEM_P (operands[0]) && MEM_P (operands[1]))
2217 operands[1] = force_reg (QImode, operands[1]);
2220 (define_insn "*movstrictqi_1"
2221 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
2222 (match_operand:QI 1 "general_operand" "*qn,m"))]
2223 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
2224 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2225 "mov{b}\t{%1, %0|%0, %1}"
2226 [(set_attr "type" "imov")
2227 (set_attr "mode" "QI")])
2229 (define_insn "*movstrictqi_xor"
2230 [(set (strict_low_part (match_operand:QI 0 "q_regs_operand" "+q"))
2231 (match_operand:QI 1 "const0_operand" ""))
2232 (clobber (reg:CC FLAGS_REG))]
2235 [(set_attr "type" "alu1")
2236 (set_attr "mode" "QI")
2237 (set_attr "length_immediate" "0")])
2239 (define_insn "*movsi_extv_1"
2240 [(set (match_operand:SI 0 "register_operand" "=R")
2241 (sign_extract:SI (match_operand 1 "ext_register_operand" "Q")
2245 "movs{bl|x}\t{%h1, %0|%0, %h1}"
2246 [(set_attr "type" "imovx")
2247 (set_attr "mode" "SI")])
2249 (define_insn "*movhi_extv_1"
2250 [(set (match_operand:HI 0 "register_operand" "=R")
2251 (sign_extract:HI (match_operand 1 "ext_register_operand" "Q")
2255 "movs{bl|x}\t{%h1, %k0|%k0, %h1}"
2256 [(set_attr "type" "imovx")
2257 (set_attr "mode" "SI")])
2259 (define_insn "*movqi_extv_1"
2260 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?r")
2261 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2266 switch (get_attr_type (insn))
2269 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2271 return "mov{b}\t{%h1, %0|%0, %h1}";
2275 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2276 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2277 (ne (symbol_ref "TARGET_MOVX")
2279 (const_string "imovx")
2280 (const_string "imov")))
2282 (if_then_else (eq_attr "type" "imovx")
2284 (const_string "QI")))])
2286 (define_insn "*movqi_extv_1_rex64"
2287 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2288 (sign_extract:QI (match_operand 1 "ext_register_operand" "Q,Q")
2293 switch (get_attr_type (insn))
2296 return "movs{bl|x}\t{%h1, %k0|%k0, %h1}";
2298 return "mov{b}\t{%h1, %0|%0, %h1}";
2302 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2303 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2304 (ne (symbol_ref "TARGET_MOVX")
2306 (const_string "imovx")
2307 (const_string "imov")))
2309 (if_then_else (eq_attr "type" "imovx")
2311 (const_string "QI")))])
2313 ;; Stores and loads of ax to arbitrary constant address.
2314 ;; We fake an second form of instruction to force reload to load address
2315 ;; into register when rax is not available
2316 (define_insn "*movabsqi_1_rex64"
2317 [(set (mem:QI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2318 (match_operand:QI 1 "nonmemory_operand" "a,er"))]
2319 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2321 movabs{b}\t{%1, %P0|%P0, %1}
2322 mov{b}\t{%1, %a0|%a0, %1}"
2323 [(set_attr "type" "imov")
2324 (set_attr "modrm" "0,*")
2325 (set_attr "length_address" "8,0")
2326 (set_attr "length_immediate" "0,*")
2327 (set_attr "memory" "store")
2328 (set_attr "mode" "QI")])
2330 (define_insn "*movabsqi_2_rex64"
2331 [(set (match_operand:QI 0 "register_operand" "=a,r")
2332 (mem:QI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2333 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2335 movabs{b}\t{%P1, %0|%0, %P1}
2336 mov{b}\t{%a1, %0|%0, %a1}"
2337 [(set_attr "type" "imov")
2338 (set_attr "modrm" "0,*")
2339 (set_attr "length_address" "8,0")
2340 (set_attr "length_immediate" "0")
2341 (set_attr "memory" "load")
2342 (set_attr "mode" "QI")])
2344 (define_insn "*movdi_extzv_1"
2345 [(set (match_operand:DI 0 "register_operand" "=R")
2346 (zero_extract:DI (match_operand 1 "ext_register_operand" "Q")
2350 "movz{bl|x}\t{%h1, %k0|%k0, %h1}"
2351 [(set_attr "type" "imovx")
2352 (set_attr "mode" "SI")])
2354 (define_insn "*movsi_extzv_1"
2355 [(set (match_operand:SI 0 "register_operand" "=R")
2356 (zero_extract:SI (match_operand 1 "ext_register_operand" "Q")
2360 "movz{bl|x}\t{%h1, %0|%0, %h1}"
2361 [(set_attr "type" "imovx")
2362 (set_attr "mode" "SI")])
2364 (define_insn "*movqi_extzv_2"
2365 [(set (match_operand:QI 0 "nonimmediate_operand" "=Qm,?R")
2366 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2371 switch (get_attr_type (insn))
2374 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2376 return "mov{b}\t{%h1, %0|%0, %h1}";
2380 (if_then_else (and (match_operand:QI 0 "register_operand" "")
2381 (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2382 (ne (symbol_ref "TARGET_MOVX")
2384 (const_string "imovx")
2385 (const_string "imov")))
2387 (if_then_else (eq_attr "type" "imovx")
2389 (const_string "QI")))])
2391 (define_insn "*movqi_extzv_2_rex64"
2392 [(set (match_operand:QI 0 "register_operand" "=Q,?R")
2393 (subreg:QI (zero_extract:SI (match_operand 1 "ext_register_operand" "Q,Q")
2398 switch (get_attr_type (insn))
2401 return "movz{bl|x}\t{%h1, %k0|%k0, %h1}";
2403 return "mov{b}\t{%h1, %0|%0, %h1}";
2407 (if_then_else (ior (not (match_operand:QI 0 "q_regs_operand" ""))
2408 (ne (symbol_ref "TARGET_MOVX")
2410 (const_string "imovx")
2411 (const_string "imov")))
2413 (if_then_else (eq_attr "type" "imovx")
2415 (const_string "QI")))])
2417 (define_insn "movsi_insv_1"
2418 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2421 (match_operand:SI 1 "general_operand" "Qmn"))]
2423 "mov{b}\t{%b1, %h0|%h0, %b1}"
2424 [(set_attr "type" "imov")
2425 (set_attr "mode" "QI")])
2427 (define_insn "*movsi_insv_1_rex64"
2428 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2431 (match_operand:SI 1 "nonmemory_operand" "Qn"))]
2433 "mov{b}\t{%b1, %h0|%h0, %b1}"
2434 [(set_attr "type" "imov")
2435 (set_attr "mode" "QI")])
2437 (define_insn "movdi_insv_1_rex64"
2438 [(set (zero_extract:DI (match_operand 0 "ext_register_operand" "+Q")
2441 (match_operand:DI 1 "nonmemory_operand" "Qn"))]
2443 "mov{b}\t{%b1, %h0|%h0, %b1}"
2444 [(set_attr "type" "imov")
2445 (set_attr "mode" "QI")])
2447 (define_insn "*movqi_insv_2"
2448 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "+Q")
2451 (lshiftrt:SI (match_operand:SI 1 "register_operand" "Q")
2454 "mov{b}\t{%h1, %h0|%h0, %h1}"
2455 [(set_attr "type" "imov")
2456 (set_attr "mode" "QI")])
2458 (define_expand "movdi"
2459 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2460 (match_operand:DI 1 "general_operand" ""))]
2462 "ix86_expand_move (DImode, operands); DONE;")
2464 (define_insn "*pushdi"
2465 [(set (match_operand:DI 0 "push_operand" "=<")
2466 (match_operand:DI 1 "general_no_elim_operand" "riF*m"))]
2470 (define_insn "*pushdi2_rex64"
2471 [(set (match_operand:DI 0 "push_operand" "=<,!<")
2472 (match_operand:DI 1 "general_no_elim_operand" "re*m,n"))]
2477 [(set_attr "type" "push,multi")
2478 (set_attr "mode" "DI")])
2480 ;; Convert impossible pushes of immediate to existing instructions.
2481 ;; First try to get scratch register and go through it. In case this
2482 ;; fails, push sign extended lower part first and then overwrite
2483 ;; upper part by 32bit move.
2485 [(match_scratch:DI 2 "r")
2486 (set (match_operand:DI 0 "push_operand" "")
2487 (match_operand:DI 1 "immediate_operand" ""))]
2488 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2489 && !x86_64_immediate_operand (operands[1], DImode)"
2490 [(set (match_dup 2) (match_dup 1))
2491 (set (match_dup 0) (match_dup 2))]
2494 ;; We need to define this as both peepholer and splitter for case
2495 ;; peephole2 pass is not run.
2496 ;; "&& 1" is needed to keep it from matching the previous pattern.
2498 [(set (match_operand:DI 0 "push_operand" "")
2499 (match_operand:DI 1 "immediate_operand" ""))]
2500 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2501 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2502 [(set (match_dup 0) (match_dup 1))
2503 (set (match_dup 2) (match_dup 3))]
2504 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2505 operands[1] = gen_lowpart (DImode, operands[2]);
2506 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2511 [(set (match_operand:DI 0 "push_operand" "")
2512 (match_operand:DI 1 "immediate_operand" ""))]
2513 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2514 ? epilogue_completed : reload_completed)
2515 && !symbolic_operand (operands[1], DImode)
2516 && !x86_64_immediate_operand (operands[1], DImode)"
2517 [(set (match_dup 0) (match_dup 1))
2518 (set (match_dup 2) (match_dup 3))]
2519 "split_di (&operands[1], 1, &operands[2], &operands[3]);
2520 operands[1] = gen_lowpart (DImode, operands[2]);
2521 operands[2] = gen_rtx_MEM (SImode, gen_rtx_PLUS (DImode, stack_pointer_rtx,
2525 (define_insn "*pushdi2_prologue_rex64"
2526 [(set (match_operand:DI 0 "push_operand" "=<")
2527 (match_operand:DI 1 "general_no_elim_operand" "re*m"))
2528 (clobber (mem:BLK (scratch)))]
2531 [(set_attr "type" "push")
2532 (set_attr "mode" "DI")])
2534 (define_insn "*popdi1_epilogue_rex64"
2535 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2536 (mem:DI (reg:DI SP_REG)))
2537 (set (reg:DI SP_REG)
2538 (plus:DI (reg:DI SP_REG) (const_int 8)))
2539 (clobber (mem:BLK (scratch)))]
2542 [(set_attr "type" "pop")
2543 (set_attr "mode" "DI")])
2545 (define_insn "popdi1"
2546 [(set (match_operand:DI 0 "nonimmediate_operand" "=r*m")
2547 (mem:DI (reg:DI SP_REG)))
2548 (set (reg:DI SP_REG)
2549 (plus:DI (reg:DI SP_REG) (const_int 8)))]
2552 [(set_attr "type" "pop")
2553 (set_attr "mode" "DI")])
2555 (define_insn "*movdi_xor_rex64"
2556 [(set (match_operand:DI 0 "register_operand" "=r")
2557 (match_operand:DI 1 "const0_operand" ""))
2558 (clobber (reg:CC FLAGS_REG))]
2560 && reload_completed"
2562 [(set_attr "type" "alu1")
2563 (set_attr "mode" "SI")
2564 (set_attr "length_immediate" "0")])
2566 (define_insn "*movdi_or_rex64"
2567 [(set (match_operand:DI 0 "register_operand" "=r")
2568 (match_operand:DI 1 "const_int_operand" "i"))
2569 (clobber (reg:CC FLAGS_REG))]
2572 && operands[1] == constm1_rtx"
2574 operands[1] = constm1_rtx;
2575 return "or{q}\t{%1, %0|%0, %1}";
2577 [(set_attr "type" "alu1")
2578 (set_attr "mode" "DI")
2579 (set_attr "length_immediate" "1")])
2581 (define_insn "*movdi_2"
2582 [(set (match_operand:DI 0 "nonimmediate_operand"
2583 "=r ,o ,*y,m*y,*y,*Y2,m ,*Y2,*Y2,*x,m ,*x,*x")
2584 (match_operand:DI 1 "general_operand"
2585 "riFo,riF,C ,*y ,m ,C ,*Y2,*Y2,m ,C ,*x,*x,m "))]
2586 "!TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2591 movq\t{%1, %0|%0, %1}
2592 movq\t{%1, %0|%0, %1}
2594 %vmovq\t{%1, %0|%0, %1}
2595 %vmovdqa\t{%1, %0|%0, %1}
2596 %vmovq\t{%1, %0|%0, %1}
2598 movlps\t{%1, %0|%0, %1}
2599 movaps\t{%1, %0|%0, %1}
2600 movlps\t{%1, %0|%0, %1}"
2601 [(set_attr "type" "*,*,mmx,mmxmov,mmxmov,sselog1,ssemov,ssemov,ssemov,sselog1,ssemov,ssemov,ssemov")
2602 (set (attr "prefix")
2603 (if_then_else (eq_attr "alternative" "5,6,7,8")
2604 (const_string "vex")
2605 (const_string "orig")))
2606 (set_attr "mode" "DI,DI,DI,DI,DI,TI,DI,TI,DI,V4SF,V2SF,V4SF,V2SF")])
2609 [(set (match_operand:DI 0 "push_operand" "")
2610 (match_operand:DI 1 "general_operand" ""))]
2611 "!TARGET_64BIT && reload_completed
2612 && (! MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2614 "ix86_split_long_move (operands); DONE;")
2616 ;; %%% This multiword shite has got to go.
2618 [(set (match_operand:DI 0 "nonimmediate_operand" "")
2619 (match_operand:DI 1 "general_operand" ""))]
2620 "!TARGET_64BIT && reload_completed
2621 && (!MMX_REG_P (operands[0]) && !SSE_REG_P (operands[0]))
2622 && (!MMX_REG_P (operands[1]) && !SSE_REG_P (operands[1]))"
2624 "ix86_split_long_move (operands); DONE;")
2626 (define_insn "*movdi_1_rex64"
2627 [(set (match_operand:DI 0 "nonimmediate_operand"
2628 "=r,r ,r,m ,!m,*y,*y,?r ,m ,?*Ym,?*y,*x,*x,?r ,m,?*Yi,*x,?*x,?*Ym")
2629 (match_operand:DI 1 "general_operand"
2630 "Z ,rem,i,re,n ,C ,*y,*Ym,*y,r ,m ,C ,*x,*Yi,*x,r ,m ,*Ym,*x"))]
2631 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2633 switch (get_attr_type (insn))
2636 if (SSE_REG_P (operands[0]))
2637 return "movq2dq\t{%1, %0|%0, %1}";
2639 return "movdq2q\t{%1, %0|%0, %1}";
2644 if (get_attr_mode (insn) == MODE_TI)
2645 return "vmovdqa\t{%1, %0|%0, %1}";
2647 return "vmovq\t{%1, %0|%0, %1}";
2650 if (get_attr_mode (insn) == MODE_TI)
2651 return "movdqa\t{%1, %0|%0, %1}";
2655 /* Moves from and into integer register is done using movd
2656 opcode with REX prefix. */
2657 if (GENERAL_REG_P (operands[0]) || GENERAL_REG_P (operands[1]))
2658 return "movd\t{%1, %0|%0, %1}";
2659 return "movq\t{%1, %0|%0, %1}";
2662 return "%vpxor\t%0, %d0";
2665 return "pxor\t%0, %0";
2671 return "lea{q}\t{%a1, %0|%0, %a1}";
2674 gcc_assert (!flag_pic || LEGITIMATE_PIC_OPERAND_P (operands[1]));
2675 if (get_attr_mode (insn) == MODE_SI)
2676 return "mov{l}\t{%k1, %k0|%k0, %k1}";
2677 else if (which_alternative == 2)
2678 return "movabs{q}\t{%1, %0|%0, %1}";
2680 return "mov{q}\t{%1, %0|%0, %1}";
2684 (cond [(eq_attr "alternative" "5")
2685 (const_string "mmx")
2686 (eq_attr "alternative" "6,7,8,9,10")
2687 (const_string "mmxmov")
2688 (eq_attr "alternative" "11")
2689 (const_string "sselog1")
2690 (eq_attr "alternative" "12,13,14,15,16")
2691 (const_string "ssemov")
2692 (eq_attr "alternative" "17,18")
2693 (const_string "ssecvt")
2694 (eq_attr "alternative" "4")
2695 (const_string "multi")
2696 (match_operand:DI 1 "pic_32bit_operand" "")
2697 (const_string "lea")
2699 (const_string "imov")))
2702 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2704 (const_string "*")))
2705 (set (attr "length_immediate")
2707 (and (eq_attr "alternative" "2") (eq_attr "type" "imov"))
2709 (const_string "*")))
2710 (set_attr "prefix_rex" "*,*,*,*,*,*,*,1,*,1,*,*,*,*,*,*,*,*,*")
2711 (set_attr "prefix_data16" "*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,1,*,*,*")
2712 (set (attr "prefix")
2713 (if_then_else (eq_attr "alternative" "11,12,13,14,15,16")
2714 (const_string "maybe_vex")
2715 (const_string "orig")))
2716 (set_attr "mode" "SI,DI,DI,DI,SI,DI,DI,DI,DI,DI,DI,TI,TI,DI,DI,DI,DI,DI,DI")])
2718 ;; Stores and loads of ax to arbitrary constant address.
2719 ;; We fake an second form of instruction to force reload to load address
2720 ;; into register when rax is not available
2721 (define_insn "*movabsdi_1_rex64"
2722 [(set (mem:DI (match_operand:DI 0 "x86_64_movabs_operand" "i,r"))
2723 (match_operand:DI 1 "nonmemory_operand" "a,er"))]
2724 "TARGET_64BIT && ix86_check_movabs (insn, 0)"
2726 movabs{q}\t{%1, %P0|%P0, %1}
2727 mov{q}\t{%1, %a0|%a0, %1}"
2728 [(set_attr "type" "imov")
2729 (set_attr "modrm" "0,*")
2730 (set_attr "length_address" "8,0")
2731 (set_attr "length_immediate" "0,*")
2732 (set_attr "memory" "store")
2733 (set_attr "mode" "DI")])
2735 (define_insn "*movabsdi_2_rex64"
2736 [(set (match_operand:DI 0 "register_operand" "=a,r")
2737 (mem:DI (match_operand:DI 1 "x86_64_movabs_operand" "i,r")))]
2738 "TARGET_64BIT && ix86_check_movabs (insn, 1)"
2740 movabs{q}\t{%P1, %0|%0, %P1}
2741 mov{q}\t{%a1, %0|%0, %a1}"
2742 [(set_attr "type" "imov")
2743 (set_attr "modrm" "0,*")
2744 (set_attr "length_address" "8,0")
2745 (set_attr "length_immediate" "0")
2746 (set_attr "memory" "load")
2747 (set_attr "mode" "DI")])
2749 ;; Convert impossible stores of immediate to existing instructions.
2750 ;; First try to get scratch register and go through it. In case this
2751 ;; fails, move by 32bit parts.
2753 [(match_scratch:DI 2 "r")
2754 (set (match_operand:DI 0 "memory_operand" "")
2755 (match_operand:DI 1 "immediate_operand" ""))]
2756 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2757 && !x86_64_immediate_operand (operands[1], DImode)"
2758 [(set (match_dup 2) (match_dup 1))
2759 (set (match_dup 0) (match_dup 2))]
2762 ;; We need to define this as both peepholer and splitter for case
2763 ;; peephole2 pass is not run.
2764 ;; "&& 1" is needed to keep it from matching the previous pattern.
2766 [(set (match_operand:DI 0 "memory_operand" "")
2767 (match_operand:DI 1 "immediate_operand" ""))]
2768 "TARGET_64BIT && !symbolic_operand (operands[1], DImode)
2769 && !x86_64_immediate_operand (operands[1], DImode) && 1"
2770 [(set (match_dup 2) (match_dup 3))
2771 (set (match_dup 4) (match_dup 5))]
2772 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2775 [(set (match_operand:DI 0 "memory_operand" "")
2776 (match_operand:DI 1 "immediate_operand" ""))]
2777 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
2778 ? epilogue_completed : reload_completed)
2779 && !symbolic_operand (operands[1], DImode)
2780 && !x86_64_immediate_operand (operands[1], DImode)"
2781 [(set (match_dup 2) (match_dup 3))
2782 (set (match_dup 4) (match_dup 5))]
2783 "split_di (&operands[0], 2, &operands[2], &operands[4]);")
2785 (define_insn "*swapdi_rex64"
2786 [(set (match_operand:DI 0 "register_operand" "+r")
2787 (match_operand:DI 1 "register_operand" "+r"))
2792 [(set_attr "type" "imov")
2793 (set_attr "mode" "DI")
2794 (set_attr "pent_pair" "np")
2795 (set_attr "athlon_decode" "vector")
2796 (set_attr "amdfam10_decode" "double")])
2798 (define_expand "movoi"
2799 [(set (match_operand:OI 0 "nonimmediate_operand" "")
2800 (match_operand:OI 1 "general_operand" ""))]
2802 "ix86_expand_move (OImode, operands); DONE;")
2804 (define_insn "*movoi_internal"
2805 [(set (match_operand:OI 0 "nonimmediate_operand" "=x,x,m")
2806 (match_operand:OI 1 "vector_move_operand" "C,xm,x"))]
2808 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2810 switch (which_alternative)
2813 return "vxorps\t%0, %0, %0";
2816 if (misaligned_operand (operands[0], OImode)
2817 || misaligned_operand (operands[1], OImode))
2818 return "vmovdqu\t{%1, %0|%0, %1}";
2820 return "vmovdqa\t{%1, %0|%0, %1}";
2825 [(set_attr "type" "sselog1,ssemov,ssemov")
2826 (set_attr "prefix" "vex")
2827 (set_attr "mode" "OI")])
2829 (define_expand "movti"
2830 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2831 (match_operand:TI 1 "nonimmediate_operand" ""))]
2832 "TARGET_SSE || TARGET_64BIT"
2835 ix86_expand_move (TImode, operands);
2836 else if (push_operand (operands[0], TImode))
2837 ix86_expand_push (TImode, operands[1]);
2839 ix86_expand_vector_move (TImode, operands);
2843 (define_insn "*movti_internal"
2844 [(set (match_operand:TI 0 "nonimmediate_operand" "=x,x,m")
2845 (match_operand:TI 1 "vector_move_operand" "C,xm,x"))]
2846 "TARGET_SSE && !TARGET_64BIT
2847 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2849 switch (which_alternative)
2852 if (get_attr_mode (insn) == MODE_V4SF)
2853 return "%vxorps\t%0, %d0";
2855 return "%vpxor\t%0, %d0";
2858 /* TDmode values are passed as TImode on the stack. Moving them
2859 to stack may result in unaligned memory access. */
2860 if (misaligned_operand (operands[0], TImode)
2861 || misaligned_operand (operands[1], TImode))
2863 if (get_attr_mode (insn) == MODE_V4SF)
2864 return "%vmovups\t{%1, %0|%0, %1}";
2866 return "%vmovdqu\t{%1, %0|%0, %1}";
2870 if (get_attr_mode (insn) == MODE_V4SF)
2871 return "%vmovaps\t{%1, %0|%0, %1}";
2873 return "%vmovdqa\t{%1, %0|%0, %1}";
2879 [(set_attr "type" "sselog1,ssemov,ssemov")
2880 (set_attr "prefix" "maybe_vex")
2882 (cond [(ior (eq (symbol_ref "TARGET_SSE2") (const_int 0))
2883 (ne (symbol_ref "optimize_function_for_size_p (cfun)") (const_int 0)))
2884 (const_string "V4SF")
2885 (and (eq_attr "alternative" "2")
2886 (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2888 (const_string "V4SF")]
2889 (const_string "TI")))])
2891 (define_insn "*movti_rex64"
2892 [(set (match_operand:TI 0 "nonimmediate_operand" "=!r,o,x,x,xm")
2893 (match_operand:TI 1 "general_operand" "riFo,riF,C,xm,x"))]
2895 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
2897 switch (which_alternative)
2903 if (get_attr_mode (insn) == MODE_V4SF)
2904 return "%vxorps\t%0, %d0";
2906 return "%vpxor\t%0, %d0";
2909 /* TDmode values are passed as TImode on the stack. Moving them
2910 to stack may result in unaligned memory access. */
2911 if (misaligned_operand (operands[0], TImode)
2912 || misaligned_operand (operands[1], TImode))
2914 if (get_attr_mode (insn) == MODE_V4SF)
2915 return "%vmovups\t{%1, %0|%0, %1}";
2917 return "%vmovdqu\t{%1, %0|%0, %1}";
2921 if (get_attr_mode (insn) == MODE_V4SF)
2922 return "%vmovaps\t{%1, %0|%0, %1}";
2924 return "%vmovdqa\t{%1, %0|%0, %1}";
2930 [(set_attr "type" "*,*,sselog1,ssemov,ssemov")
2931 (set_attr "prefix" "*,*,maybe_vex,maybe_vex,maybe_vex")
2933 (cond [(eq_attr "alternative" "2,3")
2935 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2937 (const_string "V4SF")
2938 (const_string "TI"))
2939 (eq_attr "alternative" "4")
2941 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
2943 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
2945 (const_string "V4SF")
2946 (const_string "TI"))]
2947 (const_string "DI")))])
2950 [(set (match_operand:TI 0 "nonimmediate_operand" "")
2951 (match_operand:TI 1 "general_operand" ""))]
2952 "reload_completed && !SSE_REG_P (operands[0])
2953 && !SSE_REG_P (operands[1])"
2955 "ix86_split_long_move (operands); DONE;")
2957 ;; This expands to what emit_move_complex would generate if we didn't
2958 ;; have a movti pattern. Having this avoids problems with reload on
2959 ;; 32-bit targets when SSE is present, but doesn't seem to be harmful
2960 ;; to have around all the time.
2961 (define_expand "movcdi"
2962 [(set (match_operand:CDI 0 "nonimmediate_operand" "")
2963 (match_operand:CDI 1 "general_operand" ""))]
2966 if (push_operand (operands[0], CDImode))
2967 emit_move_complex_push (CDImode, operands[0], operands[1]);
2969 emit_move_complex_parts (operands[0], operands[1]);
2973 (define_expand "movsf"
2974 [(set (match_operand:SF 0 "nonimmediate_operand" "")
2975 (match_operand:SF 1 "general_operand" ""))]
2977 "ix86_expand_move (SFmode, operands); DONE;")
2979 (define_insn "*pushsf"
2980 [(set (match_operand:SF 0 "push_operand" "=<,<,<")
2981 (match_operand:SF 1 "general_no_elim_operand" "f,rFm,x"))]
2984 /* Anything else should be already split before reg-stack. */
2985 gcc_assert (which_alternative == 1);
2986 return "push{l}\t%1";
2988 [(set_attr "type" "multi,push,multi")
2989 (set_attr "unit" "i387,*,*")
2990 (set_attr "mode" "SF,SI,SF")])
2992 (define_insn "*pushsf_rex64"
2993 [(set (match_operand:SF 0 "push_operand" "=X,X,X")
2994 (match_operand:SF 1 "nonmemory_no_elim_operand" "f,rF,x"))]
2997 /* Anything else should be already split before reg-stack. */
2998 gcc_assert (which_alternative == 1);
2999 return "push{q}\t%q1";
3001 [(set_attr "type" "multi,push,multi")
3002 (set_attr "unit" "i387,*,*")
3003 (set_attr "mode" "SF,DI,SF")])
3006 [(set (match_operand:SF 0 "push_operand" "")
3007 (match_operand:SF 1 "memory_operand" ""))]
3009 && MEM_P (operands[1])
3010 && (operands[2] = find_constant_src (insn))"
3015 ;; %%% Kill this when call knows how to work this out.
3017 [(set (match_operand:SF 0 "push_operand" "")
3018 (match_operand:SF 1 "any_fp_register_operand" ""))]
3020 [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
3021 (set (mem:SF (reg:SI SP_REG)) (match_dup 1))])
3024 [(set (match_operand:SF 0 "push_operand" "")
3025 (match_operand:SF 1 "any_fp_register_operand" ""))]
3027 [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
3028 (set (mem:SF (reg:DI SP_REG)) (match_dup 1))])
3030 (define_insn "*movsf_1"
3031 [(set (match_operand:SF 0 "nonimmediate_operand"
3032 "=f,m,f,r ,m ,x,x,x ,m,!*y,!m,!*y,?Yi,?r,!*Ym,!r")
3033 (match_operand:SF 1 "general_operand"
3034 "fm,f,G,rmF,Fr,C,x,xm,x,m ,*y,*y ,r ,Yi,r ,*Ym"))]
3035 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3036 && (reload_in_progress || reload_completed
3037 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3038 || (!TARGET_SSE_MATH && optimize_function_for_size_p (cfun)
3039 && standard_80387_constant_p (operands[1]))
3040 || GET_CODE (operands[1]) != CONST_DOUBLE
3041 || memory_operand (operands[0], SFmode))"
3043 switch (which_alternative)
3047 return output_387_reg_move (insn, operands);
3050 return standard_80387_constant_opcode (operands[1]);
3054 return "mov{l}\t{%1, %0|%0, %1}";
3056 if (get_attr_mode (insn) == MODE_TI)
3057 return "%vpxor\t%0, %d0";
3059 return "%vxorps\t%0, %d0";
3061 if (get_attr_mode (insn) == MODE_V4SF)
3062 return "%vmovaps\t{%1, %0|%0, %1}";
3064 return "%vmovss\t{%1, %d0|%d0, %1}";
3067 return REG_P (operands[1]) ? "vmovss\t{%1, %0, %0|%0, %0, %1}"
3068 : "vmovss\t{%1, %0|%0, %1}";
3070 return "movss\t{%1, %0|%0, %1}";
3072 return "%vmovss\t{%1, %0|%0, %1}";
3074 case 9: case 10: case 14: case 15:
3075 return "movd\t{%1, %0|%0, %1}";
3077 return "%vmovd\t{%1, %0|%0, %1}";
3080 return "movq\t{%1, %0|%0, %1}";
3086 [(set_attr "type" "fmov,fmov,fmov,imov,imov,sselog1,ssemov,ssemov,ssemov,mmxmov,mmxmov,mmxmov,ssemov,ssemov,mmxmov,mmxmov")
3087 (set (attr "prefix")
3088 (if_then_else (eq_attr "alternative" "5,6,7,8,12,13")
3089 (const_string "maybe_vex")
3090 (const_string "orig")))
3092 (cond [(eq_attr "alternative" "3,4,9,10")
3094 (eq_attr "alternative" "5")
3096 (and (and (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3098 (ne (symbol_ref "TARGET_SSE2")
3100 (eq (symbol_ref "optimize_function_for_size_p (cfun)")
3103 (const_string "V4SF"))
3104 /* For architectures resolving dependencies on
3105 whole SSE registers use APS move to break dependency
3106 chains, otherwise use short move to avoid extra work.
3108 Do the same for architectures resolving dependencies on
3109 the parts. While in DF mode it is better to always handle
3110 just register parts, the SF mode is different due to lack
3111 of instructions to load just part of the register. It is
3112 better to maintain the whole registers in single format
3113 to avoid problems on using packed logical operations. */
3114 (eq_attr "alternative" "6")
3116 (ior (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3118 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3120 (const_string "V4SF")
3121 (const_string "SF"))
3122 (eq_attr "alternative" "11")
3123 (const_string "DI")]
3124 (const_string "SF")))])
3126 (define_insn "*swapsf"
3127 [(set (match_operand:SF 0 "fp_register_operand" "+f")
3128 (match_operand:SF 1 "fp_register_operand" "+f"))
3131 "reload_completed || TARGET_80387"
3133 if (STACK_TOP_P (operands[0]))
3138 [(set_attr "type" "fxch")
3139 (set_attr "mode" "SF")])
3141 (define_expand "movdf"
3142 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3143 (match_operand:DF 1 "general_operand" ""))]
3145 "ix86_expand_move (DFmode, operands); DONE;")
3147 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3148 ;; Size of pushdf using integer instructions is 2+2*memory operand size
3149 ;; On the average, pushdf using integers can be still shorter. Allow this
3150 ;; pattern for optimize_size too.
3152 (define_insn "*pushdf_nointeger"
3153 [(set (match_operand:DF 0 "push_operand" "=<,<,<,<")
3154 (match_operand:DF 1 "general_no_elim_operand" "f,Fo,*r,Y2"))]
3155 "!TARGET_64BIT && !TARGET_INTEGER_DFMODE_MOVES"
3157 /* This insn should be already split before reg-stack. */
3160 [(set_attr "type" "multi")
3161 (set_attr "unit" "i387,*,*,*")
3162 (set_attr "mode" "DF,SI,SI,DF")])
3164 (define_insn "*pushdf_integer"
3165 [(set (match_operand:DF 0 "push_operand" "=<,<,<")
3166 (match_operand:DF 1 "general_no_elim_operand" "f,rFo,Y2"))]
3167 "TARGET_64BIT || TARGET_INTEGER_DFMODE_MOVES"
3169 /* This insn should be already split before reg-stack. */
3172 [(set_attr "type" "multi")
3173 (set_attr "unit" "i387,*,*")
3174 (set_attr "mode" "DF,SI,DF")])
3176 ;; %%% Kill this when call knows how to work this out.
3178 [(set (match_operand:DF 0 "push_operand" "")
3179 (match_operand:DF 1 "any_fp_register_operand" ""))]
3181 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
3182 (set (mem:DF (reg:P SP_REG)) (match_dup 1))]
3186 [(set (match_operand:DF 0 "push_operand" "")
3187 (match_operand:DF 1 "general_operand" ""))]
3190 "ix86_split_long_move (operands); DONE;")
3192 ;; Moving is usually shorter when only FP registers are used. This separate
3193 ;; movdf pattern avoids the use of integer registers for FP operations
3194 ;; when optimizing for size.
3196 (define_insn "*movdf_nointeger"
3197 [(set (match_operand:DF 0 "nonimmediate_operand"
3198 "=f,m,f,*r ,o ,Y2*x,Y2*x,Y2*x ,m ")
3199 (match_operand:DF 1 "general_operand"
3200 "fm,f,G,*roF,*Fr,C ,Y2*x,mY2*x,Y2*x"))]
3201 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3202 && ((optimize_function_for_size_p (cfun)
3203 || !TARGET_INTEGER_DFMODE_MOVES) && !TARGET_64BIT)
3204 && (reload_in_progress || reload_completed
3205 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3206 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3207 && optimize_function_for_size_p (cfun)
3208 && !memory_operand (operands[0], DFmode)
3209 && standard_80387_constant_p (operands[1]))
3210 || GET_CODE (operands[1]) != CONST_DOUBLE
3211 || ((optimize_function_for_size_p (cfun)
3212 || !TARGET_MEMORY_MISMATCH_STALL
3213 || reload_in_progress || reload_completed)
3214 && memory_operand (operands[0], DFmode)))"
3216 switch (which_alternative)
3220 return output_387_reg_move (insn, operands);
3223 return standard_80387_constant_opcode (operands[1]);
3229 switch (get_attr_mode (insn))
3232 return "%vxorps\t%0, %d0";
3234 return "%vxorpd\t%0, %d0";
3236 return "%vpxor\t%0, %d0";
3243 switch (get_attr_mode (insn))
3246 return "%vmovaps\t{%1, %0|%0, %1}";
3248 return "%vmovapd\t{%1, %0|%0, %1}";
3250 return "%vmovdqa\t{%1, %0|%0, %1}";
3252 return "%vmovq\t{%1, %0|%0, %1}";
3256 if (REG_P (operands[0]) && REG_P (operands[1]))
3257 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3259 return "vmovsd\t{%1, %0|%0, %1}";
3262 return "movsd\t{%1, %0|%0, %1}";
3266 if (REG_P (operands[0]))
3267 return "vmovlpd\t{%1, %0, %0|%0, %0, %1}";
3269 return "vmovlpd\t{%1, %0|%0, %1}";
3272 return "movlpd\t{%1, %0|%0, %1}";
3276 if (REG_P (operands[0]))
3277 return "vmovlps\t{%1, %0, %0|%0, %0, %1}";
3279 return "vmovlps\t{%1, %0|%0, %1}";
3282 return "movlps\t{%1, %0|%0, %1}";
3291 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3292 (set (attr "prefix")
3293 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3294 (const_string "orig")
3295 (const_string "maybe_vex")))
3296 (set (attr "prefix_data16")
3297 (if_then_else (eq_attr "mode" "V1DF")
3299 (const_string "*")))
3301 (cond [(eq_attr "alternative" "0,1,2")
3303 (eq_attr "alternative" "3,4")
3306 /* For SSE1, we have many fewer alternatives. */
3307 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3308 (cond [(eq_attr "alternative" "5,6")
3309 (const_string "V4SF")
3311 (const_string "V2SF"))
3313 /* xorps is one byte shorter. */
3314 (eq_attr "alternative" "5")
3315 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3317 (const_string "V4SF")
3318 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3322 (const_string "V2DF"))
3324 /* For architectures resolving dependencies on
3325 whole SSE registers use APD move to break dependency
3326 chains, otherwise use short move to avoid extra work.
3328 movaps encodes one byte shorter. */
3329 (eq_attr "alternative" "6")
3331 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3333 (const_string "V4SF")
3334 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3336 (const_string "V2DF")
3338 (const_string "DF"))
3339 /* For architectures resolving dependencies on register
3340 parts we may avoid extra work to zero out upper part
3342 (eq_attr "alternative" "7")
3344 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3346 (const_string "V1DF")
3347 (const_string "DF"))
3349 (const_string "DF")))])
3351 (define_insn "*movdf_integer_rex64"
3352 [(set (match_operand:DF 0 "nonimmediate_operand"
3353 "=f,m,f,r ,m ,Y2*x,Y2*x,Y2*x,m ,Yi,r ")
3354 (match_operand:DF 1 "general_operand"
3355 "fm,f,G,rmF,Fr,C ,Y2*x,m ,Y2*x,r ,Yi"))]
3356 "TARGET_64BIT && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3357 && (reload_in_progress || reload_completed
3358 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3359 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3360 && optimize_function_for_size_p (cfun)
3361 && standard_80387_constant_p (operands[1]))
3362 || GET_CODE (operands[1]) != CONST_DOUBLE
3363 || memory_operand (operands[0], DFmode))"
3365 switch (which_alternative)
3369 return output_387_reg_move (insn, operands);
3372 return standard_80387_constant_opcode (operands[1]);
3379 switch (get_attr_mode (insn))
3382 return "%vxorps\t%0, %d0";
3384 return "%vxorpd\t%0, %d0";
3386 return "%vpxor\t%0, %d0";
3393 switch (get_attr_mode (insn))
3396 return "%vmovaps\t{%1, %0|%0, %1}";
3398 return "%vmovapd\t{%1, %0|%0, %1}";
3400 return "%vmovdqa\t{%1, %0|%0, %1}";
3402 return "%vmovq\t{%1, %0|%0, %1}";
3406 if (REG_P (operands[0]) && REG_P (operands[1]))
3407 return "vmovsd\t{%1, %0, %0|%0, %0, %1}";
3409 return "vmovsd\t{%1, %0|%0, %1}";
3412 return "movsd\t{%1, %0|%0, %1}";
3414 return "%vmovlpd\t{%1, %d0|%d0, %1}";
3416 return "%vmovlps\t{%1, %d0|%d0, %1}";
3423 return "%vmovd\t{%1, %0|%0, %1}";
3429 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov,ssemov,ssemov")
3430 (set (attr "prefix")
3431 (if_then_else (eq_attr "alternative" "0,1,2,3,4")
3432 (const_string "orig")
3433 (const_string "maybe_vex")))
3434 (set (attr "prefix_data16")
3435 (if_then_else (eq_attr "mode" "V1DF")
3437 (const_string "*")))
3439 (cond [(eq_attr "alternative" "0,1,2")
3441 (eq_attr "alternative" "3,4,9,10")
3444 /* For SSE1, we have many fewer alternatives. */
3445 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3446 (cond [(eq_attr "alternative" "5,6")
3447 (const_string "V4SF")
3449 (const_string "V2SF"))
3451 /* xorps is one byte shorter. */
3452 (eq_attr "alternative" "5")
3453 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3455 (const_string "V4SF")
3456 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3460 (const_string "V2DF"))
3462 /* For architectures resolving dependencies on
3463 whole SSE registers use APD move to break dependency
3464 chains, otherwise use short move to avoid extra work.
3466 movaps encodes one byte shorter. */
3467 (eq_attr "alternative" "6")
3469 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3471 (const_string "V4SF")
3472 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3474 (const_string "V2DF")
3476 (const_string "DF"))
3477 /* For architectures resolving dependencies on register
3478 parts we may avoid extra work to zero out upper part
3480 (eq_attr "alternative" "7")
3482 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3484 (const_string "V1DF")
3485 (const_string "DF"))
3487 (const_string "DF")))])
3489 (define_insn "*movdf_integer"
3490 [(set (match_operand:DF 0 "nonimmediate_operand"
3491 "=f,m,f,r ,o ,Y2*x,Y2*x,Y2*x,m ")
3492 (match_operand:DF 1 "general_operand"
3493 "fm,f,G,roF,Fr,C ,Y2*x,m ,Y2*x"))]
3494 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
3495 && optimize_function_for_speed_p (cfun)
3496 && TARGET_INTEGER_DFMODE_MOVES
3497 && (reload_in_progress || reload_completed
3498 || (ix86_cmodel == CM_MEDIUM || ix86_cmodel == CM_LARGE)
3499 || (!(TARGET_SSE2 && TARGET_SSE_MATH)
3500 && optimize_function_for_size_p (cfun)
3501 && standard_80387_constant_p (operands[1]))
3502 || GET_CODE (operands[1]) != CONST_DOUBLE
3503 || memory_operand (operands[0], DFmode))"
3505 switch (which_alternative)
3509 return output_387_reg_move (insn, operands);
3512 return standard_80387_constant_opcode (operands[1]);
3519 switch (get_attr_mode (insn))
3522 return "xorps\t%0, %0";
3524 return "xorpd\t%0, %0";
3526 return "pxor\t%0, %0";
3533 switch (get_attr_mode (insn))
3536 return "movaps\t{%1, %0|%0, %1}";
3538 return "movapd\t{%1, %0|%0, %1}";
3540 return "movdqa\t{%1, %0|%0, %1}";
3542 return "movq\t{%1, %0|%0, %1}";
3544 return "movsd\t{%1, %0|%0, %1}";
3546 return "movlpd\t{%1, %0|%0, %1}";
3548 return "movlps\t{%1, %0|%0, %1}";
3557 [(set_attr "type" "fmov,fmov,fmov,multi,multi,sselog1,ssemov,ssemov,ssemov")
3558 (set (attr "prefix_data16")
3559 (if_then_else (eq_attr "mode" "V1DF")
3561 (const_string "*")))
3563 (cond [(eq_attr "alternative" "0,1,2")
3565 (eq_attr "alternative" "3,4")
3568 /* For SSE1, we have many fewer alternatives. */
3569 (eq (symbol_ref "TARGET_SSE2") (const_int 0))
3570 (cond [(eq_attr "alternative" "5,6")
3571 (const_string "V4SF")
3573 (const_string "V2SF"))
3575 /* xorps is one byte shorter. */
3576 (eq_attr "alternative" "5")
3577 (cond [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3579 (const_string "V4SF")
3580 (ne (symbol_ref "TARGET_SSE_LOAD0_BY_PXOR")
3584 (const_string "V2DF"))
3586 /* For architectures resolving dependencies on
3587 whole SSE registers use APD move to break dependency
3588 chains, otherwise use short move to avoid extra work.
3590 movaps encodes one byte shorter. */
3591 (eq_attr "alternative" "6")
3593 [(ne (symbol_ref "optimize_function_for_size_p (cfun)")
3595 (const_string "V4SF")
3596 (ne (symbol_ref "TARGET_SSE_PARTIAL_REG_DEPENDENCY")
3598 (const_string "V2DF")
3600 (const_string "DF"))
3601 /* For architectures resolving dependencies on register
3602 parts we may avoid extra work to zero out upper part
3604 (eq_attr "alternative" "7")
3606 (ne (symbol_ref "TARGET_SSE_SPLIT_REGS")
3608 (const_string "V1DF")
3609 (const_string "DF"))
3611 (const_string "DF")))])
3614 [(set (match_operand:DF 0 "nonimmediate_operand" "")
3615 (match_operand:DF 1 "general_operand" ""))]
3617 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3618 && ! (ANY_FP_REG_P (operands[0]) ||
3619 (GET_CODE (operands[0]) == SUBREG
3620 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3621 && ! (ANY_FP_REG_P (operands[1]) ||
3622 (GET_CODE (operands[1]) == SUBREG
3623 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3625 "ix86_split_long_move (operands); DONE;")
3627 (define_insn "*swapdf"
3628 [(set (match_operand:DF 0 "fp_register_operand" "+f")
3629 (match_operand:DF 1 "fp_register_operand" "+f"))
3632 "reload_completed || TARGET_80387"
3634 if (STACK_TOP_P (operands[0]))
3639 [(set_attr "type" "fxch")
3640 (set_attr "mode" "DF")])
3642 (define_expand "movxf"
3643 [(set (match_operand:XF 0 "nonimmediate_operand" "")
3644 (match_operand:XF 1 "general_operand" ""))]
3646 "ix86_expand_move (XFmode, operands); DONE;")
3648 ;; Size of pushdf is 3 (for sub) + 2 (for fstp) + memory operand size.
3649 ;; Size of pushdf using integer instructions is 3+3*memory operand size
3650 ;; Pushing using integer instructions is longer except for constants
3651 ;; and direct memory references.
3652 ;; (assuming that any given constant is pushed only once, but this ought to be
3653 ;; handled elsewhere).
3655 (define_insn "*pushxf_nointeger"
3656 [(set (match_operand:XF 0 "push_operand" "=X,X,X")
3657 (match_operand:XF 1 "general_no_elim_operand" "f,Fo,*r"))]
3658 "optimize_function_for_size_p (cfun)"
3660 /* This insn should be already split before reg-stack. */
3663 [(set_attr "type" "multi")
3664 (set_attr "unit" "i387,*,*")
3665 (set_attr "mode" "XF,SI,SI")])
3667 (define_insn "*pushxf_integer"
3668 [(set (match_operand:XF 0 "push_operand" "=<,<")
3669 (match_operand:XF 1 "general_no_elim_operand" "f,ro"))]
3670 "optimize_function_for_speed_p (cfun)"
3672 /* This insn should be already split before reg-stack. */
3675 [(set_attr "type" "multi")
3676 (set_attr "unit" "i387,*")
3677 (set_attr "mode" "XF,SI")])
3680 [(set (match_operand 0 "push_operand" "")
3681 (match_operand 1 "general_operand" ""))]
3683 && (GET_MODE (operands[0]) == XFmode
3684 || GET_MODE (operands[0]) == DFmode)
3685 && !ANY_FP_REG_P (operands[1])"
3687 "ix86_split_long_move (operands); DONE;")
3690 [(set (match_operand:XF 0 "push_operand" "")
3691 (match_operand:XF 1 "any_fp_register_operand" ""))]
3693 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
3694 (set (mem:XF (reg:P SP_REG)) (match_dup 1))]
3695 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
3697 ;; Do not use integer registers when optimizing for size
3698 (define_insn "*movxf_nointeger"
3699 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,*r,o")
3700 (match_operand:XF 1 "general_operand" "fm,f,G,*roF,F*r"))]
3701 "optimize_function_for_size_p (cfun)
3702 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3703 && (reload_in_progress || reload_completed
3704 || standard_80387_constant_p (operands[1])
3705 || GET_CODE (operands[1]) != CONST_DOUBLE
3706 || memory_operand (operands[0], XFmode))"
3708 switch (which_alternative)
3712 return output_387_reg_move (insn, operands);
3715 return standard_80387_constant_opcode (operands[1]);
3723 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3724 (set_attr "mode" "XF,XF,XF,SI,SI")])
3726 (define_insn "*movxf_integer"
3727 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m,f,r,o")
3728 (match_operand:XF 1 "general_operand" "fm,f,G,roF,Fr"))]
3729 "optimize_function_for_speed_p (cfun)
3730 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3731 && (reload_in_progress || reload_completed
3732 || GET_CODE (operands[1]) != CONST_DOUBLE
3733 || memory_operand (operands[0], XFmode))"
3735 switch (which_alternative)
3739 return output_387_reg_move (insn, operands);
3742 return standard_80387_constant_opcode (operands[1]);
3751 [(set_attr "type" "fmov,fmov,fmov,multi,multi")
3752 (set_attr "mode" "XF,XF,XF,SI,SI")])
3754 (define_expand "movtf"
3755 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3756 (match_operand:TF 1 "nonimmediate_operand" ""))]
3759 ix86_expand_move (TFmode, operands);
3763 (define_insn "*movtf_internal"
3764 [(set (match_operand:TF 0 "nonimmediate_operand" "=x,m,x,?r,?o")
3765 (match_operand:TF 1 "general_operand" "xm,x,C,roF,Fr"))]
3767 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
3769 switch (which_alternative)
3773 if (get_attr_mode (insn) == MODE_V4SF)
3774 return "%vmovaps\t{%1, %0|%0, %1}";
3776 return "%vmovdqa\t{%1, %0|%0, %1}";
3778 if (get_attr_mode (insn) == MODE_V4SF)
3779 return "%vxorps\t%0, %d0";
3781 return "%vpxor\t%0, %d0";
3789 [(set_attr "type" "ssemov,ssemov,sselog1,*,*")
3790 (set_attr "prefix" "maybe_vex,maybe_vex,maybe_vex,*,*")
3792 (cond [(eq_attr "alternative" "0,2")
3794 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3796 (const_string "V4SF")
3797 (const_string "TI"))
3798 (eq_attr "alternative" "1")
3800 (ior (ne (symbol_ref "TARGET_SSE_TYPELESS_STORES")
3802 (ne (symbol_ref "optimize_function_for_size_p (cfun)")
3804 (const_string "V4SF")
3805 (const_string "TI"))]
3806 (const_string "DI")))])
3808 (define_insn "*pushtf_sse"
3809 [(set (match_operand:TF 0 "push_operand" "=<,<,<")
3810 (match_operand:TF 1 "general_no_elim_operand" "x,Fo,*r"))]
3813 /* This insn should be already split before reg-stack. */
3816 [(set_attr "type" "multi")
3817 (set_attr "unit" "sse,*,*")
3818 (set_attr "mode" "TF,SI,SI")])
3821 [(set (match_operand:TF 0 "push_operand" "")
3822 (match_operand:TF 1 "general_operand" ""))]
3823 "TARGET_SSE2 && reload_completed
3824 && !SSE_REG_P (operands[1])"
3826 "ix86_split_long_move (operands); DONE;")
3829 [(set (match_operand:TF 0 "push_operand" "")
3830 (match_operand:TF 1 "any_fp_register_operand" ""))]
3832 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -16)))
3833 (set (mem:TF (reg:P SP_REG)) (match_dup 1))]
3837 [(set (match_operand 0 "nonimmediate_operand" "")
3838 (match_operand 1 "general_operand" ""))]
3840 && !(MEM_P (operands[0]) && MEM_P (operands[1]))
3841 && GET_MODE (operands[0]) == XFmode
3842 && ! (ANY_FP_REG_P (operands[0]) ||
3843 (GET_CODE (operands[0]) == SUBREG
3844 && ANY_FP_REG_P (SUBREG_REG (operands[0]))))
3845 && ! (ANY_FP_REG_P (operands[1]) ||
3846 (GET_CODE (operands[1]) == SUBREG
3847 && ANY_FP_REG_P (SUBREG_REG (operands[1]))))"
3849 "ix86_split_long_move (operands); DONE;")
3852 [(set (match_operand 0 "register_operand" "")
3853 (match_operand 1 "memory_operand" ""))]
3855 && MEM_P (operands[1])
3856 && (GET_MODE (operands[0]) == TFmode
3857 || GET_MODE (operands[0]) == XFmode
3858 || GET_MODE (operands[0]) == SFmode
3859 || GET_MODE (operands[0]) == DFmode)
3860 && (operands[2] = find_constant_src (insn))"
3861 [(set (match_dup 0) (match_dup 2))]
3863 rtx c = operands[2];
3864 rtx r = operands[0];
3866 if (GET_CODE (r) == SUBREG)
3871 if (!standard_sse_constant_p (c))
3874 else if (FP_REG_P (r))
3876 if (!standard_80387_constant_p (c))
3879 else if (MMX_REG_P (r))
3884 [(set (match_operand 0 "register_operand" "")
3885 (float_extend (match_operand 1 "memory_operand" "")))]
3887 && MEM_P (operands[1])
3888 && (GET_MODE (operands[0]) == TFmode
3889 || GET_MODE (operands[0]) == XFmode
3890 || GET_MODE (operands[0]) == SFmode
3891 || GET_MODE (operands[0]) == DFmode)
3892 && (operands[2] = find_constant_src (insn))"
3893 [(set (match_dup 0) (match_dup 2))]
3895 rtx c = operands[2];
3896 rtx r = operands[0];
3898 if (GET_CODE (r) == SUBREG)
3903 if (!standard_sse_constant_p (c))
3906 else if (FP_REG_P (r))
3908 if (!standard_80387_constant_p (c))
3911 else if (MMX_REG_P (r))
3915 (define_insn "swapxf"
3916 [(set (match_operand:XF 0 "register_operand" "+f")
3917 (match_operand:XF 1 "register_operand" "+f"))
3922 if (STACK_TOP_P (operands[0]))
3927 [(set_attr "type" "fxch")
3928 (set_attr "mode" "XF")])
3930 ;; Split the load of -0.0 or -1.0 into fldz;fchs or fld1;fchs sequence
3932 [(set (match_operand:X87MODEF 0 "register_operand" "")
3933 (match_operand:X87MODEF 1 "immediate_operand" ""))]
3934 "reload_completed && FP_REGNO_P (REGNO (operands[0]))
3935 && (standard_80387_constant_p (operands[1]) == 8
3936 || standard_80387_constant_p (operands[1]) == 9)"
3937 [(set (match_dup 0)(match_dup 1))
3939 (neg:X87MODEF (match_dup 0)))]
3943 REAL_VALUE_FROM_CONST_DOUBLE (r, operands[1]);
3944 if (real_isnegzero (&r))
3945 operands[1] = CONST0_RTX (<MODE>mode);
3947 operands[1] = CONST1_RTX (<MODE>mode);
3951 [(set (match_operand:TF 0 "nonimmediate_operand" "")
3952 (match_operand:TF 1 "general_operand" ""))]
3954 && !(SSE_REG_P (operands[0]) || SSE_REG_P (operands[1]))"
3956 "ix86_split_long_move (operands); DONE;")
3958 ;; Zero extension instructions
3960 (define_expand "zero_extendhisi2"
3961 [(set (match_operand:SI 0 "register_operand" "")
3962 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "")))]
3965 if (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
3967 operands[1] = force_reg (HImode, operands[1]);
3968 emit_insn (gen_zero_extendhisi2_and (operands[0], operands[1]));
3973 (define_insn "zero_extendhisi2_and"
3974 [(set (match_operand:SI 0 "register_operand" "=r")
3975 (zero_extend:SI (match_operand:HI 1 "register_operand" "0")))
3976 (clobber (reg:CC FLAGS_REG))]
3977 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
3979 [(set_attr "type" "alu1")
3980 (set_attr "mode" "SI")])
3983 [(set (match_operand:SI 0 "register_operand" "")
3984 (zero_extend:SI (match_operand:HI 1 "register_operand" "")))
3985 (clobber (reg:CC FLAGS_REG))]
3986 "reload_completed && TARGET_ZERO_EXTEND_WITH_AND
3987 && optimize_function_for_speed_p (cfun)"
3988 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 65535)))
3989 (clobber (reg:CC FLAGS_REG))])]
3992 (define_insn "*zero_extendhisi2_movzwl"
3993 [(set (match_operand:SI 0 "register_operand" "=r")
3994 (zero_extend:SI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
3995 "!TARGET_ZERO_EXTEND_WITH_AND
3996 || optimize_function_for_size_p (cfun)"
3997 "movz{wl|x}\t{%1, %0|%0, %1}"
3998 [(set_attr "type" "imovx")
3999 (set_attr "mode" "SI")])
4001 (define_expand "zero_extendqihi2"
4003 [(set (match_operand:HI 0 "register_operand" "")
4004 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4005 (clobber (reg:CC FLAGS_REG))])]
4009 (define_insn "*zero_extendqihi2_and"
4010 [(set (match_operand:HI 0 "register_operand" "=r,?&q")
4011 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4012 (clobber (reg:CC FLAGS_REG))]
4013 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4015 [(set_attr "type" "alu1")
4016 (set_attr "mode" "HI")])
4018 (define_insn "*zero_extendqihi2_movzbw_and"
4019 [(set (match_operand:HI 0 "register_operand" "=r,r")
4020 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4021 (clobber (reg:CC FLAGS_REG))]
4022 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4024 [(set_attr "type" "imovx,alu1")
4025 (set_attr "mode" "HI")])
4027 ; zero extend to SImode here to avoid partial register stalls
4028 (define_insn "*zero_extendqihi2_movzbl"
4029 [(set (match_operand:HI 0 "register_operand" "=r")
4030 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4031 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4032 && reload_completed"
4033 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4034 [(set_attr "type" "imovx")
4035 (set_attr "mode" "SI")])
4037 ;; For the movzbw case strip only the clobber
4039 [(set (match_operand:HI 0 "register_operand" "")
4040 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4041 (clobber (reg:CC FLAGS_REG))]
4043 && (!TARGET_ZERO_EXTEND_WITH_AND
4044 || optimize_function_for_size_p (cfun))
4045 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4046 [(set (match_operand:HI 0 "register_operand" "")
4047 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))])
4049 ;; When source and destination does not overlap, clear destination
4050 ;; first and then do the movb
4052 [(set (match_operand:HI 0 "register_operand" "")
4053 (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "")))
4054 (clobber (reg:CC FLAGS_REG))]
4056 && ANY_QI_REG_P (operands[0])
4057 && (TARGET_ZERO_EXTEND_WITH_AND
4058 && optimize_function_for_speed_p (cfun))
4059 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4060 [(set (match_dup 0) (const_int 0))
4061 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4062 "operands[2] = gen_lowpart (QImode, operands[0]);")
4064 ;; Rest is handled by single and.
4066 [(set (match_operand:HI 0 "register_operand" "")
4067 (zero_extend:HI (match_operand:QI 1 "register_operand" "")))
4068 (clobber (reg:CC FLAGS_REG))]
4070 && true_regnum (operands[0]) == true_regnum (operands[1])"
4071 [(parallel [(set (match_dup 0) (and:HI (match_dup 0) (const_int 255)))
4072 (clobber (reg:CC FLAGS_REG))])]
4075 (define_expand "zero_extendqisi2"
4077 [(set (match_operand:SI 0 "register_operand" "")
4078 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4079 (clobber (reg:CC FLAGS_REG))])]
4083 (define_insn "*zero_extendqisi2_and"
4084 [(set (match_operand:SI 0 "register_operand" "=r,?&q")
4085 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "0,qm")))
4086 (clobber (reg:CC FLAGS_REG))]
4087 "TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun)"
4089 [(set_attr "type" "alu1")
4090 (set_attr "mode" "SI")])
4092 (define_insn "*zero_extendqisi2_movzbw_and"
4093 [(set (match_operand:SI 0 "register_operand" "=r,r")
4094 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm,0")))
4095 (clobber (reg:CC FLAGS_REG))]
4096 "!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun)"
4098 [(set_attr "type" "imovx,alu1")
4099 (set_attr "mode" "SI")])
4101 (define_insn "*zero_extendqisi2_movzbw"
4102 [(set (match_operand:SI 0 "register_operand" "=r")
4103 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4104 "(!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4105 && reload_completed"
4106 "movz{bl|x}\t{%1, %0|%0, %1}"
4107 [(set_attr "type" "imovx")
4108 (set_attr "mode" "SI")])
4110 ;; For the movzbl case strip only the clobber
4112 [(set (match_operand:SI 0 "register_operand" "")
4113 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4114 (clobber (reg:CC FLAGS_REG))]
4116 && (!TARGET_ZERO_EXTEND_WITH_AND || optimize_function_for_size_p (cfun))
4117 && (!REG_P (operands[1]) || ANY_QI_REG_P (operands[1]))"
4119 (zero_extend:SI (match_dup 1)))])
4121 ;; When source and destination does not overlap, clear destination
4122 ;; first and then do the movb
4124 [(set (match_operand:SI 0 "register_operand" "")
4125 (zero_extend:SI (match_operand:QI 1 "nonimmediate_operand" "")))
4126 (clobber (reg:CC FLAGS_REG))]
4128 && ANY_QI_REG_P (operands[0])
4129 && (ANY_QI_REG_P (operands[1]) || MEM_P (operands[1]))
4130 && (TARGET_ZERO_EXTEND_WITH_AND && optimize_function_for_speed_p (cfun))
4131 && !reg_overlap_mentioned_p (operands[0], operands[1])"
4132 [(set (match_dup 0) (const_int 0))
4133 (set (strict_low_part (match_dup 2)) (match_dup 1))]
4134 "operands[2] = gen_lowpart (QImode, operands[0]);")
4136 ;; Rest is handled by single and.
4138 [(set (match_operand:SI 0 "register_operand" "")
4139 (zero_extend:SI (match_operand:QI 1 "register_operand" "")))
4140 (clobber (reg:CC FLAGS_REG))]
4142 && true_regnum (operands[0]) == true_regnum (operands[1])"
4143 [(parallel [(set (match_dup 0) (and:SI (match_dup 0) (const_int 255)))
4144 (clobber (reg:CC FLAGS_REG))])]
4147 ;; %%% Kill me once multi-word ops are sane.
4148 (define_expand "zero_extendsidi2"
4149 [(set (match_operand:DI 0 "register_operand" "")
4150 (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "")))]
4155 emit_insn (gen_zero_extendsidi2_32 (operands[0], operands[1]));
4160 (define_insn "zero_extendsidi2_32"
4161 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,?r,?o,?*Ym,?*y,?*Yi,*Y2")
4163 (match_operand:SI 1 "nonimmediate_operand" "0,rm,r ,r ,m ,r ,m")))
4164 (clobber (reg:CC FLAGS_REG))]
4170 movd\t{%1, %0|%0, %1}
4171 movd\t{%1, %0|%0, %1}
4172 %vmovd\t{%1, %0|%0, %1}
4173 %vmovd\t{%1, %0|%0, %1}"
4174 [(set_attr "type" "multi,multi,multi,mmxmov,mmxmov,ssemov,ssemov")
4175 (set_attr "prefix" "*,*,*,orig,orig,maybe_vex,maybe_vex")
4176 (set_attr "mode" "SI,SI,SI,DI,DI,TI,TI")])
4178 (define_insn "zero_extendsidi2_rex64"
4179 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o,?*Ym,?*y,?*Yi,*Y2")
4181 (match_operand:SI 1 "nonimmediate_operand" "rm,0,r ,m ,r ,m")))]
4184 mov\t{%k1, %k0|%k0, %k1}
4186 movd\t{%1, %0|%0, %1}
4187 movd\t{%1, %0|%0, %1}
4188 %vmovd\t{%1, %0|%0, %1}
4189 %vmovd\t{%1, %0|%0, %1}"
4190 [(set_attr "type" "imovx,imov,mmxmov,mmxmov,ssemov,ssemov")
4191 (set_attr "prefix" "orig,*,orig,orig,maybe_vex,maybe_vex")
4192 (set_attr "prefix_0f" "0,*,*,*,*,*")
4193 (set_attr "mode" "SI,DI,DI,DI,TI,TI")])
4196 [(set (match_operand:DI 0 "memory_operand" "")
4197 (zero_extend:DI (match_dup 0)))]
4199 [(set (match_dup 4) (const_int 0))]
4200 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4203 [(set (match_operand:DI 0 "register_operand" "")
4204 (zero_extend:DI (match_operand:SI 1 "register_operand" "")))
4205 (clobber (reg:CC FLAGS_REG))]
4206 "!TARGET_64BIT && reload_completed
4207 && true_regnum (operands[0]) == true_regnum (operands[1])"
4208 [(set (match_dup 4) (const_int 0))]
4209 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4212 [(set (match_operand:DI 0 "nonimmediate_operand" "")
4213 (zero_extend:DI (match_operand:SI 1 "general_operand" "")))
4214 (clobber (reg:CC FLAGS_REG))]
4215 "!TARGET_64BIT && reload_completed
4216 && !SSE_REG_P (operands[0]) && !MMX_REG_P (operands[0])"
4217 [(set (match_dup 3) (match_dup 1))
4218 (set (match_dup 4) (const_int 0))]
4219 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4221 (define_insn "zero_extendhidi2"
4222 [(set (match_operand:DI 0 "register_operand" "=r")
4223 (zero_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4225 "movz{wl|x}\t{%1, %k0|%k0, %1}"
4226 [(set_attr "type" "imovx")
4227 (set_attr "mode" "SI")])
4229 (define_insn "zero_extendqidi2"
4230 [(set (match_operand:DI 0 "register_operand" "=r")
4231 (zero_extend:DI (match_operand:QI 1 "nonimmediate_operand" "rm")))]
4233 "movz{bl|x}\t{%1, %k0|%k0, %1}"
4234 [(set_attr "type" "imovx")
4235 (set_attr "mode" "SI")])
4237 ;; Sign extension instructions
4239 (define_expand "extendsidi2"
4240 [(parallel [(set (match_operand:DI 0 "register_operand" "")
4241 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4242 (clobber (reg:CC FLAGS_REG))
4243 (clobber (match_scratch:SI 2 ""))])]
4248 emit_insn (gen_extendsidi2_rex64 (operands[0], operands[1]));
4253 (define_insn "*extendsidi2_1"
4254 [(set (match_operand:DI 0 "nonimmediate_operand" "=*A,r,?r,?*o")
4255 (sign_extend:DI (match_operand:SI 1 "register_operand" "0,0,r,r")))
4256 (clobber (reg:CC FLAGS_REG))
4257 (clobber (match_scratch:SI 2 "=X,X,X,&r"))]
4261 (define_insn "extendsidi2_rex64"
4262 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4263 (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "*0,rm")))]
4267 movs{lq|x}\t{%1, %0|%0, %1}"
4268 [(set_attr "type" "imovx")
4269 (set_attr "mode" "DI")
4270 (set_attr "prefix_0f" "0")
4271 (set_attr "modrm" "0,1")])
4273 (define_insn "extendhidi2"
4274 [(set (match_operand:DI 0 "register_operand" "=r")
4275 (sign_extend:DI (match_operand:HI 1 "nonimmediate_operand" "rm")))]
4277 "movs{wq|x}\t{%1, %0|%0, %1}"
4278 [(set_attr "type" "imovx")
4279 (set_attr "mode" "DI")])
4281 (define_insn "extendqidi2"
4282 [(set (match_operand:DI 0 "register_operand" "=r")
4283 (sign_extend:DI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4285 "movs{bq|x}\t{%1, %0|%0, %1}"
4286 [(set_attr "type" "imovx")
4287 (set_attr "mode" "DI")])
4289 ;; Extend to memory case when source register does die.
4291 [(set (match_operand:DI 0 "memory_operand" "")
4292 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4293 (clobber (reg:CC FLAGS_REG))
4294 (clobber (match_operand:SI 2 "register_operand" ""))]
4296 && dead_or_set_p (insn, operands[1])
4297 && !reg_mentioned_p (operands[1], operands[0]))"
4298 [(set (match_dup 3) (match_dup 1))
4299 (parallel [(set (match_dup 1) (ashiftrt:SI (match_dup 1) (const_int 31)))
4300 (clobber (reg:CC FLAGS_REG))])
4301 (set (match_dup 4) (match_dup 1))]
4302 "split_di (&operands[0], 1, &operands[3], &operands[4]);")
4304 ;; Extend to memory case when source register does not die.
4306 [(set (match_operand:DI 0 "memory_operand" "")
4307 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4308 (clobber (reg:CC FLAGS_REG))
4309 (clobber (match_operand:SI 2 "register_operand" ""))]
4313 split_di (&operands[0], 1, &operands[3], &operands[4]);
4315 emit_move_insn (operands[3], operands[1]);
4317 /* Generate a cltd if possible and doing so it profitable. */
4318 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4319 && true_regnum (operands[1]) == AX_REG
4320 && true_regnum (operands[2]) == DX_REG)
4322 emit_insn (gen_ashrsi3_31 (operands[2], operands[1], GEN_INT (31)));
4326 emit_move_insn (operands[2], operands[1]);
4327 emit_insn (gen_ashrsi3_31 (operands[2], operands[2], GEN_INT (31)));
4329 emit_move_insn (operands[4], operands[2]);
4333 ;; Extend to register case. Optimize case where source and destination
4334 ;; registers match and cases where we can use cltd.
4336 [(set (match_operand:DI 0 "register_operand" "")
4337 (sign_extend:DI (match_operand:SI 1 "register_operand" "")))
4338 (clobber (reg:CC FLAGS_REG))
4339 (clobber (match_scratch:SI 2 ""))]
4343 split_di (&operands[0], 1, &operands[3], &operands[4]);
4345 if (true_regnum (operands[3]) != true_regnum (operands[1]))
4346 emit_move_insn (operands[3], operands[1]);
4348 /* Generate a cltd if possible and doing so it profitable. */
4349 if ((optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)
4350 && true_regnum (operands[3]) == AX_REG)
4352 emit_insn (gen_ashrsi3_31 (operands[4], operands[3], GEN_INT (31)));
4356 if (true_regnum (operands[4]) != true_regnum (operands[1]))
4357 emit_move_insn (operands[4], operands[1]);
4359 emit_insn (gen_ashrsi3_31 (operands[4], operands[4], GEN_INT (31)));
4363 (define_insn "extendhisi2"
4364 [(set (match_operand:SI 0 "register_operand" "=*a,r")
4365 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm")))]
4368 switch (get_attr_prefix_0f (insn))
4371 return "{cwtl|cwde}";
4373 return "movs{wl|x}\t{%1, %0|%0, %1}";
4376 [(set_attr "type" "imovx")
4377 (set_attr "mode" "SI")
4378 (set (attr "prefix_0f")
4379 ;; movsx is short decodable while cwtl is vector decoded.
4380 (if_then_else (and (eq_attr "cpu" "!k6")
4381 (eq_attr "alternative" "0"))
4383 (const_string "1")))
4385 (if_then_else (eq_attr "prefix_0f" "0")
4387 (const_string "1")))])
4389 (define_insn "*extendhisi2_zext"
4390 [(set (match_operand:DI 0 "register_operand" "=*a,r")
4392 (sign_extend:SI (match_operand:HI 1 "nonimmediate_operand" "*0,rm"))))]
4395 switch (get_attr_prefix_0f (insn))
4398 return "{cwtl|cwde}";
4400 return "movs{wl|x}\t{%1, %k0|%k0, %1}";
4403 [(set_attr "type" "imovx")
4404 (set_attr "mode" "SI")
4405 (set (attr "prefix_0f")
4406 ;; movsx is short decodable while cwtl is vector decoded.
4407 (if_then_else (and (eq_attr "cpu" "!k6")
4408 (eq_attr "alternative" "0"))
4410 (const_string "1")))
4412 (if_then_else (eq_attr "prefix_0f" "0")
4414 (const_string "1")))])
4416 (define_insn "extendqihi2"
4417 [(set (match_operand:HI 0 "register_operand" "=*a,r")
4418 (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "*0,qm")))]
4421 switch (get_attr_prefix_0f (insn))
4424 return "{cbtw|cbw}";
4426 return "movs{bw|x}\t{%1, %0|%0, %1}";
4429 [(set_attr "type" "imovx")
4430 (set_attr "mode" "HI")
4431 (set (attr "prefix_0f")
4432 ;; movsx is short decodable while cwtl is vector decoded.
4433 (if_then_else (and (eq_attr "cpu" "!k6")
4434 (eq_attr "alternative" "0"))
4436 (const_string "1")))
4438 (if_then_else (eq_attr "prefix_0f" "0")
4440 (const_string "1")))])
4442 (define_insn "extendqisi2"
4443 [(set (match_operand:SI 0 "register_operand" "=r")
4444 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm")))]
4446 "movs{bl|x}\t{%1, %0|%0, %1}"
4447 [(set_attr "type" "imovx")
4448 (set_attr "mode" "SI")])
4450 (define_insn "*extendqisi2_zext"
4451 [(set (match_operand:DI 0 "register_operand" "=r")
4453 (sign_extend:SI (match_operand:QI 1 "nonimmediate_operand" "qm"))))]
4455 "movs{bl|x}\t{%1, %k0|%k0, %1}"
4456 [(set_attr "type" "imovx")
4457 (set_attr "mode" "SI")])
4459 ;; Conversions between float and double.
4461 ;; These are all no-ops in the model used for the 80387. So just
4464 ;; %%% Kill these when call knows how to work out a DFmode push earlier.
4465 (define_insn "*dummy_extendsfdf2"
4466 [(set (match_operand:DF 0 "push_operand" "=<")
4467 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fY2")))]
4472 [(set (match_operand:DF 0 "push_operand" "")
4473 (float_extend:DF (match_operand:SF 1 "fp_register_operand" "")))]
4475 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (const_int -8)))
4476 (set (mem:DF (reg:P SP_REG)) (float_extend:DF (match_dup 1)))])
4478 (define_insn "*dummy_extendsfxf2"
4479 [(set (match_operand:XF 0 "push_operand" "=<")
4480 (float_extend:XF (match_operand:SF 1 "nonimmediate_operand" "f")))]
4485 [(set (match_operand:XF 0 "push_operand" "")
4486 (float_extend:XF (match_operand:SF 1 "fp_register_operand" "")))]
4488 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4489 (set (mem:XF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4490 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4493 [(set (match_operand:XF 0 "push_operand" "")
4494 (float_extend:XF (match_operand:DF 1 "fp_register_operand" "")))]
4496 [(set (reg:P SP_REG) (plus:P (reg:P SP_REG) (match_dup 2)))
4497 (set (mem:DF (reg:P SP_REG)) (float_extend:XF (match_dup 1)))]
4498 "operands[2] = GEN_INT (TARGET_128BIT_LONG_DOUBLE ? -16 : -12);")
4500 (define_expand "extendsfdf2"
4501 [(set (match_operand:DF 0 "nonimmediate_operand" "")
4502 (float_extend:DF (match_operand:SF 1 "general_operand" "")))]
4503 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4505 /* ??? Needed for compress_float_constant since all fp constants
4506 are LEGITIMATE_CONSTANT_P. */
4507 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4509 if ((!TARGET_SSE2 || TARGET_MIX_SSE_I387)
4510 && standard_80387_constant_p (operands[1]) > 0)
4512 operands[1] = simplify_const_unary_operation
4513 (FLOAT_EXTEND, DFmode, operands[1], SFmode);
4514 emit_move_insn_1 (operands[0], operands[1]);
4517 operands[1] = validize_mem (force_const_mem (SFmode, operands[1]));
4521 /* For converting SF(xmm2) to DF(xmm1), use the following code instead of
4523 unpcklps xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4525 We do the conversion post reload to avoid producing of 128bit spills
4526 that might lead to ICE on 32bit target. The sequence unlikely combine
4529 [(set (match_operand:DF 0 "register_operand" "")
4531 (match_operand:SF 1 "nonimmediate_operand" "")))]
4532 "TARGET_USE_VECTOR_FP_CONVERTS
4533 && optimize_insn_for_speed_p ()
4534 && reload_completed && SSE_REG_P (operands[0])"
4539 (parallel [(const_int 0) (const_int 1)]))))]
4541 operands[2] = simplify_gen_subreg (V2DFmode, operands[0], DFmode, 0);
4542 operands[3] = simplify_gen_subreg (V4SFmode, operands[0], DFmode, 0);
4543 /* Use movss for loading from memory, unpcklps reg, reg for registers.
4544 Try to avoid move when unpacking can be done in source. */
4545 if (REG_P (operands[1]))
4547 /* If it is unsafe to overwrite upper half of source, we need
4548 to move to destination and unpack there. */
4549 if ((ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4550 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 4)
4551 && true_regnum (operands[0]) != true_regnum (operands[1]))
4553 rtx tmp = gen_rtx_REG (SFmode, true_regnum (operands[0]));
4554 emit_move_insn (tmp, operands[1]);
4557 operands[3] = simplify_gen_subreg (V4SFmode, operands[1], SFmode, 0);
4558 emit_insn (gen_sse_unpcklps (operands[3], operands[3], operands[3]));
4561 emit_insn (gen_vec_setv4sf_0 (operands[3],
4562 CONST0_RTX (V4SFmode), operands[1]));
4565 (define_insn "*extendsfdf2_mixed"
4566 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m,x")
4568 (match_operand:SF 1 "nonimmediate_operand" "fm,f,xm")))]
4569 "TARGET_SSE2 && TARGET_MIX_SSE_I387"
4571 switch (which_alternative)
4575 return output_387_reg_move (insn, operands);
4578 return "%vcvtss2sd\t{%1, %d0|%d0, %1}";
4584 [(set_attr "type" "fmov,fmov,ssecvt")
4585 (set_attr "prefix" "orig,orig,maybe_vex")
4586 (set_attr "mode" "SF,XF,DF")])
4588 (define_insn "*extendsfdf2_sse"
4589 [(set (match_operand:DF 0 "nonimmediate_operand" "=x")
4590 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "xm")))]
4591 "TARGET_SSE2 && TARGET_SSE_MATH"
4592 "%vcvtss2sd\t{%1, %d0|%d0, %1}"
4593 [(set_attr "type" "ssecvt")
4594 (set_attr "prefix" "maybe_vex")
4595 (set_attr "mode" "DF")])
4597 (define_insn "*extendsfdf2_i387"
4598 [(set (match_operand:DF 0 "nonimmediate_operand" "=f,m")
4599 (float_extend:DF (match_operand:SF 1 "nonimmediate_operand" "fm,f")))]
4601 "* return output_387_reg_move (insn, operands);"
4602 [(set_attr "type" "fmov")
4603 (set_attr "mode" "SF,XF")])
4605 (define_expand "extend<mode>xf2"
4606 [(set (match_operand:XF 0 "nonimmediate_operand" "")
4607 (float_extend:XF (match_operand:MODEF 1 "general_operand" "")))]
4610 /* ??? Needed for compress_float_constant since all fp constants
4611 are LEGITIMATE_CONSTANT_P. */
4612 if (GET_CODE (operands[1]) == CONST_DOUBLE)
4614 if (standard_80387_constant_p (operands[1]) > 0)
4616 operands[1] = simplify_const_unary_operation
4617 (FLOAT_EXTEND, XFmode, operands[1], <MODE>mode);
4618 emit_move_insn_1 (operands[0], operands[1]);
4621 operands[1] = validize_mem (force_const_mem (<MODE>mode, operands[1]));
4625 (define_insn "*extend<mode>xf2_i387"
4626 [(set (match_operand:XF 0 "nonimmediate_operand" "=f,m")
4628 (match_operand:MODEF 1 "nonimmediate_operand" "fm,f")))]
4630 "* return output_387_reg_move (insn, operands);"
4631 [(set_attr "type" "fmov")
4632 (set_attr "mode" "<MODE>,XF")])
4634 ;; %%% This seems bad bad news.
4635 ;; This cannot output into an f-reg because there is no way to be sure
4636 ;; of truncating in that case. Otherwise this is just like a simple move
4637 ;; insn. So we pretend we can output to a reg in order to get better
4638 ;; register preferencing, but we really use a stack slot.
4640 ;; Conversion from DFmode to SFmode.
4642 (define_expand "truncdfsf2"
4643 [(set (match_operand:SF 0 "nonimmediate_operand" "")
4645 (match_operand:DF 1 "nonimmediate_operand" "")))]
4646 "TARGET_80387 || (TARGET_SSE2 && TARGET_SSE_MATH)"
4648 if (TARGET_SSE2 && TARGET_SSE_MATH && !TARGET_MIX_SSE_I387)
4650 else if (flag_unsafe_math_optimizations)
4654 enum ix86_stack_slot slot = (virtuals_instantiated
4657 rtx temp = assign_386_stack_local (SFmode, slot);
4658 emit_insn (gen_truncdfsf2_with_temp (operands[0], operands[1], temp));
4663 /* For converting DF(xmm2) to SF(xmm1), use the following code instead of
4665 unpcklpd xmm2,xmm2 ; packed conversion might crash on signaling NaNs
4667 We do the conversion post reload to avoid producing of 128bit spills
4668 that might lead to ICE on 32bit target. The sequence unlikely combine
4671 [(set (match_operand:SF 0 "register_operand" "")
4673 (match_operand:DF 1 "nonimmediate_operand" "")))]
4674 "TARGET_USE_VECTOR_FP_CONVERTS
4675 && optimize_insn_for_speed_p ()
4676 && reload_completed && SSE_REG_P (operands[0])"
4679 (float_truncate:V2SF
4683 operands[2] = simplify_gen_subreg (V4SFmode, operands[0], SFmode, 0);
4684 operands[3] = CONST0_RTX (V2SFmode);
4685 operands[4] = simplify_gen_subreg (V2DFmode, operands[0], SFmode, 0);
4686 /* Use movsd for loading from memory, unpcklpd for registers.
4687 Try to avoid move when unpacking can be done in source, or SSE3
4688 movddup is available. */
4689 if (REG_P (operands[1]))
4692 && true_regnum (operands[0]) != true_regnum (operands[1])
4693 && (ORIGINAL_REGNO (operands[1]) < FIRST_PSEUDO_REGISTER
4694 || PSEUDO_REGNO_BYTES (ORIGINAL_REGNO (operands[1])) > 8))
4696 rtx tmp = simplify_gen_subreg (DFmode, operands[0], SFmode, 0);
4697 emit_move_insn (tmp, operands[1]);
4700 else if (!TARGET_SSE3)
4701 operands[4] = simplify_gen_subreg (V2DFmode, operands[1], DFmode, 0);
4702 emit_insn (gen_vec_dupv2df (operands[4], operands[1]));
4705 emit_insn (gen_sse2_loadlpd (operands[4],
4706 CONST0_RTX (V2DFmode), operands[1]));
4709 (define_expand "truncdfsf2_with_temp"
4710 [(parallel [(set (match_operand:SF 0 "" "")
4711 (float_truncate:SF (match_operand:DF 1 "" "")))
4712 (clobber (match_operand:SF 2 "" ""))])]
4715 (define_insn "*truncdfsf_fast_mixed"
4716 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm,x")
4718 (match_operand:DF 1 "nonimmediate_operand" "f ,xm")))]
4719 "TARGET_SSE2 && TARGET_MIX_SSE_I387 && flag_unsafe_math_optimizations"
4721 switch (which_alternative)
4724 return output_387_reg_move (insn, operands);
4726 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4731 [(set_attr "type" "fmov,ssecvt")
4732 (set_attr "prefix" "orig,maybe_vex")
4733 (set_attr "mode" "SF")])
4735 ;; Yes, this one doesn't depend on flag_unsafe_math_optimizations,
4736 ;; because nothing we do here is unsafe.
4737 (define_insn "*truncdfsf_fast_sse"
4738 [(set (match_operand:SF 0 "nonimmediate_operand" "=x")
4740 (match_operand:DF 1 "nonimmediate_operand" "xm")))]
4741 "TARGET_SSE2 && TARGET_SSE_MATH"
4742 "%vcvtsd2ss\t{%1, %d0|%d0, %1}"
4743 [(set_attr "type" "ssecvt")
4744 (set_attr "prefix" "maybe_vex")
4745 (set_attr "mode" "SF")])
4747 (define_insn "*truncdfsf_fast_i387"
4748 [(set (match_operand:SF 0 "nonimmediate_operand" "=fm")
4750 (match_operand:DF 1 "nonimmediate_operand" "f")))]
4751 "TARGET_80387 && flag_unsafe_math_optimizations"
4752 "* return output_387_reg_move (insn, operands);"
4753 [(set_attr "type" "fmov")
4754 (set_attr "mode" "SF")])
4756 (define_insn "*truncdfsf_mixed"
4757 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,Y2 ,?f,?x,?*r")
4759 (match_operand:DF 1 "nonimmediate_operand" "f ,Y2m,f ,f ,f")))
4760 (clobber (match_operand:SF 2 "memory_operand" "=X,X ,m ,m ,m"))]
4761 "TARGET_MIX_SSE_I387"
4763 switch (which_alternative)
4766 return output_387_reg_move (insn, operands);
4768 return "%vcvtsd2ss\t{%1, %d0|%d0, %1}";
4774 [(set_attr "type" "fmov,ssecvt,multi,multi,multi")
4775 (set_attr "unit" "*,*,i387,i387,i387")
4776 (set_attr "prefix" "orig,maybe_vex,orig,orig,orig")
4777 (set_attr "mode" "SF")])
4779 (define_insn "*truncdfsf_i387"
4780 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4782 (match_operand:DF 1 "nonimmediate_operand" "f ,f ,f ,f")))
4783 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4786 switch (which_alternative)
4789 return output_387_reg_move (insn, operands);
4795 [(set_attr "type" "fmov,multi,multi,multi")
4796 (set_attr "unit" "*,i387,i387,i387")
4797 (set_attr "mode" "SF")])
4799 (define_insn "*truncdfsf2_i387_1"
4800 [(set (match_operand:SF 0 "memory_operand" "=m")
4802 (match_operand:DF 1 "register_operand" "f")))]
4804 && !(TARGET_SSE2 && TARGET_SSE_MATH)
4805 && !TARGET_MIX_SSE_I387"
4806 "* return output_387_reg_move (insn, operands);"
4807 [(set_attr "type" "fmov")
4808 (set_attr "mode" "SF")])
4811 [(set (match_operand:SF 0 "register_operand" "")
4813 (match_operand:DF 1 "fp_register_operand" "")))
4814 (clobber (match_operand 2 "" ""))]
4816 [(set (match_dup 2) (match_dup 1))
4817 (set (match_dup 0) (match_dup 2))]
4819 operands[1] = gen_rtx_REG (SFmode, true_regnum (operands[1]));
4822 ;; Conversion from XFmode to {SF,DF}mode
4824 (define_expand "truncxf<mode>2"
4825 [(parallel [(set (match_operand:MODEF 0 "nonimmediate_operand" "")
4826 (float_truncate:MODEF
4827 (match_operand:XF 1 "register_operand" "")))
4828 (clobber (match_dup 2))])]
4831 if (flag_unsafe_math_optimizations)
4833 rtx reg = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (<MODE>mode);
4834 emit_insn (gen_truncxf<mode>2_i387_noop (reg, operands[1]));
4835 if (reg != operands[0])
4836 emit_move_insn (operands[0], reg);
4841 enum ix86_stack_slot slot = (virtuals_instantiated
4844 operands[2] = assign_386_stack_local (<MODE>mode, slot);
4848 (define_insn "*truncxfsf2_mixed"
4849 [(set (match_operand:SF 0 "nonimmediate_operand" "=m,?f,?x,?*r")
4851 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4852 (clobber (match_operand:SF 2 "memory_operand" "=X,m ,m ,m"))]
4855 gcc_assert (!which_alternative);
4856 return output_387_reg_move (insn, operands);
4858 [(set_attr "type" "fmov,multi,multi,multi")
4859 (set_attr "unit" "*,i387,i387,i387")
4860 (set_attr "mode" "SF")])
4862 (define_insn "*truncxfdf2_mixed"
4863 [(set (match_operand:DF 0 "nonimmediate_operand" "=m,?f,?Y2,?*r")
4865 (match_operand:XF 1 "register_operand" "f ,f ,f ,f")))
4866 (clobber (match_operand:DF 2 "memory_operand" "=X,m ,m ,m"))]
4869 gcc_assert (!which_alternative);
4870 return output_387_reg_move (insn, operands);
4872 [(set_attr "type" "fmov,multi,multi,multi")
4873 (set_attr "unit" "*,i387,i387,i387")
4874 (set_attr "mode" "DF")])
4876 (define_insn "truncxf<mode>2_i387_noop"
4877 [(set (match_operand:MODEF 0 "register_operand" "=f")
4878 (float_truncate:MODEF
4879 (match_operand:XF 1 "register_operand" "f")))]
4880 "TARGET_80387 && flag_unsafe_math_optimizations"
4881 "* return output_387_reg_move (insn, operands);"
4882 [(set_attr "type" "fmov")
4883 (set_attr "mode" "<MODE>")])
4885 (define_insn "*truncxf<mode>2_i387"
4886 [(set (match_operand:MODEF 0 "memory_operand" "=m")
4887 (float_truncate:MODEF
4888 (match_operand:XF 1 "register_operand" "f")))]
4890 "* return output_387_reg_move (insn, operands);"
4891 [(set_attr "type" "fmov")
4892 (set_attr "mode" "<MODE>")])
4895 [(set (match_operand:MODEF 0 "register_operand" "")
4896 (float_truncate:MODEF
4897 (match_operand:XF 1 "register_operand" "")))
4898 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4899 "TARGET_80387 && reload_completed"
4900 [(set (match_dup 2) (float_truncate:MODEF (match_dup 1)))
4901 (set (match_dup 0) (match_dup 2))]
4905 [(set (match_operand:MODEF 0 "memory_operand" "")
4906 (float_truncate:MODEF
4907 (match_operand:XF 1 "register_operand" "")))
4908 (clobber (match_operand:MODEF 2 "memory_operand" ""))]
4910 [(set (match_dup 0) (float_truncate:MODEF (match_dup 1)))]
4913 ;; Signed conversion to DImode.
4915 (define_expand "fix_truncxfdi2"
4916 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4917 (fix:DI (match_operand:XF 1 "register_operand" "")))
4918 (clobber (reg:CC FLAGS_REG))])]
4923 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4928 (define_expand "fix_trunc<mode>di2"
4929 [(parallel [(set (match_operand:DI 0 "nonimmediate_operand" "")
4930 (fix:DI (match_operand:MODEF 1 "register_operand" "")))
4931 (clobber (reg:CC FLAGS_REG))])]
4932 "TARGET_80387 || (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))"
4935 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4937 emit_insn (gen_fix_truncdi_fisttp_i387_1 (operands[0], operands[1]));
4940 if (TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode))
4942 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (DImode);
4943 emit_insn (gen_fix_trunc<mode>di_sse (out, operands[1]));
4944 if (out != operands[0])
4945 emit_move_insn (operands[0], out);
4950 ;; Signed conversion to SImode.
4952 (define_expand "fix_truncxfsi2"
4953 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4954 (fix:SI (match_operand:XF 1 "register_operand" "")))
4955 (clobber (reg:CC FLAGS_REG))])]
4960 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4965 (define_expand "fix_trunc<mode>si2"
4966 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "")
4967 (fix:SI (match_operand:MODEF 1 "register_operand" "")))
4968 (clobber (reg:CC FLAGS_REG))])]
4969 "TARGET_80387 || SSE_FLOAT_MODE_P (<MODE>mode)"
4972 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
4974 emit_insn (gen_fix_truncsi_fisttp_i387_1 (operands[0], operands[1]));
4977 if (SSE_FLOAT_MODE_P (<MODE>mode))
4979 rtx out = REG_P (operands[0]) ? operands[0] : gen_reg_rtx (SImode);
4980 emit_insn (gen_fix_trunc<mode>si_sse (out, operands[1]));
4981 if (out != operands[0])
4982 emit_move_insn (operands[0], out);
4987 ;; Signed conversion to HImode.
4989 (define_expand "fix_trunc<mode>hi2"
4990 [(parallel [(set (match_operand:HI 0 "nonimmediate_operand" "")
4991 (fix:HI (match_operand:X87MODEF 1 "register_operand" "")))
4992 (clobber (reg:CC FLAGS_REG))])]
4994 && !(SSE_FLOAT_MODE_P (<MODE>mode) && (!TARGET_FISTTP || TARGET_SSE_MATH))"
4998 emit_insn (gen_fix_trunchi_fisttp_i387_1 (operands[0], operands[1]));
5003 ;; Unsigned conversion to SImode.
5005 (define_expand "fixuns_trunc<mode>si2"
5007 [(set (match_operand:SI 0 "register_operand" "")
5009 (match_operand:MODEF 1 "nonimmediate_operand" "")))
5011 (clobber (match_scratch:<ssevecmode> 3 ""))
5012 (clobber (match_scratch:<ssevecmode> 4 ""))])]
5013 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH"
5015 enum machine_mode mode = <MODE>mode;
5016 enum machine_mode vecmode = <ssevecmode>mode;
5017 REAL_VALUE_TYPE TWO31r;
5020 if (optimize_insn_for_size_p ())
5023 real_ldexp (&TWO31r, &dconst1, 31);
5024 two31 = const_double_from_real_value (TWO31r, mode);
5025 two31 = ix86_build_const_vector (mode, true, two31);
5026 operands[2] = force_reg (vecmode, two31);
5029 (define_insn_and_split "*fixuns_trunc<mode>_1"
5030 [(set (match_operand:SI 0 "register_operand" "=&x,&x")
5032 (match_operand:MODEF 3 "nonimmediate_operand" "xm,xm")))
5033 (use (match_operand:<ssevecmode> 4 "nonimmediate_operand" "m,x"))
5034 (clobber (match_scratch:<ssevecmode> 1 "=x,&x"))
5035 (clobber (match_scratch:<ssevecmode> 2 "=x,x"))]
5036 "!TARGET_64BIT && TARGET_SSE2 && TARGET_SSE_MATH
5037 && optimize_function_for_speed_p (cfun)"
5039 "&& reload_completed"
5042 ix86_split_convert_uns_si_sse (operands);
5046 ;; Unsigned conversion to HImode.
5047 ;; Without these patterns, we'll try the unsigned SI conversion which
5048 ;; is complex for SSE, rather than the signed SI conversion, which isn't.
5050 (define_expand "fixuns_trunc<mode>hi2"
5052 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "")))
5053 (set (match_operand:HI 0 "nonimmediate_operand" "")
5054 (subreg:HI (match_dup 2) 0))]
5055 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
5056 "operands[2] = gen_reg_rtx (SImode);")
5058 ;; When SSE is available, it is always faster to use it!
5059 (define_insn "fix_trunc<mode>di_sse"
5060 [(set (match_operand:DI 0 "register_operand" "=r,r")
5061 (fix:DI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5062 "TARGET_64BIT && SSE_FLOAT_MODE_P (<MODE>mode)
5063 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5064 "%vcvtts<ssemodefsuffix>2si{q}\t{%1, %0|%0, %1}"
5065 [(set_attr "type" "sseicvt")
5066 (set_attr "prefix" "maybe_vex")
5067 (set_attr "prefix_rex" "1")
5068 (set_attr "mode" "<MODE>")
5069 (set_attr "athlon_decode" "double,vector")
5070 (set_attr "amdfam10_decode" "double,double")])
5072 (define_insn "fix_trunc<mode>si_sse"
5073 [(set (match_operand:SI 0 "register_operand" "=r,r")
5074 (fix:SI (match_operand:MODEF 1 "nonimmediate_operand" "x,m")))]
5075 "SSE_FLOAT_MODE_P (<MODE>mode)
5076 && (!TARGET_FISTTP || TARGET_SSE_MATH)"
5077 "%vcvtts<ssemodefsuffix>2si\t{%1, %0|%0, %1}"
5078 [(set_attr "type" "sseicvt")
5079 (set_attr "prefix" "maybe_vex")
5080 (set_attr "mode" "<MODE>")
5081 (set_attr "athlon_decode" "double,vector")
5082 (set_attr "amdfam10_decode" "double,double")])
5084 ;; Shorten x87->SSE reload sequences of fix_trunc?f?i_sse patterns.
5086 [(set (match_operand:MODEF 0 "register_operand" "")
5087 (match_operand:MODEF 1 "memory_operand" ""))
5088 (set (match_operand:SSEMODEI24 2 "register_operand" "")
5089 (fix:SSEMODEI24 (match_dup 0)))]
5090 "TARGET_SHORTEN_X87_SSE
5091 && peep2_reg_dead_p (2, operands[0])"
5092 [(set (match_dup 2) (fix:SSEMODEI24 (match_dup 1)))]
5095 ;; Avoid vector decoded forms of the instruction.
5097 [(match_scratch:DF 2 "Y2")
5098 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5099 (fix:SSEMODEI24 (match_operand:DF 1 "memory_operand" "")))]
5100 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5101 [(set (match_dup 2) (match_dup 1))
5102 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5106 [(match_scratch:SF 2 "x")
5107 (set (match_operand:SSEMODEI24 0 "register_operand" "")
5108 (fix:SSEMODEI24 (match_operand:SF 1 "memory_operand" "")))]
5109 "TARGET_AVOID_VECTOR_DECODE && optimize_insn_for_speed_p ()"
5110 [(set (match_dup 2) (match_dup 1))
5111 (set (match_dup 0) (fix:SSEMODEI24 (match_dup 2)))]
5114 (define_insn_and_split "fix_trunc<mode>_fisttp_i387_1"
5115 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5116 (fix:X87MODEI (match_operand 1 "register_operand" "")))]
5117 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5119 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5120 && (TARGET_64BIT || <MODE>mode != DImode))
5122 && !(reload_completed || reload_in_progress)"
5127 if (memory_operand (operands[0], VOIDmode))
5128 emit_insn (gen_fix_trunc<mode>_i387_fisttp (operands[0], operands[1]));
5131 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5132 emit_insn (gen_fix_trunc<mode>_i387_fisttp_with_temp (operands[0],
5138 [(set_attr "type" "fisttp")
5139 (set_attr "mode" "<MODE>")])
5141 (define_insn "fix_trunc<mode>_i387_fisttp"
5142 [(set (match_operand:X87MODEI 0 "memory_operand" "=m")
5143 (fix:X87MODEI (match_operand 1 "register_operand" "f")))
5144 (clobber (match_scratch:XF 2 "=&1f"))]
5145 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5147 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5148 && (TARGET_64BIT || <MODE>mode != DImode))
5149 && TARGET_SSE_MATH)"
5150 "* return output_fix_trunc (insn, operands, 1);"
5151 [(set_attr "type" "fisttp")
5152 (set_attr "mode" "<MODE>")])
5154 (define_insn "fix_trunc<mode>_i387_fisttp_with_temp"
5155 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "=m,?r")
5156 (fix:X87MODEI (match_operand 1 "register_operand" "f,f")))
5157 (clobber (match_operand:X87MODEI 2 "memory_operand" "=X,m"))
5158 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
5159 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5161 && !((SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5162 && (TARGET_64BIT || <MODE>mode != DImode))
5163 && TARGET_SSE_MATH)"
5165 [(set_attr "type" "fisttp")
5166 (set_attr "mode" "<MODE>")])
5169 [(set (match_operand:X87MODEI 0 "register_operand" "")
5170 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5171 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5172 (clobber (match_scratch 3 ""))]
5174 [(parallel [(set (match_dup 2) (fix:X87MODEI (match_dup 1)))
5175 (clobber (match_dup 3))])
5176 (set (match_dup 0) (match_dup 2))]
5180 [(set (match_operand:X87MODEI 0 "memory_operand" "")
5181 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5182 (clobber (match_operand:X87MODEI 2 "memory_operand" ""))
5183 (clobber (match_scratch 3 ""))]
5185 [(parallel [(set (match_dup 0) (fix:X87MODEI (match_dup 1)))
5186 (clobber (match_dup 3))])]
5189 ;; See the comments in i386.h near OPTIMIZE_MODE_SWITCHING for the description
5190 ;; of the machinery. Please note the clobber of FLAGS_REG. In i387 control
5191 ;; word calculation (inserted by LCM in mode switching pass) a FLAGS_REG
5192 ;; clobbering insns can be used. Look at emit_i387_cw_initialization ()
5193 ;; function in i386.c.
5194 (define_insn_and_split "*fix_trunc<mode>_i387_1"
5195 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
5196 (fix:X87MODEI (match_operand 1 "register_operand" "")))
5197 (clobber (reg:CC FLAGS_REG))]
5198 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5200 && !(SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
5201 && (TARGET_64BIT || <MODE>mode != DImode))
5202 && !(reload_completed || reload_in_progress)"
5207 ix86_optimize_mode_switching[I387_TRUNC] = 1;
5209 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
5210 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
5211 if (memory_operand (operands[0], VOIDmode))
5212 emit_insn (gen_fix_trunc<mode>_i387 (operands[0], operands[1],
5213 operands[2], operands[3]));
5216 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
5217 emit_insn (gen_fix_trunc<mode>_i387_with_temp (operands[0], operands[1],
5218 operands[2], operands[3],
5223 [(set_attr "type" "fistp")
5224 (set_attr "i387_cw" "trunc")
5225 (set_attr "mode" "<MODE>")])
5227 (define_insn "fix_truncdi_i387"
5228 [(set (match_operand:DI 0 "memory_operand" "=m")
5229 (fix:DI (match_operand 1 "register_operand" "f")))
5230 (use (match_operand:HI 2 "memory_operand" "m"))
5231 (use (match_operand:HI 3 "memory_operand" "m"))
5232 (clobber (match_scratch:XF 4 "=&1f"))]
5233 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5235 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5236 "* return output_fix_trunc (insn, operands, 0);"
5237 [(set_attr "type" "fistp")
5238 (set_attr "i387_cw" "trunc")
5239 (set_attr "mode" "DI")])
5241 (define_insn "fix_truncdi_i387_with_temp"
5242 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
5243 (fix:DI (match_operand 1 "register_operand" "f,f")))
5244 (use (match_operand:HI 2 "memory_operand" "m,m"))
5245 (use (match_operand:HI 3 "memory_operand" "m,m"))
5246 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
5247 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
5248 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5250 && !(TARGET_64BIT && SSE_FLOAT_MODE_P (GET_MODE (operands[1])))"
5252 [(set_attr "type" "fistp")
5253 (set_attr "i387_cw" "trunc")
5254 (set_attr "mode" "DI")])
5257 [(set (match_operand:DI 0 "register_operand" "")
5258 (fix:DI (match_operand 1 "register_operand" "")))
5259 (use (match_operand:HI 2 "memory_operand" ""))
5260 (use (match_operand:HI 3 "memory_operand" ""))
5261 (clobber (match_operand:DI 4 "memory_operand" ""))
5262 (clobber (match_scratch 5 ""))]
5264 [(parallel [(set (match_dup 4) (fix:DI (match_dup 1)))
5267 (clobber (match_dup 5))])
5268 (set (match_dup 0) (match_dup 4))]
5272 [(set (match_operand:DI 0 "memory_operand" "")
5273 (fix:DI (match_operand 1 "register_operand" "")))
5274 (use (match_operand:HI 2 "memory_operand" ""))
5275 (use (match_operand:HI 3 "memory_operand" ""))
5276 (clobber (match_operand:DI 4 "memory_operand" ""))
5277 (clobber (match_scratch 5 ""))]
5279 [(parallel [(set (match_dup 0) (fix:DI (match_dup 1)))
5282 (clobber (match_dup 5))])]
5285 (define_insn "fix_trunc<mode>_i387"
5286 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
5287 (fix:X87MODEI12 (match_operand 1 "register_operand" "f")))
5288 (use (match_operand:HI 2 "memory_operand" "m"))
5289 (use (match_operand:HI 3 "memory_operand" "m"))]
5290 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5292 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5293 "* return output_fix_trunc (insn, operands, 0);"
5294 [(set_attr "type" "fistp")
5295 (set_attr "i387_cw" "trunc")
5296 (set_attr "mode" "<MODE>")])
5298 (define_insn "fix_trunc<mode>_i387_with_temp"
5299 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
5300 (fix:X87MODEI12 (match_operand 1 "register_operand" "f,f")))
5301 (use (match_operand:HI 2 "memory_operand" "m,m"))
5302 (use (match_operand:HI 3 "memory_operand" "m,m"))
5303 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
5304 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
5306 && !SSE_FLOAT_MODE_P (GET_MODE (operands[1]))"
5308 [(set_attr "type" "fistp")
5309 (set_attr "i387_cw" "trunc")
5310 (set_attr "mode" "<MODE>")])
5313 [(set (match_operand:X87MODEI12 0 "register_operand" "")
5314 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5315 (use (match_operand:HI 2 "memory_operand" ""))
5316 (use (match_operand:HI 3 "memory_operand" ""))
5317 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5319 [(parallel [(set (match_dup 4) (fix:X87MODEI12 (match_dup 1)))
5321 (use (match_dup 3))])
5322 (set (match_dup 0) (match_dup 4))]
5326 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
5327 (fix:X87MODEI12 (match_operand 1 "register_operand" "")))
5328 (use (match_operand:HI 2 "memory_operand" ""))
5329 (use (match_operand:HI 3 "memory_operand" ""))
5330 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
5332 [(parallel [(set (match_dup 0) (fix:X87MODEI12 (match_dup 1)))
5334 (use (match_dup 3))])]
5337 (define_insn "x86_fnstcw_1"
5338 [(set (match_operand:HI 0 "memory_operand" "=m")
5339 (unspec:HI [(reg:HI FPCR_REG)] UNSPEC_FSTCW))]
5342 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5343 (set_attr "mode" "HI")
5344 (set_attr "unit" "i387")])
5346 (define_insn "x86_fldcw_1"
5347 [(set (reg:HI FPCR_REG)
5348 (unspec:HI [(match_operand:HI 0 "memory_operand" "m")] UNSPEC_FLDCW))]
5351 [(set (attr "length") (symbol_ref "ix86_attr_length_address_default (insn) + 2"))
5352 (set_attr "mode" "HI")
5353 (set_attr "unit" "i387")
5354 (set_attr "athlon_decode" "vector")
5355 (set_attr "amdfam10_decode" "vector")])
5357 ;; Conversion between fixed point and floating point.
5359 ;; Even though we only accept memory inputs, the backend _really_
5360 ;; wants to be able to do this between registers.
5362 (define_expand "floathi<mode>2"
5363 [(set (match_operand:X87MODEF 0 "register_operand" "")
5364 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "")))]
5366 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5367 || TARGET_MIX_SSE_I387)"
5370 ;; Pre-reload splitter to add memory clobber to the pattern.
5371 (define_insn_and_split "*floathi<mode>2_1"
5372 [(set (match_operand:X87MODEF 0 "register_operand" "")
5373 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))]
5375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5376 || TARGET_MIX_SSE_I387)
5377 && !(reload_completed || reload_in_progress)"
5380 [(parallel [(set (match_dup 0)
5381 (float:X87MODEF (match_dup 1)))
5382 (clobber (match_dup 2))])]
5383 "operands[2] = assign_386_stack_local (HImode, SLOT_TEMP);")
5385 (define_insn "*floathi<mode>2_i387_with_temp"
5386 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5387 (float:X87MODEF (match_operand:HI 1 "nonimmediate_operand" "m,?r")))
5388 (clobber (match_operand:HI 2 "memory_operand" "=m,m"))]
5390 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5391 || TARGET_MIX_SSE_I387)"
5393 [(set_attr "type" "fmov,multi")
5394 (set_attr "mode" "<MODE>")
5395 (set_attr "unit" "*,i387")
5396 (set_attr "fp_int_src" "true")])
5398 (define_insn "*floathi<mode>2_i387"
5399 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5400 (float:X87MODEF (match_operand:HI 1 "memory_operand" "m")))]
5402 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5403 || TARGET_MIX_SSE_I387)"
5405 [(set_attr "type" "fmov")
5406 (set_attr "mode" "<MODE>")
5407 (set_attr "fp_int_src" "true")])
5410 [(set (match_operand:X87MODEF 0 "register_operand" "")
5411 (float:X87MODEF (match_operand:HI 1 "register_operand" "")))
5412 (clobber (match_operand:HI 2 "memory_operand" ""))]
5414 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5415 || TARGET_MIX_SSE_I387)
5416 && reload_completed"
5417 [(set (match_dup 2) (match_dup 1))
5418 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5422 [(set (match_operand:X87MODEF 0 "register_operand" "")
5423 (float:X87MODEF (match_operand:HI 1 "memory_operand" "")))
5424 (clobber (match_operand:HI 2 "memory_operand" ""))]
5426 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
5427 || TARGET_MIX_SSE_I387)
5428 && reload_completed"
5429 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5432 (define_expand "float<SSEMODEI24:mode><X87MODEF:mode>2"
5433 [(set (match_operand:X87MODEF 0 "register_operand" "")
5435 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))]
5437 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5438 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)"
5441 if (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5442 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5443 && !X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode))
5445 rtx reg = gen_reg_rtx (XFmode);
5446 emit_insn (gen_float<SSEMODEI24:mode>xf2 (reg, operands[1]));
5447 /* Avoid references to nonexistent function in dead code in XFmode case. */
5448 #define gen_truncxfxf2 gen_truncxfdf2
5449 emit_insn (gen_truncxf<X87MODEF:mode>2 (operands[0], reg));
5450 #undef gen_truncxfxf2
5455 ;; Pre-reload splitter to add memory clobber to the pattern.
5456 (define_insn_and_split "*float<SSEMODEI24:mode><X87MODEF:mode>2_1"
5457 [(set (match_operand:X87MODEF 0 "register_operand" "")
5458 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))]
5460 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5461 && (!((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5462 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH)
5463 || TARGET_MIX_SSE_I387))
5464 || ((<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5465 && SSE_FLOAT_MODE_P (<X87MODEF:MODE>mode) && TARGET_SSE_MATH
5466 && ((<SSEMODEI24:MODE>mode == SImode
5467 && TARGET_SSE2 && TARGET_USE_VECTOR_CONVERTS
5468 && optimize_function_for_speed_p (cfun)
5469 && flag_trapping_math)
5470 || !(TARGET_INTER_UNIT_CONVERSIONS
5471 || optimize_function_for_size_p (cfun)))))
5472 && !(reload_completed || reload_in_progress)"
5475 [(parallel [(set (match_dup 0) (float:X87MODEF (match_dup 1)))
5476 (clobber (match_dup 2))])]
5478 operands[2] = assign_386_stack_local (<SSEMODEI24:MODE>mode, SLOT_TEMP);
5480 /* Avoid store forwarding (partial memory) stall penalty
5481 by passing DImode value through XMM registers. */
5482 if (<SSEMODEI24:MODE>mode == DImode && !TARGET_64BIT
5483 && TARGET_80387 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5484 && optimize_function_for_speed_p (cfun))
5486 emit_insn (gen_floatdi<X87MODEF:mode>2_i387_with_xmm (operands[0],
5493 (define_insn "*floatsi<mode>2_vector_mixed_with_temp"
5494 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x,x")
5496 (match_operand:SI 1 "nonimmediate_operand" "m,?r,r,m,!x")))
5497 (clobber (match_operand:SI 2 "memory_operand" "=X,m,m,X,m"))]
5498 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5499 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5501 [(set_attr "type" "fmov,multi,sseicvt,sseicvt,sseicvt")
5502 (set_attr "mode" "<MODE>,<MODE>,<MODE>,<MODE>,<ssevecmode>")
5503 (set_attr "unit" "*,i387,*,*,*")
5504 (set_attr "athlon_decode" "*,*,double,direct,double")
5505 (set_attr "amdfam10_decode" "*,*,vector,double,double")
5506 (set_attr "fp_int_src" "true")])
5508 (define_insn "*floatsi<mode>2_vector_mixed"
5509 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5510 (float:MODEF (match_operand:SI 1 "memory_operand" "m,m")))]
5511 "TARGET_SSE2 && TARGET_MIX_SSE_I387
5512 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5516 [(set_attr "type" "fmov,sseicvt")
5517 (set_attr "mode" "<MODE>,<ssevecmode>")
5518 (set_attr "unit" "i387,*")
5519 (set_attr "athlon_decode" "*,direct")
5520 (set_attr "amdfam10_decode" "*,double")
5521 (set_attr "fp_int_src" "true")])
5523 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_with_temp"
5524 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x,x")
5526 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r,r,m")))
5527 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m,m,X"))]
5528 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5529 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387"
5531 [(set_attr "type" "fmov,multi,sseicvt,sseicvt")
5532 (set_attr "mode" "<MODEF:MODE>")
5533 (set_attr "unit" "*,i387,*,*")
5534 (set_attr "athlon_decode" "*,*,double,direct")
5535 (set_attr "amdfam10_decode" "*,*,vector,double")
5536 (set_attr "fp_int_src" "true")])
5539 [(set (match_operand:MODEF 0 "register_operand" "")
5540 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5541 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5542 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5543 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5544 && TARGET_INTER_UNIT_CONVERSIONS
5546 && (SSE_REG_P (operands[0])
5547 || (GET_CODE (operands[0]) == SUBREG
5548 && SSE_REG_P (operands[0])))"
5549 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5553 [(set (match_operand:MODEF 0 "register_operand" "")
5554 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5555 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5556 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5557 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5558 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5560 && (SSE_REG_P (operands[0])
5561 || (GET_CODE (operands[0]) == SUBREG
5562 && SSE_REG_P (operands[0])))"
5563 [(set (match_dup 2) (match_dup 1))
5564 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5567 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_interunit"
5568 [(set (match_operand:MODEF 0 "register_operand" "=f,x,x")
5570 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,r,m")))]
5571 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5572 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5573 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5576 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}
5577 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5578 [(set_attr "type" "fmov,sseicvt,sseicvt")
5579 (set_attr "prefix" "orig,maybe_vex,maybe_vex")
5580 (set_attr "mode" "<MODEF:MODE>")
5581 (set (attr "prefix_rex")
5583 (and (eq_attr "prefix" "maybe_vex")
5584 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5586 (const_string "*")))
5587 (set_attr "unit" "i387,*,*")
5588 (set_attr "athlon_decode" "*,double,direct")
5589 (set_attr "amdfam10_decode" "*,vector,double")
5590 (set_attr "fp_int_src" "true")])
5592 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_mixed_nointerunit"
5593 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
5595 (match_operand:SSEMODEI24 1 "memory_operand" "m,m")))]
5596 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5597 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_MIX_SSE_I387
5598 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5601 %vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5602 [(set_attr "type" "fmov,sseicvt")
5603 (set_attr "prefix" "orig,maybe_vex")
5604 (set_attr "mode" "<MODEF:MODE>")
5605 (set (attr "prefix_rex")
5607 (and (eq_attr "prefix" "maybe_vex")
5608 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5610 (const_string "*")))
5611 (set_attr "athlon_decode" "*,direct")
5612 (set_attr "amdfam10_decode" "*,double")
5613 (set_attr "fp_int_src" "true")])
5615 (define_insn "*floatsi<mode>2_vector_sse_with_temp"
5616 [(set (match_operand:MODEF 0 "register_operand" "=x,x,x")
5618 (match_operand:SI 1 "nonimmediate_operand" "r,m,!x")))
5619 (clobber (match_operand:SI 2 "memory_operand" "=m,X,m"))]
5620 "TARGET_SSE2 && TARGET_SSE_MATH
5621 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5623 [(set_attr "type" "sseicvt")
5624 (set_attr "mode" "<MODE>,<MODE>,<ssevecmode>")
5625 (set_attr "athlon_decode" "double,direct,double")
5626 (set_attr "amdfam10_decode" "vector,double,double")
5627 (set_attr "fp_int_src" "true")])
5629 (define_insn "*floatsi<mode>2_vector_sse"
5630 [(set (match_operand:MODEF 0 "register_operand" "=x")
5631 (float:MODEF (match_operand:SI 1 "memory_operand" "m")))]
5632 "TARGET_SSE2 && TARGET_SSE_MATH
5633 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)"
5635 [(set_attr "type" "sseicvt")
5636 (set_attr "mode" "<MODE>")
5637 (set_attr "athlon_decode" "direct")
5638 (set_attr "amdfam10_decode" "double")
5639 (set_attr "fp_int_src" "true")])
5642 [(set (match_operand:MODEF 0 "register_operand" "")
5643 (float:MODEF (match_operand:SI 1 "register_operand" "")))
5644 (clobber (match_operand:SI 2 "memory_operand" ""))]
5645 "TARGET_SSE2 && TARGET_SSE_MATH
5646 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5648 && (SSE_REG_P (operands[0])
5649 || (GET_CODE (operands[0]) == SUBREG
5650 && SSE_REG_P (operands[0])))"
5653 rtx op1 = operands[1];
5655 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5657 if (GET_CODE (op1) == SUBREG)
5658 op1 = SUBREG_REG (op1);
5660 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5662 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5663 emit_insn (gen_sse2_loadld (operands[4],
5664 CONST0_RTX (V4SImode), operands[1]));
5666 /* We can ignore possible trapping value in the
5667 high part of SSE register for non-trapping math. */
5668 else if (SSE_REG_P (op1) && !flag_trapping_math)
5669 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5672 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5673 emit_move_insn (operands[2], operands[1]);
5674 emit_insn (gen_sse2_loadld (operands[4],
5675 CONST0_RTX (V4SImode), operands[2]));
5678 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5683 [(set (match_operand:MODEF 0 "register_operand" "")
5684 (float:MODEF (match_operand:SI 1 "memory_operand" "")))
5685 (clobber (match_operand:SI 2 "memory_operand" ""))]
5686 "TARGET_SSE2 && TARGET_SSE_MATH
5687 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5689 && (SSE_REG_P (operands[0])
5690 || (GET_CODE (operands[0]) == SUBREG
5691 && SSE_REG_P (operands[0])))"
5694 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5696 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5698 emit_insn (gen_sse2_loadld (operands[4],
5699 CONST0_RTX (V4SImode), operands[1]));
5701 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5706 [(set (match_operand:MODEF 0 "register_operand" "")
5707 (float:MODEF (match_operand:SI 1 "register_operand" "")))]
5708 "TARGET_SSE2 && TARGET_SSE_MATH
5709 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5711 && (SSE_REG_P (operands[0])
5712 || (GET_CODE (operands[0]) == SUBREG
5713 && SSE_REG_P (operands[0])))"
5716 rtx op1 = operands[1];
5718 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5720 if (GET_CODE (op1) == SUBREG)
5721 op1 = SUBREG_REG (op1);
5723 if (GENERAL_REG_P (op1) && TARGET_INTER_UNIT_MOVES)
5725 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5726 emit_insn (gen_sse2_loadld (operands[4],
5727 CONST0_RTX (V4SImode), operands[1]));
5729 /* We can ignore possible trapping value in the
5730 high part of SSE register for non-trapping math. */
5731 else if (SSE_REG_P (op1) && !flag_trapping_math)
5732 operands[4] = simplify_gen_subreg (V4SImode, operands[1], SImode, 0);
5736 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5741 [(set (match_operand:MODEF 0 "register_operand" "")
5742 (float:MODEF (match_operand:SI 1 "memory_operand" "")))]
5743 "TARGET_SSE2 && TARGET_SSE_MATH
5744 && TARGET_USE_VECTOR_CONVERTS && optimize_function_for_speed_p (cfun)
5746 && (SSE_REG_P (operands[0])
5747 || (GET_CODE (operands[0]) == SUBREG
5748 && SSE_REG_P (operands[0])))"
5751 operands[3] = simplify_gen_subreg (<ssevecmode>mode, operands[0],
5753 operands[4] = simplify_gen_subreg (V4SImode, operands[0], <MODE>mode, 0);
5755 emit_insn (gen_sse2_loadld (operands[4],
5756 CONST0_RTX (V4SImode), operands[1]));
5758 (gen_sse2_cvtdq2p<ssemodefsuffix> (operands[3], operands[4]));
5762 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_with_temp"
5763 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5765 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))
5766 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=m,X"))]
5767 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5768 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH"
5770 [(set_attr "type" "sseicvt")
5771 (set_attr "mode" "<MODEF:MODE>")
5772 (set_attr "athlon_decode" "double,direct")
5773 (set_attr "amdfam10_decode" "vector,double")
5774 (set_attr "fp_int_src" "true")])
5776 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_interunit"
5777 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
5779 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "r,m")))]
5780 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5781 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5782 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5783 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5784 [(set_attr "type" "sseicvt")
5785 (set_attr "prefix" "maybe_vex")
5786 (set_attr "mode" "<MODEF:MODE>")
5787 (set (attr "prefix_rex")
5789 (and (eq_attr "prefix" "maybe_vex")
5790 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5792 (const_string "*")))
5793 (set_attr "athlon_decode" "double,direct")
5794 (set_attr "amdfam10_decode" "vector,double")
5795 (set_attr "fp_int_src" "true")])
5798 [(set (match_operand:MODEF 0 "register_operand" "")
5799 (float:MODEF (match_operand:SSEMODEI24 1 "nonimmediate_operand" "")))
5800 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5801 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5802 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5803 && (TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5805 && (SSE_REG_P (operands[0])
5806 || (GET_CODE (operands[0]) == SUBREG
5807 && SSE_REG_P (operands[0])))"
5808 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5811 (define_insn "*float<SSEMODEI24:mode><MODEF:mode>2_sse_nointerunit"
5812 [(set (match_operand:MODEF 0 "register_operand" "=x")
5814 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5815 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5816 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5817 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))"
5818 "%vcvtsi2s<MODEF:ssemodefsuffix><SSEMODEI24:rex64suffix>\t{%1, %d0|%d0, %1}"
5819 [(set_attr "type" "sseicvt")
5820 (set_attr "prefix" "maybe_vex")
5821 (set_attr "mode" "<MODEF:MODE>")
5822 (set (attr "prefix_rex")
5824 (and (eq_attr "prefix" "maybe_vex")
5825 (ne (symbol_ref "<SSEMODEI24:MODE>mode == DImode") (const_int 0)))
5827 (const_string "*")))
5828 (set_attr "athlon_decode" "direct")
5829 (set_attr "amdfam10_decode" "double")
5830 (set_attr "fp_int_src" "true")])
5833 [(set (match_operand:MODEF 0 "register_operand" "")
5834 (float:MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5835 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5836 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5837 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5838 && !(TARGET_INTER_UNIT_CONVERSIONS || optimize_function_for_size_p (cfun))
5840 && (SSE_REG_P (operands[0])
5841 || (GET_CODE (operands[0]) == SUBREG
5842 && SSE_REG_P (operands[0])))"
5843 [(set (match_dup 2) (match_dup 1))
5844 (set (match_dup 0) (float:MODEF (match_dup 2)))]
5848 [(set (match_operand:MODEF 0 "register_operand" "")
5849 (float:MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5850 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5851 "(<SSEMODEI24:MODE>mode != DImode || TARGET_64BIT)
5852 && SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
5854 && (SSE_REG_P (operands[0])
5855 || (GET_CODE (operands[0]) == SUBREG
5856 && SSE_REG_P (operands[0])))"
5857 [(set (match_dup 0) (float:MODEF (match_dup 1)))]
5860 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387_with_temp"
5861 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5863 (match_operand:SSEMODEI24 1 "nonimmediate_operand" "m,?r")))
5864 (clobber (match_operand:SSEMODEI24 2 "memory_operand" "=X,m"))]
5866 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5870 [(set_attr "type" "fmov,multi")
5871 (set_attr "mode" "<X87MODEF:MODE>")
5872 (set_attr "unit" "*,i387")
5873 (set_attr "fp_int_src" "true")])
5875 (define_insn "*float<SSEMODEI24:mode><X87MODEF:mode>2_i387"
5876 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
5878 (match_operand:SSEMODEI24 1 "memory_operand" "m")))]
5880 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)"
5882 [(set_attr "type" "fmov")
5883 (set_attr "mode" "<X87MODEF:MODE>")
5884 (set_attr "fp_int_src" "true")])
5887 [(set (match_operand:X87MODEF 0 "register_operand" "")
5888 (float:X87MODEF (match_operand:SSEMODEI24 1 "register_operand" "")))
5889 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5891 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5893 && FP_REG_P (operands[0])"
5894 [(set (match_dup 2) (match_dup 1))
5895 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5899 [(set (match_operand:X87MODEF 0 "register_operand" "")
5900 (float:X87MODEF (match_operand:SSEMODEI24 1 "memory_operand" "")))
5901 (clobber (match_operand:SSEMODEI24 2 "memory_operand" ""))]
5903 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, <SSEMODEI24:MODE>mode)
5905 && FP_REG_P (operands[0])"
5906 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5909 ;; Avoid store forwarding (partial memory) stall penalty
5910 ;; by passing DImode value through XMM registers. */
5912 (define_insn "floatdi<X87MODEF:mode>2_i387_with_xmm"
5913 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5915 (match_operand:DI 1 "nonimmediate_operand" "m,?r")))
5916 (clobber (match_scratch:V4SI 3 "=X,x"))
5917 (clobber (match_scratch:V4SI 4 "=X,x"))
5918 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))]
5919 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5920 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5921 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)"
5923 [(set_attr "type" "multi")
5924 (set_attr "mode" "<X87MODEF:MODE>")
5925 (set_attr "unit" "i387")
5926 (set_attr "fp_int_src" "true")])
5929 [(set (match_operand:X87MODEF 0 "register_operand" "")
5930 (float:X87MODEF (match_operand:DI 1 "register_operand" "")))
5931 (clobber (match_scratch:V4SI 3 ""))
5932 (clobber (match_scratch:V4SI 4 ""))
5933 (clobber (match_operand:DI 2 "memory_operand" ""))]
5934 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5935 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5936 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5938 && FP_REG_P (operands[0])"
5939 [(set (match_dup 2) (match_dup 3))
5940 (set (match_dup 0) (float:X87MODEF (match_dup 2)))]
5942 /* The DImode arrived in a pair of integral registers (e.g. %edx:%eax).
5943 Assemble the 64-bit DImode value in an xmm register. */
5944 emit_insn (gen_sse2_loadld (operands[3], CONST0_RTX (V4SImode),
5945 gen_rtx_SUBREG (SImode, operands[1], 0)));
5946 emit_insn (gen_sse2_loadld (operands[4], CONST0_RTX (V4SImode),
5947 gen_rtx_SUBREG (SImode, operands[1], 4)));
5948 emit_insn (gen_sse2_punpckldq (operands[3], operands[3], operands[4]));
5950 operands[3] = gen_rtx_REG (DImode, REGNO (operands[3]));
5954 [(set (match_operand:X87MODEF 0 "register_operand" "")
5955 (float:X87MODEF (match_operand:DI 1 "memory_operand" "")))
5956 (clobber (match_scratch:V4SI 3 ""))
5957 (clobber (match_scratch:V4SI 4 ""))
5958 (clobber (match_operand:DI 2 "memory_operand" ""))]
5959 "TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5960 && TARGET_SSE2 && TARGET_INTER_UNIT_MOVES
5961 && !TARGET_64BIT && optimize_function_for_speed_p (cfun)
5963 && FP_REG_P (operands[0])"
5964 [(set (match_dup 0) (float:X87MODEF (match_dup 1)))]
5967 ;; Avoid store forwarding (partial memory) stall penalty by extending
5968 ;; SImode value to DImode through XMM register instead of pushing two
5969 ;; SImode values to stack. Note that even !TARGET_INTER_UNIT_MOVES
5970 ;; targets benefit from this optimization. Also note that fild
5971 ;; loads from memory only.
5973 (define_insn "*floatunssi<mode>2_1"
5974 [(set (match_operand:X87MODEF 0 "register_operand" "=f,f")
5975 (unsigned_float:X87MODEF
5976 (match_operand:SI 1 "nonimmediate_operand" "x,m")))
5977 (clobber (match_operand:DI 2 "memory_operand" "=m,m"))
5978 (clobber (match_scratch:SI 3 "=X,x"))]
5980 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5983 [(set_attr "type" "multi")
5984 (set_attr "mode" "<MODE>")])
5987 [(set (match_operand:X87MODEF 0 "register_operand" "")
5988 (unsigned_float:X87MODEF
5989 (match_operand:SI 1 "register_operand" "")))
5990 (clobber (match_operand:DI 2 "memory_operand" ""))
5991 (clobber (match_scratch:SI 3 ""))]
5993 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
5995 && reload_completed"
5996 [(set (match_dup 2) (match_dup 1))
5998 (float:X87MODEF (match_dup 2)))]
5999 "operands[1] = simplify_gen_subreg (DImode, operands[1], SImode, 0);")
6002 [(set (match_operand:X87MODEF 0 "register_operand" "")
6003 (unsigned_float:X87MODEF
6004 (match_operand:SI 1 "memory_operand" "")))
6005 (clobber (match_operand:DI 2 "memory_operand" ""))
6006 (clobber (match_scratch:SI 3 ""))]
6008 && TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6010 && reload_completed"
6011 [(set (match_dup 2) (match_dup 3))
6013 (float:X87MODEF (match_dup 2)))]
6015 emit_move_insn (operands[3], operands[1]);
6016 operands[3] = simplify_gen_subreg (DImode, operands[3], SImode, 0);
6019 (define_expand "floatunssi<mode>2"
6021 [(set (match_operand:X87MODEF 0 "register_operand" "")
6022 (unsigned_float:X87MODEF
6023 (match_operand:SI 1 "nonimmediate_operand" "")))
6024 (clobber (match_dup 2))
6025 (clobber (match_scratch:SI 3 ""))])]
6027 && ((TARGET_80387 && X87_ENABLE_FLOAT (<X87MODEF:MODE>mode, DImode)
6029 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
6031 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
6033 ix86_expand_convert_uns_si<mode>_sse (operands[0], operands[1]);
6038 enum ix86_stack_slot slot = (virtuals_instantiated
6041 operands[2] = assign_386_stack_local (DImode, slot);
6045 (define_expand "floatunsdisf2"
6046 [(use (match_operand:SF 0 "register_operand" ""))
6047 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6048 "TARGET_64BIT && TARGET_SSE_MATH"
6049 "x86_emit_floatuns (operands); DONE;")
6051 (define_expand "floatunsdidf2"
6052 [(use (match_operand:DF 0 "register_operand" ""))
6053 (use (match_operand:DI 1 "nonimmediate_operand" ""))]
6054 "(TARGET_64BIT || TARGET_KEEPS_VECTOR_ALIGNED_STACK)
6055 && TARGET_SSE2 && TARGET_SSE_MATH"
6058 x86_emit_floatuns (operands);
6060 ix86_expand_convert_uns_didf_sse (operands[0], operands[1]);
6066 ;; %%% splits for addditi3
6068 (define_expand "addti3"
6069 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6070 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6071 (match_operand:TI 2 "x86_64_general_operand" "")))]
6073 "ix86_expand_binary_operator (PLUS, TImode, operands); DONE;")
6075 (define_insn "*addti3_1"
6076 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
6077 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "%0,0")
6078 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
6079 (clobber (reg:CC FLAGS_REG))]
6080 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, TImode, operands)"
6084 [(set (match_operand:TI 0 "nonimmediate_operand" "")
6085 (plus:TI (match_operand:TI 1 "nonimmediate_operand" "")
6086 (match_operand:TI 2 "x86_64_general_operand" "")))
6087 (clobber (reg:CC FLAGS_REG))]
6088 "TARGET_64BIT && reload_completed"
6089 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6091 (set (match_dup 0) (plus:DI (match_dup 1) (match_dup 2)))])
6092 (parallel [(set (match_dup 3)
6093 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
6096 (clobber (reg:CC FLAGS_REG))])]
6097 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
6099 ;; %%% splits for addsidi3
6100 ; [(set (match_operand:DI 0 "nonimmediate_operand" "")
6101 ; (plus:DI (match_operand:DI 1 "general_operand" "")
6102 ; (zero_extend:DI (match_operand:SI 2 "general_operand" ""))))]
6104 (define_expand "adddi3"
6105 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6106 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6107 (match_operand:DI 2 "x86_64_general_operand" "")))]
6109 "ix86_expand_binary_operator (PLUS, DImode, operands); DONE;")
6111 (define_insn "*adddi3_1"
6112 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
6113 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6114 (match_operand:DI 2 "general_operand" "roiF,riF")))
6115 (clobber (reg:CC FLAGS_REG))]
6116 "!TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6120 [(set (match_operand:DI 0 "nonimmediate_operand" "")
6121 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "")
6122 (match_operand:DI 2 "general_operand" "")))
6123 (clobber (reg:CC FLAGS_REG))]
6124 "!TARGET_64BIT && reload_completed"
6125 [(parallel [(set (reg:CC FLAGS_REG) (unspec:CC [(match_dup 1) (match_dup 2)]
6127 (set (match_dup 0) (plus:SI (match_dup 1) (match_dup 2)))])
6128 (parallel [(set (match_dup 3)
6129 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
6132 (clobber (reg:CC FLAGS_REG))])]
6133 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
6135 (define_insn "adddi3_carry_rex64"
6136 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6137 (plus:DI (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
6138 (match_operand:DI 1 "nonimmediate_operand" "%0,0"))
6139 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
6140 (clobber (reg:CC FLAGS_REG))]
6141 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6142 "adc{q}\t{%2, %0|%0, %2}"
6143 [(set_attr "type" "alu")
6144 (set_attr "use_carry" "1")
6145 (set_attr "pent_pair" "pu")
6146 (set_attr "mode" "DI")])
6148 (define_insn "*adddi3_cc_rex64"
6149 [(set (reg:CC FLAGS_REG)
6150 (unspec:CC [(match_operand:DI 1 "nonimmediate_operand" "%0,0")
6151 (match_operand:DI 2 "x86_64_general_operand" "re,rm")]
6153 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
6154 (plus:DI (match_dup 1) (match_dup 2)))]
6155 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6156 "add{q}\t{%2, %0|%0, %2}"
6157 [(set_attr "type" "alu")
6158 (set_attr "mode" "DI")])
6160 (define_insn "*<plusminus_insn><mode>3_cc_overflow"
6161 [(set (reg:CCC FLAGS_REG)
6164 (match_operand:SWI 1 "nonimmediate_operand" "<comm>0,0")
6165 (match_operand:SWI 2 "<general_operand>" "<r><i>,<r>m"))
6167 (set (match_operand:SWI 0 "nonimmediate_operand" "=<r>m,<r>")
6168 (plusminus:SWI (match_dup 1) (match_dup 2)))]
6169 "ix86_binary_operator_ok (<CODE>, <MODE>mode, operands)"
6170 "<plusminus_mnemonic>{<imodesuffix>}\t{%2, %0|%0, %2}"
6171 [(set_attr "type" "alu")
6172 (set_attr "mode" "<MODE>")])
6174 (define_insn "*add<mode>3_cconly_overflow"
6175 [(set (reg:CCC FLAGS_REG)
6177 (plus:SWI (match_operand:SWI 1 "nonimmediate_operand" "%0")
6178 (match_operand:SWI 2 "<general_operand>" "<r><i>m"))
6180 (clobber (match_scratch:SWI 0 "=<r>"))]
6181 "ix86_binary_operator_ok (PLUS, <MODE>mode, operands)"
6182 "add{<imodesuffix>}\t{%2, %0|%0, %2}"
6183 [(set_attr "type" "alu")
6184 (set_attr "mode" "<MODE>")])
6186 (define_insn "*sub<mode>3_cconly_overflow"
6187 [(set (reg:CCC FLAGS_REG)
6189 (minus:SWI (match_operand:SWI 0 "nonimmediate_operand" "<r>m,<r>")
6190 (match_operand:SWI 1 "<general_operand>" "<r><i>,<r>m"))
6193 "cmp{<imodesuffix>}\t{%1, %0|%0, %1}"
6194 [(set_attr "type" "icmp")
6195 (set_attr "mode" "<MODE>")])
6197 (define_insn "*<plusminus_insn>si3_zext_cc_overflow"
6198 [(set (reg:CCC FLAGS_REG)
6200 (plusminus:SI (match_operand:SI 1 "nonimmediate_operand" "<comm>0")
6201 (match_operand:SI 2 "general_operand" "g"))
6203 (set (match_operand:DI 0 "register_operand" "=r")
6204 (zero_extend:DI (plusminus:SI (match_dup 1) (match_dup 2))))]
6205 "TARGET_64BIT && ix86_binary_operator_ok (<CODE>, SImode, operands)"
6206 "<plusminus_mnemonic>{l}\t{%2, %k0|%k0, %2}"
6207 [(set_attr "type" "alu")
6208 (set_attr "mode" "SI")])
6210 (define_insn "addqi3_carry"
6211 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6212 (plus:QI (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
6213 (match_operand:QI 1 "nonimmediate_operand" "%0,0"))
6214 (match_operand:QI 2 "general_operand" "qn,qm")))
6215 (clobber (reg:CC FLAGS_REG))]
6216 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6217 "adc{b}\t{%2, %0|%0, %2}"
6218 [(set_attr "type" "alu")
6219 (set_attr "use_carry" "1")
6220 (set_attr "pent_pair" "pu")
6221 (set_attr "mode" "QI")])
6223 (define_insn "addhi3_carry"
6224 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
6225 (plus:HI (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
6226 (match_operand:HI 1 "nonimmediate_operand" "%0,0"))
6227 (match_operand:HI 2 "general_operand" "rn,rm")))
6228 (clobber (reg:CC FLAGS_REG))]
6229 "ix86_binary_operator_ok (PLUS, HImode, operands)"
6230 "adc{w}\t{%2, %0|%0, %2}"
6231 [(set_attr "type" "alu")
6232 (set_attr "use_carry" "1")
6233 (set_attr "pent_pair" "pu")
6234 (set_attr "mode" "HI")])
6236 (define_insn "addsi3_carry"
6237 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6238 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6239 (match_operand:SI 1 "nonimmediate_operand" "%0,0"))
6240 (match_operand:SI 2 "general_operand" "ri,rm")))
6241 (clobber (reg:CC FLAGS_REG))]
6242 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6243 "adc{l}\t{%2, %0|%0, %2}"
6244 [(set_attr "type" "alu")
6245 (set_attr "use_carry" "1")
6246 (set_attr "pent_pair" "pu")
6247 (set_attr "mode" "SI")])
6249 (define_insn "*addsi3_carry_zext"
6250 [(set (match_operand:DI 0 "register_operand" "=r")
6252 (plus:SI (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
6253 (match_operand:SI 1 "nonimmediate_operand" "%0"))
6254 (match_operand:SI 2 "general_operand" "g"))))
6255 (clobber (reg:CC FLAGS_REG))]
6256 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6257 "adc{l}\t{%2, %k0|%k0, %2}"
6258 [(set_attr "type" "alu")
6259 (set_attr "use_carry" "1")
6260 (set_attr "pent_pair" "pu")
6261 (set_attr "mode" "SI")])
6263 (define_insn "*addsi3_cc"
6264 [(set (reg:CC FLAGS_REG)
6265 (unspec:CC [(match_operand:SI 1 "nonimmediate_operand" "%0,0")
6266 (match_operand:SI 2 "general_operand" "ri,rm")]
6268 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
6269 (plus:SI (match_dup 1) (match_dup 2)))]
6270 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6271 "add{l}\t{%2, %0|%0, %2}"
6272 [(set_attr "type" "alu")
6273 (set_attr "mode" "SI")])
6275 (define_insn "addqi3_cc"
6276 [(set (reg:CC FLAGS_REG)
6277 (unspec:CC [(match_operand:QI 1 "nonimmediate_operand" "%0,0")
6278 (match_operand:QI 2 "general_operand" "qn,qm")]
6280 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
6281 (plus:QI (match_dup 1) (match_dup 2)))]
6282 "ix86_binary_operator_ok (PLUS, QImode, operands)"
6283 "add{b}\t{%2, %0|%0, %2}"
6284 [(set_attr "type" "alu")
6285 (set_attr "mode" "QI")])
6287 (define_expand "addsi3"
6288 [(set (match_operand:SI 0 "nonimmediate_operand" "")
6289 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "")
6290 (match_operand:SI 2 "general_operand" "")))]
6292 "ix86_expand_binary_operator (PLUS, SImode, operands); DONE;")
6294 (define_insn "*lea_1"
6295 [(set (match_operand:SI 0 "register_operand" "=r")
6296 (match_operand:SI 1 "no_seg_address_operand" "p"))]
6298 "lea{l}\t{%a1, %0|%0, %a1}"
6299 [(set_attr "type" "lea")
6300 (set_attr "mode" "SI")])
6302 (define_insn "*lea_1_rex64"
6303 [(set (match_operand:SI 0 "register_operand" "=r")
6304 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0))]
6306 "lea{l}\t{%a1, %0|%0, %a1}"
6307 [(set_attr "type" "lea")
6308 (set_attr "mode" "SI")])
6310 (define_insn "*lea_1_zext"
6311 [(set (match_operand:DI 0 "register_operand" "=r")
6313 (subreg:SI (match_operand:DI 1 "no_seg_address_operand" "p") 0)))]
6315 "lea{l}\t{%a1, %k0|%k0, %a1}"
6316 [(set_attr "type" "lea")
6317 (set_attr "mode" "SI")])
6319 (define_insn "*lea_2_rex64"
6320 [(set (match_operand:DI 0 "register_operand" "=r")
6321 (match_operand:DI 1 "no_seg_address_operand" "p"))]
6323 "lea{q}\t{%a1, %0|%0, %a1}"
6324 [(set_attr "type" "lea")
6325 (set_attr "mode" "DI")])
6327 ;; The lea patterns for non-Pmodes needs to be matched by several
6328 ;; insns converted to real lea by splitters.
6330 (define_insn_and_split "*lea_general_1"
6331 [(set (match_operand 0 "register_operand" "=r")
6332 (plus (plus (match_operand 1 "index_register_operand" "l")
6333 (match_operand 2 "register_operand" "r"))
6334 (match_operand 3 "immediate_operand" "i")))]
6335 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6336 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6337 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6338 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6339 && GET_MODE (operands[0]) == GET_MODE (operands[2])
6340 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6341 || GET_MODE (operands[3]) == VOIDmode)"
6343 "&& reload_completed"
6347 operands[0] = gen_lowpart (SImode, operands[0]);
6348 operands[1] = gen_lowpart (Pmode, operands[1]);
6349 operands[2] = gen_lowpart (Pmode, operands[2]);
6350 operands[3] = gen_lowpart (Pmode, operands[3]);
6351 pat = gen_rtx_PLUS (Pmode, gen_rtx_PLUS (Pmode, operands[1], operands[2]),
6353 if (Pmode != SImode)
6354 pat = gen_rtx_SUBREG (SImode, pat, 0);
6355 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6358 [(set_attr "type" "lea")
6359 (set_attr "mode" "SI")])
6361 (define_insn_and_split "*lea_general_1_zext"
6362 [(set (match_operand:DI 0 "register_operand" "=r")
6364 (plus:SI (plus:SI (match_operand:SI 1 "index_register_operand" "l")
6365 (match_operand:SI 2 "register_operand" "r"))
6366 (match_operand:SI 3 "immediate_operand" "i"))))]
6369 "&& reload_completed"
6371 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (match_dup 1)
6373 (match_dup 3)) 0)))]
6375 operands[1] = gen_lowpart (Pmode, operands[1]);
6376 operands[2] = gen_lowpart (Pmode, operands[2]);
6377 operands[3] = gen_lowpart (Pmode, operands[3]);
6379 [(set_attr "type" "lea")
6380 (set_attr "mode" "SI")])
6382 (define_insn_and_split "*lea_general_2"
6383 [(set (match_operand 0 "register_operand" "=r")
6384 (plus (mult (match_operand 1 "index_register_operand" "l")
6385 (match_operand 2 "const248_operand" "i"))
6386 (match_operand 3 "nonmemory_operand" "ri")))]
6387 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6388 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6389 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6390 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6391 && (GET_MODE (operands[0]) == GET_MODE (operands[3])
6392 || GET_MODE (operands[3]) == VOIDmode)"
6394 "&& reload_completed"
6398 operands[0] = gen_lowpart (SImode, operands[0]);
6399 operands[1] = gen_lowpart (Pmode, operands[1]);
6400 operands[3] = gen_lowpart (Pmode, operands[3]);
6401 pat = gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1], operands[2]),
6403 if (Pmode != SImode)
6404 pat = gen_rtx_SUBREG (SImode, pat, 0);
6405 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6408 [(set_attr "type" "lea")
6409 (set_attr "mode" "SI")])
6411 (define_insn_and_split "*lea_general_2_zext"
6412 [(set (match_operand:DI 0 "register_operand" "=r")
6414 (plus:SI (mult:SI (match_operand:SI 1 "index_register_operand" "l")
6415 (match_operand:SI 2 "const248_operand" "n"))
6416 (match_operand:SI 3 "nonmemory_operand" "ri"))))]
6419 "&& reload_completed"
6421 (zero_extend:DI (subreg:SI (plus:DI (mult:DI (match_dup 1)
6423 (match_dup 3)) 0)))]
6425 operands[1] = gen_lowpart (Pmode, operands[1]);
6426 operands[3] = gen_lowpart (Pmode, operands[3]);
6428 [(set_attr "type" "lea")
6429 (set_attr "mode" "SI")])
6431 (define_insn_and_split "*lea_general_3"
6432 [(set (match_operand 0 "register_operand" "=r")
6433 (plus (plus (mult (match_operand 1 "index_register_operand" "l")
6434 (match_operand 2 "const248_operand" "i"))
6435 (match_operand 3 "register_operand" "r"))
6436 (match_operand 4 "immediate_operand" "i")))]
6437 "(GET_MODE (operands[0]) == QImode || GET_MODE (operands[0]) == HImode
6438 || (TARGET_64BIT && GET_MODE (operands[0]) == SImode))
6439 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
6440 && GET_MODE (operands[0]) == GET_MODE (operands[1])
6441 && GET_MODE (operands[0]) == GET_MODE (operands[3])"
6443 "&& reload_completed"
6447 operands[0] = gen_lowpart (SImode, operands[0]);
6448 operands[1] = gen_lowpart (Pmode, operands[1]);
6449 operands[3] = gen_lowpart (Pmode, operands[3]);
6450 operands[4] = gen_lowpart (Pmode, operands[4]);
6451 pat = gen_rtx_PLUS (Pmode,
6452 gen_rtx_PLUS (Pmode, gen_rtx_MULT (Pmode, operands[1],
6456 if (Pmode != SImode)
6457 pat = gen_rtx_SUBREG (SImode, pat, 0);
6458 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6461 [(set_attr "type" "lea")
6462 (set_attr "mode" "SI")])
6464 (define_insn_and_split "*lea_general_3_zext"
6465 [(set (match_operand:DI 0 "register_operand" "=r")
6467 (plus:SI (plus:SI (mult:SI
6468 (match_operand:SI 1 "index_register_operand" "l")
6469 (match_operand:SI 2 "const248_operand" "n"))
6470 (match_operand:SI 3 "register_operand" "r"))
6471 (match_operand:SI 4 "immediate_operand" "i"))))]
6474 "&& reload_completed"
6476 (zero_extend:DI (subreg:SI (plus:DI (plus:DI (mult:DI (match_dup 1)
6479 (match_dup 4)) 0)))]
6481 operands[1] = gen_lowpart (Pmode, operands[1]);
6482 operands[3] = gen_lowpart (Pmode, operands[3]);
6483 operands[4] = gen_lowpart (Pmode, operands[4]);
6485 [(set_attr "type" "lea")
6486 (set_attr "mode" "SI")])
6488 (define_insn "*adddi_1_rex64"
6489 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
6490 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,r,r")
6491 (match_operand:DI 2 "x86_64_general_operand" "rme,re,0,le")))
6492 (clobber (reg:CC FLAGS_REG))]
6493 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, DImode, operands)"
6495 switch (get_attr_type (insn))
6498 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6499 return "lea{q}\t{%a2, %0|%0, %a2}";
6502 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6503 if (operands[2] == const1_rtx)
6504 return "inc{q}\t%0";
6507 gcc_assert (operands[2] == constm1_rtx);
6508 return "dec{q}\t%0";
6512 /* Use add as much as possible to replace lea for AGU optimization. */
6513 if (which_alternative == 2 && TARGET_OPT_AGU)
6514 return "add{q}\t{%1, %0|%0, %1}";
6516 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6518 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6519 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6520 if (CONST_INT_P (operands[2])
6521 /* Avoid overflows. */
6522 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6523 && (INTVAL (operands[2]) == 128
6524 || (INTVAL (operands[2]) < 0
6525 && INTVAL (operands[2]) != -128)))
6527 operands[2] = GEN_INT (-INTVAL (operands[2]));
6528 return "sub{q}\t{%2, %0|%0, %2}";
6530 return "add{q}\t{%2, %0|%0, %2}";
6534 (cond [(and (eq_attr "alternative" "2")
6535 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6536 (const_string "lea")
6537 (eq_attr "alternative" "3")
6538 (const_string "lea")
6539 ; Current assemblers are broken and do not allow @GOTOFF in
6540 ; ought but a memory context.
6541 (match_operand:DI 2 "pic_symbolic_operand" "")
6542 (const_string "lea")
6543 (match_operand:DI 2 "incdec_operand" "")
6544 (const_string "incdec")
6546 (const_string "alu")))
6547 (set (attr "length_immediate")
6549 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6551 (const_string "*")))
6552 (set_attr "mode" "DI")])
6554 ;; Convert lea to the lea pattern to avoid flags dependency.
6556 [(set (match_operand:DI 0 "register_operand" "")
6557 (plus:DI (match_operand:DI 1 "register_operand" "")
6558 (match_operand:DI 2 "x86_64_nonmemory_operand" "")))
6559 (clobber (reg:CC FLAGS_REG))]
6560 "TARGET_64BIT && reload_completed
6561 && ix86_lea_for_add_ok (PLUS, insn, operands)"
6563 (plus:DI (match_dup 1)
6567 (define_insn "*adddi_2_rex64"
6568 [(set (reg FLAGS_REG)
6570 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
6571 (match_operand:DI 2 "x86_64_general_operand" "rme,re"))
6573 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
6574 (plus:DI (match_dup 1) (match_dup 2)))]
6575 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
6576 && ix86_binary_operator_ok (PLUS, DImode, operands)
6577 /* Current assemblers are broken and do not allow @GOTOFF in
6578 ought but a memory context. */
6579 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6581 switch (get_attr_type (insn))
6584 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6585 if (operands[2] == const1_rtx)
6586 return "inc{q}\t%0";
6589 gcc_assert (operands[2] == constm1_rtx);
6590 return "dec{q}\t%0";
6594 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6595 /* ???? We ought to handle there the 32bit case too
6596 - do we need new constraint? */
6597 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6598 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6599 if (CONST_INT_P (operands[2])
6600 /* Avoid overflows. */
6601 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6602 && (INTVAL (operands[2]) == 128
6603 || (INTVAL (operands[2]) < 0
6604 && INTVAL (operands[2]) != -128)))
6606 operands[2] = GEN_INT (-INTVAL (operands[2]));
6607 return "sub{q}\t{%2, %0|%0, %2}";
6609 return "add{q}\t{%2, %0|%0, %2}";
6613 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6614 (const_string "incdec")
6615 (const_string "alu")))
6616 (set (attr "length_immediate")
6618 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6620 (const_string "*")))
6621 (set_attr "mode" "DI")])
6623 (define_insn "*adddi_3_rex64"
6624 [(set (reg FLAGS_REG)
6625 (compare (neg:DI (match_operand:DI 2 "x86_64_general_operand" "rme"))
6626 (match_operand:DI 1 "x86_64_general_operand" "%0")))
6627 (clobber (match_scratch:DI 0 "=r"))]
6629 && ix86_match_ccmode (insn, CCZmode)
6630 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6631 /* Current assemblers are broken and do not allow @GOTOFF in
6632 ought but a memory context. */
6633 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6635 switch (get_attr_type (insn))
6638 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6639 if (operands[2] == const1_rtx)
6640 return "inc{q}\t%0";
6643 gcc_assert (operands[2] == constm1_rtx);
6644 return "dec{q}\t%0";
6648 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6649 /* ???? We ought to handle there the 32bit case too
6650 - do we need new constraint? */
6651 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6652 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6653 if (CONST_INT_P (operands[2])
6654 /* Avoid overflows. */
6655 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6656 && (INTVAL (operands[2]) == 128
6657 || (INTVAL (operands[2]) < 0
6658 && INTVAL (operands[2]) != -128)))
6660 operands[2] = GEN_INT (-INTVAL (operands[2]));
6661 return "sub{q}\t{%2, %0|%0, %2}";
6663 return "add{q}\t{%2, %0|%0, %2}";
6667 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6668 (const_string "incdec")
6669 (const_string "alu")))
6670 (set (attr "length_immediate")
6672 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6674 (const_string "*")))
6675 (set_attr "mode" "DI")])
6677 ; For comparisons against 1, -1 and 128, we may generate better code
6678 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
6679 ; is matched then. We can't accept general immediate, because for
6680 ; case of overflows, the result is messed up.
6681 ; This pattern also don't hold of 0x8000000000000000, since the value overflows
6683 ; Also carry flag is reversed compared to cmp, so this conversion is valid
6684 ; only for comparisons not depending on it.
6685 (define_insn "*adddi_4_rex64"
6686 [(set (reg FLAGS_REG)
6687 (compare (match_operand:DI 1 "nonimmediate_operand" "0")
6688 (match_operand:DI 2 "x86_64_immediate_operand" "e")))
6689 (clobber (match_scratch:DI 0 "=rm"))]
6691 && ix86_match_ccmode (insn, CCGCmode)"
6693 switch (get_attr_type (insn))
6696 if (operands[2] == constm1_rtx)
6697 return "inc{q}\t%0";
6700 gcc_assert (operands[2] == const1_rtx);
6701 return "dec{q}\t%0";
6705 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6706 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6707 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6708 if ((INTVAL (operands[2]) == -128
6709 || (INTVAL (operands[2]) > 0
6710 && INTVAL (operands[2]) != 128))
6711 /* Avoid overflows. */
6712 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1))))
6713 return "sub{q}\t{%2, %0|%0, %2}";
6714 operands[2] = GEN_INT (-INTVAL (operands[2]));
6715 return "add{q}\t{%2, %0|%0, %2}";
6719 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6720 (const_string "incdec")
6721 (const_string "alu")))
6722 (set (attr "length_immediate")
6724 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6726 (const_string "*")))
6727 (set_attr "mode" "DI")])
6729 (define_insn "*adddi_5_rex64"
6730 [(set (reg FLAGS_REG)
6732 (plus:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
6733 (match_operand:DI 2 "x86_64_general_operand" "rme"))
6735 (clobber (match_scratch:DI 0 "=r"))]
6737 && ix86_match_ccmode (insn, CCGOCmode)
6738 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
6739 /* Current assemblers are broken and do not allow @GOTOFF in
6740 ought but a memory context. */
6741 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6743 switch (get_attr_type (insn))
6746 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6747 if (operands[2] == const1_rtx)
6748 return "inc{q}\t%0";
6751 gcc_assert (operands[2] == constm1_rtx);
6752 return "dec{q}\t%0";
6756 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6757 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6758 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6759 if (CONST_INT_P (operands[2])
6760 /* Avoid overflows. */
6761 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
6762 && (INTVAL (operands[2]) == 128
6763 || (INTVAL (operands[2]) < 0
6764 && INTVAL (operands[2]) != -128)))
6766 operands[2] = GEN_INT (-INTVAL (operands[2]));
6767 return "sub{q}\t{%2, %0|%0, %2}";
6769 return "add{q}\t{%2, %0|%0, %2}";
6773 (if_then_else (match_operand:DI 2 "incdec_operand" "")
6774 (const_string "incdec")
6775 (const_string "alu")))
6776 (set (attr "length_immediate")
6778 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6780 (const_string "*")))
6781 (set_attr "mode" "DI")])
6784 (define_insn "*addsi_1"
6785 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,rm,r,r")
6786 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,r,r")
6787 (match_operand:SI 2 "general_operand" "g,ri,0,li")))
6788 (clobber (reg:CC FLAGS_REG))]
6789 "ix86_binary_operator_ok (PLUS, SImode, operands)"
6791 switch (get_attr_type (insn))
6794 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6795 return "lea{l}\t{%a2, %0|%0, %a2}";
6798 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6799 if (operands[2] == const1_rtx)
6800 return "inc{l}\t%0";
6803 gcc_assert (operands[2] == constm1_rtx);
6804 return "dec{l}\t%0";
6808 /* Use add as much as possible to replace lea for AGU optimization. */
6809 if (which_alternative == 2 && TARGET_OPT_AGU)
6810 return "add{l}\t{%1, %0|%0, %1}";
6812 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6814 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6815 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6816 if (CONST_INT_P (operands[2])
6817 && (INTVAL (operands[2]) == 128
6818 || (INTVAL (operands[2]) < 0
6819 && INTVAL (operands[2]) != -128)))
6821 operands[2] = GEN_INT (-INTVAL (operands[2]));
6822 return "sub{l}\t{%2, %0|%0, %2}";
6824 return "add{l}\t{%2, %0|%0, %2}";
6828 (cond [(and (eq_attr "alternative" "2")
6829 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
6830 (const_string "lea")
6831 (eq_attr "alternative" "3")
6832 (const_string "lea")
6833 ; Current assemblers are broken and do not allow @GOTOFF in
6834 ; ought but a memory context.
6835 (match_operand:SI 2 "pic_symbolic_operand" "")
6836 (const_string "lea")
6837 (match_operand:SI 2 "incdec_operand" "")
6838 (const_string "incdec")
6840 (const_string "alu")))
6841 (set (attr "length_immediate")
6843 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6845 (const_string "*")))
6846 (set_attr "mode" "SI")])
6848 ;; Convert lea to the lea pattern to avoid flags dependency.
6850 [(set (match_operand 0 "register_operand" "")
6851 (plus (match_operand 1 "register_operand" "")
6852 (match_operand 2 "nonmemory_operand" "")))
6853 (clobber (reg:CC FLAGS_REG))]
6854 "reload_completed && ix86_lea_for_add_ok (PLUS, insn, operands)"
6858 /* In -fPIC mode the constructs like (const (unspec [symbol_ref]))
6859 may confuse gen_lowpart. */
6860 if (GET_MODE (operands[0]) != Pmode)
6862 operands[1] = gen_lowpart (Pmode, operands[1]);
6863 operands[2] = gen_lowpart (Pmode, operands[2]);
6865 operands[0] = gen_lowpart (SImode, operands[0]);
6866 pat = gen_rtx_PLUS (Pmode, operands[1], operands[2]);
6867 if (Pmode != SImode)
6868 pat = gen_rtx_SUBREG (SImode, pat, 0);
6869 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
6873 ;; It may seem that nonimmediate operand is proper one for operand 1.
6874 ;; The addsi_1 pattern allows nonimmediate operand at that place and
6875 ;; we take care in ix86_binary_operator_ok to not allow two memory
6876 ;; operands so proper swapping will be done in reload. This allow
6877 ;; patterns constructed from addsi_1 to match.
6878 (define_insn "addsi_1_zext"
6879 [(set (match_operand:DI 0 "register_operand" "=r,r")
6881 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,r")
6882 (match_operand:SI 2 "general_operand" "g,li"))))
6883 (clobber (reg:CC FLAGS_REG))]
6884 "TARGET_64BIT && ix86_binary_operator_ok (PLUS, SImode, operands)"
6886 switch (get_attr_type (insn))
6889 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
6890 return "lea{l}\t{%a2, %k0|%k0, %a2}";
6893 if (operands[2] == const1_rtx)
6894 return "inc{l}\t%k0";
6897 gcc_assert (operands[2] == constm1_rtx);
6898 return "dec{l}\t%k0";
6902 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6903 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6904 if (CONST_INT_P (operands[2])
6905 && (INTVAL (operands[2]) == 128
6906 || (INTVAL (operands[2]) < 0
6907 && INTVAL (operands[2]) != -128)))
6909 operands[2] = GEN_INT (-INTVAL (operands[2]));
6910 return "sub{l}\t{%2, %k0|%k0, %2}";
6912 return "add{l}\t{%2, %k0|%k0, %2}";
6916 (cond [(eq_attr "alternative" "1")
6917 (const_string "lea")
6918 ; Current assemblers are broken and do not allow @GOTOFF in
6919 ; ought but a memory context.
6920 (match_operand:SI 2 "pic_symbolic_operand" "")
6921 (const_string "lea")
6922 (match_operand:SI 2 "incdec_operand" "")
6923 (const_string "incdec")
6925 (const_string "alu")))
6926 (set (attr "length_immediate")
6928 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6930 (const_string "*")))
6931 (set_attr "mode" "SI")])
6933 ;; Convert lea to the lea pattern to avoid flags dependency.
6935 [(set (match_operand:DI 0 "register_operand" "")
6937 (plus:SI (match_operand:SI 1 "register_operand" "")
6938 (match_operand:SI 2 "nonmemory_operand" ""))))
6939 (clobber (reg:CC FLAGS_REG))]
6940 "TARGET_64BIT && reload_completed
6941 && true_regnum (operands[0]) != true_regnum (operands[1])"
6943 (zero_extend:DI (subreg:SI (plus:DI (match_dup 1) (match_dup 2)) 0)))]
6945 operands[1] = gen_lowpart (Pmode, operands[1]);
6946 operands[2] = gen_lowpart (Pmode, operands[2]);
6949 (define_insn "*addsi_2"
6950 [(set (reg FLAGS_REG)
6952 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
6953 (match_operand:SI 2 "general_operand" "g,ri"))
6955 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
6956 (plus:SI (match_dup 1) (match_dup 2)))]
6957 "ix86_match_ccmode (insn, CCGOCmode)
6958 && ix86_binary_operator_ok (PLUS, SImode, operands)
6959 /* Current assemblers are broken and do not allow @GOTOFF in
6960 ought but a memory context. */
6961 && ! pic_symbolic_operand (operands[2], VOIDmode)"
6963 switch (get_attr_type (insn))
6966 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6967 if (operands[2] == const1_rtx)
6968 return "inc{l}\t%0";
6971 gcc_assert (operands[2] == constm1_rtx);
6972 return "dec{l}\t%0";
6976 gcc_assert (rtx_equal_p (operands[0], operands[1]));
6977 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
6978 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
6979 if (CONST_INT_P (operands[2])
6980 && (INTVAL (operands[2]) == 128
6981 || (INTVAL (operands[2]) < 0
6982 && INTVAL (operands[2]) != -128)))
6984 operands[2] = GEN_INT (-INTVAL (operands[2]));
6985 return "sub{l}\t{%2, %0|%0, %2}";
6987 return "add{l}\t{%2, %0|%0, %2}";
6991 (if_then_else (match_operand:SI 2 "incdec_operand" "")
6992 (const_string "incdec")
6993 (const_string "alu")))
6994 (set (attr "length_immediate")
6996 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
6998 (const_string "*")))
6999 (set_attr "mode" "SI")])
7001 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7002 (define_insn "*addsi_2_zext"
7003 [(set (reg FLAGS_REG)
7005 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7006 (match_operand:SI 2 "general_operand" "g"))
7008 (set (match_operand:DI 0 "register_operand" "=r")
7009 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7010 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
7011 && ix86_binary_operator_ok (PLUS, SImode, operands)
7012 /* Current assemblers are broken and do not allow @GOTOFF in
7013 ought but a memory context. */
7014 && ! pic_symbolic_operand (operands[2], VOIDmode)"
7016 switch (get_attr_type (insn))
7019 if (operands[2] == const1_rtx)
7020 return "inc{l}\t%k0";
7023 gcc_assert (operands[2] == constm1_rtx);
7024 return "dec{l}\t%k0";
7028 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7029 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7030 if (CONST_INT_P (operands[2])
7031 && (INTVAL (operands[2]) == 128
7032 || (INTVAL (operands[2]) < 0
7033 && INTVAL (operands[2]) != -128)))
7035 operands[2] = GEN_INT (-INTVAL (operands[2]));
7036 return "sub{l}\t{%2, %k0|%k0, %2}";
7038 return "add{l}\t{%2, %k0|%k0, %2}";
7042 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7043 (const_string "incdec")
7044 (const_string "alu")))
7045 (set (attr "length_immediate")
7047 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7049 (const_string "*")))
7050 (set_attr "mode" "SI")])
7052 (define_insn "*addsi_3"
7053 [(set (reg FLAGS_REG)
7054 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
7055 (match_operand:SI 1 "nonimmediate_operand" "%0")))
7056 (clobber (match_scratch:SI 0 "=r"))]
7057 "ix86_match_ccmode (insn, CCZmode)
7058 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7059 /* Current assemblers are broken and do not allow @GOTOFF in
7060 ought but a memory context. */
7061 && ! pic_symbolic_operand (operands[2], VOIDmode)"
7063 switch (get_attr_type (insn))
7066 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7067 if (operands[2] == const1_rtx)
7068 return "inc{l}\t%0";
7071 gcc_assert (operands[2] == constm1_rtx);
7072 return "dec{l}\t%0";
7076 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7077 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7078 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7079 if (CONST_INT_P (operands[2])
7080 && (INTVAL (operands[2]) == 128
7081 || (INTVAL (operands[2]) < 0
7082 && INTVAL (operands[2]) != -128)))
7084 operands[2] = GEN_INT (-INTVAL (operands[2]));
7085 return "sub{l}\t{%2, %0|%0, %2}";
7087 return "add{l}\t{%2, %0|%0, %2}";
7091 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7092 (const_string "incdec")
7093 (const_string "alu")))
7094 (set (attr "length_immediate")
7096 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7098 (const_string "*")))
7099 (set_attr "mode" "SI")])
7101 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
7102 (define_insn "*addsi_3_zext"
7103 [(set (reg FLAGS_REG)
7104 (compare (neg:SI (match_operand:SI 2 "general_operand" "g"))
7105 (match_operand:SI 1 "nonimmediate_operand" "%0")))
7106 (set (match_operand:DI 0 "register_operand" "=r")
7107 (zero_extend:DI (plus:SI (match_dup 1) (match_dup 2))))]
7108 "TARGET_64BIT && ix86_match_ccmode (insn, CCZmode)
7109 && ix86_binary_operator_ok (PLUS, SImode, operands)
7110 /* Current assemblers are broken and do not allow @GOTOFF in
7111 ought but a memory context. */
7112 && ! pic_symbolic_operand (operands[2], VOIDmode)"
7114 switch (get_attr_type (insn))
7117 if (operands[2] == const1_rtx)
7118 return "inc{l}\t%k0";
7121 gcc_assert (operands[2] == constm1_rtx);
7122 return "dec{l}\t%k0";
7126 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7127 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7128 if (CONST_INT_P (operands[2])
7129 && (INTVAL (operands[2]) == 128
7130 || (INTVAL (operands[2]) < 0
7131 && INTVAL (operands[2]) != -128)))
7133 operands[2] = GEN_INT (-INTVAL (operands[2]));
7134 return "sub{l}\t{%2, %k0|%k0, %2}";
7136 return "add{l}\t{%2, %k0|%k0, %2}";
7140 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7141 (const_string "incdec")
7142 (const_string "alu")))
7143 (set (attr "length_immediate")
7145 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7147 (const_string "*")))
7148 (set_attr "mode" "SI")])
7150 ; For comparisons against 1, -1 and 128, we may generate better code
7151 ; by converting cmp to add, inc or dec as done by peephole2. This pattern
7152 ; is matched then. We can't accept general immediate, because for
7153 ; case of overflows, the result is messed up.
7154 ; This pattern also don't hold of 0x80000000, since the value overflows
7156 ; Also carry flag is reversed compared to cmp, so this conversion is valid
7157 ; only for comparisons not depending on it.
7158 (define_insn "*addsi_4"
7159 [(set (reg FLAGS_REG)
7160 (compare (match_operand:SI 1 "nonimmediate_operand" "0")
7161 (match_operand:SI 2 "const_int_operand" "n")))
7162 (clobber (match_scratch:SI 0 "=rm"))]
7163 "ix86_match_ccmode (insn, CCGCmode)
7164 && (INTVAL (operands[2]) & 0xffffffff) != 0x80000000"
7166 switch (get_attr_type (insn))
7169 if (operands[2] == constm1_rtx)
7170 return "inc{l}\t%0";
7173 gcc_assert (operands[2] == const1_rtx);
7174 return "dec{l}\t%0";
7178 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7179 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7180 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7181 if ((INTVAL (operands[2]) == -128
7182 || (INTVAL (operands[2]) > 0
7183 && INTVAL (operands[2]) != 128)))
7184 return "sub{l}\t{%2, %0|%0, %2}";
7185 operands[2] = GEN_INT (-INTVAL (operands[2]));
7186 return "add{l}\t{%2, %0|%0, %2}";
7190 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7191 (const_string "incdec")
7192 (const_string "alu")))
7193 (set (attr "length_immediate")
7195 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7197 (const_string "*")))
7198 (set_attr "mode" "SI")])
7200 (define_insn "*addsi_5"
7201 [(set (reg FLAGS_REG)
7203 (plus:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
7204 (match_operand:SI 2 "general_operand" "g"))
7206 (clobber (match_scratch:SI 0 "=r"))]
7207 "ix86_match_ccmode (insn, CCGOCmode)
7208 && !(MEM_P (operands[1]) && MEM_P (operands[2]))
7209 /* Current assemblers are broken and do not allow @GOTOFF in
7210 ought but a memory context. */
7211 && ! pic_symbolic_operand (operands[2], VOIDmode)"
7213 switch (get_attr_type (insn))
7216 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7217 if (operands[2] == const1_rtx)
7218 return "inc{l}\t%0";
7221 gcc_assert (operands[2] == constm1_rtx);
7222 return "dec{l}\t%0";
7226 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7227 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7228 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7229 if (CONST_INT_P (operands[2])
7230 && (INTVAL (operands[2]) == 128
7231 || (INTVAL (operands[2]) < 0
7232 && INTVAL (operands[2]) != -128)))
7234 operands[2] = GEN_INT (-INTVAL (operands[2]));
7235 return "sub{l}\t{%2, %0|%0, %2}";
7237 return "add{l}\t{%2, %0|%0, %2}";
7241 (if_then_else (match_operand:SI 2 "incdec_operand" "")
7242 (const_string "incdec")
7243 (const_string "alu")))
7244 (set (attr "length_immediate")
7246 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7248 (const_string "*")))
7249 (set_attr "mode" "SI")])
7251 (define_expand "addhi3"
7252 [(set (match_operand:HI 0 "nonimmediate_operand" "")
7253 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "")
7254 (match_operand:HI 2 "general_operand" "")))]
7255 "TARGET_HIMODE_MATH"
7256 "ix86_expand_binary_operator (PLUS, HImode, operands); DONE;")
7258 ;; %%% After Dave's SUBREG_BYTE stuff goes in, re-enable incb %ah
7259 ;; type optimizations enabled by define-splits. This is not important
7260 ;; for PII, and in fact harmful because of partial register stalls.
7262 (define_insn "*addhi_1_lea"
7263 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
7264 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,r")
7265 (match_operand:HI 2 "general_operand" "rn,rm,ln")))
7266 (clobber (reg:CC FLAGS_REG))]
7267 "!TARGET_PARTIAL_REG_STALL
7268 && ix86_binary_operator_ok (PLUS, HImode, operands)"
7270 switch (get_attr_type (insn))
7275 if (operands[2] == const1_rtx)
7276 return "inc{w}\t%0";
7279 gcc_assert (operands[2] == constm1_rtx);
7280 return "dec{w}\t%0";
7284 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7285 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7286 if (CONST_INT_P (operands[2])
7287 && (INTVAL (operands[2]) == 128
7288 || (INTVAL (operands[2]) < 0
7289 && INTVAL (operands[2]) != -128)))
7291 operands[2] = GEN_INT (-INTVAL (operands[2]));
7292 return "sub{w}\t{%2, %0|%0, %2}";
7294 return "add{w}\t{%2, %0|%0, %2}";
7298 (if_then_else (eq_attr "alternative" "2")
7299 (const_string "lea")
7300 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7301 (const_string "incdec")
7302 (const_string "alu"))))
7303 (set (attr "length_immediate")
7305 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7307 (const_string "*")))
7308 (set_attr "mode" "HI,HI,SI")])
7310 (define_insn "*addhi_1"
7311 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
7312 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7313 (match_operand:HI 2 "general_operand" "rn,rm")))
7314 (clobber (reg:CC FLAGS_REG))]
7315 "TARGET_PARTIAL_REG_STALL
7316 && ix86_binary_operator_ok (PLUS, HImode, operands)"
7318 switch (get_attr_type (insn))
7321 if (operands[2] == const1_rtx)
7322 return "inc{w}\t%0";
7325 gcc_assert (operands[2] == constm1_rtx);
7326 return "dec{w}\t%0";
7330 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7331 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7332 if (CONST_INT_P (operands[2])
7333 && (INTVAL (operands[2]) == 128
7334 || (INTVAL (operands[2]) < 0
7335 && INTVAL (operands[2]) != -128)))
7337 operands[2] = GEN_INT (-INTVAL (operands[2]));
7338 return "sub{w}\t{%2, %0|%0, %2}";
7340 return "add{w}\t{%2, %0|%0, %2}";
7344 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7345 (const_string "incdec")
7346 (const_string "alu")))
7347 (set (attr "length_immediate")
7349 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7351 (const_string "*")))
7352 (set_attr "mode" "HI")])
7354 (define_insn "*addhi_2"
7355 [(set (reg FLAGS_REG)
7357 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
7358 (match_operand:HI 2 "general_operand" "rmn,rn"))
7360 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
7361 (plus:HI (match_dup 1) (match_dup 2)))]
7362 "ix86_match_ccmode (insn, CCGOCmode)
7363 && ix86_binary_operator_ok (PLUS, HImode, operands)"
7365 switch (get_attr_type (insn))
7368 if (operands[2] == const1_rtx)
7369 return "inc{w}\t%0";
7372 gcc_assert (operands[2] == constm1_rtx);
7373 return "dec{w}\t%0";
7377 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7378 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7379 if (CONST_INT_P (operands[2])
7380 && (INTVAL (operands[2]) == 128
7381 || (INTVAL (operands[2]) < 0
7382 && INTVAL (operands[2]) != -128)))
7384 operands[2] = GEN_INT (-INTVAL (operands[2]));
7385 return "sub{w}\t{%2, %0|%0, %2}";
7387 return "add{w}\t{%2, %0|%0, %2}";
7391 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7392 (const_string "incdec")
7393 (const_string "alu")))
7394 (set (attr "length_immediate")
7396 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7398 (const_string "*")))
7399 (set_attr "mode" "HI")])
7401 (define_insn "*addhi_3"
7402 [(set (reg FLAGS_REG)
7403 (compare (neg:HI (match_operand:HI 2 "general_operand" "rmn"))
7404 (match_operand:HI 1 "nonimmediate_operand" "%0")))
7405 (clobber (match_scratch:HI 0 "=r"))]
7406 "ix86_match_ccmode (insn, CCZmode)
7407 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7409 switch (get_attr_type (insn))
7412 if (operands[2] == const1_rtx)
7413 return "inc{w}\t%0";
7416 gcc_assert (operands[2] == constm1_rtx);
7417 return "dec{w}\t%0";
7421 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7422 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7423 if (CONST_INT_P (operands[2])
7424 && (INTVAL (operands[2]) == 128
7425 || (INTVAL (operands[2]) < 0
7426 && INTVAL (operands[2]) != -128)))
7428 operands[2] = GEN_INT (-INTVAL (operands[2]));
7429 return "sub{w}\t{%2, %0|%0, %2}";
7431 return "add{w}\t{%2, %0|%0, %2}";
7435 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7436 (const_string "incdec")
7437 (const_string "alu")))
7438 (set (attr "length_immediate")
7440 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7442 (const_string "*")))
7443 (set_attr "mode" "HI")])
7445 ; See comments above addsi_4 for details.
7446 (define_insn "*addhi_4"
7447 [(set (reg FLAGS_REG)
7448 (compare (match_operand:HI 1 "nonimmediate_operand" "0")
7449 (match_operand:HI 2 "const_int_operand" "n")))
7450 (clobber (match_scratch:HI 0 "=rm"))]
7451 "ix86_match_ccmode (insn, CCGCmode)
7452 && (INTVAL (operands[2]) & 0xffff) != 0x8000"
7454 switch (get_attr_type (insn))
7457 if (operands[2] == constm1_rtx)
7458 return "inc{w}\t%0";
7461 gcc_assert (operands[2] == const1_rtx);
7462 return "dec{w}\t%0";
7466 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7467 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7468 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7469 if ((INTVAL (operands[2]) == -128
7470 || (INTVAL (operands[2]) > 0
7471 && INTVAL (operands[2]) != 128)))
7472 return "sub{w}\t{%2, %0|%0, %2}";
7473 operands[2] = GEN_INT (-INTVAL (operands[2]));
7474 return "add{w}\t{%2, %0|%0, %2}";
7478 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7479 (const_string "incdec")
7480 (const_string "alu")))
7481 (set (attr "length_immediate")
7483 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7485 (const_string "*")))
7486 (set_attr "mode" "HI")])
7489 (define_insn "*addhi_5"
7490 [(set (reg FLAGS_REG)
7492 (plus:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
7493 (match_operand:HI 2 "general_operand" "rmn"))
7495 (clobber (match_scratch:HI 0 "=r"))]
7496 "ix86_match_ccmode (insn, CCGOCmode)
7497 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7499 switch (get_attr_type (insn))
7502 if (operands[2] == const1_rtx)
7503 return "inc{w}\t%0";
7506 gcc_assert (operands[2] == constm1_rtx);
7507 return "dec{w}\t%0";
7511 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7512 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7513 if (CONST_INT_P (operands[2])
7514 && (INTVAL (operands[2]) == 128
7515 || (INTVAL (operands[2]) < 0
7516 && INTVAL (operands[2]) != -128)))
7518 operands[2] = GEN_INT (-INTVAL (operands[2]));
7519 return "sub{w}\t{%2, %0|%0, %2}";
7521 return "add{w}\t{%2, %0|%0, %2}";
7525 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7526 (const_string "incdec")
7527 (const_string "alu")))
7528 (set (attr "length_immediate")
7530 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7532 (const_string "*")))
7533 (set_attr "mode" "HI")])
7535 (define_expand "addqi3"
7536 [(set (match_operand:QI 0 "nonimmediate_operand" "")
7537 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "")
7538 (match_operand:QI 2 "general_operand" "")))]
7539 "TARGET_QIMODE_MATH"
7540 "ix86_expand_binary_operator (PLUS, QImode, operands); DONE;")
7542 ;; %%% Potential partial reg stall on alternative 2. What to do?
7543 (define_insn "*addqi_1_lea"
7544 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r,r")
7545 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0,r")
7546 (match_operand:QI 2 "general_operand" "qn,qmn,rn,ln")))
7547 (clobber (reg:CC FLAGS_REG))]
7548 "!TARGET_PARTIAL_REG_STALL
7549 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7551 int widen = (which_alternative == 2);
7552 switch (get_attr_type (insn))
7557 if (operands[2] == const1_rtx)
7558 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7561 gcc_assert (operands[2] == constm1_rtx);
7562 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7566 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7567 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7568 if (CONST_INT_P (operands[2])
7569 && (INTVAL (operands[2]) == 128
7570 || (INTVAL (operands[2]) < 0
7571 && INTVAL (operands[2]) != -128)))
7573 operands[2] = GEN_INT (-INTVAL (operands[2]));
7575 return "sub{l}\t{%2, %k0|%k0, %2}";
7577 return "sub{b}\t{%2, %0|%0, %2}";
7580 return "add{l}\t{%k2, %k0|%k0, %k2}";
7582 return "add{b}\t{%2, %0|%0, %2}";
7586 (if_then_else (eq_attr "alternative" "3")
7587 (const_string "lea")
7588 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7589 (const_string "incdec")
7590 (const_string "alu"))))
7591 (set (attr "length_immediate")
7593 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7595 (const_string "*")))
7596 (set_attr "mode" "QI,QI,SI,SI")])
7598 (define_insn "*addqi_1"
7599 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
7600 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
7601 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
7602 (clobber (reg:CC FLAGS_REG))]
7603 "TARGET_PARTIAL_REG_STALL
7604 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7606 int widen = (which_alternative == 2);
7607 switch (get_attr_type (insn))
7610 if (operands[2] == const1_rtx)
7611 return widen ? "inc{l}\t%k0" : "inc{b}\t%0";
7614 gcc_assert (operands[2] == constm1_rtx);
7615 return widen ? "dec{l}\t%k0" : "dec{b}\t%0";
7619 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'.
7620 Exceptions: -128 encodes smaller than 128, so swap sign and op. */
7621 if (CONST_INT_P (operands[2])
7622 && (INTVAL (operands[2]) == 128
7623 || (INTVAL (operands[2]) < 0
7624 && INTVAL (operands[2]) != -128)))
7626 operands[2] = GEN_INT (-INTVAL (operands[2]));
7628 return "sub{l}\t{%2, %k0|%k0, %2}";
7630 return "sub{b}\t{%2, %0|%0, %2}";
7633 return "add{l}\t{%k2, %k0|%k0, %k2}";
7635 return "add{b}\t{%2, %0|%0, %2}";
7639 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7640 (const_string "incdec")
7641 (const_string "alu")))
7642 (set (attr "length_immediate")
7644 (and (eq_attr "type" "alu") (match_operand 2 "const128_operand" ""))
7646 (const_string "*")))
7647 (set_attr "mode" "QI,QI,SI")])
7649 (define_insn "*addqi_1_slp"
7650 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
7651 (plus:QI (match_dup 0)
7652 (match_operand:QI 1 "general_operand" "qn,qnm")))
7653 (clobber (reg:CC FLAGS_REG))]
7654 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
7655 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
7657 switch (get_attr_type (insn))
7660 if (operands[1] == const1_rtx)
7661 return "inc{b}\t%0";
7664 gcc_assert (operands[1] == constm1_rtx);
7665 return "dec{b}\t%0";
7669 /* Make things pretty and `subl $4,%eax' rather than `addl $-4, %eax'. */
7670 if (CONST_INT_P (operands[1])
7671 && INTVAL (operands[1]) < 0)
7673 operands[1] = GEN_INT (-INTVAL (operands[1]));
7674 return "sub{b}\t{%1, %0|%0, %1}";
7676 return "add{b}\t{%1, %0|%0, %1}";
7680 (if_then_else (match_operand:QI 1 "incdec_operand" "")
7681 (const_string "incdec")
7682 (const_string "alu1")))
7683 (set (attr "memory")
7684 (if_then_else (match_operand 1 "memory_operand" "")
7685 (const_string "load")
7686 (const_string "none")))
7687 (set_attr "mode" "QI")])
7689 (define_insn "*addqi_2"
7690 [(set (reg FLAGS_REG)
7692 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
7693 (match_operand:QI 2 "general_operand" "qmn,qn"))
7695 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
7696 (plus:QI (match_dup 1) (match_dup 2)))]
7697 "ix86_match_ccmode (insn, CCGOCmode)
7698 && ix86_binary_operator_ok (PLUS, QImode, operands)"
7700 switch (get_attr_type (insn))
7703 if (operands[2] == const1_rtx)
7704 return "inc{b}\t%0";
7707 gcc_assert (operands[2] == constm1_rtx
7708 || (CONST_INT_P (operands[2])
7709 && INTVAL (operands[2]) == 255));
7710 return "dec{b}\t%0";
7714 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7715 if (CONST_INT_P (operands[2])
7716 && INTVAL (operands[2]) < 0)
7718 operands[2] = GEN_INT (-INTVAL (operands[2]));
7719 return "sub{b}\t{%2, %0|%0, %2}";
7721 return "add{b}\t{%2, %0|%0, %2}";
7725 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7726 (const_string "incdec")
7727 (const_string "alu")))
7728 (set_attr "mode" "QI")])
7730 (define_insn "*addqi_3"
7731 [(set (reg FLAGS_REG)
7732 (compare (neg:QI (match_operand:QI 2 "general_operand" "qmn"))
7733 (match_operand:QI 1 "nonimmediate_operand" "%0")))
7734 (clobber (match_scratch:QI 0 "=q"))]
7735 "ix86_match_ccmode (insn, CCZmode)
7736 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7738 switch (get_attr_type (insn))
7741 if (operands[2] == const1_rtx)
7742 return "inc{b}\t%0";
7745 gcc_assert (operands[2] == constm1_rtx
7746 || (CONST_INT_P (operands[2])
7747 && INTVAL (operands[2]) == 255));
7748 return "dec{b}\t%0";
7752 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7753 if (CONST_INT_P (operands[2])
7754 && INTVAL (operands[2]) < 0)
7756 operands[2] = GEN_INT (-INTVAL (operands[2]));
7757 return "sub{b}\t{%2, %0|%0, %2}";
7759 return "add{b}\t{%2, %0|%0, %2}";
7763 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7764 (const_string "incdec")
7765 (const_string "alu")))
7766 (set_attr "mode" "QI")])
7768 ; See comments above addsi_4 for details.
7769 (define_insn "*addqi_4"
7770 [(set (reg FLAGS_REG)
7771 (compare (match_operand:QI 1 "nonimmediate_operand" "0")
7772 (match_operand:QI 2 "const_int_operand" "n")))
7773 (clobber (match_scratch:QI 0 "=qm"))]
7774 "ix86_match_ccmode (insn, CCGCmode)
7775 && (INTVAL (operands[2]) & 0xff) != 0x80"
7777 switch (get_attr_type (insn))
7780 if (operands[2] == constm1_rtx
7781 || (CONST_INT_P (operands[2])
7782 && INTVAL (operands[2]) == 255))
7783 return "inc{b}\t%0";
7786 gcc_assert (operands[2] == const1_rtx);
7787 return "dec{b}\t%0";
7791 gcc_assert (rtx_equal_p (operands[0], operands[1]));
7792 if (INTVAL (operands[2]) < 0)
7794 operands[2] = GEN_INT (-INTVAL (operands[2]));
7795 return "add{b}\t{%2, %0|%0, %2}";
7797 return "sub{b}\t{%2, %0|%0, %2}";
7801 (if_then_else (match_operand:HI 2 "incdec_operand" "")
7802 (const_string "incdec")
7803 (const_string "alu")))
7804 (set_attr "mode" "QI")])
7807 (define_insn "*addqi_5"
7808 [(set (reg FLAGS_REG)
7810 (plus:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
7811 (match_operand:QI 2 "general_operand" "qmn"))
7813 (clobber (match_scratch:QI 0 "=q"))]
7814 "ix86_match_ccmode (insn, CCGOCmode)
7815 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
7817 switch (get_attr_type (insn))
7820 if (operands[2] == const1_rtx)
7821 return "inc{b}\t%0";
7824 gcc_assert (operands[2] == constm1_rtx
7825 || (CONST_INT_P (operands[2])
7826 && INTVAL (operands[2]) == 255));
7827 return "dec{b}\t%0";
7831 /* Make things pretty and `subb $4,%al' rather than `addb $-4, %al'. */
7832 if (CONST_INT_P (operands[2])
7833 && INTVAL (operands[2]) < 0)
7835 operands[2] = GEN_INT (-INTVAL (operands[2]));
7836 return "sub{b}\t{%2, %0|%0, %2}";
7838 return "add{b}\t{%2, %0|%0, %2}";
7842 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7843 (const_string "incdec")
7844 (const_string "alu")))
7845 (set_attr "mode" "QI")])
7848 (define_insn "addqi_ext_1"
7849 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7854 (match_operand 1 "ext_register_operand" "0")
7857 (match_operand:QI 2 "general_operand" "Qmn")))
7858 (clobber (reg:CC FLAGS_REG))]
7861 switch (get_attr_type (insn))
7864 if (operands[2] == const1_rtx)
7865 return "inc{b}\t%h0";
7868 gcc_assert (operands[2] == constm1_rtx
7869 || (CONST_INT_P (operands[2])
7870 && INTVAL (operands[2]) == 255));
7871 return "dec{b}\t%h0";
7875 return "add{b}\t{%2, %h0|%h0, %2}";
7879 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7880 (const_string "incdec")
7881 (const_string "alu")))
7882 (set_attr "modrm" "1")
7883 (set_attr "mode" "QI")])
7885 (define_insn "*addqi_ext_1_rex64"
7886 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7891 (match_operand 1 "ext_register_operand" "0")
7894 (match_operand:QI 2 "nonmemory_operand" "Qn")))
7895 (clobber (reg:CC FLAGS_REG))]
7898 switch (get_attr_type (insn))
7901 if (operands[2] == const1_rtx)
7902 return "inc{b}\t%h0";
7905 gcc_assert (operands[2] == constm1_rtx
7906 || (CONST_INT_P (operands[2])
7907 && INTVAL (operands[2]) == 255));
7908 return "dec{b}\t%h0";
7912 return "add{b}\t{%2, %h0|%h0, %2}";
7916 (if_then_else (match_operand:QI 2 "incdec_operand" "")
7917 (const_string "incdec")
7918 (const_string "alu")))
7919 (set_attr "modrm" "1")
7920 (set_attr "mode" "QI")])
7922 (define_insn "*addqi_ext_2"
7923 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
7928 (match_operand 1 "ext_register_operand" "%0")
7932 (match_operand 2 "ext_register_operand" "Q")
7935 (clobber (reg:CC FLAGS_REG))]
7937 "add{b}\t{%h2, %h0|%h0, %h2}"
7938 [(set_attr "type" "alu")
7939 (set_attr "mode" "QI")])
7941 ;; The patterns that match these are at the end of this file.
7943 (define_expand "addxf3"
7944 [(set (match_operand:XF 0 "register_operand" "")
7945 (plus:XF (match_operand:XF 1 "register_operand" "")
7946 (match_operand:XF 2 "register_operand" "")))]
7950 (define_expand "add<mode>3"
7951 [(set (match_operand:MODEF 0 "register_operand" "")
7952 (plus:MODEF (match_operand:MODEF 1 "register_operand" "")
7953 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
7954 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
7955 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
7958 ;; Subtract instructions
7960 ;; %%% splits for subditi3
7962 (define_expand "subti3"
7963 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7964 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7965 (match_operand:TI 2 "x86_64_general_operand" "")))]
7967 "ix86_expand_binary_operator (MINUS, TImode, operands); DONE;")
7969 (define_insn "*subti3_1"
7970 [(set (match_operand:TI 0 "nonimmediate_operand" "=r,o")
7971 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "0,0")
7972 (match_operand:TI 2 "x86_64_general_operand" "roe,re")))
7973 (clobber (reg:CC FLAGS_REG))]
7974 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, TImode, operands)"
7978 [(set (match_operand:TI 0 "nonimmediate_operand" "")
7979 (minus:TI (match_operand:TI 1 "nonimmediate_operand" "")
7980 (match_operand:TI 2 "x86_64_general_operand" "")))
7981 (clobber (reg:CC FLAGS_REG))]
7982 "TARGET_64BIT && reload_completed"
7983 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
7984 (set (match_dup 0) (minus:DI (match_dup 1) (match_dup 2)))])
7985 (parallel [(set (match_dup 3)
7986 (minus:DI (match_dup 4)
7987 (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
7989 (clobber (reg:CC FLAGS_REG))])]
7990 "split_ti (&operands[0], 3, &operands[0], &operands[3]);")
7992 ;; %%% splits for subsidi3
7994 (define_expand "subdi3"
7995 [(set (match_operand:DI 0 "nonimmediate_operand" "")
7996 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
7997 (match_operand:DI 2 "x86_64_general_operand" "")))]
7999 "ix86_expand_binary_operator (MINUS, DImode, operands); DONE;")
8001 (define_insn "*subdi3_1"
8002 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,o")
8003 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8004 (match_operand:DI 2 "general_operand" "roiF,riF")))
8005 (clobber (reg:CC FLAGS_REG))]
8006 "!TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8010 [(set (match_operand:DI 0 "nonimmediate_operand" "")
8011 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "")
8012 (match_operand:DI 2 "general_operand" "")))
8013 (clobber (reg:CC FLAGS_REG))]
8014 "!TARGET_64BIT && reload_completed"
8015 [(parallel [(set (reg:CC FLAGS_REG) (compare:CC (match_dup 1) (match_dup 2)))
8016 (set (match_dup 0) (minus:SI (match_dup 1) (match_dup 2)))])
8017 (parallel [(set (match_dup 3)
8018 (minus:SI (match_dup 4)
8019 (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
8021 (clobber (reg:CC FLAGS_REG))])]
8022 "split_di (&operands[0], 3, &operands[0], &operands[3]);")
8024 (define_insn "subdi3_carry_rex64"
8025 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8026 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8027 (plus:DI (match_operand:DI 3 "ix86_carry_flag_operator" "")
8028 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))))
8029 (clobber (reg:CC FLAGS_REG))]
8030 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8031 "sbb{q}\t{%2, %0|%0, %2}"
8032 [(set_attr "type" "alu")
8033 (set_attr "use_carry" "1")
8034 (set_attr "pent_pair" "pu")
8035 (set_attr "mode" "DI")])
8037 (define_insn "*subdi_1_rex64"
8038 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8039 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8040 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8041 (clobber (reg:CC FLAGS_REG))]
8042 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, DImode, operands)"
8043 "sub{q}\t{%2, %0|%0, %2}"
8044 [(set_attr "type" "alu")
8045 (set_attr "mode" "DI")])
8047 (define_insn "*subdi_2_rex64"
8048 [(set (reg FLAGS_REG)
8050 (minus:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
8051 (match_operand:DI 2 "x86_64_general_operand" "re,rm"))
8053 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8054 (minus:DI (match_dup 1) (match_dup 2)))]
8055 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8056 && ix86_binary_operator_ok (MINUS, DImode, operands)"
8057 "sub{q}\t{%2, %0|%0, %2}"
8058 [(set_attr "type" "alu")
8059 (set_attr "mode" "DI")])
8061 (define_insn "*subdi_3_rex63"
8062 [(set (reg FLAGS_REG)
8063 (compare (match_operand:DI 1 "nonimmediate_operand" "0,0")
8064 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
8065 (set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
8066 (minus:DI (match_dup 1) (match_dup 2)))]
8067 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8068 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8069 "sub{q}\t{%2, %0|%0, %2}"
8070 [(set_attr "type" "alu")
8071 (set_attr "mode" "DI")])
8073 (define_insn "subqi3_carry"
8074 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8075 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8076 (plus:QI (match_operand:QI 3 "ix86_carry_flag_operator" "")
8077 (match_operand:QI 2 "general_operand" "qn,qm"))))
8078 (clobber (reg:CC FLAGS_REG))]
8079 "ix86_binary_operator_ok (MINUS, QImode, operands)"
8080 "sbb{b}\t{%2, %0|%0, %2}"
8081 [(set_attr "type" "alu")
8082 (set_attr "use_carry" "1")
8083 (set_attr "pent_pair" "pu")
8084 (set_attr "mode" "QI")])
8086 (define_insn "subhi3_carry"
8087 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8088 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8089 (plus:HI (match_operand:HI 3 "ix86_carry_flag_operator" "")
8090 (match_operand:HI 2 "general_operand" "rn,rm"))))
8091 (clobber (reg:CC FLAGS_REG))]
8092 "ix86_binary_operator_ok (MINUS, HImode, operands)"
8093 "sbb{w}\t{%2, %0|%0, %2}"
8094 [(set_attr "type" "alu")
8095 (set_attr "use_carry" "1")
8096 (set_attr "pent_pair" "pu")
8097 (set_attr "mode" "HI")])
8099 (define_insn "subsi3_carry"
8100 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8101 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8102 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
8103 (match_operand:SI 2 "general_operand" "ri,rm"))))
8104 (clobber (reg:CC FLAGS_REG))]
8105 "ix86_binary_operator_ok (MINUS, SImode, operands)"
8106 "sbb{l}\t{%2, %0|%0, %2}"
8107 [(set_attr "type" "alu")
8108 (set_attr "use_carry" "1")
8109 (set_attr "pent_pair" "pu")
8110 (set_attr "mode" "SI")])
8112 (define_insn "subsi3_carry_zext"
8113 [(set (match_operand:DI 0 "register_operand" "=r")
8115 (minus:SI (match_operand:SI 1 "register_operand" "0")
8116 (plus:SI (match_operand:SI 3 "ix86_carry_flag_operator" "")
8117 (match_operand:SI 2 "general_operand" "g")))))
8118 (clobber (reg:CC FLAGS_REG))]
8119 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8120 "sbb{l}\t{%2, %k0|%k0, %2}"
8121 [(set_attr "type" "alu")
8122 (set_attr "pent_pair" "pu")
8123 (set_attr "mode" "SI")])
8125 (define_expand "subsi3"
8126 [(set (match_operand:SI 0 "nonimmediate_operand" "")
8127 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "")
8128 (match_operand:SI 2 "general_operand" "")))]
8130 "ix86_expand_binary_operator (MINUS, SImode, operands); DONE;")
8132 (define_insn "*subsi_1"
8133 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8134 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8135 (match_operand:SI 2 "general_operand" "ri,rm")))
8136 (clobber (reg:CC FLAGS_REG))]
8137 "ix86_binary_operator_ok (MINUS, SImode, operands)"
8138 "sub{l}\t{%2, %0|%0, %2}"
8139 [(set_attr "type" "alu")
8140 (set_attr "mode" "SI")])
8142 (define_insn "*subsi_1_zext"
8143 [(set (match_operand:DI 0 "register_operand" "=r")
8145 (minus:SI (match_operand:SI 1 "register_operand" "0")
8146 (match_operand:SI 2 "general_operand" "g"))))
8147 (clobber (reg:CC FLAGS_REG))]
8148 "TARGET_64BIT && ix86_binary_operator_ok (MINUS, SImode, operands)"
8149 "sub{l}\t{%2, %k0|%k0, %2}"
8150 [(set_attr "type" "alu")
8151 (set_attr "mode" "SI")])
8153 (define_insn "*subsi_2"
8154 [(set (reg FLAGS_REG)
8156 (minus:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
8157 (match_operand:SI 2 "general_operand" "ri,rm"))
8159 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8160 (minus:SI (match_dup 1) (match_dup 2)))]
8161 "ix86_match_ccmode (insn, CCGOCmode)
8162 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8163 "sub{l}\t{%2, %0|%0, %2}"
8164 [(set_attr "type" "alu")
8165 (set_attr "mode" "SI")])
8167 (define_insn "*subsi_2_zext"
8168 [(set (reg FLAGS_REG)
8170 (minus:SI (match_operand:SI 1 "register_operand" "0")
8171 (match_operand:SI 2 "general_operand" "g"))
8173 (set (match_operand:DI 0 "register_operand" "=r")
8175 (minus:SI (match_dup 1)
8177 "TARGET_64BIT && ix86_match_ccmode (insn, CCGOCmode)
8178 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8179 "sub{l}\t{%2, %k0|%k0, %2}"
8180 [(set_attr "type" "alu")
8181 (set_attr "mode" "SI")])
8183 (define_insn "*subsi_3"
8184 [(set (reg FLAGS_REG)
8185 (compare (match_operand:SI 1 "nonimmediate_operand" "0,0")
8186 (match_operand:SI 2 "general_operand" "ri,rm")))
8187 (set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
8188 (minus:SI (match_dup 1) (match_dup 2)))]
8189 "ix86_match_ccmode (insn, CCmode)
8190 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8191 "sub{l}\t{%2, %0|%0, %2}"
8192 [(set_attr "type" "alu")
8193 (set_attr "mode" "SI")])
8195 (define_insn "*subsi_3_zext"
8196 [(set (reg FLAGS_REG)
8197 (compare (match_operand:SI 1 "register_operand" "0")
8198 (match_operand:SI 2 "general_operand" "g")))
8199 (set (match_operand:DI 0 "register_operand" "=r")
8201 (minus:SI (match_dup 1)
8203 "TARGET_64BIT && ix86_match_ccmode (insn, CCmode)
8204 && ix86_binary_operator_ok (MINUS, SImode, operands)"
8205 "sub{l}\t{%2, %1|%1, %2}"
8206 [(set_attr "type" "alu")
8207 (set_attr "mode" "DI")])
8209 (define_expand "subhi3"
8210 [(set (match_operand:HI 0 "nonimmediate_operand" "")
8211 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "")
8212 (match_operand:HI 2 "general_operand" "")))]
8213 "TARGET_HIMODE_MATH"
8214 "ix86_expand_binary_operator (MINUS, HImode, operands); DONE;")
8216 (define_insn "*subhi_1"
8217 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8218 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8219 (match_operand:HI 2 "general_operand" "rn,rm")))
8220 (clobber (reg:CC FLAGS_REG))]
8221 "ix86_binary_operator_ok (MINUS, HImode, operands)"
8222 "sub{w}\t{%2, %0|%0, %2}"
8223 [(set_attr "type" "alu")
8224 (set_attr "mode" "HI")])
8226 (define_insn "*subhi_2"
8227 [(set (reg FLAGS_REG)
8229 (minus:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
8230 (match_operand:HI 2 "general_operand" "rn,rm"))
8232 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8233 (minus:HI (match_dup 1) (match_dup 2)))]
8234 "ix86_match_ccmode (insn, CCGOCmode)
8235 && ix86_binary_operator_ok (MINUS, HImode, operands)"
8236 "sub{w}\t{%2, %0|%0, %2}"
8237 [(set_attr "type" "alu")
8238 (set_attr "mode" "HI")])
8240 (define_insn "*subhi_3"
8241 [(set (reg FLAGS_REG)
8242 (compare (match_operand:HI 1 "nonimmediate_operand" "0,0")
8243 (match_operand:HI 2 "general_operand" "rn,rm")))
8244 (set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
8245 (minus:HI (match_dup 1) (match_dup 2)))]
8246 "ix86_match_ccmode (insn, CCmode)
8247 && ix86_binary_operator_ok (MINUS, HImode, operands)"
8248 "sub{w}\t{%2, %0|%0, %2}"
8249 [(set_attr "type" "alu")
8250 (set_attr "mode" "HI")])
8252 (define_expand "subqi3"
8253 [(set (match_operand:QI 0 "nonimmediate_operand" "")
8254 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "")
8255 (match_operand:QI 2 "general_operand" "")))]
8256 "TARGET_QIMODE_MATH"
8257 "ix86_expand_binary_operator (MINUS, QImode, operands); DONE;")
8259 (define_insn "*subqi_1"
8260 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8261 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8262 (match_operand:QI 2 "general_operand" "qn,qm")))
8263 (clobber (reg:CC FLAGS_REG))]
8264 "ix86_binary_operator_ok (MINUS, QImode, operands)"
8265 "sub{b}\t{%2, %0|%0, %2}"
8266 [(set_attr "type" "alu")
8267 (set_attr "mode" "QI")])
8269 (define_insn "*subqi_1_slp"
8270 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
8271 (minus:QI (match_dup 0)
8272 (match_operand:QI 1 "general_operand" "qn,qm")))
8273 (clobber (reg:CC FLAGS_REG))]
8274 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
8275 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
8276 "sub{b}\t{%1, %0|%0, %1}"
8277 [(set_attr "type" "alu1")
8278 (set_attr "mode" "QI")])
8280 (define_insn "*subqi_2"
8281 [(set (reg FLAGS_REG)
8283 (minus:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
8284 (match_operand:QI 2 "general_operand" "qn,qm"))
8286 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8287 (minus:QI (match_dup 1) (match_dup 2)))]
8288 "ix86_match_ccmode (insn, CCGOCmode)
8289 && ix86_binary_operator_ok (MINUS, QImode, operands)"
8290 "sub{b}\t{%2, %0|%0, %2}"
8291 [(set_attr "type" "alu")
8292 (set_attr "mode" "QI")])
8294 (define_insn "*subqi_3"
8295 [(set (reg FLAGS_REG)
8296 (compare (match_operand:QI 1 "nonimmediate_operand" "0,0")
8297 (match_operand:QI 2 "general_operand" "qn,qm")))
8298 (set (match_operand:QI 0 "nonimmediate_operand" "=qm,q")
8299 (minus:QI (match_dup 1) (match_dup 2)))]
8300 "ix86_match_ccmode (insn, CCmode)
8301 && ix86_binary_operator_ok (MINUS, QImode, operands)"
8302 "sub{b}\t{%2, %0|%0, %2}"
8303 [(set_attr "type" "alu")
8304 (set_attr "mode" "QI")])
8306 ;; The patterns that match these are at the end of this file.
8308 (define_expand "subxf3"
8309 [(set (match_operand:XF 0 "register_operand" "")
8310 (minus:XF (match_operand:XF 1 "register_operand" "")
8311 (match_operand:XF 2 "register_operand" "")))]
8315 (define_expand "sub<mode>3"
8316 [(set (match_operand:MODEF 0 "register_operand" "")
8317 (minus:MODEF (match_operand:MODEF 1 "register_operand" "")
8318 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8319 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8320 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8323 ;; Multiply instructions
8325 (define_expand "muldi3"
8326 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8327 (mult:DI (match_operand:DI 1 "register_operand" "")
8328 (match_operand:DI 2 "x86_64_general_operand" "")))
8329 (clobber (reg:CC FLAGS_REG))])]
8334 ;; IMUL reg64, reg64, imm8 Direct
8335 ;; IMUL reg64, mem64, imm8 VectorPath
8336 ;; IMUL reg64, reg64, imm32 Direct
8337 ;; IMUL reg64, mem64, imm32 VectorPath
8338 ;; IMUL reg64, reg64 Direct
8339 ;; IMUL reg64, mem64 Direct
8341 (define_insn "*muldi3_1_rex64"
8342 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8343 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "%rm,rm,0")
8344 (match_operand:DI 2 "x86_64_general_operand" "K,e,mr")))
8345 (clobber (reg:CC FLAGS_REG))]
8347 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8349 imul{q}\t{%2, %1, %0|%0, %1, %2}
8350 imul{q}\t{%2, %1, %0|%0, %1, %2}
8351 imul{q}\t{%2, %0|%0, %2}"
8352 [(set_attr "type" "imul")
8353 (set_attr "prefix_0f" "0,0,1")
8354 (set (attr "athlon_decode")
8355 (cond [(eq_attr "cpu" "athlon")
8356 (const_string "vector")
8357 (eq_attr "alternative" "1")
8358 (const_string "vector")
8359 (and (eq_attr "alternative" "2")
8360 (match_operand 1 "memory_operand" ""))
8361 (const_string "vector")]
8362 (const_string "direct")))
8363 (set (attr "amdfam10_decode")
8364 (cond [(and (eq_attr "alternative" "0,1")
8365 (match_operand 1 "memory_operand" ""))
8366 (const_string "vector")]
8367 (const_string "direct")))
8368 (set_attr "mode" "DI")])
8370 (define_expand "mulsi3"
8371 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8372 (mult:SI (match_operand:SI 1 "register_operand" "")
8373 (match_operand:SI 2 "general_operand" "")))
8374 (clobber (reg:CC FLAGS_REG))])]
8379 ;; IMUL reg32, reg32, imm8 Direct
8380 ;; IMUL reg32, mem32, imm8 VectorPath
8381 ;; IMUL reg32, reg32, imm32 Direct
8382 ;; IMUL reg32, mem32, imm32 VectorPath
8383 ;; IMUL reg32, reg32 Direct
8384 ;; IMUL reg32, mem32 Direct
8386 (define_insn "*mulsi3_1"
8387 [(set (match_operand:SI 0 "register_operand" "=r,r,r")
8388 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8389 (match_operand:SI 2 "general_operand" "K,i,mr")))
8390 (clobber (reg:CC FLAGS_REG))]
8391 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8393 imul{l}\t{%2, %1, %0|%0, %1, %2}
8394 imul{l}\t{%2, %1, %0|%0, %1, %2}
8395 imul{l}\t{%2, %0|%0, %2}"
8396 [(set_attr "type" "imul")
8397 (set_attr "prefix_0f" "0,0,1")
8398 (set (attr "athlon_decode")
8399 (cond [(eq_attr "cpu" "athlon")
8400 (const_string "vector")
8401 (eq_attr "alternative" "1")
8402 (const_string "vector")
8403 (and (eq_attr "alternative" "2")
8404 (match_operand 1 "memory_operand" ""))
8405 (const_string "vector")]
8406 (const_string "direct")))
8407 (set (attr "amdfam10_decode")
8408 (cond [(and (eq_attr "alternative" "0,1")
8409 (match_operand 1 "memory_operand" ""))
8410 (const_string "vector")]
8411 (const_string "direct")))
8412 (set_attr "mode" "SI")])
8414 (define_insn "*mulsi3_1_zext"
8415 [(set (match_operand:DI 0 "register_operand" "=r,r,r")
8417 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "%rm,rm,0")
8418 (match_operand:SI 2 "general_operand" "K,i,mr"))))
8419 (clobber (reg:CC FLAGS_REG))]
8421 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8423 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8424 imul{l}\t{%2, %1, %k0|%k0, %1, %2}
8425 imul{l}\t{%2, %k0|%k0, %2}"
8426 [(set_attr "type" "imul")
8427 (set_attr "prefix_0f" "0,0,1")
8428 (set (attr "athlon_decode")
8429 (cond [(eq_attr "cpu" "athlon")
8430 (const_string "vector")
8431 (eq_attr "alternative" "1")
8432 (const_string "vector")
8433 (and (eq_attr "alternative" "2")
8434 (match_operand 1 "memory_operand" ""))
8435 (const_string "vector")]
8436 (const_string "direct")))
8437 (set (attr "amdfam10_decode")
8438 (cond [(and (eq_attr "alternative" "0,1")
8439 (match_operand 1 "memory_operand" ""))
8440 (const_string "vector")]
8441 (const_string "direct")))
8442 (set_attr "mode" "SI")])
8444 (define_expand "mulhi3"
8445 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8446 (mult:HI (match_operand:HI 1 "register_operand" "")
8447 (match_operand:HI 2 "general_operand" "")))
8448 (clobber (reg:CC FLAGS_REG))])]
8449 "TARGET_HIMODE_MATH"
8453 ;; IMUL reg16, reg16, imm8 VectorPath
8454 ;; IMUL reg16, mem16, imm8 VectorPath
8455 ;; IMUL reg16, reg16, imm16 VectorPath
8456 ;; IMUL reg16, mem16, imm16 VectorPath
8457 ;; IMUL reg16, reg16 Direct
8458 ;; IMUL reg16, mem16 Direct
8459 (define_insn "*mulhi3_1"
8460 [(set (match_operand:HI 0 "register_operand" "=r,r,r")
8461 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "%rm,rm,0")
8462 (match_operand:HI 2 "general_operand" "K,n,mr")))
8463 (clobber (reg:CC FLAGS_REG))]
8464 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8466 imul{w}\t{%2, %1, %0|%0, %1, %2}
8467 imul{w}\t{%2, %1, %0|%0, %1, %2}
8468 imul{w}\t{%2, %0|%0, %2}"
8469 [(set_attr "type" "imul")
8470 (set_attr "prefix_0f" "0,0,1")
8471 (set (attr "athlon_decode")
8472 (cond [(eq_attr "cpu" "athlon")
8473 (const_string "vector")
8474 (eq_attr "alternative" "1,2")
8475 (const_string "vector")]
8476 (const_string "direct")))
8477 (set (attr "amdfam10_decode")
8478 (cond [(eq_attr "alternative" "0,1")
8479 (const_string "vector")]
8480 (const_string "direct")))
8481 (set_attr "mode" "HI")])
8483 (define_expand "mulqi3"
8484 [(parallel [(set (match_operand:QI 0 "register_operand" "")
8485 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "")
8486 (match_operand:QI 2 "register_operand" "")))
8487 (clobber (reg:CC FLAGS_REG))])]
8488 "TARGET_QIMODE_MATH"
8495 (define_insn "*mulqi3_1"
8496 [(set (match_operand:QI 0 "register_operand" "=a")
8497 (mult:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
8498 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8499 (clobber (reg:CC FLAGS_REG))]
8501 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8503 [(set_attr "type" "imul")
8504 (set_attr "length_immediate" "0")
8505 (set (attr "athlon_decode")
8506 (if_then_else (eq_attr "cpu" "athlon")
8507 (const_string "vector")
8508 (const_string "direct")))
8509 (set_attr "amdfam10_decode" "direct")
8510 (set_attr "mode" "QI")])
8512 (define_expand "umulqihi3"
8513 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8514 (mult:HI (zero_extend:HI
8515 (match_operand:QI 1 "nonimmediate_operand" ""))
8517 (match_operand:QI 2 "register_operand" ""))))
8518 (clobber (reg:CC FLAGS_REG))])]
8519 "TARGET_QIMODE_MATH"
8522 (define_insn "*umulqihi3_1"
8523 [(set (match_operand:HI 0 "register_operand" "=a")
8524 (mult:HI (zero_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8525 (zero_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8526 (clobber (reg:CC FLAGS_REG))]
8528 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8530 [(set_attr "type" "imul")
8531 (set_attr "length_immediate" "0")
8532 (set (attr "athlon_decode")
8533 (if_then_else (eq_attr "cpu" "athlon")
8534 (const_string "vector")
8535 (const_string "direct")))
8536 (set_attr "amdfam10_decode" "direct")
8537 (set_attr "mode" "QI")])
8539 (define_expand "mulqihi3"
8540 [(parallel [(set (match_operand:HI 0 "register_operand" "")
8541 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" ""))
8542 (sign_extend:HI (match_operand:QI 2 "register_operand" ""))))
8543 (clobber (reg:CC FLAGS_REG))])]
8544 "TARGET_QIMODE_MATH"
8547 (define_insn "*mulqihi3_insn"
8548 [(set (match_operand:HI 0 "register_operand" "=a")
8549 (mult:HI (sign_extend:HI (match_operand:QI 1 "nonimmediate_operand" "%0"))
8550 (sign_extend:HI (match_operand:QI 2 "nonimmediate_operand" "qm"))))
8551 (clobber (reg:CC FLAGS_REG))]
8553 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8555 [(set_attr "type" "imul")
8556 (set_attr "length_immediate" "0")
8557 (set (attr "athlon_decode")
8558 (if_then_else (eq_attr "cpu" "athlon")
8559 (const_string "vector")
8560 (const_string "direct")))
8561 (set_attr "amdfam10_decode" "direct")
8562 (set_attr "mode" "QI")])
8564 (define_expand "umulditi3"
8565 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8566 (mult:TI (zero_extend:TI
8567 (match_operand:DI 1 "nonimmediate_operand" ""))
8569 (match_operand:DI 2 "register_operand" ""))))
8570 (clobber (reg:CC FLAGS_REG))])]
8574 (define_insn "*umulditi3_insn"
8575 [(set (match_operand:TI 0 "register_operand" "=A")
8576 (mult:TI (zero_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8577 (zero_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8578 (clobber (reg:CC FLAGS_REG))]
8580 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8582 [(set_attr "type" "imul")
8583 (set_attr "length_immediate" "0")
8584 (set (attr "athlon_decode")
8585 (if_then_else (eq_attr "cpu" "athlon")
8586 (const_string "vector")
8587 (const_string "double")))
8588 (set_attr "amdfam10_decode" "double")
8589 (set_attr "mode" "DI")])
8591 ;; We can't use this pattern in 64bit mode, since it results in two separate 32bit registers
8592 (define_expand "umulsidi3"
8593 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8594 (mult:DI (zero_extend:DI
8595 (match_operand:SI 1 "nonimmediate_operand" ""))
8597 (match_operand:SI 2 "register_operand" ""))))
8598 (clobber (reg:CC FLAGS_REG))])]
8602 (define_insn "*umulsidi3_insn"
8603 [(set (match_operand:DI 0 "register_operand" "=A")
8604 (mult:DI (zero_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8605 (zero_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8606 (clobber (reg:CC FLAGS_REG))]
8608 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8610 [(set_attr "type" "imul")
8611 (set_attr "length_immediate" "0")
8612 (set (attr "athlon_decode")
8613 (if_then_else (eq_attr "cpu" "athlon")
8614 (const_string "vector")
8615 (const_string "double")))
8616 (set_attr "amdfam10_decode" "double")
8617 (set_attr "mode" "SI")])
8619 (define_expand "mulditi3"
8620 [(parallel [(set (match_operand:TI 0 "register_operand" "")
8621 (mult:TI (sign_extend:TI
8622 (match_operand:DI 1 "nonimmediate_operand" ""))
8624 (match_operand:DI 2 "register_operand" ""))))
8625 (clobber (reg:CC FLAGS_REG))])]
8629 (define_insn "*mulditi3_insn"
8630 [(set (match_operand:TI 0 "register_operand" "=A")
8631 (mult:TI (sign_extend:TI (match_operand:DI 1 "nonimmediate_operand" "%0"))
8632 (sign_extend:TI (match_operand:DI 2 "nonimmediate_operand" "rm"))))
8633 (clobber (reg:CC FLAGS_REG))]
8635 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8637 [(set_attr "type" "imul")
8638 (set_attr "length_immediate" "0")
8639 (set (attr "athlon_decode")
8640 (if_then_else (eq_attr "cpu" "athlon")
8641 (const_string "vector")
8642 (const_string "double")))
8643 (set_attr "amdfam10_decode" "double")
8644 (set_attr "mode" "DI")])
8646 (define_expand "mulsidi3"
8647 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8648 (mult:DI (sign_extend:DI
8649 (match_operand:SI 1 "nonimmediate_operand" ""))
8651 (match_operand:SI 2 "register_operand" ""))))
8652 (clobber (reg:CC FLAGS_REG))])]
8656 (define_insn "*mulsidi3_insn"
8657 [(set (match_operand:DI 0 "register_operand" "=A")
8658 (mult:DI (sign_extend:DI (match_operand:SI 1 "nonimmediate_operand" "%0"))
8659 (sign_extend:DI (match_operand:SI 2 "nonimmediate_operand" "rm"))))
8660 (clobber (reg:CC FLAGS_REG))]
8662 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8664 [(set_attr "type" "imul")
8665 (set_attr "length_immediate" "0")
8666 (set (attr "athlon_decode")
8667 (if_then_else (eq_attr "cpu" "athlon")
8668 (const_string "vector")
8669 (const_string "double")))
8670 (set_attr "amdfam10_decode" "double")
8671 (set_attr "mode" "SI")])
8673 (define_expand "umuldi3_highpart"
8674 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8677 (mult:TI (zero_extend:TI
8678 (match_operand:DI 1 "nonimmediate_operand" ""))
8680 (match_operand:DI 2 "register_operand" "")))
8682 (clobber (match_scratch:DI 3 ""))
8683 (clobber (reg:CC FLAGS_REG))])]
8687 (define_insn "*umuldi3_highpart_rex64"
8688 [(set (match_operand:DI 0 "register_operand" "=d")
8691 (mult:TI (zero_extend:TI
8692 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8694 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8696 (clobber (match_scratch:DI 3 "=1"))
8697 (clobber (reg:CC FLAGS_REG))]
8699 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8701 [(set_attr "type" "imul")
8702 (set_attr "length_immediate" "0")
8703 (set (attr "athlon_decode")
8704 (if_then_else (eq_attr "cpu" "athlon")
8705 (const_string "vector")
8706 (const_string "double")))
8707 (set_attr "amdfam10_decode" "double")
8708 (set_attr "mode" "DI")])
8710 (define_expand "umulsi3_highpart"
8711 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8714 (mult:DI (zero_extend:DI
8715 (match_operand:SI 1 "nonimmediate_operand" ""))
8717 (match_operand:SI 2 "register_operand" "")))
8719 (clobber (match_scratch:SI 3 ""))
8720 (clobber (reg:CC FLAGS_REG))])]
8724 (define_insn "*umulsi3_highpart_insn"
8725 [(set (match_operand:SI 0 "register_operand" "=d")
8728 (mult:DI (zero_extend:DI
8729 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8731 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8733 (clobber (match_scratch:SI 3 "=1"))
8734 (clobber (reg:CC FLAGS_REG))]
8735 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8737 [(set_attr "type" "imul")
8738 (set_attr "length_immediate" "0")
8739 (set (attr "athlon_decode")
8740 (if_then_else (eq_attr "cpu" "athlon")
8741 (const_string "vector")
8742 (const_string "double")))
8743 (set_attr "amdfam10_decode" "double")
8744 (set_attr "mode" "SI")])
8746 (define_insn "*umulsi3_highpart_zext"
8747 [(set (match_operand:DI 0 "register_operand" "=d")
8748 (zero_extend:DI (truncate:SI
8750 (mult:DI (zero_extend:DI
8751 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8753 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8755 (clobber (match_scratch:SI 3 "=1"))
8756 (clobber (reg:CC FLAGS_REG))]
8758 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8760 [(set_attr "type" "imul")
8761 (set_attr "length_immediate" "0")
8762 (set (attr "athlon_decode")
8763 (if_then_else (eq_attr "cpu" "athlon")
8764 (const_string "vector")
8765 (const_string "double")))
8766 (set_attr "amdfam10_decode" "double")
8767 (set_attr "mode" "SI")])
8769 (define_expand "smuldi3_highpart"
8770 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8773 (mult:TI (sign_extend:TI
8774 (match_operand:DI 1 "nonimmediate_operand" ""))
8776 (match_operand:DI 2 "register_operand" "")))
8778 (clobber (match_scratch:DI 3 ""))
8779 (clobber (reg:CC FLAGS_REG))])]
8783 (define_insn "*smuldi3_highpart_rex64"
8784 [(set (match_operand:DI 0 "register_operand" "=d")
8787 (mult:TI (sign_extend:TI
8788 (match_operand:DI 1 "nonimmediate_operand" "%a"))
8790 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8792 (clobber (match_scratch:DI 3 "=1"))
8793 (clobber (reg:CC FLAGS_REG))]
8795 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8797 [(set_attr "type" "imul")
8798 (set (attr "athlon_decode")
8799 (if_then_else (eq_attr "cpu" "athlon")
8800 (const_string "vector")
8801 (const_string "double")))
8802 (set_attr "amdfam10_decode" "double")
8803 (set_attr "mode" "DI")])
8805 (define_expand "smulsi3_highpart"
8806 [(parallel [(set (match_operand:SI 0 "register_operand" "")
8809 (mult:DI (sign_extend:DI
8810 (match_operand:SI 1 "nonimmediate_operand" ""))
8812 (match_operand:SI 2 "register_operand" "")))
8814 (clobber (match_scratch:SI 3 ""))
8815 (clobber (reg:CC FLAGS_REG))])]
8819 (define_insn "*smulsi3_highpart_insn"
8820 [(set (match_operand:SI 0 "register_operand" "=d")
8823 (mult:DI (sign_extend:DI
8824 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8826 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8828 (clobber (match_scratch:SI 3 "=1"))
8829 (clobber (reg:CC FLAGS_REG))]
8830 "!(MEM_P (operands[1]) && MEM_P (operands[2]))"
8832 [(set_attr "type" "imul")
8833 (set (attr "athlon_decode")
8834 (if_then_else (eq_attr "cpu" "athlon")
8835 (const_string "vector")
8836 (const_string "double")))
8837 (set_attr "amdfam10_decode" "double")
8838 (set_attr "mode" "SI")])
8840 (define_insn "*smulsi3_highpart_zext"
8841 [(set (match_operand:DI 0 "register_operand" "=d")
8842 (zero_extend:DI (truncate:SI
8844 (mult:DI (sign_extend:DI
8845 (match_operand:SI 1 "nonimmediate_operand" "%a"))
8847 (match_operand:SI 2 "nonimmediate_operand" "rm")))
8849 (clobber (match_scratch:SI 3 "=1"))
8850 (clobber (reg:CC FLAGS_REG))]
8852 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
8854 [(set_attr "type" "imul")
8855 (set (attr "athlon_decode")
8856 (if_then_else (eq_attr "cpu" "athlon")
8857 (const_string "vector")
8858 (const_string "double")))
8859 (set_attr "amdfam10_decode" "double")
8860 (set_attr "mode" "SI")])
8862 ;; The patterns that match these are at the end of this file.
8864 (define_expand "mulxf3"
8865 [(set (match_operand:XF 0 "register_operand" "")
8866 (mult:XF (match_operand:XF 1 "register_operand" "")
8867 (match_operand:XF 2 "register_operand" "")))]
8871 (define_expand "mul<mode>3"
8872 [(set (match_operand:MODEF 0 "register_operand" "")
8873 (mult:MODEF (match_operand:MODEF 1 "register_operand" "")
8874 (match_operand:MODEF 2 "nonimmediate_operand" "")))]
8875 "(TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode))
8876 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
8879 ;; SSE5 scalar multiply/add instructions are defined in sse.md.
8882 ;; Divide instructions
8884 (define_insn "divqi3"
8885 [(set (match_operand:QI 0 "register_operand" "=a")
8886 (div:QI (match_operand:HI 1 "register_operand" "0")
8887 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8888 (clobber (reg:CC FLAGS_REG))]
8889 "TARGET_QIMODE_MATH"
8891 [(set_attr "type" "idiv")
8892 (set_attr "mode" "QI")])
8894 (define_insn "udivqi3"
8895 [(set (match_operand:QI 0 "register_operand" "=a")
8896 (udiv:QI (match_operand:HI 1 "register_operand" "0")
8897 (match_operand:QI 2 "nonimmediate_operand" "qm")))
8898 (clobber (reg:CC FLAGS_REG))]
8899 "TARGET_QIMODE_MATH"
8901 [(set_attr "type" "idiv")
8902 (set_attr "mode" "QI")])
8904 ;; The patterns that match these are at the end of this file.
8906 (define_expand "divxf3"
8907 [(set (match_operand:XF 0 "register_operand" "")
8908 (div:XF (match_operand:XF 1 "register_operand" "")
8909 (match_operand:XF 2 "register_operand" "")))]
8913 (define_expand "divdf3"
8914 [(set (match_operand:DF 0 "register_operand" "")
8915 (div:DF (match_operand:DF 1 "register_operand" "")
8916 (match_operand:DF 2 "nonimmediate_operand" "")))]
8917 "(TARGET_80387 && X87_ENABLE_ARITH (DFmode))
8918 || (TARGET_SSE2 && TARGET_SSE_MATH)"
8921 (define_expand "divsf3"
8922 [(set (match_operand:SF 0 "register_operand" "")
8923 (div:SF (match_operand:SF 1 "register_operand" "")
8924 (match_operand:SF 2 "nonimmediate_operand" "")))]
8925 "(TARGET_80387 && X87_ENABLE_ARITH (SFmode))
8928 if (TARGET_SSE_MATH && TARGET_RECIP && optimize_insn_for_speed_p ()
8929 && flag_finite_math_only && !flag_trapping_math
8930 && flag_unsafe_math_optimizations)
8932 ix86_emit_swdivsf (operands[0], operands[1],
8933 operands[2], SFmode);
8938 ;; Remainder instructions.
8940 (define_expand "divmoddi4"
8941 [(parallel [(set (match_operand:DI 0 "register_operand" "")
8942 (div:DI (match_operand:DI 1 "register_operand" "")
8943 (match_operand:DI 2 "nonimmediate_operand" "")))
8944 (set (match_operand:DI 3 "register_operand" "")
8945 (mod:DI (match_dup 1) (match_dup 2)))
8946 (clobber (reg:CC FLAGS_REG))])]
8950 ;; Allow to come the parameter in eax or edx to avoid extra moves.
8951 ;; Penalize eax case slightly because it results in worse scheduling
8953 (define_insn "*divmoddi4_nocltd_rex64"
8954 [(set (match_operand:DI 0 "register_operand" "=&a,?a")
8955 (div:DI (match_operand:DI 2 "register_operand" "1,0")
8956 (match_operand:DI 3 "nonimmediate_operand" "rm,rm")))
8957 (set (match_operand:DI 1 "register_operand" "=&d,&d")
8958 (mod:DI (match_dup 2) (match_dup 3)))
8959 (clobber (reg:CC FLAGS_REG))]
8960 "TARGET_64BIT && optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
8962 [(set_attr "type" "multi")])
8964 (define_insn "*divmoddi4_cltd_rex64"
8965 [(set (match_operand:DI 0 "register_operand" "=a")
8966 (div:DI (match_operand:DI 2 "register_operand" "a")
8967 (match_operand:DI 3 "nonimmediate_operand" "rm")))
8968 (set (match_operand:DI 1 "register_operand" "=&d")
8969 (mod:DI (match_dup 2) (match_dup 3)))
8970 (clobber (reg:CC FLAGS_REG))]
8971 "TARGET_64BIT && (optimize_function_for_size_p (cfun) || TARGET_USE_CLTD)"
8973 [(set_attr "type" "multi")])
8975 (define_insn "*divmoddi_noext_rex64"
8976 [(set (match_operand:DI 0 "register_operand" "=a")
8977 (div:DI (match_operand:DI 1 "register_operand" "0")
8978 (match_operand:DI 2 "nonimmediate_operand" "rm")))
8979 (set (match_operand:DI 3 "register_operand" "=d")
8980 (mod:DI (match_dup 1) (match_dup 2)))
8981 (use (match_operand:DI 4 "register_operand" "3"))
8982 (clobber (reg:CC FLAGS_REG))]
8985 [(set_attr "type" "idiv")
8986 (set_attr "mode" "DI")])
8989 [(set (match_operand:DI 0 "register_operand" "")
8990 (div:DI (match_operand:DI 1 "register_operand" "")
8991 (match_operand:DI 2 "nonimmediate_operand" "")))
8992 (set (match_operand:DI 3 "register_operand" "")
8993 (mod:DI (match_dup 1) (match_dup 2)))
8994 (clobber (reg:CC FLAGS_REG))]
8995 "TARGET_64BIT && reload_completed"
8996 [(parallel [(set (match_dup 3)
8997 (ashiftrt:DI (match_dup 4) (const_int 63)))
8998 (clobber (reg:CC FLAGS_REG))])
8999 (parallel [(set (match_dup 0)
9000 (div:DI (reg:DI 0) (match_dup 2)))
9002 (mod:DI (reg:DI 0) (match_dup 2)))
9004 (clobber (reg:CC FLAGS_REG))])]
9006 /* Avoid use of cltd in favor of a mov+shift. */
9007 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9009 if (true_regnum (operands[1]))
9010 emit_move_insn (operands[0], operands[1]);
9012 emit_move_insn (operands[3], operands[1]);
9013 operands[4] = operands[3];
9017 gcc_assert (!true_regnum (operands[1]));
9018 operands[4] = operands[1];
9023 (define_expand "divmodsi4"
9024 [(parallel [(set (match_operand:SI 0 "register_operand" "")
9025 (div:SI (match_operand:SI 1 "register_operand" "")
9026 (match_operand:SI 2 "nonimmediate_operand" "")))
9027 (set (match_operand:SI 3 "register_operand" "")
9028 (mod:SI (match_dup 1) (match_dup 2)))
9029 (clobber (reg:CC FLAGS_REG))])]
9033 ;; Allow to come the parameter in eax or edx to avoid extra moves.
9034 ;; Penalize eax case slightly because it results in worse scheduling
9036 (define_insn "*divmodsi4_nocltd"
9037 [(set (match_operand:SI 0 "register_operand" "=&a,?a")
9038 (div:SI (match_operand:SI 2 "register_operand" "1,0")
9039 (match_operand:SI 3 "nonimmediate_operand" "rm,rm")))
9040 (set (match_operand:SI 1 "register_operand" "=&d,&d")
9041 (mod:SI (match_dup 2) (match_dup 3)))
9042 (clobber (reg:CC FLAGS_REG))]
9043 "optimize_function_for_speed_p (cfun) && !TARGET_USE_CLTD"
9045 [(set_attr "type" "multi")])
9047 (define_insn "*divmodsi4_cltd"
9048 [(set (match_operand:SI 0 "register_operand" "=a")
9049 (div:SI (match_operand:SI 2 "register_operand" "a")
9050 (match_operand:SI 3 "nonimmediate_operand" "rm")))
9051 (set (match_operand:SI 1 "register_operand" "=&d")
9052 (mod:SI (match_dup 2) (match_dup 3)))
9053 (clobber (reg:CC FLAGS_REG))]
9054 "optimize_function_for_size_p (cfun) || TARGET_USE_CLTD"
9056 [(set_attr "type" "multi")])
9058 (define_insn "*divmodsi_noext"
9059 [(set (match_operand:SI 0 "register_operand" "=a")
9060 (div:SI (match_operand:SI 1 "register_operand" "0")
9061 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9062 (set (match_operand:SI 3 "register_operand" "=d")
9063 (mod:SI (match_dup 1) (match_dup 2)))
9064 (use (match_operand:SI 4 "register_operand" "3"))
9065 (clobber (reg:CC FLAGS_REG))]
9068 [(set_attr "type" "idiv")
9069 (set_attr "mode" "SI")])
9072 [(set (match_operand:SI 0 "register_operand" "")
9073 (div:SI (match_operand:SI 1 "register_operand" "")
9074 (match_operand:SI 2 "nonimmediate_operand" "")))
9075 (set (match_operand:SI 3 "register_operand" "")
9076 (mod:SI (match_dup 1) (match_dup 2)))
9077 (clobber (reg:CC FLAGS_REG))]
9079 [(parallel [(set (match_dup 3)
9080 (ashiftrt:SI (match_dup 4) (const_int 31)))
9081 (clobber (reg:CC FLAGS_REG))])
9082 (parallel [(set (match_dup 0)
9083 (div:SI (reg:SI 0) (match_dup 2)))
9085 (mod:SI (reg:SI 0) (match_dup 2)))
9087 (clobber (reg:CC FLAGS_REG))])]
9089 /* Avoid use of cltd in favor of a mov+shift. */
9090 if (!TARGET_USE_CLTD && optimize_function_for_speed_p (cfun))
9092 if (true_regnum (operands[1]))
9093 emit_move_insn (operands[0], operands[1]);
9095 emit_move_insn (operands[3], operands[1]);
9096 operands[4] = operands[3];
9100 gcc_assert (!true_regnum (operands[1]));
9101 operands[4] = operands[1];
9105 (define_insn "divmodhi4"
9106 [(set (match_operand:HI 0 "register_operand" "=a")
9107 (div:HI (match_operand:HI 1 "register_operand" "0")
9108 (match_operand:HI 2 "nonimmediate_operand" "rm")))
9109 (set (match_operand:HI 3 "register_operand" "=&d")
9110 (mod:HI (match_dup 1) (match_dup 2)))
9111 (clobber (reg:CC FLAGS_REG))]
9112 "TARGET_HIMODE_MATH"
9114 [(set_attr "type" "multi")
9115 (set_attr "length_immediate" "0")
9116 (set_attr "mode" "SI")])
9118 (define_insn "udivmoddi4"
9119 [(set (match_operand:DI 0 "register_operand" "=a")
9120 (udiv:DI (match_operand:DI 1 "register_operand" "0")
9121 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9122 (set (match_operand:DI 3 "register_operand" "=&d")
9123 (umod:DI (match_dup 1) (match_dup 2)))
9124 (clobber (reg:CC FLAGS_REG))]
9126 "xor{q}\t%3, %3\;div{q}\t%2"
9127 [(set_attr "type" "multi")
9128 (set_attr "length_immediate" "0")
9129 (set_attr "mode" "DI")])
9131 (define_insn "*udivmoddi4_noext"
9132 [(set (match_operand:DI 0 "register_operand" "=a")
9133 (udiv:DI (match_operand:DI 1 "register_operand" "0")
9134 (match_operand:DI 2 "nonimmediate_operand" "rm")))
9135 (set (match_operand:DI 3 "register_operand" "=d")
9136 (umod:DI (match_dup 1) (match_dup 2)))
9138 (clobber (reg:CC FLAGS_REG))]
9141 [(set_attr "type" "idiv")
9142 (set_attr "mode" "DI")])
9145 [(set (match_operand:DI 0 "register_operand" "")
9146 (udiv:DI (match_operand:DI 1 "register_operand" "")
9147 (match_operand:DI 2 "nonimmediate_operand" "")))
9148 (set (match_operand:DI 3 "register_operand" "")
9149 (umod:DI (match_dup 1) (match_dup 2)))
9150 (clobber (reg:CC FLAGS_REG))]
9151 "TARGET_64BIT && reload_completed"
9152 [(set (match_dup 3) (const_int 0))
9153 (parallel [(set (match_dup 0)
9154 (udiv:DI (match_dup 1) (match_dup 2)))
9156 (umod:DI (match_dup 1) (match_dup 2)))
9158 (clobber (reg:CC FLAGS_REG))])]
9161 (define_insn "udivmodsi4"
9162 [(set (match_operand:SI 0 "register_operand" "=a")
9163 (udiv:SI (match_operand:SI 1 "register_operand" "0")
9164 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9165 (set (match_operand:SI 3 "register_operand" "=&d")
9166 (umod:SI (match_dup 1) (match_dup 2)))
9167 (clobber (reg:CC FLAGS_REG))]
9169 "xor{l}\t%3, %3\;div{l}\t%2"
9170 [(set_attr "type" "multi")
9171 (set_attr "length_immediate" "0")
9172 (set_attr "mode" "SI")])
9174 (define_insn "*udivmodsi4_noext"
9175 [(set (match_operand:SI 0 "register_operand" "=a")
9176 (udiv:SI (match_operand:SI 1 "register_operand" "0")
9177 (match_operand:SI 2 "nonimmediate_operand" "rm")))
9178 (set (match_operand:SI 3 "register_operand" "=d")
9179 (umod:SI (match_dup 1) (match_dup 2)))
9181 (clobber (reg:CC FLAGS_REG))]
9184 [(set_attr "type" "idiv")
9185 (set_attr "mode" "SI")])
9188 [(set (match_operand:SI 0 "register_operand" "")
9189 (udiv:SI (match_operand:SI 1 "register_operand" "")
9190 (match_operand:SI 2 "nonimmediate_operand" "")))
9191 (set (match_operand:SI 3 "register_operand" "")
9192 (umod:SI (match_dup 1) (match_dup 2)))
9193 (clobber (reg:CC FLAGS_REG))]
9195 [(set (match_dup 3) (const_int 0))
9196 (parallel [(set (match_dup 0)
9197 (udiv:SI (match_dup 1) (match_dup 2)))
9199 (umod:SI (match_dup 1) (match_dup 2)))
9201 (clobber (reg:CC FLAGS_REG))])]
9204 (define_expand "udivmodhi4"
9205 [(set (match_dup 4) (const_int 0))
9206 (parallel [(set (match_operand:HI 0 "register_operand" "")
9207 (udiv:HI (match_operand:HI 1 "register_operand" "")
9208 (match_operand:HI 2 "nonimmediate_operand" "")))
9209 (set (match_operand:HI 3 "register_operand" "")
9210 (umod:HI (match_dup 1) (match_dup 2)))
9212 (clobber (reg:CC FLAGS_REG))])]
9213 "TARGET_HIMODE_MATH"
9214 "operands[4] = gen_reg_rtx (HImode);")
9216 (define_insn "*udivmodhi_noext"
9217 [(set (match_operand:HI 0 "register_operand" "=a")
9218 (udiv:HI (match_operand:HI 1 "register_operand" "0")
9219 (match_operand:HI 2 "nonimmediate_operand" "rm")))
9220 (set (match_operand:HI 3 "register_operand" "=d")
9221 (umod:HI (match_dup 1) (match_dup 2)))
9222 (use (match_operand:HI 4 "register_operand" "3"))
9223 (clobber (reg:CC FLAGS_REG))]
9226 [(set_attr "type" "idiv")
9227 (set_attr "mode" "HI")])
9229 ;; We cannot use div/idiv for double division, because it causes
9230 ;; "division by zero" on the overflow and that's not what we expect
9231 ;; from truncate. Because true (non truncating) double division is
9232 ;; never generated, we can't create this insn anyway.
9235 ; [(set (match_operand:SI 0 "register_operand" "=a")
9237 ; (udiv:DI (match_operand:DI 1 "register_operand" "A")
9239 ; (match_operand:SI 2 "nonimmediate_operand" "rm")))))
9240 ; (set (match_operand:SI 3 "register_operand" "=d")
9242 ; (umod:DI (match_dup 1) (zero_extend:DI (match_dup 2)))))
9243 ; (clobber (reg:CC FLAGS_REG))]
9245 ; "div{l}\t{%2, %0|%0, %2}"
9246 ; [(set_attr "type" "idiv")])
9248 ;;- Logical AND instructions
9250 ;; On Pentium, "test imm, reg" is pairable only with eax, ax, and al.
9251 ;; Note that this excludes ah.
9253 (define_insn "*testdi_1_rex64"
9254 [(set (reg FLAGS_REG)
9256 (and:DI (match_operand:DI 0 "nonimmediate_operand" "%!*a,r,!*a,r,rm")
9257 (match_operand:DI 1 "x86_64_szext_general_operand" "Z,Z,e,e,re"))
9259 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9260 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9262 test{l}\t{%k1, %k0|%k0, %k1}
9263 test{l}\t{%k1, %k0|%k0, %k1}
9264 test{q}\t{%1, %0|%0, %1}
9265 test{q}\t{%1, %0|%0, %1}
9266 test{q}\t{%1, %0|%0, %1}"
9267 [(set_attr "type" "test")
9268 (set_attr "modrm" "0,1,0,1,1")
9269 (set_attr "mode" "SI,SI,DI,DI,DI")
9270 (set_attr "pent_pair" "uv,np,uv,np,uv")])
9272 (define_insn "testsi_1"
9273 [(set (reg FLAGS_REG)
9275 (and:SI (match_operand:SI 0 "nonimmediate_operand" "%!*a,r,rm")
9276 (match_operand:SI 1 "general_operand" "i,i,ri"))
9278 "ix86_match_ccmode (insn, CCNOmode)
9279 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9280 "test{l}\t{%1, %0|%0, %1}"
9281 [(set_attr "type" "test")
9282 (set_attr "modrm" "0,1,1")
9283 (set_attr "mode" "SI")
9284 (set_attr "pent_pair" "uv,np,uv")])
9286 (define_expand "testsi_ccno_1"
9287 [(set (reg:CCNO FLAGS_REG)
9289 (and:SI (match_operand:SI 0 "nonimmediate_operand" "")
9290 (match_operand:SI 1 "nonmemory_operand" ""))
9295 (define_insn "*testhi_1"
9296 [(set (reg FLAGS_REG)
9297 (compare (and:HI (match_operand:HI 0 "nonimmediate_operand" "%!*a,r,rm")
9298 (match_operand:HI 1 "general_operand" "n,n,rn"))
9300 "ix86_match_ccmode (insn, CCNOmode)
9301 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9302 "test{w}\t{%1, %0|%0, %1}"
9303 [(set_attr "type" "test")
9304 (set_attr "modrm" "0,1,1")
9305 (set_attr "mode" "HI")
9306 (set_attr "pent_pair" "uv,np,uv")])
9308 (define_expand "testqi_ccz_1"
9309 [(set (reg:CCZ FLAGS_REG)
9310 (compare:CCZ (and:QI (match_operand:QI 0 "nonimmediate_operand" "")
9311 (match_operand:QI 1 "nonmemory_operand" ""))
9316 (define_insn "*testqi_1_maybe_si"
9317 [(set (reg FLAGS_REG)
9320 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm,r")
9321 (match_operand:QI 1 "general_operand" "n,n,qn,n"))
9323 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9324 && ix86_match_ccmode (insn,
9325 CONST_INT_P (operands[1])
9326 && INTVAL (operands[1]) >= 0 ? CCNOmode : CCZmode)"
9328 if (which_alternative == 3)
9330 if (CONST_INT_P (operands[1]) && INTVAL (operands[1]) < 0)
9331 operands[1] = GEN_INT (INTVAL (operands[1]) & 0xff);
9332 return "test{l}\t{%1, %k0|%k0, %1}";
9334 return "test{b}\t{%1, %0|%0, %1}";
9336 [(set_attr "type" "test")
9337 (set_attr "modrm" "0,1,1,1")
9338 (set_attr "mode" "QI,QI,QI,SI")
9339 (set_attr "pent_pair" "uv,np,uv,np")])
9341 (define_insn "*testqi_1"
9342 [(set (reg FLAGS_REG)
9345 (match_operand:QI 0 "nonimmediate_operand" "%!*a,q,qm")
9346 (match_operand:QI 1 "general_operand" "n,n,qn"))
9348 "!(MEM_P (operands[0]) && MEM_P (operands[1]))
9349 && ix86_match_ccmode (insn, CCNOmode)"
9350 "test{b}\t{%1, %0|%0, %1}"
9351 [(set_attr "type" "test")
9352 (set_attr "modrm" "0,1,1")
9353 (set_attr "mode" "QI")
9354 (set_attr "pent_pair" "uv,np,uv")])
9356 (define_expand "testqi_ext_ccno_0"
9357 [(set (reg:CCNO FLAGS_REG)
9361 (match_operand 0 "ext_register_operand" "")
9364 (match_operand 1 "const_int_operand" ""))
9369 (define_insn "*testqi_ext_0"
9370 [(set (reg FLAGS_REG)
9374 (match_operand 0 "ext_register_operand" "Q")
9377 (match_operand 1 "const_int_operand" "n"))
9379 "ix86_match_ccmode (insn, CCNOmode)"
9380 "test{b}\t{%1, %h0|%h0, %1}"
9381 [(set_attr "type" "test")
9382 (set_attr "mode" "QI")
9383 (set_attr "length_immediate" "1")
9384 (set_attr "modrm" "1")
9385 (set_attr "pent_pair" "np")])
9387 (define_insn "*testqi_ext_1"
9388 [(set (reg FLAGS_REG)
9392 (match_operand 0 "ext_register_operand" "Q")
9396 (match_operand:QI 1 "general_operand" "Qm")))
9398 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9399 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9400 "test{b}\t{%1, %h0|%h0, %1}"
9401 [(set_attr "type" "test")
9402 (set_attr "mode" "QI")])
9404 (define_insn "*testqi_ext_1_rex64"
9405 [(set (reg FLAGS_REG)
9409 (match_operand 0 "ext_register_operand" "Q")
9413 (match_operand:QI 1 "register_operand" "Q")))
9415 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
9416 "test{b}\t{%1, %h0|%h0, %1}"
9417 [(set_attr "type" "test")
9418 (set_attr "mode" "QI")])
9420 (define_insn "*testqi_ext_2"
9421 [(set (reg FLAGS_REG)
9425 (match_operand 0 "ext_register_operand" "Q")
9429 (match_operand 1 "ext_register_operand" "Q")
9433 "ix86_match_ccmode (insn, CCNOmode)"
9434 "test{b}\t{%h1, %h0|%h0, %h1}"
9435 [(set_attr "type" "test")
9436 (set_attr "mode" "QI")])
9438 ;; Combine likes to form bit extractions for some tests. Humor it.
9439 (define_insn "*testqi_ext_3"
9440 [(set (reg FLAGS_REG)
9441 (compare (zero_extract:SI
9442 (match_operand 0 "nonimmediate_operand" "rm")
9443 (match_operand:SI 1 "const_int_operand" "")
9444 (match_operand:SI 2 "const_int_operand" ""))
9446 "ix86_match_ccmode (insn, CCNOmode)
9447 && INTVAL (operands[1]) > 0
9448 && INTVAL (operands[2]) >= 0
9449 && INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9450 && (GET_MODE (operands[0]) == SImode
9451 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode)
9452 || GET_MODE (operands[0]) == HImode
9453 || GET_MODE (operands[0]) == QImode)"
9456 (define_insn "*testqi_ext_3_rex64"
9457 [(set (reg FLAGS_REG)
9458 (compare (zero_extract:DI
9459 (match_operand 0 "nonimmediate_operand" "rm")
9460 (match_operand:DI 1 "const_int_operand" "")
9461 (match_operand:DI 2 "const_int_operand" ""))
9464 && ix86_match_ccmode (insn, CCNOmode)
9465 && INTVAL (operands[1]) > 0
9466 && INTVAL (operands[2]) >= 0
9467 /* Ensure that resulting mask is zero or sign extended operand. */
9468 && (INTVAL (operands[1]) + INTVAL (operands[2]) <= 32
9469 || (INTVAL (operands[1]) + INTVAL (operands[2]) == 64
9470 && INTVAL (operands[1]) > 32))
9471 && (GET_MODE (operands[0]) == SImode
9472 || GET_MODE (operands[0]) == DImode
9473 || GET_MODE (operands[0]) == HImode
9474 || GET_MODE (operands[0]) == QImode)"
9478 [(set (match_operand 0 "flags_reg_operand" "")
9479 (match_operator 1 "compare_operator"
9481 (match_operand 2 "nonimmediate_operand" "")
9482 (match_operand 3 "const_int_operand" "")
9483 (match_operand 4 "const_int_operand" ""))
9485 "ix86_match_ccmode (insn, CCNOmode)"
9486 [(set (match_dup 0) (match_op_dup 1 [(match_dup 2) (const_int 0)]))]
9488 rtx val = operands[2];
9489 HOST_WIDE_INT len = INTVAL (operands[3]);
9490 HOST_WIDE_INT pos = INTVAL (operands[4]);
9492 enum machine_mode mode, submode;
9494 mode = GET_MODE (val);
9497 /* ??? Combine likes to put non-volatile mem extractions in QImode
9498 no matter the size of the test. So find a mode that works. */
9499 if (! MEM_VOLATILE_P (val))
9501 mode = smallest_mode_for_size (pos + len, MODE_INT);
9502 val = adjust_address (val, mode, 0);
9505 else if (GET_CODE (val) == SUBREG
9506 && (submode = GET_MODE (SUBREG_REG (val)),
9507 GET_MODE_BITSIZE (mode) > GET_MODE_BITSIZE (submode))
9508 && pos + len <= GET_MODE_BITSIZE (submode))
9510 /* Narrow a paradoxical subreg to prevent partial register stalls. */
9512 val = SUBREG_REG (val);
9514 else if (mode == HImode && pos + len <= 8)
9516 /* Small HImode tests can be converted to QImode. */
9518 val = gen_lowpart (QImode, val);
9521 if (len == HOST_BITS_PER_WIDE_INT)
9524 mask = ((HOST_WIDE_INT)1 << len) - 1;
9527 operands[2] = gen_rtx_AND (mode, val, gen_int_mode (mask, mode));
9530 ;; Convert HImode/SImode test instructions with immediate to QImode ones.
9531 ;; i386 does not allow to encode test with 8bit sign extended immediate, so
9532 ;; this is relatively important trick.
9533 ;; Do the conversion only post-reload to avoid limiting of the register class
9536 [(set (match_operand 0 "flags_reg_operand" "")
9537 (match_operator 1 "compare_operator"
9538 [(and (match_operand 2 "register_operand" "")
9539 (match_operand 3 "const_int_operand" ""))
9542 && QI_REG_P (operands[2])
9543 && GET_MODE (operands[2]) != QImode
9544 && ((ix86_match_ccmode (insn, CCZmode)
9545 && !(INTVAL (operands[3]) & ~(255 << 8)))
9546 || (ix86_match_ccmode (insn, CCNOmode)
9547 && !(INTVAL (operands[3]) & ~(127 << 8))))"
9550 [(and:SI (zero_extract:SI (match_dup 2) (const_int 8) (const_int 8))
9553 "operands[2] = gen_lowpart (SImode, operands[2]);
9554 operands[3] = gen_int_mode (INTVAL (operands[3]) >> 8, SImode);")
9557 [(set (match_operand 0 "flags_reg_operand" "")
9558 (match_operator 1 "compare_operator"
9559 [(and (match_operand 2 "nonimmediate_operand" "")
9560 (match_operand 3 "const_int_operand" ""))
9563 && GET_MODE (operands[2]) != QImode
9564 && (!REG_P (operands[2]) || ANY_QI_REG_P (operands[2]))
9565 && ((ix86_match_ccmode (insn, CCZmode)
9566 && !(INTVAL (operands[3]) & ~255))
9567 || (ix86_match_ccmode (insn, CCNOmode)
9568 && !(INTVAL (operands[3]) & ~127)))"
9570 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
9572 "operands[2] = gen_lowpart (QImode, operands[2]);
9573 operands[3] = gen_lowpart (QImode, operands[3]);")
9576 ;; %%% This used to optimize known byte-wide and operations to memory,
9577 ;; and sometimes to QImode registers. If this is considered useful,
9578 ;; it should be done with splitters.
9580 (define_expand "anddi3"
9581 [(set (match_operand:DI 0 "nonimmediate_operand" "")
9582 (and:DI (match_operand:DI 1 "nonimmediate_operand" "")
9583 (match_operand:DI 2 "x86_64_szext_general_operand" "")))]
9585 "ix86_expand_binary_operator (AND, DImode, operands); DONE;")
9587 (define_insn "*anddi_1_rex64"
9588 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,rm,r,r")
9589 (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0,qm")
9590 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,re,rm,L")))
9591 (clobber (reg:CC FLAGS_REG))]
9592 "TARGET_64BIT && ix86_binary_operator_ok (AND, DImode, operands)"
9594 switch (get_attr_type (insn))
9598 enum machine_mode mode;
9600 gcc_assert (CONST_INT_P (operands[2]));
9601 if (INTVAL (operands[2]) == 0xff)
9605 gcc_assert (INTVAL (operands[2]) == 0xffff);
9609 operands[1] = gen_lowpart (mode, operands[1]);
9611 return "movz{bl|x}\t{%1, %k0|%k0, %1}";
9613 return "movz{wl|x}\t{%1, %k0|%k0, %1}";
9617 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9618 if (get_attr_mode (insn) == MODE_SI)
9619 return "and{l}\t{%k2, %k0|%k0, %k2}";
9621 return "and{q}\t{%2, %0|%0, %2}";
9624 [(set_attr "type" "alu,alu,alu,imovx")
9625 (set_attr "length_immediate" "*,*,*,0")
9626 (set (attr "prefix_rex")
9628 (and (eq_attr "type" "imovx")
9629 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9630 (match_operand 1 "ext_QIreg_nomode_operand" "")))
9632 (const_string "*")))
9633 (set_attr "mode" "SI,DI,DI,SI")])
9635 (define_insn "*anddi_2"
9636 [(set (reg FLAGS_REG)
9637 (compare (and:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0,0")
9638 (match_operand:DI 2 "x86_64_szext_general_operand" "Z,rem,re"))
9640 (set (match_operand:DI 0 "nonimmediate_operand" "=r,r,rm")
9641 (and:DI (match_dup 1) (match_dup 2)))]
9642 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9643 && ix86_binary_operator_ok (AND, DImode, operands)"
9645 and{l}\t{%k2, %k0|%k0, %k2}
9646 and{q}\t{%2, %0|%0, %2}
9647 and{q}\t{%2, %0|%0, %2}"
9648 [(set_attr "type" "alu")
9649 (set_attr "mode" "SI,DI,DI")])
9651 (define_expand "andsi3"
9652 [(set (match_operand:SI 0 "nonimmediate_operand" "")
9653 (and:SI (match_operand:SI 1 "nonimmediate_operand" "")
9654 (match_operand:SI 2 "general_operand" "")))]
9656 "ix86_expand_binary_operator (AND, SImode, operands); DONE;")
9658 (define_insn "*andsi_1"
9659 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r,r")
9660 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0,qm")
9661 (match_operand:SI 2 "general_operand" "ri,rm,L")))
9662 (clobber (reg:CC FLAGS_REG))]
9663 "ix86_binary_operator_ok (AND, SImode, operands)"
9665 switch (get_attr_type (insn))
9669 enum machine_mode mode;
9671 gcc_assert (CONST_INT_P (operands[2]));
9672 if (INTVAL (operands[2]) == 0xff)
9676 gcc_assert (INTVAL (operands[2]) == 0xffff);
9680 operands[1] = gen_lowpart (mode, operands[1]);
9682 return "movz{bl|x}\t{%1, %0|%0, %1}";
9684 return "movz{wl|x}\t{%1, %0|%0, %1}";
9688 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9689 return "and{l}\t{%2, %0|%0, %2}";
9692 [(set_attr "type" "alu,alu,imovx")
9693 (set (attr "prefix_rex")
9695 (and (eq_attr "type" "imovx")
9696 (and (ne (symbol_ref "INTVAL (operands[2]) == 0xff") (const_int 0))
9697 (match_operand 1 "ext_QIreg_nomode_operand" "")))
9699 (const_string "*")))
9700 (set_attr "length_immediate" "*,*,0")
9701 (set_attr "mode" "SI")])
9704 [(set (match_operand 0 "register_operand" "")
9706 (const_int -65536)))
9707 (clobber (reg:CC FLAGS_REG))]
9708 "optimize_function_for_size_p (cfun) || (TARGET_FAST_PREFIX && !TARGET_PARTIAL_REG_STALL)"
9709 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9710 "operands[1] = gen_lowpart (HImode, operands[0]);")
9713 [(set (match_operand 0 "ext_register_operand" "")
9716 (clobber (reg:CC FLAGS_REG))]
9717 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9718 [(set (strict_low_part (match_dup 1)) (const_int 0))]
9719 "operands[1] = gen_lowpart (QImode, operands[0]);")
9722 [(set (match_operand 0 "ext_register_operand" "")
9724 (const_int -65281)))
9725 (clobber (reg:CC FLAGS_REG))]
9726 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_REG_STALL) && reload_completed"
9727 [(parallel [(set (zero_extract:SI (match_dup 0)
9731 (zero_extract:SI (match_dup 0)
9734 (zero_extract:SI (match_dup 0)
9737 (clobber (reg:CC FLAGS_REG))])]
9738 "operands[0] = gen_lowpart (SImode, operands[0]);")
9740 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9741 (define_insn "*andsi_1_zext"
9742 [(set (match_operand:DI 0 "register_operand" "=r")
9744 (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9745 (match_operand:SI 2 "general_operand" "g"))))
9746 (clobber (reg:CC FLAGS_REG))]
9747 "TARGET_64BIT && ix86_binary_operator_ok (AND, SImode, operands)"
9748 "and{l}\t{%2, %k0|%k0, %2}"
9749 [(set_attr "type" "alu")
9750 (set_attr "mode" "SI")])
9752 (define_insn "*andsi_2"
9753 [(set (reg FLAGS_REG)
9754 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
9755 (match_operand:SI 2 "general_operand" "g,ri"))
9757 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
9758 (and:SI (match_dup 1) (match_dup 2)))]
9759 "ix86_match_ccmode (insn, CCNOmode)
9760 && ix86_binary_operator_ok (AND, SImode, operands)"
9761 "and{l}\t{%2, %0|%0, %2}"
9762 [(set_attr "type" "alu")
9763 (set_attr "mode" "SI")])
9765 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
9766 (define_insn "*andsi_2_zext"
9767 [(set (reg FLAGS_REG)
9768 (compare (and:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
9769 (match_operand:SI 2 "general_operand" "g"))
9771 (set (match_operand:DI 0 "register_operand" "=r")
9772 (zero_extend:DI (and:SI (match_dup 1) (match_dup 2))))]
9773 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
9774 && ix86_binary_operator_ok (AND, SImode, operands)"
9775 "and{l}\t{%2, %k0|%k0, %2}"
9776 [(set_attr "type" "alu")
9777 (set_attr "mode" "SI")])
9779 (define_expand "andhi3"
9780 [(set (match_operand:HI 0 "nonimmediate_operand" "")
9781 (and:HI (match_operand:HI 1 "nonimmediate_operand" "")
9782 (match_operand:HI 2 "general_operand" "")))]
9783 "TARGET_HIMODE_MATH"
9784 "ix86_expand_binary_operator (AND, HImode, operands); DONE;")
9786 (define_insn "*andhi_1"
9787 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r,r")
9788 (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0,qm")
9789 (match_operand:HI 2 "general_operand" "rn,rm,L")))
9790 (clobber (reg:CC FLAGS_REG))]
9791 "ix86_binary_operator_ok (AND, HImode, operands)"
9793 switch (get_attr_type (insn))
9796 gcc_assert (CONST_INT_P (operands[2]));
9797 gcc_assert (INTVAL (operands[2]) == 0xff);
9798 return "movz{bl|x}\t{%b1, %k0|%k0, %b1}";
9801 gcc_assert (rtx_equal_p (operands[0], operands[1]));
9803 return "and{w}\t{%2, %0|%0, %2}";
9806 [(set_attr "type" "alu,alu,imovx")
9807 (set_attr "length_immediate" "*,*,0")
9808 (set (attr "prefix_rex")
9810 (and (eq_attr "type" "imovx")
9811 (match_operand 1 "ext_QIreg_nomode_operand" ""))
9813 (const_string "*")))
9814 (set_attr "mode" "HI,HI,SI")])
9816 (define_insn "*andhi_2"
9817 [(set (reg FLAGS_REG)
9818 (compare (and:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
9819 (match_operand:HI 2 "general_operand" "rmn,rn"))
9821 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
9822 (and:HI (match_dup 1) (match_dup 2)))]
9823 "ix86_match_ccmode (insn, CCNOmode)
9824 && ix86_binary_operator_ok (AND, HImode, operands)"
9825 "and{w}\t{%2, %0|%0, %2}"
9826 [(set_attr "type" "alu")
9827 (set_attr "mode" "HI")])
9829 (define_expand "andqi3"
9830 [(set (match_operand:QI 0 "nonimmediate_operand" "")
9831 (and:QI (match_operand:QI 1 "nonimmediate_operand" "")
9832 (match_operand:QI 2 "general_operand" "")))]
9833 "TARGET_QIMODE_MATH"
9834 "ix86_expand_binary_operator (AND, QImode, operands); DONE;")
9836 ;; %%% Potential partial reg stall on alternative 2. What to do?
9837 (define_insn "*andqi_1"
9838 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,q,r")
9839 (and:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9840 (match_operand:QI 2 "general_operand" "qn,qmn,rn")))
9841 (clobber (reg:CC FLAGS_REG))]
9842 "ix86_binary_operator_ok (AND, QImode, operands)"
9844 and{b}\t{%2, %0|%0, %2}
9845 and{b}\t{%2, %0|%0, %2}
9846 and{l}\t{%k2, %k0|%k0, %k2}"
9847 [(set_attr "type" "alu")
9848 (set_attr "mode" "QI,QI,SI")])
9850 (define_insn "*andqi_1_slp"
9851 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
9852 (and:QI (match_dup 0)
9853 (match_operand:QI 1 "general_operand" "qn,qmn")))
9854 (clobber (reg:CC FLAGS_REG))]
9855 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9856 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9857 "and{b}\t{%1, %0|%0, %1}"
9858 [(set_attr "type" "alu1")
9859 (set_attr "mode" "QI")])
9861 (define_insn "*andqi_2_maybe_si"
9862 [(set (reg FLAGS_REG)
9864 (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
9865 (match_operand:QI 2 "general_operand" "qmn,qn,n"))
9867 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm,*r")
9868 (and:QI (match_dup 1) (match_dup 2)))]
9869 "ix86_binary_operator_ok (AND, QImode, operands)
9870 && ix86_match_ccmode (insn,
9871 CONST_INT_P (operands[2])
9872 && INTVAL (operands[2]) >= 0 ? CCNOmode : CCZmode)"
9874 if (which_alternative == 2)
9876 if (CONST_INT_P (operands[2]) && INTVAL (operands[2]) < 0)
9877 operands[2] = GEN_INT (INTVAL (operands[2]) & 0xff);
9878 return "and{l}\t{%2, %k0|%k0, %2}";
9880 return "and{b}\t{%2, %0|%0, %2}";
9882 [(set_attr "type" "alu")
9883 (set_attr "mode" "QI,QI,SI")])
9885 (define_insn "*andqi_2"
9886 [(set (reg FLAGS_REG)
9888 (match_operand:QI 1 "nonimmediate_operand" "%0,0")
9889 (match_operand:QI 2 "general_operand" "qmn,qn"))
9891 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
9892 (and:QI (match_dup 1) (match_dup 2)))]
9893 "ix86_match_ccmode (insn, CCNOmode)
9894 && ix86_binary_operator_ok (AND, QImode, operands)"
9895 "and{b}\t{%2, %0|%0, %2}"
9896 [(set_attr "type" "alu")
9897 (set_attr "mode" "QI")])
9899 (define_insn "*andqi_2_slp"
9900 [(set (reg FLAGS_REG)
9902 (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
9903 (match_operand:QI 1 "nonimmediate_operand" "qmn,qn"))
9905 (set (strict_low_part (match_dup 0))
9906 (and:QI (match_dup 0) (match_dup 1)))]
9907 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
9908 && ix86_match_ccmode (insn, CCNOmode)
9909 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
9910 "and{b}\t{%1, %0|%0, %1}"
9911 [(set_attr "type" "alu1")
9912 (set_attr "mode" "QI")])
9914 ;; ??? A bug in recog prevents it from recognizing a const_int as an
9915 ;; operand to zero_extend in andqi_ext_1. It was checking explicitly
9916 ;; for a QImode operand, which of course failed.
9918 (define_insn "andqi_ext_0"
9919 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9924 (match_operand 1 "ext_register_operand" "0")
9927 (match_operand 2 "const_int_operand" "n")))
9928 (clobber (reg:CC FLAGS_REG))]
9930 "and{b}\t{%2, %h0|%h0, %2}"
9931 [(set_attr "type" "alu")
9932 (set_attr "length_immediate" "1")
9933 (set_attr "modrm" "1")
9934 (set_attr "mode" "QI")])
9936 ;; Generated by peephole translating test to and. This shows up
9937 ;; often in fp comparisons.
9939 (define_insn "*andqi_ext_0_cc"
9940 [(set (reg FLAGS_REG)
9944 (match_operand 1 "ext_register_operand" "0")
9947 (match_operand 2 "const_int_operand" "n"))
9949 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9958 "ix86_match_ccmode (insn, CCNOmode)"
9959 "and{b}\t{%2, %h0|%h0, %2}"
9960 [(set_attr "type" "alu")
9961 (set_attr "length_immediate" "1")
9962 (set_attr "modrm" "1")
9963 (set_attr "mode" "QI")])
9965 (define_insn "*andqi_ext_1"
9966 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9971 (match_operand 1 "ext_register_operand" "0")
9975 (match_operand:QI 2 "general_operand" "Qm"))))
9976 (clobber (reg:CC FLAGS_REG))]
9978 "and{b}\t{%2, %h0|%h0, %2}"
9979 [(set_attr "type" "alu")
9980 (set_attr "length_immediate" "0")
9981 (set_attr "mode" "QI")])
9983 (define_insn "*andqi_ext_1_rex64"
9984 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
9989 (match_operand 1 "ext_register_operand" "0")
9993 (match_operand 2 "ext_register_operand" "Q"))))
9994 (clobber (reg:CC FLAGS_REG))]
9996 "and{b}\t{%2, %h0|%h0, %2}"
9997 [(set_attr "type" "alu")
9998 (set_attr "length_immediate" "0")
9999 (set_attr "mode" "QI")])
10001 (define_insn "*andqi_ext_2"
10002 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10007 (match_operand 1 "ext_register_operand" "%0")
10011 (match_operand 2 "ext_register_operand" "Q")
10014 (clobber (reg:CC FLAGS_REG))]
10016 "and{b}\t{%h2, %h0|%h0, %h2}"
10017 [(set_attr "type" "alu")
10018 (set_attr "length_immediate" "0")
10019 (set_attr "mode" "QI")])
10021 ;; Convert wide AND instructions with immediate operand to shorter QImode
10022 ;; equivalents when possible.
10023 ;; Don't do the splitting with memory operands, since it introduces risk
10024 ;; of memory mismatch stalls. We may want to do the splitting for optimizing
10025 ;; for size, but that can (should?) be handled by generic code instead.
10027 [(set (match_operand 0 "register_operand" "")
10028 (and (match_operand 1 "register_operand" "")
10029 (match_operand 2 "const_int_operand" "")))
10030 (clobber (reg:CC FLAGS_REG))]
10032 && QI_REG_P (operands[0])
10033 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10034 && !(~INTVAL (operands[2]) & ~(255 << 8))
10035 && GET_MODE (operands[0]) != QImode"
10036 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10037 (and:SI (zero_extract:SI (match_dup 1)
10038 (const_int 8) (const_int 8))
10040 (clobber (reg:CC FLAGS_REG))])]
10041 "operands[0] = gen_lowpart (SImode, operands[0]);
10042 operands[1] = gen_lowpart (SImode, operands[1]);
10043 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10045 ;; Since AND can be encoded with sign extended immediate, this is only
10046 ;; profitable when 7th bit is not set.
10048 [(set (match_operand 0 "register_operand" "")
10049 (and (match_operand 1 "general_operand" "")
10050 (match_operand 2 "const_int_operand" "")))
10051 (clobber (reg:CC FLAGS_REG))]
10053 && ANY_QI_REG_P (operands[0])
10054 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10055 && !(~INTVAL (operands[2]) & ~255)
10056 && !(INTVAL (operands[2]) & 128)
10057 && GET_MODE (operands[0]) != QImode"
10058 [(parallel [(set (strict_low_part (match_dup 0))
10059 (and:QI (match_dup 1)
10061 (clobber (reg:CC FLAGS_REG))])]
10062 "operands[0] = gen_lowpart (QImode, operands[0]);
10063 operands[1] = gen_lowpart (QImode, operands[1]);
10064 operands[2] = gen_lowpart (QImode, operands[2]);")
10066 ;; Logical inclusive OR instructions
10068 ;; %%% This used to optimize known byte-wide and operations to memory.
10069 ;; If this is considered useful, it should be done with splitters.
10071 (define_expand "iordi3"
10072 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10073 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "")
10074 (match_operand:DI 2 "x86_64_general_operand" "")))]
10076 "ix86_expand_binary_operator (IOR, DImode, operands); DONE;")
10078 (define_insn "*iordi_1_rex64"
10079 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10080 (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10081 (match_operand:DI 2 "x86_64_general_operand" "re,rme")))
10082 (clobber (reg:CC FLAGS_REG))]
10084 && ix86_binary_operator_ok (IOR, DImode, operands)"
10085 "or{q}\t{%2, %0|%0, %2}"
10086 [(set_attr "type" "alu")
10087 (set_attr "mode" "DI")])
10089 (define_insn "*iordi_2_rex64"
10090 [(set (reg FLAGS_REG)
10091 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10092 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10094 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10095 (ior:DI (match_dup 1) (match_dup 2)))]
10097 && ix86_match_ccmode (insn, CCNOmode)
10098 && ix86_binary_operator_ok (IOR, DImode, operands)"
10099 "or{q}\t{%2, %0|%0, %2}"
10100 [(set_attr "type" "alu")
10101 (set_attr "mode" "DI")])
10103 (define_insn "*iordi_3_rex64"
10104 [(set (reg FLAGS_REG)
10105 (compare (ior:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10106 (match_operand:DI 2 "x86_64_general_operand" "rem"))
10108 (clobber (match_scratch:DI 0 "=r"))]
10110 && ix86_match_ccmode (insn, CCNOmode)
10111 && ix86_binary_operator_ok (IOR, DImode, operands)"
10112 "or{q}\t{%2, %0|%0, %2}"
10113 [(set_attr "type" "alu")
10114 (set_attr "mode" "DI")])
10117 (define_expand "iorsi3"
10118 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10119 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "")
10120 (match_operand:SI 2 "general_operand" "")))]
10122 "ix86_expand_binary_operator (IOR, SImode, operands); DONE;")
10124 (define_insn "*iorsi_1"
10125 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10126 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10127 (match_operand:SI 2 "general_operand" "ri,g")))
10128 (clobber (reg:CC FLAGS_REG))]
10129 "ix86_binary_operator_ok (IOR, SImode, operands)"
10130 "or{l}\t{%2, %0|%0, %2}"
10131 [(set_attr "type" "alu")
10132 (set_attr "mode" "SI")])
10134 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10135 (define_insn "*iorsi_1_zext"
10136 [(set (match_operand:DI 0 "register_operand" "=r")
10138 (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10139 (match_operand:SI 2 "general_operand" "g"))))
10140 (clobber (reg:CC FLAGS_REG))]
10141 "TARGET_64BIT && ix86_binary_operator_ok (IOR, SImode, operands)"
10142 "or{l}\t{%2, %k0|%k0, %2}"
10143 [(set_attr "type" "alu")
10144 (set_attr "mode" "SI")])
10146 (define_insn "*iorsi_1_zext_imm"
10147 [(set (match_operand:DI 0 "register_operand" "=r")
10148 (ior:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10149 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10150 (clobber (reg:CC FLAGS_REG))]
10152 "or{l}\t{%2, %k0|%k0, %2}"
10153 [(set_attr "type" "alu")
10154 (set_attr "mode" "SI")])
10156 (define_insn "*iorsi_2"
10157 [(set (reg FLAGS_REG)
10158 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10159 (match_operand:SI 2 "general_operand" "g,ri"))
10161 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10162 (ior:SI (match_dup 1) (match_dup 2)))]
10163 "ix86_match_ccmode (insn, CCNOmode)
10164 && ix86_binary_operator_ok (IOR, SImode, operands)"
10165 "or{l}\t{%2, %0|%0, %2}"
10166 [(set_attr "type" "alu")
10167 (set_attr "mode" "SI")])
10169 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10170 ;; ??? Special case for immediate operand is missing - it is tricky.
10171 (define_insn "*iorsi_2_zext"
10172 [(set (reg FLAGS_REG)
10173 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10174 (match_operand:SI 2 "general_operand" "g"))
10176 (set (match_operand:DI 0 "register_operand" "=r")
10177 (zero_extend:DI (ior:SI (match_dup 1) (match_dup 2))))]
10178 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10179 && ix86_binary_operator_ok (IOR, SImode, operands)"
10180 "or{l}\t{%2, %k0|%k0, %2}"
10181 [(set_attr "type" "alu")
10182 (set_attr "mode" "SI")])
10184 (define_insn "*iorsi_2_zext_imm"
10185 [(set (reg FLAGS_REG)
10186 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10187 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10189 (set (match_operand:DI 0 "register_operand" "=r")
10190 (ior:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10191 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10192 && ix86_binary_operator_ok (IOR, SImode, operands)"
10193 "or{l}\t{%2, %k0|%k0, %2}"
10194 [(set_attr "type" "alu")
10195 (set_attr "mode" "SI")])
10197 (define_insn "*iorsi_3"
10198 [(set (reg FLAGS_REG)
10199 (compare (ior:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10200 (match_operand:SI 2 "general_operand" "g"))
10202 (clobber (match_scratch:SI 0 "=r"))]
10203 "ix86_match_ccmode (insn, CCNOmode)
10204 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10205 "or{l}\t{%2, %0|%0, %2}"
10206 [(set_attr "type" "alu")
10207 (set_attr "mode" "SI")])
10209 (define_expand "iorhi3"
10210 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10211 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "")
10212 (match_operand:HI 2 "general_operand" "")))]
10213 "TARGET_HIMODE_MATH"
10214 "ix86_expand_binary_operator (IOR, HImode, operands); DONE;")
10216 (define_insn "*iorhi_1"
10217 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10218 (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10219 (match_operand:HI 2 "general_operand" "rmn,rn")))
10220 (clobber (reg:CC FLAGS_REG))]
10221 "ix86_binary_operator_ok (IOR, HImode, operands)"
10222 "or{w}\t{%2, %0|%0, %2}"
10223 [(set_attr "type" "alu")
10224 (set_attr "mode" "HI")])
10226 (define_insn "*iorhi_2"
10227 [(set (reg FLAGS_REG)
10228 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10229 (match_operand:HI 2 "general_operand" "rmn,rn"))
10231 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10232 (ior:HI (match_dup 1) (match_dup 2)))]
10233 "ix86_match_ccmode (insn, CCNOmode)
10234 && ix86_binary_operator_ok (IOR, HImode, operands)"
10235 "or{w}\t{%2, %0|%0, %2}"
10236 [(set_attr "type" "alu")
10237 (set_attr "mode" "HI")])
10239 (define_insn "*iorhi_3"
10240 [(set (reg FLAGS_REG)
10241 (compare (ior:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10242 (match_operand:HI 2 "general_operand" "rmn"))
10244 (clobber (match_scratch:HI 0 "=r"))]
10245 "ix86_match_ccmode (insn, CCNOmode)
10246 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10247 "or{w}\t{%2, %0|%0, %2}"
10248 [(set_attr "type" "alu")
10249 (set_attr "mode" "HI")])
10251 (define_expand "iorqi3"
10252 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10253 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "")
10254 (match_operand:QI 2 "general_operand" "")))]
10255 "TARGET_QIMODE_MATH"
10256 "ix86_expand_binary_operator (IOR, QImode, operands); DONE;")
10258 ;; %%% Potential partial reg stall on alternative 2. What to do?
10259 (define_insn "*iorqi_1"
10260 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10261 (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10262 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10263 (clobber (reg:CC FLAGS_REG))]
10264 "ix86_binary_operator_ok (IOR, QImode, operands)"
10266 or{b}\t{%2, %0|%0, %2}
10267 or{b}\t{%2, %0|%0, %2}
10268 or{l}\t{%k2, %k0|%k0, %k2}"
10269 [(set_attr "type" "alu")
10270 (set_attr "mode" "QI,QI,SI")])
10272 (define_insn "*iorqi_1_slp"
10273 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+q,m"))
10274 (ior:QI (match_dup 0)
10275 (match_operand:QI 1 "general_operand" "qmn,qn")))
10276 (clobber (reg:CC FLAGS_REG))]
10277 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10278 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10279 "or{b}\t{%1, %0|%0, %1}"
10280 [(set_attr "type" "alu1")
10281 (set_attr "mode" "QI")])
10283 (define_insn "*iorqi_2"
10284 [(set (reg FLAGS_REG)
10285 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10286 (match_operand:QI 2 "general_operand" "qmn,qn"))
10288 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10289 (ior:QI (match_dup 1) (match_dup 2)))]
10290 "ix86_match_ccmode (insn, CCNOmode)
10291 && ix86_binary_operator_ok (IOR, QImode, operands)"
10292 "or{b}\t{%2, %0|%0, %2}"
10293 [(set_attr "type" "alu")
10294 (set_attr "mode" "QI")])
10296 (define_insn "*iorqi_2_slp"
10297 [(set (reg FLAGS_REG)
10298 (compare (ior:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10299 (match_operand:QI 1 "general_operand" "qmn,qn"))
10301 (set (strict_low_part (match_dup 0))
10302 (ior:QI (match_dup 0) (match_dup 1)))]
10303 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10304 && ix86_match_ccmode (insn, CCNOmode)
10305 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10306 "or{b}\t{%1, %0|%0, %1}"
10307 [(set_attr "type" "alu1")
10308 (set_attr "mode" "QI")])
10310 (define_insn "*iorqi_3"
10311 [(set (reg FLAGS_REG)
10312 (compare (ior:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10313 (match_operand:QI 2 "general_operand" "qmn"))
10315 (clobber (match_scratch:QI 0 "=q"))]
10316 "ix86_match_ccmode (insn, CCNOmode)
10317 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10318 "or{b}\t{%2, %0|%0, %2}"
10319 [(set_attr "type" "alu")
10320 (set_attr "mode" "QI")])
10322 (define_insn "*iorqi_ext_0"
10323 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10328 (match_operand 1 "ext_register_operand" "0")
10331 (match_operand 2 "const_int_operand" "n")))
10332 (clobber (reg:CC FLAGS_REG))]
10333 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10334 "or{b}\t{%2, %h0|%h0, %2}"
10335 [(set_attr "type" "alu")
10336 (set_attr "length_immediate" "1")
10337 (set_attr "modrm" "1")
10338 (set_attr "mode" "QI")])
10340 (define_insn "*iorqi_ext_1"
10341 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10346 (match_operand 1 "ext_register_operand" "0")
10350 (match_operand:QI 2 "general_operand" "Qm"))))
10351 (clobber (reg:CC FLAGS_REG))]
10353 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10354 "or{b}\t{%2, %h0|%h0, %2}"
10355 [(set_attr "type" "alu")
10356 (set_attr "length_immediate" "0")
10357 (set_attr "mode" "QI")])
10359 (define_insn "*iorqi_ext_1_rex64"
10360 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10365 (match_operand 1 "ext_register_operand" "0")
10369 (match_operand 2 "ext_register_operand" "Q"))))
10370 (clobber (reg:CC FLAGS_REG))]
10372 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10373 "or{b}\t{%2, %h0|%h0, %2}"
10374 [(set_attr "type" "alu")
10375 (set_attr "length_immediate" "0")
10376 (set_attr "mode" "QI")])
10378 (define_insn "*iorqi_ext_2"
10379 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10383 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10386 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10389 (clobber (reg:CC FLAGS_REG))]
10390 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10391 "ior{b}\t{%h2, %h0|%h0, %h2}"
10392 [(set_attr "type" "alu")
10393 (set_attr "length_immediate" "0")
10394 (set_attr "mode" "QI")])
10397 [(set (match_operand 0 "register_operand" "")
10398 (ior (match_operand 1 "register_operand" "")
10399 (match_operand 2 "const_int_operand" "")))
10400 (clobber (reg:CC FLAGS_REG))]
10402 && QI_REG_P (operands[0])
10403 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10404 && !(INTVAL (operands[2]) & ~(255 << 8))
10405 && GET_MODE (operands[0]) != QImode"
10406 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10407 (ior:SI (zero_extract:SI (match_dup 1)
10408 (const_int 8) (const_int 8))
10410 (clobber (reg:CC FLAGS_REG))])]
10411 "operands[0] = gen_lowpart (SImode, operands[0]);
10412 operands[1] = gen_lowpart (SImode, operands[1]);
10413 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10415 ;; Since OR can be encoded with sign extended immediate, this is only
10416 ;; profitable when 7th bit is set.
10418 [(set (match_operand 0 "register_operand" "")
10419 (ior (match_operand 1 "general_operand" "")
10420 (match_operand 2 "const_int_operand" "")))
10421 (clobber (reg:CC FLAGS_REG))]
10423 && ANY_QI_REG_P (operands[0])
10424 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10425 && !(INTVAL (operands[2]) & ~255)
10426 && (INTVAL (operands[2]) & 128)
10427 && GET_MODE (operands[0]) != QImode"
10428 [(parallel [(set (strict_low_part (match_dup 0))
10429 (ior:QI (match_dup 1)
10431 (clobber (reg:CC FLAGS_REG))])]
10432 "operands[0] = gen_lowpart (QImode, operands[0]);
10433 operands[1] = gen_lowpart (QImode, operands[1]);
10434 operands[2] = gen_lowpart (QImode, operands[2]);")
10436 ;; Logical XOR instructions
10438 ;; %%% This used to optimize known byte-wide and operations to memory.
10439 ;; If this is considered useful, it should be done with splitters.
10441 (define_expand "xordi3"
10442 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10443 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "")
10444 (match_operand:DI 2 "x86_64_general_operand" "")))]
10446 "ix86_expand_binary_operator (XOR, DImode, operands); DONE;")
10448 (define_insn "*xordi_1_rex64"
10449 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
10450 (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10451 (match_operand:DI 2 "x86_64_general_operand" "re,rm")))
10452 (clobber (reg:CC FLAGS_REG))]
10454 && ix86_binary_operator_ok (XOR, DImode, operands)"
10455 "xor{q}\t{%2, %0|%0, %2}"
10456 [(set_attr "type" "alu")
10457 (set_attr "mode" "DI")])
10459 (define_insn "*xordi_2_rex64"
10460 [(set (reg FLAGS_REG)
10461 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0,0")
10462 (match_operand:DI 2 "x86_64_general_operand" "rem,re"))
10464 (set (match_operand:DI 0 "nonimmediate_operand" "=r,rm")
10465 (xor:DI (match_dup 1) (match_dup 2)))]
10467 && ix86_match_ccmode (insn, CCNOmode)
10468 && ix86_binary_operator_ok (XOR, DImode, operands)"
10469 "xor{q}\t{%2, %0|%0, %2}"
10470 [(set_attr "type" "alu")
10471 (set_attr "mode" "DI")])
10473 (define_insn "*xordi_3_rex64"
10474 [(set (reg FLAGS_REG)
10475 (compare (xor:DI (match_operand:DI 1 "nonimmediate_operand" "%0")
10476 (match_operand:DI 2 "x86_64_general_operand" "rem"))
10478 (clobber (match_scratch:DI 0 "=r"))]
10480 && ix86_match_ccmode (insn, CCNOmode)
10481 && ix86_binary_operator_ok (XOR, DImode, operands)"
10482 "xor{q}\t{%2, %0|%0, %2}"
10483 [(set_attr "type" "alu")
10484 (set_attr "mode" "DI")])
10486 (define_expand "xorsi3"
10487 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10488 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "")
10489 (match_operand:SI 2 "general_operand" "")))]
10491 "ix86_expand_binary_operator (XOR, SImode, operands); DONE;")
10493 (define_insn "*xorsi_1"
10494 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
10495 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10496 (match_operand:SI 2 "general_operand" "ri,rm")))
10497 (clobber (reg:CC FLAGS_REG))]
10498 "ix86_binary_operator_ok (XOR, SImode, operands)"
10499 "xor{l}\t{%2, %0|%0, %2}"
10500 [(set_attr "type" "alu")
10501 (set_attr "mode" "SI")])
10503 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10504 ;; Add speccase for immediates
10505 (define_insn "*xorsi_1_zext"
10506 [(set (match_operand:DI 0 "register_operand" "=r")
10508 (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10509 (match_operand:SI 2 "general_operand" "g"))))
10510 (clobber (reg:CC FLAGS_REG))]
10511 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10512 "xor{l}\t{%2, %k0|%k0, %2}"
10513 [(set_attr "type" "alu")
10514 (set_attr "mode" "SI")])
10516 (define_insn "*xorsi_1_zext_imm"
10517 [(set (match_operand:DI 0 "register_operand" "=r")
10518 (xor:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "%0"))
10519 (match_operand:DI 2 "x86_64_zext_immediate_operand" "Z")))
10520 (clobber (reg:CC FLAGS_REG))]
10521 "TARGET_64BIT && ix86_binary_operator_ok (XOR, SImode, operands)"
10522 "xor{l}\t{%2, %k0|%k0, %2}"
10523 [(set_attr "type" "alu")
10524 (set_attr "mode" "SI")])
10526 (define_insn "*xorsi_2"
10527 [(set (reg FLAGS_REG)
10528 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0,0")
10529 (match_operand:SI 2 "general_operand" "g,ri"))
10531 (set (match_operand:SI 0 "nonimmediate_operand" "=r,rm")
10532 (xor:SI (match_dup 1) (match_dup 2)))]
10533 "ix86_match_ccmode (insn, CCNOmode)
10534 && ix86_binary_operator_ok (XOR, SImode, operands)"
10535 "xor{l}\t{%2, %0|%0, %2}"
10536 [(set_attr "type" "alu")
10537 (set_attr "mode" "SI")])
10539 ;; See comment for addsi_1_zext why we do use nonimmediate_operand
10540 ;; ??? Special case for immediate operand is missing - it is tricky.
10541 (define_insn "*xorsi_2_zext"
10542 [(set (reg FLAGS_REG)
10543 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10544 (match_operand:SI 2 "general_operand" "g"))
10546 (set (match_operand:DI 0 "register_operand" "=r")
10547 (zero_extend:DI (xor:SI (match_dup 1) (match_dup 2))))]
10548 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10549 && ix86_binary_operator_ok (XOR, SImode, operands)"
10550 "xor{l}\t{%2, %k0|%k0, %2}"
10551 [(set_attr "type" "alu")
10552 (set_attr "mode" "SI")])
10554 (define_insn "*xorsi_2_zext_imm"
10555 [(set (reg FLAGS_REG)
10556 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10557 (match_operand 2 "x86_64_zext_immediate_operand" "Z"))
10559 (set (match_operand:DI 0 "register_operand" "=r")
10560 (xor:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
10561 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
10562 && ix86_binary_operator_ok (XOR, SImode, operands)"
10563 "xor{l}\t{%2, %k0|%k0, %2}"
10564 [(set_attr "type" "alu")
10565 (set_attr "mode" "SI")])
10567 (define_insn "*xorsi_3"
10568 [(set (reg FLAGS_REG)
10569 (compare (xor:SI (match_operand:SI 1 "nonimmediate_operand" "%0")
10570 (match_operand:SI 2 "general_operand" "g"))
10572 (clobber (match_scratch:SI 0 "=r"))]
10573 "ix86_match_ccmode (insn, CCNOmode)
10574 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10575 "xor{l}\t{%2, %0|%0, %2}"
10576 [(set_attr "type" "alu")
10577 (set_attr "mode" "SI")])
10579 (define_expand "xorhi3"
10580 [(set (match_operand:HI 0 "nonimmediate_operand" "")
10581 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "")
10582 (match_operand:HI 2 "general_operand" "")))]
10583 "TARGET_HIMODE_MATH"
10584 "ix86_expand_binary_operator (XOR, HImode, operands); DONE;")
10586 (define_insn "*xorhi_1"
10587 [(set (match_operand:HI 0 "nonimmediate_operand" "=r,m")
10588 (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10589 (match_operand:HI 2 "general_operand" "rmn,rn")))
10590 (clobber (reg:CC FLAGS_REG))]
10591 "ix86_binary_operator_ok (XOR, HImode, operands)"
10592 "xor{w}\t{%2, %0|%0, %2}"
10593 [(set_attr "type" "alu")
10594 (set_attr "mode" "HI")])
10596 (define_insn "*xorhi_2"
10597 [(set (reg FLAGS_REG)
10598 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0,0")
10599 (match_operand:HI 2 "general_operand" "rmn,rn"))
10601 (set (match_operand:HI 0 "nonimmediate_operand" "=r,rm")
10602 (xor:HI (match_dup 1) (match_dup 2)))]
10603 "ix86_match_ccmode (insn, CCNOmode)
10604 && ix86_binary_operator_ok (XOR, HImode, operands)"
10605 "xor{w}\t{%2, %0|%0, %2}"
10606 [(set_attr "type" "alu")
10607 (set_attr "mode" "HI")])
10609 (define_insn "*xorhi_3"
10610 [(set (reg FLAGS_REG)
10611 (compare (xor:HI (match_operand:HI 1 "nonimmediate_operand" "%0")
10612 (match_operand:HI 2 "general_operand" "rmn"))
10614 (clobber (match_scratch:HI 0 "=r"))]
10615 "ix86_match_ccmode (insn, CCNOmode)
10616 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10617 "xor{w}\t{%2, %0|%0, %2}"
10618 [(set_attr "type" "alu")
10619 (set_attr "mode" "HI")])
10621 (define_expand "xorqi3"
10622 [(set (match_operand:QI 0 "nonimmediate_operand" "")
10623 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "")
10624 (match_operand:QI 2 "general_operand" "")))]
10625 "TARGET_QIMODE_MATH"
10626 "ix86_expand_binary_operator (XOR, QImode, operands); DONE;")
10628 ;; %%% Potential partial reg stall on alternative 2. What to do?
10629 (define_insn "*xorqi_1"
10630 [(set (match_operand:QI 0 "nonimmediate_operand" "=q,m,r")
10631 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0,0")
10632 (match_operand:QI 2 "general_operand" "qmn,qn,rn")))
10633 (clobber (reg:CC FLAGS_REG))]
10634 "ix86_binary_operator_ok (XOR, QImode, operands)"
10636 xor{b}\t{%2, %0|%0, %2}
10637 xor{b}\t{%2, %0|%0, %2}
10638 xor{l}\t{%k2, %k0|%k0, %k2}"
10639 [(set_attr "type" "alu")
10640 (set_attr "mode" "QI,QI,SI")])
10642 (define_insn "*xorqi_1_slp"
10643 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,q"))
10644 (xor:QI (match_dup 0)
10645 (match_operand:QI 1 "general_operand" "qn,qmn")))
10646 (clobber (reg:CC FLAGS_REG))]
10647 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10648 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10649 "xor{b}\t{%1, %0|%0, %1}"
10650 [(set_attr "type" "alu1")
10651 (set_attr "mode" "QI")])
10653 (define_insn "*xorqi_ext_0"
10654 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10659 (match_operand 1 "ext_register_operand" "0")
10662 (match_operand 2 "const_int_operand" "n")))
10663 (clobber (reg:CC FLAGS_REG))]
10664 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10665 "xor{b}\t{%2, %h0|%h0, %2}"
10666 [(set_attr "type" "alu")
10667 (set_attr "length_immediate" "1")
10668 (set_attr "modrm" "1")
10669 (set_attr "mode" "QI")])
10671 (define_insn "*xorqi_ext_1"
10672 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10677 (match_operand 1 "ext_register_operand" "0")
10681 (match_operand:QI 2 "general_operand" "Qm"))))
10682 (clobber (reg:CC FLAGS_REG))]
10684 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10685 "xor{b}\t{%2, %h0|%h0, %2}"
10686 [(set_attr "type" "alu")
10687 (set_attr "length_immediate" "0")
10688 (set_attr "mode" "QI")])
10690 (define_insn "*xorqi_ext_1_rex64"
10691 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10696 (match_operand 1 "ext_register_operand" "0")
10700 (match_operand 2 "ext_register_operand" "Q"))))
10701 (clobber (reg:CC FLAGS_REG))]
10703 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10704 "xor{b}\t{%2, %h0|%h0, %2}"
10705 [(set_attr "type" "alu")
10706 (set_attr "length_immediate" "0")
10707 (set_attr "mode" "QI")])
10709 (define_insn "*xorqi_ext_2"
10710 [(set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10714 (zero_extract:SI (match_operand 1 "ext_register_operand" "0")
10717 (zero_extract:SI (match_operand 2 "ext_register_operand" "Q")
10720 (clobber (reg:CC FLAGS_REG))]
10721 "(!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))"
10722 "xor{b}\t{%h2, %h0|%h0, %h2}"
10723 [(set_attr "type" "alu")
10724 (set_attr "length_immediate" "0")
10725 (set_attr "mode" "QI")])
10727 (define_insn "*xorqi_cc_1"
10728 [(set (reg FLAGS_REG)
10730 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0,0")
10731 (match_operand:QI 2 "general_operand" "qmn,qn"))
10733 (set (match_operand:QI 0 "nonimmediate_operand" "=q,qm")
10734 (xor:QI (match_dup 1) (match_dup 2)))]
10735 "ix86_match_ccmode (insn, CCNOmode)
10736 && ix86_binary_operator_ok (XOR, QImode, operands)"
10737 "xor{b}\t{%2, %0|%0, %2}"
10738 [(set_attr "type" "alu")
10739 (set_attr "mode" "QI")])
10741 (define_insn "*xorqi_2_slp"
10742 [(set (reg FLAGS_REG)
10743 (compare (xor:QI (match_operand:QI 0 "nonimmediate_operand" "+q,qm")
10744 (match_operand:QI 1 "general_operand" "qmn,qn"))
10746 (set (strict_low_part (match_dup 0))
10747 (xor:QI (match_dup 0) (match_dup 1)))]
10748 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10749 && ix86_match_ccmode (insn, CCNOmode)
10750 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
10751 "xor{b}\t{%1, %0|%0, %1}"
10752 [(set_attr "type" "alu1")
10753 (set_attr "mode" "QI")])
10755 (define_insn "*xorqi_cc_2"
10756 [(set (reg FLAGS_REG)
10758 (xor:QI (match_operand:QI 1 "nonimmediate_operand" "%0")
10759 (match_operand:QI 2 "general_operand" "qmn"))
10761 (clobber (match_scratch:QI 0 "=q"))]
10762 "ix86_match_ccmode (insn, CCNOmode)
10763 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
10764 "xor{b}\t{%2, %0|%0, %2}"
10765 [(set_attr "type" "alu")
10766 (set_attr "mode" "QI")])
10768 (define_insn "*xorqi_cc_ext_1"
10769 [(set (reg FLAGS_REG)
10773 (match_operand 1 "ext_register_operand" "0")
10776 (match_operand:QI 2 "general_operand" "qmn"))
10778 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=q")
10782 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10784 "!TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10785 "xor{b}\t{%2, %h0|%h0, %2}"
10786 [(set_attr "type" "alu")
10787 (set_attr "modrm" "1")
10788 (set_attr "mode" "QI")])
10790 (define_insn "*xorqi_cc_ext_1_rex64"
10791 [(set (reg FLAGS_REG)
10795 (match_operand 1 "ext_register_operand" "0")
10798 (match_operand:QI 2 "nonmemory_operand" "Qn"))
10800 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "=Q")
10804 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10806 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
10807 "xor{b}\t{%2, %h0|%h0, %2}"
10808 [(set_attr "type" "alu")
10809 (set_attr "modrm" "1")
10810 (set_attr "mode" "QI")])
10812 (define_expand "xorqi_cc_ext_1"
10814 (set (reg:CCNO FLAGS_REG)
10818 (match_operand 1 "ext_register_operand" "")
10821 (match_operand:QI 2 "general_operand" ""))
10823 (set (zero_extract:SI (match_operand 0 "ext_register_operand" "")
10827 (zero_extract:SI (match_dup 1) (const_int 8) (const_int 8))
10833 [(set (match_operand 0 "register_operand" "")
10834 (xor (match_operand 1 "register_operand" "")
10835 (match_operand 2 "const_int_operand" "")))
10836 (clobber (reg:CC FLAGS_REG))]
10838 && QI_REG_P (operands[0])
10839 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10840 && !(INTVAL (operands[2]) & ~(255 << 8))
10841 && GET_MODE (operands[0]) != QImode"
10842 [(parallel [(set (zero_extract:SI (match_dup 0) (const_int 8) (const_int 8))
10843 (xor:SI (zero_extract:SI (match_dup 1)
10844 (const_int 8) (const_int 8))
10846 (clobber (reg:CC FLAGS_REG))])]
10847 "operands[0] = gen_lowpart (SImode, operands[0]);
10848 operands[1] = gen_lowpart (SImode, operands[1]);
10849 operands[2] = gen_int_mode ((INTVAL (operands[2]) >> 8) & 0xff, SImode);")
10851 ;; Since XOR can be encoded with sign extended immediate, this is only
10852 ;; profitable when 7th bit is set.
10854 [(set (match_operand 0 "register_operand" "")
10855 (xor (match_operand 1 "general_operand" "")
10856 (match_operand 2 "const_int_operand" "")))
10857 (clobber (reg:CC FLAGS_REG))]
10859 && ANY_QI_REG_P (operands[0])
10860 && (!TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
10861 && !(INTVAL (operands[2]) & ~255)
10862 && (INTVAL (operands[2]) & 128)
10863 && GET_MODE (operands[0]) != QImode"
10864 [(parallel [(set (strict_low_part (match_dup 0))
10865 (xor:QI (match_dup 1)
10867 (clobber (reg:CC FLAGS_REG))])]
10868 "operands[0] = gen_lowpart (QImode, operands[0]);
10869 operands[1] = gen_lowpart (QImode, operands[1]);
10870 operands[2] = gen_lowpart (QImode, operands[2]);")
10872 ;; Negation instructions
10874 (define_expand "negti2"
10875 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10876 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))]
10878 "ix86_expand_unary_operator (NEG, TImode, operands); DONE;")
10880 (define_insn "*negti2_1"
10881 [(set (match_operand:TI 0 "nonimmediate_operand" "=ro")
10882 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "0")))
10883 (clobber (reg:CC FLAGS_REG))]
10885 && ix86_unary_operator_ok (NEG, TImode, operands)"
10889 [(set (match_operand:TI 0 "nonimmediate_operand" "")
10890 (neg:TI (match_operand:TI 1 "nonimmediate_operand" "")))
10891 (clobber (reg:CC FLAGS_REG))]
10892 "TARGET_64BIT && reload_completed"
10894 [(set (reg:CCZ FLAGS_REG)
10895 (compare:CCZ (neg:DI (match_dup 1)) (const_int 0)))
10896 (set (match_dup 0) (neg:DI (match_dup 1)))])
10898 [(set (match_dup 2)
10899 (plus:DI (plus:DI (ltu:DI (reg:CC FLAGS_REG) (const_int 0))
10902 (clobber (reg:CC FLAGS_REG))])
10904 [(set (match_dup 2)
10905 (neg:DI (match_dup 2)))
10906 (clobber (reg:CC FLAGS_REG))])]
10907 "split_ti (&operands[0], 2, &operands[0], &operands[2]);")
10909 (define_expand "negdi2"
10910 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10911 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
10913 "ix86_expand_unary_operator (NEG, DImode, operands); DONE;")
10915 (define_insn "*negdi2_1"
10916 [(set (match_operand:DI 0 "nonimmediate_operand" "=ro")
10917 (neg:DI (match_operand:DI 1 "general_operand" "0")))
10918 (clobber (reg:CC FLAGS_REG))]
10920 && ix86_unary_operator_ok (NEG, DImode, operands)"
10924 [(set (match_operand:DI 0 "nonimmediate_operand" "")
10925 (neg:DI (match_operand:DI 1 "general_operand" "")))
10926 (clobber (reg:CC FLAGS_REG))]
10927 "!TARGET_64BIT && reload_completed"
10929 [(set (reg:CCZ FLAGS_REG)
10930 (compare:CCZ (neg:SI (match_dup 1)) (const_int 0)))
10931 (set (match_dup 0) (neg:SI (match_dup 1)))])
10933 [(set (match_dup 2)
10934 (plus:SI (plus:SI (ltu:SI (reg:CC FLAGS_REG) (const_int 0))
10937 (clobber (reg:CC FLAGS_REG))])
10939 [(set (match_dup 2)
10940 (neg:SI (match_dup 2)))
10941 (clobber (reg:CC FLAGS_REG))])]
10942 "split_di (&operands[0], 2, &operands[0], &operands[2]);");
10944 (define_insn "*negdi2_1_rex64"
10945 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10946 (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0")))
10947 (clobber (reg:CC FLAGS_REG))]
10948 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10950 [(set_attr "type" "negnot")
10951 (set_attr "mode" "DI")])
10953 ;; The problem with neg is that it does not perform (compare x 0),
10954 ;; it really performs (compare 0 x), which leaves us with the zero
10955 ;; flag being the only useful item.
10957 (define_insn "*negdi2_cmpz_rex64"
10958 [(set (reg:CCZ FLAGS_REG)
10959 (compare:CCZ (neg:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
10961 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
10962 (neg:DI (match_dup 1)))]
10963 "TARGET_64BIT && ix86_unary_operator_ok (NEG, DImode, operands)"
10965 [(set_attr "type" "negnot")
10966 (set_attr "mode" "DI")])
10969 (define_expand "negsi2"
10970 [(set (match_operand:SI 0 "nonimmediate_operand" "")
10971 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
10973 "ix86_expand_unary_operator (NEG, SImode, operands); DONE;")
10975 (define_insn "*negsi2_1"
10976 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
10977 (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0")))
10978 (clobber (reg:CC FLAGS_REG))]
10979 "ix86_unary_operator_ok (NEG, SImode, operands)"
10981 [(set_attr "type" "negnot")
10982 (set_attr "mode" "SI")])
10984 ;; Combine is quite creative about this pattern.
10985 (define_insn "*negsi2_1_zext"
10986 [(set (match_operand:DI 0 "register_operand" "=r")
10987 (lshiftrt:DI (neg:DI (ashift:DI (match_operand:DI 1 "register_operand" "0")
10990 (clobber (reg:CC FLAGS_REG))]
10991 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
10993 [(set_attr "type" "negnot")
10994 (set_attr "mode" "SI")])
10996 ;; The problem with neg is that it does not perform (compare x 0),
10997 ;; it really performs (compare 0 x), which leaves us with the zero
10998 ;; flag being the only useful item.
11000 (define_insn "*negsi2_cmpz"
11001 [(set (reg:CCZ FLAGS_REG)
11002 (compare:CCZ (neg:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11004 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11005 (neg:SI (match_dup 1)))]
11006 "ix86_unary_operator_ok (NEG, SImode, operands)"
11008 [(set_attr "type" "negnot")
11009 (set_attr "mode" "SI")])
11011 (define_insn "*negsi2_cmpz_zext"
11012 [(set (reg:CCZ FLAGS_REG)
11013 (compare:CCZ (lshiftrt:DI
11015 (match_operand:DI 1 "register_operand" "0")
11019 (set (match_operand:DI 0 "register_operand" "=r")
11020 (lshiftrt:DI (neg:DI (ashift:DI (match_dup 1)
11023 "TARGET_64BIT && ix86_unary_operator_ok (NEG, SImode, operands)"
11025 [(set_attr "type" "negnot")
11026 (set_attr "mode" "SI")])
11028 (define_expand "neghi2"
11029 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11030 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11031 "TARGET_HIMODE_MATH"
11032 "ix86_expand_unary_operator (NEG, HImode, operands); DONE;")
11034 (define_insn "*neghi2_1"
11035 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11036 (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0")))
11037 (clobber (reg:CC FLAGS_REG))]
11038 "ix86_unary_operator_ok (NEG, HImode, operands)"
11040 [(set_attr "type" "negnot")
11041 (set_attr "mode" "HI")])
11043 (define_insn "*neghi2_cmpz"
11044 [(set (reg:CCZ FLAGS_REG)
11045 (compare:CCZ (neg:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11047 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11048 (neg:HI (match_dup 1)))]
11049 "ix86_unary_operator_ok (NEG, HImode, operands)"
11051 [(set_attr "type" "negnot")
11052 (set_attr "mode" "HI")])
11054 (define_expand "negqi2"
11055 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11056 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11057 "TARGET_QIMODE_MATH"
11058 "ix86_expand_unary_operator (NEG, QImode, operands); DONE;")
11060 (define_insn "*negqi2_1"
11061 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11062 (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0")))
11063 (clobber (reg:CC FLAGS_REG))]
11064 "ix86_unary_operator_ok (NEG, QImode, operands)"
11066 [(set_attr "type" "negnot")
11067 (set_attr "mode" "QI")])
11069 (define_insn "*negqi2_cmpz"
11070 [(set (reg:CCZ FLAGS_REG)
11071 (compare:CCZ (neg:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11073 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11074 (neg:QI (match_dup 1)))]
11075 "ix86_unary_operator_ok (NEG, QImode, operands)"
11077 [(set_attr "type" "negnot")
11078 (set_attr "mode" "QI")])
11080 ;; Changing of sign for FP values is doable using integer unit too.
11082 (define_expand "<code><mode>2"
11083 [(set (match_operand:X87MODEF 0 "register_operand" "")
11084 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "")))]
11085 "TARGET_80387 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11086 "ix86_expand_fp_absneg_operator (<CODE>, <MODE>mode, operands); DONE;")
11088 (define_insn "*absneg<mode>2_mixed"
11089 [(set (match_operand:MODEF 0 "register_operand" "=x,x,f,!r")
11090 (match_operator:MODEF 3 "absneg_operator"
11091 [(match_operand:MODEF 1 "register_operand" "0,x,0,0")]))
11092 (use (match_operand:<ssevecmode> 2 "nonimmediate_operand" "xm,0,X,X"))
11093 (clobber (reg:CC FLAGS_REG))]
11094 "TARGET_MIX_SSE_I387 && SSE_FLOAT_MODE_P (<MODE>mode)"
11097 (define_insn "*absneg<mode>2_sse"
11098 [(set (match_operand:MODEF 0 "register_operand" "=x,x,!r")
11099 (match_operator:MODEF 3 "absneg_operator"
11100 [(match_operand:MODEF 1 "register_operand" "0 ,x,0")]))
11101 (use (match_operand:<ssevecmode> 2 "register_operand" "xm,0,X"))
11102 (clobber (reg:CC FLAGS_REG))]
11103 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
11106 (define_insn "*absneg<mode>2_i387"
11107 [(set (match_operand:X87MODEF 0 "register_operand" "=f,!r")
11108 (match_operator:X87MODEF 3 "absneg_operator"
11109 [(match_operand:X87MODEF 1 "register_operand" "0,0")]))
11110 (use (match_operand 2 "" ""))
11111 (clobber (reg:CC FLAGS_REG))]
11112 "TARGET_80387 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
11115 (define_expand "<code>tf2"
11116 [(set (match_operand:TF 0 "register_operand" "")
11117 (absneg:TF (match_operand:TF 1 "register_operand" "")))]
11119 "ix86_expand_fp_absneg_operator (<CODE>, TFmode, operands); DONE;")
11121 (define_insn "*absnegtf2_sse"
11122 [(set (match_operand:TF 0 "register_operand" "=x,x")
11123 (match_operator:TF 3 "absneg_operator"
11124 [(match_operand:TF 1 "register_operand" "0,x")]))
11125 (use (match_operand:TF 2 "nonimmediate_operand" "xm,0"))
11126 (clobber (reg:CC FLAGS_REG))]
11130 ;; Splitters for fp abs and neg.
11133 [(set (match_operand 0 "fp_register_operand" "")
11134 (match_operator 1 "absneg_operator" [(match_dup 0)]))
11135 (use (match_operand 2 "" ""))
11136 (clobber (reg:CC FLAGS_REG))]
11138 [(set (match_dup 0) (match_op_dup 1 [(match_dup 0)]))])
11141 [(set (match_operand 0 "register_operand" "")
11142 (match_operator 3 "absneg_operator"
11143 [(match_operand 1 "register_operand" "")]))
11144 (use (match_operand 2 "nonimmediate_operand" ""))
11145 (clobber (reg:CC FLAGS_REG))]
11146 "reload_completed && SSE_REG_P (operands[0])"
11147 [(set (match_dup 0) (match_dup 3))]
11149 enum machine_mode mode = GET_MODE (operands[0]);
11150 enum machine_mode vmode = GET_MODE (operands[2]);
11153 operands[0] = simplify_gen_subreg (vmode, operands[0], mode, 0);
11154 operands[1] = simplify_gen_subreg (vmode, operands[1], mode, 0);
11155 if (operands_match_p (operands[0], operands[2]))
11158 operands[1] = operands[2];
11161 if (GET_CODE (operands[3]) == ABS)
11162 tmp = gen_rtx_AND (vmode, operands[1], operands[2]);
11164 tmp = gen_rtx_XOR (vmode, operands[1], operands[2]);
11169 [(set (match_operand:SF 0 "register_operand" "")
11170 (match_operator:SF 1 "absneg_operator" [(match_dup 0)]))
11171 (use (match_operand:V4SF 2 "" ""))
11172 (clobber (reg:CC FLAGS_REG))]
11174 [(parallel [(set (match_dup 0) (match_dup 1))
11175 (clobber (reg:CC FLAGS_REG))])]
11178 operands[0] = gen_lowpart (SImode, operands[0]);
11179 if (GET_CODE (operands[1]) == ABS)
11181 tmp = gen_int_mode (0x7fffffff, SImode);
11182 tmp = gen_rtx_AND (SImode, operands[0], tmp);
11186 tmp = gen_int_mode (0x80000000, SImode);
11187 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11193 [(set (match_operand:DF 0 "register_operand" "")
11194 (match_operator:DF 1 "absneg_operator" [(match_dup 0)]))
11195 (use (match_operand 2 "" ""))
11196 (clobber (reg:CC FLAGS_REG))]
11198 [(parallel [(set (match_dup 0) (match_dup 1))
11199 (clobber (reg:CC FLAGS_REG))])]
11204 tmp = gen_lowpart (DImode, operands[0]);
11205 tmp = gen_rtx_ZERO_EXTRACT (DImode, tmp, const1_rtx, GEN_INT (63));
11208 if (GET_CODE (operands[1]) == ABS)
11211 tmp = gen_rtx_NOT (DImode, tmp);
11215 operands[0] = gen_highpart (SImode, operands[0]);
11216 if (GET_CODE (operands[1]) == ABS)
11218 tmp = gen_int_mode (0x7fffffff, SImode);
11219 tmp = gen_rtx_AND (SImode, operands[0], tmp);
11223 tmp = gen_int_mode (0x80000000, SImode);
11224 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11231 [(set (match_operand:XF 0 "register_operand" "")
11232 (match_operator:XF 1 "absneg_operator" [(match_dup 0)]))
11233 (use (match_operand 2 "" ""))
11234 (clobber (reg:CC FLAGS_REG))]
11236 [(parallel [(set (match_dup 0) (match_dup 1))
11237 (clobber (reg:CC FLAGS_REG))])]
11240 operands[0] = gen_rtx_REG (SImode,
11241 true_regnum (operands[0])
11242 + (TARGET_64BIT ? 1 : 2));
11243 if (GET_CODE (operands[1]) == ABS)
11245 tmp = GEN_INT (0x7fff);
11246 tmp = gen_rtx_AND (SImode, operands[0], tmp);
11250 tmp = GEN_INT (0x8000);
11251 tmp = gen_rtx_XOR (SImode, operands[0], tmp);
11256 ;; Conditionalize these after reload. If they match before reload, we
11257 ;; lose the clobber and ability to use integer instructions.
11259 (define_insn "*<code><mode>2_1"
11260 [(set (match_operand:X87MODEF 0 "register_operand" "=f")
11261 (absneg:X87MODEF (match_operand:X87MODEF 1 "register_operand" "0")))]
11263 && (reload_completed
11264 || !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))"
11266 [(set_attr "type" "fsgn")
11267 (set_attr "mode" "<MODE>")])
11269 (define_insn "*<code>extendsfdf2"
11270 [(set (match_operand:DF 0 "register_operand" "=f")
11271 (absneg:DF (float_extend:DF
11272 (match_operand:SF 1 "register_operand" "0"))))]
11273 "TARGET_80387 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)"
11275 [(set_attr "type" "fsgn")
11276 (set_attr "mode" "DF")])
11278 (define_insn "*<code>extendsfxf2"
11279 [(set (match_operand:XF 0 "register_operand" "=f")
11280 (absneg:XF (float_extend:XF
11281 (match_operand:SF 1 "register_operand" "0"))))]
11284 [(set_attr "type" "fsgn")
11285 (set_attr "mode" "XF")])
11287 (define_insn "*<code>extenddfxf2"
11288 [(set (match_operand:XF 0 "register_operand" "=f")
11289 (absneg:XF (float_extend:XF
11290 (match_operand:DF 1 "register_operand" "0"))))]
11293 [(set_attr "type" "fsgn")
11294 (set_attr "mode" "XF")])
11296 ;; Copysign instructions
11298 (define_mode_iterator CSGNMODE [SF DF TF])
11299 (define_mode_attr CSGNVMODE [(SF "V4SF") (DF "V2DF") (TF "TF")])
11301 (define_expand "copysign<mode>3"
11302 [(match_operand:CSGNMODE 0 "register_operand" "")
11303 (match_operand:CSGNMODE 1 "nonmemory_operand" "")
11304 (match_operand:CSGNMODE 2 "register_operand" "")]
11305 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11306 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11308 ix86_expand_copysign (operands);
11312 (define_insn_and_split "copysign<mode>3_const"
11313 [(set (match_operand:CSGNMODE 0 "register_operand" "=x")
11315 [(match_operand:<CSGNVMODE> 1 "vector_move_operand" "xmC")
11316 (match_operand:CSGNMODE 2 "register_operand" "0")
11317 (match_operand:<CSGNVMODE> 3 "nonimmediate_operand" "xm")]
11319 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11320 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11322 "&& reload_completed"
11325 ix86_split_copysign_const (operands);
11329 (define_insn "copysign<mode>3_var"
11330 [(set (match_operand:CSGNMODE 0 "register_operand" "=x,x,x,x,x")
11332 [(match_operand:CSGNMODE 2 "register_operand" "x,0,0,x,x")
11333 (match_operand:CSGNMODE 3 "register_operand" "1,1,x,1,x")
11334 (match_operand:<CSGNVMODE> 4 "nonimmediate_operand" "X,xm,xm,0,0")
11335 (match_operand:<CSGNVMODE> 5 "nonimmediate_operand" "0,xm,1,xm,1")]
11337 (clobber (match_scratch:<CSGNVMODE> 1 "=x,x,x,x,x"))]
11338 "(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11339 || (TARGET_SSE2 && (<MODE>mode == TFmode))"
11343 [(set (match_operand:CSGNMODE 0 "register_operand" "")
11345 [(match_operand:CSGNMODE 2 "register_operand" "")
11346 (match_operand:CSGNMODE 3 "register_operand" "")
11347 (match_operand:<CSGNVMODE> 4 "" "")
11348 (match_operand:<CSGNVMODE> 5 "" "")]
11350 (clobber (match_scratch:<CSGNVMODE> 1 ""))]
11351 "((SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
11352 || (TARGET_SSE2 && (<MODE>mode == TFmode)))
11353 && reload_completed"
11356 ix86_split_copysign_var (operands);
11360 ;; One complement instructions
11362 (define_expand "one_cmpldi2"
11363 [(set (match_operand:DI 0 "nonimmediate_operand" "")
11364 (not:DI (match_operand:DI 1 "nonimmediate_operand" "")))]
11366 "ix86_expand_unary_operator (NOT, DImode, operands); DONE;")
11368 (define_insn "*one_cmpldi2_1_rex64"
11369 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11370 (not:DI (match_operand:DI 1 "nonimmediate_operand" "0")))]
11371 "TARGET_64BIT && ix86_unary_operator_ok (NOT, DImode, operands)"
11373 [(set_attr "type" "negnot")
11374 (set_attr "mode" "DI")])
11376 (define_insn "*one_cmpldi2_2_rex64"
11377 [(set (reg FLAGS_REG)
11378 (compare (not:DI (match_operand:DI 1 "nonimmediate_operand" "0"))
11380 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11381 (not:DI (match_dup 1)))]
11382 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11383 && ix86_unary_operator_ok (NOT, DImode, operands)"
11385 [(set_attr "type" "alu1")
11386 (set_attr "mode" "DI")])
11389 [(set (match_operand 0 "flags_reg_operand" "")
11390 (match_operator 2 "compare_operator"
11391 [(not:DI (match_operand:DI 3 "nonimmediate_operand" ""))
11393 (set (match_operand:DI 1 "nonimmediate_operand" "")
11394 (not:DI (match_dup 3)))]
11395 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)"
11396 [(parallel [(set (match_dup 0)
11398 [(xor:DI (match_dup 3) (const_int -1))
11401 (xor:DI (match_dup 3) (const_int -1)))])]
11404 (define_expand "one_cmplsi2"
11405 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11406 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
11408 "ix86_expand_unary_operator (NOT, SImode, operands); DONE;")
11410 (define_insn "*one_cmplsi2_1"
11411 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11412 (not:SI (match_operand:SI 1 "nonimmediate_operand" "0")))]
11413 "ix86_unary_operator_ok (NOT, SImode, operands)"
11415 [(set_attr "type" "negnot")
11416 (set_attr "mode" "SI")])
11418 ;; ??? Currently never generated - xor is used instead.
11419 (define_insn "*one_cmplsi2_1_zext"
11420 [(set (match_operand:DI 0 "register_operand" "=r")
11421 (zero_extend:DI (not:SI (match_operand:SI 1 "register_operand" "0"))))]
11422 "TARGET_64BIT && ix86_unary_operator_ok (NOT, SImode, operands)"
11424 [(set_attr "type" "negnot")
11425 (set_attr "mode" "SI")])
11427 (define_insn "*one_cmplsi2_2"
11428 [(set (reg FLAGS_REG)
11429 (compare (not:SI (match_operand:SI 1 "nonimmediate_operand" "0"))
11431 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
11432 (not:SI (match_dup 1)))]
11433 "ix86_match_ccmode (insn, CCNOmode)
11434 && ix86_unary_operator_ok (NOT, SImode, operands)"
11436 [(set_attr "type" "alu1")
11437 (set_attr "mode" "SI")])
11440 [(set (match_operand 0 "flags_reg_operand" "")
11441 (match_operator 2 "compare_operator"
11442 [(not:SI (match_operand:SI 3 "nonimmediate_operand" ""))
11444 (set (match_operand:SI 1 "nonimmediate_operand" "")
11445 (not:SI (match_dup 3)))]
11446 "ix86_match_ccmode (insn, CCNOmode)"
11447 [(parallel [(set (match_dup 0)
11448 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11451 (xor:SI (match_dup 3) (const_int -1)))])]
11454 ;; ??? Currently never generated - xor is used instead.
11455 (define_insn "*one_cmplsi2_2_zext"
11456 [(set (reg FLAGS_REG)
11457 (compare (not:SI (match_operand:SI 1 "register_operand" "0"))
11459 (set (match_operand:DI 0 "register_operand" "=r")
11460 (zero_extend:DI (not:SI (match_dup 1))))]
11461 "TARGET_64BIT && ix86_match_ccmode (insn, CCNOmode)
11462 && ix86_unary_operator_ok (NOT, SImode, operands)"
11464 [(set_attr "type" "alu1")
11465 (set_attr "mode" "SI")])
11468 [(set (match_operand 0 "flags_reg_operand" "")
11469 (match_operator 2 "compare_operator"
11470 [(not:SI (match_operand:SI 3 "register_operand" ""))
11472 (set (match_operand:DI 1 "register_operand" "")
11473 (zero_extend:DI (not:SI (match_dup 3))))]
11474 "ix86_match_ccmode (insn, CCNOmode)"
11475 [(parallel [(set (match_dup 0)
11476 (match_op_dup 2 [(xor:SI (match_dup 3) (const_int -1))
11479 (zero_extend:DI (xor:SI (match_dup 3) (const_int -1))))])]
11482 (define_expand "one_cmplhi2"
11483 [(set (match_operand:HI 0 "nonimmediate_operand" "")
11484 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
11485 "TARGET_HIMODE_MATH"
11486 "ix86_expand_unary_operator (NOT, HImode, operands); DONE;")
11488 (define_insn "*one_cmplhi2_1"
11489 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11490 (not:HI (match_operand:HI 1 "nonimmediate_operand" "0")))]
11491 "ix86_unary_operator_ok (NOT, HImode, operands)"
11493 [(set_attr "type" "negnot")
11494 (set_attr "mode" "HI")])
11496 (define_insn "*one_cmplhi2_2"
11497 [(set (reg FLAGS_REG)
11498 (compare (not:HI (match_operand:HI 1 "nonimmediate_operand" "0"))
11500 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
11501 (not:HI (match_dup 1)))]
11502 "ix86_match_ccmode (insn, CCNOmode)
11503 && ix86_unary_operator_ok (NEG, HImode, operands)"
11505 [(set_attr "type" "alu1")
11506 (set_attr "mode" "HI")])
11509 [(set (match_operand 0 "flags_reg_operand" "")
11510 (match_operator 2 "compare_operator"
11511 [(not:HI (match_operand:HI 3 "nonimmediate_operand" ""))
11513 (set (match_operand:HI 1 "nonimmediate_operand" "")
11514 (not:HI (match_dup 3)))]
11515 "ix86_match_ccmode (insn, CCNOmode)"
11516 [(parallel [(set (match_dup 0)
11517 (match_op_dup 2 [(xor:HI (match_dup 3) (const_int -1))
11520 (xor:HI (match_dup 3) (const_int -1)))])]
11523 ;; %%% Potential partial reg stall on alternative 1. What to do?
11524 (define_expand "one_cmplqi2"
11525 [(set (match_operand:QI 0 "nonimmediate_operand" "")
11526 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
11527 "TARGET_QIMODE_MATH"
11528 "ix86_expand_unary_operator (NOT, QImode, operands); DONE;")
11530 (define_insn "*one_cmplqi2_1"
11531 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
11532 (not:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")))]
11533 "ix86_unary_operator_ok (NOT, QImode, operands)"
11537 [(set_attr "type" "negnot")
11538 (set_attr "mode" "QI,SI")])
11540 (define_insn "*one_cmplqi2_2"
11541 [(set (reg FLAGS_REG)
11542 (compare (not:QI (match_operand:QI 1 "nonimmediate_operand" "0"))
11544 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
11545 (not:QI (match_dup 1)))]
11546 "ix86_match_ccmode (insn, CCNOmode)
11547 && ix86_unary_operator_ok (NOT, QImode, operands)"
11549 [(set_attr "type" "alu1")
11550 (set_attr "mode" "QI")])
11553 [(set (match_operand 0 "flags_reg_operand" "")
11554 (match_operator 2 "compare_operator"
11555 [(not:QI (match_operand:QI 3 "nonimmediate_operand" ""))
11557 (set (match_operand:QI 1 "nonimmediate_operand" "")
11558 (not:QI (match_dup 3)))]
11559 "ix86_match_ccmode (insn, CCNOmode)"
11560 [(parallel [(set (match_dup 0)
11561 (match_op_dup 2 [(xor:QI (match_dup 3) (const_int -1))
11564 (xor:QI (match_dup 3) (const_int -1)))])]
11567 ;; Arithmetic shift instructions
11569 ;; DImode shifts are implemented using the i386 "shift double" opcode,
11570 ;; which is written as "sh[lr]d[lw] imm,reg,reg/mem". If the shift count
11571 ;; is variable, then the count is in %cl and the "imm" operand is dropped
11572 ;; from the assembler input.
11574 ;; This instruction shifts the target reg/mem as usual, but instead of
11575 ;; shifting in zeros, bits are shifted in from reg operand. If the insn
11576 ;; is a left shift double, bits are taken from the high order bits of
11577 ;; reg, else if the insn is a shift right double, bits are taken from the
11578 ;; low order bits of reg. So if %eax is "1234" and %edx is "5678",
11579 ;; "shldl $8,%edx,%eax" leaves %edx unchanged and sets %eax to "2345".
11581 ;; Since sh[lr]d does not change the `reg' operand, that is done
11582 ;; separately, making all shifts emit pairs of shift double and normal
11583 ;; shift. Since sh[lr]d does not shift more than 31 bits, and we wish to
11584 ;; support a 63 bit shift, each shift where the count is in a reg expands
11585 ;; to a pair of shifts, a branch, a shift by 32 and a label.
11587 ;; If the shift count is a constant, we need never emit more than one
11588 ;; shift pair, instead using moves and sign extension for counts greater
11591 (define_expand "ashlti3"
11592 [(set (match_operand:TI 0 "register_operand" "")
11593 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "")
11594 (match_operand:QI 2 "nonmemory_operand" "")))]
11596 "ix86_expand_binary_operator (ASHIFT, TImode, operands); DONE;")
11598 ;; This pattern must be defined before *ashlti3_1 to prevent
11599 ;; combine pass from converting sse2_ashlti3 to *ashlti3_1.
11601 (define_insn "*avx_ashlti3"
11602 [(set (match_operand:TI 0 "register_operand" "=x")
11603 (ashift:TI (match_operand:TI 1 "register_operand" "x")
11604 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11607 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11608 return "vpslldq\t{%2, %1, %0|%0, %1, %2}";
11610 [(set_attr "type" "sseishft")
11611 (set_attr "prefix" "vex")
11612 (set_attr "length_immediate" "1")
11613 (set_attr "mode" "TI")])
11615 (define_insn "sse2_ashlti3"
11616 [(set (match_operand:TI 0 "register_operand" "=x")
11617 (ashift:TI (match_operand:TI 1 "register_operand" "0")
11618 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
11621 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
11622 return "pslldq\t{%2, %0|%0, %2}";
11624 [(set_attr "type" "sseishft")
11625 (set_attr "prefix_data16" "1")
11626 (set_attr "length_immediate" "1")
11627 (set_attr "mode" "TI")])
11629 (define_insn "*ashlti3_1"
11630 [(set (match_operand:TI 0 "register_operand" "=&r,r")
11631 (ashift:TI (match_operand:TI 1 "reg_or_pm1_operand" "n,0")
11632 (match_operand:QI 2 "nonmemory_operand" "Oc,Oc")))
11633 (clobber (reg:CC FLAGS_REG))]
11636 [(set_attr "type" "multi")])
11639 [(match_scratch:DI 3 "r")
11640 (parallel [(set (match_operand:TI 0 "register_operand" "")
11641 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11642 (match_operand:QI 2 "nonmemory_operand" "")))
11643 (clobber (reg:CC FLAGS_REG))])
11647 "ix86_split_ashl (operands, operands[3], TImode); DONE;")
11650 [(set (match_operand:TI 0 "register_operand" "")
11651 (ashift:TI (match_operand:TI 1 "nonmemory_operand" "")
11652 (match_operand:QI 2 "nonmemory_operand" "")))
11653 (clobber (reg:CC FLAGS_REG))]
11654 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11655 ? epilogue_completed : reload_completed)"
11657 "ix86_split_ashl (operands, NULL_RTX, TImode); DONE;")
11659 (define_insn "x86_64_shld"
11660 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
11661 (ior:DI (ashift:DI (match_dup 0)
11662 (match_operand:QI 2 "nonmemory_operand" "Jc"))
11663 (lshiftrt:DI (match_operand:DI 1 "register_operand" "r")
11664 (minus:QI (const_int 64) (match_dup 2)))))
11665 (clobber (reg:CC FLAGS_REG))]
11667 "shld{q}\t{%s2%1, %0|%0, %1, %2}"
11668 [(set_attr "type" "ishift")
11669 (set_attr "prefix_0f" "1")
11670 (set_attr "mode" "DI")
11671 (set_attr "athlon_decode" "vector")
11672 (set_attr "amdfam10_decode" "vector")])
11674 (define_expand "x86_64_shift_adj_1"
11675 [(set (reg:CCZ FLAGS_REG)
11676 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11679 (set (match_operand:DI 0 "register_operand" "")
11680 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11681 (match_operand:DI 1 "register_operand" "")
11684 (if_then_else:DI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11685 (match_operand:DI 3 "register_operand" "r")
11690 (define_expand "x86_64_shift_adj_2"
11691 [(use (match_operand:DI 0 "register_operand" ""))
11692 (use (match_operand:DI 1 "register_operand" ""))
11693 (use (match_operand:QI 2 "register_operand" ""))]
11696 rtx label = gen_label_rtx ();
11699 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
11701 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11702 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11703 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11704 gen_rtx_LABEL_REF (VOIDmode, label),
11706 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11707 JUMP_LABEL (tmp) = label;
11709 emit_move_insn (operands[0], operands[1]);
11710 ix86_expand_clear (operands[1]);
11712 emit_label (label);
11713 LABEL_NUSES (label) = 1;
11718 (define_expand "ashldi3"
11719 [(set (match_operand:DI 0 "shiftdi_operand" "")
11720 (ashift:DI (match_operand:DI 1 "ashldi_input_operand" "")
11721 (match_operand:QI 2 "nonmemory_operand" "")))]
11723 "ix86_expand_binary_operator (ASHIFT, DImode, operands); DONE;")
11725 (define_insn "*ashldi3_1_rex64"
11726 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,r")
11727 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0,l")
11728 (match_operand:QI 2 "nonmemory_operand" "cJ,M")))
11729 (clobber (reg:CC FLAGS_REG))]
11730 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11732 switch (get_attr_type (insn))
11735 gcc_assert (operands[2] == const1_rtx);
11736 gcc_assert (rtx_equal_p (operands[0], operands[1]));
11737 return "add{q}\t%0, %0";
11740 gcc_assert (CONST_INT_P (operands[2]));
11741 gcc_assert ((unsigned HOST_WIDE_INT) INTVAL (operands[2]) <= 3);
11742 operands[1] = gen_rtx_MULT (DImode, operands[1],
11743 GEN_INT (1 << INTVAL (operands[2])));
11744 return "lea{q}\t{%a1, %0|%0, %a1}";
11747 if (REG_P (operands[2]))
11748 return "sal{q}\t{%b2, %0|%0, %b2}";
11749 else if (operands[2] == const1_rtx
11750 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11751 return "sal{q}\t%0";
11753 return "sal{q}\t{%2, %0|%0, %2}";
11756 [(set (attr "type")
11757 (cond [(eq_attr "alternative" "1")
11758 (const_string "lea")
11759 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11761 (match_operand 0 "register_operand" ""))
11762 (match_operand 2 "const1_operand" ""))
11763 (const_string "alu")
11765 (const_string "ishift")))
11766 (set (attr "length_immediate")
11768 (ior (eq_attr "type" "alu")
11769 (and (eq_attr "type" "ishift")
11770 (and (match_operand 2 "const1_operand" "")
11771 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11774 (const_string "*")))
11775 (set_attr "mode" "DI")])
11777 ;; Convert lea to the lea pattern to avoid flags dependency.
11779 [(set (match_operand:DI 0 "register_operand" "")
11780 (ashift:DI (match_operand:DI 1 "index_register_operand" "")
11781 (match_operand:QI 2 "immediate_operand" "")))
11782 (clobber (reg:CC FLAGS_REG))]
11783 "TARGET_64BIT && reload_completed
11784 && true_regnum (operands[0]) != true_regnum (operands[1])"
11785 [(set (match_dup 0)
11786 (mult:DI (match_dup 1)
11788 "operands[2] = gen_int_mode (1 << INTVAL (operands[2]), DImode);")
11790 ;; This pattern can't accept a variable shift count, since shifts by
11791 ;; zero don't affect the flags. We assume that shifts by constant
11792 ;; zero are optimized away.
11793 (define_insn "*ashldi3_cmp_rex64"
11794 [(set (reg FLAGS_REG)
11796 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11797 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11799 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
11800 (ashift:DI (match_dup 1) (match_dup 2)))]
11802 && (optimize_function_for_size_p (cfun)
11803 || !TARGET_PARTIAL_FLAG_REG_STALL
11804 || (operands[2] == const1_rtx
11806 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
11807 && ix86_match_ccmode (insn, CCGOCmode)
11808 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11810 switch (get_attr_type (insn))
11813 gcc_assert (operands[2] == const1_rtx);
11814 return "add{q}\t%0, %0";
11817 if (REG_P (operands[2]))
11818 return "sal{q}\t{%b2, %0|%0, %b2}";
11819 else if (operands[2] == const1_rtx
11820 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11821 return "sal{q}\t%0";
11823 return "sal{q}\t{%2, %0|%0, %2}";
11826 [(set (attr "type")
11827 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11829 (match_operand 0 "register_operand" ""))
11830 (match_operand 2 "const1_operand" ""))
11831 (const_string "alu")
11833 (const_string "ishift")))
11834 (set (attr "length_immediate")
11836 (ior (eq_attr "type" "alu")
11837 (and (eq_attr "type" "ishift")
11838 (and (match_operand 2 "const1_operand" "")
11839 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11842 (const_string "*")))
11843 (set_attr "mode" "DI")])
11845 (define_insn "*ashldi3_cconly_rex64"
11846 [(set (reg FLAGS_REG)
11848 (ashift:DI (match_operand:DI 1 "nonimmediate_operand" "0")
11849 (match_operand:QI 2 "const_1_to_63_operand" "J"))
11851 (clobber (match_scratch:DI 0 "=r"))]
11853 && (optimize_function_for_size_p (cfun)
11854 || !TARGET_PARTIAL_FLAG_REG_STALL
11855 || (operands[2] == const1_rtx
11857 || TARGET_DOUBLE_WITH_ADD)))
11858 && ix86_match_ccmode (insn, CCGOCmode)
11859 && ix86_binary_operator_ok (ASHIFT, DImode, operands)"
11861 switch (get_attr_type (insn))
11864 gcc_assert (operands[2] == const1_rtx);
11865 return "add{q}\t%0, %0";
11868 if (REG_P (operands[2]))
11869 return "sal{q}\t{%b2, %0|%0, %b2}";
11870 else if (operands[2] == const1_rtx
11871 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
11872 return "sal{q}\t%0";
11874 return "sal{q}\t{%2, %0|%0, %2}";
11877 [(set (attr "type")
11878 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
11880 (match_operand 0 "register_operand" ""))
11881 (match_operand 2 "const1_operand" ""))
11882 (const_string "alu")
11884 (const_string "ishift")))
11885 (set (attr "length_immediate")
11887 (ior (eq_attr "type" "alu")
11888 (and (eq_attr "type" "ishift")
11889 (and (match_operand 2 "const1_operand" "")
11890 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
11893 (const_string "*")))
11894 (set_attr "mode" "DI")])
11896 (define_insn "*ashldi3_1"
11897 [(set (match_operand:DI 0 "register_operand" "=&r,r")
11898 (ashift:DI (match_operand:DI 1 "reg_or_pm1_operand" "n,0")
11899 (match_operand:QI 2 "nonmemory_operand" "Jc,Jc")))
11900 (clobber (reg:CC FLAGS_REG))]
11903 [(set_attr "type" "multi")])
11905 ;; By default we don't ask for a scratch register, because when DImode
11906 ;; values are manipulated, registers are already at a premium. But if
11907 ;; we have one handy, we won't turn it away.
11909 [(match_scratch:SI 3 "r")
11910 (parallel [(set (match_operand:DI 0 "register_operand" "")
11911 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11912 (match_operand:QI 2 "nonmemory_operand" "")))
11913 (clobber (reg:CC FLAGS_REG))])
11915 "!TARGET_64BIT && TARGET_CMOVE"
11917 "ix86_split_ashl (operands, operands[3], DImode); DONE;")
11920 [(set (match_operand:DI 0 "register_operand" "")
11921 (ashift:DI (match_operand:DI 1 "nonmemory_operand" "")
11922 (match_operand:QI 2 "nonmemory_operand" "")))
11923 (clobber (reg:CC FLAGS_REG))]
11924 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
11925 ? epilogue_completed : reload_completed)"
11927 "ix86_split_ashl (operands, NULL_RTX, DImode); DONE;")
11929 (define_insn "x86_shld"
11930 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
11931 (ior:SI (ashift:SI (match_dup 0)
11932 (match_operand:QI 2 "nonmemory_operand" "Ic"))
11933 (lshiftrt:SI (match_operand:SI 1 "register_operand" "r")
11934 (minus:QI (const_int 32) (match_dup 2)))))
11935 (clobber (reg:CC FLAGS_REG))]
11937 "shld{l}\t{%s2%1, %0|%0, %1, %2}"
11938 [(set_attr "type" "ishift")
11939 (set_attr "prefix_0f" "1")
11940 (set_attr "mode" "SI")
11941 (set_attr "pent_pair" "np")
11942 (set_attr "athlon_decode" "vector")
11943 (set_attr "amdfam10_decode" "vector")])
11945 (define_expand "x86_shift_adj_1"
11946 [(set (reg:CCZ FLAGS_REG)
11947 (compare:CCZ (and:QI (match_operand:QI 2 "register_operand" "")
11950 (set (match_operand:SI 0 "register_operand" "")
11951 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11952 (match_operand:SI 1 "register_operand" "")
11955 (if_then_else:SI (ne (reg:CCZ FLAGS_REG) (const_int 0))
11956 (match_operand:SI 3 "register_operand" "r")
11961 (define_expand "x86_shift_adj_2"
11962 [(use (match_operand:SI 0 "register_operand" ""))
11963 (use (match_operand:SI 1 "register_operand" ""))
11964 (use (match_operand:QI 2 "register_operand" ""))]
11967 rtx label = gen_label_rtx ();
11970 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
11972 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
11973 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
11974 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
11975 gen_rtx_LABEL_REF (VOIDmode, label),
11977 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
11978 JUMP_LABEL (tmp) = label;
11980 emit_move_insn (operands[0], operands[1]);
11981 ix86_expand_clear (operands[1]);
11983 emit_label (label);
11984 LABEL_NUSES (label) = 1;
11989 (define_expand "ashlsi3"
11990 [(set (match_operand:SI 0 "nonimmediate_operand" "")
11991 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "")
11992 (match_operand:QI 2 "nonmemory_operand" "")))]
11994 "ix86_expand_binary_operator (ASHIFT, SImode, operands); DONE;")
11996 (define_insn "*ashlsi3_1"
11997 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,r")
11998 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0,l")
11999 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
12000 (clobber (reg:CC FLAGS_REG))]
12001 "ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12003 switch (get_attr_type (insn))
12006 gcc_assert (operands[2] == const1_rtx);
12007 gcc_assert (rtx_equal_p (operands[0], operands[1]));
12008 return "add{l}\t%0, %0";
12014 if (REG_P (operands[2]))
12015 return "sal{l}\t{%b2, %0|%0, %b2}";
12016 else if (operands[2] == const1_rtx
12017 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12018 return "sal{l}\t%0";
12020 return "sal{l}\t{%2, %0|%0, %2}";
12023 [(set (attr "type")
12024 (cond [(eq_attr "alternative" "1")
12025 (const_string "lea")
12026 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12028 (match_operand 0 "register_operand" ""))
12029 (match_operand 2 "const1_operand" ""))
12030 (const_string "alu")
12032 (const_string "ishift")))
12033 (set (attr "length_immediate")
12035 (ior (eq_attr "type" "alu")
12036 (and (eq_attr "type" "ishift")
12037 (and (match_operand 2 "const1_operand" "")
12038 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12041 (const_string "*")))
12042 (set_attr "mode" "SI")])
12044 ;; Convert lea to the lea pattern to avoid flags dependency.
12046 [(set (match_operand 0 "register_operand" "")
12047 (ashift (match_operand 1 "index_register_operand" "")
12048 (match_operand:QI 2 "const_int_operand" "")))
12049 (clobber (reg:CC FLAGS_REG))]
12051 && true_regnum (operands[0]) != true_regnum (operands[1])
12052 && GET_MODE_SIZE (GET_MODE (operands[0])) <= 4"
12056 enum machine_mode mode = GET_MODE (operands[0]);
12058 if (GET_MODE_SIZE (mode) < 4)
12059 operands[0] = gen_lowpart (SImode, operands[0]);
12061 operands[1] = gen_lowpart (Pmode, operands[1]);
12062 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
12064 pat = gen_rtx_MULT (Pmode, operands[1], operands[2]);
12065 if (Pmode != SImode)
12066 pat = gen_rtx_SUBREG (SImode, pat, 0);
12067 emit_insn (gen_rtx_SET (VOIDmode, operands[0], pat));
12071 ;; Rare case of shifting RSP is handled by generating move and shift
12073 [(set (match_operand 0 "register_operand" "")
12074 (ashift (match_operand 1 "register_operand" "")
12075 (match_operand:QI 2 "const_int_operand" "")))
12076 (clobber (reg:CC FLAGS_REG))]
12078 && true_regnum (operands[0]) != true_regnum (operands[1])"
12082 emit_move_insn (operands[0], operands[1]);
12083 pat = gen_rtx_SET (VOIDmode, operands[0],
12084 gen_rtx_ASHIFT (GET_MODE (operands[0]),
12085 operands[0], operands[2]));
12086 clob = gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (CCmode, FLAGS_REG));
12087 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, pat, clob)));
12091 (define_insn "*ashlsi3_1_zext"
12092 [(set (match_operand:DI 0 "register_operand" "=r,r")
12093 (zero_extend:DI (ashift:SI (match_operand:SI 1 "register_operand" "0,l")
12094 (match_operand:QI 2 "nonmemory_operand" "cI,M"))))
12095 (clobber (reg:CC FLAGS_REG))]
12096 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12098 switch (get_attr_type (insn))
12101 gcc_assert (operands[2] == const1_rtx);
12102 return "add{l}\t%k0, %k0";
12108 if (REG_P (operands[2]))
12109 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12110 else if (operands[2] == const1_rtx
12111 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12112 return "sal{l}\t%k0";
12114 return "sal{l}\t{%2, %k0|%k0, %2}";
12117 [(set (attr "type")
12118 (cond [(eq_attr "alternative" "1")
12119 (const_string "lea")
12120 (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12122 (match_operand 2 "const1_operand" ""))
12123 (const_string "alu")
12125 (const_string "ishift")))
12126 (set (attr "length_immediate")
12128 (ior (eq_attr "type" "alu")
12129 (and (eq_attr "type" "ishift")
12130 (and (match_operand 2 "const1_operand" "")
12131 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12134 (const_string "*")))
12135 (set_attr "mode" "SI")])
12137 ;; Convert lea to the lea pattern to avoid flags dependency.
12139 [(set (match_operand:DI 0 "register_operand" "")
12140 (zero_extend:DI (ashift (match_operand 1 "register_operand" "")
12141 (match_operand:QI 2 "const_int_operand" ""))))
12142 (clobber (reg:CC FLAGS_REG))]
12143 "TARGET_64BIT && reload_completed
12144 && true_regnum (operands[0]) != true_regnum (operands[1])"
12145 [(set (match_dup 0) (zero_extend:DI
12146 (subreg:SI (mult:SI (match_dup 1)
12147 (match_dup 2)) 0)))]
12149 operands[1] = gen_lowpart (Pmode, operands[1]);
12150 operands[2] = gen_int_mode (1 << INTVAL (operands[2]), Pmode);
12153 ;; This pattern can't accept a variable shift count, since shifts by
12154 ;; zero don't affect the flags. We assume that shifts by constant
12155 ;; zero are optimized away.
12156 (define_insn "*ashlsi3_cmp"
12157 [(set (reg FLAGS_REG)
12159 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12160 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12162 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
12163 (ashift:SI (match_dup 1) (match_dup 2)))]
12164 "(optimize_function_for_size_p (cfun)
12165 || !TARGET_PARTIAL_FLAG_REG_STALL
12166 || (operands[2] == const1_rtx
12168 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12169 && ix86_match_ccmode (insn, CCGOCmode)
12170 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12172 switch (get_attr_type (insn))
12175 gcc_assert (operands[2] == const1_rtx);
12176 return "add{l}\t%0, %0";
12179 if (REG_P (operands[2]))
12180 return "sal{l}\t{%b2, %0|%0, %b2}";
12181 else if (operands[2] == const1_rtx
12182 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12183 return "sal{l}\t%0";
12185 return "sal{l}\t{%2, %0|%0, %2}";
12188 [(set (attr "type")
12189 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12191 (match_operand 0 "register_operand" ""))
12192 (match_operand 2 "const1_operand" ""))
12193 (const_string "alu")
12195 (const_string "ishift")))
12196 (set (attr "length_immediate")
12198 (ior (eq_attr "type" "alu")
12199 (and (eq_attr "type" "ishift")
12200 (and (match_operand 2 "const1_operand" "")
12201 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12204 (const_string "*")))
12205 (set_attr "mode" "SI")])
12207 (define_insn "*ashlsi3_cconly"
12208 [(set (reg FLAGS_REG)
12210 (ashift:SI (match_operand:SI 1 "nonimmediate_operand" "0")
12211 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12213 (clobber (match_scratch:SI 0 "=r"))]
12214 "(optimize_function_for_size_p (cfun)
12215 || !TARGET_PARTIAL_FLAG_REG_STALL
12216 || (operands[2] == const1_rtx
12218 || TARGET_DOUBLE_WITH_ADD)))
12219 && ix86_match_ccmode (insn, CCGOCmode)
12220 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12222 switch (get_attr_type (insn))
12225 gcc_assert (operands[2] == const1_rtx);
12226 return "add{l}\t%0, %0";
12229 if (REG_P (operands[2]))
12230 return "sal{l}\t{%b2, %0|%0, %b2}";
12231 else if (operands[2] == const1_rtx
12232 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12233 return "sal{l}\t%0";
12235 return "sal{l}\t{%2, %0|%0, %2}";
12238 [(set (attr "type")
12239 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12241 (match_operand 0 "register_operand" ""))
12242 (match_operand 2 "const1_operand" ""))
12243 (const_string "alu")
12245 (const_string "ishift")))
12246 (set (attr "length_immediate")
12248 (ior (eq_attr "type" "alu")
12249 (and (eq_attr "type" "ishift")
12250 (and (match_operand 2 "const1_operand" "")
12251 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12254 (const_string "*")))
12255 (set_attr "mode" "SI")])
12257 (define_insn "*ashlsi3_cmp_zext"
12258 [(set (reg FLAGS_REG)
12260 (ashift:SI (match_operand:SI 1 "register_operand" "0")
12261 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12263 (set (match_operand:DI 0 "register_operand" "=r")
12264 (zero_extend:DI (ashift:SI (match_dup 1) (match_dup 2))))]
12266 && (optimize_function_for_size_p (cfun)
12267 || !TARGET_PARTIAL_FLAG_REG_STALL
12268 || (operands[2] == const1_rtx
12270 || TARGET_DOUBLE_WITH_ADD)))
12271 && ix86_match_ccmode (insn, CCGOCmode)
12272 && ix86_binary_operator_ok (ASHIFT, SImode, operands)"
12274 switch (get_attr_type (insn))
12277 gcc_assert (operands[2] == const1_rtx);
12278 return "add{l}\t%k0, %k0";
12281 if (REG_P (operands[2]))
12282 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12283 else if (operands[2] == const1_rtx
12284 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12285 return "sal{l}\t%k0";
12287 return "sal{l}\t{%2, %k0|%k0, %2}";
12290 [(set (attr "type")
12291 (cond [(and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12293 (match_operand 2 "const1_operand" ""))
12294 (const_string "alu")
12296 (const_string "ishift")))
12297 (set (attr "length_immediate")
12299 (ior (eq_attr "type" "alu")
12300 (and (eq_attr "type" "ishift")
12301 (and (match_operand 2 "const1_operand" "")
12302 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12305 (const_string "*")))
12306 (set_attr "mode" "SI")])
12308 (define_expand "ashlhi3"
12309 [(set (match_operand:HI 0 "nonimmediate_operand" "")
12310 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "")
12311 (match_operand:QI 2 "nonmemory_operand" "")))]
12312 "TARGET_HIMODE_MATH"
12313 "ix86_expand_binary_operator (ASHIFT, HImode, operands); DONE;")
12315 (define_insn "*ashlhi3_1_lea"
12316 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,r")
12317 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0,l")
12318 (match_operand:QI 2 "nonmemory_operand" "cI,M")))
12319 (clobber (reg:CC FLAGS_REG))]
12320 "!TARGET_PARTIAL_REG_STALL
12321 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12323 switch (get_attr_type (insn))
12328 gcc_assert (operands[2] == const1_rtx);
12329 return "add{w}\t%0, %0";
12332 if (REG_P (operands[2]))
12333 return "sal{w}\t{%b2, %0|%0, %b2}";
12334 else if (operands[2] == const1_rtx
12335 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12336 return "sal{w}\t%0";
12338 return "sal{w}\t{%2, %0|%0, %2}";
12341 [(set (attr "type")
12342 (cond [(eq_attr "alternative" "1")
12343 (const_string "lea")
12344 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12346 (match_operand 0 "register_operand" ""))
12347 (match_operand 2 "const1_operand" ""))
12348 (const_string "alu")
12350 (const_string "ishift")))
12351 (set (attr "length_immediate")
12353 (ior (eq_attr "type" "alu")
12354 (and (eq_attr "type" "ishift")
12355 (and (match_operand 2 "const1_operand" "")
12356 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12359 (const_string "*")))
12360 (set_attr "mode" "HI,SI")])
12362 (define_insn "*ashlhi3_1"
12363 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12364 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12365 (match_operand:QI 2 "nonmemory_operand" "cI")))
12366 (clobber (reg:CC FLAGS_REG))]
12367 "TARGET_PARTIAL_REG_STALL
12368 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12370 switch (get_attr_type (insn))
12373 gcc_assert (operands[2] == const1_rtx);
12374 return "add{w}\t%0, %0";
12377 if (REG_P (operands[2]))
12378 return "sal{w}\t{%b2, %0|%0, %b2}";
12379 else if (operands[2] == const1_rtx
12380 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12381 return "sal{w}\t%0";
12383 return "sal{w}\t{%2, %0|%0, %2}";
12386 [(set (attr "type")
12387 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12389 (match_operand 0 "register_operand" ""))
12390 (match_operand 2 "const1_operand" ""))
12391 (const_string "alu")
12393 (const_string "ishift")))
12394 (set (attr "length_immediate")
12396 (ior (eq_attr "type" "alu")
12397 (and (eq_attr "type" "ishift")
12398 (and (match_operand 2 "const1_operand" "")
12399 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12402 (const_string "*")))
12403 (set_attr "mode" "HI")])
12405 ;; This pattern can't accept a variable shift count, since shifts by
12406 ;; zero don't affect the flags. We assume that shifts by constant
12407 ;; zero are optimized away.
12408 (define_insn "*ashlhi3_cmp"
12409 [(set (reg FLAGS_REG)
12411 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12412 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12414 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
12415 (ashift:HI (match_dup 1) (match_dup 2)))]
12416 "(optimize_function_for_size_p (cfun)
12417 || !TARGET_PARTIAL_FLAG_REG_STALL
12418 || (operands[2] == const1_rtx
12420 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12421 && ix86_match_ccmode (insn, CCGOCmode)
12422 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12424 switch (get_attr_type (insn))
12427 gcc_assert (operands[2] == const1_rtx);
12428 return "add{w}\t%0, %0";
12431 if (REG_P (operands[2]))
12432 return "sal{w}\t{%b2, %0|%0, %b2}";
12433 else if (operands[2] == const1_rtx
12434 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12435 return "sal{w}\t%0";
12437 return "sal{w}\t{%2, %0|%0, %2}";
12440 [(set (attr "type")
12441 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12443 (match_operand 0 "register_operand" ""))
12444 (match_operand 2 "const1_operand" ""))
12445 (const_string "alu")
12447 (const_string "ishift")))
12448 (set (attr "length_immediate")
12450 (ior (eq_attr "type" "alu")
12451 (and (eq_attr "type" "ishift")
12452 (and (match_operand 2 "const1_operand" "")
12453 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12456 (const_string "*")))
12457 (set_attr "mode" "HI")])
12459 (define_insn "*ashlhi3_cconly"
12460 [(set (reg FLAGS_REG)
12462 (ashift:HI (match_operand:HI 1 "nonimmediate_operand" "0")
12463 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12465 (clobber (match_scratch:HI 0 "=r"))]
12466 "(optimize_function_for_size_p (cfun)
12467 || !TARGET_PARTIAL_FLAG_REG_STALL
12468 || (operands[2] == const1_rtx
12470 || TARGET_DOUBLE_WITH_ADD)))
12471 && ix86_match_ccmode (insn, CCGOCmode)
12472 && ix86_binary_operator_ok (ASHIFT, HImode, operands)"
12474 switch (get_attr_type (insn))
12477 gcc_assert (operands[2] == const1_rtx);
12478 return "add{w}\t%0, %0";
12481 if (REG_P (operands[2]))
12482 return "sal{w}\t{%b2, %0|%0, %b2}";
12483 else if (operands[2] == const1_rtx
12484 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12485 return "sal{w}\t%0";
12487 return "sal{w}\t{%2, %0|%0, %2}";
12490 [(set (attr "type")
12491 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12493 (match_operand 0 "register_operand" ""))
12494 (match_operand 2 "const1_operand" ""))
12495 (const_string "alu")
12497 (const_string "ishift")))
12498 (set (attr "length_immediate")
12500 (ior (eq_attr "type" "alu")
12501 (and (eq_attr "type" "ishift")
12502 (and (match_operand 2 "const1_operand" "")
12503 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12506 (const_string "*")))
12507 (set_attr "mode" "HI")])
12509 (define_expand "ashlqi3"
12510 [(set (match_operand:QI 0 "nonimmediate_operand" "")
12511 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "")
12512 (match_operand:QI 2 "nonmemory_operand" "")))]
12513 "TARGET_QIMODE_MATH"
12514 "ix86_expand_binary_operator (ASHIFT, QImode, operands); DONE;")
12516 ;; %%% Potential partial reg stall on alternative 2. What to do?
12518 (define_insn "*ashlqi3_1_lea"
12519 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r,r")
12520 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0,l")
12521 (match_operand:QI 2 "nonmemory_operand" "cI,cI,M")))
12522 (clobber (reg:CC FLAGS_REG))]
12523 "!TARGET_PARTIAL_REG_STALL
12524 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12526 switch (get_attr_type (insn))
12531 gcc_assert (operands[2] == const1_rtx);
12532 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12533 return "add{l}\t%k0, %k0";
12535 return "add{b}\t%0, %0";
12538 if (REG_P (operands[2]))
12540 if (get_attr_mode (insn) == MODE_SI)
12541 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12543 return "sal{b}\t{%b2, %0|%0, %b2}";
12545 else if (operands[2] == const1_rtx
12546 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12548 if (get_attr_mode (insn) == MODE_SI)
12549 return "sal{l}\t%0";
12551 return "sal{b}\t%0";
12555 if (get_attr_mode (insn) == MODE_SI)
12556 return "sal{l}\t{%2, %k0|%k0, %2}";
12558 return "sal{b}\t{%2, %0|%0, %2}";
12562 [(set (attr "type")
12563 (cond [(eq_attr "alternative" "2")
12564 (const_string "lea")
12565 (and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12567 (match_operand 0 "register_operand" ""))
12568 (match_operand 2 "const1_operand" ""))
12569 (const_string "alu")
12571 (const_string "ishift")))
12572 (set (attr "length_immediate")
12574 (ior (eq_attr "type" "alu")
12575 (and (eq_attr "type" "ishift")
12576 (and (match_operand 2 "const1_operand" "")
12577 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12580 (const_string "*")))
12581 (set_attr "mode" "QI,SI,SI")])
12583 (define_insn "*ashlqi3_1"
12584 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,r")
12585 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
12586 (match_operand:QI 2 "nonmemory_operand" "cI,cI")))
12587 (clobber (reg:CC FLAGS_REG))]
12588 "TARGET_PARTIAL_REG_STALL
12589 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12591 switch (get_attr_type (insn))
12594 gcc_assert (operands[2] == const1_rtx);
12595 if (REG_P (operands[1]) && !ANY_QI_REG_P (operands[1]))
12596 return "add{l}\t%k0, %k0";
12598 return "add{b}\t%0, %0";
12601 if (REG_P (operands[2]))
12603 if (get_attr_mode (insn) == MODE_SI)
12604 return "sal{l}\t{%b2, %k0|%k0, %b2}";
12606 return "sal{b}\t{%b2, %0|%0, %b2}";
12608 else if (operands[2] == const1_rtx
12609 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12611 if (get_attr_mode (insn) == MODE_SI)
12612 return "sal{l}\t%0";
12614 return "sal{b}\t%0";
12618 if (get_attr_mode (insn) == MODE_SI)
12619 return "sal{l}\t{%2, %k0|%k0, %2}";
12621 return "sal{b}\t{%2, %0|%0, %2}";
12625 [(set (attr "type")
12626 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12628 (match_operand 0 "register_operand" ""))
12629 (match_operand 2 "const1_operand" ""))
12630 (const_string "alu")
12632 (const_string "ishift")))
12633 (set (attr "length_immediate")
12635 (ior (eq_attr "type" "alu")
12636 (and (eq_attr "type" "ishift")
12637 (and (match_operand 2 "const1_operand" "")
12638 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12641 (const_string "*")))
12642 (set_attr "mode" "QI,SI")])
12644 ;; This pattern can't accept a variable shift count, since shifts by
12645 ;; zero don't affect the flags. We assume that shifts by constant
12646 ;; zero are optimized away.
12647 (define_insn "*ashlqi3_cmp"
12648 [(set (reg FLAGS_REG)
12650 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12651 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12653 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
12654 (ashift:QI (match_dup 1) (match_dup 2)))]
12655 "(optimize_function_for_size_p (cfun)
12656 || !TARGET_PARTIAL_FLAG_REG_STALL
12657 || (operands[2] == const1_rtx
12659 || (TARGET_DOUBLE_WITH_ADD && REG_P (operands[0])))))
12660 && ix86_match_ccmode (insn, CCGOCmode)
12661 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12663 switch (get_attr_type (insn))
12666 gcc_assert (operands[2] == const1_rtx);
12667 return "add{b}\t%0, %0";
12670 if (REG_P (operands[2]))
12671 return "sal{b}\t{%b2, %0|%0, %b2}";
12672 else if (operands[2] == const1_rtx
12673 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12674 return "sal{b}\t%0";
12676 return "sal{b}\t{%2, %0|%0, %2}";
12679 [(set (attr "type")
12680 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12682 (match_operand 0 "register_operand" ""))
12683 (match_operand 2 "const1_operand" ""))
12684 (const_string "alu")
12686 (const_string "ishift")))
12687 (set (attr "length_immediate")
12689 (ior (eq_attr "type" "alu")
12690 (and (eq_attr "type" "ishift")
12691 (and (match_operand 2 "const1_operand" "")
12692 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12695 (const_string "*")))
12696 (set_attr "mode" "QI")])
12698 (define_insn "*ashlqi3_cconly"
12699 [(set (reg FLAGS_REG)
12701 (ashift:QI (match_operand:QI 1 "nonimmediate_operand" "0")
12702 (match_operand:QI 2 "const_1_to_31_operand" "I"))
12704 (clobber (match_scratch:QI 0 "=q"))]
12705 "(optimize_function_for_size_p (cfun)
12706 || !TARGET_PARTIAL_FLAG_REG_STALL
12707 || (operands[2] == const1_rtx
12709 || TARGET_DOUBLE_WITH_ADD)))
12710 && ix86_match_ccmode (insn, CCGOCmode)
12711 && ix86_binary_operator_ok (ASHIFT, QImode, operands)"
12713 switch (get_attr_type (insn))
12716 gcc_assert (operands[2] == const1_rtx);
12717 return "add{b}\t%0, %0";
12720 if (REG_P (operands[2]))
12721 return "sal{b}\t{%b2, %0|%0, %b2}";
12722 else if (operands[2] == const1_rtx
12723 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun)))
12724 return "sal{b}\t%0";
12726 return "sal{b}\t{%2, %0|%0, %2}";
12729 [(set (attr "type")
12730 (cond [(and (and (ne (symbol_ref "TARGET_DOUBLE_WITH_ADD")
12732 (match_operand 0 "register_operand" ""))
12733 (match_operand 2 "const1_operand" ""))
12734 (const_string "alu")
12736 (const_string "ishift")))
12737 (set (attr "length_immediate")
12739 (ior (eq_attr "type" "alu")
12740 (and (eq_attr "type" "ishift")
12741 (and (match_operand 2 "const1_operand" "")
12742 (ne (symbol_ref "TARGET_SHIFT1 || optimize_function_for_size_p (cfun)")
12745 (const_string "*")))
12746 (set_attr "mode" "QI")])
12748 ;; See comment above `ashldi3' about how this works.
12750 (define_expand "ashrti3"
12751 [(set (match_operand:TI 0 "register_operand" "")
12752 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12753 (match_operand:QI 2 "nonmemory_operand" "")))]
12755 "ix86_expand_binary_operator (ASHIFTRT, TImode, operands); DONE;")
12757 (define_insn "*ashrti3_1"
12758 [(set (match_operand:TI 0 "register_operand" "=r")
12759 (ashiftrt:TI (match_operand:TI 1 "register_operand" "0")
12760 (match_operand:QI 2 "nonmemory_operand" "Oc")))
12761 (clobber (reg:CC FLAGS_REG))]
12764 [(set_attr "type" "multi")])
12767 [(match_scratch:DI 3 "r")
12768 (parallel [(set (match_operand:TI 0 "register_operand" "")
12769 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12770 (match_operand:QI 2 "nonmemory_operand" "")))
12771 (clobber (reg:CC FLAGS_REG))])
12775 "ix86_split_ashr (operands, operands[3], TImode); DONE;")
12778 [(set (match_operand:TI 0 "register_operand" "")
12779 (ashiftrt:TI (match_operand:TI 1 "register_operand" "")
12780 (match_operand:QI 2 "nonmemory_operand" "")))
12781 (clobber (reg:CC FLAGS_REG))]
12782 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12783 ? epilogue_completed : reload_completed)"
12785 "ix86_split_ashr (operands, NULL_RTX, TImode); DONE;")
12787 (define_insn "x86_64_shrd"
12788 [(set (match_operand:DI 0 "nonimmediate_operand" "+r*m")
12789 (ior:DI (ashiftrt:DI (match_dup 0)
12790 (match_operand:QI 2 "nonmemory_operand" "Jc"))
12791 (ashift:DI (match_operand:DI 1 "register_operand" "r")
12792 (minus:QI (const_int 64) (match_dup 2)))))
12793 (clobber (reg:CC FLAGS_REG))]
12795 "shrd{q}\t{%s2%1, %0|%0, %1, %2}"
12796 [(set_attr "type" "ishift")
12797 (set_attr "prefix_0f" "1")
12798 (set_attr "mode" "DI")
12799 (set_attr "athlon_decode" "vector")
12800 (set_attr "amdfam10_decode" "vector")])
12802 (define_expand "ashrdi3"
12803 [(set (match_operand:DI 0 "shiftdi_operand" "")
12804 (ashiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
12805 (match_operand:QI 2 "nonmemory_operand" "")))]
12807 "ix86_expand_binary_operator (ASHIFTRT, DImode, operands); DONE;")
12809 (define_expand "x86_64_shift_adj_3"
12810 [(use (match_operand:DI 0 "register_operand" ""))
12811 (use (match_operand:DI 1 "register_operand" ""))
12812 (use (match_operand:QI 2 "register_operand" ""))]
12815 rtx label = gen_label_rtx ();
12818 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (64)));
12820 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
12821 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
12822 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
12823 gen_rtx_LABEL_REF (VOIDmode, label),
12825 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
12826 JUMP_LABEL (tmp) = label;
12828 emit_move_insn (operands[0], operands[1]);
12829 emit_insn (gen_ashrdi3_63_rex64 (operands[1], operands[1], GEN_INT (63)));
12831 emit_label (label);
12832 LABEL_NUSES (label) = 1;
12837 (define_insn "ashrdi3_63_rex64"
12838 [(set (match_operand:DI 0 "nonimmediate_operand" "=*d,rm")
12839 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "*a,0")
12840 (match_operand:DI 2 "const_int_operand" "i,i")))
12841 (clobber (reg:CC FLAGS_REG))]
12842 "TARGET_64BIT && INTVAL (operands[2]) == 63
12843 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
12844 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12847 sar{q}\t{%2, %0|%0, %2}"
12848 [(set_attr "type" "imovx,ishift")
12849 (set_attr "prefix_0f" "0,*")
12850 (set_attr "length_immediate" "0,*")
12851 (set_attr "modrm" "0,1")
12852 (set_attr "mode" "DI")])
12854 (define_insn "*ashrdi3_1_one_bit_rex64"
12855 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12856 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12857 (match_operand:QI 2 "const1_operand" "")))
12858 (clobber (reg:CC FLAGS_REG))]
12860 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12861 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12863 [(set_attr "type" "ishift")
12864 (set_attr "length_immediate" "0")
12865 (set_attr "mode" "DI")])
12867 (define_insn "*ashrdi3_1_rex64"
12868 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
12869 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
12870 (match_operand:QI 2 "nonmemory_operand" "J,c")))
12871 (clobber (reg:CC FLAGS_REG))]
12872 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12874 sar{q}\t{%2, %0|%0, %2}
12875 sar{q}\t{%b2, %0|%0, %b2}"
12876 [(set_attr "type" "ishift")
12877 (set_attr "mode" "DI")])
12879 ;; This pattern can't accept a variable shift count, since shifts by
12880 ;; zero don't affect the flags. We assume that shifts by constant
12881 ;; zero are optimized away.
12882 (define_insn "*ashrdi3_one_bit_cmp_rex64"
12883 [(set (reg FLAGS_REG)
12885 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12886 (match_operand:QI 2 "const1_operand" ""))
12888 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12889 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12891 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12892 && ix86_match_ccmode (insn, CCGOCmode)
12893 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12895 [(set_attr "type" "ishift")
12896 (set_attr "length_immediate" "0")
12897 (set_attr "mode" "DI")])
12899 (define_insn "*ashrdi3_one_bit_cconly_rex64"
12900 [(set (reg FLAGS_REG)
12902 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12903 (match_operand:QI 2 "const1_operand" ""))
12905 (clobber (match_scratch:DI 0 "=r"))]
12907 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
12908 && ix86_match_ccmode (insn, CCGOCmode)
12909 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12911 [(set_attr "type" "ishift")
12912 (set_attr "length_immediate" "0")
12913 (set_attr "mode" "DI")])
12915 ;; This pattern can't accept a variable shift count, since shifts by
12916 ;; zero don't affect the flags. We assume that shifts by constant
12917 ;; zero are optimized away.
12918 (define_insn "*ashrdi3_cmp_rex64"
12919 [(set (reg FLAGS_REG)
12921 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12922 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12924 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
12925 (ashiftrt:DI (match_dup 1) (match_dup 2)))]
12927 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12928 && ix86_match_ccmode (insn, CCGOCmode)
12929 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12930 "sar{q}\t{%2, %0|%0, %2}"
12931 [(set_attr "type" "ishift")
12932 (set_attr "mode" "DI")])
12934 (define_insn "*ashrdi3_cconly_rex64"
12935 [(set (reg FLAGS_REG)
12937 (ashiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
12938 (match_operand:QI 2 "const_1_to_63_operand" "J"))
12940 (clobber (match_scratch:DI 0 "=r"))]
12942 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
12943 && ix86_match_ccmode (insn, CCGOCmode)
12944 && ix86_binary_operator_ok (ASHIFTRT, DImode, operands)"
12945 "sar{q}\t{%2, %0|%0, %2}"
12946 [(set_attr "type" "ishift")
12947 (set_attr "mode" "DI")])
12949 (define_insn "*ashrdi3_1"
12950 [(set (match_operand:DI 0 "register_operand" "=r")
12951 (ashiftrt:DI (match_operand:DI 1 "register_operand" "0")
12952 (match_operand:QI 2 "nonmemory_operand" "Jc")))
12953 (clobber (reg:CC FLAGS_REG))]
12956 [(set_attr "type" "multi")])
12958 ;; By default we don't ask for a scratch register, because when DImode
12959 ;; values are manipulated, registers are already at a premium. But if
12960 ;; we have one handy, we won't turn it away.
12962 [(match_scratch:SI 3 "r")
12963 (parallel [(set (match_operand:DI 0 "register_operand" "")
12964 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12965 (match_operand:QI 2 "nonmemory_operand" "")))
12966 (clobber (reg:CC FLAGS_REG))])
12968 "!TARGET_64BIT && TARGET_CMOVE"
12970 "ix86_split_ashr (operands, operands[3], DImode); DONE;")
12973 [(set (match_operand:DI 0 "register_operand" "")
12974 (ashiftrt:DI (match_operand:DI 1 "register_operand" "")
12975 (match_operand:QI 2 "nonmemory_operand" "")))
12976 (clobber (reg:CC FLAGS_REG))]
12977 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
12978 ? epilogue_completed : reload_completed)"
12980 "ix86_split_ashr (operands, NULL_RTX, DImode); DONE;")
12982 (define_insn "x86_shrd"
12983 [(set (match_operand:SI 0 "nonimmediate_operand" "+r*m")
12984 (ior:SI (ashiftrt:SI (match_dup 0)
12985 (match_operand:QI 2 "nonmemory_operand" "Ic"))
12986 (ashift:SI (match_operand:SI 1 "register_operand" "r")
12987 (minus:QI (const_int 32) (match_dup 2)))))
12988 (clobber (reg:CC FLAGS_REG))]
12990 "shrd{l}\t{%s2%1, %0|%0, %1, %2}"
12991 [(set_attr "type" "ishift")
12992 (set_attr "prefix_0f" "1")
12993 (set_attr "pent_pair" "np")
12994 (set_attr "mode" "SI")])
12996 (define_expand "x86_shift_adj_3"
12997 [(use (match_operand:SI 0 "register_operand" ""))
12998 (use (match_operand:SI 1 "register_operand" ""))
12999 (use (match_operand:QI 2 "register_operand" ""))]
13002 rtx label = gen_label_rtx ();
13005 emit_insn (gen_testqi_ccz_1 (operands[2], GEN_INT (32)));
13007 tmp = gen_rtx_REG (CCZmode, FLAGS_REG);
13008 tmp = gen_rtx_EQ (VOIDmode, tmp, const0_rtx);
13009 tmp = gen_rtx_IF_THEN_ELSE (VOIDmode, tmp,
13010 gen_rtx_LABEL_REF (VOIDmode, label),
13012 tmp = emit_jump_insn (gen_rtx_SET (VOIDmode, pc_rtx, tmp));
13013 JUMP_LABEL (tmp) = label;
13015 emit_move_insn (operands[0], operands[1]);
13016 emit_insn (gen_ashrsi3_31 (operands[1], operands[1], GEN_INT (31)));
13018 emit_label (label);
13019 LABEL_NUSES (label) = 1;
13024 (define_expand "ashrsi3_31"
13025 [(parallel [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13026 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13027 (match_operand:SI 2 "const_int_operand" "i,i")))
13028 (clobber (reg:CC FLAGS_REG))])]
13031 (define_insn "*ashrsi3_31"
13032 [(set (match_operand:SI 0 "nonimmediate_operand" "=*d,rm")
13033 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "*a,0")
13034 (match_operand:SI 2 "const_int_operand" "i,i")))
13035 (clobber (reg:CC FLAGS_REG))]
13036 "INTVAL (operands[2]) == 31
13037 && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
13038 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13041 sar{l}\t{%2, %0|%0, %2}"
13042 [(set_attr "type" "imovx,ishift")
13043 (set_attr "prefix_0f" "0,*")
13044 (set_attr "length_immediate" "0,*")
13045 (set_attr "modrm" "0,1")
13046 (set_attr "mode" "SI")])
13048 (define_insn "*ashrsi3_31_zext"
13049 [(set (match_operand:DI 0 "register_operand" "=*d,r")
13050 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "*a,0")
13051 (match_operand:SI 2 "const_int_operand" "i,i"))))
13052 (clobber (reg:CC FLAGS_REG))]
13053 "TARGET_64BIT && (TARGET_USE_CLTD || optimize_function_for_size_p (cfun))
13054 && INTVAL (operands[2]) == 31
13055 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13058 sar{l}\t{%2, %k0|%k0, %2}"
13059 [(set_attr "type" "imovx,ishift")
13060 (set_attr "prefix_0f" "0,*")
13061 (set_attr "length_immediate" "0,*")
13062 (set_attr "modrm" "0,1")
13063 (set_attr "mode" "SI")])
13065 (define_expand "ashrsi3"
13066 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13067 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13068 (match_operand:QI 2 "nonmemory_operand" "")))]
13070 "ix86_expand_binary_operator (ASHIFTRT, SImode, operands); DONE;")
13072 (define_insn "*ashrsi3_1_one_bit"
13073 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13074 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13075 (match_operand:QI 2 "const1_operand" "")))
13076 (clobber (reg:CC FLAGS_REG))]
13077 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13078 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13080 [(set_attr "type" "ishift")
13081 (set_attr "length_immediate" "0")
13082 (set_attr "mode" "SI")])
13084 (define_insn "*ashrsi3_1_one_bit_zext"
13085 [(set (match_operand:DI 0 "register_operand" "=r")
13086 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13087 (match_operand:QI 2 "const1_operand" ""))))
13088 (clobber (reg:CC FLAGS_REG))]
13090 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13091 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13093 [(set_attr "type" "ishift")
13094 (set_attr "length_immediate" "0")
13095 (set_attr "mode" "SI")])
13097 (define_insn "*ashrsi3_1"
13098 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13099 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13100 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13101 (clobber (reg:CC FLAGS_REG))]
13102 "ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13104 sar{l}\t{%2, %0|%0, %2}
13105 sar{l}\t{%b2, %0|%0, %b2}"
13106 [(set_attr "type" "ishift")
13107 (set_attr "mode" "SI")])
13109 (define_insn "*ashrsi3_1_zext"
13110 [(set (match_operand:DI 0 "register_operand" "=r,r")
13111 (zero_extend:DI (ashiftrt:SI (match_operand:SI 1 "register_operand" "0,0")
13112 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13113 (clobber (reg:CC FLAGS_REG))]
13114 "TARGET_64BIT && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13116 sar{l}\t{%2, %k0|%k0, %2}
13117 sar{l}\t{%b2, %k0|%k0, %b2}"
13118 [(set_attr "type" "ishift")
13119 (set_attr "mode" "SI")])
13121 ;; This pattern can't accept a variable shift count, since shifts by
13122 ;; zero don't affect the flags. We assume that shifts by constant
13123 ;; zero are optimized away.
13124 (define_insn "*ashrsi3_one_bit_cmp"
13125 [(set (reg FLAGS_REG)
13127 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13128 (match_operand:QI 2 "const1_operand" ""))
13130 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13131 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
13132 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13133 && ix86_match_ccmode (insn, CCGOCmode)
13134 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13136 [(set_attr "type" "ishift")
13137 (set_attr "length_immediate" "0")
13138 (set_attr "mode" "SI")])
13140 (define_insn "*ashrsi3_one_bit_cconly"
13141 [(set (reg FLAGS_REG)
13143 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13144 (match_operand:QI 2 "const1_operand" ""))
13146 (clobber (match_scratch:SI 0 "=r"))]
13147 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13148 && ix86_match_ccmode (insn, CCGOCmode)
13149 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13151 [(set_attr "type" "ishift")
13152 (set_attr "length_immediate" "0")
13153 (set_attr "mode" "SI")])
13155 (define_insn "*ashrsi3_one_bit_cmp_zext"
13156 [(set (reg FLAGS_REG)
13158 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13159 (match_operand:QI 2 "const1_operand" ""))
13161 (set (match_operand:DI 0 "register_operand" "=r")
13162 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
13164 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13165 && ix86_match_ccmode (insn, CCmode)
13166 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13168 [(set_attr "type" "ishift")
13169 (set_attr "length_immediate" "0")
13170 (set_attr "mode" "SI")])
13172 ;; This pattern can't accept a variable shift count, since shifts by
13173 ;; zero don't affect the flags. We assume that shifts by constant
13174 ;; zero are optimized away.
13175 (define_insn "*ashrsi3_cmp"
13176 [(set (reg FLAGS_REG)
13178 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13179 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13181 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13182 (ashiftrt:SI (match_dup 1) (match_dup 2)))]
13183 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13184 && ix86_match_ccmode (insn, CCGOCmode)
13185 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13186 "sar{l}\t{%2, %0|%0, %2}"
13187 [(set_attr "type" "ishift")
13188 (set_attr "mode" "SI")])
13190 (define_insn "*ashrsi3_cconly"
13191 [(set (reg FLAGS_REG)
13193 (ashiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13194 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13196 (clobber (match_scratch:SI 0 "=r"))]
13197 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13198 && ix86_match_ccmode (insn, CCGOCmode)
13199 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13200 "sar{l}\t{%2, %0|%0, %2}"
13201 [(set_attr "type" "ishift")
13202 (set_attr "mode" "SI")])
13204 (define_insn "*ashrsi3_cmp_zext"
13205 [(set (reg FLAGS_REG)
13207 (ashiftrt:SI (match_operand:SI 1 "register_operand" "0")
13208 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13210 (set (match_operand:DI 0 "register_operand" "=r")
13211 (zero_extend:DI (ashiftrt:SI (match_dup 1) (match_dup 2))))]
13213 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13214 && ix86_match_ccmode (insn, CCGOCmode)
13215 && ix86_binary_operator_ok (ASHIFTRT, SImode, operands)"
13216 "sar{l}\t{%2, %k0|%k0, %2}"
13217 [(set_attr "type" "ishift")
13218 (set_attr "mode" "SI")])
13220 (define_expand "ashrhi3"
13221 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13222 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13223 (match_operand:QI 2 "nonmemory_operand" "")))]
13224 "TARGET_HIMODE_MATH"
13225 "ix86_expand_binary_operator (ASHIFTRT, HImode, operands); DONE;")
13227 (define_insn "*ashrhi3_1_one_bit"
13228 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13229 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13230 (match_operand:QI 2 "const1_operand" "")))
13231 (clobber (reg:CC FLAGS_REG))]
13232 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13233 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13235 [(set_attr "type" "ishift")
13236 (set_attr "length_immediate" "0")
13237 (set_attr "mode" "HI")])
13239 (define_insn "*ashrhi3_1"
13240 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13241 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13242 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13243 (clobber (reg:CC FLAGS_REG))]
13244 "ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13246 sar{w}\t{%2, %0|%0, %2}
13247 sar{w}\t{%b2, %0|%0, %b2}"
13248 [(set_attr "type" "ishift")
13249 (set_attr "mode" "HI")])
13251 ;; This pattern can't accept a variable shift count, since shifts by
13252 ;; zero don't affect the flags. We assume that shifts by constant
13253 ;; zero are optimized away.
13254 (define_insn "*ashrhi3_one_bit_cmp"
13255 [(set (reg FLAGS_REG)
13257 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13258 (match_operand:QI 2 "const1_operand" ""))
13260 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13261 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
13262 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13263 && ix86_match_ccmode (insn, CCGOCmode)
13264 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13266 [(set_attr "type" "ishift")
13267 (set_attr "length_immediate" "0")
13268 (set_attr "mode" "HI")])
13270 (define_insn "*ashrhi3_one_bit_cconly"
13271 [(set (reg FLAGS_REG)
13273 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13274 (match_operand:QI 2 "const1_operand" ""))
13276 (clobber (match_scratch:HI 0 "=r"))]
13277 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13278 && ix86_match_ccmode (insn, CCGOCmode)
13279 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13281 [(set_attr "type" "ishift")
13282 (set_attr "length_immediate" "0")
13283 (set_attr "mode" "HI")])
13285 ;; This pattern can't accept a variable shift count, since shifts by
13286 ;; zero don't affect the flags. We assume that shifts by constant
13287 ;; zero are optimized away.
13288 (define_insn "*ashrhi3_cmp"
13289 [(set (reg FLAGS_REG)
13291 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13292 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13294 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13295 (ashiftrt:HI (match_dup 1) (match_dup 2)))]
13296 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13297 && ix86_match_ccmode (insn, CCGOCmode)
13298 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13299 "sar{w}\t{%2, %0|%0, %2}"
13300 [(set_attr "type" "ishift")
13301 (set_attr "mode" "HI")])
13303 (define_insn "*ashrhi3_cconly"
13304 [(set (reg FLAGS_REG)
13306 (ashiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13307 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13309 (clobber (match_scratch:HI 0 "=r"))]
13310 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13311 && ix86_match_ccmode (insn, CCGOCmode)
13312 && ix86_binary_operator_ok (ASHIFTRT, HImode, operands)"
13313 "sar{w}\t{%2, %0|%0, %2}"
13314 [(set_attr "type" "ishift")
13315 (set_attr "mode" "HI")])
13317 (define_expand "ashrqi3"
13318 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13319 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13320 (match_operand:QI 2 "nonmemory_operand" "")))]
13321 "TARGET_QIMODE_MATH"
13322 "ix86_expand_binary_operator (ASHIFTRT, QImode, operands); DONE;")
13324 (define_insn "*ashrqi3_1_one_bit"
13325 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13326 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13327 (match_operand:QI 2 "const1_operand" "")))
13328 (clobber (reg:CC FLAGS_REG))]
13329 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13330 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13332 [(set_attr "type" "ishift")
13333 (set_attr "length_immediate" "0")
13334 (set_attr "mode" "QI")])
13336 (define_insn "*ashrqi3_1_one_bit_slp"
13337 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13338 (ashiftrt:QI (match_dup 0)
13339 (match_operand:QI 1 "const1_operand" "")))
13340 (clobber (reg:CC FLAGS_REG))]
13341 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13343 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13345 [(set_attr "type" "ishift1")
13346 (set_attr "length_immediate" "0")
13347 (set_attr "mode" "QI")])
13349 (define_insn "*ashrqi3_1"
13350 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13351 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13352 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13353 (clobber (reg:CC FLAGS_REG))]
13354 "ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13356 sar{b}\t{%2, %0|%0, %2}
13357 sar{b}\t{%b2, %0|%0, %b2}"
13358 [(set_attr "type" "ishift")
13359 (set_attr "mode" "QI")])
13361 (define_insn "*ashrqi3_1_slp"
13362 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13363 (ashiftrt:QI (match_dup 0)
13364 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13365 (clobber (reg:CC FLAGS_REG))]
13366 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13367 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13369 sar{b}\t{%1, %0|%0, %1}
13370 sar{b}\t{%b1, %0|%0, %b1}"
13371 [(set_attr "type" "ishift1")
13372 (set_attr "mode" "QI")])
13374 ;; This pattern can't accept a variable shift count, since shifts by
13375 ;; zero don't affect the flags. We assume that shifts by constant
13376 ;; zero are optimized away.
13377 (define_insn "*ashrqi3_one_bit_cmp"
13378 [(set (reg FLAGS_REG)
13380 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13381 (match_operand:QI 2 "const1_operand" "I"))
13383 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13384 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13385 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13386 && ix86_match_ccmode (insn, CCGOCmode)
13387 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13389 [(set_attr "type" "ishift")
13390 (set_attr "length_immediate" "0")
13391 (set_attr "mode" "QI")])
13393 (define_insn "*ashrqi3_one_bit_cconly"
13394 [(set (reg FLAGS_REG)
13396 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13397 (match_operand:QI 2 "const1_operand" ""))
13399 (clobber (match_scratch:QI 0 "=q"))]
13400 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13401 && ix86_match_ccmode (insn, CCGOCmode)
13402 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13404 [(set_attr "type" "ishift")
13405 (set_attr "length_immediate" "0")
13406 (set_attr "mode" "QI")])
13408 ;; This pattern can't accept a variable shift count, since shifts by
13409 ;; zero don't affect the flags. We assume that shifts by constant
13410 ;; zero are optimized away.
13411 (define_insn "*ashrqi3_cmp"
13412 [(set (reg FLAGS_REG)
13414 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13415 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13417 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13418 (ashiftrt:QI (match_dup 1) (match_dup 2)))]
13419 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13420 && ix86_match_ccmode (insn, CCGOCmode)
13421 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13422 "sar{b}\t{%2, %0|%0, %2}"
13423 [(set_attr "type" "ishift")
13424 (set_attr "mode" "QI")])
13426 (define_insn "*ashrqi3_cconly"
13427 [(set (reg FLAGS_REG)
13429 (ashiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13430 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13432 (clobber (match_scratch:QI 0 "=q"))]
13433 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13434 && ix86_match_ccmode (insn, CCGOCmode)
13435 && ix86_binary_operator_ok (ASHIFTRT, QImode, operands)"
13436 "sar{b}\t{%2, %0|%0, %2}"
13437 [(set_attr "type" "ishift")
13438 (set_attr "mode" "QI")])
13441 ;; Logical shift instructions
13443 ;; See comment above `ashldi3' about how this works.
13445 (define_expand "lshrti3"
13446 [(set (match_operand:TI 0 "register_operand" "")
13447 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13448 (match_operand:QI 2 "nonmemory_operand" "")))]
13450 "ix86_expand_binary_operator (LSHIFTRT, TImode, operands); DONE;")
13452 ;; This pattern must be defined before *lshrti3_1 to prevent
13453 ;; combine pass from converting sse2_lshrti3 to *lshrti3_1.
13455 (define_insn "*avx_lshrti3"
13456 [(set (match_operand:TI 0 "register_operand" "=x")
13457 (lshiftrt:TI (match_operand:TI 1 "register_operand" "x")
13458 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13461 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13462 return "vpsrldq\t{%2, %1, %0|%0, %1, %2}";
13464 [(set_attr "type" "sseishft")
13465 (set_attr "prefix" "vex")
13466 (set_attr "length_immediate" "1")
13467 (set_attr "mode" "TI")])
13469 (define_insn "sse2_lshrti3"
13470 [(set (match_operand:TI 0 "register_operand" "=x")
13471 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13472 (match_operand:SI 2 "const_0_to_255_mul_8_operand" "n")))]
13475 operands[2] = GEN_INT (INTVAL (operands[2]) / 8);
13476 return "psrldq\t{%2, %0|%0, %2}";
13478 [(set_attr "type" "sseishft")
13479 (set_attr "prefix_data16" "1")
13480 (set_attr "length_immediate" "1")
13481 (set_attr "mode" "TI")])
13483 (define_insn "*lshrti3_1"
13484 [(set (match_operand:TI 0 "register_operand" "=r")
13485 (lshiftrt:TI (match_operand:TI 1 "register_operand" "0")
13486 (match_operand:QI 2 "nonmemory_operand" "Oc")))
13487 (clobber (reg:CC FLAGS_REG))]
13490 [(set_attr "type" "multi")])
13493 [(match_scratch:DI 3 "r")
13494 (parallel [(set (match_operand:TI 0 "register_operand" "")
13495 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13496 (match_operand:QI 2 "nonmemory_operand" "")))
13497 (clobber (reg:CC FLAGS_REG))])
13501 "ix86_split_lshr (operands, operands[3], TImode); DONE;")
13504 [(set (match_operand:TI 0 "register_operand" "")
13505 (lshiftrt:TI (match_operand:TI 1 "register_operand" "")
13506 (match_operand:QI 2 "nonmemory_operand" "")))
13507 (clobber (reg:CC FLAGS_REG))]
13508 "TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13509 ? epilogue_completed : reload_completed)"
13511 "ix86_split_lshr (operands, NULL_RTX, TImode); DONE;")
13513 (define_expand "lshrdi3"
13514 [(set (match_operand:DI 0 "shiftdi_operand" "")
13515 (lshiftrt:DI (match_operand:DI 1 "shiftdi_operand" "")
13516 (match_operand:QI 2 "nonmemory_operand" "")))]
13518 "ix86_expand_binary_operator (LSHIFTRT, DImode, operands); DONE;")
13520 (define_insn "*lshrdi3_1_one_bit_rex64"
13521 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13522 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13523 (match_operand:QI 2 "const1_operand" "")))
13524 (clobber (reg:CC FLAGS_REG))]
13526 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13527 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13529 [(set_attr "type" "ishift")
13530 (set_attr "length_immediate" "0")
13531 (set_attr "mode" "DI")])
13533 (define_insn "*lshrdi3_1_rex64"
13534 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
13535 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
13536 (match_operand:QI 2 "nonmemory_operand" "J,c")))
13537 (clobber (reg:CC FLAGS_REG))]
13538 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13540 shr{q}\t{%2, %0|%0, %2}
13541 shr{q}\t{%b2, %0|%0, %b2}"
13542 [(set_attr "type" "ishift")
13543 (set_attr "mode" "DI")])
13545 ;; This pattern can't accept a variable shift count, since shifts by
13546 ;; zero don't affect the flags. We assume that shifts by constant
13547 ;; zero are optimized away.
13548 (define_insn "*lshrdi3_cmp_one_bit_rex64"
13549 [(set (reg FLAGS_REG)
13551 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13552 (match_operand:QI 2 "const1_operand" ""))
13554 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13555 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13557 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13558 && ix86_match_ccmode (insn, CCGOCmode)
13559 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13561 [(set_attr "type" "ishift")
13562 (set_attr "length_immediate" "0")
13563 (set_attr "mode" "DI")])
13565 (define_insn "*lshrdi3_cconly_one_bit_rex64"
13566 [(set (reg FLAGS_REG)
13568 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13569 (match_operand:QI 2 "const1_operand" ""))
13571 (clobber (match_scratch:DI 0 "=r"))]
13573 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13574 && ix86_match_ccmode (insn, CCGOCmode)
13575 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13577 [(set_attr "type" "ishift")
13578 (set_attr "length_immediate" "0")
13579 (set_attr "mode" "DI")])
13581 ;; This pattern can't accept a variable shift count, since shifts by
13582 ;; zero don't affect the flags. We assume that shifts by constant
13583 ;; zero are optimized away.
13584 (define_insn "*lshrdi3_cmp_rex64"
13585 [(set (reg FLAGS_REG)
13587 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13588 (match_operand:QI 2 "const_1_to_63_operand" "J"))
13590 (set (match_operand:DI 0 "nonimmediate_operand" "=rm")
13591 (lshiftrt:DI (match_dup 1) (match_dup 2)))]
13593 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13594 && ix86_match_ccmode (insn, CCGOCmode)
13595 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13596 "shr{q}\t{%2, %0|%0, %2}"
13597 [(set_attr "type" "ishift")
13598 (set_attr "mode" "DI")])
13600 (define_insn "*lshrdi3_cconly_rex64"
13601 [(set (reg FLAGS_REG)
13603 (lshiftrt:DI (match_operand:DI 1 "nonimmediate_operand" "0")
13604 (match_operand:QI 2 "const_1_to_63_operand" "J"))
13606 (clobber (match_scratch:DI 0 "=r"))]
13608 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13609 && ix86_match_ccmode (insn, CCGOCmode)
13610 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13611 "shr{q}\t{%2, %0|%0, %2}"
13612 [(set_attr "type" "ishift")
13613 (set_attr "mode" "DI")])
13615 (define_insn "*lshrdi3_1"
13616 [(set (match_operand:DI 0 "register_operand" "=r")
13617 (lshiftrt:DI (match_operand:DI 1 "register_operand" "0")
13618 (match_operand:QI 2 "nonmemory_operand" "Jc")))
13619 (clobber (reg:CC FLAGS_REG))]
13622 [(set_attr "type" "multi")])
13624 ;; By default we don't ask for a scratch register, because when DImode
13625 ;; values are manipulated, registers are already at a premium. But if
13626 ;; we have one handy, we won't turn it away.
13628 [(match_scratch:SI 3 "r")
13629 (parallel [(set (match_operand:DI 0 "register_operand" "")
13630 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13631 (match_operand:QI 2 "nonmemory_operand" "")))
13632 (clobber (reg:CC FLAGS_REG))])
13634 "!TARGET_64BIT && TARGET_CMOVE"
13636 "ix86_split_lshr (operands, operands[3], DImode); DONE;")
13639 [(set (match_operand:DI 0 "register_operand" "")
13640 (lshiftrt:DI (match_operand:DI 1 "register_operand" "")
13641 (match_operand:QI 2 "nonmemory_operand" "")))
13642 (clobber (reg:CC FLAGS_REG))]
13643 "!TARGET_64BIT && ((optimize > 0 && flag_peephole2)
13644 ? epilogue_completed : reload_completed)"
13646 "ix86_split_lshr (operands, NULL_RTX, DImode); DONE;")
13648 (define_expand "lshrsi3"
13649 [(set (match_operand:SI 0 "nonimmediate_operand" "")
13650 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "")
13651 (match_operand:QI 2 "nonmemory_operand" "")))]
13653 "ix86_expand_binary_operator (LSHIFTRT, SImode, operands); DONE;")
13655 (define_insn "*lshrsi3_1_one_bit"
13656 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13657 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13658 (match_operand:QI 2 "const1_operand" "")))
13659 (clobber (reg:CC FLAGS_REG))]
13660 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13661 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13663 [(set_attr "type" "ishift")
13664 (set_attr "length_immediate" "0")
13665 (set_attr "mode" "SI")])
13667 (define_insn "*lshrsi3_1_one_bit_zext"
13668 [(set (match_operand:DI 0 "register_operand" "=r")
13669 (lshiftrt:DI (zero_extend:DI (match_operand:SI 1 "register_operand" "0"))
13670 (match_operand:QI 2 "const1_operand" "")))
13671 (clobber (reg:CC FLAGS_REG))]
13673 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13674 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13676 [(set_attr "type" "ishift")
13677 (set_attr "length_immediate" "0")
13678 (set_attr "mode" "SI")])
13680 (define_insn "*lshrsi3_1"
13681 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
13682 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13683 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13684 (clobber (reg:CC FLAGS_REG))]
13685 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13687 shr{l}\t{%2, %0|%0, %2}
13688 shr{l}\t{%b2, %0|%0, %b2}"
13689 [(set_attr "type" "ishift")
13690 (set_attr "mode" "SI")])
13692 (define_insn "*lshrsi3_1_zext"
13693 [(set (match_operand:DI 0 "register_operand" "=r,r")
13695 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
13696 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
13697 (clobber (reg:CC FLAGS_REG))]
13698 "TARGET_64BIT && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13700 shr{l}\t{%2, %k0|%k0, %2}
13701 shr{l}\t{%b2, %k0|%k0, %b2}"
13702 [(set_attr "type" "ishift")
13703 (set_attr "mode" "SI")])
13705 ;; This pattern can't accept a variable shift count, since shifts by
13706 ;; zero don't affect the flags. We assume that shifts by constant
13707 ;; zero are optimized away.
13708 (define_insn "*lshrsi3_one_bit_cmp"
13709 [(set (reg FLAGS_REG)
13711 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13712 (match_operand:QI 2 "const1_operand" ""))
13714 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13715 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13716 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13717 && ix86_match_ccmode (insn, CCGOCmode)
13718 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13720 [(set_attr "type" "ishift")
13721 (set_attr "length_immediate" "0")
13722 (set_attr "mode" "SI")])
13724 (define_insn "*lshrsi3_one_bit_cconly"
13725 [(set (reg FLAGS_REG)
13727 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13728 (match_operand:QI 2 "const1_operand" ""))
13730 (clobber (match_scratch:SI 0 "=r"))]
13731 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13732 && ix86_match_ccmode (insn, CCGOCmode)
13733 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13735 [(set_attr "type" "ishift")
13736 (set_attr "length_immediate" "0")
13737 (set_attr "mode" "SI")])
13739 (define_insn "*lshrsi3_cmp_one_bit_zext"
13740 [(set (reg FLAGS_REG)
13742 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13743 (match_operand:QI 2 "const1_operand" ""))
13745 (set (match_operand:DI 0 "register_operand" "=r")
13746 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13748 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13749 && ix86_match_ccmode (insn, CCGOCmode)
13750 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13752 [(set_attr "type" "ishift")
13753 (set_attr "length_immediate" "0")
13754 (set_attr "mode" "SI")])
13756 ;; This pattern can't accept a variable shift count, since shifts by
13757 ;; zero don't affect the flags. We assume that shifts by constant
13758 ;; zero are optimized away.
13759 (define_insn "*lshrsi3_cmp"
13760 [(set (reg FLAGS_REG)
13762 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13763 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13765 (set (match_operand:SI 0 "nonimmediate_operand" "=rm")
13766 (lshiftrt:SI (match_dup 1) (match_dup 2)))]
13767 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13768 && ix86_match_ccmode (insn, CCGOCmode)
13769 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13770 "shr{l}\t{%2, %0|%0, %2}"
13771 [(set_attr "type" "ishift")
13772 (set_attr "mode" "SI")])
13774 (define_insn "*lshrsi3_cconly"
13775 [(set (reg FLAGS_REG)
13777 (lshiftrt:SI (match_operand:SI 1 "nonimmediate_operand" "0")
13778 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13780 (clobber (match_scratch:SI 0 "=r"))]
13781 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13782 && ix86_match_ccmode (insn, CCGOCmode)
13783 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13784 "shr{l}\t{%2, %0|%0, %2}"
13785 [(set_attr "type" "ishift")
13786 (set_attr "mode" "SI")])
13788 (define_insn "*lshrsi3_cmp_zext"
13789 [(set (reg FLAGS_REG)
13791 (lshiftrt:SI (match_operand:SI 1 "register_operand" "0")
13792 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13794 (set (match_operand:DI 0 "register_operand" "=r")
13795 (lshiftrt:DI (zero_extend:DI (match_dup 1)) (match_dup 2)))]
13797 && (optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13798 && ix86_match_ccmode (insn, CCGOCmode)
13799 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13800 "shr{l}\t{%2, %k0|%k0, %2}"
13801 [(set_attr "type" "ishift")
13802 (set_attr "mode" "SI")])
13804 (define_expand "lshrhi3"
13805 [(set (match_operand:HI 0 "nonimmediate_operand" "")
13806 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "")
13807 (match_operand:QI 2 "nonmemory_operand" "")))]
13808 "TARGET_HIMODE_MATH"
13809 "ix86_expand_binary_operator (LSHIFTRT, HImode, operands); DONE;")
13811 (define_insn "*lshrhi3_1_one_bit"
13812 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13813 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13814 (match_operand:QI 2 "const1_operand" "")))
13815 (clobber (reg:CC FLAGS_REG))]
13816 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13817 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13819 [(set_attr "type" "ishift")
13820 (set_attr "length_immediate" "0")
13821 (set_attr "mode" "HI")])
13823 (define_insn "*lshrhi3_1"
13824 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
13825 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
13826 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13827 (clobber (reg:CC FLAGS_REG))]
13828 "ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13830 shr{w}\t{%2, %0|%0, %2}
13831 shr{w}\t{%b2, %0|%0, %b2}"
13832 [(set_attr "type" "ishift")
13833 (set_attr "mode" "HI")])
13835 ;; This pattern can't accept a variable shift count, since shifts by
13836 ;; zero don't affect the flags. We assume that shifts by constant
13837 ;; zero are optimized away.
13838 (define_insn "*lshrhi3_one_bit_cmp"
13839 [(set (reg FLAGS_REG)
13841 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13842 (match_operand:QI 2 "const1_operand" ""))
13844 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13845 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13846 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13847 && ix86_match_ccmode (insn, CCGOCmode)
13848 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13850 [(set_attr "type" "ishift")
13851 (set_attr "length_immediate" "0")
13852 (set_attr "mode" "HI")])
13854 (define_insn "*lshrhi3_one_bit_cconly"
13855 [(set (reg FLAGS_REG)
13857 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13858 (match_operand:QI 2 "const1_operand" ""))
13860 (clobber (match_scratch:HI 0 "=r"))]
13861 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13862 && ix86_match_ccmode (insn, CCGOCmode)
13863 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13865 [(set_attr "type" "ishift")
13866 (set_attr "length_immediate" "0")
13867 (set_attr "mode" "HI")])
13869 ;; This pattern can't accept a variable shift count, since shifts by
13870 ;; zero don't affect the flags. We assume that shifts by constant
13871 ;; zero are optimized away.
13872 (define_insn "*lshrhi3_cmp"
13873 [(set (reg FLAGS_REG)
13875 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13876 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13878 (set (match_operand:HI 0 "nonimmediate_operand" "=rm")
13879 (lshiftrt:HI (match_dup 1) (match_dup 2)))]
13880 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13881 && ix86_match_ccmode (insn, CCGOCmode)
13882 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13883 "shr{w}\t{%2, %0|%0, %2}"
13884 [(set_attr "type" "ishift")
13885 (set_attr "mode" "HI")])
13887 (define_insn "*lshrhi3_cconly"
13888 [(set (reg FLAGS_REG)
13890 (lshiftrt:HI (match_operand:HI 1 "nonimmediate_operand" "0")
13891 (match_operand:QI 2 "const_1_to_31_operand" "I"))
13893 (clobber (match_scratch:HI 0 "=r"))]
13894 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
13895 && ix86_match_ccmode (insn, CCGOCmode)
13896 && ix86_binary_operator_ok (LSHIFTRT, HImode, operands)"
13897 "shr{w}\t{%2, %0|%0, %2}"
13898 [(set_attr "type" "ishift")
13899 (set_attr "mode" "HI")])
13901 (define_expand "lshrqi3"
13902 [(set (match_operand:QI 0 "nonimmediate_operand" "")
13903 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "")
13904 (match_operand:QI 2 "nonmemory_operand" "")))]
13905 "TARGET_QIMODE_MATH"
13906 "ix86_expand_binary_operator (LSHIFTRT, QImode, operands); DONE;")
13908 (define_insn "*lshrqi3_1_one_bit"
13909 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13910 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13911 (match_operand:QI 2 "const1_operand" "")))
13912 (clobber (reg:CC FLAGS_REG))]
13913 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13914 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13916 [(set_attr "type" "ishift")
13917 (set_attr "length_immediate" "0")
13918 (set_attr "mode" "QI")])
13920 (define_insn "*lshrqi3_1_one_bit_slp"
13921 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
13922 (lshiftrt:QI (match_dup 0)
13923 (match_operand:QI 1 "const1_operand" "")))
13924 (clobber (reg:CC FLAGS_REG))]
13925 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13926 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
13928 [(set_attr "type" "ishift1")
13929 (set_attr "length_immediate" "0")
13930 (set_attr "mode" "QI")])
13932 (define_insn "*lshrqi3_1"
13933 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
13934 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
13935 (match_operand:QI 2 "nonmemory_operand" "I,c")))
13936 (clobber (reg:CC FLAGS_REG))]
13937 "ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13939 shr{b}\t{%2, %0|%0, %2}
13940 shr{b}\t{%b2, %0|%0, %b2}"
13941 [(set_attr "type" "ishift")
13942 (set_attr "mode" "QI")])
13944 (define_insn "*lshrqi3_1_slp"
13945 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
13946 (lshiftrt:QI (match_dup 0)
13947 (match_operand:QI 1 "nonmemory_operand" "I,c")))
13948 (clobber (reg:CC FLAGS_REG))]
13949 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
13950 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
13952 shr{b}\t{%1, %0|%0, %1}
13953 shr{b}\t{%b1, %0|%0, %b1}"
13954 [(set_attr "type" "ishift1")
13955 (set_attr "mode" "QI")])
13957 ;; This pattern can't accept a variable shift count, since shifts by
13958 ;; zero don't affect the flags. We assume that shifts by constant
13959 ;; zero are optimized away.
13960 (define_insn "*lshrqi2_one_bit_cmp"
13961 [(set (reg FLAGS_REG)
13963 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13964 (match_operand:QI 2 "const1_operand" ""))
13966 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
13967 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
13968 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13969 && ix86_match_ccmode (insn, CCGOCmode)
13970 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13972 [(set_attr "type" "ishift")
13973 (set_attr "length_immediate" "0")
13974 (set_attr "mode" "QI")])
13976 (define_insn "*lshrqi2_one_bit_cconly"
13977 [(set (reg FLAGS_REG)
13979 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13980 (match_operand:QI 2 "const1_operand" ""))
13982 (clobber (match_scratch:QI 0 "=q"))]
13983 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
13984 && ix86_match_ccmode (insn, CCGOCmode)
13985 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
13987 [(set_attr "type" "ishift")
13988 (set_attr "length_immediate" "0")
13989 (set_attr "mode" "QI")])
13991 ;; This pattern can't accept a variable shift count, since shifts by
13992 ;; zero don't affect the flags. We assume that shifts by constant
13993 ;; zero are optimized away.
13994 (define_insn "*lshrqi2_cmp"
13995 [(set (reg FLAGS_REG)
13997 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
13998 (match_operand:QI 2 "const_1_to_31_operand" "I"))
14000 (set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14001 (lshiftrt:QI (match_dup 1) (match_dup 2)))]
14002 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
14003 && ix86_match_ccmode (insn, CCGOCmode)
14004 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14005 "shr{b}\t{%2, %0|%0, %2}"
14006 [(set_attr "type" "ishift")
14007 (set_attr "mode" "QI")])
14009 (define_insn "*lshrqi2_cconly"
14010 [(set (reg FLAGS_REG)
14012 (lshiftrt:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14013 (match_operand:QI 2 "const_1_to_31_operand" "I"))
14015 (clobber (match_scratch:QI 0 "=q"))]
14016 "(optimize_function_for_size_p (cfun) || !TARGET_PARTIAL_FLAG_REG_STALL)
14017 && ix86_match_ccmode (insn, CCGOCmode)
14018 && ix86_binary_operator_ok (LSHIFTRT, QImode, operands)"
14019 "shr{b}\t{%2, %0|%0, %2}"
14020 [(set_attr "type" "ishift")
14021 (set_attr "mode" "QI")])
14023 ;; Rotate instructions
14025 (define_expand "rotldi3"
14026 [(set (match_operand:DI 0 "shiftdi_operand" "")
14027 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
14028 (match_operand:QI 2 "nonmemory_operand" "")))]
14033 ix86_expand_binary_operator (ROTATE, DImode, operands);
14036 if (!const_1_to_31_operand (operands[2], VOIDmode))
14038 emit_insn (gen_ix86_rotldi3 (operands[0], operands[1], operands[2]));
14042 ;; Implement rotation using two double-precision shift instructions
14043 ;; and a scratch register.
14044 (define_insn_and_split "ix86_rotldi3"
14045 [(set (match_operand:DI 0 "register_operand" "=r")
14046 (rotate:DI (match_operand:DI 1 "register_operand" "0")
14047 (match_operand:QI 2 "const_1_to_31_operand" "I")))
14048 (clobber (reg:CC FLAGS_REG))
14049 (clobber (match_scratch:SI 3 "=&r"))]
14052 "&& reload_completed"
14053 [(set (match_dup 3) (match_dup 4))
14055 [(set (match_dup 4)
14056 (ior:SI (ashift:SI (match_dup 4) (match_dup 2))
14057 (lshiftrt:SI (match_dup 5)
14058 (minus:QI (const_int 32) (match_dup 2)))))
14059 (clobber (reg:CC FLAGS_REG))])
14061 [(set (match_dup 5)
14062 (ior:SI (ashift:SI (match_dup 5) (match_dup 2))
14063 (lshiftrt:SI (match_dup 3)
14064 (minus:QI (const_int 32) (match_dup 2)))))
14065 (clobber (reg:CC FLAGS_REG))])]
14066 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
14068 (define_insn "*rotlsi3_1_one_bit_rex64"
14069 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14070 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0")
14071 (match_operand:QI 2 "const1_operand" "")))
14072 (clobber (reg:CC FLAGS_REG))]
14074 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14075 && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14077 [(set_attr "type" "rotate")
14078 (set_attr "length_immediate" "0")
14079 (set_attr "mode" "DI")])
14081 (define_insn "*rotldi3_1_rex64"
14082 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14083 (rotate:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14084 (match_operand:QI 2 "nonmemory_operand" "e,c")))
14085 (clobber (reg:CC FLAGS_REG))]
14086 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, DImode, operands)"
14088 rol{q}\t{%2, %0|%0, %2}
14089 rol{q}\t{%b2, %0|%0, %b2}"
14090 [(set_attr "type" "rotate")
14091 (set_attr "mode" "DI")])
14093 (define_expand "rotlsi3"
14094 [(set (match_operand:SI 0 "nonimmediate_operand" "")
14095 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "")
14096 (match_operand:QI 2 "nonmemory_operand" "")))]
14098 "ix86_expand_binary_operator (ROTATE, SImode, operands); DONE;")
14100 (define_insn "*rotlsi3_1_one_bit"
14101 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14102 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0")
14103 (match_operand:QI 2 "const1_operand" "")))
14104 (clobber (reg:CC FLAGS_REG))]
14105 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14106 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14108 [(set_attr "type" "rotate")
14109 (set_attr "length_immediate" "0")
14110 (set_attr "mode" "SI")])
14112 (define_insn "*rotlsi3_1_one_bit_zext"
14113 [(set (match_operand:DI 0 "register_operand" "=r")
14115 (rotate:SI (match_operand:SI 1 "register_operand" "0")
14116 (match_operand:QI 2 "const1_operand" ""))))
14117 (clobber (reg:CC FLAGS_REG))]
14119 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14120 && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14122 [(set_attr "type" "rotate")
14123 (set_attr "length_immediate" "0")
14124 (set_attr "mode" "SI")])
14126 (define_insn "*rotlsi3_1"
14127 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14128 (rotate:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14129 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14130 (clobber (reg:CC FLAGS_REG))]
14131 "ix86_binary_operator_ok (ROTATE, SImode, operands)"
14133 rol{l}\t{%2, %0|%0, %2}
14134 rol{l}\t{%b2, %0|%0, %b2}"
14135 [(set_attr "type" "rotate")
14136 (set_attr "mode" "SI")])
14138 (define_insn "*rotlsi3_1_zext"
14139 [(set (match_operand:DI 0 "register_operand" "=r,r")
14141 (rotate:SI (match_operand:SI 1 "register_operand" "0,0")
14142 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14143 (clobber (reg:CC FLAGS_REG))]
14144 "TARGET_64BIT && ix86_binary_operator_ok (ROTATE, SImode, operands)"
14146 rol{l}\t{%2, %k0|%k0, %2}
14147 rol{l}\t{%b2, %k0|%k0, %b2}"
14148 [(set_attr "type" "rotate")
14149 (set_attr "mode" "SI")])
14151 (define_expand "rotlhi3"
14152 [(set (match_operand:HI 0 "nonimmediate_operand" "")
14153 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "")
14154 (match_operand:QI 2 "nonmemory_operand" "")))]
14155 "TARGET_HIMODE_MATH"
14156 "ix86_expand_binary_operator (ROTATE, HImode, operands); DONE;")
14158 (define_insn "*rotlhi3_1_one_bit"
14159 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14160 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14161 (match_operand:QI 2 "const1_operand" "")))
14162 (clobber (reg:CC FLAGS_REG))]
14163 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14164 && ix86_binary_operator_ok (ROTATE, HImode, operands)"
14166 [(set_attr "type" "rotate")
14167 (set_attr "length_immediate" "0")
14168 (set_attr "mode" "HI")])
14170 (define_insn "*rotlhi3_1"
14171 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14172 (rotate:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14173 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14174 (clobber (reg:CC FLAGS_REG))]
14175 "ix86_binary_operator_ok (ROTATE, HImode, operands)"
14177 rol{w}\t{%2, %0|%0, %2}
14178 rol{w}\t{%b2, %0|%0, %b2}"
14179 [(set_attr "type" "rotate")
14180 (set_attr "mode" "HI")])
14183 [(set (match_operand:HI 0 "register_operand" "")
14184 (rotate:HI (match_dup 0) (const_int 8)))
14185 (clobber (reg:CC FLAGS_REG))]
14187 [(parallel [(set (strict_low_part (match_dup 0))
14188 (bswap:HI (match_dup 0)))
14189 (clobber (reg:CC FLAGS_REG))])]
14192 (define_expand "rotlqi3"
14193 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14194 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "")
14195 (match_operand:QI 2 "nonmemory_operand" "")))]
14196 "TARGET_QIMODE_MATH"
14197 "ix86_expand_binary_operator (ROTATE, QImode, operands); DONE;")
14199 (define_insn "*rotlqi3_1_one_bit_slp"
14200 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14201 (rotate:QI (match_dup 0)
14202 (match_operand:QI 1 "const1_operand" "")))
14203 (clobber (reg:CC FLAGS_REG))]
14204 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14205 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14207 [(set_attr "type" "rotate1")
14208 (set_attr "length_immediate" "0")
14209 (set_attr "mode" "QI")])
14211 (define_insn "*rotlqi3_1_one_bit"
14212 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14213 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14214 (match_operand:QI 2 "const1_operand" "")))
14215 (clobber (reg:CC FLAGS_REG))]
14216 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14217 && ix86_binary_operator_ok (ROTATE, QImode, operands)"
14219 [(set_attr "type" "rotate")
14220 (set_attr "length_immediate" "0")
14221 (set_attr "mode" "QI")])
14223 (define_insn "*rotlqi3_1_slp"
14224 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14225 (rotate:QI (match_dup 0)
14226 (match_operand:QI 1 "nonmemory_operand" "I,c")))
14227 (clobber (reg:CC FLAGS_REG))]
14228 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14229 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14231 rol{b}\t{%1, %0|%0, %1}
14232 rol{b}\t{%b1, %0|%0, %b1}"
14233 [(set_attr "type" "rotate1")
14234 (set_attr "mode" "QI")])
14236 (define_insn "*rotlqi3_1"
14237 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14238 (rotate:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14239 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14240 (clobber (reg:CC FLAGS_REG))]
14241 "ix86_binary_operator_ok (ROTATE, QImode, operands)"
14243 rol{b}\t{%2, %0|%0, %2}
14244 rol{b}\t{%b2, %0|%0, %b2}"
14245 [(set_attr "type" "rotate")
14246 (set_attr "mode" "QI")])
14248 (define_expand "rotrdi3"
14249 [(set (match_operand:DI 0 "shiftdi_operand" "")
14250 (rotate:DI (match_operand:DI 1 "shiftdi_operand" "")
14251 (match_operand:QI 2 "nonmemory_operand" "")))]
14256 ix86_expand_binary_operator (ROTATERT, DImode, operands);
14259 if (!const_1_to_31_operand (operands[2], VOIDmode))
14261 emit_insn (gen_ix86_rotrdi3 (operands[0], operands[1], operands[2]));
14265 ;; Implement rotation using two double-precision shift instructions
14266 ;; and a scratch register.
14267 (define_insn_and_split "ix86_rotrdi3"
14268 [(set (match_operand:DI 0 "register_operand" "=r")
14269 (rotatert:DI (match_operand:DI 1 "register_operand" "0")
14270 (match_operand:QI 2 "const_1_to_31_operand" "I")))
14271 (clobber (reg:CC FLAGS_REG))
14272 (clobber (match_scratch:SI 3 "=&r"))]
14275 "&& reload_completed"
14276 [(set (match_dup 3) (match_dup 4))
14278 [(set (match_dup 4)
14279 (ior:SI (ashiftrt:SI (match_dup 4) (match_dup 2))
14280 (ashift:SI (match_dup 5)
14281 (minus:QI (const_int 32) (match_dup 2)))))
14282 (clobber (reg:CC FLAGS_REG))])
14284 [(set (match_dup 5)
14285 (ior:SI (ashiftrt:SI (match_dup 5) (match_dup 2))
14286 (ashift:SI (match_dup 3)
14287 (minus:QI (const_int 32) (match_dup 2)))))
14288 (clobber (reg:CC FLAGS_REG))])]
14289 "split_di (&operands[0], 1, &operands[4], &operands[5]);")
14291 (define_insn "*rotrdi3_1_one_bit_rex64"
14292 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm")
14293 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0")
14294 (match_operand:QI 2 "const1_operand" "")))
14295 (clobber (reg:CC FLAGS_REG))]
14297 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14298 && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14300 [(set_attr "type" "rotate")
14301 (set_attr "length_immediate" "0")
14302 (set_attr "mode" "DI")])
14304 (define_insn "*rotrdi3_1_rex64"
14305 [(set (match_operand:DI 0 "nonimmediate_operand" "=rm,rm")
14306 (rotatert:DI (match_operand:DI 1 "nonimmediate_operand" "0,0")
14307 (match_operand:QI 2 "nonmemory_operand" "J,c")))
14308 (clobber (reg:CC FLAGS_REG))]
14309 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, DImode, operands)"
14311 ror{q}\t{%2, %0|%0, %2}
14312 ror{q}\t{%b2, %0|%0, %b2}"
14313 [(set_attr "type" "rotate")
14314 (set_attr "mode" "DI")])
14316 (define_expand "rotrsi3"
14317 [(set (match_operand:SI 0 "nonimmediate_operand" "")
14318 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "")
14319 (match_operand:QI 2 "nonmemory_operand" "")))]
14321 "ix86_expand_binary_operator (ROTATERT, SImode, operands); DONE;")
14323 (define_insn "*rotrsi3_1_one_bit"
14324 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm")
14325 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0")
14326 (match_operand:QI 2 "const1_operand" "")))
14327 (clobber (reg:CC FLAGS_REG))]
14328 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14329 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14331 [(set_attr "type" "rotate")
14332 (set_attr "length_immediate" "0")
14333 (set_attr "mode" "SI")])
14335 (define_insn "*rotrsi3_1_one_bit_zext"
14336 [(set (match_operand:DI 0 "register_operand" "=r")
14338 (rotatert:SI (match_operand:SI 1 "register_operand" "0")
14339 (match_operand:QI 2 "const1_operand" ""))))
14340 (clobber (reg:CC FLAGS_REG))]
14342 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14343 && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14345 [(set_attr "type" "rotate")
14346 (set_attr "length_immediate" "0")
14347 (set_attr "mode" "SI")])
14349 (define_insn "*rotrsi3_1"
14350 [(set (match_operand:SI 0 "nonimmediate_operand" "=rm,rm")
14351 (rotatert:SI (match_operand:SI 1 "nonimmediate_operand" "0,0")
14352 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14353 (clobber (reg:CC FLAGS_REG))]
14354 "ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14356 ror{l}\t{%2, %0|%0, %2}
14357 ror{l}\t{%b2, %0|%0, %b2}"
14358 [(set_attr "type" "rotate")
14359 (set_attr "mode" "SI")])
14361 (define_insn "*rotrsi3_1_zext"
14362 [(set (match_operand:DI 0 "register_operand" "=r,r")
14364 (rotatert:SI (match_operand:SI 1 "register_operand" "0,0")
14365 (match_operand:QI 2 "nonmemory_operand" "I,c"))))
14366 (clobber (reg:CC FLAGS_REG))]
14367 "TARGET_64BIT && ix86_binary_operator_ok (ROTATERT, SImode, operands)"
14369 ror{l}\t{%2, %k0|%k0, %2}
14370 ror{l}\t{%b2, %k0|%k0, %b2}"
14371 [(set_attr "type" "rotate")
14372 (set_attr "mode" "SI")])
14374 (define_expand "rotrhi3"
14375 [(set (match_operand:HI 0 "nonimmediate_operand" "")
14376 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "")
14377 (match_operand:QI 2 "nonmemory_operand" "")))]
14378 "TARGET_HIMODE_MATH"
14379 "ix86_expand_binary_operator (ROTATERT, HImode, operands); DONE;")
14381 (define_insn "*rotrhi3_one_bit"
14382 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm")
14383 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0")
14384 (match_operand:QI 2 "const1_operand" "")))
14385 (clobber (reg:CC FLAGS_REG))]
14386 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14387 && ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14389 [(set_attr "type" "rotate")
14390 (set_attr "length_immediate" "0")
14391 (set_attr "mode" "HI")])
14393 (define_insn "*rotrhi3_1"
14394 [(set (match_operand:HI 0 "nonimmediate_operand" "=rm,rm")
14395 (rotatert:HI (match_operand:HI 1 "nonimmediate_operand" "0,0")
14396 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14397 (clobber (reg:CC FLAGS_REG))]
14398 "ix86_binary_operator_ok (ROTATERT, HImode, operands)"
14400 ror{w}\t{%2, %0|%0, %2}
14401 ror{w}\t{%b2, %0|%0, %b2}"
14402 [(set_attr "type" "rotate")
14403 (set_attr "mode" "HI")])
14406 [(set (match_operand:HI 0 "register_operand" "")
14407 (rotatert:HI (match_dup 0) (const_int 8)))
14408 (clobber (reg:CC FLAGS_REG))]
14410 [(parallel [(set (strict_low_part (match_dup 0))
14411 (bswap:HI (match_dup 0)))
14412 (clobber (reg:CC FLAGS_REG))])]
14415 (define_expand "rotrqi3"
14416 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14417 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "")
14418 (match_operand:QI 2 "nonmemory_operand" "")))]
14419 "TARGET_QIMODE_MATH"
14420 "ix86_expand_binary_operator (ROTATERT, QImode, operands); DONE;")
14422 (define_insn "*rotrqi3_1_one_bit"
14423 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14424 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0")
14425 (match_operand:QI 2 "const1_operand" "")))
14426 (clobber (reg:CC FLAGS_REG))]
14427 "(TARGET_SHIFT1 || optimize_function_for_size_p (cfun))
14428 && ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14430 [(set_attr "type" "rotate")
14431 (set_attr "length_immediate" "0")
14432 (set_attr "mode" "QI")])
14434 (define_insn "*rotrqi3_1_one_bit_slp"
14435 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14436 (rotatert:QI (match_dup 0)
14437 (match_operand:QI 1 "const1_operand" "")))
14438 (clobber (reg:CC FLAGS_REG))]
14439 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14440 && (TARGET_SHIFT1 || optimize_function_for_size_p (cfun))"
14442 [(set_attr "type" "rotate1")
14443 (set_attr "length_immediate" "0")
14444 (set_attr "mode" "QI")])
14446 (define_insn "*rotrqi3_1"
14447 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm,qm")
14448 (rotatert:QI (match_operand:QI 1 "nonimmediate_operand" "0,0")
14449 (match_operand:QI 2 "nonmemory_operand" "I,c")))
14450 (clobber (reg:CC FLAGS_REG))]
14451 "ix86_binary_operator_ok (ROTATERT, QImode, operands)"
14453 ror{b}\t{%2, %0|%0, %2}
14454 ror{b}\t{%b2, %0|%0, %b2}"
14455 [(set_attr "type" "rotate")
14456 (set_attr "mode" "QI")])
14458 (define_insn "*rotrqi3_1_slp"
14459 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm,qm"))
14460 (rotatert:QI (match_dup 0)
14461 (match_operand:QI 1 "nonmemory_operand" "I,c")))
14462 (clobber (reg:CC FLAGS_REG))]
14463 "(! TARGET_PARTIAL_REG_STALL || optimize_function_for_size_p (cfun))
14464 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
14466 ror{b}\t{%1, %0|%0, %1}
14467 ror{b}\t{%b1, %0|%0, %b1}"
14468 [(set_attr "type" "rotate1")
14469 (set_attr "mode" "QI")])
14471 ;; Bit set / bit test instructions
14473 (define_expand "extv"
14474 [(set (match_operand:SI 0 "register_operand" "")
14475 (sign_extract:SI (match_operand:SI 1 "register_operand" "")
14476 (match_operand:SI 2 "const8_operand" "")
14477 (match_operand:SI 3 "const8_operand" "")))]
14480 /* Handle extractions from %ah et al. */
14481 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14484 /* From mips.md: extract_bit_field doesn't verify that our source
14485 matches the predicate, so check it again here. */
14486 if (! ext_register_operand (operands[1], VOIDmode))
14490 (define_expand "extzv"
14491 [(set (match_operand:SI 0 "register_operand" "")
14492 (zero_extract:SI (match_operand 1 "ext_register_operand" "")
14493 (match_operand:SI 2 "const8_operand" "")
14494 (match_operand:SI 3 "const8_operand" "")))]
14497 /* Handle extractions from %ah et al. */
14498 if (INTVAL (operands[2]) != 8 || INTVAL (operands[3]) != 8)
14501 /* From mips.md: extract_bit_field doesn't verify that our source
14502 matches the predicate, so check it again here. */
14503 if (! ext_register_operand (operands[1], VOIDmode))
14507 (define_expand "insv"
14508 [(set (zero_extract (match_operand 0 "ext_register_operand" "")
14509 (match_operand 1 "const8_operand" "")
14510 (match_operand 2 "const8_operand" ""))
14511 (match_operand 3 "register_operand" ""))]
14514 /* Handle insertions to %ah et al. */
14515 if (INTVAL (operands[1]) != 8 || INTVAL (operands[2]) != 8)
14518 /* From mips.md: insert_bit_field doesn't verify that our source
14519 matches the predicate, so check it again here. */
14520 if (! ext_register_operand (operands[0], VOIDmode))
14524 emit_insn (gen_movdi_insv_1_rex64 (operands[0], operands[3]));
14526 emit_insn (gen_movsi_insv_1 (operands[0], operands[3]));
14531 ;; %%% bts, btr, btc, bt.
14532 ;; In general these instructions are *slow* when applied to memory,
14533 ;; since they enforce atomic operation. When applied to registers,
14534 ;; it depends on the cpu implementation. They're never faster than
14535 ;; the corresponding and/ior/xor operations, so with 32-bit there's
14536 ;; no point. But in 64-bit, we can't hold the relevant immediates
14537 ;; within the instruction itself, so operating on bits in the high
14538 ;; 32-bits of a register becomes easier.
14540 ;; These are slow on Nocona, but fast on Athlon64. We do require the use
14541 ;; of btrq and btcq for corner cases of post-reload expansion of absdf and
14542 ;; negdf respectively, so they can never be disabled entirely.
14544 (define_insn "*btsq"
14545 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14547 (match_operand:DI 1 "const_0_to_63_operand" ""))
14549 (clobber (reg:CC FLAGS_REG))]
14550 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14551 "bts{q}\t{%1, %0|%0, %1}"
14552 [(set_attr "type" "alu1")
14553 (set_attr "prefix_0f" "1")
14554 (set_attr "mode" "DI")])
14556 (define_insn "*btrq"
14557 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14559 (match_operand:DI 1 "const_0_to_63_operand" ""))
14561 (clobber (reg:CC FLAGS_REG))]
14562 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14563 "btr{q}\t{%1, %0|%0, %1}"
14564 [(set_attr "type" "alu1")
14565 (set_attr "prefix_0f" "1")
14566 (set_attr "mode" "DI")])
14568 (define_insn "*btcq"
14569 [(set (zero_extract:DI (match_operand:DI 0 "register_operand" "+r")
14571 (match_operand:DI 1 "const_0_to_63_operand" ""))
14572 (not:DI (zero_extract:DI (match_dup 0) (const_int 1) (match_dup 1))))
14573 (clobber (reg:CC FLAGS_REG))]
14574 "TARGET_64BIT && (TARGET_USE_BT || reload_completed)"
14575 "btc{q}\t{%1, %0|%0, %1}"
14576 [(set_attr "type" "alu1")
14577 (set_attr "prefix_0f" "1")
14578 (set_attr "mode" "DI")])
14580 ;; Allow Nocona to avoid these instructions if a register is available.
14583 [(match_scratch:DI 2 "r")
14584 (parallel [(set (zero_extract:DI
14585 (match_operand:DI 0 "register_operand" "")
14587 (match_operand:DI 1 "const_0_to_63_operand" ""))
14589 (clobber (reg:CC FLAGS_REG))])]
14590 "TARGET_64BIT && !TARGET_USE_BT"
14593 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14596 if (HOST_BITS_PER_WIDE_INT >= 64)
14597 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14598 else if (i < HOST_BITS_PER_WIDE_INT)
14599 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14601 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14603 op1 = immed_double_const (lo, hi, DImode);
14606 emit_move_insn (operands[2], op1);
14610 emit_insn (gen_iordi3 (operands[0], operands[0], op1));
14615 [(match_scratch:DI 2 "r")
14616 (parallel [(set (zero_extract:DI
14617 (match_operand:DI 0 "register_operand" "")
14619 (match_operand:DI 1 "const_0_to_63_operand" ""))
14621 (clobber (reg:CC FLAGS_REG))])]
14622 "TARGET_64BIT && !TARGET_USE_BT"
14625 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14628 if (HOST_BITS_PER_WIDE_INT >= 64)
14629 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14630 else if (i < HOST_BITS_PER_WIDE_INT)
14631 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14633 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14635 op1 = immed_double_const (~lo, ~hi, DImode);
14638 emit_move_insn (operands[2], op1);
14642 emit_insn (gen_anddi3 (operands[0], operands[0], op1));
14647 [(match_scratch:DI 2 "r")
14648 (parallel [(set (zero_extract:DI
14649 (match_operand:DI 0 "register_operand" "")
14651 (match_operand:DI 1 "const_0_to_63_operand" ""))
14652 (not:DI (zero_extract:DI
14653 (match_dup 0) (const_int 1) (match_dup 1))))
14654 (clobber (reg:CC FLAGS_REG))])]
14655 "TARGET_64BIT && !TARGET_USE_BT"
14658 HOST_WIDE_INT i = INTVAL (operands[1]), hi, lo;
14661 if (HOST_BITS_PER_WIDE_INT >= 64)
14662 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14663 else if (i < HOST_BITS_PER_WIDE_INT)
14664 lo = (HOST_WIDE_INT)1 << i, hi = 0;
14666 lo = 0, hi = (HOST_WIDE_INT)1 << (i - HOST_BITS_PER_WIDE_INT);
14668 op1 = immed_double_const (lo, hi, DImode);
14671 emit_move_insn (operands[2], op1);
14675 emit_insn (gen_xordi3 (operands[0], operands[0], op1));
14679 (define_insn "*btdi_rex64"
14680 [(set (reg:CCC FLAGS_REG)
14683 (match_operand:DI 0 "register_operand" "r")
14685 (match_operand:DI 1 "nonmemory_operand" "rN"))
14687 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14688 "bt{q}\t{%1, %0|%0, %1}"
14689 [(set_attr "type" "alu1")
14690 (set_attr "prefix_0f" "1")
14691 (set_attr "mode" "DI")])
14693 (define_insn "*btsi"
14694 [(set (reg:CCC FLAGS_REG)
14697 (match_operand:SI 0 "register_operand" "r")
14699 (match_operand:SI 1 "nonmemory_operand" "rN"))
14701 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
14702 "bt{l}\t{%1, %0|%0, %1}"
14703 [(set_attr "type" "alu1")
14704 (set_attr "prefix_0f" "1")
14705 (set_attr "mode" "SI")])
14707 ;; Store-flag instructions.
14709 ;; For all sCOND expanders, also expand the compare or test insn that
14710 ;; generates cc0. Generate an equality comparison if `seq' or `sne'.
14712 ;; %%% Do the expansion to SImode. If PII, do things the xor+setcc way
14713 ;; to avoid partial register stalls. Otherwise do things the setcc+movzx
14714 ;; way, which can later delete the movzx if only QImode is needed.
14716 (define_insn "*setcc_1"
14717 [(set (match_operand:QI 0 "nonimmediate_operand" "=qm")
14718 (match_operator:QI 1 "ix86_comparison_operator"
14719 [(reg FLAGS_REG) (const_int 0)]))]
14722 [(set_attr "type" "setcc")
14723 (set_attr "mode" "QI")])
14725 (define_insn "*setcc_2"
14726 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" "+qm"))
14727 (match_operator:QI 1 "ix86_comparison_operator"
14728 [(reg FLAGS_REG) (const_int 0)]))]
14731 [(set_attr "type" "setcc")
14732 (set_attr "mode" "QI")])
14734 ;; In general it is not safe to assume too much about CCmode registers,
14735 ;; so simplify-rtx stops when it sees a second one. Under certain
14736 ;; conditions this is safe on x86, so help combine not create
14743 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14744 (ne:QI (match_operator 1 "ix86_comparison_operator"
14745 [(reg FLAGS_REG) (const_int 0)])
14748 [(set (match_dup 0) (match_dup 1))]
14750 PUT_MODE (operands[1], QImode);
14754 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14755 (ne:QI (match_operator 1 "ix86_comparison_operator"
14756 [(reg FLAGS_REG) (const_int 0)])
14759 [(set (match_dup 0) (match_dup 1))]
14761 PUT_MODE (operands[1], QImode);
14765 [(set (match_operand:QI 0 "nonimmediate_operand" "")
14766 (eq:QI (match_operator 1 "ix86_comparison_operator"
14767 [(reg FLAGS_REG) (const_int 0)])
14770 [(set (match_dup 0) (match_dup 1))]
14772 rtx new_op1 = copy_rtx (operands[1]);
14773 operands[1] = new_op1;
14774 PUT_MODE (new_op1, QImode);
14775 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14776 GET_MODE (XEXP (new_op1, 0))));
14778 /* Make sure that (a) the CCmode we have for the flags is strong
14779 enough for the reversed compare or (b) we have a valid FP compare. */
14780 if (! ix86_comparison_operator (new_op1, VOIDmode))
14785 [(set (strict_low_part (match_operand:QI 0 "nonimmediate_operand" ""))
14786 (eq:QI (match_operator 1 "ix86_comparison_operator"
14787 [(reg FLAGS_REG) (const_int 0)])
14790 [(set (match_dup 0) (match_dup 1))]
14792 rtx new_op1 = copy_rtx (operands[1]);
14793 operands[1] = new_op1;
14794 PUT_MODE (new_op1, QImode);
14795 PUT_CODE (new_op1, ix86_reverse_condition (GET_CODE (new_op1),
14796 GET_MODE (XEXP (new_op1, 0))));
14798 /* Make sure that (a) the CCmode we have for the flags is strong
14799 enough for the reversed compare or (b) we have a valid FP compare. */
14800 if (! ix86_comparison_operator (new_op1, VOIDmode))
14804 ;; The SSE store flag instructions saves 0 or 0xffffffff to the result.
14805 ;; subsequent logical operations are used to imitate conditional moves.
14806 ;; 0xffffffff is NaN, but not in normalized form, so we can't represent
14809 (define_insn "*avx_setcc<mode>"
14810 [(set (match_operand:MODEF 0 "register_operand" "=x")
14811 (match_operator:MODEF 1 "avx_comparison_float_operator"
14812 [(match_operand:MODEF 2 "register_operand" "x")
14813 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14815 "vcmp%D1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14816 [(set_attr "type" "ssecmp")
14817 (set_attr "prefix" "vex")
14818 (set_attr "length_immediate" "1")
14819 (set_attr "mode" "<MODE>")])
14821 (define_insn "*sse_setcc<mode>"
14822 [(set (match_operand:MODEF 0 "register_operand" "=x")
14823 (match_operator:MODEF 1 "sse_comparison_operator"
14824 [(match_operand:MODEF 2 "register_operand" "0")
14825 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14826 "SSE_FLOAT_MODE_P (<MODE>mode) && !TARGET_SSE5"
14827 "cmp%D1s<ssemodefsuffix>\t{%3, %0|%0, %3}"
14828 [(set_attr "type" "ssecmp")
14829 (set_attr "length_immediate" "1")
14830 (set_attr "mode" "<MODE>")])
14832 (define_insn "*sse5_setcc<mode>"
14833 [(set (match_operand:MODEF 0 "register_operand" "=x")
14834 (match_operator:MODEF 1 "sse5_comparison_float_operator"
14835 [(match_operand:MODEF 2 "register_operand" "x")
14836 (match_operand:MODEF 3 "nonimmediate_operand" "xm")]))]
14838 "com%Y1s<ssemodefsuffix>\t{%3, %2, %0|%0, %2, %3}"
14839 [(set_attr "type" "sse4arg")
14840 (set_attr "length_immediate" "1")
14841 (set_attr "mode" "<MODE>")])
14844 ;; Basic conditional jump instructions.
14845 ;; We ignore the overflow flag for signed branch instructions.
14847 (define_insn "*jcc_1"
14849 (if_then_else (match_operator 1 "ix86_comparison_operator"
14850 [(reg FLAGS_REG) (const_int 0)])
14851 (label_ref (match_operand 0 "" ""))
14855 [(set_attr "type" "ibr")
14856 (set_attr "modrm" "0")
14857 (set (attr "length")
14858 (if_then_else (and (ge (minus (match_dup 0) (pc))
14860 (lt (minus (match_dup 0) (pc))
14865 (define_insn "*jcc_2"
14867 (if_then_else (match_operator 1 "ix86_comparison_operator"
14868 [(reg FLAGS_REG) (const_int 0)])
14870 (label_ref (match_operand 0 "" ""))))]
14873 [(set_attr "type" "ibr")
14874 (set_attr "modrm" "0")
14875 (set (attr "length")
14876 (if_then_else (and (ge (minus (match_dup 0) (pc))
14878 (lt (minus (match_dup 0) (pc))
14883 ;; In general it is not safe to assume too much about CCmode registers,
14884 ;; so simplify-rtx stops when it sees a second one. Under certain
14885 ;; conditions this is safe on x86, so help combine not create
14893 (if_then_else (ne (match_operator 0 "ix86_comparison_operator"
14894 [(reg FLAGS_REG) (const_int 0)])
14896 (label_ref (match_operand 1 "" ""))
14900 (if_then_else (match_dup 0)
14901 (label_ref (match_dup 1))
14904 PUT_MODE (operands[0], VOIDmode);
14909 (if_then_else (eq (match_operator 0 "ix86_comparison_operator"
14910 [(reg FLAGS_REG) (const_int 0)])
14912 (label_ref (match_operand 1 "" ""))
14916 (if_then_else (match_dup 0)
14917 (label_ref (match_dup 1))
14920 rtx new_op0 = copy_rtx (operands[0]);
14921 operands[0] = new_op0;
14922 PUT_MODE (new_op0, VOIDmode);
14923 PUT_CODE (new_op0, ix86_reverse_condition (GET_CODE (new_op0),
14924 GET_MODE (XEXP (new_op0, 0))));
14926 /* Make sure that (a) the CCmode we have for the flags is strong
14927 enough for the reversed compare or (b) we have a valid FP compare. */
14928 if (! ix86_comparison_operator (new_op0, VOIDmode))
14932 ;; zero_extend in SImode is correct, since this is what combine pass
14933 ;; generates from shift insn with QImode operand. Actually, the mode of
14934 ;; operand 2 (bit offset operand) doesn't matter since bt insn takes
14935 ;; appropriate modulo of the bit offset value.
14937 (define_insn_and_split "*jcc_btdi_rex64"
14939 (if_then_else (match_operator 0 "bt_comparison_operator"
14941 (match_operand:DI 1 "register_operand" "r")
14944 (match_operand:QI 2 "register_operand" "r")))
14946 (label_ref (match_operand 3 "" ""))
14948 (clobber (reg:CC FLAGS_REG))]
14949 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))"
14952 [(set (reg:CCC FLAGS_REG)
14960 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14961 (label_ref (match_dup 3))
14964 operands[2] = simplify_gen_subreg (DImode, operands[2], QImode, 0);
14966 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
14969 ;; avoid useless masking of bit offset operand
14970 (define_insn_and_split "*jcc_btdi_mask_rex64"
14972 (if_then_else (match_operator 0 "bt_comparison_operator"
14974 (match_operand:DI 1 "register_operand" "r")
14977 (match_operand:SI 2 "register_operand" "r")
14978 (match_operand:SI 3 "const_int_operand" "n")))])
14979 (label_ref (match_operand 4 "" ""))
14981 (clobber (reg:CC FLAGS_REG))]
14982 "TARGET_64BIT && (TARGET_USE_BT || optimize_function_for_size_p (cfun))
14983 && (INTVAL (operands[3]) & 0x3f) == 0x3f"
14986 [(set (reg:CCC FLAGS_REG)
14994 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
14995 (label_ref (match_dup 4))
14998 operands[2] = simplify_gen_subreg (DImode, operands[2], SImode, 0);
15000 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15003 (define_insn_and_split "*jcc_btsi"
15005 (if_then_else (match_operator 0 "bt_comparison_operator"
15007 (match_operand:SI 1 "register_operand" "r")
15010 (match_operand:QI 2 "register_operand" "r")))
15012 (label_ref (match_operand 3 "" ""))
15014 (clobber (reg:CC FLAGS_REG))]
15015 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
15018 [(set (reg:CCC FLAGS_REG)
15026 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15027 (label_ref (match_dup 3))
15030 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15032 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15035 ;; avoid useless masking of bit offset operand
15036 (define_insn_and_split "*jcc_btsi_mask"
15038 (if_then_else (match_operator 0 "bt_comparison_operator"
15040 (match_operand:SI 1 "register_operand" "r")
15043 (match_operand:SI 2 "register_operand" "r")
15044 (match_operand:SI 3 "const_int_operand" "n")))])
15045 (label_ref (match_operand 4 "" ""))
15047 (clobber (reg:CC FLAGS_REG))]
15048 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15049 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15052 [(set (reg:CCC FLAGS_REG)
15060 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15061 (label_ref (match_dup 4))
15063 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15065 (define_insn_and_split "*jcc_btsi_1"
15067 (if_then_else (match_operator 0 "bt_comparison_operator"
15070 (match_operand:SI 1 "register_operand" "r")
15071 (match_operand:QI 2 "register_operand" "r"))
15074 (label_ref (match_operand 3 "" ""))
15076 (clobber (reg:CC FLAGS_REG))]
15077 "TARGET_USE_BT || optimize_function_for_size_p (cfun)"
15080 [(set (reg:CCC FLAGS_REG)
15088 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15089 (label_ref (match_dup 3))
15092 operands[2] = simplify_gen_subreg (SImode, operands[2], QImode, 0);
15094 PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));
15097 ;; avoid useless masking of bit offset operand
15098 (define_insn_and_split "*jcc_btsi_mask_1"
15101 (match_operator 0 "bt_comparison_operator"
15104 (match_operand:SI 1 "register_operand" "r")
15107 (match_operand:SI 2 "register_operand" "r")
15108 (match_operand:SI 3 "const_int_operand" "n")) 0))
15111 (label_ref (match_operand 4 "" ""))
15113 (clobber (reg:CC FLAGS_REG))]
15114 "(TARGET_USE_BT || optimize_function_for_size_p (cfun))
15115 && (INTVAL (operands[3]) & 0x1f) == 0x1f"
15118 [(set (reg:CCC FLAGS_REG)
15126 (if_then_else (match_op_dup 0 [(reg:CCC FLAGS_REG) (const_int 0)])
15127 (label_ref (match_dup 4))
15129 "PUT_CODE (operands[0], reverse_condition (GET_CODE (operands[0])));")
15131 ;; Define combination compare-and-branch fp compare instructions to use
15132 ;; during early optimization. Splitting the operation apart early makes
15133 ;; for bad code when we want to reverse the operation.
15135 (define_insn "*fp_jcc_1_mixed"
15137 (if_then_else (match_operator 0 "comparison_operator"
15138 [(match_operand 1 "register_operand" "f,x")
15139 (match_operand 2 "nonimmediate_operand" "f,xm")])
15140 (label_ref (match_operand 3 "" ""))
15142 (clobber (reg:CCFP FPSR_REG))
15143 (clobber (reg:CCFP FLAGS_REG))]
15144 "TARGET_MIX_SSE_I387
15145 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
15146 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15147 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15150 (define_insn "*fp_jcc_1_sse"
15152 (if_then_else (match_operator 0 "comparison_operator"
15153 [(match_operand 1 "register_operand" "x")
15154 (match_operand 2 "nonimmediate_operand" "xm")])
15155 (label_ref (match_operand 3 "" ""))
15157 (clobber (reg:CCFP FPSR_REG))
15158 (clobber (reg:CCFP FLAGS_REG))]
15160 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
15161 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15162 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15165 (define_insn "*fp_jcc_1_387"
15167 (if_then_else (match_operator 0 "comparison_operator"
15168 [(match_operand 1 "register_operand" "f")
15169 (match_operand 2 "register_operand" "f")])
15170 (label_ref (match_operand 3 "" ""))
15172 (clobber (reg:CCFP FPSR_REG))
15173 (clobber (reg:CCFP FLAGS_REG))]
15174 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15176 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15177 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15180 (define_insn "*fp_jcc_2_mixed"
15182 (if_then_else (match_operator 0 "comparison_operator"
15183 [(match_operand 1 "register_operand" "f,x")
15184 (match_operand 2 "nonimmediate_operand" "f,xm")])
15186 (label_ref (match_operand 3 "" ""))))
15187 (clobber (reg:CCFP FPSR_REG))
15188 (clobber (reg:CCFP FLAGS_REG))]
15189 "TARGET_MIX_SSE_I387
15190 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
15191 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15192 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15195 (define_insn "*fp_jcc_2_sse"
15197 (if_then_else (match_operator 0 "comparison_operator"
15198 [(match_operand 1 "register_operand" "x")
15199 (match_operand 2 "nonimmediate_operand" "xm")])
15201 (label_ref (match_operand 3 "" ""))))
15202 (clobber (reg:CCFP FPSR_REG))
15203 (clobber (reg:CCFP FLAGS_REG))]
15205 && SSE_FLOAT_MODE_P (GET_MODE (operands[1]))
15206 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15207 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15210 (define_insn "*fp_jcc_2_387"
15212 (if_then_else (match_operator 0 "comparison_operator"
15213 [(match_operand 1 "register_operand" "f")
15214 (match_operand 2 "register_operand" "f")])
15216 (label_ref (match_operand 3 "" ""))))
15217 (clobber (reg:CCFP FPSR_REG))
15218 (clobber (reg:CCFP FLAGS_REG))]
15219 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15221 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15222 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15225 (define_insn "*fp_jcc_3_387"
15227 (if_then_else (match_operator 0 "comparison_operator"
15228 [(match_operand 1 "register_operand" "f")
15229 (match_operand 2 "nonimmediate_operand" "fm")])
15230 (label_ref (match_operand 3 "" ""))
15232 (clobber (reg:CCFP FPSR_REG))
15233 (clobber (reg:CCFP FLAGS_REG))
15234 (clobber (match_scratch:HI 4 "=a"))]
15236 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
15237 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15238 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
15239 && SELECT_CC_MODE (GET_CODE (operands[0]),
15240 operands[1], operands[2]) == CCFPmode
15241 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15244 (define_insn "*fp_jcc_4_387"
15246 (if_then_else (match_operator 0 "comparison_operator"
15247 [(match_operand 1 "register_operand" "f")
15248 (match_operand 2 "nonimmediate_operand" "fm")])
15250 (label_ref (match_operand 3 "" ""))))
15251 (clobber (reg:CCFP FPSR_REG))
15252 (clobber (reg:CCFP FLAGS_REG))
15253 (clobber (match_scratch:HI 4 "=a"))]
15255 && (GET_MODE (operands[1]) == SFmode || GET_MODE (operands[1]) == DFmode)
15256 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15257 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
15258 && SELECT_CC_MODE (GET_CODE (operands[0]),
15259 operands[1], operands[2]) == CCFPmode
15260 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15263 (define_insn "*fp_jcc_5_387"
15265 (if_then_else (match_operator 0 "comparison_operator"
15266 [(match_operand 1 "register_operand" "f")
15267 (match_operand 2 "register_operand" "f")])
15268 (label_ref (match_operand 3 "" ""))
15270 (clobber (reg:CCFP FPSR_REG))
15271 (clobber (reg:CCFP FLAGS_REG))
15272 (clobber (match_scratch:HI 4 "=a"))]
15273 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15274 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15275 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15278 (define_insn "*fp_jcc_6_387"
15280 (if_then_else (match_operator 0 "comparison_operator"
15281 [(match_operand 1 "register_operand" "f")
15282 (match_operand 2 "register_operand" "f")])
15284 (label_ref (match_operand 3 "" ""))))
15285 (clobber (reg:CCFP FPSR_REG))
15286 (clobber (reg:CCFP FLAGS_REG))
15287 (clobber (match_scratch:HI 4 "=a"))]
15288 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15289 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15290 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15293 (define_insn "*fp_jcc_7_387"
15295 (if_then_else (match_operator 0 "comparison_operator"
15296 [(match_operand 1 "register_operand" "f")
15297 (match_operand 2 "const0_operand" "")])
15298 (label_ref (match_operand 3 "" ""))
15300 (clobber (reg:CCFP FPSR_REG))
15301 (clobber (reg:CCFP FLAGS_REG))
15302 (clobber (match_scratch:HI 4 "=a"))]
15303 "X87_FLOAT_MODE_P (GET_MODE (operands[1]))
15304 && GET_MODE (operands[1]) == GET_MODE (operands[2])
15305 && !ix86_use_fcomi_compare (GET_CODE (operands[0]))
15306 && SELECT_CC_MODE (GET_CODE (operands[0]),
15307 operands[1], operands[2]) == CCFPmode
15308 && ix86_fp_jump_nontrivial_p (GET_CODE (operands[0]))"
15311 ;; The order of operands in *fp_jcc_8_387 is forced by combine in
15312 ;; simplify_comparison () function. Float operator is treated as RTX_OBJ
15313 ;; with a precedence over other operators and is always put in the first
15314 ;; place. Swap condition and operands to match ficom instruction.
15316 (define_insn "*fp_jcc_8<mode>_387"
15318 (if_then_else (match_operator 0 "comparison_operator"
15319 [(match_operator 1 "float_operator"
15320 [(match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r")])
15321 (match_operand 3 "register_operand" "f,f")])
15322 (label_ref (match_operand 4 "" ""))
15324 (clobber (reg:CCFP FPSR_REG))
15325 (clobber (reg:CCFP FLAGS_REG))
15326 (clobber (match_scratch:HI 5 "=a,a"))]
15327 "X87_FLOAT_MODE_P (GET_MODE (operands[3]))
15328 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))
15329 && GET_MODE (operands[1]) == GET_MODE (operands[3])
15330 && !ix86_use_fcomi_compare (swap_condition (GET_CODE (operands[0])))
15331 && ix86_fp_compare_mode (swap_condition (GET_CODE (operands[0]))) == CCFPmode
15332 && ix86_fp_jump_nontrivial_p (swap_condition (GET_CODE (operands[0])))"
15337 (if_then_else (match_operator 0 "comparison_operator"
15338 [(match_operand 1 "register_operand" "")
15339 (match_operand 2 "nonimmediate_operand" "")])
15340 (match_operand 3 "" "")
15341 (match_operand 4 "" "")))
15342 (clobber (reg:CCFP FPSR_REG))
15343 (clobber (reg:CCFP FLAGS_REG))]
15347 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15348 operands[3], operands[4], NULL_RTX, NULL_RTX);
15354 (if_then_else (match_operator 0 "comparison_operator"
15355 [(match_operand 1 "register_operand" "")
15356 (match_operand 2 "general_operand" "")])
15357 (match_operand 3 "" "")
15358 (match_operand 4 "" "")))
15359 (clobber (reg:CCFP FPSR_REG))
15360 (clobber (reg:CCFP FLAGS_REG))
15361 (clobber (match_scratch:HI 5 "=a"))]
15365 ix86_split_fp_branch (GET_CODE (operands[0]), operands[1], operands[2],
15366 operands[3], operands[4], operands[5], NULL_RTX);
15372 (if_then_else (match_operator 0 "comparison_operator"
15373 [(match_operator 1 "float_operator"
15374 [(match_operand:X87MODEI12 2 "memory_operand" "")])
15375 (match_operand 3 "register_operand" "")])
15376 (match_operand 4 "" "")
15377 (match_operand 5 "" "")))
15378 (clobber (reg:CCFP FPSR_REG))
15379 (clobber (reg:CCFP FLAGS_REG))
15380 (clobber (match_scratch:HI 6 "=a"))]
15384 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[2]);
15385 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15386 operands[3], operands[7],
15387 operands[4], operands[5], operands[6], NULL_RTX);
15391 ;; %%% Kill this when reload knows how to do it.
15394 (if_then_else (match_operator 0 "comparison_operator"
15395 [(match_operator 1 "float_operator"
15396 [(match_operand:X87MODEI12 2 "register_operand" "")])
15397 (match_operand 3 "register_operand" "")])
15398 (match_operand 4 "" "")
15399 (match_operand 5 "" "")))
15400 (clobber (reg:CCFP FPSR_REG))
15401 (clobber (reg:CCFP FLAGS_REG))
15402 (clobber (match_scratch:HI 6 "=a"))]
15406 operands[7] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
15407 operands[7] = gen_rtx_FLOAT (GET_MODE (operands[1]), operands[7]);
15408 ix86_split_fp_branch (swap_condition (GET_CODE (operands[0])),
15409 operands[3], operands[7],
15410 operands[4], operands[5], operands[6], operands[2]);
15414 ;; Unconditional and other jump instructions
15416 (define_insn "jump"
15418 (label_ref (match_operand 0 "" "")))]
15421 [(set_attr "type" "ibr")
15422 (set (attr "length")
15423 (if_then_else (and (ge (minus (match_dup 0) (pc))
15425 (lt (minus (match_dup 0) (pc))
15429 (set_attr "modrm" "0")])
15431 (define_expand "indirect_jump"
15432 [(set (pc) (match_operand 0 "nonimmediate_operand" ""))]
15436 (define_insn "*indirect_jump"
15437 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))]
15440 [(set_attr "type" "ibr")
15441 (set_attr "length_immediate" "0")])
15443 (define_expand "tablejump"
15444 [(parallel [(set (pc) (match_operand 0 "nonimmediate_operand" ""))
15445 (use (label_ref (match_operand 1 "" "")))])]
15448 /* In PIC mode, the table entries are stored GOT (32-bit) or PC (64-bit)
15449 relative. Convert the relative address to an absolute address. */
15453 enum rtx_code code;
15455 /* We can't use @GOTOFF for text labels on VxWorks;
15456 see gotoff_operand. */
15457 if (TARGET_64BIT || TARGET_VXWORKS_RTP)
15461 op1 = gen_rtx_LABEL_REF (Pmode, operands[1]);
15463 else if (TARGET_MACHO || HAVE_AS_GOTOFF_IN_DATA)
15467 op1 = pic_offset_table_rtx;
15472 op0 = pic_offset_table_rtx;
15476 operands[0] = expand_simple_binop (Pmode, code, op0, op1, NULL_RTX, 0,
15481 (define_insn "*tablejump_1"
15482 [(set (pc) (match_operand:P 0 "nonimmediate_operand" "rm"))
15483 (use (label_ref (match_operand 1 "" "")))]
15486 [(set_attr "type" "ibr")
15487 (set_attr "length_immediate" "0")])
15489 ;; Convert setcc + movzbl to xor + setcc if operands don't overlap.
15492 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15493 (set (match_operand:QI 1 "register_operand" "")
15494 (match_operator:QI 2 "ix86_comparison_operator"
15495 [(reg FLAGS_REG) (const_int 0)]))
15496 (set (match_operand 3 "q_regs_operand" "")
15497 (zero_extend (match_dup 1)))]
15498 "(peep2_reg_dead_p (3, operands[1])
15499 || operands_match_p (operands[1], operands[3]))
15500 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15501 [(set (match_dup 4) (match_dup 0))
15502 (set (strict_low_part (match_dup 5))
15505 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15506 operands[5] = gen_lowpart (QImode, operands[3]);
15507 ix86_expand_clear (operands[3]);
15510 ;; Similar, but match zero_extendhisi2_and, which adds a clobber.
15513 [(set (reg FLAGS_REG) (match_operand 0 "" ""))
15514 (set (match_operand:QI 1 "register_operand" "")
15515 (match_operator:QI 2 "ix86_comparison_operator"
15516 [(reg FLAGS_REG) (const_int 0)]))
15517 (parallel [(set (match_operand 3 "q_regs_operand" "")
15518 (zero_extend (match_dup 1)))
15519 (clobber (reg:CC FLAGS_REG))])]
15520 "(peep2_reg_dead_p (3, operands[1])
15521 || operands_match_p (operands[1], operands[3]))
15522 && ! reg_overlap_mentioned_p (operands[3], operands[0])"
15523 [(set (match_dup 4) (match_dup 0))
15524 (set (strict_low_part (match_dup 5))
15527 operands[4] = gen_rtx_REG (GET_MODE (operands[0]), FLAGS_REG);
15528 operands[5] = gen_lowpart (QImode, operands[3]);
15529 ix86_expand_clear (operands[3]);
15532 ;; Call instructions.
15534 ;; The predicates normally associated with named expanders are not properly
15535 ;; checked for calls. This is a bug in the generic code, but it isn't that
15536 ;; easy to fix. Ignore it for now and be prepared to fix things up.
15538 ;; Call subroutine returning no value.
15540 (define_expand "call_pop"
15541 [(parallel [(call (match_operand:QI 0 "" "")
15542 (match_operand:SI 1 "" ""))
15543 (set (reg:SI SP_REG)
15544 (plus:SI (reg:SI SP_REG)
15545 (match_operand:SI 3 "" "")))])]
15548 ix86_expand_call (NULL, operands[0], operands[1], operands[2], operands[3], 0);
15552 (define_insn "*call_pop_0"
15553 [(call (mem:QI (match_operand:SI 0 "constant_call_address_operand" ""))
15554 (match_operand:SI 1 "" ""))
15555 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15556 (match_operand:SI 2 "immediate_operand" "")))]
15559 if (SIBLING_CALL_P (insn))
15562 return "call\t%P0";
15564 [(set_attr "type" "call")])
15566 (define_insn "*call_pop_1"
15567 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15568 (match_operand:SI 1 "" ""))
15569 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
15570 (match_operand:SI 2 "immediate_operand" "i")))]
15573 if (constant_call_address_operand (operands[0], Pmode))
15575 if (SIBLING_CALL_P (insn))
15578 return "call\t%P0";
15580 if (SIBLING_CALL_P (insn))
15583 return "call\t%A0";
15585 [(set_attr "type" "call")])
15587 (define_expand "call"
15588 [(call (match_operand:QI 0 "" "")
15589 (match_operand 1 "" ""))
15590 (use (match_operand 2 "" ""))]
15593 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 0);
15597 (define_expand "sibcall"
15598 [(call (match_operand:QI 0 "" "")
15599 (match_operand 1 "" ""))
15600 (use (match_operand 2 "" ""))]
15603 ix86_expand_call (NULL, operands[0], operands[1], operands[2], NULL, 1);
15607 (define_insn "*call_0"
15608 [(call (mem:QI (match_operand 0 "constant_call_address_operand" ""))
15609 (match_operand 1 "" ""))]
15612 if (SIBLING_CALL_P (insn))
15615 return "call\t%P0";
15617 [(set_attr "type" "call")])
15619 (define_insn "*call_1"
15620 [(call (mem:QI (match_operand:SI 0 "call_insn_operand" "rsm"))
15621 (match_operand 1 "" ""))]
15622 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
15624 if (constant_call_address_operand (operands[0], Pmode))
15625 return "call\t%P0";
15626 return "call\t%A0";
15628 [(set_attr "type" "call")])
15630 (define_insn "*sibcall_1"
15631 [(call (mem:QI (match_operand:SI 0 "sibcall_insn_operand" "s,c,d,a"))
15632 (match_operand 1 "" ""))]
15633 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
15635 if (constant_call_address_operand (operands[0], Pmode))
15639 [(set_attr "type" "call")])
15641 (define_insn "*call_1_rex64"
15642 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15643 (match_operand 1 "" ""))]
15644 "!SIBLING_CALL_P (insn) && TARGET_64BIT
15645 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
15647 if (constant_call_address_operand (operands[0], Pmode))
15648 return "call\t%P0";
15649 return "call\t%A0";
15651 [(set_attr "type" "call")])
15653 (define_insn "*call_1_rex64_ms_sysv"
15654 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rsm"))
15655 (match_operand 1 "" ""))
15656 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
15657 (clobber (reg:TI XMM6_REG))
15658 (clobber (reg:TI XMM7_REG))
15659 (clobber (reg:TI XMM8_REG))
15660 (clobber (reg:TI XMM9_REG))
15661 (clobber (reg:TI XMM10_REG))
15662 (clobber (reg:TI XMM11_REG))
15663 (clobber (reg:TI XMM12_REG))
15664 (clobber (reg:TI XMM13_REG))
15665 (clobber (reg:TI XMM14_REG))
15666 (clobber (reg:TI XMM15_REG))
15667 (clobber (reg:DI SI_REG))
15668 (clobber (reg:DI DI_REG))]
15669 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15671 if (constant_call_address_operand (operands[0], Pmode))
15672 return "call\t%P0";
15673 return "call\t%A0";
15675 [(set_attr "type" "call")])
15677 (define_insn "*call_1_rex64_large"
15678 [(call (mem:QI (match_operand:DI 0 "call_insn_operand" "rm"))
15679 (match_operand 1 "" ""))]
15680 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
15682 [(set_attr "type" "call")])
15684 (define_insn "*sibcall_1_rex64"
15685 [(call (mem:QI (match_operand:DI 0 "constant_call_address_operand" ""))
15686 (match_operand 1 "" ""))]
15687 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15689 [(set_attr "type" "call")])
15691 (define_insn "*sibcall_1_rex64_v"
15692 [(call (mem:QI (reg:DI R11_REG))
15693 (match_operand 0 "" ""))]
15694 "SIBLING_CALL_P (insn) && TARGET_64BIT"
15696 [(set_attr "type" "call")])
15699 ;; Call subroutine, returning value in operand 0
15701 (define_expand "call_value_pop"
15702 [(parallel [(set (match_operand 0 "" "")
15703 (call (match_operand:QI 1 "" "")
15704 (match_operand:SI 2 "" "")))
15705 (set (reg:SI SP_REG)
15706 (plus:SI (reg:SI SP_REG)
15707 (match_operand:SI 4 "" "")))])]
15710 ix86_expand_call (operands[0], operands[1], operands[2],
15711 operands[3], operands[4], 0);
15715 (define_expand "call_value"
15716 [(set (match_operand 0 "" "")
15717 (call (match_operand:QI 1 "" "")
15718 (match_operand:SI 2 "" "")))
15719 (use (match_operand:SI 3 "" ""))]
15720 ;; Operand 2 not used on the i386.
15723 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 0);
15727 (define_expand "sibcall_value"
15728 [(set (match_operand 0 "" "")
15729 (call (match_operand:QI 1 "" "")
15730 (match_operand:SI 2 "" "")))
15731 (use (match_operand:SI 3 "" ""))]
15732 ;; Operand 2 not used on the i386.
15735 ix86_expand_call (operands[0], operands[1], operands[2], operands[3], NULL, 1);
15739 ;; Call subroutine returning any type.
15741 (define_expand "untyped_call"
15742 [(parallel [(call (match_operand 0 "" "")
15744 (match_operand 1 "" "")
15745 (match_operand 2 "" "")])]
15750 /* In order to give reg-stack an easier job in validating two
15751 coprocessor registers as containing a possible return value,
15752 simply pretend the untyped call returns a complex long double
15755 We can't use SSE_REGPARM_MAX here since callee is unprototyped
15756 and should have the default ABI. */
15758 ix86_expand_call ((TARGET_FLOAT_RETURNS_IN_80387
15759 ? gen_rtx_REG (XCmode, FIRST_FLOAT_REG) : NULL),
15760 operands[0], const0_rtx,
15761 GEN_INT ((TARGET_64BIT
15762 ? (ix86_abi == SYSV_ABI
15763 ? X86_64_SSE_REGPARM_MAX
15764 : X86_64_MS_SSE_REGPARM_MAX)
15765 : X86_32_SSE_REGPARM_MAX)
15769 for (i = 0; i < XVECLEN (operands[2], 0); i++)
15771 rtx set = XVECEXP (operands[2], 0, i);
15772 emit_move_insn (SET_DEST (set), SET_SRC (set));
15775 /* The optimizer does not know that the call sets the function value
15776 registers we stored in the result block. We avoid problems by
15777 claiming that all hard registers are used and clobbered at this
15779 emit_insn (gen_blockage ());
15784 ;; Prologue and epilogue instructions
15786 ;; UNSPEC_VOLATILE is considered to use and clobber all hard registers and
15787 ;; all of memory. This blocks insns from being moved across this point.
15789 (define_insn "blockage"
15790 [(unspec_volatile [(const_int 0)] UNSPECV_BLOCKAGE)]
15793 [(set_attr "length" "0")])
15795 ;; Do not schedule instructions accessing memory across this point.
15797 (define_expand "memory_blockage"
15798 [(set (match_dup 0)
15799 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15802 operands[0] = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
15803 MEM_VOLATILE_P (operands[0]) = 1;
15806 (define_insn "*memory_blockage"
15807 [(set (match_operand:BLK 0 "" "")
15808 (unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BLOCKAGE))]
15811 [(set_attr "length" "0")])
15813 ;; As USE insns aren't meaningful after reload, this is used instead
15814 ;; to prevent deleting instructions setting registers for PIC code
15815 (define_insn "prologue_use"
15816 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_PROLOGUE_USE)]
15819 [(set_attr "length" "0")])
15821 ;; Insn emitted into the body of a function to return from a function.
15822 ;; This is only done if the function's epilogue is known to be simple.
15823 ;; See comments for ix86_can_use_return_insn_p in i386.c.
15825 (define_expand "return"
15827 "ix86_can_use_return_insn_p ()"
15829 if (crtl->args.pops_args)
15831 rtx popc = GEN_INT (crtl->args.pops_args);
15832 emit_jump_insn (gen_return_pop_internal (popc));
15837 (define_insn "return_internal"
15841 [(set_attr "length" "1")
15842 (set_attr "atom_unit" "jeu")
15843 (set_attr "length_immediate" "0")
15844 (set_attr "modrm" "0")])
15846 ;; Used by x86_machine_dependent_reorg to avoid penalty on single byte RET
15847 ;; instruction Athlon and K8 have.
15849 (define_insn "return_internal_long"
15851 (unspec [(const_int 0)] UNSPEC_REP)]
15854 [(set_attr "length" "2")
15855 (set_attr "atom_unit" "jeu")
15856 (set_attr "length_immediate" "0")
15857 (set_attr "prefix_rep" "1")
15858 (set_attr "modrm" "0")])
15860 (define_insn "return_pop_internal"
15862 (use (match_operand:SI 0 "const_int_operand" ""))]
15865 [(set_attr "length" "3")
15866 (set_attr "atom_unit" "jeu")
15867 (set_attr "length_immediate" "2")
15868 (set_attr "modrm" "0")])
15870 (define_insn "return_indirect_internal"
15872 (use (match_operand:SI 0 "register_operand" "r"))]
15875 [(set_attr "type" "ibr")
15876 (set_attr "length_immediate" "0")])
15882 [(set_attr "length" "1")
15883 (set_attr "length_immediate" "0")
15884 (set_attr "modrm" "0")])
15886 ;; Pad to 16-byte boundary, max skip in op0. Used to avoid
15887 ;; branch prediction penalty for the third jump in a 16-byte
15891 [(unspec_volatile [(match_operand 0 "" "")] UNSPECV_ALIGN)]
15894 #ifdef ASM_OUTPUT_MAX_SKIP_PAD
15895 ASM_OUTPUT_MAX_SKIP_PAD (asm_out_file, 4, (int)INTVAL (operands[0]));
15897 /* It is tempting to use ASM_OUTPUT_ALIGN here, but we don't want to do that.
15898 The align insn is used to avoid 3 jump instructions in the row to improve
15899 branch prediction and the benefits hardly outweigh the cost of extra 8
15900 nops on the average inserted by full alignment pseudo operation. */
15904 [(set_attr "length" "16")])
15906 (define_expand "prologue"
15909 "ix86_expand_prologue (); DONE;")
15911 (define_insn "set_got"
15912 [(set (match_operand:SI 0 "register_operand" "=r")
15913 (unspec:SI [(const_int 0)] UNSPEC_SET_GOT))
15914 (clobber (reg:CC FLAGS_REG))]
15916 { return output_set_got (operands[0], NULL_RTX); }
15917 [(set_attr "type" "multi")
15918 (set_attr "length" "12")])
15920 (define_insn "set_got_labelled"
15921 [(set (match_operand:SI 0 "register_operand" "=r")
15922 (unspec:SI [(label_ref (match_operand 1 "" ""))]
15924 (clobber (reg:CC FLAGS_REG))]
15926 { return output_set_got (operands[0], operands[1]); }
15927 [(set_attr "type" "multi")
15928 (set_attr "length" "12")])
15930 (define_insn "set_got_rex64"
15931 [(set (match_operand:DI 0 "register_operand" "=r")
15932 (unspec:DI [(const_int 0)] UNSPEC_SET_GOT))]
15934 "lea{q}\t{_GLOBAL_OFFSET_TABLE_(%%rip), %0|%0, _GLOBAL_OFFSET_TABLE_[rip]}"
15935 [(set_attr "type" "lea")
15936 (set_attr "length_address" "4")
15937 (set_attr "mode" "DI")])
15939 (define_insn "set_rip_rex64"
15940 [(set (match_operand:DI 0 "register_operand" "=r")
15941 (unspec:DI [(label_ref (match_operand 1 "" ""))] UNSPEC_SET_RIP))]
15943 "lea{q}\t{%l1(%%rip), %0|%0, %l1[rip]}"
15944 [(set_attr "type" "lea")
15945 (set_attr "length_address" "4")
15946 (set_attr "mode" "DI")])
15948 (define_insn "set_got_offset_rex64"
15949 [(set (match_operand:DI 0 "register_operand" "=r")
15951 [(label_ref (match_operand 1 "" ""))]
15952 UNSPEC_SET_GOT_OFFSET))]
15954 "movabs{q}\t{$_GLOBAL_OFFSET_TABLE_-%l1, %0|%0, OFFSET FLAT:_GLOBAL_OFFSET_TABLE_-%l1}"
15955 [(set_attr "type" "imov")
15956 (set_attr "length_immediate" "0")
15957 (set_attr "length_address" "8")
15958 (set_attr "mode" "DI")])
15960 (define_expand "epilogue"
15963 "ix86_expand_epilogue (1); DONE;")
15965 (define_expand "sibcall_epilogue"
15968 "ix86_expand_epilogue (0); DONE;")
15970 (define_expand "eh_return"
15971 [(use (match_operand 0 "register_operand" ""))]
15974 rtx tmp, sa = EH_RETURN_STACKADJ_RTX, ra = operands[0];
15976 /* Tricky bit: we write the address of the handler to which we will
15977 be returning into someone else's stack frame, one word below the
15978 stack address we wish to restore. */
15979 tmp = gen_rtx_PLUS (Pmode, arg_pointer_rtx, sa);
15980 tmp = plus_constant (tmp, -UNITS_PER_WORD);
15981 tmp = gen_rtx_MEM (Pmode, tmp);
15982 emit_move_insn (tmp, ra);
15984 emit_jump_insn (gen_eh_return_internal ());
15989 (define_insn_and_split "eh_return_internal"
15993 "epilogue_completed"
15995 "ix86_expand_epilogue (2); DONE;")
15997 (define_insn "leave"
15998 [(set (reg:SI SP_REG) (plus:SI (reg:SI BP_REG) (const_int 4)))
15999 (set (reg:SI BP_REG) (mem:SI (reg:SI BP_REG)))
16000 (clobber (mem:BLK (scratch)))]
16003 [(set_attr "type" "leave")])
16005 (define_insn "leave_rex64"
16006 [(set (reg:DI SP_REG) (plus:DI (reg:DI BP_REG) (const_int 8)))
16007 (set (reg:DI BP_REG) (mem:DI (reg:DI BP_REG)))
16008 (clobber (mem:BLK (scratch)))]
16011 [(set_attr "type" "leave")])
16013 (define_expand "ffssi2"
16015 [(set (match_operand:SI 0 "register_operand" "")
16016 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "")))
16017 (clobber (match_scratch:SI 2 ""))
16018 (clobber (reg:CC FLAGS_REG))])]
16023 emit_insn (gen_ffs_cmove (operands[0], operands[1]));
16028 (define_expand "ffs_cmove"
16029 [(set (match_dup 2) (const_int -1))
16030 (parallel [(set (reg:CCZ FLAGS_REG)
16031 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "")
16033 (set (match_operand:SI 0 "register_operand" "")
16034 (ctz:SI (match_dup 1)))])
16035 (set (match_dup 0) (if_then_else:SI
16036 (eq (reg:CCZ FLAGS_REG) (const_int 0))
16039 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16040 (clobber (reg:CC FLAGS_REG))])]
16042 "operands[2] = gen_reg_rtx (SImode);")
16044 (define_insn_and_split "*ffs_no_cmove"
16045 [(set (match_operand:SI 0 "register_operand" "=r")
16046 (ffs:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16047 (clobber (match_scratch:SI 2 "=&q"))
16048 (clobber (reg:CC FLAGS_REG))]
16051 "&& reload_completed"
16052 [(parallel [(set (reg:CCZ FLAGS_REG)
16053 (compare:CCZ (match_dup 1) (const_int 0)))
16054 (set (match_dup 0) (ctz:SI (match_dup 1)))])
16055 (set (strict_low_part (match_dup 3))
16056 (eq:QI (reg:CCZ FLAGS_REG) (const_int 0)))
16057 (parallel [(set (match_dup 2) (neg:SI (match_dup 2)))
16058 (clobber (reg:CC FLAGS_REG))])
16059 (parallel [(set (match_dup 0) (ior:SI (match_dup 0) (match_dup 2)))
16060 (clobber (reg:CC FLAGS_REG))])
16061 (parallel [(set (match_dup 0) (plus:SI (match_dup 0) (const_int 1)))
16062 (clobber (reg:CC FLAGS_REG))])]
16064 operands[3] = gen_lowpart (QImode, operands[2]);
16065 ix86_expand_clear (operands[2]);
16068 (define_insn "*ffssi_1"
16069 [(set (reg:CCZ FLAGS_REG)
16070 (compare:CCZ (match_operand:SI 1 "nonimmediate_operand" "rm")
16072 (set (match_operand:SI 0 "register_operand" "=r")
16073 (ctz:SI (match_dup 1)))]
16075 "bsf{l}\t{%1, %0|%0, %1}"
16076 [(set_attr "type" "alu1")
16077 (set_attr "prefix_0f" "1")
16078 (set_attr "mode" "SI")])
16080 (define_expand "ffsdi2"
16081 [(set (match_dup 2) (const_int -1))
16082 (parallel [(set (reg:CCZ FLAGS_REG)
16083 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "")
16085 (set (match_operand:DI 0 "register_operand" "")
16086 (ctz:DI (match_dup 1)))])
16087 (set (match_dup 0) (if_then_else:DI
16088 (eq (reg:CCZ FLAGS_REG) (const_int 0))
16091 (parallel [(set (match_dup 0) (plus:DI (match_dup 0) (const_int 1)))
16092 (clobber (reg:CC FLAGS_REG))])]
16094 "operands[2] = gen_reg_rtx (DImode);")
16096 (define_insn "*ffsdi_1"
16097 [(set (reg:CCZ FLAGS_REG)
16098 (compare:CCZ (match_operand:DI 1 "nonimmediate_operand" "rm")
16100 (set (match_operand:DI 0 "register_operand" "=r")
16101 (ctz:DI (match_dup 1)))]
16103 "bsf{q}\t{%1, %0|%0, %1}"
16104 [(set_attr "type" "alu1")
16105 (set_attr "prefix_0f" "1")
16106 (set_attr "mode" "DI")])
16108 (define_insn "ctzsi2"
16109 [(set (match_operand:SI 0 "register_operand" "=r")
16110 (ctz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16111 (clobber (reg:CC FLAGS_REG))]
16113 "bsf{l}\t{%1, %0|%0, %1}"
16114 [(set_attr "type" "alu1")
16115 (set_attr "prefix_0f" "1")
16116 (set_attr "mode" "SI")])
16118 (define_insn "ctzdi2"
16119 [(set (match_operand:DI 0 "register_operand" "=r")
16120 (ctz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16121 (clobber (reg:CC FLAGS_REG))]
16123 "bsf{q}\t{%1, %0|%0, %1}"
16124 [(set_attr "type" "alu1")
16125 (set_attr "prefix_0f" "1")
16126 (set_attr "mode" "DI")])
16128 (define_expand "clzsi2"
16130 [(set (match_operand:SI 0 "register_operand" "")
16131 (minus:SI (const_int 31)
16132 (clz:SI (match_operand:SI 1 "nonimmediate_operand" ""))))
16133 (clobber (reg:CC FLAGS_REG))])
16135 [(set (match_dup 0) (xor:SI (match_dup 0) (const_int 31)))
16136 (clobber (reg:CC FLAGS_REG))])]
16141 emit_insn (gen_clzsi2_abm (operands[0], operands[1]));
16146 (define_insn "clzsi2_abm"
16147 [(set (match_operand:SI 0 "register_operand" "=r")
16148 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm")))
16149 (clobber (reg:CC FLAGS_REG))]
16151 "lzcnt{l}\t{%1, %0|%0, %1}"
16152 [(set_attr "prefix_rep" "1")
16153 (set_attr "type" "bitmanip")
16154 (set_attr "mode" "SI")])
16156 (define_insn "*bsr"
16157 [(set (match_operand:SI 0 "register_operand" "=r")
16158 (minus:SI (const_int 31)
16159 (clz:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))))
16160 (clobber (reg:CC FLAGS_REG))]
16162 "bsr{l}\t{%1, %0|%0, %1}"
16163 [(set_attr "type" "alu1")
16164 (set_attr "prefix_0f" "1")
16165 (set_attr "mode" "SI")])
16167 (define_insn "popcount<mode>2"
16168 [(set (match_operand:SWI248 0 "register_operand" "=r")
16170 (match_operand:SWI248 1 "nonimmediate_operand" "rm")))
16171 (clobber (reg:CC FLAGS_REG))]
16175 return "popcnt\t{%1, %0|%0, %1}";
16177 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16180 [(set_attr "prefix_rep" "1")
16181 (set_attr "type" "bitmanip")
16182 (set_attr "mode" "<MODE>")])
16184 (define_insn "*popcount<mode>2_cmp"
16185 [(set (reg FLAGS_REG)
16188 (match_operand:SWI248 1 "nonimmediate_operand" "rm"))
16190 (set (match_operand:SWI248 0 "register_operand" "=r")
16191 (popcount:SWI248 (match_dup 1)))]
16192 "TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16195 return "popcnt\t{%1, %0|%0, %1}";
16197 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16200 [(set_attr "prefix_rep" "1")
16201 (set_attr "type" "bitmanip")
16202 (set_attr "mode" "<MODE>")])
16204 (define_insn "*popcountsi2_cmp_zext"
16205 [(set (reg FLAGS_REG)
16207 (popcount:SI (match_operand:SI 1 "nonimmediate_operand" "rm"))
16209 (set (match_operand:DI 0 "register_operand" "=r")
16210 (zero_extend:DI(popcount:SI (match_dup 1))))]
16211 "TARGET_64BIT && TARGET_POPCNT && ix86_match_ccmode (insn, CCZmode)"
16214 return "popcnt\t{%1, %0|%0, %1}";
16216 return "popcnt{<imodesuffix>}\t{%1, %0|%0, %1}";
16219 [(set_attr "prefix_rep" "1")
16220 (set_attr "type" "bitmanip")
16221 (set_attr "mode" "SI")])
16223 (define_expand "bswapsi2"
16224 [(set (match_operand:SI 0 "register_operand" "")
16225 (bswap:SI (match_operand:SI 1 "register_operand" "")))]
16228 if (!(TARGET_BSWAP || TARGET_MOVBE))
16230 rtx x = operands[0];
16232 emit_move_insn (x, operands[1]);
16233 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16234 emit_insn (gen_rotlsi3 (x, x, GEN_INT (16)));
16235 emit_insn (gen_bswaphi_lowpart (gen_lowpart (HImode, x)));
16240 (define_insn "*bswapsi_movbe"
16241 [(set (match_operand:SI 0 "nonimmediate_operand" "=r,r,m")
16242 (bswap:SI (match_operand:SI 1 "nonimmediate_operand" "0,m,r")))]
16243 "TARGET_MOVBE && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16246 movbe\t{%1, %0|%0, %1}
16247 movbe\t{%1, %0|%0, %1}"
16248 [(set_attr "type" "*,imov,imov")
16249 (set_attr "modrm" "*,1,1")
16250 (set_attr "prefix_0f" "1")
16251 (set_attr "prefix_extra" "*,1,1")
16252 (set_attr "length" "2,*,*")
16253 (set_attr "mode" "SI")])
16255 (define_insn "*bswapsi_1"
16256 [(set (match_operand:SI 0 "register_operand" "=r")
16257 (bswap:SI (match_operand:SI 1 "register_operand" "0")))]
16260 [(set_attr "prefix_0f" "1")
16261 (set_attr "length" "2")])
16263 (define_insn "*bswaphi_lowpart_1"
16264 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+Q,r"))
16265 (bswap:HI (match_dup 0)))
16266 (clobber (reg:CC FLAGS_REG))]
16267 "TARGET_USE_XCHGB || optimize_function_for_size_p (cfun)"
16269 xchg{b}\t{%h0, %b0|%b0, %h0}
16270 rol{w}\t{$8, %0|%0, 8}"
16271 [(set_attr "length" "2,4")
16272 (set_attr "mode" "QI,HI")])
16274 (define_insn "bswaphi_lowpart"
16275 [(set (strict_low_part (match_operand:HI 0 "register_operand" "+r"))
16276 (bswap:HI (match_dup 0)))
16277 (clobber (reg:CC FLAGS_REG))]
16279 "rol{w}\t{$8, %0|%0, 8}"
16280 [(set_attr "length" "4")
16281 (set_attr "mode" "HI")])
16283 (define_expand "bswapdi2"
16284 [(set (match_operand:DI 0 "register_operand" "")
16285 (bswap:DI (match_operand:DI 1 "register_operand" "")))]
16289 (define_insn "*bswapdi_movbe"
16290 [(set (match_operand:DI 0 "nonimmediate_operand" "=r,r,m")
16291 (bswap:DI (match_operand:DI 1 "nonimmediate_operand" "0,m,r")))]
16292 "TARGET_64BIT && TARGET_MOVBE
16293 && !(MEM_P (operands[0]) && MEM_P (operands[1]))"
16296 movbe\t{%1, %0|%0, %1}
16297 movbe\t{%1, %0|%0, %1}"
16298 [(set_attr "type" "*,imov,imov")
16299 (set_attr "modrm" "*,1,1")
16300 (set_attr "prefix_0f" "1")
16301 (set_attr "prefix_extra" "*,1,1")
16302 (set_attr "length" "3,*,*")
16303 (set_attr "mode" "DI")])
16305 (define_insn "*bswapdi_1"
16306 [(set (match_operand:DI 0 "register_operand" "=r")
16307 (bswap:DI (match_operand:DI 1 "register_operand" "0")))]
16310 [(set_attr "prefix_0f" "1")
16311 (set_attr "length" "3")])
16313 (define_expand "clzdi2"
16315 [(set (match_operand:DI 0 "register_operand" "")
16316 (minus:DI (const_int 63)
16317 (clz:DI (match_operand:DI 1 "nonimmediate_operand" ""))))
16318 (clobber (reg:CC FLAGS_REG))])
16320 [(set (match_dup 0) (xor:DI (match_dup 0) (const_int 63)))
16321 (clobber (reg:CC FLAGS_REG))])]
16326 emit_insn (gen_clzdi2_abm (operands[0], operands[1]));
16331 (define_insn "clzdi2_abm"
16332 [(set (match_operand:DI 0 "register_operand" "=r")
16333 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm")))
16334 (clobber (reg:CC FLAGS_REG))]
16335 "TARGET_64BIT && TARGET_ABM"
16336 "lzcnt{q}\t{%1, %0|%0, %1}"
16337 [(set_attr "prefix_rep" "1")
16338 (set_attr "type" "bitmanip")
16339 (set_attr "mode" "DI")])
16341 (define_insn "*bsr_rex64"
16342 [(set (match_operand:DI 0 "register_operand" "=r")
16343 (minus:DI (const_int 63)
16344 (clz:DI (match_operand:DI 1 "nonimmediate_operand" "rm"))))
16345 (clobber (reg:CC FLAGS_REG))]
16347 "bsr{q}\t{%1, %0|%0, %1}"
16348 [(set_attr "type" "alu1")
16349 (set_attr "prefix_0f" "1")
16350 (set_attr "mode" "DI")])
16352 (define_expand "clzhi2"
16354 [(set (match_operand:HI 0 "register_operand" "")
16355 (minus:HI (const_int 15)
16356 (clz:HI (match_operand:HI 1 "nonimmediate_operand" ""))))
16357 (clobber (reg:CC FLAGS_REG))])
16359 [(set (match_dup 0) (xor:HI (match_dup 0) (const_int 15)))
16360 (clobber (reg:CC FLAGS_REG))])]
16365 emit_insn (gen_clzhi2_abm (operands[0], operands[1]));
16370 (define_insn "clzhi2_abm"
16371 [(set (match_operand:HI 0 "register_operand" "=r")
16372 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm")))
16373 (clobber (reg:CC FLAGS_REG))]
16375 "lzcnt{w}\t{%1, %0|%0, %1}"
16376 [(set_attr "prefix_rep" "1")
16377 (set_attr "type" "bitmanip")
16378 (set_attr "mode" "HI")])
16380 (define_insn "*bsrhi"
16381 [(set (match_operand:HI 0 "register_operand" "=r")
16382 (minus:HI (const_int 15)
16383 (clz:HI (match_operand:HI 1 "nonimmediate_operand" "rm"))))
16384 (clobber (reg:CC FLAGS_REG))]
16386 "bsr{w}\t{%1, %0|%0, %1}"
16387 [(set_attr "type" "alu1")
16388 (set_attr "prefix_0f" "1")
16389 (set_attr "mode" "HI")])
16391 (define_expand "paritydi2"
16392 [(set (match_operand:DI 0 "register_operand" "")
16393 (parity:DI (match_operand:DI 1 "register_operand" "")))]
16396 rtx scratch = gen_reg_rtx (QImode);
16399 emit_insn (gen_paritydi2_cmp (NULL_RTX, NULL_RTX,
16400 NULL_RTX, operands[1]));
16402 cond = gen_rtx_fmt_ee (ORDERED, QImode,
16403 gen_rtx_REG (CCmode, FLAGS_REG),
16405 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16408 emit_insn (gen_zero_extendqidi2 (operands[0], scratch));
16411 rtx tmp = gen_reg_rtx (SImode);
16413 emit_insn (gen_zero_extendqisi2 (tmp, scratch));
16414 emit_insn (gen_zero_extendsidi2 (operands[0], tmp));
16419 (define_insn_and_split "paritydi2_cmp"
16420 [(set (reg:CC FLAGS_REG)
16421 (parity:CC (match_operand:DI 3 "register_operand" "0")))
16422 (clobber (match_scratch:DI 0 "=r"))
16423 (clobber (match_scratch:SI 1 "=&r"))
16424 (clobber (match_scratch:HI 2 "=Q"))]
16427 "&& reload_completed"
16429 [(set (match_dup 1)
16430 (xor:SI (match_dup 1) (match_dup 4)))
16431 (clobber (reg:CC FLAGS_REG))])
16433 [(set (reg:CC FLAGS_REG)
16434 (parity:CC (match_dup 1)))
16435 (clobber (match_dup 1))
16436 (clobber (match_dup 2))])]
16438 operands[4] = gen_lowpart (SImode, operands[3]);
16442 emit_move_insn (operands[1], gen_lowpart (SImode, operands[3]));
16443 emit_insn (gen_lshrdi3 (operands[3], operands[3], GEN_INT (32)));
16446 operands[1] = gen_highpart (SImode, operands[3]);
16449 (define_expand "paritysi2"
16450 [(set (match_operand:SI 0 "register_operand" "")
16451 (parity:SI (match_operand:SI 1 "register_operand" "")))]
16454 rtx scratch = gen_reg_rtx (QImode);
16457 emit_insn (gen_paritysi2_cmp (NULL_RTX, NULL_RTX, operands[1]));
16459 cond = gen_rtx_fmt_ee (ORDERED, QImode,
16460 gen_rtx_REG (CCmode, FLAGS_REG),
16462 emit_insn (gen_rtx_SET (VOIDmode, scratch, cond));
16464 emit_insn (gen_zero_extendqisi2 (operands[0], scratch));
16468 (define_insn_and_split "paritysi2_cmp"
16469 [(set (reg:CC FLAGS_REG)
16470 (parity:CC (match_operand:SI 2 "register_operand" "0")))
16471 (clobber (match_scratch:SI 0 "=r"))
16472 (clobber (match_scratch:HI 1 "=&Q"))]
16475 "&& reload_completed"
16477 [(set (match_dup 1)
16478 (xor:HI (match_dup 1) (match_dup 3)))
16479 (clobber (reg:CC FLAGS_REG))])
16481 [(set (reg:CC FLAGS_REG)
16482 (parity:CC (match_dup 1)))
16483 (clobber (match_dup 1))])]
16485 operands[3] = gen_lowpart (HImode, operands[2]);
16487 emit_move_insn (operands[1], gen_lowpart (HImode, operands[2]));
16488 emit_insn (gen_lshrsi3 (operands[2], operands[2], GEN_INT (16)));
16491 (define_insn "*parityhi2_cmp"
16492 [(set (reg:CC FLAGS_REG)
16493 (parity:CC (match_operand:HI 1 "register_operand" "0")))
16494 (clobber (match_scratch:HI 0 "=Q"))]
16496 "xor{b}\t{%h0, %b0|%b0, %h0}"
16497 [(set_attr "length" "2")
16498 (set_attr "mode" "HI")])
16500 (define_insn "*parityqi2_cmp"
16501 [(set (reg:CC FLAGS_REG)
16502 (parity:CC (match_operand:QI 0 "register_operand" "q")))]
16505 [(set_attr "length" "2")
16506 (set_attr "mode" "QI")])
16508 ;; Thread-local storage patterns for ELF.
16510 ;; Note that these code sequences must appear exactly as shown
16511 ;; in order to allow linker relaxation.
16513 (define_insn "*tls_global_dynamic_32_gnu"
16514 [(set (match_operand:SI 0 "register_operand" "=a")
16515 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16516 (match_operand:SI 2 "tls_symbolic_operand" "")
16517 (match_operand:SI 3 "call_insn_operand" "")]
16519 (clobber (match_scratch:SI 4 "=d"))
16520 (clobber (match_scratch:SI 5 "=c"))
16521 (clobber (reg:CC FLAGS_REG))]
16522 "!TARGET_64BIT && TARGET_GNU_TLS"
16523 "lea{l}\t{%a2@TLSGD(,%1,1), %0|%0, %a2@TLSGD[%1*1]}\;call\t%P3"
16524 [(set_attr "type" "multi")
16525 (set_attr "length" "12")])
16527 (define_insn "*tls_global_dynamic_32_sun"
16528 [(set (match_operand:SI 0 "register_operand" "=a")
16529 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16530 (match_operand:SI 2 "tls_symbolic_operand" "")
16531 (match_operand:SI 3 "call_insn_operand" "")]
16533 (clobber (match_scratch:SI 4 "=d"))
16534 (clobber (match_scratch:SI 5 "=c"))
16535 (clobber (reg:CC FLAGS_REG))]
16536 "!TARGET_64BIT && TARGET_SUN_TLS"
16537 "lea{l}\t{%a2@DTLNDX(%1), %4|%4, %a2@DTLNDX[%1]}
16538 push{l}\t%4\;call\t%a2@TLSPLT\;pop{l}\t%4\;nop"
16539 [(set_attr "type" "multi")
16540 (set_attr "length" "14")])
16542 (define_expand "tls_global_dynamic_32"
16543 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16546 (match_operand:SI 1 "tls_symbolic_operand" "")
16549 (clobber (match_scratch:SI 4 ""))
16550 (clobber (match_scratch:SI 5 ""))
16551 (clobber (reg:CC FLAGS_REG))])]
16555 operands[2] = pic_offset_table_rtx;
16558 operands[2] = gen_reg_rtx (Pmode);
16559 emit_insn (gen_set_got (operands[2]));
16561 if (TARGET_GNU2_TLS)
16563 emit_insn (gen_tls_dynamic_gnu2_32
16564 (operands[0], operands[1], operands[2]));
16567 operands[3] = ix86_tls_get_addr ();
16570 (define_insn "*tls_global_dynamic_64"
16571 [(set (match_operand:DI 0 "register_operand" "=a")
16572 (call:DI (mem:QI (match_operand:DI 2 "call_insn_operand" ""))
16573 (match_operand:DI 3 "" "")))
16574 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16577 ".byte\t0x66\;lea{q}\t{%a1@TLSGD(%%rip), %%rdi|rdi, %a1@TLSGD[rip]}\;.word\t0x6666\;rex64\;call\t%P2"
16578 [(set_attr "type" "multi")
16579 (set_attr "length" "16")])
16581 (define_expand "tls_global_dynamic_64"
16582 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16583 (call:DI (mem:QI (match_dup 2)) (const_int 0)))
16584 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16588 if (TARGET_GNU2_TLS)
16590 emit_insn (gen_tls_dynamic_gnu2_64
16591 (operands[0], operands[1]));
16594 operands[2] = ix86_tls_get_addr ();
16597 (define_insn "*tls_local_dynamic_base_32_gnu"
16598 [(set (match_operand:SI 0 "register_operand" "=a")
16599 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16600 (match_operand:SI 2 "call_insn_operand" "")]
16601 UNSPEC_TLS_LD_BASE))
16602 (clobber (match_scratch:SI 3 "=d"))
16603 (clobber (match_scratch:SI 4 "=c"))
16604 (clobber (reg:CC FLAGS_REG))]
16605 "!TARGET_64BIT && TARGET_GNU_TLS"
16606 "lea{l}\t{%&@TLSLDM(%1), %0|%0, %&@TLSLDM[%1]}\;call\t%P2"
16607 [(set_attr "type" "multi")
16608 (set_attr "length" "11")])
16610 (define_insn "*tls_local_dynamic_base_32_sun"
16611 [(set (match_operand:SI 0 "register_operand" "=a")
16612 (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16613 (match_operand:SI 2 "call_insn_operand" "")]
16614 UNSPEC_TLS_LD_BASE))
16615 (clobber (match_scratch:SI 3 "=d"))
16616 (clobber (match_scratch:SI 4 "=c"))
16617 (clobber (reg:CC FLAGS_REG))]
16618 "!TARGET_64BIT && TARGET_SUN_TLS"
16619 "lea{l}\t{%&@TMDNX(%1), %3|%3, %&@TMDNX[%1]}
16620 push{l}\t%3\;call\t%&@TLSPLT\;pop{l}\t%3"
16621 [(set_attr "type" "multi")
16622 (set_attr "length" "13")])
16624 (define_expand "tls_local_dynamic_base_32"
16625 [(parallel [(set (match_operand:SI 0 "register_operand" "")
16626 (unspec:SI [(match_dup 1) (match_dup 2)]
16627 UNSPEC_TLS_LD_BASE))
16628 (clobber (match_scratch:SI 3 ""))
16629 (clobber (match_scratch:SI 4 ""))
16630 (clobber (reg:CC FLAGS_REG))])]
16634 operands[1] = pic_offset_table_rtx;
16637 operands[1] = gen_reg_rtx (Pmode);
16638 emit_insn (gen_set_got (operands[1]));
16640 if (TARGET_GNU2_TLS)
16642 emit_insn (gen_tls_dynamic_gnu2_32
16643 (operands[0], ix86_tls_module_base (), operands[1]));
16646 operands[2] = ix86_tls_get_addr ();
16649 (define_insn "*tls_local_dynamic_base_64"
16650 [(set (match_operand:DI 0 "register_operand" "=a")
16651 (call:DI (mem:QI (match_operand:DI 1 "call_insn_operand" ""))
16652 (match_operand:DI 2 "" "")))
16653 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)]
16655 "lea{q}\t{%&@TLSLD(%%rip), %%rdi|rdi, %&@TLSLD[rip]}\;call\t%P1"
16656 [(set_attr "type" "multi")
16657 (set_attr "length" "12")])
16659 (define_expand "tls_local_dynamic_base_64"
16660 [(parallel [(set (match_operand:DI 0 "register_operand" "")
16661 (call:DI (mem:QI (match_dup 1)) (const_int 0)))
16662 (unspec:DI [(const_int 0)] UNSPEC_TLS_LD_BASE)])]
16665 if (TARGET_GNU2_TLS)
16667 emit_insn (gen_tls_dynamic_gnu2_64
16668 (operands[0], ix86_tls_module_base ()));
16671 operands[1] = ix86_tls_get_addr ();
16674 ;; Local dynamic of a single variable is a lose. Show combine how
16675 ;; to convert that back to global dynamic.
16677 (define_insn_and_split "*tls_local_dynamic_32_once"
16678 [(set (match_operand:SI 0 "register_operand" "=a")
16679 (plus:SI (unspec:SI [(match_operand:SI 1 "register_operand" "b")
16680 (match_operand:SI 2 "call_insn_operand" "")]
16681 UNSPEC_TLS_LD_BASE)
16682 (const:SI (unspec:SI
16683 [(match_operand:SI 3 "tls_symbolic_operand" "")]
16685 (clobber (match_scratch:SI 4 "=d"))
16686 (clobber (match_scratch:SI 5 "=c"))
16687 (clobber (reg:CC FLAGS_REG))]
16691 [(parallel [(set (match_dup 0)
16692 (unspec:SI [(match_dup 1) (match_dup 3) (match_dup 2)]
16694 (clobber (match_dup 4))
16695 (clobber (match_dup 5))
16696 (clobber (reg:CC FLAGS_REG))])]
16699 ;; Load and add the thread base pointer from %gs:0.
16701 (define_insn "*load_tp_si"
16702 [(set (match_operand:SI 0 "register_operand" "=r")
16703 (unspec:SI [(const_int 0)] UNSPEC_TP))]
16705 "mov{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16706 [(set_attr "type" "imov")
16707 (set_attr "modrm" "0")
16708 (set_attr "length" "7")
16709 (set_attr "memory" "load")
16710 (set_attr "imm_disp" "false")])
16712 (define_insn "*add_tp_si"
16713 [(set (match_operand:SI 0 "register_operand" "=r")
16714 (plus:SI (unspec:SI [(const_int 0)] UNSPEC_TP)
16715 (match_operand:SI 1 "register_operand" "0")))
16716 (clobber (reg:CC FLAGS_REG))]
16718 "add{l}\t{%%gs:0, %0|%0, DWORD PTR gs:0}"
16719 [(set_attr "type" "alu")
16720 (set_attr "modrm" "0")
16721 (set_attr "length" "7")
16722 (set_attr "memory" "load")
16723 (set_attr "imm_disp" "false")])
16725 (define_insn "*load_tp_di"
16726 [(set (match_operand:DI 0 "register_operand" "=r")
16727 (unspec:DI [(const_int 0)] UNSPEC_TP))]
16729 "mov{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16730 [(set_attr "type" "imov")
16731 (set_attr "modrm" "0")
16732 (set_attr "length" "7")
16733 (set_attr "memory" "load")
16734 (set_attr "imm_disp" "false")])
16736 (define_insn "*add_tp_di"
16737 [(set (match_operand:DI 0 "register_operand" "=r")
16738 (plus:DI (unspec:DI [(const_int 0)] UNSPEC_TP)
16739 (match_operand:DI 1 "register_operand" "0")))
16740 (clobber (reg:CC FLAGS_REG))]
16742 "add{q}\t{%%fs:0, %0|%0, QWORD PTR fs:0}"
16743 [(set_attr "type" "alu")
16744 (set_attr "modrm" "0")
16745 (set_attr "length" "7")
16746 (set_attr "memory" "load")
16747 (set_attr "imm_disp" "false")])
16749 ;; GNU2 TLS patterns can be split.
16751 (define_expand "tls_dynamic_gnu2_32"
16752 [(set (match_dup 3)
16753 (plus:SI (match_operand:SI 2 "register_operand" "")
16755 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")]
16758 [(set (match_operand:SI 0 "register_operand" "")
16759 (unspec:SI [(match_dup 1) (match_dup 3)
16760 (match_dup 2) (reg:SI SP_REG)]
16762 (clobber (reg:CC FLAGS_REG))])]
16763 "!TARGET_64BIT && TARGET_GNU2_TLS"
16765 operands[3] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16766 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16769 (define_insn "*tls_dynamic_lea_32"
16770 [(set (match_operand:SI 0 "register_operand" "=r")
16771 (plus:SI (match_operand:SI 1 "register_operand" "b")
16773 (unspec:SI [(match_operand:SI 2 "tls_symbolic_operand" "")]
16774 UNSPEC_TLSDESC))))]
16775 "!TARGET_64BIT && TARGET_GNU2_TLS"
16776 "lea{l}\t{%a2@TLSDESC(%1), %0|%0, %a2@TLSDESC[%1]}"
16777 [(set_attr "type" "lea")
16778 (set_attr "mode" "SI")
16779 (set_attr "length" "6")
16780 (set_attr "length_address" "4")])
16782 (define_insn "*tls_dynamic_call_32"
16783 [(set (match_operand:SI 0 "register_operand" "=a")
16784 (unspec:SI [(match_operand:SI 1 "tls_symbolic_operand" "")
16785 (match_operand:SI 2 "register_operand" "0")
16786 ;; we have to make sure %ebx still points to the GOT
16787 (match_operand:SI 3 "register_operand" "b")
16790 (clobber (reg:CC FLAGS_REG))]
16791 "!TARGET_64BIT && TARGET_GNU2_TLS"
16792 "call\t{*%a1@TLSCALL(%2)|[DWORD PTR [%2+%a1@TLSCALL]]}"
16793 [(set_attr "type" "call")
16794 (set_attr "length" "2")
16795 (set_attr "length_address" "0")])
16797 (define_insn_and_split "*tls_dynamic_gnu2_combine_32"
16798 [(set (match_operand:SI 0 "register_operand" "=&a")
16800 (unspec:SI [(match_operand:SI 3 "tls_modbase_operand" "")
16801 (match_operand:SI 4 "" "")
16802 (match_operand:SI 2 "register_operand" "b")
16805 (const:SI (unspec:SI
16806 [(match_operand:SI 1 "tls_symbolic_operand" "")]
16808 (clobber (reg:CC FLAGS_REG))]
16809 "!TARGET_64BIT && TARGET_GNU2_TLS"
16812 [(set (match_dup 0) (match_dup 5))]
16814 operands[5] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16815 emit_insn (gen_tls_dynamic_gnu2_32 (operands[5], operands[1], operands[2]));
16818 (define_expand "tls_dynamic_gnu2_64"
16819 [(set (match_dup 2)
16820 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16823 [(set (match_operand:DI 0 "register_operand" "")
16824 (unspec:DI [(match_dup 1) (match_dup 2) (reg:DI SP_REG)]
16826 (clobber (reg:CC FLAGS_REG))])]
16827 "TARGET_64BIT && TARGET_GNU2_TLS"
16829 operands[2] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16830 ix86_tls_descriptor_calls_expanded_in_cfun = true;
16833 (define_insn "*tls_dynamic_lea_64"
16834 [(set (match_operand:DI 0 "register_operand" "=r")
16835 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")]
16837 "TARGET_64BIT && TARGET_GNU2_TLS"
16838 "lea{q}\t{%a1@TLSDESC(%%rip), %0|%0, %a1@TLSDESC[rip]}"
16839 [(set_attr "type" "lea")
16840 (set_attr "mode" "DI")
16841 (set_attr "length" "7")
16842 (set_attr "length_address" "4")])
16844 (define_insn "*tls_dynamic_call_64"
16845 [(set (match_operand:DI 0 "register_operand" "=a")
16846 (unspec:DI [(match_operand:DI 1 "tls_symbolic_operand" "")
16847 (match_operand:DI 2 "register_operand" "0")
16850 (clobber (reg:CC FLAGS_REG))]
16851 "TARGET_64BIT && TARGET_GNU2_TLS"
16852 "call\t{*%a1@TLSCALL(%2)|[QWORD PTR [%2+%a1@TLSCALL]]}"
16853 [(set_attr "type" "call")
16854 (set_attr "length" "2")
16855 (set_attr "length_address" "0")])
16857 (define_insn_and_split "*tls_dynamic_gnu2_combine_64"
16858 [(set (match_operand:DI 0 "register_operand" "=&a")
16860 (unspec:DI [(match_operand:DI 2 "tls_modbase_operand" "")
16861 (match_operand:DI 3 "" "")
16864 (const:DI (unspec:DI
16865 [(match_operand:DI 1 "tls_symbolic_operand" "")]
16867 (clobber (reg:CC FLAGS_REG))]
16868 "TARGET_64BIT && TARGET_GNU2_TLS"
16871 [(set (match_dup 0) (match_dup 4))]
16873 operands[4] = !can_create_pseudo_p () ? operands[0] : gen_reg_rtx (Pmode);
16874 emit_insn (gen_tls_dynamic_gnu2_64 (operands[4], operands[1]));
16879 ;; These patterns match the binary 387 instructions for addM3, subM3,
16880 ;; mulM3 and divM3. There are three patterns for each of DFmode and
16881 ;; SFmode. The first is the normal insn, the second the same insn but
16882 ;; with one operand a conversion, and the third the same insn but with
16883 ;; the other operand a conversion. The conversion may be SFmode or
16884 ;; SImode if the target mode DFmode, but only SImode if the target mode
16887 ;; Gcc is slightly more smart about handling normal two address instructions
16888 ;; so use special patterns for add and mull.
16890 (define_insn "*fop_<mode>_comm_mixed_avx"
16891 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16892 (match_operator:MODEF 3 "binary_fp_operator"
16893 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,x")
16894 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16895 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16896 && COMMUTATIVE_ARITH_P (operands[3])
16897 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16898 "* return output_387_binary_op (insn, operands);"
16899 [(set (attr "type")
16900 (if_then_else (eq_attr "alternative" "1")
16901 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16902 (const_string "ssemul")
16903 (const_string "sseadd"))
16904 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16905 (const_string "fmul")
16906 (const_string "fop"))))
16907 (set_attr "prefix" "orig,maybe_vex")
16908 (set_attr "mode" "<MODE>")])
16910 (define_insn "*fop_<mode>_comm_mixed"
16911 [(set (match_operand:MODEF 0 "register_operand" "=f,x")
16912 (match_operator:MODEF 3 "binary_fp_operator"
16913 [(match_operand:MODEF 1 "nonimmediate_operand" "%0,0")
16914 (match_operand:MODEF 2 "nonimmediate_operand" "fm,xm")]))]
16915 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16916 && COMMUTATIVE_ARITH_P (operands[3])
16917 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16918 "* return output_387_binary_op (insn, operands);"
16919 [(set (attr "type")
16920 (if_then_else (eq_attr "alternative" "1")
16921 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16922 (const_string "ssemul")
16923 (const_string "sseadd"))
16924 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16925 (const_string "fmul")
16926 (const_string "fop"))))
16927 (set_attr "mode" "<MODE>")])
16929 (define_insn "*fop_<mode>_comm_avx"
16930 [(set (match_operand:MODEF 0 "register_operand" "=x")
16931 (match_operator:MODEF 3 "binary_fp_operator"
16932 [(match_operand:MODEF 1 "nonimmediate_operand" "%x")
16933 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16934 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16935 && COMMUTATIVE_ARITH_P (operands[3])
16936 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16937 "* return output_387_binary_op (insn, operands);"
16938 [(set (attr "type")
16939 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16940 (const_string "ssemul")
16941 (const_string "sseadd")))
16942 (set_attr "prefix" "vex")
16943 (set_attr "mode" "<MODE>")])
16945 (define_insn "*fop_<mode>_comm_sse"
16946 [(set (match_operand:MODEF 0 "register_operand" "=x")
16947 (match_operator:MODEF 3 "binary_fp_operator"
16948 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16949 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
16950 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
16951 && COMMUTATIVE_ARITH_P (operands[3])
16952 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16953 "* return output_387_binary_op (insn, operands);"
16954 [(set (attr "type")
16955 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16956 (const_string "ssemul")
16957 (const_string "sseadd")))
16958 (set_attr "mode" "<MODE>")])
16960 (define_insn "*fop_<mode>_comm_i387"
16961 [(set (match_operand:MODEF 0 "register_operand" "=f")
16962 (match_operator:MODEF 3 "binary_fp_operator"
16963 [(match_operand:MODEF 1 "nonimmediate_operand" "%0")
16964 (match_operand:MODEF 2 "nonimmediate_operand" "fm")]))]
16965 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
16966 && COMMUTATIVE_ARITH_P (operands[3])
16967 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16968 "* return output_387_binary_op (insn, operands);"
16969 [(set (attr "type")
16970 (if_then_else (match_operand:MODEF 3 "mult_operator" "")
16971 (const_string "fmul")
16972 (const_string "fop")))
16973 (set_attr "mode" "<MODE>")])
16975 (define_insn "*fop_<mode>_1_mixed_avx"
16976 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
16977 (match_operator:MODEF 3 "binary_fp_operator"
16978 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,x")
16979 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
16980 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
16981 && !COMMUTATIVE_ARITH_P (operands[3])
16982 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
16983 "* return output_387_binary_op (insn, operands);"
16984 [(set (attr "type")
16985 (cond [(and (eq_attr "alternative" "2")
16986 (match_operand:MODEF 3 "mult_operator" ""))
16987 (const_string "ssemul")
16988 (and (eq_attr "alternative" "2")
16989 (match_operand:MODEF 3 "div_operator" ""))
16990 (const_string "ssediv")
16991 (eq_attr "alternative" "2")
16992 (const_string "sseadd")
16993 (match_operand:MODEF 3 "mult_operator" "")
16994 (const_string "fmul")
16995 (match_operand:MODEF 3 "div_operator" "")
16996 (const_string "fdiv")
16998 (const_string "fop")))
16999 (set_attr "prefix" "orig,orig,maybe_vex")
17000 (set_attr "mode" "<MODE>")])
17002 (define_insn "*fop_<mode>_1_mixed"
17003 [(set (match_operand:MODEF 0 "register_operand" "=f,f,x")
17004 (match_operator:MODEF 3 "binary_fp_operator"
17005 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm,0")
17006 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0,xm")]))]
17007 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_MIX_SSE_I387
17008 && !COMMUTATIVE_ARITH_P (operands[3])
17009 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17010 "* return output_387_binary_op (insn, operands);"
17011 [(set (attr "type")
17012 (cond [(and (eq_attr "alternative" "2")
17013 (match_operand:MODEF 3 "mult_operator" ""))
17014 (const_string "ssemul")
17015 (and (eq_attr "alternative" "2")
17016 (match_operand:MODEF 3 "div_operator" ""))
17017 (const_string "ssediv")
17018 (eq_attr "alternative" "2")
17019 (const_string "sseadd")
17020 (match_operand:MODEF 3 "mult_operator" "")
17021 (const_string "fmul")
17022 (match_operand:MODEF 3 "div_operator" "")
17023 (const_string "fdiv")
17025 (const_string "fop")))
17026 (set_attr "mode" "<MODE>")])
17028 (define_insn "*rcpsf2_sse"
17029 [(set (match_operand:SF 0 "register_operand" "=x")
17030 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17033 "%vrcpss\t{%1, %d0|%d0, %1}"
17034 [(set_attr "type" "sse")
17035 (set_attr "atom_sse_attr" "rcp")
17036 (set_attr "prefix" "maybe_vex")
17037 (set_attr "mode" "SF")])
17039 (define_insn "*fop_<mode>_1_avx"
17040 [(set (match_operand:MODEF 0 "register_operand" "=x")
17041 (match_operator:MODEF 3 "binary_fp_operator"
17042 [(match_operand:MODEF 1 "register_operand" "x")
17043 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
17044 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17045 && !COMMUTATIVE_ARITH_P (operands[3])"
17046 "* return output_387_binary_op (insn, operands);"
17047 [(set (attr "type")
17048 (cond [(match_operand:MODEF 3 "mult_operator" "")
17049 (const_string "ssemul")
17050 (match_operand:MODEF 3 "div_operator" "")
17051 (const_string "ssediv")
17053 (const_string "sseadd")))
17054 (set_attr "prefix" "vex")
17055 (set_attr "mode" "<MODE>")])
17057 (define_insn "*fop_<mode>_1_sse"
17058 [(set (match_operand:MODEF 0 "register_operand" "=x")
17059 (match_operator:MODEF 3 "binary_fp_operator"
17060 [(match_operand:MODEF 1 "register_operand" "0")
17061 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]))]
17062 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17063 && !COMMUTATIVE_ARITH_P (operands[3])"
17064 "* return output_387_binary_op (insn, operands);"
17065 [(set (attr "type")
17066 (cond [(match_operand:MODEF 3 "mult_operator" "")
17067 (const_string "ssemul")
17068 (match_operand:MODEF 3 "div_operator" "")
17069 (const_string "ssediv")
17071 (const_string "sseadd")))
17072 (set_attr "mode" "<MODE>")])
17074 ;; This pattern is not fully shadowed by the pattern above.
17075 (define_insn "*fop_<mode>_1_i387"
17076 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17077 (match_operator:MODEF 3 "binary_fp_operator"
17078 [(match_operand:MODEF 1 "nonimmediate_operand" "0,fm")
17079 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0")]))]
17080 "TARGET_80387 && X87_ENABLE_ARITH (<MODE>mode)
17081 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17082 && !COMMUTATIVE_ARITH_P (operands[3])
17083 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17084 "* return output_387_binary_op (insn, operands);"
17085 [(set (attr "type")
17086 (cond [(match_operand:MODEF 3 "mult_operator" "")
17087 (const_string "fmul")
17088 (match_operand:MODEF 3 "div_operator" "")
17089 (const_string "fdiv")
17091 (const_string "fop")))
17092 (set_attr "mode" "<MODE>")])
17094 ;; ??? Add SSE splitters for these!
17095 (define_insn "*fop_<MODEF:mode>_2_i387"
17096 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17097 (match_operator:MODEF 3 "binary_fp_operator"
17099 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17100 (match_operand:MODEF 2 "register_operand" "0,0")]))]
17101 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17102 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17103 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17104 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17105 [(set (attr "type")
17106 (cond [(match_operand:MODEF 3 "mult_operator" "")
17107 (const_string "fmul")
17108 (match_operand:MODEF 3 "div_operator" "")
17109 (const_string "fdiv")
17111 (const_string "fop")))
17112 (set_attr "fp_int_src" "true")
17113 (set_attr "mode" "<X87MODEI12:MODE>")])
17115 (define_insn "*fop_<MODEF:mode>_3_i387"
17116 [(set (match_operand:MODEF 0 "register_operand" "=f,f")
17117 (match_operator:MODEF 3 "binary_fp_operator"
17118 [(match_operand:MODEF 1 "register_operand" "0,0")
17120 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17121 "TARGET_80387 && X87_ENABLE_FLOAT (<MODEF:MODE>mode, <X87MODEI12:MODE>mode)
17122 && !(SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH)
17123 && (TARGET_USE_<X87MODEI12:MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17124 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17125 [(set (attr "type")
17126 (cond [(match_operand:MODEF 3 "mult_operator" "")
17127 (const_string "fmul")
17128 (match_operand:MODEF 3 "div_operator" "")
17129 (const_string "fdiv")
17131 (const_string "fop")))
17132 (set_attr "fp_int_src" "true")
17133 (set_attr "mode" "<MODE>")])
17135 (define_insn "*fop_df_4_i387"
17136 [(set (match_operand:DF 0 "register_operand" "=f,f")
17137 (match_operator:DF 3 "binary_fp_operator"
17139 (match_operand:SF 1 "nonimmediate_operand" "fm,0"))
17140 (match_operand:DF 2 "register_operand" "0,f")]))]
17141 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17142 && !(TARGET_SSE2 && TARGET_SSE_MATH)
17143 && !(MEM_P (operands[1]) && MEM_P (operands[2]))"
17144 "* return output_387_binary_op (insn, operands);"
17145 [(set (attr "type")
17146 (cond [(match_operand:DF 3 "mult_operator" "")
17147 (const_string "fmul")
17148 (match_operand:DF 3 "div_operator" "")
17149 (const_string "fdiv")
17151 (const_string "fop")))
17152 (set_attr "mode" "SF")])
17154 (define_insn "*fop_df_5_i387"
17155 [(set (match_operand:DF 0 "register_operand" "=f,f")
17156 (match_operator:DF 3 "binary_fp_operator"
17157 [(match_operand:DF 1 "register_operand" "0,f")
17159 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17160 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17161 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17162 "* return output_387_binary_op (insn, operands);"
17163 [(set (attr "type")
17164 (cond [(match_operand:DF 3 "mult_operator" "")
17165 (const_string "fmul")
17166 (match_operand:DF 3 "div_operator" "")
17167 (const_string "fdiv")
17169 (const_string "fop")))
17170 (set_attr "mode" "SF")])
17172 (define_insn "*fop_df_6_i387"
17173 [(set (match_operand:DF 0 "register_operand" "=f,f")
17174 (match_operator:DF 3 "binary_fp_operator"
17176 (match_operand:SF 1 "register_operand" "0,f"))
17178 (match_operand:SF 2 "nonimmediate_operand" "fm,0"))]))]
17179 "TARGET_80387 && X87_ENABLE_ARITH (DFmode)
17180 && !(TARGET_SSE2 && TARGET_SSE_MATH)"
17181 "* return output_387_binary_op (insn, operands);"
17182 [(set (attr "type")
17183 (cond [(match_operand:DF 3 "mult_operator" "")
17184 (const_string "fmul")
17185 (match_operand:DF 3 "div_operator" "")
17186 (const_string "fdiv")
17188 (const_string "fop")))
17189 (set_attr "mode" "SF")])
17191 (define_insn "*fop_xf_comm_i387"
17192 [(set (match_operand:XF 0 "register_operand" "=f")
17193 (match_operator:XF 3 "binary_fp_operator"
17194 [(match_operand:XF 1 "register_operand" "%0")
17195 (match_operand:XF 2 "register_operand" "f")]))]
17197 && COMMUTATIVE_ARITH_P (operands[3])"
17198 "* return output_387_binary_op (insn, operands);"
17199 [(set (attr "type")
17200 (if_then_else (match_operand:XF 3 "mult_operator" "")
17201 (const_string "fmul")
17202 (const_string "fop")))
17203 (set_attr "mode" "XF")])
17205 (define_insn "*fop_xf_1_i387"
17206 [(set (match_operand:XF 0 "register_operand" "=f,f")
17207 (match_operator:XF 3 "binary_fp_operator"
17208 [(match_operand:XF 1 "register_operand" "0,f")
17209 (match_operand:XF 2 "register_operand" "f,0")]))]
17211 && !COMMUTATIVE_ARITH_P (operands[3])"
17212 "* return output_387_binary_op (insn, operands);"
17213 [(set (attr "type")
17214 (cond [(match_operand:XF 3 "mult_operator" "")
17215 (const_string "fmul")
17216 (match_operand:XF 3 "div_operator" "")
17217 (const_string "fdiv")
17219 (const_string "fop")))
17220 (set_attr "mode" "XF")])
17222 (define_insn "*fop_xf_2_i387"
17223 [(set (match_operand:XF 0 "register_operand" "=f,f")
17224 (match_operator:XF 3 "binary_fp_operator"
17226 (match_operand:X87MODEI12 1 "nonimmediate_operand" "m,?r"))
17227 (match_operand:XF 2 "register_operand" "0,0")]))]
17228 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17229 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17230 [(set (attr "type")
17231 (cond [(match_operand:XF 3 "mult_operator" "")
17232 (const_string "fmul")
17233 (match_operand:XF 3 "div_operator" "")
17234 (const_string "fdiv")
17236 (const_string "fop")))
17237 (set_attr "fp_int_src" "true")
17238 (set_attr "mode" "<MODE>")])
17240 (define_insn "*fop_xf_3_i387"
17241 [(set (match_operand:XF 0 "register_operand" "=f,f")
17242 (match_operator:XF 3 "binary_fp_operator"
17243 [(match_operand:XF 1 "register_operand" "0,0")
17245 (match_operand:X87MODEI12 2 "nonimmediate_operand" "m,?r"))]))]
17246 "TARGET_80387 && (TARGET_USE_<MODE>MODE_FIOP || optimize_function_for_size_p (cfun))"
17247 "* return which_alternative ? \"#\" : output_387_binary_op (insn, operands);"
17248 [(set (attr "type")
17249 (cond [(match_operand:XF 3 "mult_operator" "")
17250 (const_string "fmul")
17251 (match_operand:XF 3 "div_operator" "")
17252 (const_string "fdiv")
17254 (const_string "fop")))
17255 (set_attr "fp_int_src" "true")
17256 (set_attr "mode" "<MODE>")])
17258 (define_insn "*fop_xf_4_i387"
17259 [(set (match_operand:XF 0 "register_operand" "=f,f")
17260 (match_operator:XF 3 "binary_fp_operator"
17262 (match_operand:MODEF 1 "nonimmediate_operand" "fm,0"))
17263 (match_operand:XF 2 "register_operand" "0,f")]))]
17265 "* return output_387_binary_op (insn, operands);"
17266 [(set (attr "type")
17267 (cond [(match_operand:XF 3 "mult_operator" "")
17268 (const_string "fmul")
17269 (match_operand:XF 3 "div_operator" "")
17270 (const_string "fdiv")
17272 (const_string "fop")))
17273 (set_attr "mode" "<MODE>")])
17275 (define_insn "*fop_xf_5_i387"
17276 [(set (match_operand:XF 0 "register_operand" "=f,f")
17277 (match_operator:XF 3 "binary_fp_operator"
17278 [(match_operand:XF 1 "register_operand" "0,f")
17280 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17282 "* return output_387_binary_op (insn, operands);"
17283 [(set (attr "type")
17284 (cond [(match_operand:XF 3 "mult_operator" "")
17285 (const_string "fmul")
17286 (match_operand:XF 3 "div_operator" "")
17287 (const_string "fdiv")
17289 (const_string "fop")))
17290 (set_attr "mode" "<MODE>")])
17292 (define_insn "*fop_xf_6_i387"
17293 [(set (match_operand:XF 0 "register_operand" "=f,f")
17294 (match_operator:XF 3 "binary_fp_operator"
17296 (match_operand:MODEF 1 "register_operand" "0,f"))
17298 (match_operand:MODEF 2 "nonimmediate_operand" "fm,0"))]))]
17300 "* return output_387_binary_op (insn, operands);"
17301 [(set (attr "type")
17302 (cond [(match_operand:XF 3 "mult_operator" "")
17303 (const_string "fmul")
17304 (match_operand:XF 3 "div_operator" "")
17305 (const_string "fdiv")
17307 (const_string "fop")))
17308 (set_attr "mode" "<MODE>")])
17311 [(set (match_operand 0 "register_operand" "")
17312 (match_operator 3 "binary_fp_operator"
17313 [(float (match_operand:X87MODEI12 1 "register_operand" ""))
17314 (match_operand 2 "register_operand" "")]))]
17316 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17317 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[1]))"
17320 operands[4] = ix86_force_to_memory (GET_MODE (operands[1]), operands[1]);
17321 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17322 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17323 gen_rtx_fmt_ee (GET_CODE (operands[3]),
17324 GET_MODE (operands[3]),
17327 ix86_free_from_memory (GET_MODE (operands[1]));
17332 [(set (match_operand 0 "register_operand" "")
17333 (match_operator 3 "binary_fp_operator"
17334 [(match_operand 1 "register_operand" "")
17335 (float (match_operand:X87MODEI12 2 "register_operand" ""))]))]
17337 && X87_FLOAT_MODE_P (GET_MODE (operands[0]))
17338 && X87_ENABLE_FLOAT (GET_MODE (operands[0]), GET_MODE (operands[2]))"
17341 operands[4] = ix86_force_to_memory (GET_MODE (operands[2]), operands[2]);
17342 operands[4] = gen_rtx_FLOAT (GET_MODE (operands[0]), operands[4]);
17343 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
17344 gen_rtx_fmt_ee (GET_CODE (operands[3]),
17345 GET_MODE (operands[3]),
17348 ix86_free_from_memory (GET_MODE (operands[2]));
17352 ;; FPU special functions.
17354 ;; This pattern implements a no-op XFmode truncation for
17355 ;; all fancy i386 XFmode math functions.
17357 (define_insn "truncxf<mode>2_i387_noop_unspec"
17358 [(set (match_operand:MODEF 0 "register_operand" "=f")
17359 (unspec:MODEF [(match_operand:XF 1 "register_operand" "f")]
17360 UNSPEC_TRUNC_NOOP))]
17361 "TARGET_USE_FANCY_MATH_387"
17362 "* return output_387_reg_move (insn, operands);"
17363 [(set_attr "type" "fmov")
17364 (set_attr "mode" "<MODE>")])
17366 (define_insn "sqrtxf2"
17367 [(set (match_operand:XF 0 "register_operand" "=f")
17368 (sqrt:XF (match_operand:XF 1 "register_operand" "0")))]
17369 "TARGET_USE_FANCY_MATH_387"
17371 [(set_attr "type" "fpspc")
17372 (set_attr "mode" "XF")
17373 (set_attr "athlon_decode" "direct")
17374 (set_attr "amdfam10_decode" "direct")])
17376 (define_insn "sqrt_extend<mode>xf2_i387"
17377 [(set (match_operand:XF 0 "register_operand" "=f")
17380 (match_operand:MODEF 1 "register_operand" "0"))))]
17381 "TARGET_USE_FANCY_MATH_387"
17383 [(set_attr "type" "fpspc")
17384 (set_attr "mode" "XF")
17385 (set_attr "athlon_decode" "direct")
17386 (set_attr "amdfam10_decode" "direct")])
17388 (define_insn "*rsqrtsf2_sse"
17389 [(set (match_operand:SF 0 "register_operand" "=x")
17390 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "xm")]
17393 "%vrsqrtss\t{%1, %d0|%d0, %1}"
17394 [(set_attr "type" "sse")
17395 (set_attr "atom_sse_attr" "rcp")
17396 (set_attr "prefix" "maybe_vex")
17397 (set_attr "mode" "SF")])
17399 (define_expand "rsqrtsf2"
17400 [(set (match_operand:SF 0 "register_operand" "")
17401 (unspec:SF [(match_operand:SF 1 "nonimmediate_operand" "")]
17405 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 1);
17409 (define_insn "*sqrt<mode>2_sse"
17410 [(set (match_operand:MODEF 0 "register_operand" "=x")
17412 (match_operand:MODEF 1 "nonimmediate_operand" "xm")))]
17413 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
17414 "%vsqrts<ssemodefsuffix>\t{%1, %d0|%d0, %1}"
17415 [(set_attr "type" "sse")
17416 (set_attr "atom_sse_attr" "sqrt")
17417 (set_attr "prefix" "maybe_vex")
17418 (set_attr "mode" "<MODE>")
17419 (set_attr "athlon_decode" "*")
17420 (set_attr "amdfam10_decode" "*")])
17422 (define_expand "sqrt<mode>2"
17423 [(set (match_operand:MODEF 0 "register_operand" "")
17425 (match_operand:MODEF 1 "nonimmediate_operand" "")))]
17426 "(TARGET_USE_FANCY_MATH_387 && X87_ENABLE_ARITH (<MODE>mode))
17427 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
17429 if (<MODE>mode == SFmode
17430 && TARGET_SSE_MATH && TARGET_RECIP && !optimize_function_for_size_p (cfun)
17431 && flag_finite_math_only && !flag_trapping_math
17432 && flag_unsafe_math_optimizations)
17434 ix86_emit_swsqrtsf (operands[0], operands[1], SFmode, 0);
17438 if (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH))
17440 rtx op0 = gen_reg_rtx (XFmode);
17441 rtx op1 = force_reg (<MODE>mode, operands[1]);
17443 emit_insn (gen_sqrt_extend<mode>xf2_i387 (op0, op1));
17444 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op0));
17449 (define_insn "fpremxf4_i387"
17450 [(set (match_operand:XF 0 "register_operand" "=f")
17451 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17452 (match_operand:XF 3 "register_operand" "1")]
17454 (set (match_operand:XF 1 "register_operand" "=u")
17455 (unspec:XF [(match_dup 2) (match_dup 3)]
17457 (set (reg:CCFP FPSR_REG)
17458 (unspec:CCFP [(match_dup 2) (match_dup 3)]
17460 "TARGET_USE_FANCY_MATH_387"
17462 [(set_attr "type" "fpspc")
17463 (set_attr "mode" "XF")])
17465 (define_expand "fmodxf3"
17466 [(use (match_operand:XF 0 "register_operand" ""))
17467 (use (match_operand:XF 1 "general_operand" ""))
17468 (use (match_operand:XF 2 "general_operand" ""))]
17469 "TARGET_USE_FANCY_MATH_387"
17471 rtx label = gen_label_rtx ();
17473 rtx op1 = gen_reg_rtx (XFmode);
17474 rtx op2 = gen_reg_rtx (XFmode);
17476 emit_move_insn (op2, operands[2]);
17477 emit_move_insn (op1, operands[1]);
17479 emit_label (label);
17480 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17481 ix86_emit_fp_unordered_jump (label);
17482 LABEL_NUSES (label) = 1;
17484 emit_move_insn (operands[0], op1);
17488 (define_expand "fmod<mode>3"
17489 [(use (match_operand:MODEF 0 "register_operand" ""))
17490 (use (match_operand:MODEF 1 "general_operand" ""))
17491 (use (match_operand:MODEF 2 "general_operand" ""))]
17492 "TARGET_USE_FANCY_MATH_387"
17494 rtx label = gen_label_rtx ();
17496 rtx op1 = gen_reg_rtx (XFmode);
17497 rtx op2 = gen_reg_rtx (XFmode);
17499 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17500 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17502 emit_label (label);
17503 emit_insn (gen_fpremxf4_i387 (op1, op2, op1, op2));
17504 ix86_emit_fp_unordered_jump (label);
17505 LABEL_NUSES (label) = 1;
17507 /* Truncate the result properly for strict SSE math. */
17508 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17509 && !TARGET_MIX_SSE_I387)
17510 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17512 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17517 (define_insn "fprem1xf4_i387"
17518 [(set (match_operand:XF 0 "register_operand" "=f")
17519 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
17520 (match_operand:XF 3 "register_operand" "1")]
17522 (set (match_operand:XF 1 "register_operand" "=u")
17523 (unspec:XF [(match_dup 2) (match_dup 3)]
17525 (set (reg:CCFP FPSR_REG)
17526 (unspec:CCFP [(match_dup 2) (match_dup 3)]
17528 "TARGET_USE_FANCY_MATH_387"
17530 [(set_attr "type" "fpspc")
17531 (set_attr "mode" "XF")])
17533 (define_expand "remainderxf3"
17534 [(use (match_operand:XF 0 "register_operand" ""))
17535 (use (match_operand:XF 1 "general_operand" ""))
17536 (use (match_operand:XF 2 "general_operand" ""))]
17537 "TARGET_USE_FANCY_MATH_387"
17539 rtx label = gen_label_rtx ();
17541 rtx op1 = gen_reg_rtx (XFmode);
17542 rtx op2 = gen_reg_rtx (XFmode);
17544 emit_move_insn (op2, operands[2]);
17545 emit_move_insn (op1, operands[1]);
17547 emit_label (label);
17548 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17549 ix86_emit_fp_unordered_jump (label);
17550 LABEL_NUSES (label) = 1;
17552 emit_move_insn (operands[0], op1);
17556 (define_expand "remainder<mode>3"
17557 [(use (match_operand:MODEF 0 "register_operand" ""))
17558 (use (match_operand:MODEF 1 "general_operand" ""))
17559 (use (match_operand:MODEF 2 "general_operand" ""))]
17560 "TARGET_USE_FANCY_MATH_387"
17562 rtx label = gen_label_rtx ();
17564 rtx op1 = gen_reg_rtx (XFmode);
17565 rtx op2 = gen_reg_rtx (XFmode);
17567 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
17568 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17570 emit_label (label);
17572 emit_insn (gen_fprem1xf4_i387 (op1, op2, op1, op2));
17573 ix86_emit_fp_unordered_jump (label);
17574 LABEL_NUSES (label) = 1;
17576 /* Truncate the result properly for strict SSE math. */
17577 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
17578 && !TARGET_MIX_SSE_I387)
17579 emit_insn (gen_truncxf<mode>2 (operands[0], op1));
17581 emit_insn (gen_truncxf<mode>2_i387_noop_unspec (operands[0], op1));
17586 (define_insn "*sinxf2_i387"
17587 [(set (match_operand:XF 0 "register_operand" "=f")
17588 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_SIN))]
17589 "TARGET_USE_FANCY_MATH_387
17590 && flag_unsafe_math_optimizations"
17592 [(set_attr "type" "fpspc")
17593 (set_attr "mode" "XF")])
17595 (define_insn "*sin_extend<mode>xf2_i387"
17596 [(set (match_operand:XF 0 "register_operand" "=f")
17597 (unspec:XF [(float_extend:XF
17598 (match_operand:MODEF 1 "register_operand" "0"))]
17600 "TARGET_USE_FANCY_MATH_387
17601 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17602 || TARGET_MIX_SSE_I387)
17603 && flag_unsafe_math_optimizations"
17605 [(set_attr "type" "fpspc")
17606 (set_attr "mode" "XF")])
17608 (define_insn "*cosxf2_i387"
17609 [(set (match_operand:XF 0 "register_operand" "=f")
17610 (unspec:XF [(match_operand:XF 1 "register_operand" "0")] UNSPEC_COS))]
17611 "TARGET_USE_FANCY_MATH_387
17612 && flag_unsafe_math_optimizations"
17614 [(set_attr "type" "fpspc")
17615 (set_attr "mode" "XF")])
17617 (define_insn "*cos_extend<mode>xf2_i387"
17618 [(set (match_operand:XF 0 "register_operand" "=f")
17619 (unspec:XF [(float_extend:XF
17620 (match_operand:MODEF 1 "register_operand" "0"))]
17622 "TARGET_USE_FANCY_MATH_387
17623 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17624 || TARGET_MIX_SSE_I387)
17625 && flag_unsafe_math_optimizations"
17627 [(set_attr "type" "fpspc")
17628 (set_attr "mode" "XF")])
17630 ;; When sincos pattern is defined, sin and cos builtin functions will be
17631 ;; expanded to sincos pattern with one of its outputs left unused.
17632 ;; CSE pass will figure out if two sincos patterns can be combined,
17633 ;; otherwise sincos pattern will be split back to sin or cos pattern,
17634 ;; depending on the unused output.
17636 (define_insn "sincosxf3"
17637 [(set (match_operand:XF 0 "register_operand" "=f")
17638 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17639 UNSPEC_SINCOS_COS))
17640 (set (match_operand:XF 1 "register_operand" "=u")
17641 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17642 "TARGET_USE_FANCY_MATH_387
17643 && flag_unsafe_math_optimizations"
17645 [(set_attr "type" "fpspc")
17646 (set_attr "mode" "XF")])
17649 [(set (match_operand:XF 0 "register_operand" "")
17650 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17651 UNSPEC_SINCOS_COS))
17652 (set (match_operand:XF 1 "register_operand" "")
17653 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17654 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17655 && !(reload_completed || reload_in_progress)"
17656 [(set (match_dup 1) (unspec:XF [(match_dup 2)] UNSPEC_SIN))]
17660 [(set (match_operand:XF 0 "register_operand" "")
17661 (unspec:XF [(match_operand:XF 2 "register_operand" "")]
17662 UNSPEC_SINCOS_COS))
17663 (set (match_operand:XF 1 "register_operand" "")
17664 (unspec:XF [(match_dup 2)] UNSPEC_SINCOS_SIN))]
17665 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17666 && !(reload_completed || reload_in_progress)"
17667 [(set (match_dup 0) (unspec:XF [(match_dup 2)] UNSPEC_COS))]
17670 (define_insn "sincos_extend<mode>xf3_i387"
17671 [(set (match_operand:XF 0 "register_operand" "=f")
17672 (unspec:XF [(float_extend:XF
17673 (match_operand:MODEF 2 "register_operand" "0"))]
17674 UNSPEC_SINCOS_COS))
17675 (set (match_operand:XF 1 "register_operand" "=u")
17676 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17677 "TARGET_USE_FANCY_MATH_387
17678 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17679 || TARGET_MIX_SSE_I387)
17680 && flag_unsafe_math_optimizations"
17682 [(set_attr "type" "fpspc")
17683 (set_attr "mode" "XF")])
17686 [(set (match_operand:XF 0 "register_operand" "")
17687 (unspec:XF [(float_extend:XF
17688 (match_operand:MODEF 2 "register_operand" ""))]
17689 UNSPEC_SINCOS_COS))
17690 (set (match_operand:XF 1 "register_operand" "")
17691 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17692 "find_regno_note (insn, REG_UNUSED, REGNO (operands[0]))
17693 && !(reload_completed || reload_in_progress)"
17694 [(set (match_dup 1) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SIN))]
17698 [(set (match_operand:XF 0 "register_operand" "")
17699 (unspec:XF [(float_extend:XF
17700 (match_operand:MODEF 2 "register_operand" ""))]
17701 UNSPEC_SINCOS_COS))
17702 (set (match_operand:XF 1 "register_operand" "")
17703 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_SINCOS_SIN))]
17704 "find_regno_note (insn, REG_UNUSED, REGNO (operands[1]))
17705 && !(reload_completed || reload_in_progress)"
17706 [(set (match_dup 0) (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_COS))]
17709 (define_expand "sincos<mode>3"
17710 [(use (match_operand:MODEF 0 "register_operand" ""))
17711 (use (match_operand:MODEF 1 "register_operand" ""))
17712 (use (match_operand:MODEF 2 "register_operand" ""))]
17713 "TARGET_USE_FANCY_MATH_387
17714 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17715 || TARGET_MIX_SSE_I387)
17716 && flag_unsafe_math_optimizations"
17718 rtx op0 = gen_reg_rtx (XFmode);
17719 rtx op1 = gen_reg_rtx (XFmode);
17721 emit_insn (gen_sincos_extend<mode>xf3_i387 (op0, op1, operands[2]));
17722 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17723 emit_insn (gen_truncxf<mode>2_i387_noop (operands[1], op1));
17727 (define_insn "fptanxf4_i387"
17728 [(set (match_operand:XF 0 "register_operand" "=f")
17729 (match_operand:XF 3 "const_double_operand" "F"))
17730 (set (match_operand:XF 1 "register_operand" "=u")
17731 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
17733 "TARGET_USE_FANCY_MATH_387
17734 && flag_unsafe_math_optimizations
17735 && standard_80387_constant_p (operands[3]) == 2"
17737 [(set_attr "type" "fpspc")
17738 (set_attr "mode" "XF")])
17740 (define_insn "fptan_extend<mode>xf4_i387"
17741 [(set (match_operand:MODEF 0 "register_operand" "=f")
17742 (match_operand:MODEF 3 "const_double_operand" "F"))
17743 (set (match_operand:XF 1 "register_operand" "=u")
17744 (unspec:XF [(float_extend:XF
17745 (match_operand:MODEF 2 "register_operand" "0"))]
17747 "TARGET_USE_FANCY_MATH_387
17748 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17749 || TARGET_MIX_SSE_I387)
17750 && flag_unsafe_math_optimizations
17751 && standard_80387_constant_p (operands[3]) == 2"
17753 [(set_attr "type" "fpspc")
17754 (set_attr "mode" "XF")])
17756 (define_expand "tanxf2"
17757 [(use (match_operand:XF 0 "register_operand" ""))
17758 (use (match_operand:XF 1 "register_operand" ""))]
17759 "TARGET_USE_FANCY_MATH_387
17760 && flag_unsafe_math_optimizations"
17762 rtx one = gen_reg_rtx (XFmode);
17763 rtx op2 = CONST1_RTX (XFmode); /* fld1 */
17765 emit_insn (gen_fptanxf4_i387 (one, operands[0], operands[1], op2));
17769 (define_expand "tan<mode>2"
17770 [(use (match_operand:MODEF 0 "register_operand" ""))
17771 (use (match_operand:MODEF 1 "register_operand" ""))]
17772 "TARGET_USE_FANCY_MATH_387
17773 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17774 || TARGET_MIX_SSE_I387)
17775 && flag_unsafe_math_optimizations"
17777 rtx op0 = gen_reg_rtx (XFmode);
17779 rtx one = gen_reg_rtx (<MODE>mode);
17780 rtx op2 = CONST1_RTX (<MODE>mode); /* fld1 */
17782 emit_insn (gen_fptan_extend<mode>xf4_i387 (one, op0,
17783 operands[1], op2));
17784 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17788 (define_insn "*fpatanxf3_i387"
17789 [(set (match_operand:XF 0 "register_operand" "=f")
17790 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17791 (match_operand:XF 2 "register_operand" "u")]
17793 (clobber (match_scratch:XF 3 "=2"))]
17794 "TARGET_USE_FANCY_MATH_387
17795 && flag_unsafe_math_optimizations"
17797 [(set_attr "type" "fpspc")
17798 (set_attr "mode" "XF")])
17800 (define_insn "fpatan_extend<mode>xf3_i387"
17801 [(set (match_operand:XF 0 "register_operand" "=f")
17802 (unspec:XF [(float_extend:XF
17803 (match_operand:MODEF 1 "register_operand" "0"))
17805 (match_operand:MODEF 2 "register_operand" "u"))]
17807 (clobber (match_scratch:XF 3 "=2"))]
17808 "TARGET_USE_FANCY_MATH_387
17809 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17810 || TARGET_MIX_SSE_I387)
17811 && flag_unsafe_math_optimizations"
17813 [(set_attr "type" "fpspc")
17814 (set_attr "mode" "XF")])
17816 (define_expand "atan2xf3"
17817 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17818 (unspec:XF [(match_operand:XF 2 "register_operand" "")
17819 (match_operand:XF 1 "register_operand" "")]
17821 (clobber (match_scratch:XF 3 ""))])]
17822 "TARGET_USE_FANCY_MATH_387
17823 && flag_unsafe_math_optimizations"
17826 (define_expand "atan2<mode>3"
17827 [(use (match_operand:MODEF 0 "register_operand" ""))
17828 (use (match_operand:MODEF 1 "register_operand" ""))
17829 (use (match_operand:MODEF 2 "register_operand" ""))]
17830 "TARGET_USE_FANCY_MATH_387
17831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17832 || TARGET_MIX_SSE_I387)
17833 && flag_unsafe_math_optimizations"
17835 rtx op0 = gen_reg_rtx (XFmode);
17837 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, operands[2], operands[1]));
17838 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17842 (define_expand "atanxf2"
17843 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17844 (unspec:XF [(match_dup 2)
17845 (match_operand:XF 1 "register_operand" "")]
17847 (clobber (match_scratch:XF 3 ""))])]
17848 "TARGET_USE_FANCY_MATH_387
17849 && flag_unsafe_math_optimizations"
17851 operands[2] = gen_reg_rtx (XFmode);
17852 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
17855 (define_expand "atan<mode>2"
17856 [(use (match_operand:MODEF 0 "register_operand" ""))
17857 (use (match_operand:MODEF 1 "register_operand" ""))]
17858 "TARGET_USE_FANCY_MATH_387
17859 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17860 || TARGET_MIX_SSE_I387)
17861 && flag_unsafe_math_optimizations"
17863 rtx op0 = gen_reg_rtx (XFmode);
17865 rtx op2 = gen_reg_rtx (<MODE>mode);
17866 emit_move_insn (op2, CONST1_RTX (<MODE>mode)); /* fld1 */
17868 emit_insn (gen_fpatan_extend<mode>xf3_i387 (op0, op2, operands[1]));
17869 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17873 (define_expand "asinxf2"
17874 [(set (match_dup 2)
17875 (mult:XF (match_operand:XF 1 "register_operand" "")
17877 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17878 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17879 (parallel [(set (match_operand:XF 0 "register_operand" "")
17880 (unspec:XF [(match_dup 5) (match_dup 1)]
17882 (clobber (match_scratch:XF 6 ""))])]
17883 "TARGET_USE_FANCY_MATH_387
17884 && flag_unsafe_math_optimizations"
17888 if (optimize_insn_for_size_p ())
17891 for (i = 2; i < 6; i++)
17892 operands[i] = gen_reg_rtx (XFmode);
17894 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17897 (define_expand "asin<mode>2"
17898 [(use (match_operand:MODEF 0 "register_operand" ""))
17899 (use (match_operand:MODEF 1 "general_operand" ""))]
17900 "TARGET_USE_FANCY_MATH_387
17901 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17902 || TARGET_MIX_SSE_I387)
17903 && flag_unsafe_math_optimizations"
17905 rtx op0 = gen_reg_rtx (XFmode);
17906 rtx op1 = gen_reg_rtx (XFmode);
17908 if (optimize_insn_for_size_p ())
17911 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17912 emit_insn (gen_asinxf2 (op0, op1));
17913 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17917 (define_expand "acosxf2"
17918 [(set (match_dup 2)
17919 (mult:XF (match_operand:XF 1 "register_operand" "")
17921 (set (match_dup 4) (minus:XF (match_dup 3) (match_dup 2)))
17922 (set (match_dup 5) (sqrt:XF (match_dup 4)))
17923 (parallel [(set (match_operand:XF 0 "register_operand" "")
17924 (unspec:XF [(match_dup 1) (match_dup 5)]
17926 (clobber (match_scratch:XF 6 ""))])]
17927 "TARGET_USE_FANCY_MATH_387
17928 && flag_unsafe_math_optimizations"
17932 if (optimize_insn_for_size_p ())
17935 for (i = 2; i < 6; i++)
17936 operands[i] = gen_reg_rtx (XFmode);
17938 emit_move_insn (operands[3], CONST1_RTX (XFmode)); /* fld1 */
17941 (define_expand "acos<mode>2"
17942 [(use (match_operand:MODEF 0 "register_operand" ""))
17943 (use (match_operand:MODEF 1 "general_operand" ""))]
17944 "TARGET_USE_FANCY_MATH_387
17945 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17946 || TARGET_MIX_SSE_I387)
17947 && flag_unsafe_math_optimizations"
17949 rtx op0 = gen_reg_rtx (XFmode);
17950 rtx op1 = gen_reg_rtx (XFmode);
17952 if (optimize_insn_for_size_p ())
17955 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
17956 emit_insn (gen_acosxf2 (op0, op1));
17957 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
17961 (define_insn "fyl2xxf3_i387"
17962 [(set (match_operand:XF 0 "register_operand" "=f")
17963 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
17964 (match_operand:XF 2 "register_operand" "u")]
17966 (clobber (match_scratch:XF 3 "=2"))]
17967 "TARGET_USE_FANCY_MATH_387
17968 && flag_unsafe_math_optimizations"
17970 [(set_attr "type" "fpspc")
17971 (set_attr "mode" "XF")])
17973 (define_insn "fyl2x_extend<mode>xf3_i387"
17974 [(set (match_operand:XF 0 "register_operand" "=f")
17975 (unspec:XF [(float_extend:XF
17976 (match_operand:MODEF 1 "register_operand" "0"))
17977 (match_operand:XF 2 "register_operand" "u")]
17979 (clobber (match_scratch:XF 3 "=2"))]
17980 "TARGET_USE_FANCY_MATH_387
17981 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
17982 || TARGET_MIX_SSE_I387)
17983 && flag_unsafe_math_optimizations"
17985 [(set_attr "type" "fpspc")
17986 (set_attr "mode" "XF")])
17988 (define_expand "logxf2"
17989 [(parallel [(set (match_operand:XF 0 "register_operand" "")
17990 (unspec:XF [(match_operand:XF 1 "register_operand" "")
17991 (match_dup 2)] UNSPEC_FYL2X))
17992 (clobber (match_scratch:XF 3 ""))])]
17993 "TARGET_USE_FANCY_MATH_387
17994 && flag_unsafe_math_optimizations"
17996 operands[2] = gen_reg_rtx (XFmode);
17997 emit_move_insn (operands[2], standard_80387_constant_rtx (4)); /* fldln2 */
18000 (define_expand "log<mode>2"
18001 [(use (match_operand:MODEF 0 "register_operand" ""))
18002 (use (match_operand:MODEF 1 "register_operand" ""))]
18003 "TARGET_USE_FANCY_MATH_387
18004 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18005 || TARGET_MIX_SSE_I387)
18006 && flag_unsafe_math_optimizations"
18008 rtx op0 = gen_reg_rtx (XFmode);
18010 rtx op2 = gen_reg_rtx (XFmode);
18011 emit_move_insn (op2, standard_80387_constant_rtx (4)); /* fldln2 */
18013 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
18014 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18018 (define_expand "log10xf2"
18019 [(parallel [(set (match_operand:XF 0 "register_operand" "")
18020 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18021 (match_dup 2)] UNSPEC_FYL2X))
18022 (clobber (match_scratch:XF 3 ""))])]
18023 "TARGET_USE_FANCY_MATH_387
18024 && flag_unsafe_math_optimizations"
18026 operands[2] = gen_reg_rtx (XFmode);
18027 emit_move_insn (operands[2], standard_80387_constant_rtx (3)); /* fldlg2 */
18030 (define_expand "log10<mode>2"
18031 [(use (match_operand:MODEF 0 "register_operand" ""))
18032 (use (match_operand:MODEF 1 "register_operand" ""))]
18033 "TARGET_USE_FANCY_MATH_387
18034 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18035 || TARGET_MIX_SSE_I387)
18036 && flag_unsafe_math_optimizations"
18038 rtx op0 = gen_reg_rtx (XFmode);
18040 rtx op2 = gen_reg_rtx (XFmode);
18041 emit_move_insn (op2, standard_80387_constant_rtx (3)); /* fldlg2 */
18043 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
18044 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18048 (define_expand "log2xf2"
18049 [(parallel [(set (match_operand:XF 0 "register_operand" "")
18050 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18051 (match_dup 2)] UNSPEC_FYL2X))
18052 (clobber (match_scratch:XF 3 ""))])]
18053 "TARGET_USE_FANCY_MATH_387
18054 && flag_unsafe_math_optimizations"
18056 operands[2] = gen_reg_rtx (XFmode);
18057 emit_move_insn (operands[2], CONST1_RTX (XFmode)); /* fld1 */
18060 (define_expand "log2<mode>2"
18061 [(use (match_operand:MODEF 0 "register_operand" ""))
18062 (use (match_operand:MODEF 1 "register_operand" ""))]
18063 "TARGET_USE_FANCY_MATH_387
18064 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18065 || TARGET_MIX_SSE_I387)
18066 && flag_unsafe_math_optimizations"
18068 rtx op0 = gen_reg_rtx (XFmode);
18070 rtx op2 = gen_reg_rtx (XFmode);
18071 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
18073 emit_insn (gen_fyl2x_extend<mode>xf3_i387 (op0, operands[1], op2));
18074 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18078 (define_insn "fyl2xp1xf3_i387"
18079 [(set (match_operand:XF 0 "register_operand" "=f")
18080 (unspec:XF [(match_operand:XF 1 "register_operand" "0")
18081 (match_operand:XF 2 "register_operand" "u")]
18083 (clobber (match_scratch:XF 3 "=2"))]
18084 "TARGET_USE_FANCY_MATH_387
18085 && flag_unsafe_math_optimizations"
18087 [(set_attr "type" "fpspc")
18088 (set_attr "mode" "XF")])
18090 (define_insn "fyl2xp1_extend<mode>xf3_i387"
18091 [(set (match_operand:XF 0 "register_operand" "=f")
18092 (unspec:XF [(float_extend:XF
18093 (match_operand:MODEF 1 "register_operand" "0"))
18094 (match_operand:XF 2 "register_operand" "u")]
18096 (clobber (match_scratch:XF 3 "=2"))]
18097 "TARGET_USE_FANCY_MATH_387
18098 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18099 || TARGET_MIX_SSE_I387)
18100 && flag_unsafe_math_optimizations"
18102 [(set_attr "type" "fpspc")
18103 (set_attr "mode" "XF")])
18105 (define_expand "log1pxf2"
18106 [(use (match_operand:XF 0 "register_operand" ""))
18107 (use (match_operand:XF 1 "register_operand" ""))]
18108 "TARGET_USE_FANCY_MATH_387
18109 && flag_unsafe_math_optimizations"
18111 if (optimize_insn_for_size_p ())
18114 ix86_emit_i387_log1p (operands[0], operands[1]);
18118 (define_expand "log1p<mode>2"
18119 [(use (match_operand:MODEF 0 "register_operand" ""))
18120 (use (match_operand:MODEF 1 "register_operand" ""))]
18121 "TARGET_USE_FANCY_MATH_387
18122 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18123 || TARGET_MIX_SSE_I387)
18124 && flag_unsafe_math_optimizations"
18128 if (optimize_insn_for_size_p ())
18131 op0 = gen_reg_rtx (XFmode);
18133 operands[1] = gen_rtx_FLOAT_EXTEND (XFmode, operands[1]);
18135 ix86_emit_i387_log1p (op0, operands[1]);
18136 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18140 (define_insn "fxtractxf3_i387"
18141 [(set (match_operand:XF 0 "register_operand" "=f")
18142 (unspec:XF [(match_operand:XF 2 "register_operand" "0")]
18143 UNSPEC_XTRACT_FRACT))
18144 (set (match_operand:XF 1 "register_operand" "=u")
18145 (unspec:XF [(match_dup 2)] UNSPEC_XTRACT_EXP))]
18146 "TARGET_USE_FANCY_MATH_387
18147 && flag_unsafe_math_optimizations"
18149 [(set_attr "type" "fpspc")
18150 (set_attr "mode" "XF")])
18152 (define_insn "fxtract_extend<mode>xf3_i387"
18153 [(set (match_operand:XF 0 "register_operand" "=f")
18154 (unspec:XF [(float_extend:XF
18155 (match_operand:MODEF 2 "register_operand" "0"))]
18156 UNSPEC_XTRACT_FRACT))
18157 (set (match_operand:XF 1 "register_operand" "=u")
18158 (unspec:XF [(float_extend:XF (match_dup 2))] UNSPEC_XTRACT_EXP))]
18159 "TARGET_USE_FANCY_MATH_387
18160 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18161 || TARGET_MIX_SSE_I387)
18162 && flag_unsafe_math_optimizations"
18164 [(set_attr "type" "fpspc")
18165 (set_attr "mode" "XF")])
18167 (define_expand "logbxf2"
18168 [(parallel [(set (match_dup 2)
18169 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18170 UNSPEC_XTRACT_FRACT))
18171 (set (match_operand:XF 0 "register_operand" "")
18172 (unspec:XF [(match_dup 1)] UNSPEC_XTRACT_EXP))])]
18173 "TARGET_USE_FANCY_MATH_387
18174 && flag_unsafe_math_optimizations"
18176 operands[2] = gen_reg_rtx (XFmode);
18179 (define_expand "logb<mode>2"
18180 [(use (match_operand:MODEF 0 "register_operand" ""))
18181 (use (match_operand:MODEF 1 "register_operand" ""))]
18182 "TARGET_USE_FANCY_MATH_387
18183 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18184 || TARGET_MIX_SSE_I387)
18185 && flag_unsafe_math_optimizations"
18187 rtx op0 = gen_reg_rtx (XFmode);
18188 rtx op1 = gen_reg_rtx (XFmode);
18190 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18191 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op1));
18195 (define_expand "ilogbxf2"
18196 [(use (match_operand:SI 0 "register_operand" ""))
18197 (use (match_operand:XF 1 "register_operand" ""))]
18198 "TARGET_USE_FANCY_MATH_387
18199 && flag_unsafe_math_optimizations"
18203 if (optimize_insn_for_size_p ())
18206 op0 = gen_reg_rtx (XFmode);
18207 op1 = gen_reg_rtx (XFmode);
18209 emit_insn (gen_fxtractxf3_i387 (op0, op1, operands[1]));
18210 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18214 (define_expand "ilogb<mode>2"
18215 [(use (match_operand:SI 0 "register_operand" ""))
18216 (use (match_operand:MODEF 1 "register_operand" ""))]
18217 "TARGET_USE_FANCY_MATH_387
18218 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18219 || TARGET_MIX_SSE_I387)
18220 && flag_unsafe_math_optimizations"
18224 if (optimize_insn_for_size_p ())
18227 op0 = gen_reg_rtx (XFmode);
18228 op1 = gen_reg_rtx (XFmode);
18230 emit_insn (gen_fxtract_extend<mode>xf3_i387 (op0, op1, operands[1]));
18231 emit_insn (gen_fix_truncxfsi2 (operands[0], op1));
18235 (define_insn "*f2xm1xf2_i387"
18236 [(set (match_operand:XF 0 "register_operand" "=f")
18237 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18239 "TARGET_USE_FANCY_MATH_387
18240 && flag_unsafe_math_optimizations"
18242 [(set_attr "type" "fpspc")
18243 (set_attr "mode" "XF")])
18245 (define_insn "*fscalexf4_i387"
18246 [(set (match_operand:XF 0 "register_operand" "=f")
18247 (unspec:XF [(match_operand:XF 2 "register_operand" "0")
18248 (match_operand:XF 3 "register_operand" "1")]
18249 UNSPEC_FSCALE_FRACT))
18250 (set (match_operand:XF 1 "register_operand" "=u")
18251 (unspec:XF [(match_dup 2) (match_dup 3)]
18252 UNSPEC_FSCALE_EXP))]
18253 "TARGET_USE_FANCY_MATH_387
18254 && flag_unsafe_math_optimizations"
18256 [(set_attr "type" "fpspc")
18257 (set_attr "mode" "XF")])
18259 (define_expand "expNcorexf3"
18260 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18261 (match_operand:XF 2 "register_operand" "")))
18262 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18263 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18264 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18265 (set (match_dup 8) (plus:XF (match_dup 6) (match_dup 7)))
18266 (parallel [(set (match_operand:XF 0 "register_operand" "")
18267 (unspec:XF [(match_dup 8) (match_dup 4)]
18268 UNSPEC_FSCALE_FRACT))
18270 (unspec:XF [(match_dup 8) (match_dup 4)]
18271 UNSPEC_FSCALE_EXP))])]
18272 "TARGET_USE_FANCY_MATH_387
18273 && flag_unsafe_math_optimizations"
18277 if (optimize_insn_for_size_p ())
18280 for (i = 3; i < 10; i++)
18281 operands[i] = gen_reg_rtx (XFmode);
18283 emit_move_insn (operands[7], CONST1_RTX (XFmode)); /* fld1 */
18286 (define_expand "expxf2"
18287 [(use (match_operand:XF 0 "register_operand" ""))
18288 (use (match_operand:XF 1 "register_operand" ""))]
18289 "TARGET_USE_FANCY_MATH_387
18290 && flag_unsafe_math_optimizations"
18294 if (optimize_insn_for_size_p ())
18297 op2 = gen_reg_rtx (XFmode);
18298 emit_move_insn (op2, standard_80387_constant_rtx (5)); /* fldl2e */
18300 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18304 (define_expand "exp<mode>2"
18305 [(use (match_operand:MODEF 0 "register_operand" ""))
18306 (use (match_operand:MODEF 1 "general_operand" ""))]
18307 "TARGET_USE_FANCY_MATH_387
18308 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18309 || TARGET_MIX_SSE_I387)
18310 && flag_unsafe_math_optimizations"
18314 if (optimize_insn_for_size_p ())
18317 op0 = gen_reg_rtx (XFmode);
18318 op1 = gen_reg_rtx (XFmode);
18320 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18321 emit_insn (gen_expxf2 (op0, op1));
18322 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18326 (define_expand "exp10xf2"
18327 [(use (match_operand:XF 0 "register_operand" ""))
18328 (use (match_operand:XF 1 "register_operand" ""))]
18329 "TARGET_USE_FANCY_MATH_387
18330 && flag_unsafe_math_optimizations"
18334 if (optimize_insn_for_size_p ())
18337 op2 = gen_reg_rtx (XFmode);
18338 emit_move_insn (op2, standard_80387_constant_rtx (6)); /* fldl2t */
18340 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18344 (define_expand "exp10<mode>2"
18345 [(use (match_operand:MODEF 0 "register_operand" ""))
18346 (use (match_operand:MODEF 1 "general_operand" ""))]
18347 "TARGET_USE_FANCY_MATH_387
18348 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18349 || TARGET_MIX_SSE_I387)
18350 && flag_unsafe_math_optimizations"
18354 if (optimize_insn_for_size_p ())
18357 op0 = gen_reg_rtx (XFmode);
18358 op1 = gen_reg_rtx (XFmode);
18360 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18361 emit_insn (gen_exp10xf2 (op0, op1));
18362 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18366 (define_expand "exp2xf2"
18367 [(use (match_operand:XF 0 "register_operand" ""))
18368 (use (match_operand:XF 1 "register_operand" ""))]
18369 "TARGET_USE_FANCY_MATH_387
18370 && flag_unsafe_math_optimizations"
18374 if (optimize_insn_for_size_p ())
18377 op2 = gen_reg_rtx (XFmode);
18378 emit_move_insn (op2, CONST1_RTX (XFmode)); /* fld1 */
18380 emit_insn (gen_expNcorexf3 (operands[0], operands[1], op2));
18384 (define_expand "exp2<mode>2"
18385 [(use (match_operand:MODEF 0 "register_operand" ""))
18386 (use (match_operand:MODEF 1 "general_operand" ""))]
18387 "TARGET_USE_FANCY_MATH_387
18388 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18389 || TARGET_MIX_SSE_I387)
18390 && flag_unsafe_math_optimizations"
18394 if (optimize_insn_for_size_p ())
18397 op0 = gen_reg_rtx (XFmode);
18398 op1 = gen_reg_rtx (XFmode);
18400 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18401 emit_insn (gen_exp2xf2 (op0, op1));
18402 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18406 (define_expand "expm1xf2"
18407 [(set (match_dup 3) (mult:XF (match_operand:XF 1 "register_operand" "")
18409 (set (match_dup 4) (unspec:XF [(match_dup 3)] UNSPEC_FRNDINT))
18410 (set (match_dup 5) (minus:XF (match_dup 3) (match_dup 4)))
18411 (set (match_dup 9) (float_extend:XF (match_dup 13)))
18412 (set (match_dup 6) (unspec:XF [(match_dup 5)] UNSPEC_F2XM1))
18413 (parallel [(set (match_dup 7)
18414 (unspec:XF [(match_dup 6) (match_dup 4)]
18415 UNSPEC_FSCALE_FRACT))
18417 (unspec:XF [(match_dup 6) (match_dup 4)]
18418 UNSPEC_FSCALE_EXP))])
18419 (parallel [(set (match_dup 10)
18420 (unspec:XF [(match_dup 9) (match_dup 8)]
18421 UNSPEC_FSCALE_FRACT))
18422 (set (match_dup 11)
18423 (unspec:XF [(match_dup 9) (match_dup 8)]
18424 UNSPEC_FSCALE_EXP))])
18425 (set (match_dup 12) (minus:XF (match_dup 10)
18426 (float_extend:XF (match_dup 13))))
18427 (set (match_operand:XF 0 "register_operand" "")
18428 (plus:XF (match_dup 12) (match_dup 7)))]
18429 "TARGET_USE_FANCY_MATH_387
18430 && flag_unsafe_math_optimizations"
18434 if (optimize_insn_for_size_p ())
18437 for (i = 2; i < 13; i++)
18438 operands[i] = gen_reg_rtx (XFmode);
18441 = validize_mem (force_const_mem (SFmode, CONST1_RTX (SFmode))); /* fld1 */
18443 emit_move_insn (operands[2], standard_80387_constant_rtx (5)); /* fldl2e */
18446 (define_expand "expm1<mode>2"
18447 [(use (match_operand:MODEF 0 "register_operand" ""))
18448 (use (match_operand:MODEF 1 "general_operand" ""))]
18449 "TARGET_USE_FANCY_MATH_387
18450 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18451 || TARGET_MIX_SSE_I387)
18452 && flag_unsafe_math_optimizations"
18456 if (optimize_insn_for_size_p ())
18459 op0 = gen_reg_rtx (XFmode);
18460 op1 = gen_reg_rtx (XFmode);
18462 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18463 emit_insn (gen_expm1xf2 (op0, op1));
18464 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18468 (define_expand "ldexpxf3"
18469 [(set (match_dup 3)
18470 (float:XF (match_operand:SI 2 "register_operand" "")))
18471 (parallel [(set (match_operand:XF 0 " register_operand" "")
18472 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18474 UNSPEC_FSCALE_FRACT))
18476 (unspec:XF [(match_dup 1) (match_dup 3)]
18477 UNSPEC_FSCALE_EXP))])]
18478 "TARGET_USE_FANCY_MATH_387
18479 && flag_unsafe_math_optimizations"
18481 if (optimize_insn_for_size_p ())
18484 operands[3] = gen_reg_rtx (XFmode);
18485 operands[4] = gen_reg_rtx (XFmode);
18488 (define_expand "ldexp<mode>3"
18489 [(use (match_operand:MODEF 0 "register_operand" ""))
18490 (use (match_operand:MODEF 1 "general_operand" ""))
18491 (use (match_operand:SI 2 "register_operand" ""))]
18492 "TARGET_USE_FANCY_MATH_387
18493 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18494 || TARGET_MIX_SSE_I387)
18495 && flag_unsafe_math_optimizations"
18499 if (optimize_insn_for_size_p ())
18502 op0 = gen_reg_rtx (XFmode);
18503 op1 = gen_reg_rtx (XFmode);
18505 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18506 emit_insn (gen_ldexpxf3 (op0, op1, operands[2]));
18507 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18511 (define_expand "scalbxf3"
18512 [(parallel [(set (match_operand:XF 0 " register_operand" "")
18513 (unspec:XF [(match_operand:XF 1 "register_operand" "")
18514 (match_operand:XF 2 "register_operand" "")]
18515 UNSPEC_FSCALE_FRACT))
18517 (unspec:XF [(match_dup 1) (match_dup 2)]
18518 UNSPEC_FSCALE_EXP))])]
18519 "TARGET_USE_FANCY_MATH_387
18520 && flag_unsafe_math_optimizations"
18522 if (optimize_insn_for_size_p ())
18525 operands[3] = gen_reg_rtx (XFmode);
18528 (define_expand "scalb<mode>3"
18529 [(use (match_operand:MODEF 0 "register_operand" ""))
18530 (use (match_operand:MODEF 1 "general_operand" ""))
18531 (use (match_operand:MODEF 2 "register_operand" ""))]
18532 "TARGET_USE_FANCY_MATH_387
18533 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18534 || TARGET_MIX_SSE_I387)
18535 && flag_unsafe_math_optimizations"
18539 if (optimize_insn_for_size_p ())
18542 op0 = gen_reg_rtx (XFmode);
18543 op1 = gen_reg_rtx (XFmode);
18544 op2 = gen_reg_rtx (XFmode);
18546 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18547 emit_insn (gen_extend<mode>xf2 (op2, operands[2]));
18548 emit_insn (gen_scalbxf3 (op0, op1, op2));
18549 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18554 (define_insn "sse4_1_round<mode>2"
18555 [(set (match_operand:MODEF 0 "register_operand" "=x")
18556 (unspec:MODEF [(match_operand:MODEF 1 "register_operand" "x")
18557 (match_operand:SI 2 "const_0_to_15_operand" "n")]
18560 "%vrounds<ssemodefsuffix>\t{%2, %1, %d0|%d0, %1, %2}"
18561 [(set_attr "type" "ssecvt")
18562 (set_attr "prefix_extra" "1")
18563 (set_attr "prefix" "maybe_vex")
18564 (set_attr "mode" "<MODE>")])
18566 (define_insn "rintxf2"
18567 [(set (match_operand:XF 0 "register_operand" "=f")
18568 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18570 "TARGET_USE_FANCY_MATH_387
18571 && flag_unsafe_math_optimizations"
18573 [(set_attr "type" "fpspc")
18574 (set_attr "mode" "XF")])
18576 (define_expand "rint<mode>2"
18577 [(use (match_operand:MODEF 0 "register_operand" ""))
18578 (use (match_operand:MODEF 1 "register_operand" ""))]
18579 "(TARGET_USE_FANCY_MATH_387
18580 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18581 || TARGET_MIX_SSE_I387)
18582 && flag_unsafe_math_optimizations)
18583 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18584 && !flag_trapping_math)"
18586 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18587 && !flag_trapping_math)
18589 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18592 emit_insn (gen_sse4_1_round<mode>2
18593 (operands[0], operands[1], GEN_INT (0x04)));
18595 ix86_expand_rint (operand0, operand1);
18599 rtx op0 = gen_reg_rtx (XFmode);
18600 rtx op1 = gen_reg_rtx (XFmode);
18602 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18603 emit_insn (gen_rintxf2 (op0, op1));
18605 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18610 (define_expand "round<mode>2"
18611 [(match_operand:MODEF 0 "register_operand" "")
18612 (match_operand:MODEF 1 "nonimmediate_operand" "")]
18613 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18614 && !flag_trapping_math && !flag_rounding_math"
18616 if (optimize_insn_for_size_p ())
18618 if (TARGET_64BIT || (<MODE>mode != DFmode))
18619 ix86_expand_round (operand0, operand1);
18621 ix86_expand_rounddf_32 (operand0, operand1);
18625 (define_insn_and_split "*fistdi2_1"
18626 [(set (match_operand:DI 0 "nonimmediate_operand" "")
18627 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18629 "TARGET_USE_FANCY_MATH_387
18630 && !(reload_completed || reload_in_progress)"
18635 if (memory_operand (operands[0], VOIDmode))
18636 emit_insn (gen_fistdi2 (operands[0], operands[1]));
18639 operands[2] = assign_386_stack_local (DImode, SLOT_TEMP);
18640 emit_insn (gen_fistdi2_with_temp (operands[0], operands[1],
18645 [(set_attr "type" "fpspc")
18646 (set_attr "mode" "DI")])
18648 (define_insn "fistdi2"
18649 [(set (match_operand:DI 0 "memory_operand" "=m")
18650 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18652 (clobber (match_scratch:XF 2 "=&1f"))]
18653 "TARGET_USE_FANCY_MATH_387"
18654 "* return output_fix_trunc (insn, operands, 0);"
18655 [(set_attr "type" "fpspc")
18656 (set_attr "mode" "DI")])
18658 (define_insn "fistdi2_with_temp"
18659 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18660 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18662 (clobber (match_operand:DI 2 "memory_operand" "=X,m"))
18663 (clobber (match_scratch:XF 3 "=&1f,&1f"))]
18664 "TARGET_USE_FANCY_MATH_387"
18666 [(set_attr "type" "fpspc")
18667 (set_attr "mode" "DI")])
18670 [(set (match_operand:DI 0 "register_operand" "")
18671 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18673 (clobber (match_operand:DI 2 "memory_operand" ""))
18674 (clobber (match_scratch 3 ""))]
18676 [(parallel [(set (match_dup 2) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18677 (clobber (match_dup 3))])
18678 (set (match_dup 0) (match_dup 2))]
18682 [(set (match_operand:DI 0 "memory_operand" "")
18683 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18685 (clobber (match_operand:DI 2 "memory_operand" ""))
18686 (clobber (match_scratch 3 ""))]
18688 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST))
18689 (clobber (match_dup 3))])]
18692 (define_insn_and_split "*fist<mode>2_1"
18693 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18694 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18696 "TARGET_USE_FANCY_MATH_387
18697 && !(reload_completed || reload_in_progress)"
18702 operands[2] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18703 emit_insn (gen_fist<mode>2_with_temp (operands[0], operands[1],
18707 [(set_attr "type" "fpspc")
18708 (set_attr "mode" "<MODE>")])
18710 (define_insn "fist<mode>2"
18711 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18712 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18714 "TARGET_USE_FANCY_MATH_387"
18715 "* return output_fix_trunc (insn, operands, 0);"
18716 [(set_attr "type" "fpspc")
18717 (set_attr "mode" "<MODE>")])
18719 (define_insn "fist<mode>2_with_temp"
18720 [(set (match_operand:X87MODEI12 0 "register_operand" "=r")
18721 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18723 (clobber (match_operand:X87MODEI12 2 "memory_operand" "=m"))]
18724 "TARGET_USE_FANCY_MATH_387"
18726 [(set_attr "type" "fpspc")
18727 (set_attr "mode" "<MODE>")])
18730 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18731 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18733 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18735 [(set (match_dup 2) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))
18736 (set (match_dup 0) (match_dup 2))]
18740 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
18741 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18743 (clobber (match_operand:X87MODEI12 2 "memory_operand" ""))]
18745 [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)] UNSPEC_FIST))]
18748 (define_expand "lrintxf<mode>2"
18749 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18750 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18752 "TARGET_USE_FANCY_MATH_387"
18755 (define_expand "lrint<MODEF:mode><SSEMODEI24:mode>2"
18756 [(set (match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18757 (unspec:SSEMODEI24 [(match_operand:MODEF 1 "register_operand" "")]
18758 UNSPEC_FIX_NOTRUNC))]
18759 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18760 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)"
18763 (define_expand "lround<MODEF:mode><SSEMODEI24:mode>2"
18764 [(match_operand:SSEMODEI24 0 "nonimmediate_operand" "")
18765 (match_operand:MODEF 1 "register_operand" "")]
18766 "SSE_FLOAT_MODE_P (<MODEF:MODE>mode) && TARGET_SSE_MATH
18767 && ((<SSEMODEI24:MODE>mode != DImode) || TARGET_64BIT)
18768 && !flag_trapping_math && !flag_rounding_math"
18770 if (optimize_insn_for_size_p ())
18772 ix86_expand_lround (operand0, operand1);
18776 ;; Rounding mode control word calculation could clobber FLAGS_REG.
18777 (define_insn_and_split "frndintxf2_floor"
18778 [(set (match_operand:XF 0 "register_operand" "")
18779 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
18780 UNSPEC_FRNDINT_FLOOR))
18781 (clobber (reg:CC FLAGS_REG))]
18782 "TARGET_USE_FANCY_MATH_387
18783 && flag_unsafe_math_optimizations
18784 && !(reload_completed || reload_in_progress)"
18789 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18791 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18792 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18794 emit_insn (gen_frndintxf2_floor_i387 (operands[0], operands[1],
18795 operands[2], operands[3]));
18798 [(set_attr "type" "frndint")
18799 (set_attr "i387_cw" "floor")
18800 (set_attr "mode" "XF")])
18802 (define_insn "frndintxf2_floor_i387"
18803 [(set (match_operand:XF 0 "register_operand" "=f")
18804 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
18805 UNSPEC_FRNDINT_FLOOR))
18806 (use (match_operand:HI 2 "memory_operand" "m"))
18807 (use (match_operand:HI 3 "memory_operand" "m"))]
18808 "TARGET_USE_FANCY_MATH_387
18809 && flag_unsafe_math_optimizations"
18810 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
18811 [(set_attr "type" "frndint")
18812 (set_attr "i387_cw" "floor")
18813 (set_attr "mode" "XF")])
18815 (define_expand "floorxf2"
18816 [(use (match_operand:XF 0 "register_operand" ""))
18817 (use (match_operand:XF 1 "register_operand" ""))]
18818 "TARGET_USE_FANCY_MATH_387
18819 && flag_unsafe_math_optimizations"
18821 if (optimize_insn_for_size_p ())
18823 emit_insn (gen_frndintxf2_floor (operands[0], operands[1]));
18827 (define_expand "floor<mode>2"
18828 [(use (match_operand:MODEF 0 "register_operand" ""))
18829 (use (match_operand:MODEF 1 "register_operand" ""))]
18830 "(TARGET_USE_FANCY_MATH_387
18831 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
18832 || TARGET_MIX_SSE_I387)
18833 && flag_unsafe_math_optimizations)
18834 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18835 && !flag_trapping_math)"
18837 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
18838 && !flag_trapping_math
18839 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
18841 if (!TARGET_ROUND && optimize_insn_for_size_p ())
18844 emit_insn (gen_sse4_1_round<mode>2
18845 (operands[0], operands[1], GEN_INT (0x01)));
18846 else if (TARGET_64BIT || (<MODE>mode != DFmode))
18847 ix86_expand_floorceil (operand0, operand1, true);
18849 ix86_expand_floorceildf_32 (operand0, operand1, true);
18855 if (optimize_insn_for_size_p ())
18858 op0 = gen_reg_rtx (XFmode);
18859 op1 = gen_reg_rtx (XFmode);
18860 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
18861 emit_insn (gen_frndintxf2_floor (op0, op1));
18863 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
18868 (define_insn_and_split "*fist<mode>2_floor_1"
18869 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
18870 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
18871 UNSPEC_FIST_FLOOR))
18872 (clobber (reg:CC FLAGS_REG))]
18873 "TARGET_USE_FANCY_MATH_387
18874 && flag_unsafe_math_optimizations
18875 && !(reload_completed || reload_in_progress)"
18880 ix86_optimize_mode_switching[I387_FLOOR] = 1;
18882 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
18883 operands[3] = assign_386_stack_local (HImode, SLOT_CW_FLOOR);
18884 if (memory_operand (operands[0], VOIDmode))
18885 emit_insn (gen_fist<mode>2_floor (operands[0], operands[1],
18886 operands[2], operands[3]));
18889 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
18890 emit_insn (gen_fist<mode>2_floor_with_temp (operands[0], operands[1],
18891 operands[2], operands[3],
18896 [(set_attr "type" "fistp")
18897 (set_attr "i387_cw" "floor")
18898 (set_attr "mode" "<MODE>")])
18900 (define_insn "fistdi2_floor"
18901 [(set (match_operand:DI 0 "memory_operand" "=m")
18902 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
18903 UNSPEC_FIST_FLOOR))
18904 (use (match_operand:HI 2 "memory_operand" "m"))
18905 (use (match_operand:HI 3 "memory_operand" "m"))
18906 (clobber (match_scratch:XF 4 "=&1f"))]
18907 "TARGET_USE_FANCY_MATH_387
18908 && flag_unsafe_math_optimizations"
18909 "* return output_fix_trunc (insn, operands, 0);"
18910 [(set_attr "type" "fistp")
18911 (set_attr "i387_cw" "floor")
18912 (set_attr "mode" "DI")])
18914 (define_insn "fistdi2_floor_with_temp"
18915 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
18916 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
18917 UNSPEC_FIST_FLOOR))
18918 (use (match_operand:HI 2 "memory_operand" "m,m"))
18919 (use (match_operand:HI 3 "memory_operand" "m,m"))
18920 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
18921 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
18922 "TARGET_USE_FANCY_MATH_387
18923 && flag_unsafe_math_optimizations"
18925 [(set_attr "type" "fistp")
18926 (set_attr "i387_cw" "floor")
18927 (set_attr "mode" "DI")])
18930 [(set (match_operand:DI 0 "register_operand" "")
18931 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18932 UNSPEC_FIST_FLOOR))
18933 (use (match_operand:HI 2 "memory_operand" ""))
18934 (use (match_operand:HI 3 "memory_operand" ""))
18935 (clobber (match_operand:DI 4 "memory_operand" ""))
18936 (clobber (match_scratch 5 ""))]
18938 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18939 (use (match_dup 2))
18940 (use (match_dup 3))
18941 (clobber (match_dup 5))])
18942 (set (match_dup 0) (match_dup 4))]
18946 [(set (match_operand:DI 0 "memory_operand" "")
18947 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
18948 UNSPEC_FIST_FLOOR))
18949 (use (match_operand:HI 2 "memory_operand" ""))
18950 (use (match_operand:HI 3 "memory_operand" ""))
18951 (clobber (match_operand:DI 4 "memory_operand" ""))
18952 (clobber (match_scratch 5 ""))]
18954 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_FLOOR))
18955 (use (match_dup 2))
18956 (use (match_dup 3))
18957 (clobber (match_dup 5))])]
18960 (define_insn "fist<mode>2_floor"
18961 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
18962 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
18963 UNSPEC_FIST_FLOOR))
18964 (use (match_operand:HI 2 "memory_operand" "m"))
18965 (use (match_operand:HI 3 "memory_operand" "m"))]
18966 "TARGET_USE_FANCY_MATH_387
18967 && flag_unsafe_math_optimizations"
18968 "* return output_fix_trunc (insn, operands, 0);"
18969 [(set_attr "type" "fistp")
18970 (set_attr "i387_cw" "floor")
18971 (set_attr "mode" "<MODE>")])
18973 (define_insn "fist<mode>2_floor_with_temp"
18974 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
18975 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
18976 UNSPEC_FIST_FLOOR))
18977 (use (match_operand:HI 2 "memory_operand" "m,m"))
18978 (use (match_operand:HI 3 "memory_operand" "m,m"))
18979 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
18980 "TARGET_USE_FANCY_MATH_387
18981 && flag_unsafe_math_optimizations"
18983 [(set_attr "type" "fistp")
18984 (set_attr "i387_cw" "floor")
18985 (set_attr "mode" "<MODE>")])
18988 [(set (match_operand:X87MODEI12 0 "register_operand" "")
18989 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
18990 UNSPEC_FIST_FLOOR))
18991 (use (match_operand:HI 2 "memory_operand" ""))
18992 (use (match_operand:HI 3 "memory_operand" ""))
18993 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
18995 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
18996 UNSPEC_FIST_FLOOR))
18997 (use (match_dup 2))
18998 (use (match_dup 3))])
18999 (set (match_dup 0) (match_dup 4))]
19003 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19004 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19005 UNSPEC_FIST_FLOOR))
19006 (use (match_operand:HI 2 "memory_operand" ""))
19007 (use (match_operand:HI 3 "memory_operand" ""))
19008 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19010 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19011 UNSPEC_FIST_FLOOR))
19012 (use (match_dup 2))
19013 (use (match_dup 3))])]
19016 (define_expand "lfloorxf<mode>2"
19017 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19018 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19019 UNSPEC_FIST_FLOOR))
19020 (clobber (reg:CC FLAGS_REG))])]
19021 "TARGET_USE_FANCY_MATH_387
19022 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19023 && flag_unsafe_math_optimizations"
19026 (define_expand "lfloor<mode>di2"
19027 [(match_operand:DI 0 "nonimmediate_operand" "")
19028 (match_operand:MODEF 1 "register_operand" "")]
19029 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
19030 && !flag_trapping_math"
19032 if (optimize_insn_for_size_p ())
19034 ix86_expand_lfloorceil (operand0, operand1, true);
19038 (define_expand "lfloor<mode>si2"
19039 [(match_operand:SI 0 "nonimmediate_operand" "")
19040 (match_operand:MODEF 1 "register_operand" "")]
19041 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19042 && !flag_trapping_math"
19044 if (optimize_insn_for_size_p () && TARGET_64BIT)
19046 ix86_expand_lfloorceil (operand0, operand1, true);
19050 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19051 (define_insn_and_split "frndintxf2_ceil"
19052 [(set (match_operand:XF 0 "register_operand" "")
19053 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19054 UNSPEC_FRNDINT_CEIL))
19055 (clobber (reg:CC FLAGS_REG))]
19056 "TARGET_USE_FANCY_MATH_387
19057 && flag_unsafe_math_optimizations
19058 && !(reload_completed || reload_in_progress)"
19063 ix86_optimize_mode_switching[I387_CEIL] = 1;
19065 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19066 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19068 emit_insn (gen_frndintxf2_ceil_i387 (operands[0], operands[1],
19069 operands[2], operands[3]));
19072 [(set_attr "type" "frndint")
19073 (set_attr "i387_cw" "ceil")
19074 (set_attr "mode" "XF")])
19076 (define_insn "frndintxf2_ceil_i387"
19077 [(set (match_operand:XF 0 "register_operand" "=f")
19078 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19079 UNSPEC_FRNDINT_CEIL))
19080 (use (match_operand:HI 2 "memory_operand" "m"))
19081 (use (match_operand:HI 3 "memory_operand" "m"))]
19082 "TARGET_USE_FANCY_MATH_387
19083 && flag_unsafe_math_optimizations"
19084 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19085 [(set_attr "type" "frndint")
19086 (set_attr "i387_cw" "ceil")
19087 (set_attr "mode" "XF")])
19089 (define_expand "ceilxf2"
19090 [(use (match_operand:XF 0 "register_operand" ""))
19091 (use (match_operand:XF 1 "register_operand" ""))]
19092 "TARGET_USE_FANCY_MATH_387
19093 && flag_unsafe_math_optimizations"
19095 if (optimize_insn_for_size_p ())
19097 emit_insn (gen_frndintxf2_ceil (operands[0], operands[1]));
19101 (define_expand "ceil<mode>2"
19102 [(use (match_operand:MODEF 0 "register_operand" ""))
19103 (use (match_operand:MODEF 1 "register_operand" ""))]
19104 "(TARGET_USE_FANCY_MATH_387
19105 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19106 || TARGET_MIX_SSE_I387)
19107 && flag_unsafe_math_optimizations)
19108 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19109 && !flag_trapping_math)"
19111 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19112 && !flag_trapping_math
19113 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19116 emit_insn (gen_sse4_1_round<mode>2
19117 (operands[0], operands[1], GEN_INT (0x02)));
19118 else if (optimize_insn_for_size_p ())
19120 else if (TARGET_64BIT || (<MODE>mode != DFmode))
19121 ix86_expand_floorceil (operand0, operand1, false);
19123 ix86_expand_floorceildf_32 (operand0, operand1, false);
19129 if (optimize_insn_for_size_p ())
19132 op0 = gen_reg_rtx (XFmode);
19133 op1 = gen_reg_rtx (XFmode);
19134 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19135 emit_insn (gen_frndintxf2_ceil (op0, op1));
19137 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19142 (define_insn_and_split "*fist<mode>2_ceil_1"
19143 [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19144 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19146 (clobber (reg:CC FLAGS_REG))]
19147 "TARGET_USE_FANCY_MATH_387
19148 && flag_unsafe_math_optimizations
19149 && !(reload_completed || reload_in_progress)"
19154 ix86_optimize_mode_switching[I387_CEIL] = 1;
19156 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19157 operands[3] = assign_386_stack_local (HImode, SLOT_CW_CEIL);
19158 if (memory_operand (operands[0], VOIDmode))
19159 emit_insn (gen_fist<mode>2_ceil (operands[0], operands[1],
19160 operands[2], operands[3]));
19163 operands[4] = assign_386_stack_local (<MODE>mode, SLOT_TEMP);
19164 emit_insn (gen_fist<mode>2_ceil_with_temp (operands[0], operands[1],
19165 operands[2], operands[3],
19170 [(set_attr "type" "fistp")
19171 (set_attr "i387_cw" "ceil")
19172 (set_attr "mode" "<MODE>")])
19174 (define_insn "fistdi2_ceil"
19175 [(set (match_operand:DI 0 "memory_operand" "=m")
19176 (unspec:DI [(match_operand:XF 1 "register_operand" "f")]
19178 (use (match_operand:HI 2 "memory_operand" "m"))
19179 (use (match_operand:HI 3 "memory_operand" "m"))
19180 (clobber (match_scratch:XF 4 "=&1f"))]
19181 "TARGET_USE_FANCY_MATH_387
19182 && flag_unsafe_math_optimizations"
19183 "* return output_fix_trunc (insn, operands, 0);"
19184 [(set_attr "type" "fistp")
19185 (set_attr "i387_cw" "ceil")
19186 (set_attr "mode" "DI")])
19188 (define_insn "fistdi2_ceil_with_temp"
19189 [(set (match_operand:DI 0 "nonimmediate_operand" "=m,?r")
19190 (unspec:DI [(match_operand:XF 1 "register_operand" "f,f")]
19192 (use (match_operand:HI 2 "memory_operand" "m,m"))
19193 (use (match_operand:HI 3 "memory_operand" "m,m"))
19194 (clobber (match_operand:DI 4 "memory_operand" "=X,m"))
19195 (clobber (match_scratch:XF 5 "=&1f,&1f"))]
19196 "TARGET_USE_FANCY_MATH_387
19197 && flag_unsafe_math_optimizations"
19199 [(set_attr "type" "fistp")
19200 (set_attr "i387_cw" "ceil")
19201 (set_attr "mode" "DI")])
19204 [(set (match_operand:DI 0 "register_operand" "")
19205 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19207 (use (match_operand:HI 2 "memory_operand" ""))
19208 (use (match_operand:HI 3 "memory_operand" ""))
19209 (clobber (match_operand:DI 4 "memory_operand" ""))
19210 (clobber (match_scratch 5 ""))]
19212 [(parallel [(set (match_dup 4) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19213 (use (match_dup 2))
19214 (use (match_dup 3))
19215 (clobber (match_dup 5))])
19216 (set (match_dup 0) (match_dup 4))]
19220 [(set (match_operand:DI 0 "memory_operand" "")
19221 (unspec:DI [(match_operand:XF 1 "register_operand" "")]
19223 (use (match_operand:HI 2 "memory_operand" ""))
19224 (use (match_operand:HI 3 "memory_operand" ""))
19225 (clobber (match_operand:DI 4 "memory_operand" ""))
19226 (clobber (match_scratch 5 ""))]
19228 [(parallel [(set (match_dup 0) (unspec:DI [(match_dup 1)] UNSPEC_FIST_CEIL))
19229 (use (match_dup 2))
19230 (use (match_dup 3))
19231 (clobber (match_dup 5))])]
19234 (define_insn "fist<mode>2_ceil"
19235 [(set (match_operand:X87MODEI12 0 "memory_operand" "=m")
19236 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f")]
19238 (use (match_operand:HI 2 "memory_operand" "m"))
19239 (use (match_operand:HI 3 "memory_operand" "m"))]
19240 "TARGET_USE_FANCY_MATH_387
19241 && flag_unsafe_math_optimizations"
19242 "* return output_fix_trunc (insn, operands, 0);"
19243 [(set_attr "type" "fistp")
19244 (set_attr "i387_cw" "ceil")
19245 (set_attr "mode" "<MODE>")])
19247 (define_insn "fist<mode>2_ceil_with_temp"
19248 [(set (match_operand:X87MODEI12 0 "nonimmediate_operand" "=m,?r")
19249 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "f,f")]
19251 (use (match_operand:HI 2 "memory_operand" "m,m"))
19252 (use (match_operand:HI 3 "memory_operand" "m,m"))
19253 (clobber (match_operand:X87MODEI12 4 "memory_operand" "=X,m"))]
19254 "TARGET_USE_FANCY_MATH_387
19255 && flag_unsafe_math_optimizations"
19257 [(set_attr "type" "fistp")
19258 (set_attr "i387_cw" "ceil")
19259 (set_attr "mode" "<MODE>")])
19262 [(set (match_operand:X87MODEI12 0 "register_operand" "")
19263 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19265 (use (match_operand:HI 2 "memory_operand" ""))
19266 (use (match_operand:HI 3 "memory_operand" ""))
19267 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19269 [(parallel [(set (match_dup 4) (unspec:X87MODEI12 [(match_dup 1)]
19271 (use (match_dup 2))
19272 (use (match_dup 3))])
19273 (set (match_dup 0) (match_dup 4))]
19277 [(set (match_operand:X87MODEI12 0 "memory_operand" "")
19278 (unspec:X87MODEI12 [(match_operand:XF 1 "register_operand" "")]
19280 (use (match_operand:HI 2 "memory_operand" ""))
19281 (use (match_operand:HI 3 "memory_operand" ""))
19282 (clobber (match_operand:X87MODEI12 4 "memory_operand" ""))]
19284 [(parallel [(set (match_dup 0) (unspec:X87MODEI12 [(match_dup 1)]
19286 (use (match_dup 2))
19287 (use (match_dup 3))])]
19290 (define_expand "lceilxf<mode>2"
19291 [(parallel [(set (match_operand:X87MODEI 0 "nonimmediate_operand" "")
19292 (unspec:X87MODEI [(match_operand:XF 1 "register_operand" "")]
19294 (clobber (reg:CC FLAGS_REG))])]
19295 "TARGET_USE_FANCY_MATH_387
19296 && (!TARGET_SSE_MATH || TARGET_MIX_SSE_I387)
19297 && flag_unsafe_math_optimizations"
19300 (define_expand "lceil<mode>di2"
19301 [(match_operand:DI 0 "nonimmediate_operand" "")
19302 (match_operand:MODEF 1 "register_operand" "")]
19303 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH && TARGET_64BIT
19304 && !flag_trapping_math"
19306 ix86_expand_lfloorceil (operand0, operand1, false);
19310 (define_expand "lceil<mode>si2"
19311 [(match_operand:SI 0 "nonimmediate_operand" "")
19312 (match_operand:MODEF 1 "register_operand" "")]
19313 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19314 && !flag_trapping_math"
19316 ix86_expand_lfloorceil (operand0, operand1, false);
19320 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19321 (define_insn_and_split "frndintxf2_trunc"
19322 [(set (match_operand:XF 0 "register_operand" "")
19323 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19324 UNSPEC_FRNDINT_TRUNC))
19325 (clobber (reg:CC FLAGS_REG))]
19326 "TARGET_USE_FANCY_MATH_387
19327 && flag_unsafe_math_optimizations
19328 && !(reload_completed || reload_in_progress)"
19333 ix86_optimize_mode_switching[I387_TRUNC] = 1;
19335 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19336 operands[3] = assign_386_stack_local (HImode, SLOT_CW_TRUNC);
19338 emit_insn (gen_frndintxf2_trunc_i387 (operands[0], operands[1],
19339 operands[2], operands[3]));
19342 [(set_attr "type" "frndint")
19343 (set_attr "i387_cw" "trunc")
19344 (set_attr "mode" "XF")])
19346 (define_insn "frndintxf2_trunc_i387"
19347 [(set (match_operand:XF 0 "register_operand" "=f")
19348 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19349 UNSPEC_FRNDINT_TRUNC))
19350 (use (match_operand:HI 2 "memory_operand" "m"))
19351 (use (match_operand:HI 3 "memory_operand" "m"))]
19352 "TARGET_USE_FANCY_MATH_387
19353 && flag_unsafe_math_optimizations"
19354 "fldcw\t%3\n\tfrndint\n\tfldcw\t%2"
19355 [(set_attr "type" "frndint")
19356 (set_attr "i387_cw" "trunc")
19357 (set_attr "mode" "XF")])
19359 (define_expand "btruncxf2"
19360 [(use (match_operand:XF 0 "register_operand" ""))
19361 (use (match_operand:XF 1 "register_operand" ""))]
19362 "TARGET_USE_FANCY_MATH_387
19363 && flag_unsafe_math_optimizations"
19365 if (optimize_insn_for_size_p ())
19367 emit_insn (gen_frndintxf2_trunc (operands[0], operands[1]));
19371 (define_expand "btrunc<mode>2"
19372 [(use (match_operand:MODEF 0 "register_operand" ""))
19373 (use (match_operand:MODEF 1 "register_operand" ""))]
19374 "(TARGET_USE_FANCY_MATH_387
19375 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19376 || TARGET_MIX_SSE_I387)
19377 && flag_unsafe_math_optimizations)
19378 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19379 && !flag_trapping_math)"
19381 if (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH
19382 && !flag_trapping_math
19383 && (TARGET_ROUND || optimize_insn_for_speed_p ()))
19386 emit_insn (gen_sse4_1_round<mode>2
19387 (operands[0], operands[1], GEN_INT (0x03)));
19388 else if (optimize_insn_for_size_p ())
19390 else if (TARGET_64BIT || (<MODE>mode != DFmode))
19391 ix86_expand_trunc (operand0, operand1);
19393 ix86_expand_truncdf_32 (operand0, operand1);
19399 if (optimize_insn_for_size_p ())
19402 op0 = gen_reg_rtx (XFmode);
19403 op1 = gen_reg_rtx (XFmode);
19404 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19405 emit_insn (gen_frndintxf2_trunc (op0, op1));
19407 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19412 ;; Rounding mode control word calculation could clobber FLAGS_REG.
19413 (define_insn_and_split "frndintxf2_mask_pm"
19414 [(set (match_operand:XF 0 "register_operand" "")
19415 (unspec:XF [(match_operand:XF 1 "register_operand" "")]
19416 UNSPEC_FRNDINT_MASK_PM))
19417 (clobber (reg:CC FLAGS_REG))]
19418 "TARGET_USE_FANCY_MATH_387
19419 && flag_unsafe_math_optimizations
19420 && !(reload_completed || reload_in_progress)"
19425 ix86_optimize_mode_switching[I387_MASK_PM] = 1;
19427 operands[2] = assign_386_stack_local (HImode, SLOT_CW_STORED);
19428 operands[3] = assign_386_stack_local (HImode, SLOT_CW_MASK_PM);
19430 emit_insn (gen_frndintxf2_mask_pm_i387 (operands[0], operands[1],
19431 operands[2], operands[3]));
19434 [(set_attr "type" "frndint")
19435 (set_attr "i387_cw" "mask_pm")
19436 (set_attr "mode" "XF")])
19438 (define_insn "frndintxf2_mask_pm_i387"
19439 [(set (match_operand:XF 0 "register_operand" "=f")
19440 (unspec:XF [(match_operand:XF 1 "register_operand" "0")]
19441 UNSPEC_FRNDINT_MASK_PM))
19442 (use (match_operand:HI 2 "memory_operand" "m"))
19443 (use (match_operand:HI 3 "memory_operand" "m"))]
19444 "TARGET_USE_FANCY_MATH_387
19445 && flag_unsafe_math_optimizations"
19446 "fldcw\t%3\n\tfrndint\n\tfclex\n\tfldcw\t%2"
19447 [(set_attr "type" "frndint")
19448 (set_attr "i387_cw" "mask_pm")
19449 (set_attr "mode" "XF")])
19451 (define_expand "nearbyintxf2"
19452 [(use (match_operand:XF 0 "register_operand" ""))
19453 (use (match_operand:XF 1 "register_operand" ""))]
19454 "TARGET_USE_FANCY_MATH_387
19455 && flag_unsafe_math_optimizations"
19457 emit_insn (gen_frndintxf2_mask_pm (operands[0], operands[1]));
19462 (define_expand "nearbyint<mode>2"
19463 [(use (match_operand:MODEF 0 "register_operand" ""))
19464 (use (match_operand:MODEF 1 "register_operand" ""))]
19465 "TARGET_USE_FANCY_MATH_387
19466 && (!(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)
19467 || TARGET_MIX_SSE_I387)
19468 && flag_unsafe_math_optimizations"
19470 rtx op0 = gen_reg_rtx (XFmode);
19471 rtx op1 = gen_reg_rtx (XFmode);
19473 emit_insn (gen_extend<mode>xf2 (op1, operands[1]));
19474 emit_insn (gen_frndintxf2_mask_pm (op0, op1));
19476 emit_insn (gen_truncxf<mode>2_i387_noop (operands[0], op0));
19480 (define_insn "fxam<mode>2_i387"
19481 [(set (match_operand:HI 0 "register_operand" "=a")
19483 [(match_operand:X87MODEF 1 "register_operand" "f")]
19485 "TARGET_USE_FANCY_MATH_387"
19486 "fxam\n\tfnstsw\t%0"
19487 [(set_attr "type" "multi")
19488 (set_attr "length" "4")
19489 (set_attr "unit" "i387")
19490 (set_attr "mode" "<MODE>")])
19492 (define_insn_and_split "fxam<mode>2_i387_with_temp"
19493 [(set (match_operand:HI 0 "register_operand" "")
19495 [(match_operand:MODEF 1 "memory_operand" "")]
19497 "TARGET_USE_FANCY_MATH_387
19498 && !(reload_completed || reload_in_progress)"
19501 [(set (match_dup 2)(match_dup 1))
19503 (unspec:HI [(match_dup 2)] UNSPEC_FXAM))]
19505 operands[2] = gen_reg_rtx (<MODE>mode);
19507 MEM_VOLATILE_P (operands[1]) = 1;
19509 [(set_attr "type" "multi")
19510 (set_attr "unit" "i387")
19511 (set_attr "mode" "<MODE>")])
19513 (define_expand "isinfxf2"
19514 [(use (match_operand:SI 0 "register_operand" ""))
19515 (use (match_operand:XF 1 "register_operand" ""))]
19516 "TARGET_USE_FANCY_MATH_387
19517 && TARGET_C99_FUNCTIONS"
19519 rtx mask = GEN_INT (0x45);
19520 rtx val = GEN_INT (0x05);
19524 rtx scratch = gen_reg_rtx (HImode);
19525 rtx res = gen_reg_rtx (QImode);
19527 emit_insn (gen_fxamxf2_i387 (scratch, operands[1]));
19529 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19530 emit_insn (gen_cmpqi_ext_3 (scratch, val));
19531 cond = gen_rtx_fmt_ee (EQ, QImode,
19532 gen_rtx_REG (CCmode, FLAGS_REG),
19534 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19535 emit_insn (gen_zero_extendqisi2 (operands[0], res));
19539 (define_expand "isinf<mode>2"
19540 [(use (match_operand:SI 0 "register_operand" ""))
19541 (use (match_operand:MODEF 1 "nonimmediate_operand" ""))]
19542 "TARGET_USE_FANCY_MATH_387
19543 && TARGET_C99_FUNCTIONS
19544 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19546 rtx mask = GEN_INT (0x45);
19547 rtx val = GEN_INT (0x05);
19551 rtx scratch = gen_reg_rtx (HImode);
19552 rtx res = gen_reg_rtx (QImode);
19554 /* Remove excess precision by forcing value through memory. */
19555 if (memory_operand (operands[1], VOIDmode))
19556 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, operands[1]));
19559 enum ix86_stack_slot slot = (virtuals_instantiated
19562 rtx temp = assign_386_stack_local (<MODE>mode, slot);
19564 emit_move_insn (temp, operands[1]);
19565 emit_insn (gen_fxam<mode>2_i387_with_temp (scratch, temp));
19568 emit_insn (gen_andqi_ext_0 (scratch, scratch, mask));
19569 emit_insn (gen_cmpqi_ext_3 (scratch, val));
19570 cond = gen_rtx_fmt_ee (EQ, QImode,
19571 gen_rtx_REG (CCmode, FLAGS_REG),
19573 emit_insn (gen_rtx_SET (VOIDmode, res, cond));
19574 emit_insn (gen_zero_extendqisi2 (operands[0], res));
19578 (define_expand "signbit<mode>2"
19579 [(use (match_operand:SI 0 "register_operand" ""))
19580 (use (match_operand:X87MODEF 1 "register_operand" ""))]
19581 "TARGET_USE_FANCY_MATH_387
19582 && !(SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
19584 rtx mask = GEN_INT (0x0200);
19586 rtx scratch = gen_reg_rtx (HImode);
19588 emit_insn (gen_fxam<mode>2_i387 (scratch, operands[1]));
19589 emit_insn (gen_andsi3 (operands[0], gen_lowpart (SImode, scratch), mask));
19593 ;; Block operation instructions
19596 [(unspec_volatile [(const_int 0)] UNSPECV_CLD)]
19599 [(set_attr "length" "1")
19600 (set_attr "length_immediate" "0")
19601 (set_attr "modrm" "0")])
19603 (define_expand "movmemsi"
19604 [(use (match_operand:BLK 0 "memory_operand" ""))
19605 (use (match_operand:BLK 1 "memory_operand" ""))
19606 (use (match_operand:SI 2 "nonmemory_operand" ""))
19607 (use (match_operand:SI 3 "const_int_operand" ""))
19608 (use (match_operand:SI 4 "const_int_operand" ""))
19609 (use (match_operand:SI 5 "const_int_operand" ""))]
19612 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19613 operands[4], operands[5]))
19619 (define_expand "movmemdi"
19620 [(use (match_operand:BLK 0 "memory_operand" ""))
19621 (use (match_operand:BLK 1 "memory_operand" ""))
19622 (use (match_operand:DI 2 "nonmemory_operand" ""))
19623 (use (match_operand:DI 3 "const_int_operand" ""))
19624 (use (match_operand:SI 4 "const_int_operand" ""))
19625 (use (match_operand:SI 5 "const_int_operand" ""))]
19628 if (ix86_expand_movmem (operands[0], operands[1], operands[2], operands[3],
19629 operands[4], operands[5]))
19635 ;; Most CPUs don't like single string operations
19636 ;; Handle this case here to simplify previous expander.
19638 (define_expand "strmov"
19639 [(set (match_dup 4) (match_operand 3 "memory_operand" ""))
19640 (set (match_operand 1 "memory_operand" "") (match_dup 4))
19641 (parallel [(set (match_operand 0 "register_operand" "") (match_dup 5))
19642 (clobber (reg:CC FLAGS_REG))])
19643 (parallel [(set (match_operand 2 "register_operand" "") (match_dup 6))
19644 (clobber (reg:CC FLAGS_REG))])]
19647 rtx adjust = GEN_INT (GET_MODE_SIZE (GET_MODE (operands[1])));
19649 /* If .md ever supports :P for Pmode, these can be directly
19650 in the pattern above. */
19651 operands[5] = gen_rtx_PLUS (Pmode, operands[0], adjust);
19652 operands[6] = gen_rtx_PLUS (Pmode, operands[2], adjust);
19654 /* Can't use this if the user has appropriated esi or edi. */
19655 if ((TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19656 && !(fixed_regs[SI_REG] || fixed_regs[DI_REG]))
19658 emit_insn (gen_strmov_singleop (operands[0], operands[1],
19659 operands[2], operands[3],
19660 operands[5], operands[6]));
19664 operands[4] = gen_reg_rtx (GET_MODE (operands[1]));
19667 (define_expand "strmov_singleop"
19668 [(parallel [(set (match_operand 1 "memory_operand" "")
19669 (match_operand 3 "memory_operand" ""))
19670 (set (match_operand 0 "register_operand" "")
19671 (match_operand 4 "" ""))
19672 (set (match_operand 2 "register_operand" "")
19673 (match_operand 5 "" ""))])]
19675 "ix86_current_function_needs_cld = 1;")
19677 (define_insn "*strmovdi_rex_1"
19678 [(set (mem:DI (match_operand:DI 2 "register_operand" "0"))
19679 (mem:DI (match_operand:DI 3 "register_operand" "1")))
19680 (set (match_operand:DI 0 "register_operand" "=D")
19681 (plus:DI (match_dup 2)
19683 (set (match_operand:DI 1 "register_operand" "=S")
19684 (plus:DI (match_dup 3)
19688 [(set_attr "type" "str")
19689 (set_attr "mode" "DI")
19690 (set_attr "memory" "both")])
19692 (define_insn "*strmovsi_1"
19693 [(set (mem:SI (match_operand:SI 2 "register_operand" "0"))
19694 (mem:SI (match_operand:SI 3 "register_operand" "1")))
19695 (set (match_operand:SI 0 "register_operand" "=D")
19696 (plus:SI (match_dup 2)
19698 (set (match_operand:SI 1 "register_operand" "=S")
19699 (plus:SI (match_dup 3)
19703 [(set_attr "type" "str")
19704 (set_attr "mode" "SI")
19705 (set_attr "memory" "both")])
19707 (define_insn "*strmovsi_rex_1"
19708 [(set (mem:SI (match_operand:DI 2 "register_operand" "0"))
19709 (mem:SI (match_operand:DI 3 "register_operand" "1")))
19710 (set (match_operand:DI 0 "register_operand" "=D")
19711 (plus:DI (match_dup 2)
19713 (set (match_operand:DI 1 "register_operand" "=S")
19714 (plus:DI (match_dup 3)
19718 [(set_attr "type" "str")
19719 (set_attr "mode" "SI")
19720 (set_attr "memory" "both")])
19722 (define_insn "*strmovhi_1"
19723 [(set (mem:HI (match_operand:SI 2 "register_operand" "0"))
19724 (mem:HI (match_operand:SI 3 "register_operand" "1")))
19725 (set (match_operand:SI 0 "register_operand" "=D")
19726 (plus:SI (match_dup 2)
19728 (set (match_operand:SI 1 "register_operand" "=S")
19729 (plus:SI (match_dup 3)
19733 [(set_attr "type" "str")
19734 (set_attr "memory" "both")
19735 (set_attr "mode" "HI")])
19737 (define_insn "*strmovhi_rex_1"
19738 [(set (mem:HI (match_operand:DI 2 "register_operand" "0"))
19739 (mem:HI (match_operand:DI 3 "register_operand" "1")))
19740 (set (match_operand:DI 0 "register_operand" "=D")
19741 (plus:DI (match_dup 2)
19743 (set (match_operand:DI 1 "register_operand" "=S")
19744 (plus:DI (match_dup 3)
19748 [(set_attr "type" "str")
19749 (set_attr "memory" "both")
19750 (set_attr "mode" "HI")])
19752 (define_insn "*strmovqi_1"
19753 [(set (mem:QI (match_operand:SI 2 "register_operand" "0"))
19754 (mem:QI (match_operand:SI 3 "register_operand" "1")))
19755 (set (match_operand:SI 0 "register_operand" "=D")
19756 (plus:SI (match_dup 2)
19758 (set (match_operand:SI 1 "register_operand" "=S")
19759 (plus:SI (match_dup 3)
19763 [(set_attr "type" "str")
19764 (set_attr "memory" "both")
19765 (set_attr "mode" "QI")])
19767 (define_insn "*strmovqi_rex_1"
19768 [(set (mem:QI (match_operand:DI 2 "register_operand" "0"))
19769 (mem:QI (match_operand:DI 3 "register_operand" "1")))
19770 (set (match_operand:DI 0 "register_operand" "=D")
19771 (plus:DI (match_dup 2)
19773 (set (match_operand:DI 1 "register_operand" "=S")
19774 (plus:DI (match_dup 3)
19778 [(set_attr "type" "str")
19779 (set_attr "memory" "both")
19780 (set_attr "prefix_rex" "0")
19781 (set_attr "mode" "QI")])
19783 (define_expand "rep_mov"
19784 [(parallel [(set (match_operand 4 "register_operand" "") (const_int 0))
19785 (set (match_operand 0 "register_operand" "")
19786 (match_operand 5 "" ""))
19787 (set (match_operand 2 "register_operand" "")
19788 (match_operand 6 "" ""))
19789 (set (match_operand 1 "memory_operand" "")
19790 (match_operand 3 "memory_operand" ""))
19791 (use (match_dup 4))])]
19793 "ix86_current_function_needs_cld = 1;")
19795 (define_insn "*rep_movdi_rex64"
19796 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19797 (set (match_operand:DI 0 "register_operand" "=D")
19798 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19800 (match_operand:DI 3 "register_operand" "0")))
19801 (set (match_operand:DI 1 "register_operand" "=S")
19802 (plus:DI (ashift:DI (match_dup 5) (const_int 3))
19803 (match_operand:DI 4 "register_operand" "1")))
19804 (set (mem:BLK (match_dup 3))
19805 (mem:BLK (match_dup 4)))
19806 (use (match_dup 5))]
19809 [(set_attr "type" "str")
19810 (set_attr "prefix_rep" "1")
19811 (set_attr "memory" "both")
19812 (set_attr "mode" "DI")])
19814 (define_insn "*rep_movsi"
19815 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19816 (set (match_operand:SI 0 "register_operand" "=D")
19817 (plus:SI (ashift:SI (match_operand:SI 5 "register_operand" "2")
19819 (match_operand:SI 3 "register_operand" "0")))
19820 (set (match_operand:SI 1 "register_operand" "=S")
19821 (plus:SI (ashift:SI (match_dup 5) (const_int 2))
19822 (match_operand:SI 4 "register_operand" "1")))
19823 (set (mem:BLK (match_dup 3))
19824 (mem:BLK (match_dup 4)))
19825 (use (match_dup 5))]
19828 [(set_attr "type" "str")
19829 (set_attr "prefix_rep" "1")
19830 (set_attr "memory" "both")
19831 (set_attr "mode" "SI")])
19833 (define_insn "*rep_movsi_rex64"
19834 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19835 (set (match_operand:DI 0 "register_operand" "=D")
19836 (plus:DI (ashift:DI (match_operand:DI 5 "register_operand" "2")
19838 (match_operand:DI 3 "register_operand" "0")))
19839 (set (match_operand:DI 1 "register_operand" "=S")
19840 (plus:DI (ashift:DI (match_dup 5) (const_int 2))
19841 (match_operand:DI 4 "register_operand" "1")))
19842 (set (mem:BLK (match_dup 3))
19843 (mem:BLK (match_dup 4)))
19844 (use (match_dup 5))]
19847 [(set_attr "type" "str")
19848 (set_attr "prefix_rep" "1")
19849 (set_attr "memory" "both")
19850 (set_attr "mode" "SI")])
19852 (define_insn "*rep_movqi"
19853 [(set (match_operand:SI 2 "register_operand" "=c") (const_int 0))
19854 (set (match_operand:SI 0 "register_operand" "=D")
19855 (plus:SI (match_operand:SI 3 "register_operand" "0")
19856 (match_operand:SI 5 "register_operand" "2")))
19857 (set (match_operand:SI 1 "register_operand" "=S")
19858 (plus:SI (match_operand:SI 4 "register_operand" "1") (match_dup 5)))
19859 (set (mem:BLK (match_dup 3))
19860 (mem:BLK (match_dup 4)))
19861 (use (match_dup 5))]
19864 [(set_attr "type" "str")
19865 (set_attr "prefix_rep" "1")
19866 (set_attr "memory" "both")
19867 (set_attr "mode" "SI")])
19869 (define_insn "*rep_movqi_rex64"
19870 [(set (match_operand:DI 2 "register_operand" "=c") (const_int 0))
19871 (set (match_operand:DI 0 "register_operand" "=D")
19872 (plus:DI (match_operand:DI 3 "register_operand" "0")
19873 (match_operand:DI 5 "register_operand" "2")))
19874 (set (match_operand:DI 1 "register_operand" "=S")
19875 (plus:DI (match_operand:DI 4 "register_operand" "1") (match_dup 5)))
19876 (set (mem:BLK (match_dup 3))
19877 (mem:BLK (match_dup 4)))
19878 (use (match_dup 5))]
19881 [(set_attr "type" "str")
19882 (set_attr "prefix_rep" "1")
19883 (set_attr "memory" "both")
19884 (set_attr "mode" "SI")])
19886 (define_expand "setmemsi"
19887 [(use (match_operand:BLK 0 "memory_operand" ""))
19888 (use (match_operand:SI 1 "nonmemory_operand" ""))
19889 (use (match_operand 2 "const_int_operand" ""))
19890 (use (match_operand 3 "const_int_operand" ""))
19891 (use (match_operand:SI 4 "const_int_operand" ""))
19892 (use (match_operand:SI 5 "const_int_operand" ""))]
19895 if (ix86_expand_setmem (operands[0], operands[1],
19896 operands[2], operands[3],
19897 operands[4], operands[5]))
19903 (define_expand "setmemdi"
19904 [(use (match_operand:BLK 0 "memory_operand" ""))
19905 (use (match_operand:DI 1 "nonmemory_operand" ""))
19906 (use (match_operand 2 "const_int_operand" ""))
19907 (use (match_operand 3 "const_int_operand" ""))
19908 (use (match_operand 4 "const_int_operand" ""))
19909 (use (match_operand 5 "const_int_operand" ""))]
19912 if (ix86_expand_setmem (operands[0], operands[1],
19913 operands[2], operands[3],
19914 operands[4], operands[5]))
19920 ;; Most CPUs don't like single string operations
19921 ;; Handle this case here to simplify previous expander.
19923 (define_expand "strset"
19924 [(set (match_operand 1 "memory_operand" "")
19925 (match_operand 2 "register_operand" ""))
19926 (parallel [(set (match_operand 0 "register_operand" "")
19928 (clobber (reg:CC FLAGS_REG))])]
19931 if (GET_MODE (operands[1]) != GET_MODE (operands[2]))
19932 operands[1] = adjust_address_nv (operands[1], GET_MODE (operands[2]), 0);
19934 /* If .md ever supports :P for Pmode, this can be directly
19935 in the pattern above. */
19936 operands[3] = gen_rtx_PLUS (Pmode, operands[0],
19937 GEN_INT (GET_MODE_SIZE (GET_MODE
19939 if (TARGET_SINGLE_STRINGOP || optimize_insn_for_size_p ())
19941 emit_insn (gen_strset_singleop (operands[0], operands[1], operands[2],
19947 (define_expand "strset_singleop"
19948 [(parallel [(set (match_operand 1 "memory_operand" "")
19949 (match_operand 2 "register_operand" ""))
19950 (set (match_operand 0 "register_operand" "")
19951 (match_operand 3 "" ""))])]
19953 "ix86_current_function_needs_cld = 1;")
19955 (define_insn "*strsetdi_rex_1"
19956 [(set (mem:DI (match_operand:DI 1 "register_operand" "0"))
19957 (match_operand:DI 2 "register_operand" "a"))
19958 (set (match_operand:DI 0 "register_operand" "=D")
19959 (plus:DI (match_dup 1)
19963 [(set_attr "type" "str")
19964 (set_attr "memory" "store")
19965 (set_attr "mode" "DI")])
19967 (define_insn "*strsetsi_1"
19968 [(set (mem:SI (match_operand:SI 1 "register_operand" "0"))
19969 (match_operand:SI 2 "register_operand" "a"))
19970 (set (match_operand:SI 0 "register_operand" "=D")
19971 (plus:SI (match_dup 1)
19975 [(set_attr "type" "str")
19976 (set_attr "memory" "store")
19977 (set_attr "mode" "SI")])
19979 (define_insn "*strsetsi_rex_1"
19980 [(set (mem:SI (match_operand:DI 1 "register_operand" "0"))
19981 (match_operand:SI 2 "register_operand" "a"))
19982 (set (match_operand:DI 0 "register_operand" "=D")
19983 (plus:DI (match_dup 1)
19987 [(set_attr "type" "str")
19988 (set_attr "memory" "store")
19989 (set_attr "mode" "SI")])
19991 (define_insn "*strsethi_1"
19992 [(set (mem:HI (match_operand:SI 1 "register_operand" "0"))
19993 (match_operand:HI 2 "register_operand" "a"))
19994 (set (match_operand:SI 0 "register_operand" "=D")
19995 (plus:SI (match_dup 1)
19999 [(set_attr "type" "str")
20000 (set_attr "memory" "store")
20001 (set_attr "mode" "HI")])
20003 (define_insn "*strsethi_rex_1"
20004 [(set (mem:HI (match_operand:DI 1 "register_operand" "0"))
20005 (match_operand:HI 2 "register_operand" "a"))
20006 (set (match_operand:DI 0 "register_operand" "=D")
20007 (plus:DI (match_dup 1)
20011 [(set_attr "type" "str")
20012 (set_attr "memory" "store")
20013 (set_attr "mode" "HI")])
20015 (define_insn "*strsetqi_1"
20016 [(set (mem:QI (match_operand:SI 1 "register_operand" "0"))
20017 (match_operand:QI 2 "register_operand" "a"))
20018 (set (match_operand:SI 0 "register_operand" "=D")
20019 (plus:SI (match_dup 1)
20023 [(set_attr "type" "str")
20024 (set_attr "memory" "store")
20025 (set_attr "mode" "QI")])
20027 (define_insn "*strsetqi_rex_1"
20028 [(set (mem:QI (match_operand:DI 1 "register_operand" "0"))
20029 (match_operand:QI 2 "register_operand" "a"))
20030 (set (match_operand:DI 0 "register_operand" "=D")
20031 (plus:DI (match_dup 1)
20035 [(set_attr "type" "str")
20036 (set_attr "memory" "store")
20037 (set_attr "prefix_rex" "0")
20038 (set_attr "mode" "QI")])
20040 (define_expand "rep_stos"
20041 [(parallel [(set (match_operand 1 "register_operand" "") (const_int 0))
20042 (set (match_operand 0 "register_operand" "")
20043 (match_operand 4 "" ""))
20044 (set (match_operand 2 "memory_operand" "") (const_int 0))
20045 (use (match_operand 3 "register_operand" ""))
20046 (use (match_dup 1))])]
20048 "ix86_current_function_needs_cld = 1;")
20050 (define_insn "*rep_stosdi_rex64"
20051 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20052 (set (match_operand:DI 0 "register_operand" "=D")
20053 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20055 (match_operand:DI 3 "register_operand" "0")))
20056 (set (mem:BLK (match_dup 3))
20058 (use (match_operand:DI 2 "register_operand" "a"))
20059 (use (match_dup 4))]
20062 [(set_attr "type" "str")
20063 (set_attr "prefix_rep" "1")
20064 (set_attr "memory" "store")
20065 (set_attr "mode" "DI")])
20067 (define_insn "*rep_stossi"
20068 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20069 (set (match_operand:SI 0 "register_operand" "=D")
20070 (plus:SI (ashift:SI (match_operand:SI 4 "register_operand" "1")
20072 (match_operand:SI 3 "register_operand" "0")))
20073 (set (mem:BLK (match_dup 3))
20075 (use (match_operand:SI 2 "register_operand" "a"))
20076 (use (match_dup 4))]
20079 [(set_attr "type" "str")
20080 (set_attr "prefix_rep" "1")
20081 (set_attr "memory" "store")
20082 (set_attr "mode" "SI")])
20084 (define_insn "*rep_stossi_rex64"
20085 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20086 (set (match_operand:DI 0 "register_operand" "=D")
20087 (plus:DI (ashift:DI (match_operand:DI 4 "register_operand" "1")
20089 (match_operand:DI 3 "register_operand" "0")))
20090 (set (mem:BLK (match_dup 3))
20092 (use (match_operand:SI 2 "register_operand" "a"))
20093 (use (match_dup 4))]
20096 [(set_attr "type" "str")
20097 (set_attr "prefix_rep" "1")
20098 (set_attr "memory" "store")
20099 (set_attr "mode" "SI")])
20101 (define_insn "*rep_stosqi"
20102 [(set (match_operand:SI 1 "register_operand" "=c") (const_int 0))
20103 (set (match_operand:SI 0 "register_operand" "=D")
20104 (plus:SI (match_operand:SI 3 "register_operand" "0")
20105 (match_operand:SI 4 "register_operand" "1")))
20106 (set (mem:BLK (match_dup 3))
20108 (use (match_operand:QI 2 "register_operand" "a"))
20109 (use (match_dup 4))]
20112 [(set_attr "type" "str")
20113 (set_attr "prefix_rep" "1")
20114 (set_attr "memory" "store")
20115 (set_attr "mode" "QI")])
20117 (define_insn "*rep_stosqi_rex64"
20118 [(set (match_operand:DI 1 "register_operand" "=c") (const_int 0))
20119 (set (match_operand:DI 0 "register_operand" "=D")
20120 (plus:DI (match_operand:DI 3 "register_operand" "0")
20121 (match_operand:DI 4 "register_operand" "1")))
20122 (set (mem:BLK (match_dup 3))
20124 (use (match_operand:QI 2 "register_operand" "a"))
20125 (use (match_dup 4))]
20128 [(set_attr "type" "str")
20129 (set_attr "prefix_rep" "1")
20130 (set_attr "memory" "store")
20131 (set_attr "prefix_rex" "0")
20132 (set_attr "mode" "QI")])
20134 (define_expand "cmpstrnsi"
20135 [(set (match_operand:SI 0 "register_operand" "")
20136 (compare:SI (match_operand:BLK 1 "general_operand" "")
20137 (match_operand:BLK 2 "general_operand" "")))
20138 (use (match_operand 3 "general_operand" ""))
20139 (use (match_operand 4 "immediate_operand" ""))]
20142 rtx addr1, addr2, out, outlow, count, countreg, align;
20144 if (optimize_insn_for_size_p () && !TARGET_INLINE_ALL_STRINGOPS)
20147 /* Can't use this if the user has appropriated esi or edi. */
20148 if (fixed_regs[SI_REG] || fixed_regs[DI_REG])
20153 out = gen_reg_rtx (SImode);
20155 addr1 = copy_to_mode_reg (Pmode, XEXP (operands[1], 0));
20156 addr2 = copy_to_mode_reg (Pmode, XEXP (operands[2], 0));
20157 if (addr1 != XEXP (operands[1], 0))
20158 operands[1] = replace_equiv_address_nv (operands[1], addr1);
20159 if (addr2 != XEXP (operands[2], 0))
20160 operands[2] = replace_equiv_address_nv (operands[2], addr2);
20162 count = operands[3];
20163 countreg = ix86_zero_extend_to_Pmode (count);
20165 /* %%% Iff we are testing strict equality, we can use known alignment
20166 to good advantage. This may be possible with combine, particularly
20167 once cc0 is dead. */
20168 align = operands[4];
20170 if (CONST_INT_P (count))
20172 if (INTVAL (count) == 0)
20174 emit_move_insn (operands[0], const0_rtx);
20177 emit_insn (gen_cmpstrnqi_nz_1 (addr1, addr2, countreg, align,
20178 operands[1], operands[2]));
20183 emit_insn (gen_cmpdi_1_rex64 (countreg, countreg));
20185 emit_insn (gen_cmpsi_1 (countreg, countreg));
20186 emit_insn (gen_cmpstrnqi_1 (addr1, addr2, countreg, align,
20187 operands[1], operands[2]));
20190 outlow = gen_lowpart (QImode, out);
20191 emit_insn (gen_cmpintqi (outlow));
20192 emit_move_insn (out, gen_rtx_SIGN_EXTEND (SImode, outlow));
20194 if (operands[0] != out)
20195 emit_move_insn (operands[0], out);
20200 ;; Produce a tri-state integer (-1, 0, 1) from condition codes.
20202 (define_expand "cmpintqi"
20203 [(set (match_dup 1)
20204 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20206 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20207 (parallel [(set (match_operand:QI 0 "register_operand" "")
20208 (minus:QI (match_dup 1)
20210 (clobber (reg:CC FLAGS_REG))])]
20212 "operands[1] = gen_reg_rtx (QImode);
20213 operands[2] = gen_reg_rtx (QImode);")
20215 ;; memcmp recognizers. The `cmpsb' opcode does nothing if the count is
20216 ;; zero. Emit extra code to make sure that a zero-length compare is EQ.
20218 (define_expand "cmpstrnqi_nz_1"
20219 [(parallel [(set (reg:CC FLAGS_REG)
20220 (compare:CC (match_operand 4 "memory_operand" "")
20221 (match_operand 5 "memory_operand" "")))
20222 (use (match_operand 2 "register_operand" ""))
20223 (use (match_operand:SI 3 "immediate_operand" ""))
20224 (clobber (match_operand 0 "register_operand" ""))
20225 (clobber (match_operand 1 "register_operand" ""))
20226 (clobber (match_dup 2))])]
20228 "ix86_current_function_needs_cld = 1;")
20230 (define_insn "*cmpstrnqi_nz_1"
20231 [(set (reg:CC FLAGS_REG)
20232 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20233 (mem:BLK (match_operand:SI 5 "register_operand" "1"))))
20234 (use (match_operand:SI 6 "register_operand" "2"))
20235 (use (match_operand:SI 3 "immediate_operand" "i"))
20236 (clobber (match_operand:SI 0 "register_operand" "=S"))
20237 (clobber (match_operand:SI 1 "register_operand" "=D"))
20238 (clobber (match_operand:SI 2 "register_operand" "=c"))]
20241 [(set_attr "type" "str")
20242 (set_attr "mode" "QI")
20243 (set_attr "prefix_rep" "1")])
20245 (define_insn "*cmpstrnqi_nz_rex_1"
20246 [(set (reg:CC FLAGS_REG)
20247 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20248 (mem:BLK (match_operand:DI 5 "register_operand" "1"))))
20249 (use (match_operand:DI 6 "register_operand" "2"))
20250 (use (match_operand:SI 3 "immediate_operand" "i"))
20251 (clobber (match_operand:DI 0 "register_operand" "=S"))
20252 (clobber (match_operand:DI 1 "register_operand" "=D"))
20253 (clobber (match_operand:DI 2 "register_operand" "=c"))]
20256 [(set_attr "type" "str")
20257 (set_attr "mode" "QI")
20258 (set_attr "prefix_rex" "0")
20259 (set_attr "prefix_rep" "1")])
20261 ;; The same, but the count is not known to not be zero.
20263 (define_expand "cmpstrnqi_1"
20264 [(parallel [(set (reg:CC FLAGS_REG)
20265 (if_then_else:CC (ne (match_operand 2 "register_operand" "")
20267 (compare:CC (match_operand 4 "memory_operand" "")
20268 (match_operand 5 "memory_operand" ""))
20270 (use (match_operand:SI 3 "immediate_operand" ""))
20271 (use (reg:CC FLAGS_REG))
20272 (clobber (match_operand 0 "register_operand" ""))
20273 (clobber (match_operand 1 "register_operand" ""))
20274 (clobber (match_dup 2))])]
20276 "ix86_current_function_needs_cld = 1;")
20278 (define_insn "*cmpstrnqi_1"
20279 [(set (reg:CC FLAGS_REG)
20280 (if_then_else:CC (ne (match_operand:SI 6 "register_operand" "2")
20282 (compare:CC (mem:BLK (match_operand:SI 4 "register_operand" "0"))
20283 (mem:BLK (match_operand:SI 5 "register_operand" "1")))
20285 (use (match_operand:SI 3 "immediate_operand" "i"))
20286 (use (reg:CC FLAGS_REG))
20287 (clobber (match_operand:SI 0 "register_operand" "=S"))
20288 (clobber (match_operand:SI 1 "register_operand" "=D"))
20289 (clobber (match_operand:SI 2 "register_operand" "=c"))]
20292 [(set_attr "type" "str")
20293 (set_attr "mode" "QI")
20294 (set_attr "prefix_rep" "1")])
20296 (define_insn "*cmpstrnqi_rex_1"
20297 [(set (reg:CC FLAGS_REG)
20298 (if_then_else:CC (ne (match_operand:DI 6 "register_operand" "2")
20300 (compare:CC (mem:BLK (match_operand:DI 4 "register_operand" "0"))
20301 (mem:BLK (match_operand:DI 5 "register_operand" "1")))
20303 (use (match_operand:SI 3 "immediate_operand" "i"))
20304 (use (reg:CC FLAGS_REG))
20305 (clobber (match_operand:DI 0 "register_operand" "=S"))
20306 (clobber (match_operand:DI 1 "register_operand" "=D"))
20307 (clobber (match_operand:DI 2 "register_operand" "=c"))]
20310 [(set_attr "type" "str")
20311 (set_attr "mode" "QI")
20312 (set_attr "prefix_rex" "0")
20313 (set_attr "prefix_rep" "1")])
20315 (define_expand "strlensi"
20316 [(set (match_operand:SI 0 "register_operand" "")
20317 (unspec:SI [(match_operand:BLK 1 "general_operand" "")
20318 (match_operand:QI 2 "immediate_operand" "")
20319 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20322 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20328 (define_expand "strlendi"
20329 [(set (match_operand:DI 0 "register_operand" "")
20330 (unspec:DI [(match_operand:BLK 1 "general_operand" "")
20331 (match_operand:QI 2 "immediate_operand" "")
20332 (match_operand 3 "immediate_operand" "")] UNSPEC_SCAS))]
20335 if (ix86_expand_strlen (operands[0], operands[1], operands[2], operands[3]))
20341 (define_expand "strlenqi_1"
20342 [(parallel [(set (match_operand 0 "register_operand" "") (match_operand 2 "" ""))
20343 (clobber (match_operand 1 "register_operand" ""))
20344 (clobber (reg:CC FLAGS_REG))])]
20346 "ix86_current_function_needs_cld = 1;")
20348 (define_insn "*strlenqi_1"
20349 [(set (match_operand:SI 0 "register_operand" "=&c")
20350 (unspec:SI [(mem:BLK (match_operand:SI 5 "register_operand" "1"))
20351 (match_operand:QI 2 "register_operand" "a")
20352 (match_operand:SI 3 "immediate_operand" "i")
20353 (match_operand:SI 4 "register_operand" "0")] UNSPEC_SCAS))
20354 (clobber (match_operand:SI 1 "register_operand" "=D"))
20355 (clobber (reg:CC FLAGS_REG))]
20358 [(set_attr "type" "str")
20359 (set_attr "mode" "QI")
20360 (set_attr "prefix_rep" "1")])
20362 (define_insn "*strlenqi_rex_1"
20363 [(set (match_operand:DI 0 "register_operand" "=&c")
20364 (unspec:DI [(mem:BLK (match_operand:DI 5 "register_operand" "1"))
20365 (match_operand:QI 2 "register_operand" "a")
20366 (match_operand:DI 3 "immediate_operand" "i")
20367 (match_operand:DI 4 "register_operand" "0")] UNSPEC_SCAS))
20368 (clobber (match_operand:DI 1 "register_operand" "=D"))
20369 (clobber (reg:CC FLAGS_REG))]
20372 [(set_attr "type" "str")
20373 (set_attr "mode" "QI")
20374 (set_attr "prefix_rex" "0")
20375 (set_attr "prefix_rep" "1")])
20377 ;; Peephole optimizations to clean up after cmpstrn*. This should be
20378 ;; handled in combine, but it is not currently up to the task.
20379 ;; When used for their truth value, the cmpstrn* expanders generate
20388 ;; The intermediate three instructions are unnecessary.
20390 ;; This one handles cmpstrn*_nz_1...
20393 (set (reg:CC FLAGS_REG)
20394 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20395 (mem:BLK (match_operand 5 "register_operand" ""))))
20396 (use (match_operand 6 "register_operand" ""))
20397 (use (match_operand:SI 3 "immediate_operand" ""))
20398 (clobber (match_operand 0 "register_operand" ""))
20399 (clobber (match_operand 1 "register_operand" ""))
20400 (clobber (match_operand 2 "register_operand" ""))])
20401 (set (match_operand:QI 7 "register_operand" "")
20402 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20403 (set (match_operand:QI 8 "register_operand" "")
20404 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20405 (set (reg FLAGS_REG)
20406 (compare (match_dup 7) (match_dup 8)))
20408 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20410 (set (reg:CC FLAGS_REG)
20411 (compare:CC (mem:BLK (match_dup 4))
20412 (mem:BLK (match_dup 5))))
20413 (use (match_dup 6))
20414 (use (match_dup 3))
20415 (clobber (match_dup 0))
20416 (clobber (match_dup 1))
20417 (clobber (match_dup 2))])]
20420 ;; ...and this one handles cmpstrn*_1.
20423 (set (reg:CC FLAGS_REG)
20424 (if_then_else:CC (ne (match_operand 6 "register_operand" "")
20426 (compare:CC (mem:BLK (match_operand 4 "register_operand" ""))
20427 (mem:BLK (match_operand 5 "register_operand" "")))
20429 (use (match_operand:SI 3 "immediate_operand" ""))
20430 (use (reg:CC FLAGS_REG))
20431 (clobber (match_operand 0 "register_operand" ""))
20432 (clobber (match_operand 1 "register_operand" ""))
20433 (clobber (match_operand 2 "register_operand" ""))])
20434 (set (match_operand:QI 7 "register_operand" "")
20435 (gtu:QI (reg:CC FLAGS_REG) (const_int 0)))
20436 (set (match_operand:QI 8 "register_operand" "")
20437 (ltu:QI (reg:CC FLAGS_REG) (const_int 0)))
20438 (set (reg FLAGS_REG)
20439 (compare (match_dup 7) (match_dup 8)))
20441 "peep2_reg_dead_p (4, operands[7]) && peep2_reg_dead_p (4, operands[8])"
20443 (set (reg:CC FLAGS_REG)
20444 (if_then_else:CC (ne (match_dup 6)
20446 (compare:CC (mem:BLK (match_dup 4))
20447 (mem:BLK (match_dup 5)))
20449 (use (match_dup 3))
20450 (use (reg:CC FLAGS_REG))
20451 (clobber (match_dup 0))
20452 (clobber (match_dup 1))
20453 (clobber (match_dup 2))])]
20458 ;; Conditional move instructions.
20460 (define_expand "movdicc"
20461 [(set (match_operand:DI 0 "register_operand" "")
20462 (if_then_else:DI (match_operand 1 "comparison_operator" "")
20463 (match_operand:DI 2 "general_operand" "")
20464 (match_operand:DI 3 "general_operand" "")))]
20466 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20468 (define_insn "x86_movdicc_0_m1_rex64"
20469 [(set (match_operand:DI 0 "register_operand" "=r")
20470 (if_then_else:DI (match_operand 1 "ix86_carry_flag_operator" "")
20473 (clobber (reg:CC FLAGS_REG))]
20476 ; Since we don't have the proper number of operands for an alu insn,
20477 ; fill in all the blanks.
20478 [(set_attr "type" "alu")
20479 (set_attr "use_carry" "1")
20480 (set_attr "pent_pair" "pu")
20481 (set_attr "memory" "none")
20482 (set_attr "imm_disp" "false")
20483 (set_attr "mode" "DI")
20484 (set_attr "length_immediate" "0")])
20486 (define_insn "*x86_movdicc_0_m1_se"
20487 [(set (match_operand:DI 0 "register_operand" "=r")
20488 (sign_extract:DI (match_operand 1 "ix86_carry_flag_operator" "")
20491 (clobber (reg:CC FLAGS_REG))]
20494 [(set_attr "type" "alu")
20495 (set_attr "use_carry" "1")
20496 (set_attr "pent_pair" "pu")
20497 (set_attr "memory" "none")
20498 (set_attr "imm_disp" "false")
20499 (set_attr "mode" "DI")
20500 (set_attr "length_immediate" "0")])
20502 (define_insn "*movdicc_c_rex64"
20503 [(set (match_operand:DI 0 "register_operand" "=r,r")
20504 (if_then_else:DI (match_operator 1 "ix86_comparison_operator"
20505 [(reg FLAGS_REG) (const_int 0)])
20506 (match_operand:DI 2 "nonimmediate_operand" "rm,0")
20507 (match_operand:DI 3 "nonimmediate_operand" "0,rm")))]
20508 "TARGET_64BIT && TARGET_CMOVE
20509 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20511 cmov%O2%C1\t{%2, %0|%0, %2}
20512 cmov%O2%c1\t{%3, %0|%0, %3}"
20513 [(set_attr "type" "icmov")
20514 (set_attr "mode" "DI")])
20516 (define_expand "movsicc"
20517 [(set (match_operand:SI 0 "register_operand" "")
20518 (if_then_else:SI (match_operand 1 "comparison_operator" "")
20519 (match_operand:SI 2 "general_operand" "")
20520 (match_operand:SI 3 "general_operand" "")))]
20522 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20524 ;; Data flow gets confused by our desire for `sbbl reg,reg', and clearing
20525 ;; the register first winds up with `sbbl $0,reg', which is also weird.
20526 ;; So just document what we're doing explicitly.
20528 (define_insn "x86_movsicc_0_m1"
20529 [(set (match_operand:SI 0 "register_operand" "=r")
20530 (if_then_else:SI (match_operand 1 "ix86_carry_flag_operator" "")
20533 (clobber (reg:CC FLAGS_REG))]
20536 ; Since we don't have the proper number of operands for an alu insn,
20537 ; fill in all the blanks.
20538 [(set_attr "type" "alu")
20539 (set_attr "use_carry" "1")
20540 (set_attr "pent_pair" "pu")
20541 (set_attr "memory" "none")
20542 (set_attr "imm_disp" "false")
20543 (set_attr "mode" "SI")
20544 (set_attr "length_immediate" "0")])
20546 (define_insn "*x86_movsicc_0_m1_se"
20547 [(set (match_operand:SI 0 "register_operand" "=r")
20548 (sign_extract:SI (match_operand 1 "ix86_carry_flag_operator" "")
20551 (clobber (reg:CC FLAGS_REG))]
20554 [(set_attr "type" "alu")
20555 (set_attr "use_carry" "1")
20556 (set_attr "pent_pair" "pu")
20557 (set_attr "memory" "none")
20558 (set_attr "imm_disp" "false")
20559 (set_attr "mode" "SI")
20560 (set_attr "length_immediate" "0")])
20562 (define_insn "*movsicc_noc"
20563 [(set (match_operand:SI 0 "register_operand" "=r,r")
20564 (if_then_else:SI (match_operator 1 "ix86_comparison_operator"
20565 [(reg FLAGS_REG) (const_int 0)])
20566 (match_operand:SI 2 "nonimmediate_operand" "rm,0")
20567 (match_operand:SI 3 "nonimmediate_operand" "0,rm")))]
20569 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20571 cmov%O2%C1\t{%2, %0|%0, %2}
20572 cmov%O2%c1\t{%3, %0|%0, %3}"
20573 [(set_attr "type" "icmov")
20574 (set_attr "mode" "SI")])
20576 (define_expand "movhicc"
20577 [(set (match_operand:HI 0 "register_operand" "")
20578 (if_then_else:HI (match_operand 1 "comparison_operator" "")
20579 (match_operand:HI 2 "general_operand" "")
20580 (match_operand:HI 3 "general_operand" "")))]
20581 "TARGET_HIMODE_MATH"
20582 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20584 (define_insn "*movhicc_noc"
20585 [(set (match_operand:HI 0 "register_operand" "=r,r")
20586 (if_then_else:HI (match_operator 1 "ix86_comparison_operator"
20587 [(reg FLAGS_REG) (const_int 0)])
20588 (match_operand:HI 2 "nonimmediate_operand" "rm,0")
20589 (match_operand:HI 3 "nonimmediate_operand" "0,rm")))]
20591 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20593 cmov%O2%C1\t{%2, %0|%0, %2}
20594 cmov%O2%c1\t{%3, %0|%0, %3}"
20595 [(set_attr "type" "icmov")
20596 (set_attr "mode" "HI")])
20598 (define_expand "movqicc"
20599 [(set (match_operand:QI 0 "register_operand" "")
20600 (if_then_else:QI (match_operand 1 "comparison_operator" "")
20601 (match_operand:QI 2 "general_operand" "")
20602 (match_operand:QI 3 "general_operand" "")))]
20603 "TARGET_QIMODE_MATH"
20604 "if (ix86_expand_int_movcc (operands)) DONE; else FAIL;")
20606 (define_insn_and_split "*movqicc_noc"
20607 [(set (match_operand:QI 0 "register_operand" "=r,r")
20608 (if_then_else:QI (match_operator 1 "ix86_comparison_operator"
20609 [(match_operand 4 "flags_reg_operand" "")
20611 (match_operand:QI 2 "register_operand" "r,0")
20612 (match_operand:QI 3 "register_operand" "0,r")))]
20613 "TARGET_CMOVE && !TARGET_PARTIAL_REG_STALL"
20615 "&& reload_completed"
20616 [(set (match_dup 0)
20617 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20620 "operands[0] = gen_lowpart (SImode, operands[0]);
20621 operands[2] = gen_lowpart (SImode, operands[2]);
20622 operands[3] = gen_lowpart (SImode, operands[3]);"
20623 [(set_attr "type" "icmov")
20624 (set_attr "mode" "SI")])
20626 (define_expand "mov<mode>cc"
20627 [(set (match_operand:X87MODEF 0 "register_operand" "")
20628 (if_then_else:X87MODEF
20629 (match_operand 1 "comparison_operator" "")
20630 (match_operand:X87MODEF 2 "register_operand" "")
20631 (match_operand:X87MODEF 3 "register_operand" "")))]
20632 "(TARGET_80387 && TARGET_CMOVE)
20633 || (SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH)"
20634 "if (ix86_expand_fp_movcc (operands)) DONE; else FAIL;")
20636 (define_insn "*movsfcc_1_387"
20637 [(set (match_operand:SF 0 "register_operand" "=f,f,r,r")
20638 (if_then_else:SF (match_operator 1 "fcmov_comparison_operator"
20639 [(reg FLAGS_REG) (const_int 0)])
20640 (match_operand:SF 2 "nonimmediate_operand" "f,0,rm,0")
20641 (match_operand:SF 3 "nonimmediate_operand" "0,f,0,rm")))]
20642 "TARGET_80387 && TARGET_CMOVE
20643 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20645 fcmov%F1\t{%2, %0|%0, %2}
20646 fcmov%f1\t{%3, %0|%0, %3}
20647 cmov%O2%C1\t{%2, %0|%0, %2}
20648 cmov%O2%c1\t{%3, %0|%0, %3}"
20649 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20650 (set_attr "mode" "SF,SF,SI,SI")])
20652 (define_insn "*movdfcc_1"
20653 [(set (match_operand:DF 0 "register_operand" "=f,f,&r,&r")
20654 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20655 [(reg FLAGS_REG) (const_int 0)])
20656 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20657 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20658 "!TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20659 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20661 fcmov%F1\t{%2, %0|%0, %2}
20662 fcmov%f1\t{%3, %0|%0, %3}
20665 [(set_attr "type" "fcmov,fcmov,multi,multi")
20666 (set_attr "mode" "DF")])
20668 (define_insn "*movdfcc_1_rex64"
20669 [(set (match_operand:DF 0 "register_operand" "=f,f,r,r")
20670 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20671 [(reg FLAGS_REG) (const_int 0)])
20672 (match_operand:DF 2 "nonimmediate_operand" "f,0,rm,0")
20673 (match_operand:DF 3 "nonimmediate_operand" "0,f,0,rm")))]
20674 "TARGET_64BIT && TARGET_80387 && TARGET_CMOVE
20675 && !(MEM_P (operands[2]) && MEM_P (operands[3]))"
20677 fcmov%F1\t{%2, %0|%0, %2}
20678 fcmov%f1\t{%3, %0|%0, %3}
20679 cmov%O2%C1\t{%2, %0|%0, %2}
20680 cmov%O2%c1\t{%3, %0|%0, %3}"
20681 [(set_attr "type" "fcmov,fcmov,icmov,icmov")
20682 (set_attr "mode" "DF")])
20685 [(set (match_operand:DF 0 "register_and_not_any_fp_reg_operand" "")
20686 (if_then_else:DF (match_operator 1 "fcmov_comparison_operator"
20687 [(match_operand 4 "flags_reg_operand" "")
20689 (match_operand:DF 2 "nonimmediate_operand" "")
20690 (match_operand:DF 3 "nonimmediate_operand" "")))]
20691 "!TARGET_64BIT && reload_completed"
20692 [(set (match_dup 2)
20693 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20697 (if_then_else:SI (match_op_dup 1 [(match_dup 4) (const_int 0)])
20700 "split_di (&operands[2], 2, &operands[5], &operands[7]);
20701 split_di (&operands[0], 1, &operands[2], &operands[3]);")
20703 (define_insn "*movxfcc_1"
20704 [(set (match_operand:XF 0 "register_operand" "=f,f")
20705 (if_then_else:XF (match_operator 1 "fcmov_comparison_operator"
20706 [(reg FLAGS_REG) (const_int 0)])
20707 (match_operand:XF 2 "register_operand" "f,0")
20708 (match_operand:XF 3 "register_operand" "0,f")))]
20709 "TARGET_80387 && TARGET_CMOVE"
20711 fcmov%F1\t{%2, %0|%0, %2}
20712 fcmov%f1\t{%3, %0|%0, %3}"
20713 [(set_attr "type" "fcmov")
20714 (set_attr "mode" "XF")])
20716 ;; All moves in SSE5 pcmov instructions are 128 bits and hence we restrict
20717 ;; the scalar versions to have only XMM registers as operands.
20719 ;; SSE5 conditional move
20720 (define_insn "*sse5_pcmov_<mode>"
20721 [(set (match_operand:MODEF 0 "register_operand" "=x,x")
20722 (if_then_else:MODEF
20723 (match_operand:MODEF 1 "register_operand" "x,0")
20724 (match_operand:MODEF 2 "register_operand" "0,x")
20725 (match_operand:MODEF 3 "register_operand" "x,x")))]
20726 "TARGET_SSE5 && ix86_sse5_valid_op_p (operands, insn, 4, true, 1, false)"
20727 "pcmov\t{%1, %3, %2, %0|%0, %2, %3, %1}"
20728 [(set_attr "type" "sse4arg")])
20730 ;; These versions of the min/max patterns are intentionally ignorant of
20731 ;; their behavior wrt -0.0 and NaN (via the commutative operand mark).
20732 ;; Since both the tree-level MAX_EXPR and the rtl-level SMAX operator
20733 ;; are undefined in this condition, we're certain this is correct.
20735 (define_insn "*avx_<code><mode>3"
20736 [(set (match_operand:MODEF 0 "register_operand" "=x")
20738 (match_operand:MODEF 1 "nonimmediate_operand" "%x")
20739 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20740 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20741 "v<maxminfprefix>s<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20742 [(set_attr "type" "sseadd")
20743 (set_attr "prefix" "vex")
20744 (set_attr "mode" "<MODE>")])
20746 (define_insn "<code><mode>3"
20747 [(set (match_operand:MODEF 0 "register_operand" "=x")
20749 (match_operand:MODEF 1 "nonimmediate_operand" "%0")
20750 (match_operand:MODEF 2 "nonimmediate_operand" "xm")))]
20751 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20752 "<maxminfprefix>s<ssemodefsuffix>\t{%2, %0|%0, %2}"
20753 [(set_attr "type" "sseadd")
20754 (set_attr "mode" "<MODE>")])
20756 ;; These versions of the min/max patterns implement exactly the operations
20757 ;; min = (op1 < op2 ? op1 : op2)
20758 ;; max = (!(op1 < op2) ? op1 : op2)
20759 ;; Their operands are not commutative, and thus they may be used in the
20760 ;; presence of -0.0 and NaN.
20762 (define_insn "*avx_ieee_smin<mode>3"
20763 [(set (match_operand:MODEF 0 "register_operand" "=x")
20765 [(match_operand:MODEF 1 "register_operand" "x")
20766 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20768 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20769 "vmins<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20770 [(set_attr "type" "sseadd")
20771 (set_attr "prefix" "vex")
20772 (set_attr "mode" "<MODE>")])
20774 (define_insn "*ieee_smin<mode>3"
20775 [(set (match_operand:MODEF 0 "register_operand" "=x")
20777 [(match_operand:MODEF 1 "register_operand" "0")
20778 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20780 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20781 "mins<ssemodefsuffix>\t{%2, %0|%0, %2}"
20782 [(set_attr "type" "sseadd")
20783 (set_attr "mode" "<MODE>")])
20785 (define_insn "*avx_ieee_smax<mode>3"
20786 [(set (match_operand:MODEF 0 "register_operand" "=x")
20788 [(match_operand:MODEF 1 "register_operand" "0")
20789 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20791 "AVX_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20792 "vmaxs<ssemodefsuffix>\t{%2, %1, %0|%0, %1, %2}"
20793 [(set_attr "type" "sseadd")
20794 (set_attr "prefix" "vex")
20795 (set_attr "mode" "<MODE>")])
20797 (define_insn "*ieee_smax<mode>3"
20798 [(set (match_operand:MODEF 0 "register_operand" "=x")
20800 [(match_operand:MODEF 1 "register_operand" "0")
20801 (match_operand:MODEF 2 "nonimmediate_operand" "xm")]
20803 "SSE_FLOAT_MODE_P (<MODE>mode) && TARGET_SSE_MATH"
20804 "maxs<ssemodefsuffix>\t{%2, %0|%0, %2}"
20805 [(set_attr "type" "sseadd")
20806 (set_attr "mode" "<MODE>")])
20808 ;; Make two stack loads independent:
20810 ;; fld %st(0) -> fld bb
20811 ;; fmul bb fmul %st(1), %st
20813 ;; Actually we only match the last two instructions for simplicity.
20815 [(set (match_operand 0 "fp_register_operand" "")
20816 (match_operand 1 "fp_register_operand" ""))
20818 (match_operator 2 "binary_fp_operator"
20820 (match_operand 3 "memory_operand" "")]))]
20821 "REGNO (operands[0]) != REGNO (operands[1])"
20822 [(set (match_dup 0) (match_dup 3))
20823 (set (match_dup 0) (match_dup 4))]
20825 ;; The % modifier is not operational anymore in peephole2's, so we have to
20826 ;; swap the operands manually in the case of addition and multiplication.
20827 "if (COMMUTATIVE_ARITH_P (operands[2]))
20828 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20829 operands[0], operands[1]);
20831 operands[4] = gen_rtx_fmt_ee (GET_CODE (operands[2]), GET_MODE (operands[2]),
20832 operands[1], operands[0]);")
20834 ;; Conditional addition patterns
20835 (define_expand "add<mode>cc"
20836 [(match_operand:SWI 0 "register_operand" "")
20837 (match_operand 1 "comparison_operator" "")
20838 (match_operand:SWI 2 "register_operand" "")
20839 (match_operand:SWI 3 "const_int_operand" "")]
20841 "if (ix86_expand_int_addcc (operands)) DONE; else FAIL;")
20844 ;; Misc patterns (?)
20846 ;; This pattern exists to put a dependency on all ebp-based memory accesses.
20847 ;; Otherwise there will be nothing to keep
20849 ;; [(set (reg ebp) (reg esp))]
20850 ;; [(set (reg esp) (plus (reg esp) (const_int -160000)))
20851 ;; (clobber (eflags)]
20852 ;; [(set (mem (plus (reg ebp) (const_int -160000))) (const_int 0))]
20854 ;; in proper program order.
20855 (define_insn "pro_epilogue_adjust_stack_1"
20856 [(set (match_operand:SI 0 "register_operand" "=r,r")
20857 (plus:SI (match_operand:SI 1 "register_operand" "0,r")
20858 (match_operand:SI 2 "immediate_operand" "i,i")))
20859 (clobber (reg:CC FLAGS_REG))
20860 (clobber (mem:BLK (scratch)))]
20863 switch (get_attr_type (insn))
20866 return "mov{l}\t{%1, %0|%0, %1}";
20869 if (CONST_INT_P (operands[2])
20870 && (INTVAL (operands[2]) == 128
20871 || (INTVAL (operands[2]) < 0
20872 && INTVAL (operands[2]) != -128)))
20874 operands[2] = GEN_INT (-INTVAL (operands[2]));
20875 return "sub{l}\t{%2, %0|%0, %2}";
20877 return "add{l}\t{%2, %0|%0, %2}";
20880 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20881 return "lea{l}\t{%a2, %0|%0, %a2}";
20884 gcc_unreachable ();
20887 [(set (attr "type")
20888 (cond [(and (eq_attr "alternative" "0")
20889 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20890 (const_string "alu")
20891 (match_operand:SI 2 "const0_operand" "")
20892 (const_string "imov")
20894 (const_string "lea")))
20895 (set (attr "length_immediate")
20896 (cond [(eq_attr "type" "imov")
20898 (and (eq_attr "type" "alu")
20899 (match_operand 2 "const128_operand" ""))
20902 (const_string "*")))
20903 (set_attr "mode" "SI")])
20905 (define_insn "pro_epilogue_adjust_stack_rex64"
20906 [(set (match_operand:DI 0 "register_operand" "=r,r")
20907 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20908 (match_operand:DI 2 "x86_64_immediate_operand" "e,e")))
20909 (clobber (reg:CC FLAGS_REG))
20910 (clobber (mem:BLK (scratch)))]
20913 switch (get_attr_type (insn))
20916 return "mov{q}\t{%1, %0|%0, %1}";
20919 if (CONST_INT_P (operands[2])
20920 /* Avoid overflows. */
20921 && ((INTVAL (operands[2]) & ((((unsigned int) 1) << 31) - 1)))
20922 && (INTVAL (operands[2]) == 128
20923 || (INTVAL (operands[2]) < 0
20924 && INTVAL (operands[2]) != -128)))
20926 operands[2] = GEN_INT (-INTVAL (operands[2]));
20927 return "sub{q}\t{%2, %0|%0, %2}";
20929 return "add{q}\t{%2, %0|%0, %2}";
20932 operands[2] = SET_SRC (XVECEXP (PATTERN (insn), 0, 0));
20933 return "lea{q}\t{%a2, %0|%0, %a2}";
20936 gcc_unreachable ();
20939 [(set (attr "type")
20940 (cond [(and (eq_attr "alternative" "0")
20941 (eq (symbol_ref "TARGET_OPT_AGU") (const_int 0)))
20942 (const_string "alu")
20943 (match_operand:DI 2 "const0_operand" "")
20944 (const_string "imov")
20946 (const_string "lea")))
20947 (set (attr "length_immediate")
20948 (cond [(eq_attr "type" "imov")
20950 (and (eq_attr "type" "alu")
20951 (match_operand 2 "const128_operand" ""))
20954 (const_string "*")))
20955 (set_attr "mode" "DI")])
20957 (define_insn "pro_epilogue_adjust_stack_rex64_2"
20958 [(set (match_operand:DI 0 "register_operand" "=r,r")
20959 (plus:DI (match_operand:DI 1 "register_operand" "0,r")
20960 (match_operand:DI 3 "immediate_operand" "i,i")))
20961 (use (match_operand:DI 2 "register_operand" "r,r"))
20962 (clobber (reg:CC FLAGS_REG))
20963 (clobber (mem:BLK (scratch)))]
20966 switch (get_attr_type (insn))
20969 return "add{q}\t{%2, %0|%0, %2}";
20972 operands[2] = gen_rtx_PLUS (DImode, operands[1], operands[2]);
20973 return "lea{q}\t{%a2, %0|%0, %a2}";
20976 gcc_unreachable ();
20979 [(set_attr "type" "alu,lea")
20980 (set_attr "mode" "DI")])
20982 (define_insn "allocate_stack_worker_32"
20983 [(set (match_operand:SI 0 "register_operand" "=a")
20984 (unspec_volatile:SI [(match_operand:SI 1 "register_operand" "0")]
20985 UNSPECV_STACK_PROBE))
20986 (set (reg:SI SP_REG) (minus:SI (reg:SI SP_REG) (match_dup 1)))
20987 (clobber (reg:CC FLAGS_REG))]
20988 "!TARGET_64BIT && TARGET_STACK_PROBE"
20990 [(set_attr "type" "multi")
20991 (set_attr "length" "5")])
20993 (define_insn "allocate_stack_worker_64"
20994 [(set (match_operand:DI 0 "register_operand" "=a")
20995 (unspec_volatile:DI [(match_operand:DI 1 "register_operand" "0")]
20996 UNSPECV_STACK_PROBE))
20997 (set (reg:DI SP_REG) (minus:DI (reg:DI SP_REG) (match_dup 1)))
20998 (clobber (reg:DI R10_REG))
20999 (clobber (reg:DI R11_REG))
21000 (clobber (reg:CC FLAGS_REG))]
21001 "TARGET_64BIT && TARGET_STACK_PROBE"
21003 [(set_attr "type" "multi")
21004 (set_attr "length" "5")])
21006 (define_expand "allocate_stack"
21007 [(match_operand 0 "register_operand" "")
21008 (match_operand 1 "general_operand" "")]
21009 "TARGET_STACK_PROBE"
21013 #ifndef CHECK_STACK_LIMIT
21014 #define CHECK_STACK_LIMIT 0
21017 if (CHECK_STACK_LIMIT && CONST_INT_P (operands[1])
21018 && INTVAL (operands[1]) < CHECK_STACK_LIMIT)
21020 x = expand_simple_binop (Pmode, MINUS, stack_pointer_rtx, operands[1],
21021 stack_pointer_rtx, 0, OPTAB_DIRECT);
21022 if (x != stack_pointer_rtx)
21023 emit_move_insn (stack_pointer_rtx, x);
21027 x = copy_to_mode_reg (Pmode, operands[1]);
21029 x = gen_allocate_stack_worker_64 (x, x);
21031 x = gen_allocate_stack_worker_32 (x, x);
21035 emit_move_insn (operands[0], virtual_stack_dynamic_rtx);
21039 (define_expand "builtin_setjmp_receiver"
21040 [(label_ref (match_operand 0 "" ""))]
21041 "!TARGET_64BIT && flag_pic"
21047 rtx picreg = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
21048 rtx label_rtx = gen_label_rtx ();
21049 emit_insn (gen_set_got_labelled (pic_offset_table_rtx, label_rtx));
21050 xops[0] = xops[1] = picreg;
21051 xops[2] = machopic_gen_offset (gen_rtx_LABEL_REF (SImode, label_rtx));
21052 ix86_expand_binary_operator (MINUS, SImode, xops);
21056 emit_insn (gen_set_got (pic_offset_table_rtx));
21060 ;; Avoid redundant prefixes by splitting HImode arithmetic to SImode.
21063 [(set (match_operand 0 "register_operand" "")
21064 (match_operator 3 "promotable_binary_operator"
21065 [(match_operand 1 "register_operand" "")
21066 (match_operand 2 "aligned_operand" "")]))
21067 (clobber (reg:CC FLAGS_REG))]
21068 "! TARGET_PARTIAL_REG_STALL && reload_completed
21069 && ((GET_MODE (operands[0]) == HImode
21070 && ((optimize_function_for_speed_p (cfun) && !TARGET_FAST_PREFIX)
21071 /* ??? next two lines just !satisfies_constraint_K (...) */
21072 || !CONST_INT_P (operands[2])
21073 || satisfies_constraint_K (operands[2])))
21074 || (GET_MODE (operands[0]) == QImode
21075 && (TARGET_PROMOTE_QImode || optimize_function_for_size_p (cfun))))"
21076 [(parallel [(set (match_dup 0)
21077 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21078 (clobber (reg:CC FLAGS_REG))])]
21079 "operands[0] = gen_lowpart (SImode, operands[0]);
21080 operands[1] = gen_lowpart (SImode, operands[1]);
21081 if (GET_CODE (operands[3]) != ASHIFT)
21082 operands[2] = gen_lowpart (SImode, operands[2]);
21083 PUT_MODE (operands[3], SImode);")
21085 ; Promote the QImode tests, as i386 has encoding of the AND
21086 ; instruction with 32-bit sign-extended immediate and thus the
21087 ; instruction size is unchanged, except in the %eax case for
21088 ; which it is increased by one byte, hence the ! optimize_size.
21090 [(set (match_operand 0 "flags_reg_operand" "")
21091 (match_operator 2 "compare_operator"
21092 [(and (match_operand 3 "aligned_operand" "")
21093 (match_operand 4 "const_int_operand" ""))
21095 (set (match_operand 1 "register_operand" "")
21096 (and (match_dup 3) (match_dup 4)))]
21097 "! TARGET_PARTIAL_REG_STALL && reload_completed
21098 && optimize_insn_for_speed_p ()
21099 && ((GET_MODE (operands[1]) == HImode && ! TARGET_FAST_PREFIX)
21100 || (GET_MODE (operands[1]) == QImode && TARGET_PROMOTE_QImode))
21101 /* Ensure that the operand will remain sign-extended immediate. */
21102 && ix86_match_ccmode (insn, INTVAL (operands[4]) >= 0 ? CCNOmode : CCZmode)"
21103 [(parallel [(set (match_dup 0)
21104 (match_op_dup 2 [(and:SI (match_dup 3) (match_dup 4))
21107 (and:SI (match_dup 3) (match_dup 4)))])]
21110 = gen_int_mode (INTVAL (operands[4])
21111 & GET_MODE_MASK (GET_MODE (operands[1])), SImode);
21112 operands[1] = gen_lowpart (SImode, operands[1]);
21113 operands[3] = gen_lowpart (SImode, operands[3]);
21116 ; Don't promote the QImode tests, as i386 doesn't have encoding of
21117 ; the TEST instruction with 32-bit sign-extended immediate and thus
21118 ; the instruction size would at least double, which is not what we
21119 ; want even with ! optimize_size.
21121 [(set (match_operand 0 "flags_reg_operand" "")
21122 (match_operator 1 "compare_operator"
21123 [(and (match_operand:HI 2 "aligned_operand" "")
21124 (match_operand:HI 3 "const_int_operand" ""))
21126 "! TARGET_PARTIAL_REG_STALL && reload_completed
21127 && ! TARGET_FAST_PREFIX
21128 && optimize_insn_for_speed_p ()
21129 /* Ensure that the operand will remain sign-extended immediate. */
21130 && ix86_match_ccmode (insn, INTVAL (operands[3]) >= 0 ? CCNOmode : CCZmode)"
21131 [(set (match_dup 0)
21132 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21136 = gen_int_mode (INTVAL (operands[3])
21137 & GET_MODE_MASK (GET_MODE (operands[2])), SImode);
21138 operands[2] = gen_lowpart (SImode, operands[2]);
21142 [(set (match_operand 0 "register_operand" "")
21143 (neg (match_operand 1 "register_operand" "")))
21144 (clobber (reg:CC FLAGS_REG))]
21145 "! TARGET_PARTIAL_REG_STALL && reload_completed
21146 && (GET_MODE (operands[0]) == HImode
21147 || (GET_MODE (operands[0]) == QImode
21148 && (TARGET_PROMOTE_QImode
21149 || optimize_insn_for_size_p ())))"
21150 [(parallel [(set (match_dup 0)
21151 (neg:SI (match_dup 1)))
21152 (clobber (reg:CC FLAGS_REG))])]
21153 "operands[0] = gen_lowpart (SImode, operands[0]);
21154 operands[1] = gen_lowpart (SImode, operands[1]);")
21157 [(set (match_operand 0 "register_operand" "")
21158 (not (match_operand 1 "register_operand" "")))]
21159 "! TARGET_PARTIAL_REG_STALL && reload_completed
21160 && (GET_MODE (operands[0]) == HImode
21161 || (GET_MODE (operands[0]) == QImode
21162 && (TARGET_PROMOTE_QImode
21163 || optimize_insn_for_size_p ())))"
21164 [(set (match_dup 0)
21165 (not:SI (match_dup 1)))]
21166 "operands[0] = gen_lowpart (SImode, operands[0]);
21167 operands[1] = gen_lowpart (SImode, operands[1]);")
21170 [(set (match_operand 0 "register_operand" "")
21171 (if_then_else (match_operator 1 "comparison_operator"
21172 [(reg FLAGS_REG) (const_int 0)])
21173 (match_operand 2 "register_operand" "")
21174 (match_operand 3 "register_operand" "")))]
21175 "! TARGET_PARTIAL_REG_STALL && TARGET_CMOVE
21176 && (GET_MODE (operands[0]) == HImode
21177 || (GET_MODE (operands[0]) == QImode
21178 && (TARGET_PROMOTE_QImode
21179 || optimize_insn_for_size_p ())))"
21180 [(set (match_dup 0)
21181 (if_then_else:SI (match_dup 1) (match_dup 2) (match_dup 3)))]
21182 "operands[0] = gen_lowpart (SImode, operands[0]);
21183 operands[2] = gen_lowpart (SImode, operands[2]);
21184 operands[3] = gen_lowpart (SImode, operands[3]);")
21187 ;; RTL Peephole optimizations, run before sched2. These primarily look to
21188 ;; transform a complex memory operation into two memory to register operations.
21190 ;; Don't push memory operands
21192 [(set (match_operand:SI 0 "push_operand" "")
21193 (match_operand:SI 1 "memory_operand" ""))
21194 (match_scratch:SI 2 "r")]
21195 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21196 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21197 [(set (match_dup 2) (match_dup 1))
21198 (set (match_dup 0) (match_dup 2))]
21202 [(set (match_operand:DI 0 "push_operand" "")
21203 (match_operand:DI 1 "memory_operand" ""))
21204 (match_scratch:DI 2 "r")]
21205 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21206 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21207 [(set (match_dup 2) (match_dup 1))
21208 (set (match_dup 0) (match_dup 2))]
21211 ;; We need to handle SFmode only, because DFmode and XFmode is split to
21214 [(set (match_operand:SF 0 "push_operand" "")
21215 (match_operand:SF 1 "memory_operand" ""))
21216 (match_scratch:SF 2 "r")]
21217 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21218 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21219 [(set (match_dup 2) (match_dup 1))
21220 (set (match_dup 0) (match_dup 2))]
21224 [(set (match_operand:HI 0 "push_operand" "")
21225 (match_operand:HI 1 "memory_operand" ""))
21226 (match_scratch:HI 2 "r")]
21227 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21228 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21229 [(set (match_dup 2) (match_dup 1))
21230 (set (match_dup 0) (match_dup 2))]
21234 [(set (match_operand:QI 0 "push_operand" "")
21235 (match_operand:QI 1 "memory_operand" ""))
21236 (match_scratch:QI 2 "q")]
21237 "optimize_insn_for_speed_p () && !TARGET_PUSH_MEMORY
21238 && !RTX_FRAME_RELATED_P (peep2_next_insn (0))"
21239 [(set (match_dup 2) (match_dup 1))
21240 (set (match_dup 0) (match_dup 2))]
21243 ;; Don't move an immediate directly to memory when the instruction
21246 [(match_scratch:SI 1 "r")
21247 (set (match_operand:SI 0 "memory_operand" "")
21249 "optimize_insn_for_speed_p ()
21250 && ! TARGET_USE_MOV0
21251 && TARGET_SPLIT_LONG_MOVES
21252 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21253 && peep2_regno_dead_p (0, FLAGS_REG)"
21254 [(parallel [(set (match_dup 1) (const_int 0))
21255 (clobber (reg:CC FLAGS_REG))])
21256 (set (match_dup 0) (match_dup 1))]
21260 [(match_scratch:HI 1 "r")
21261 (set (match_operand:HI 0 "memory_operand" "")
21263 "optimize_insn_for_speed_p ()
21264 && ! TARGET_USE_MOV0
21265 && TARGET_SPLIT_LONG_MOVES
21266 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21267 && peep2_regno_dead_p (0, FLAGS_REG)"
21268 [(parallel [(set (match_dup 2) (const_int 0))
21269 (clobber (reg:CC FLAGS_REG))])
21270 (set (match_dup 0) (match_dup 1))]
21271 "operands[2] = gen_lowpart (SImode, operands[1]);")
21274 [(match_scratch:QI 1 "q")
21275 (set (match_operand:QI 0 "memory_operand" "")
21277 "optimize_insn_for_speed_p ()
21278 && ! TARGET_USE_MOV0
21279 && TARGET_SPLIT_LONG_MOVES
21280 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn
21281 && peep2_regno_dead_p (0, FLAGS_REG)"
21282 [(parallel [(set (match_dup 2) (const_int 0))
21283 (clobber (reg:CC FLAGS_REG))])
21284 (set (match_dup 0) (match_dup 1))]
21285 "operands[2] = gen_lowpart (SImode, operands[1]);")
21288 [(match_scratch:SI 2 "r")
21289 (set (match_operand:SI 0 "memory_operand" "")
21290 (match_operand:SI 1 "immediate_operand" ""))]
21291 "optimize_insn_for_speed_p ()
21292 && TARGET_SPLIT_LONG_MOVES
21293 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21294 [(set (match_dup 2) (match_dup 1))
21295 (set (match_dup 0) (match_dup 2))]
21299 [(match_scratch:HI 2 "r")
21300 (set (match_operand:HI 0 "memory_operand" "")
21301 (match_operand:HI 1 "immediate_operand" ""))]
21302 "optimize_insn_for_speed_p ()
21303 && TARGET_SPLIT_LONG_MOVES
21304 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21305 [(set (match_dup 2) (match_dup 1))
21306 (set (match_dup 0) (match_dup 2))]
21310 [(match_scratch:QI 2 "q")
21311 (set (match_operand:QI 0 "memory_operand" "")
21312 (match_operand:QI 1 "immediate_operand" ""))]
21313 "optimize_insn_for_speed_p ()
21314 && TARGET_SPLIT_LONG_MOVES
21315 && get_attr_length (insn) >= ix86_cur_cost ()->large_insn"
21316 [(set (match_dup 2) (match_dup 1))
21317 (set (match_dup 0) (match_dup 2))]
21320 ;; Don't compare memory with zero, load and use a test instead.
21322 [(set (match_operand 0 "flags_reg_operand" "")
21323 (match_operator 1 "compare_operator"
21324 [(match_operand:SI 2 "memory_operand" "")
21326 (match_scratch:SI 3 "r")]
21327 "optimize_insn_for_speed_p () && ix86_match_ccmode (insn, CCNOmode)"
21328 [(set (match_dup 3) (match_dup 2))
21329 (set (match_dup 0) (match_op_dup 1 [(match_dup 3) (const_int 0)]))]
21332 ;; NOT is not pairable on Pentium, while XOR is, but one byte longer.
21333 ;; Don't split NOTs with a displacement operand, because resulting XOR
21334 ;; will not be pairable anyway.
21336 ;; On AMD K6, NOT is vector decoded with memory operand that cannot be
21337 ;; represented using a modRM byte. The XOR replacement is long decoded,
21338 ;; so this split helps here as well.
21340 ;; Note: Can't do this as a regular split because we can't get proper
21341 ;; lifetime information then.
21344 [(set (match_operand:SI 0 "nonimmediate_operand" "")
21345 (not:SI (match_operand:SI 1 "nonimmediate_operand" "")))]
21346 "optimize_insn_for_speed_p ()
21347 && ((TARGET_NOT_UNPAIRABLE
21348 && (!MEM_P (operands[0])
21349 || !memory_displacement_operand (operands[0], SImode)))
21350 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], SImode)))
21351 && peep2_regno_dead_p (0, FLAGS_REG)"
21352 [(parallel [(set (match_dup 0)
21353 (xor:SI (match_dup 1) (const_int -1)))
21354 (clobber (reg:CC FLAGS_REG))])]
21358 [(set (match_operand:HI 0 "nonimmediate_operand" "")
21359 (not:HI (match_operand:HI 1 "nonimmediate_operand" "")))]
21360 "optimize_insn_for_speed_p ()
21361 && ((TARGET_NOT_UNPAIRABLE
21362 && (!MEM_P (operands[0])
21363 || !memory_displacement_operand (operands[0], HImode)))
21364 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], HImode)))
21365 && peep2_regno_dead_p (0, FLAGS_REG)"
21366 [(parallel [(set (match_dup 0)
21367 (xor:HI (match_dup 1) (const_int -1)))
21368 (clobber (reg:CC FLAGS_REG))])]
21372 [(set (match_operand:QI 0 "nonimmediate_operand" "")
21373 (not:QI (match_operand:QI 1 "nonimmediate_operand" "")))]
21374 "optimize_insn_for_speed_p ()
21375 && ((TARGET_NOT_UNPAIRABLE
21376 && (!MEM_P (operands[0])
21377 || !memory_displacement_operand (operands[0], QImode)))
21378 || (TARGET_NOT_VECTORMODE && long_memory_operand (operands[0], QImode)))
21379 && peep2_regno_dead_p (0, FLAGS_REG)"
21380 [(parallel [(set (match_dup 0)
21381 (xor:QI (match_dup 1) (const_int -1)))
21382 (clobber (reg:CC FLAGS_REG))])]
21385 ;; Non pairable "test imm, reg" instructions can be translated to
21386 ;; "and imm, reg" if reg dies. The "and" form is also shorter (one
21387 ;; byte opcode instead of two, have a short form for byte operands),
21388 ;; so do it for other CPUs as well. Given that the value was dead,
21389 ;; this should not create any new dependencies. Pass on the sub-word
21390 ;; versions if we're concerned about partial register stalls.
21393 [(set (match_operand 0 "flags_reg_operand" "")
21394 (match_operator 1 "compare_operator"
21395 [(and:SI (match_operand:SI 2 "register_operand" "")
21396 (match_operand:SI 3 "immediate_operand" ""))
21398 "ix86_match_ccmode (insn, CCNOmode)
21399 && (true_regnum (operands[2]) != AX_REG
21400 || satisfies_constraint_K (operands[3]))
21401 && peep2_reg_dead_p (1, operands[2])"
21403 [(set (match_dup 0)
21404 (match_op_dup 1 [(and:SI (match_dup 2) (match_dup 3))
21407 (and:SI (match_dup 2) (match_dup 3)))])]
21410 ;; We don't need to handle HImode case, because it will be promoted to SImode
21411 ;; on ! TARGET_PARTIAL_REG_STALL
21414 [(set (match_operand 0 "flags_reg_operand" "")
21415 (match_operator 1 "compare_operator"
21416 [(and:QI (match_operand:QI 2 "register_operand" "")
21417 (match_operand:QI 3 "immediate_operand" ""))
21419 "! TARGET_PARTIAL_REG_STALL
21420 && ix86_match_ccmode (insn, CCNOmode)
21421 && true_regnum (operands[2]) != AX_REG
21422 && peep2_reg_dead_p (1, operands[2])"
21424 [(set (match_dup 0)
21425 (match_op_dup 1 [(and:QI (match_dup 2) (match_dup 3))
21428 (and:QI (match_dup 2) (match_dup 3)))])]
21432 [(set (match_operand 0 "flags_reg_operand" "")
21433 (match_operator 1 "compare_operator"
21436 (match_operand 2 "ext_register_operand" "")
21439 (match_operand 3 "const_int_operand" ""))
21441 "! TARGET_PARTIAL_REG_STALL
21442 && ix86_match_ccmode (insn, CCNOmode)
21443 && true_regnum (operands[2]) != AX_REG
21444 && peep2_reg_dead_p (1, operands[2])"
21445 [(parallel [(set (match_dup 0)
21454 (set (zero_extract:SI (match_dup 2)
21465 ;; Don't do logical operations with memory inputs.
21467 [(match_scratch:SI 2 "r")
21468 (parallel [(set (match_operand:SI 0 "register_operand" "")
21469 (match_operator:SI 3 "arith_or_logical_operator"
21471 (match_operand:SI 1 "memory_operand" "")]))
21472 (clobber (reg:CC FLAGS_REG))])]
21473 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21474 [(set (match_dup 2) (match_dup 1))
21475 (parallel [(set (match_dup 0)
21476 (match_op_dup 3 [(match_dup 0) (match_dup 2)]))
21477 (clobber (reg:CC FLAGS_REG))])]
21481 [(match_scratch:SI 2 "r")
21482 (parallel [(set (match_operand:SI 0 "register_operand" "")
21483 (match_operator:SI 3 "arith_or_logical_operator"
21484 [(match_operand:SI 1 "memory_operand" "")
21486 (clobber (reg:CC FLAGS_REG))])]
21487 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY"
21488 [(set (match_dup 2) (match_dup 1))
21489 (parallel [(set (match_dup 0)
21490 (match_op_dup 3 [(match_dup 2) (match_dup 0)]))
21491 (clobber (reg:CC FLAGS_REG))])]
21494 ;; Prefer Load+RegOp to Mov+MemOp. Watch out for cases when the memory address
21495 ;; refers to the destination of the load!
21498 [(set (match_operand:SI 0 "register_operand" "")
21499 (match_operand:SI 1 "register_operand" ""))
21500 (parallel [(set (match_dup 0)
21501 (match_operator:SI 3 "commutative_operator"
21503 (match_operand:SI 2 "memory_operand" "")]))
21504 (clobber (reg:CC FLAGS_REG))])]
21505 "REGNO (operands[0]) != REGNO (operands[1])
21506 && GENERAL_REGNO_P (REGNO (operands[0]))
21507 && GENERAL_REGNO_P (REGNO (operands[1]))"
21508 [(set (match_dup 0) (match_dup 4))
21509 (parallel [(set (match_dup 0)
21510 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))
21511 (clobber (reg:CC FLAGS_REG))])]
21512 "operands[4] = replace_rtx (operands[2], operands[0], operands[1]);")
21515 [(set (match_operand 0 "register_operand" "")
21516 (match_operand 1 "register_operand" ""))
21518 (match_operator 3 "commutative_operator"
21520 (match_operand 2 "memory_operand" "")]))]
21521 "REGNO (operands[0]) != REGNO (operands[1])
21522 && ((MMX_REG_P (operands[0]) && MMX_REG_P (operands[1]))
21523 || (SSE_REG_P (operands[0]) && SSE_REG_P (operands[1])))"
21524 [(set (match_dup 0) (match_dup 2))
21526 (match_op_dup 3 [(match_dup 0) (match_dup 1)]))]
21529 ; Don't do logical operations with memory outputs
21531 ; These two don't make sense for PPro/PII -- we're expanding a 4-uop
21532 ; instruction into two 1-uop insns plus a 2-uop insn. That last has
21533 ; the same decoder scheduling characteristics as the original.
21536 [(match_scratch:SI 2 "r")
21537 (parallel [(set (match_operand:SI 0 "memory_operand" "")
21538 (match_operator:SI 3 "arith_or_logical_operator"
21540 (match_operand:SI 1 "nonmemory_operand" "")]))
21541 (clobber (reg:CC FLAGS_REG))])]
21542 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21543 [(set (match_dup 2) (match_dup 0))
21544 (parallel [(set (match_dup 2)
21545 (match_op_dup 3 [(match_dup 2) (match_dup 1)]))
21546 (clobber (reg:CC FLAGS_REG))])
21547 (set (match_dup 0) (match_dup 2))]
21551 [(match_scratch:SI 2 "r")
21552 (parallel [(set (match_operand:SI 0 "memory_operand" "")
21553 (match_operator:SI 3 "arith_or_logical_operator"
21554 [(match_operand:SI 1 "nonmemory_operand" "")
21556 (clobber (reg:CC FLAGS_REG))])]
21557 "optimize_insn_for_speed_p () && ! TARGET_READ_MODIFY_WRITE"
21558 [(set (match_dup 2) (match_dup 0))
21559 (parallel [(set (match_dup 2)
21560 (match_op_dup 3 [(match_dup 1) (match_dup 2)]))
21561 (clobber (reg:CC FLAGS_REG))])
21562 (set (match_dup 0) (match_dup 2))]
21565 ;; Attempt to always use XOR for zeroing registers.
21567 [(set (match_operand 0 "register_operand" "")
21568 (match_operand 1 "const0_operand" ""))]
21569 "GET_MODE_SIZE (GET_MODE (operands[0])) <= UNITS_PER_WORD
21570 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21571 && GENERAL_REG_P (operands[0])
21572 && peep2_regno_dead_p (0, FLAGS_REG)"
21573 [(parallel [(set (match_dup 0) (const_int 0))
21574 (clobber (reg:CC FLAGS_REG))])]
21576 operands[0] = gen_lowpart (word_mode, operands[0]);
21580 [(set (strict_low_part (match_operand 0 "register_operand" ""))
21582 "(GET_MODE (operands[0]) == QImode
21583 || GET_MODE (operands[0]) == HImode)
21584 && (! TARGET_USE_MOV0 || optimize_insn_for_size_p ())
21585 && peep2_regno_dead_p (0, FLAGS_REG)"
21586 [(parallel [(set (strict_low_part (match_dup 0)) (const_int 0))
21587 (clobber (reg:CC FLAGS_REG))])])
21589 ;; For HI and SI modes, or $-1,reg is smaller than mov $-1,reg.
21591 [(set (match_operand 0 "register_operand" "")
21593 "(GET_MODE (operands[0]) == HImode
21594 || GET_MODE (operands[0]) == SImode
21595 || (GET_MODE (operands[0]) == DImode && TARGET_64BIT))
21596 && (optimize_insn_for_size_p () || TARGET_MOVE_M1_VIA_OR)
21597 && peep2_regno_dead_p (0, FLAGS_REG)"
21598 [(parallel [(set (match_dup 0) (const_int -1))
21599 (clobber (reg:CC FLAGS_REG))])]
21600 "operands[0] = gen_lowpart (GET_MODE (operands[0]) == DImode ? DImode : SImode,
21603 ;; Attempt to convert simple leas to adds. These can be created by
21606 [(set (match_operand:SI 0 "register_operand" "")
21607 (plus:SI (match_dup 0)
21608 (match_operand:SI 1 "nonmemory_operand" "")))]
21609 "peep2_regno_dead_p (0, FLAGS_REG)"
21610 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 1)))
21611 (clobber (reg:CC FLAGS_REG))])]
21615 [(set (match_operand:SI 0 "register_operand" "")
21616 (subreg:SI (plus:DI (match_operand:DI 1 "register_operand" "")
21617 (match_operand:DI 2 "nonmemory_operand" "")) 0))]
21618 "peep2_regno_dead_p (0, FLAGS_REG) && REGNO (operands[0]) == REGNO (operands[1])"
21619 [(parallel [(set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))
21620 (clobber (reg:CC FLAGS_REG))])]
21621 "operands[2] = gen_lowpart (SImode, operands[2]);")
21624 [(set (match_operand:DI 0 "register_operand" "")
21625 (plus:DI (match_dup 0)
21626 (match_operand:DI 1 "x86_64_general_operand" "")))]
21627 "peep2_regno_dead_p (0, FLAGS_REG)"
21628 [(parallel [(set (match_dup 0) (plus:DI (match_dup 0) (match_dup 1)))
21629 (clobber (reg:CC FLAGS_REG))])]
21633 [(set (match_operand:SI 0 "register_operand" "")
21634 (mult:SI (match_dup 0)
21635 (match_operand:SI 1 "const_int_operand" "")))]
21636 "exact_log2 (INTVAL (operands[1])) >= 0
21637 && peep2_regno_dead_p (0, FLAGS_REG)"
21638 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21639 (clobber (reg:CC FLAGS_REG))])]
21640 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21643 [(set (match_operand:DI 0 "register_operand" "")
21644 (mult:DI (match_dup 0)
21645 (match_operand:DI 1 "const_int_operand" "")))]
21646 "exact_log2 (INTVAL (operands[1])) >= 0
21647 && peep2_regno_dead_p (0, FLAGS_REG)"
21648 [(parallel [(set (match_dup 0) (ashift:DI (match_dup 0) (match_dup 2)))
21649 (clobber (reg:CC FLAGS_REG))])]
21650 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[1])));")
21653 [(set (match_operand:SI 0 "register_operand" "")
21654 (subreg:SI (mult:DI (match_operand:DI 1 "register_operand" "")
21655 (match_operand:DI 2 "const_int_operand" "")) 0))]
21656 "exact_log2 (INTVAL (operands[2])) >= 0
21657 && REGNO (operands[0]) == REGNO (operands[1])
21658 && peep2_regno_dead_p (0, FLAGS_REG)"
21659 [(parallel [(set (match_dup 0) (ashift:SI (match_dup 0) (match_dup 2)))
21660 (clobber (reg:CC FLAGS_REG))])]
21661 "operands[2] = GEN_INT (exact_log2 (INTVAL (operands[2])));")
21663 ;; The ESP adjustments can be done by the push and pop instructions. Resulting
21664 ;; code is shorter, since push is only 1 byte, while add imm, %esp 3 bytes. On
21665 ;; many CPUs it is also faster, since special hardware to avoid esp
21666 ;; dependencies is present.
21668 ;; While some of these conversions may be done using splitters, we use peepholes
21669 ;; in order to allow combine_stack_adjustments pass to see nonobfuscated RTL.
21671 ;; Convert prologue esp subtractions to push.
21672 ;; We need register to push. In order to keep verify_flow_info happy we have
21674 ;; - use scratch and clobber it in order to avoid dependencies
21675 ;; - use already live register
21676 ;; We can't use the second way right now, since there is no reliable way how to
21677 ;; verify that given register is live. First choice will also most likely in
21678 ;; fewer dependencies. On the place of esp adjustments it is very likely that
21679 ;; call clobbered registers are dead. We may want to use base pointer as an
21680 ;; alternative when no register is available later.
21683 [(match_scratch:SI 0 "r")
21684 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21685 (clobber (reg:CC FLAGS_REG))
21686 (clobber (mem:BLK (scratch)))])]
21687 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21688 [(clobber (match_dup 0))
21689 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21690 (clobber (mem:BLK (scratch)))])])
21693 [(match_scratch:SI 0 "r")
21694 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21695 (clobber (reg:CC FLAGS_REG))
21696 (clobber (mem:BLK (scratch)))])]
21697 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21698 [(clobber (match_dup 0))
21699 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21700 (parallel [(set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21701 (clobber (mem:BLK (scratch)))])])
21703 ;; Convert esp subtractions to push.
21705 [(match_scratch:SI 0 "r")
21706 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -4)))
21707 (clobber (reg:CC FLAGS_REG))])]
21708 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21709 [(clobber (match_dup 0))
21710 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21713 [(match_scratch:SI 0 "r")
21714 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int -8)))
21715 (clobber (reg:CC FLAGS_REG))])]
21716 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21717 [(clobber (match_dup 0))
21718 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))
21719 (set (mem:SI (pre_dec:SI (reg:SI SP_REG))) (match_dup 0))])
21721 ;; Convert epilogue deallocator to pop.
21723 [(match_scratch:SI 0 "r")
21724 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21725 (clobber (reg:CC FLAGS_REG))
21726 (clobber (mem:BLK (scratch)))])]
21727 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21728 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21729 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21730 (clobber (mem:BLK (scratch)))])]
21733 ;; Two pops case is tricky, since pop causes dependency on destination register.
21734 ;; We use two registers if available.
21736 [(match_scratch:SI 0 "r")
21737 (match_scratch:SI 1 "r")
21738 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21739 (clobber (reg:CC FLAGS_REG))
21740 (clobber (mem:BLK (scratch)))])]
21741 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21742 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21743 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21744 (clobber (mem:BLK (scratch)))])
21745 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21746 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21750 [(match_scratch:SI 0 "r")
21751 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21752 (clobber (reg:CC FLAGS_REG))
21753 (clobber (mem:BLK (scratch)))])]
21754 "optimize_insn_for_size_p ()"
21755 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21756 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21757 (clobber (mem:BLK (scratch)))])
21758 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21759 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21762 ;; Convert esp additions to pop.
21764 [(match_scratch:SI 0 "r")
21765 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))
21766 (clobber (reg:CC FLAGS_REG))])]
21768 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21769 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21772 ;; Two pops case is tricky, since pop causes dependency on destination register.
21773 ;; We use two registers if available.
21775 [(match_scratch:SI 0 "r")
21776 (match_scratch:SI 1 "r")
21777 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21778 (clobber (reg:CC FLAGS_REG))])]
21780 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21781 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21782 (parallel [(set (match_dup 1) (mem:SI (reg:SI SP_REG)))
21783 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21787 [(match_scratch:SI 0 "r")
21788 (parallel [(set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 8)))
21789 (clobber (reg:CC FLAGS_REG))])]
21790 "optimize_insn_for_size_p ()"
21791 [(parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21792 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])
21793 (parallel [(set (match_dup 0) (mem:SI (reg:SI SP_REG)))
21794 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG) (const_int 4)))])]
21797 ;; Convert compares with 1 to shorter inc/dec operations when CF is not
21798 ;; required and register dies. Similarly for 128 to -128.
21800 [(set (match_operand 0 "flags_reg_operand" "")
21801 (match_operator 1 "compare_operator"
21802 [(match_operand 2 "register_operand" "")
21803 (match_operand 3 "const_int_operand" "")]))]
21804 "(((!TARGET_FUSE_CMP_AND_BRANCH || optimize_insn_for_size_p ())
21805 && incdec_operand (operands[3], GET_MODE (operands[3])))
21806 || (!TARGET_FUSE_CMP_AND_BRANCH
21807 && INTVAL (operands[3]) == 128))
21808 && ix86_match_ccmode (insn, CCGCmode)
21809 && peep2_reg_dead_p (1, operands[2])"
21810 [(parallel [(set (match_dup 0)
21811 (match_op_dup 1 [(match_dup 2) (match_dup 3)]))
21812 (clobber (match_dup 2))])]
21816 [(match_scratch:DI 0 "r")
21817 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21818 (clobber (reg:CC FLAGS_REG))
21819 (clobber (mem:BLK (scratch)))])]
21820 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21821 [(clobber (match_dup 0))
21822 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21823 (clobber (mem:BLK (scratch)))])])
21826 [(match_scratch:DI 0 "r")
21827 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21828 (clobber (reg:CC FLAGS_REG))
21829 (clobber (mem:BLK (scratch)))])]
21830 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21831 [(clobber (match_dup 0))
21832 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21833 (parallel [(set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21834 (clobber (mem:BLK (scratch)))])])
21836 ;; Convert esp subtractions to push.
21838 [(match_scratch:DI 0 "r")
21839 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -8)))
21840 (clobber (reg:CC FLAGS_REG))])]
21841 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_4"
21842 [(clobber (match_dup 0))
21843 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21846 [(match_scratch:DI 0 "r")
21847 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int -16)))
21848 (clobber (reg:CC FLAGS_REG))])]
21849 "optimize_insn_for_size_p () || !TARGET_SUB_ESP_8"
21850 [(clobber (match_dup 0))
21851 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))
21852 (set (mem:DI (pre_dec:DI (reg:DI SP_REG))) (match_dup 0))])
21854 ;; Convert epilogue deallocator to pop.
21856 [(match_scratch:DI 0 "r")
21857 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21858 (clobber (reg:CC FLAGS_REG))
21859 (clobber (mem:BLK (scratch)))])]
21860 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_4"
21861 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21862 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21863 (clobber (mem:BLK (scratch)))])]
21866 ;; Two pops case is tricky, since pop causes dependency on destination register.
21867 ;; We use two registers if available.
21869 [(match_scratch:DI 0 "r")
21870 (match_scratch:DI 1 "r")
21871 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21872 (clobber (reg:CC FLAGS_REG))
21873 (clobber (mem:BLK (scratch)))])]
21874 "optimize_insn_for_size_p () || !TARGET_ADD_ESP_8"
21875 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21876 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21877 (clobber (mem:BLK (scratch)))])
21878 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21879 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21883 [(match_scratch:DI 0 "r")
21884 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21885 (clobber (reg:CC FLAGS_REG))
21886 (clobber (mem:BLK (scratch)))])]
21887 "optimize_insn_for_size_p ()"
21888 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21889 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21890 (clobber (mem:BLK (scratch)))])
21891 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21892 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21895 ;; Convert esp additions to pop.
21897 [(match_scratch:DI 0 "r")
21898 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))
21899 (clobber (reg:CC FLAGS_REG))])]
21901 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21902 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21905 ;; Two pops case is tricky, since pop causes dependency on destination register.
21906 ;; We use two registers if available.
21908 [(match_scratch:DI 0 "r")
21909 (match_scratch:DI 1 "r")
21910 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21911 (clobber (reg:CC FLAGS_REG))])]
21913 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21914 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21915 (parallel [(set (match_dup 1) (mem:DI (reg:DI SP_REG)))
21916 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21920 [(match_scratch:DI 0 "r")
21921 (parallel [(set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 16)))
21922 (clobber (reg:CC FLAGS_REG))])]
21923 "optimize_insn_for_size_p ()"
21924 [(parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21925 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])
21926 (parallel [(set (match_dup 0) (mem:DI (reg:DI SP_REG)))
21927 (set (reg:DI SP_REG) (plus:DI (reg:DI SP_REG) (const_int 8)))])]
21930 ;; Convert imul by three, five and nine into lea
21933 [(set (match_operand:SI 0 "register_operand" "")
21934 (mult:SI (match_operand:SI 1 "register_operand" "")
21935 (match_operand:SI 2 "const_int_operand" "")))
21936 (clobber (reg:CC FLAGS_REG))])]
21937 "INTVAL (operands[2]) == 3
21938 || INTVAL (operands[2]) == 5
21939 || INTVAL (operands[2]) == 9"
21940 [(set (match_dup 0)
21941 (plus:SI (mult:SI (match_dup 1) (match_dup 2))
21943 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21947 [(set (match_operand:SI 0 "register_operand" "")
21948 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
21949 (match_operand:SI 2 "const_int_operand" "")))
21950 (clobber (reg:CC FLAGS_REG))])]
21951 "optimize_insn_for_speed_p ()
21952 && (INTVAL (operands[2]) == 3
21953 || INTVAL (operands[2]) == 5
21954 || INTVAL (operands[2]) == 9)"
21955 [(set (match_dup 0) (match_dup 1))
21957 (plus:SI (mult:SI (match_dup 0) (match_dup 2))
21959 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21963 [(set (match_operand:DI 0 "register_operand" "")
21964 (mult:DI (match_operand:DI 1 "register_operand" "")
21965 (match_operand:DI 2 "const_int_operand" "")))
21966 (clobber (reg:CC FLAGS_REG))])]
21968 && (INTVAL (operands[2]) == 3
21969 || INTVAL (operands[2]) == 5
21970 || INTVAL (operands[2]) == 9)"
21971 [(set (match_dup 0)
21972 (plus:DI (mult:DI (match_dup 1) (match_dup 2))
21974 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21978 [(set (match_operand:DI 0 "register_operand" "")
21979 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
21980 (match_operand:DI 2 "const_int_operand" "")))
21981 (clobber (reg:CC FLAGS_REG))])]
21983 && optimize_insn_for_speed_p ()
21984 && (INTVAL (operands[2]) == 3
21985 || INTVAL (operands[2]) == 5
21986 || INTVAL (operands[2]) == 9)"
21987 [(set (match_dup 0) (match_dup 1))
21989 (plus:DI (mult:DI (match_dup 0) (match_dup 2))
21991 { operands[2] = GEN_INT (INTVAL (operands[2]) - 1); })
21993 ;; Imul $32bit_imm, mem, reg is vector decoded, while
21994 ;; imul $32bit_imm, reg, reg is direct decoded.
21996 [(match_scratch:DI 3 "r")
21997 (parallel [(set (match_operand:DI 0 "register_operand" "")
21998 (mult:DI (match_operand:DI 1 "memory_operand" "")
21999 (match_operand:DI 2 "immediate_operand" "")))
22000 (clobber (reg:CC FLAGS_REG))])]
22001 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
22002 && !satisfies_constraint_K (operands[2])"
22003 [(set (match_dup 3) (match_dup 1))
22004 (parallel [(set (match_dup 0) (mult:DI (match_dup 3) (match_dup 2)))
22005 (clobber (reg:CC FLAGS_REG))])]
22009 [(match_scratch:SI 3 "r")
22010 (parallel [(set (match_operand:SI 0 "register_operand" "")
22011 (mult:SI (match_operand:SI 1 "memory_operand" "")
22012 (match_operand:SI 2 "immediate_operand" "")))
22013 (clobber (reg:CC FLAGS_REG))])]
22014 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
22015 && !satisfies_constraint_K (operands[2])"
22016 [(set (match_dup 3) (match_dup 1))
22017 (parallel [(set (match_dup 0) (mult:SI (match_dup 3) (match_dup 2)))
22018 (clobber (reg:CC FLAGS_REG))])]
22022 [(match_scratch:SI 3 "r")
22023 (parallel [(set (match_operand:DI 0 "register_operand" "")
22025 (mult:SI (match_operand:SI 1 "memory_operand" "")
22026 (match_operand:SI 2 "immediate_operand" ""))))
22027 (clobber (reg:CC FLAGS_REG))])]
22028 "TARGET_SLOW_IMUL_IMM32_MEM && optimize_insn_for_speed_p ()
22029 && !satisfies_constraint_K (operands[2])"
22030 [(set (match_dup 3) (match_dup 1))
22031 (parallel [(set (match_dup 0) (zero_extend:DI (mult:SI (match_dup 3) (match_dup 2))))
22032 (clobber (reg:CC FLAGS_REG))])]
22035 ;; imul $8/16bit_imm, regmem, reg is vector decoded.
22036 ;; Convert it into imul reg, reg
22037 ;; It would be better to force assembler to encode instruction using long
22038 ;; immediate, but there is apparently no way to do so.
22040 [(parallel [(set (match_operand:DI 0 "register_operand" "")
22041 (mult:DI (match_operand:DI 1 "nonimmediate_operand" "")
22042 (match_operand:DI 2 "const_int_operand" "")))
22043 (clobber (reg:CC FLAGS_REG))])
22044 (match_scratch:DI 3 "r")]
22045 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
22046 && satisfies_constraint_K (operands[2])"
22047 [(set (match_dup 3) (match_dup 2))
22048 (parallel [(set (match_dup 0) (mult:DI (match_dup 0) (match_dup 3)))
22049 (clobber (reg:CC FLAGS_REG))])]
22051 if (!rtx_equal_p (operands[0], operands[1]))
22052 emit_move_insn (operands[0], operands[1]);
22056 [(parallel [(set (match_operand:SI 0 "register_operand" "")
22057 (mult:SI (match_operand:SI 1 "nonimmediate_operand" "")
22058 (match_operand:SI 2 "const_int_operand" "")))
22059 (clobber (reg:CC FLAGS_REG))])
22060 (match_scratch:SI 3 "r")]
22061 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()
22062 && satisfies_constraint_K (operands[2])"
22063 [(set (match_dup 3) (match_dup 2))
22064 (parallel [(set (match_dup 0) (mult:SI (match_dup 0) (match_dup 3)))
22065 (clobber (reg:CC FLAGS_REG))])]
22067 if (!rtx_equal_p (operands[0], operands[1]))
22068 emit_move_insn (operands[0], operands[1]);
22072 [(parallel [(set (match_operand:HI 0 "register_operand" "")
22073 (mult:HI (match_operand:HI 1 "nonimmediate_operand" "")
22074 (match_operand:HI 2 "immediate_operand" "")))
22075 (clobber (reg:CC FLAGS_REG))])
22076 (match_scratch:HI 3 "r")]
22077 "TARGET_SLOW_IMUL_IMM8 && optimize_insn_for_speed_p ()"
22078 [(set (match_dup 3) (match_dup 2))
22079 (parallel [(set (match_dup 0) (mult:HI (match_dup 0) (match_dup 3)))
22080 (clobber (reg:CC FLAGS_REG))])]
22082 if (!rtx_equal_p (operands[0], operands[1]))
22083 emit_move_insn (operands[0], operands[1]);
22086 ;; After splitting up read-modify operations, array accesses with memory
22087 ;; operands might end up in form:
22089 ;; movl 4(%esp), %edx
22091 ;; instead of pre-splitting:
22093 ;; addl 4(%esp), %eax
22095 ;; movl 4(%esp), %edx
22096 ;; leal (%edx,%eax,4), %eax
22099 [(parallel [(set (match_operand 0 "register_operand" "")
22100 (ashift (match_operand 1 "register_operand" "")
22101 (match_operand 2 "const_int_operand" "")))
22102 (clobber (reg:CC FLAGS_REG))])
22103 (set (match_operand 3 "register_operand")
22104 (match_operand 4 "x86_64_general_operand" ""))
22105 (parallel [(set (match_operand 5 "register_operand" "")
22106 (plus (match_operand 6 "register_operand" "")
22107 (match_operand 7 "register_operand" "")))
22108 (clobber (reg:CC FLAGS_REG))])]
22109 "INTVAL (operands[2]) >= 0 && INTVAL (operands[2]) <= 3
22110 /* Validate MODE for lea. */
22111 && ((!TARGET_PARTIAL_REG_STALL
22112 && (GET_MODE (operands[0]) == QImode
22113 || GET_MODE (operands[0]) == HImode))
22114 || GET_MODE (operands[0]) == SImode
22115 || (TARGET_64BIT && GET_MODE (operands[0]) == DImode))
22116 /* We reorder load and the shift. */
22117 && !rtx_equal_p (operands[1], operands[3])
22118 && !reg_overlap_mentioned_p (operands[0], operands[4])
22119 /* Last PLUS must consist of operand 0 and 3. */
22120 && !rtx_equal_p (operands[0], operands[3])
22121 && (rtx_equal_p (operands[3], operands[6])
22122 || rtx_equal_p (operands[3], operands[7]))
22123 && (rtx_equal_p (operands[0], operands[6])
22124 || rtx_equal_p (operands[0], operands[7]))
22125 /* The intermediate operand 0 must die or be same as output. */
22126 && (rtx_equal_p (operands[0], operands[5])
22127 || peep2_reg_dead_p (3, operands[0]))"
22128 [(set (match_dup 3) (match_dup 4))
22129 (set (match_dup 0) (match_dup 1))]
22131 enum machine_mode mode = GET_MODE (operands[5]) == DImode ? DImode : SImode;
22132 int scale = 1 << INTVAL (operands[2]);
22133 rtx index = gen_lowpart (Pmode, operands[1]);
22134 rtx base = gen_lowpart (Pmode, operands[3]);
22135 rtx dest = gen_lowpart (mode, operands[5]);
22137 operands[1] = gen_rtx_PLUS (Pmode, base,
22138 gen_rtx_MULT (Pmode, index, GEN_INT (scale)));
22140 operands[1] = gen_rtx_SUBREG (mode, operands[1], 0);
22141 operands[0] = dest;
22144 ;; Call-value patterns last so that the wildcard operand does not
22145 ;; disrupt insn-recog's switch tables.
22147 (define_insn "*call_value_pop_0"
22148 [(set (match_operand 0 "" "")
22149 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22150 (match_operand:SI 2 "" "")))
22151 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22152 (match_operand:SI 3 "immediate_operand" "")))]
22155 if (SIBLING_CALL_P (insn))
22158 return "call\t%P1";
22160 [(set_attr "type" "callv")])
22162 (define_insn "*call_value_pop_1"
22163 [(set (match_operand 0 "" "")
22164 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22165 (match_operand:SI 2 "" "")))
22166 (set (reg:SI SP_REG) (plus:SI (reg:SI SP_REG)
22167 (match_operand:SI 3 "immediate_operand" "i")))]
22170 if (constant_call_address_operand (operands[1], Pmode))
22172 if (SIBLING_CALL_P (insn))
22175 return "call\t%P1";
22177 if (SIBLING_CALL_P (insn))
22180 return "call\t%A1";
22182 [(set_attr "type" "callv")])
22184 (define_insn "*call_value_0"
22185 [(set (match_operand 0 "" "")
22186 (call (mem:QI (match_operand:SI 1 "constant_call_address_operand" ""))
22187 (match_operand:SI 2 "" "")))]
22190 if (SIBLING_CALL_P (insn))
22193 return "call\t%P1";
22195 [(set_attr "type" "callv")])
22197 (define_insn "*call_value_0_rex64"
22198 [(set (match_operand 0 "" "")
22199 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22200 (match_operand:DI 2 "const_int_operand" "")))]
22203 if (SIBLING_CALL_P (insn))
22206 return "call\t%P1";
22208 [(set_attr "type" "callv")])
22210 (define_insn "*call_value_0_rex64_ms_sysv"
22211 [(set (match_operand 0 "" "")
22212 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22213 (match_operand:DI 2 "const_int_operand" "")))
22214 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22215 (clobber (reg:TI XMM6_REG))
22216 (clobber (reg:TI XMM7_REG))
22217 (clobber (reg:TI XMM8_REG))
22218 (clobber (reg:TI XMM9_REG))
22219 (clobber (reg:TI XMM10_REG))
22220 (clobber (reg:TI XMM11_REG))
22221 (clobber (reg:TI XMM12_REG))
22222 (clobber (reg:TI XMM13_REG))
22223 (clobber (reg:TI XMM14_REG))
22224 (clobber (reg:TI XMM15_REG))
22225 (clobber (reg:DI SI_REG))
22226 (clobber (reg:DI DI_REG))]
22227 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22229 if (SIBLING_CALL_P (insn))
22232 return "call\t%P1";
22234 [(set_attr "type" "callv")])
22236 (define_insn "*call_value_1"
22237 [(set (match_operand 0 "" "")
22238 (call (mem:QI (match_operand:SI 1 "call_insn_operand" "rsm"))
22239 (match_operand:SI 2 "" "")))]
22240 "!SIBLING_CALL_P (insn) && !TARGET_64BIT"
22242 if (constant_call_address_operand (operands[1], Pmode))
22243 return "call\t%P1";
22244 return "call\t%A1";
22246 [(set_attr "type" "callv")])
22248 (define_insn "*sibcall_value_1"
22249 [(set (match_operand 0 "" "")
22250 (call (mem:QI (match_operand:SI 1 "sibcall_insn_operand" "s,c,d,a"))
22251 (match_operand:SI 2 "" "")))]
22252 "SIBLING_CALL_P (insn) && !TARGET_64BIT"
22254 if (constant_call_address_operand (operands[1], Pmode))
22258 [(set_attr "type" "callv")])
22260 (define_insn "*call_value_1_rex64"
22261 [(set (match_operand 0 "" "")
22262 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22263 (match_operand:DI 2 "" "")))]
22264 "!SIBLING_CALL_P (insn) && TARGET_64BIT
22265 && ix86_cmodel != CM_LARGE && ix86_cmodel != CM_LARGE_PIC"
22267 if (constant_call_address_operand (operands[1], Pmode))
22268 return "call\t%P1";
22269 return "call\t%A1";
22271 [(set_attr "type" "callv")])
22273 (define_insn "*call_value_1_rex64_ms_sysv"
22274 [(set (match_operand 0 "" "")
22275 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rsm"))
22276 (match_operand:DI 2 "" "")))
22277 (unspec [(const_int 0)] UNSPEC_MS_TO_SYSV_CALL)
22278 (clobber (reg:TI 27))
22279 (clobber (reg:TI 28))
22280 (clobber (reg:TI 45))
22281 (clobber (reg:TI 46))
22282 (clobber (reg:TI 47))
22283 (clobber (reg:TI 48))
22284 (clobber (reg:TI 49))
22285 (clobber (reg:TI 50))
22286 (clobber (reg:TI 51))
22287 (clobber (reg:TI 52))
22288 (clobber (reg:DI SI_REG))
22289 (clobber (reg:DI DI_REG))]
22290 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22292 if (constant_call_address_operand (operands[1], Pmode))
22293 return "call\t%P1";
22294 return "call\t%A1";
22296 [(set_attr "type" "callv")])
22298 (define_insn "*call_value_1_rex64_large"
22299 [(set (match_operand 0 "" "")
22300 (call (mem:QI (match_operand:DI 1 "call_insn_operand" "rm"))
22301 (match_operand:DI 2 "" "")))]
22302 "!SIBLING_CALL_P (insn) && TARGET_64BIT"
22304 [(set_attr "type" "callv")])
22306 (define_insn "*sibcall_value_1_rex64"
22307 [(set (match_operand 0 "" "")
22308 (call (mem:QI (match_operand:DI 1 "constant_call_address_operand" ""))
22309 (match_operand:DI 2 "" "")))]
22310 "SIBLING_CALL_P (insn) && TARGET_64BIT"
22312 [(set_attr "type" "callv")])
22314 (define_insn "*sibcall_value_1_rex64_v"
22315 [(set (match_operand 0 "" "")
22316 (call (mem:QI (reg:DI R11_REG))
22317 (match_operand:DI 1 "" "")))]
22318 "SIBLING_CALL_P (insn) && TARGET_64BIT"
22320 [(set_attr "type" "callv")])
22322 ;; We used to use "int $5", in honor of #BR which maps to interrupt vector 5.
22323 ;; That, however, is usually mapped by the OS to SIGSEGV, which is often
22324 ;; caught for use by garbage collectors and the like. Using an insn that
22325 ;; maps to SIGILL makes it more likely the program will rightfully die.
22326 ;; Keeping with tradition, "6" is in honor of #UD.
22327 (define_insn "trap"
22328 [(trap_if (const_int 1) (const_int 6))]
22330 { return ASM_SHORT "0x0b0f"; }
22331 [(set_attr "length" "2")])
22333 (define_expand "sse_prologue_save"
22334 [(parallel [(set (match_operand:BLK 0 "" "")
22335 (unspec:BLK [(reg:DI 21)
22342 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22343 (use (match_operand:DI 1 "register_operand" ""))
22344 (use (match_operand:DI 2 "immediate_operand" ""))
22345 (use (label_ref:DI (match_operand 3 "" "")))])]
22349 (define_insn "*sse_prologue_save_insn"
22350 [(set (mem:BLK (plus:DI (match_operand:DI 0 "register_operand" "R")
22351 (match_operand:DI 4 "const_int_operand" "n")))
22352 (unspec:BLK [(reg:DI 21)
22359 (reg:DI 28)] UNSPEC_SSE_PROLOGUE_SAVE))
22360 (use (match_operand:DI 1 "register_operand" "r"))
22361 (use (match_operand:DI 2 "const_int_operand" "i"))
22362 (use (label_ref:DI (match_operand 3 "" "X")))]
22364 && INTVAL (operands[4]) + X86_64_SSE_REGPARM_MAX * 16 - 16 < 128
22365 && INTVAL (operands[4]) + INTVAL (operands[2]) * 16 >= -128"
22368 operands[0] = gen_rtx_MEM (Pmode,
22369 gen_rtx_PLUS (Pmode, operands[0], operands[4]));
22370 /* VEX instruction with a REX prefix will #UD. */
22371 if (TARGET_AVX && GET_CODE (XEXP (operands[0], 0)) != PLUS)
22372 gcc_unreachable ();
22374 output_asm_insn ("jmp\t%A1", operands);
22375 for (i = X86_64_SSE_REGPARM_MAX - 1; i >= INTVAL (operands[2]); i--)
22377 operands[4] = adjust_address (operands[0], DImode, i*16);
22378 operands[5] = gen_rtx_REG (TImode, SSE_REGNO (i));
22379 PUT_MODE (operands[4], TImode);
22380 if (GET_CODE (XEXP (operands[0], 0)) != PLUS)
22381 output_asm_insn ("rex", operands);
22382 output_asm_insn ("%vmovaps\t{%5, %4|%4, %5}", operands);
22384 (*targetm.asm_out.internal_label) (asm_out_file, "L",
22385 CODE_LABEL_NUMBER (operands[3]));
22388 [(set_attr "type" "other")
22389 (set_attr "length_immediate" "0")
22390 (set_attr "length_address" "0")
22391 (set (attr "length")
22393 (eq (symbol_ref "TARGET_AVX") (const_int 0))
22394 (const_string "34")
22395 (const_string "42")))
22396 (set_attr "memory" "store")
22397 (set_attr "modrm" "0")
22398 (set_attr "prefix" "maybe_vex")
22399 (set_attr "mode" "DI")])
22401 (define_expand "prefetch"
22402 [(prefetch (match_operand 0 "address_operand" "")
22403 (match_operand:SI 1 "const_int_operand" "")
22404 (match_operand:SI 2 "const_int_operand" ""))]
22405 "TARGET_PREFETCH_SSE || TARGET_3DNOW"
22407 int rw = INTVAL (operands[1]);
22408 int locality = INTVAL (operands[2]);
22410 gcc_assert (rw == 0 || rw == 1);
22411 gcc_assert (locality >= 0 && locality <= 3);
22412 gcc_assert (GET_MODE (operands[0]) == Pmode
22413 || GET_MODE (operands[0]) == VOIDmode);
22415 /* Use 3dNOW prefetch in case we are asking for write prefetch not
22416 supported by SSE counterpart or the SSE prefetch is not available
22417 (K6 machines). Otherwise use SSE prefetch as it allows specifying
22419 if (TARGET_3DNOW && (!TARGET_PREFETCH_SSE || rw))
22420 operands[2] = GEN_INT (3);
22422 operands[1] = const0_rtx;
22425 (define_insn "*prefetch_sse"
22426 [(prefetch (match_operand:SI 0 "address_operand" "p")
22428 (match_operand:SI 1 "const_int_operand" ""))]
22429 "TARGET_PREFETCH_SSE && !TARGET_64BIT"
22431 static const char * const patterns[4] = {
22432 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22435 int locality = INTVAL (operands[1]);
22436 gcc_assert (locality >= 0 && locality <= 3);
22438 return patterns[locality];
22440 [(set_attr "type" "sse")
22441 (set_attr "atom_sse_attr" "prefetch")
22442 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22443 (set_attr "memory" "none")])
22445 (define_insn "*prefetch_sse_rex"
22446 [(prefetch (match_operand:DI 0 "address_operand" "p")
22448 (match_operand:SI 1 "const_int_operand" ""))]
22449 "TARGET_PREFETCH_SSE && TARGET_64BIT"
22451 static const char * const patterns[4] = {
22452 "prefetchnta\t%a0", "prefetcht2\t%a0", "prefetcht1\t%a0", "prefetcht0\t%a0"
22455 int locality = INTVAL (operands[1]);
22456 gcc_assert (locality >= 0 && locality <= 3);
22458 return patterns[locality];
22460 [(set_attr "type" "sse")
22461 (set_attr "atom_sse_attr" "prefetch")
22462 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22463 (set_attr "memory" "none")])
22465 (define_insn "*prefetch_3dnow"
22466 [(prefetch (match_operand:SI 0 "address_operand" "p")
22467 (match_operand:SI 1 "const_int_operand" "n")
22469 "TARGET_3DNOW && !TARGET_64BIT"
22471 if (INTVAL (operands[1]) == 0)
22472 return "prefetch\t%a0";
22474 return "prefetchw\t%a0";
22476 [(set_attr "type" "mmx")
22477 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22478 (set_attr "memory" "none")])
22480 (define_insn "*prefetch_3dnow_rex"
22481 [(prefetch (match_operand:DI 0 "address_operand" "p")
22482 (match_operand:SI 1 "const_int_operand" "n")
22484 "TARGET_3DNOW && TARGET_64BIT"
22486 if (INTVAL (operands[1]) == 0)
22487 return "prefetch\t%a0";
22489 return "prefetchw\t%a0";
22491 [(set_attr "type" "mmx")
22492 (set (attr "length_address") (symbol_ref "memory_address_length (operands[0])"))
22493 (set_attr "memory" "none")])
22495 (define_expand "stack_protect_set"
22496 [(match_operand 0 "memory_operand" "")
22497 (match_operand 1 "memory_operand" "")]
22500 #ifdef TARGET_THREAD_SSP_OFFSET
22502 emit_insn (gen_stack_tls_protect_set_di (operands[0],
22503 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22505 emit_insn (gen_stack_tls_protect_set_si (operands[0],
22506 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22509 emit_insn (gen_stack_protect_set_di (operands[0], operands[1]));
22511 emit_insn (gen_stack_protect_set_si (operands[0], operands[1]));
22516 (define_insn "stack_protect_set_si"
22517 [(set (match_operand:SI 0 "memory_operand" "=m")
22518 (unspec:SI [(match_operand:SI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22519 (set (match_scratch:SI 2 "=&r") (const_int 0))
22520 (clobber (reg:CC FLAGS_REG))]
22522 "mov{l}\t{%1, %2|%2, %1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22523 [(set_attr "type" "multi")])
22525 (define_insn "stack_protect_set_di"
22526 [(set (match_operand:DI 0 "memory_operand" "=m")
22527 (unspec:DI [(match_operand:DI 1 "memory_operand" "m")] UNSPEC_SP_SET))
22528 (set (match_scratch:DI 2 "=&r") (const_int 0))
22529 (clobber (reg:CC FLAGS_REG))]
22531 "mov{q}\t{%1, %2|%2, %1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2"
22532 [(set_attr "type" "multi")])
22534 (define_insn "stack_tls_protect_set_si"
22535 [(set (match_operand:SI 0 "memory_operand" "=m")
22536 (unspec:SI [(match_operand:SI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22537 (set (match_scratch:SI 2 "=&r") (const_int 0))
22538 (clobber (reg:CC FLAGS_REG))]
22540 "mov{l}\t{%%gs:%P1, %2|%2, DWORD PTR gs:%P1}\;mov{l}\t{%2, %0|%0, %2}\;xor{l}\t%2, %2"
22541 [(set_attr "type" "multi")])
22543 (define_insn "stack_tls_protect_set_di"
22544 [(set (match_operand:DI 0 "memory_operand" "=m")
22545 (unspec:DI [(match_operand:DI 1 "const_int_operand" "i")] UNSPEC_SP_TLS_SET))
22546 (set (match_scratch:DI 2 "=&r") (const_int 0))
22547 (clobber (reg:CC FLAGS_REG))]
22550 /* The kernel uses a different segment register for performance reasons; a
22551 system call would not have to trash the userspace segment register,
22552 which would be expensive */
22553 if (ix86_cmodel != CM_KERNEL)
22554 return "mov{q}\t{%%fs:%P1, %2|%2, QWORD PTR fs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22556 return "mov{q}\t{%%gs:%P1, %2|%2, QWORD PTR gs:%P1}\;mov{q}\t{%2, %0|%0, %2}\;xor{l}\t%k2, %k2";
22558 [(set_attr "type" "multi")])
22560 (define_expand "stack_protect_test"
22561 [(match_operand 0 "memory_operand" "")
22562 (match_operand 1 "memory_operand" "")
22563 (match_operand 2 "" "")]
22566 rtx flags = gen_rtx_REG (CCZmode, FLAGS_REG);
22568 #ifdef TARGET_THREAD_SSP_OFFSET
22570 emit_insn (gen_stack_tls_protect_test_di (flags, operands[0],
22571 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22573 emit_insn (gen_stack_tls_protect_test_si (flags, operands[0],
22574 GEN_INT (TARGET_THREAD_SSP_OFFSET)));
22577 emit_insn (gen_stack_protect_test_di (flags, operands[0], operands[1]));
22579 emit_insn (gen_stack_protect_test_si (flags, operands[0], operands[1]));
22582 emit_jump_insn (gen_cbranchcc4 (gen_rtx_EQ (VOIDmode, flags, const0_rtx),
22583 flags, const0_rtx, operands[2]));
22587 (define_insn "stack_protect_test_si"
22588 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22589 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22590 (match_operand:SI 2 "memory_operand" "m")]
22592 (clobber (match_scratch:SI 3 "=&r"))]
22594 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%2, %3|%3, %2}"
22595 [(set_attr "type" "multi")])
22597 (define_insn "stack_protect_test_di"
22598 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22599 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22600 (match_operand:DI 2 "memory_operand" "m")]
22602 (clobber (match_scratch:DI 3 "=&r"))]
22604 "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%2, %3|%3, %2}"
22605 [(set_attr "type" "multi")])
22607 (define_insn "stack_tls_protect_test_si"
22608 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22609 (unspec:CCZ [(match_operand:SI 1 "memory_operand" "m")
22610 (match_operand:SI 2 "const_int_operand" "i")]
22611 UNSPEC_SP_TLS_TEST))
22612 (clobber (match_scratch:SI 3 "=r"))]
22614 "mov{l}\t{%1, %3|%3, %1}\;xor{l}\t{%%gs:%P2, %3|%3, DWORD PTR gs:%P2}"
22615 [(set_attr "type" "multi")])
22617 (define_insn "stack_tls_protect_test_di"
22618 [(set (match_operand:CCZ 0 "flags_reg_operand" "")
22619 (unspec:CCZ [(match_operand:DI 1 "memory_operand" "m")
22620 (match_operand:DI 2 "const_int_operand" "i")]
22621 UNSPEC_SP_TLS_TEST))
22622 (clobber (match_scratch:DI 3 "=r"))]
22625 /* The kernel uses a different segment register for performance reasons; a
22626 system call would not have to trash the userspace segment register,
22627 which would be expensive */
22628 if (ix86_cmodel != CM_KERNEL)
22629 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%fs:%P2, %3|%3, QWORD PTR fs:%P2}";
22631 return "mov{q}\t{%1, %3|%3, %1}\;xor{q}\t{%%gs:%P2, %3|%3, QWORD PTR gs:%P2}";
22633 [(set_attr "type" "multi")])
22635 (define_mode_iterator CRC32MODE [QI HI SI])
22636 (define_mode_attr crc32modesuffix [(QI "b") (HI "w") (SI "l")])
22637 (define_mode_attr crc32modeconstraint [(QI "qm") (HI "rm") (SI "rm")])
22639 (define_insn "sse4_2_crc32<mode>"
22640 [(set (match_operand:SI 0 "register_operand" "=r")
22642 [(match_operand:SI 1 "register_operand" "0")
22643 (match_operand:CRC32MODE 2 "nonimmediate_operand" "<crc32modeconstraint>")]
22645 "TARGET_SSE4_2 || TARGET_CRC32"
22646 "crc32<crc32modesuffix>\t{%2, %0|%0, %2}"
22647 [(set_attr "type" "sselog1")
22648 (set_attr "prefix_rep" "1")
22649 (set_attr "prefix_extra" "1")
22650 (set (attr "prefix_data16")
22651 (if_then_else (match_operand:HI 2 "" "")
22653 (const_string "*")))
22654 (set (attr "prefix_rex")
22655 (if_then_else (match_operand:QI 2 "ext_QIreg_operand" "")
22657 (const_string "*")))
22658 (set_attr "mode" "SI")])
22660 (define_insn "sse4_2_crc32di"
22661 [(set (match_operand:DI 0 "register_operand" "=r")
22663 [(match_operand:DI 1 "register_operand" "0")
22664 (match_operand:DI 2 "nonimmediate_operand" "rm")]
22666 "TARGET_64BIT && (TARGET_SSE4_2 || TARGET_CRC32)"
22667 "crc32q\t{%2, %0|%0, %2}"
22668 [(set_attr "type" "sselog1")
22669 (set_attr "prefix_rep" "1")
22670 (set_attr "prefix_extra" "1")
22671 (set_attr "mode" "DI")])
22675 (include "sync.md")